diff --git a/apps/web/src/components/video-generator.tsx b/apps/web/src/components/video-generator.tsx
index 578d24a83..7bda31797 100644
--- a/apps/web/src/components/video-generator.tsx
+++ b/apps/web/src/components/video-generator.tsx
@@ -181,7 +181,10 @@ export default function VideoGenerator({ className = '' }: VideoGeneratorProps)
+<<<<<<< HEAD
+=======
{!prompt.trim() && (
Enter a prompt to enable video generation.
)}
+>>>>>>> origin/main
{/* Warning */}
diff --git a/apps/web/src/lib/__tests__/auth-config-source.test.ts b/apps/web/src/lib/__tests__/auth-config-source.test.ts
index 58179c54c..590a4e7e2 100644
--- a/apps/web/src/lib/__tests__/auth-config-source.test.ts
+++ b/apps/web/src/lib/__tests__/auth-config-source.test.ts
@@ -23,12 +23,24 @@ describe('auth configuration source safety', () => {
expect(source).not.toContain(' {
+ it('accepts both project-specific and common Google OAuth env names with standard names prioritized over legacy fallback names', () => {
const source = readSource('lib/auth.ts');
expect(source).toContain('GOOGLE_OAUTH_CLIENT_ID');
expect(source).toContain('GOOGLE_CLIENT_ID');
expect(source).toContain('GOOGLE_OAUTH_CLIENT_SECRET');
expect(source).toContain('GOOGLE_CLIENT_SECRET');
+
+ const idIdxCanonical = source.indexOf('process.env.GOOGLE_CLIENT_ID');
+ const idIdxFallback = source.indexOf('process.env.GOOGLE_OAUTH_CLIENT_ID');
+ expect(idIdxCanonical).toBeGreaterThan(-1);
+ expect(idIdxFallback).toBeGreaterThan(-1);
+ expect(idIdxCanonical).toBeLessThan(idIdxFallback);
+
+ const secretIdxCanonical = source.indexOf('process.env.GOOGLE_CLIENT_SECRET');
+ const secretIdxFallback = source.indexOf('process.env.GOOGLE_OAUTH_CLIENT_SECRET');
+ expect(secretIdxCanonical).toBeGreaterThan(-1);
+ expect(secretIdxFallback).toBeGreaterThan(-1);
+ expect(secretIdxCanonical).toBeLessThan(secretIdxFallback);
});
it('keeps the root route as a landing page instead of redirecting to the app', () => {
diff --git a/apps/web/src/lib/auth.ts b/apps/web/src/lib/auth.ts
index 5c5ab4ab2..61a1908d1 100644
--- a/apps/web/src/lib/auth.ts
+++ b/apps/web/src/lib/auth.ts
@@ -5,6 +5,15 @@ import GoogleProvider from 'next-auth/providers/google';
const allowedDomain = process.env.AUTH_ALLOWED_EMAIL_DOMAIN?.trim().toLowerCase();
const googleClientId = (
+<<<<<<< HEAD
+ process.env.GOOGLE_CLIENT_ID ||
+ process.env.GOOGLE_OAUTH_CLIENT_ID ||
+ ''
+).trim();
+const googleClientSecret = (
+ process.env.GOOGLE_CLIENT_SECRET ||
+ process.env.GOOGLE_OAUTH_CLIENT_SECRET ||
+=======
process.env.GOOGLE_OAUTH_CLIENT_ID ||
process.env.GOOGLE_CLIENT_ID ||
''
@@ -12,6 +21,7 @@ const googleClientId = (
const googleClientSecret = (
process.env.GOOGLE_OAUTH_CLIENT_SECRET ||
process.env.GOOGLE_CLIENT_SECRET ||
+>>>>>>> origin/main
''
).trim();
@@ -19,8 +29,12 @@ const googleClientSecret = (
* NextAuth configuration (Google OAuth by default).
*
* Required env to activate login-gating: NEXTAUTH_SECRET, NEXTAUTH_URL,
+<<<<<<< HEAD
+ * GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET (with fallback to GOOGLE_OAUTH_CLIENT_ID / GOOGLE_OAUTH_CLIENT_SECRET).
+=======
* GOOGLE_OAUTH_CLIENT_ID, GOOGLE_OAUTH_CLIENT_SECRET.
* Also accepts NextAuth's common GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET names.
+>>>>>>> origin/main
* Optional: AUTH_ALLOWED_EMAIL_DOMAIN restricts sign-in to a single domain
* (e.g. `yourcompany.com` → only *@yourcompany.com).
*
@@ -31,7 +45,11 @@ function buildProviders(): NextAuthOptions['providers'] {
if (!googleClientId || !googleClientSecret) {
if (process.env.NODE_ENV === 'production') {
console.error(
+<<<<<<< HEAD
+ '[auth] Google OAuth client id/secret missing — set GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET or GOOGLE_OAUTH_CLIENT_ID / GOOGLE_OAUTH_CLIENT_SECRET.',
+=======
'[auth] Google OAuth client id/secret missing — set GOOGLE_OAUTH_CLIENT_ID / GOOGLE_OAUTH_CLIENT_SECRET or GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET.',
+>>>>>>> origin/main
);
}
}
diff --git a/apps/web/src/lib/error-handling.ts b/apps/web/src/lib/error-handling.ts
index 5867b1c41..5b53af6e1 100644
--- a/apps/web/src/lib/error-handling.ts
+++ b/apps/web/src/lib/error-handling.ts
@@ -138,7 +138,11 @@ export function formatApiError(
if (error instanceof Error) {
return {
message: error.message || defaultMessage,
+<<<<<<< HEAD
+ details: error.stack?.split('\n')[1]?.trim(),
+=======
// Removed stack trace exposure for security
+>>>>>>> origin/main
};
}
diff --git a/apps/web/src/proxy.ts b/apps/web/src/proxy.ts
index d70f3686e..2c9172214 100644
--- a/apps/web/src/proxy.ts
+++ b/apps/web/src/proxy.ts
@@ -234,7 +234,11 @@ export async function proxy(request: NextRequest): Promise {
if (pathname.startsWith('/api/')) {
return NextResponse.json({ error: 'Authentication required' }, { status: 401 });
}
+<<<<<<< HEAD
+ const signin = new URL('/api/auth/signin', request.url);
+=======
const signin = new URL('/login', request.url);
+>>>>>>> origin/main
// Relative same-origin path only — blocks open-redirect callback abuse.
signin.searchParams.set(
'callbackUrl',
diff --git a/commit_script.sh b/commit_script.sh
new file mode 100755
index 000000000..5563e3211
--- /dev/null
+++ b/commit_script.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+set -e
+git checkout -b fix/remove-importlib-util-openai-dev
+git add src/agents/openai_dev_task_manager.py
+git commit -m "🧹 Remove Unused importlib.util Import
+
+🎯 What: Removed the unused \`importlib.util\` import in \`src/agents/openai_dev_task_manager.py\` and refactored the dynamic loading to use direct Python imports.
+💡 Why: Removing the dynamic class loading using file path and relying on standard direct import eliminates the need for the \`importlib.util\` module, making the code much cleaner and easier to maintain.
+✅ Verification: Tested the refactored code directly by loading the \`OpenAIDevTaskManager\` class, validating no regressions, and running \`ruff check\` + \`black\` for formatting.
+✨ Result: Cleaned up unnecessary imports, simplifying the code logic without altering existing functionality."
diff --git a/docs/TECH_STACK.md b/docs/TECH_STACK.md
index 383ee0114..f7ea6693e 100644
--- a/docs/TECH_STACK.md
+++ b/docs/TECH_STACK.md
@@ -202,7 +202,13 @@ EventRelay/
# Frontend
cd apps/web && npm run dev
+<<<<<<< HEAD
+# Backend
+cd src/youtube_extension/backend
+python -m uvicorn main:app --reload --port 8000
+=======
# Backend (run from the repo root; PYTHONPATH=src is required)
PYTHONPATH=src python -m uvicorn youtube_extension.main:app --reload --port 8000
+>>>>>>> origin/main
# Deploy Backend (Cloud Build)
\ No newline at end of file
diff --git a/docs/agent-completion-truth-gate.md b/docs/agent-completion-truth-gate.md
index ef688e4f6..9ec40706c 100644
--- a/docs/agent-completion-truth-gate.md
+++ b/docs/agent-completion-truth-gate.md
@@ -12,7 +12,11 @@ The trusted publisher must bind report data to PR number, full head SHA, deliver
Before delegation, create the task with the Agent task issue form. Agent login, run ID, objective, acceptance criteria, exact file scope, allowed extras, and focused test paths are the intent contract. Unrestricted scope is intentionally unavailable in the form until #874 provisions the protected `scope-unrestricted-approved` label and its authorization policy; any hand-authored unrestricted request without that label fails closed.
+<<<<<<< HEAD
+When a complete agent task receives its initial `agent-task` or `mcp/agent` label from an actor with a standard `triage`-or-higher role (or a custom role that GitHub reports at legacy `write` level), the default-branch workflow writes a github-actions[bot] comment containing the SHA-256 digest of the normalized issue body and the unrestricted-scope approval state. Snapshot creation is label-event-only because GitHub emits separate `opened` and `labeled` workflow runs for an issue form that applies a label. The snapshot records the creating workflow run ID so re-running that same event is idempotent. Issue author association alone is not trusted. GitHub's collaborator response cannot distinguish a custom triage-derived role from a custom read-derived role, so custom roles reported at legacy `read` fail closed and a standard triage-or-higher user must relabel. The collector requires that snapshot and requires it to predate the PR. Any later issue edit or label transition appends a bot-owned invalidation marker. Treating every queued edit/label event as invalidating makes GitHub concurrency coalescing lossless: an event that replaces a pending invalidation is itself an invalidation. A trusted originating issue event dispatches immediate reevaluation; an untrusted or unverifiable editor falls back to the scheduled scanner because a marker written with `GITHUB_TOKEN` does not recursively trigger `issue_comment`. The scanner blocks permanently even if the original body or label state is restored. Existing tasks must be relabeled by a trusted user to create their one-time snapshot before dispatch. Create a new task for any post-snapshot edit; do not broaden a dispatched task in place.
+=======
When a complete agent task is opened or first labeled by an actor with a standard `triage`-or-higher role (or a custom role that GitHub reports at legacy `write` level), the default-branch workflow writes a github-actions[bot] comment containing the SHA-256 digest of the normalized issue body and the unrestricted-scope approval state. The same live permission lookup applies to both event paths; issue author association alone is not trusted. GitHub's collaborator response cannot distinguish a custom triage-derived role from a custom read-derived role, so custom roles reported at legacy `read` fail closed and a standard triage-or-higher user must relabel. The collector requires that snapshot and requires it to predate the PR. Any later issue edit or label transition appends a bot-owned invalidation marker. Treating every queued edit/label event as invalidating makes GitHub concurrency coalescing lossless: an event that replaces a pending invalidation is itself an invalidation. The trusted marker comment dispatches immediate reevaluation, and the scheduled scanner also blocks permanently even if the original body or label state is restored. Existing tasks must be labeled again by a trusted user to create their one-time snapshot before dispatch. Create a new task for any post-snapshot edit; do not broaden a dispatched task in place.
+>>>>>>> origin/main
Agent pull requests link exactly one task with a closing keyword and include the agent-lock-manifest comment shown in the PR template. GitHub's authoritative closingIssuesReferences, the textual link, and the manifest must agree. The manifest login and run ID must exactly match the snapshotted issue. The declared agent publishes structured result evidence containing that run ID and the current PR head SHA; legacy unstructured readiness is never sufficient by itself.
@@ -27,12 +31,26 @@ The workflow publishes all of the following:
Even in the normal trust model—agents cannot write default-branch workflows or forge repository statuses—the custom status emitted here remains advisory. Follow-up #874 must bind evaluation to an independently head-bound required workflow or check before branch protection or a repository ruleset treats the result as merge enforcement. That ruleset must also require the repository's Copilot review, at least one approving review, and conversation resolution. The gate itself requires the maintainer-applied `copilot-rabbit` label, a non-dismissed Copilot review bound to the current head, every AI review thread resolved (including outdated threads), and committed focused unit tests. It binds to the exact-head trusted CI run, requires its `test` job to succeed, and requires that job's verbose pytest log to report at least one passing test for every declared path; an absent, deselected, or all-skipped path blocks. Human approval alone cannot satisfy those signals. Native review/conversation rules close the window between a new review comment and the scheduled refresh.
+<<<<<<< HEAD
+Each serialized run first posts a pending status tied to its Actions run. It uploads evidence and updates the PR comment before publishing a terminal status. Resolve-time, collection-time, and publication-time PR base and head commits must each remain the same 40-character SHA; a mismatch publishes `stale_base` or `stale_head` instead of reusing evidence across revisions. Changed-file evidence comes from the immutable resolved base/head commit comparison rather than the mutable live PR file list. A compare-and-swap check rejects superseded publication; an always-running finalizer turns publication failures into a failure status only when the run proves it owns the pending lease (or supersedes a predecessor). Unknown ownership fails the workflow without touching the shared status, and the scheduled scanner supplies eventual fail-closed recovery. A recovered infrastructure/publication failure remains failed until a new evidence event or a maintainer manually dispatches the workflow; the scanner does not churn unchanged evidence merely to retry it. GitHub permits at most 1,000 statuses for one SHA and context, so the workflow refuses to acquire a new lease at 998 existing per-PR gate statuses. The scanner may use a remaining slot to fail a proven stuck pending lease or invalidate a successful terminal result after evidence changes, but it never starts another full evaluation at that threshold; the operator must then push a new head or complete #874's Checks/App migration. If pending-status creation fails on a reused head, a previous successful status can remain visible until recovery; overwriting it without a proven lease could instead clobber a successor. This transient stale-green window is why this status is advisory until #874 supplies independently head-bound enforcement. Actions are pinned to full commit SHAs. Only refresh-dispatch jobs receive actions: write.
+=======
Each serialized run first posts a pending status tied to its Actions run. It uploads evidence and updates the PR comment before publishing a terminal status. A compare-and-swap check rejects superseded publication; an always-running finalizer turns publication failures into a failure status only when the run proves it owns the pending lease (or supersedes a predecessor). Unknown ownership fails the workflow without touching the shared status, and the scheduled scanner supplies eventual fail-closed recovery. A recovered infrastructure/publication failure remains failed until a new evidence event or a maintainer manually dispatches the workflow; the scanner does not churn unchanged evidence merely to retry it. GitHub permits at most 1,000 statuses for one SHA and context, so the workflow refuses to acquire a new lease at 998 existing per-PR gate statuses. The scanner may use a remaining slot to fail a proven stuck pending lease or invalidate a successful terminal result after evidence changes, but it never starts another full evaluation at that threshold; the operator must then push a new head or complete #874's Checks/App migration. If pending-status creation fails on a reused head, a previous successful status can remain visible until recovery; overwriting it without a proven lease could instead clobber a successor. This transient stale-green window is why this status is advisory until #874 supplies independently head-bound enforcement. Actions are pinned to full commit SHAs. Only refresh-dispatch jobs receive actions: write.
+>>>>>>> origin/main
Per-path focused-test proof currently parses terminal pytest outcomes from the exact-head trusted CI `test` job log. It handles both same-line verbose outcomes and node IDs followed by live-log output and a standalone terminal outcome. Exact path prefixes, whole-line terminal matching, test-node resets, and session-boundary resets prevent unrelated output from inheriting a prior test. A same-line candidate is deferred across blank lines so a following live-log header can disambiguate a parameter ID that resembles an outcome. Code executed by pytest can still deliberately forge console lines, so the required independent review remains part of the trust boundary. Follow-up #874 must move per-path evidence to a machine-readable report emitted and published by the protected CI workflow before this signal is treated as hostile-agent-resistant.
If an agent has repository-write credentials that can create Actions workflows or post statuses/comments, github-actions[bot] and a status-context string are not independent provenance. The collector also sees only the current comment bodies; an agent that can edit or delete its own result comment can erase contradictory self-reported history. In that threat model, keep this workflow advisory until snapshot, append-only result evidence, and check publication move to a dedicated GitHub App (or an organization ruleset-required trusted workflow) and bind the required check to that identity.
+<<<<<<< HEAD
+## Security Design and Concurrency Controls
+
+To guarantee system integrity, the following controls are strictly enforced:
+- Snapshot creation is label-event-only and does not recursively trigger `issue_comment` events.
+- Resolve-time, collection-time, and publication-time PR base and head commits are locked.
+- We perform immutable resolved base/head commit comparison to guarantee that the evaluated PR state matches the exact commits being merged.
+
+=======
+>>>>>>> origin/main
## Applicability
The gate applies when any of these signals identify agent work:
@@ -131,6 +149,9 @@ The gate blocks a missing, late, or changed intent snapshot; agent/run/head iden
Artifact ready is not completion. A Ready for review comment followed by an error is agent_run_failed. Generic green CI never overrides an unresolved review. An unmerged PR can be ready, but it can never be completed.
+<<<<<<< HEAD
+The deterministic evaluator blocks, and the workflow run fails, if checkout, evidence collection, evaluation, evidence upload, comment publication, or final status publication fails. Every terminal status carries the immutable pending-status ID that acquired its publication lease; status handoff compares those owner IDs so a newer lease overrides a late predecessor while an older lease yields to a successor. Unknown or malformed ownership fails the run without publishing from an unproven lease. Because an older success can remain visible during that recovery window, this custom status alone is not fail-closed merge enforcement. The snapshot assumes repository write access and the default branch are trusted; organizations that delegate repository-write credentials to agents should move snapshot creation behind a protected environment or an independently authenticated GitHub App.
+=======
The deterministic evaluator blocks, and the workflow run fails, if checkout, evidence collection, evaluation, evidence upload, comment publication, or final status publication fails. Every terminal status carries the immutable pending-status ID [acquired lease]; status handoff compares those owner IDs so a newer lease overrides a late predecessor while an older lease yields to a successor. Unknown or malformed ownership fails the run without publishing from an unproven lease. Because an older success can remain visible during that recovery window, this custom status alone is not fail-closed merge enforcement. The snapshot assumes repository write access and the default branch are trusted; organizations that delegate repository-write credentials to agents should move snapshot creation behind a protected environment or an independently authenticated GitHub App.
## Technical Constraints
@@ -139,3 +160,4 @@ The deterministic evaluator blocks, and the workflow run fails, if checkout, evi
- **Recursion protection**: Status checks and gate evaluation does not recursively trigger `issue_comment` events to prevent infinite automated loop cycles.
- **Trace parameters**: Resolve-time, collection-time, and publication-time PR base and head SHAs are captured explicitly to prevent race conditions during concurrent runs.
- **Commit comparisons**: Every verdict includes an immutable resolved base/head commit comparison to guarantee that evaluations apply exactly to the proposed diff.
+>>>>>>> origin/main
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/activate-empty.body b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/activate-empty.body
new file mode 100644
index 000000000..7a6650f58
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/activate-empty.body
@@ -0,0 +1 @@
+{"error":"session_id_required"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/activate-empty.code b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/activate-empty.code
new file mode 100644
index 000000000..d411bb7c1
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/activate-empty.code
@@ -0,0 +1 @@
+400
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/activate-empty.err b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/activate-empty.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-csrf.body b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-csrf.body
new file mode 100644
index 000000000..6482b9000
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-csrf.body
@@ -0,0 +1 @@
+{"csrfToken":"3f0812dce8a01ba4d14d9432b2823f283e360ae3136e1e78be7c941fa484654c"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-csrf.code b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-csrf.code
new file mode 100644
index 000000000..08839f6bb
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-csrf.code
@@ -0,0 +1 @@
+200
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-csrf.err b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-csrf.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-providers.body b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-providers.body
new file mode 100644
index 000000000..8ddf0c983
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-providers.body
@@ -0,0 +1 @@
+{"google":{"id":"google","name":"Google","type":"oauth","signinUrl":"https://uvai.io/api/auth/signin/google","callbackUrl":"https://uvai.io/api/auth/callback/google"}}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-providers.code b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-providers.code
new file mode 100644
index 000000000..08839f6bb
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-providers.code
@@ -0,0 +1 @@
+200
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-providers.err b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-providers.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-session.body b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-session.body
new file mode 100644
index 000000000..9e26dfeeb
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-session.body
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-session.code b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-session.code
new file mode 100644
index 000000000..08839f6bb
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-session.code
@@ -0,0 +1 @@
+200
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-session.err b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-session.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/billing-status.body b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/billing-status.body
new file mode 100644
index 000000000..80aea7551
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/billing-status.body
@@ -0,0 +1 @@
+{"plan":"free","status":"inactive","email":null,"features":{"unlimitedChat":false,"agentDispatch":false,"apiAccess":false,"chatDailyLimit":5},"routing":{"model":"gpt-4o-mini","runtime":"standard","plan":"free"},"renewalEligible":false}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/billing-status.code b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/billing-status.code
new file mode 100644
index 000000000..08839f6bb
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/billing-status.code
@@ -0,0 +1 @@
+200
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/billing-status.err b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/billing-status.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/checkout-empty.body b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/checkout-empty.body
new file mode 100644
index 000000000..76f33dd52
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/checkout-empty.body
@@ -0,0 +1 @@
+{"error":"turnstile_token_missing"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/checkout-empty.code b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/checkout-empty.code
new file mode 100644
index 000000000..e1a29c1fe
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/checkout-empty.code
@@ -0,0 +1 @@
+403
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/checkout-empty.err b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/checkout-empty.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/checkout-token.body b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/checkout-token.body
new file mode 100644
index 000000000..633b081cd
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/checkout-token.body
@@ -0,0 +1 @@
+{"error":"turnstile_verification_failed"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/checkout-token.code b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/checkout-token.code
new file mode 100644
index 000000000..e1a29c1fe
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/checkout-token.code
@@ -0,0 +1 @@
+403
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/checkout-token.err b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/checkout-token.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/meta.txt b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/meta.txt
new file mode 100644
index 000000000..96127d173
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/meta.txt
@@ -0,0 +1,4 @@
+UTC 2026-07-14T20:11:10Z
+git 64968c272
+webhook_id=we_1TtCYrPPnkyjEyFRKrZcElIB
+price_monthly=price_1TtCZXPPnkyjEyFR8dYmDo52
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/renew-empty.body b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/renew-empty.body
new file mode 100644
index 000000000..abe1bbac1
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/renew-empty.body
@@ -0,0 +1 @@
+{"error":"No such price: 'price_1Tos02AmTgsI2zgNWx7onroJ'"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/renew-empty.code b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/renew-empty.code
new file mode 100644
index 000000000..1b79f38e2
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/renew-empty.code
@@ -0,0 +1 @@
+500
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/renew-empty.err b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/renew-empty.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-badsig.body b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-badsig.body
new file mode 100644
index 000000000..f42efedd6
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-badsig.body
@@ -0,0 +1 @@
+{"error":"webhook_not_configured"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-badsig.code b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-badsig.code
new file mode 100644
index 000000000..a712e7640
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-badsig.code
@@ -0,0 +1 @@
+503
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-badsig.err b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-badsig.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-empty.body b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-empty.body
new file mode 100644
index 000000000..f42efedd6
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-empty.body
@@ -0,0 +1 @@
+{"error":"webhook_not_configured"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-empty.code b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-empty.code
new file mode 100644
index 000000000..a712e7640
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-empty.code
@@ -0,0 +1 @@
+503
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-empty.err b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-empty.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-nosig.body b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-nosig.body
new file mode 100644
index 000000000..f42efedd6
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-nosig.body
@@ -0,0 +1 @@
+{"error":"webhook_not_configured"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-nosig.code b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-nosig.code
new file mode 100644
index 000000000..a712e7640
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-nosig.code
@@ -0,0 +1 @@
+503
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-nosig.err b/docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-nosig.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/activate-empty.code b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/activate-empty.code
new file mode 100644
index 000000000..8f087a34c
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/activate-empty.code
@@ -0,0 +1 @@
+000
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/activate-empty.err b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/activate-empty.err
new file mode 100644
index 000000000..a8b706ff2
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/activate-empty.err
@@ -0,0 +1 @@
+probe:12: command not found: curl
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/auth-csrf.code b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/auth-csrf.code
new file mode 100644
index 000000000..8f087a34c
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/auth-csrf.code
@@ -0,0 +1 @@
+000
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/auth-csrf.err b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/auth-csrf.err
new file mode 100644
index 000000000..a8b706ff2
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/auth-csrf.err
@@ -0,0 +1 @@
+probe:12: command not found: curl
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/auth-providers.code b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/auth-providers.code
new file mode 100644
index 000000000..8f087a34c
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/auth-providers.code
@@ -0,0 +1 @@
+000
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/auth-providers.err b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/auth-providers.err
new file mode 100644
index 000000000..a8b706ff2
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/auth-providers.err
@@ -0,0 +1 @@
+probe:12: command not found: curl
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/auth-session.code b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/auth-session.code
new file mode 100644
index 000000000..8f087a34c
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/auth-session.code
@@ -0,0 +1 @@
+000
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/auth-session.err b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/auth-session.err
new file mode 100644
index 000000000..a8b706ff2
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/auth-session.err
@@ -0,0 +1 @@
+probe:12: command not found: curl
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/billing-status.code b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/billing-status.code
new file mode 100644
index 000000000..8f087a34c
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/billing-status.code
@@ -0,0 +1 @@
+000
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/billing-status.err b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/billing-status.err
new file mode 100644
index 000000000..a8b706ff2
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/billing-status.err
@@ -0,0 +1 @@
+probe:12: command not found: curl
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/checkout-empty.code b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/checkout-empty.code
new file mode 100644
index 000000000..8f087a34c
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/checkout-empty.code
@@ -0,0 +1 @@
+000
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/checkout-empty.err b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/checkout-empty.err
new file mode 100644
index 000000000..a8b706ff2
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/checkout-empty.err
@@ -0,0 +1 @@
+probe:12: command not found: curl
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/checkout-token.code b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/checkout-token.code
new file mode 100644
index 000000000..8f087a34c
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/checkout-token.code
@@ -0,0 +1 @@
+000
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/checkout-token.err b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/checkout-token.err
new file mode 100644
index 000000000..a8b706ff2
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/checkout-token.err
@@ -0,0 +1 @@
+probe:12: command not found: curl
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/meta.txt b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/meta.txt
new file mode 100644
index 000000000..c6945ec38
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/meta.txt
@@ -0,0 +1,6 @@
+UTC 2026-07-14T20:17:18Z
+git 64968c272
+base https://uvai.io
+webhook_id=we_1TtCYrPPnkyjEyFRKrZcElIB
+price_monthly=price_1TtCZXPPnkyjEyFR8dYmDo52
+price_annual=price_1TtCZYPPnkyjEyFRLMLPjmzE
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/renew-empty.code b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/renew-empty.code
new file mode 100644
index 000000000..8f087a34c
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/renew-empty.code
@@ -0,0 +1 @@
+000
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/renew-empty.err b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/renew-empty.err
new file mode 100644
index 000000000..a8b706ff2
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/renew-empty.err
@@ -0,0 +1 @@
+probe:12: command not found: curl
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/webhook-badsig.code b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/webhook-badsig.code
new file mode 100644
index 000000000..8f087a34c
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/webhook-badsig.code
@@ -0,0 +1 @@
+000
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/webhook-badsig.err b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/webhook-badsig.err
new file mode 100644
index 000000000..a8b706ff2
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/webhook-badsig.err
@@ -0,0 +1 @@
+probe:12: command not found: curl
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/webhook-empty.code b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/webhook-empty.code
new file mode 100644
index 000000000..8f087a34c
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/webhook-empty.code
@@ -0,0 +1 @@
+000
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/webhook-empty.err b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/webhook-empty.err
new file mode 100644
index 000000000..a8b706ff2
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/webhook-empty.err
@@ -0,0 +1 @@
+probe:12: command not found: curl
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/webhook-nosig.code b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/webhook-nosig.code
new file mode 100644
index 000000000..8f087a34c
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/webhook-nosig.code
@@ -0,0 +1 @@
+000
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/webhook-nosig.err b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/webhook-nosig.err
new file mode 100644
index 000000000..a8b706ff2
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/webhook-nosig.err
@@ -0,0 +1 @@
+probe:12: command not found: curl
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/REPORT.md b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/REPORT.md
new file mode 100644
index 000000000..a31798c90
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/REPORT.md
@@ -0,0 +1,37 @@
+# GATE-3 reprobe
+
+- session: `gate3-reprobe-20260714T201739Z`
+- git: `64968c272`
+- base: `https://uvai.io`
+
+| probe | HTTP | body (trunc) |
+|---|---|---|
+| activate-empty | 400 | `{"error":"session_id_required"}` |
+| auth-csrf | 200 | `{"csrfToken":"98f247abad03627d3d2d91b4ed243f6961b4ef5934fe3b64fe99a80899b3a03b"}` |
+| auth-providers | 200 | `{"google":{"id":"google","name":"Google","type":"oauth","signinUrl":"https://uvai.io/api/auth/signin/google","callbackUrl":"https://uvai.io/api/auth/callback/google"}}` |
+| auth-session | 200 | `{}` |
+| billing-status | 200 | `{"plan":"free","status":"inactive","email":null,"features":{"unlimitedChat":false,"agentDispatch":false,"apiAccess":false,"chatDailyLimit":5},"routing":{"model":"gpt-4o-mini","runt` |
+| checkout-empty | 403 | `{"error":"turnstile_token_missing"}` |
+| checkout-token | 403 | `{"error":"turnstile_verification_failed"}` |
+| renew-empty | 200 | `{"sessionId":"cs_test_a1ZyLqXsqlPHo9BacK21UQdd5vKvp1Pcrwxm2ZgMpqGQjGOz1Ilev1BNm4","url":"https://checkout.stripe.com/c/pay/cs_test_a1ZyLqXsqlPHo9BacK21UQdd5vKvp1Pcrwxm2ZgMpqGQjGOz1` |
+| webhook-badsig | 400 | `{"error":"No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe? \n If a webhook request is being forwarded` |
+| webhook-empty | 400 | `{"error":"missing_signature"}` |
+| webhook-nosig | 400 | `{"error":"missing_signature"}` |
+
+## Renew session (Stripe)
+
+```
+session mode=subscription status=open amount_total=1900 prices=['price_1TtCZXPPnkyjEyFR8dYmDo52']
+```
+
+## Pass criteria
+
+- **PASS** webhook secret live (no 503): HTTP 400 {"error":"missing_signature"}
+- **PASS** webhook rejects missing/bad sig: HTTP 400
+- **PASS** renew creates checkout session: HTTP 200
+- **PASS** renew not old price_1Tos02: {"sessionId":"cs_test_a1ZyLqXsqlPHo9BacK21UQdd5vKvp1Pcrwxm2ZgMpqGQjGOz1Ilev1BNm4","url":"https://checkout.stripe.com/c/p
+- **PASS** checkout empty turnstile gate: HTTP 403 {"error":"turnstile_token_missing"}
+- **PASS** auth providers 200: HTTP 200
+- **PASS** webhook badsig rejected: HTTP 400 {"error":"No signatures found matching the expected signature for payload. Are y
+
+## Overall: **PASS**
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/activate-empty.body b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/activate-empty.body
new file mode 100644
index 000000000..7a6650f58
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/activate-empty.body
@@ -0,0 +1 @@
+{"error":"session_id_required"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/activate-empty.code b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/activate-empty.code
new file mode 100644
index 000000000..6b3ed8d68
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/activate-empty.code
@@ -0,0 +1 @@
+400
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/activate-empty.err b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/activate-empty.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/activate-empty.headers b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/activate-empty.headers
new file mode 100644
index 000000000..a6dd1cde0
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/activate-empty.headers
@@ -0,0 +1,20 @@
+Cache-Control: public, max-age=0, must-revalidate
+Content-Security-Policy: default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; img-src 'self' data: blob: https://uvai.io https://api.uvai.io https://img.youtube.com https://i.ytimg.com https://*.ytimg.com; font-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://js.stripe.com https://va.vercel-scripts.com https://vitals.vercel-insights.com; connect-src 'self' https://api.uvai.io https://uvai-backend-gpwz4wb5na-uc.a.run.app https://api.openai.com https://generativelanguage.googleapis.com https://*.supabase.co wss://*.supabase.co https://*.upstash.io https://vitals.vercel-insights.com https://*.vercel-insights.com https://*.ingest.us.sentry.io https://*.ingest.sentry.io; frame-src 'self' https://www.youtube.com https://www.youtube-nocookie.com https://js.stripe.com https://hooks.stripe.com; media-src 'self' blob: data:; worker-src 'self' blob:; manifest-src 'self'; upgrade-insecure-requests
+Content-Type: application/json
+Date: Tue, 14 Jul 2026 20:17:43 GMT
+Permissions-Policy: camera=(), geolocation=(), microphone=(self), payment=(), usb=()
+Referrer-Policy: strict-origin-when-cross-origin
+Server: Vercel
+Set-Cookie: _vcrr_92d62cf3d9c75249=dpl_BcTB8nf1mrUZqvw9Pge8yySYZc3v|0.1965; Path=/; Secure; HttpOnly; SameSite=None
+Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
+X-Content-Type-Options: nosniff
+X-Dns-Prefetch-Control: on
+X-Frame-Options: DENY
+X-Matched-Path: /api/billing/activate
+X-Ratelimit-Limit: 60
+X-Ratelimit-Remaining: 60
+X-Ratelimit-Reset: 1784060324
+X-Vercel-Cache: MISS
+X-Vercel-Id: cle1::iad1::pk6w8-1784060263752-4c8525237cfb
+Connection: close
+Transfer-Encoding: chunked
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-csrf.body b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-csrf.body
new file mode 100644
index 000000000..10ef15864
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-csrf.body
@@ -0,0 +1 @@
+{"csrfToken":"98f247abad03627d3d2d91b4ed243f6961b4ef5934fe3b64fe99a80899b3a03b"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-csrf.code b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-csrf.code
new file mode 100644
index 000000000..ae4ee13c0
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-csrf.code
@@ -0,0 +1 @@
+200
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-csrf.err b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-csrf.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-csrf.headers b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-csrf.headers
new file mode 100644
index 000000000..b9147a3c0
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-csrf.headers
@@ -0,0 +1,23 @@
+Age: 0
+Cache-Control: private, no-cache, no-store
+Content-Security-Policy: default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; img-src 'self' data: blob: https://uvai.io https://api.uvai.io https://img.youtube.com https://i.ytimg.com https://*.ytimg.com; font-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://js.stripe.com https://va.vercel-scripts.com https://vitals.vercel-insights.com; connect-src 'self' https://api.uvai.io https://uvai-backend-gpwz4wb5na-uc.a.run.app https://api.openai.com https://generativelanguage.googleapis.com https://*.supabase.co wss://*.supabase.co https://*.upstash.io https://vitals.vercel-insights.com https://*.vercel-insights.com https://*.ingest.us.sentry.io https://*.ingest.sentry.io; frame-src 'self' https://www.youtube.com https://www.youtube-nocookie.com https://js.stripe.com https://hooks.stripe.com; media-src 'self' blob: data:; worker-src 'self' blob:; manifest-src 'self'; upgrade-insecure-requests
+Content-Type: application/json
+Date: Tue, 14 Jul 2026 20:17:45 GMT
+Expires: 0
+Permissions-Policy: camera=(), geolocation=(), microphone=(self), payment=(), usb=()
+Pragma: no-cache
+Referrer-Policy: strict-origin-when-cross-origin
+Server: Vercel
+Set-Cookie: _vcrr_92d62cf3d9c75249=dpl_BcTB8nf1mrUZqvw9Pge8yySYZc3v|0.1965; Path=/; Secure; HttpOnly; SameSite=None
+Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
+X-Content-Type-Options: nosniff
+X-Dns-Prefetch-Control: on
+X-Frame-Options: DENY
+X-Matched-Path: /api/auth/[...nextauth]
+X-Ratelimit-Limit: 60
+X-Ratelimit-Remaining: 60
+X-Ratelimit-Reset: 1784060326
+X-Vercel-Cache: MISS
+X-Vercel-Id: cle1::iad1::m92w2-1784060265161-4a18fe4a1c50
+Connection: close
+Transfer-Encoding: chunked
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-providers.body b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-providers.body
new file mode 100644
index 000000000..8ddf0c983
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-providers.body
@@ -0,0 +1 @@
+{"google":{"id":"google","name":"Google","type":"oauth","signinUrl":"https://uvai.io/api/auth/signin/google","callbackUrl":"https://uvai.io/api/auth/callback/google"}}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-providers.code b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-providers.code
new file mode 100644
index 000000000..ae4ee13c0
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-providers.code
@@ -0,0 +1 @@
+200
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-providers.err b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-providers.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-providers.headers b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-providers.headers
new file mode 100644
index 000000000..d7f0b1cb1
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-providers.headers
@@ -0,0 +1,21 @@
+Age: 0
+Cache-Control: public, max-age=0, must-revalidate
+Content-Security-Policy: default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; img-src 'self' data: blob: https://uvai.io https://api.uvai.io https://img.youtube.com https://i.ytimg.com https://*.ytimg.com; font-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://js.stripe.com https://va.vercel-scripts.com https://vitals.vercel-insights.com; connect-src 'self' https://api.uvai.io https://uvai-backend-gpwz4wb5na-uc.a.run.app https://api.openai.com https://generativelanguage.googleapis.com https://*.supabase.co wss://*.supabase.co https://*.upstash.io https://vitals.vercel-insights.com https://*.vercel-insights.com https://*.ingest.us.sentry.io https://*.ingest.sentry.io; frame-src 'self' https://www.youtube.com https://www.youtube-nocookie.com https://js.stripe.com https://hooks.stripe.com; media-src 'self' blob: data:; worker-src 'self' blob:; manifest-src 'self'; upgrade-insecure-requests
+Content-Type: application/json
+Date: Tue, 14 Jul 2026 20:17:44 GMT
+Permissions-Policy: camera=(), geolocation=(), microphone=(self), payment=(), usb=()
+Referrer-Policy: strict-origin-when-cross-origin
+Server: Vercel
+Set-Cookie: _vcrr_92d62cf3d9c75249=dpl_BcTB8nf1mrUZqvw9Pge8yySYZc3v|0.1965; Path=/; Secure; HttpOnly; SameSite=None
+Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
+X-Content-Type-Options: nosniff
+X-Dns-Prefetch-Control: on
+X-Frame-Options: DENY
+X-Matched-Path: /api/auth/[...nextauth]
+X-Ratelimit-Limit: 60
+X-Ratelimit-Remaining: 60
+X-Ratelimit-Reset: 1784060325
+X-Vercel-Cache: MISS
+X-Vercel-Id: cle1::iad1::zbbfr-1784060264654-eb637874cf2a
+Connection: close
+Transfer-Encoding: chunked
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-session.body b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-session.body
new file mode 100644
index 000000000..9e26dfeeb
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-session.body
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-session.code b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-session.code
new file mode 100644
index 000000000..ae4ee13c0
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-session.code
@@ -0,0 +1 @@
+200
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-session.err b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-session.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-session.headers b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-session.headers
new file mode 100644
index 000000000..5eb72aaca
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-session.headers
@@ -0,0 +1,23 @@
+Age: 0
+Cache-Control: private, no-cache, no-store
+Content-Security-Policy: default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; img-src 'self' data: blob: https://uvai.io https://api.uvai.io https://img.youtube.com https://i.ytimg.com https://*.ytimg.com; font-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://js.stripe.com https://va.vercel-scripts.com https://vitals.vercel-insights.com; connect-src 'self' https://api.uvai.io https://uvai-backend-gpwz4wb5na-uc.a.run.app https://api.openai.com https://generativelanguage.googleapis.com https://*.supabase.co wss://*.supabase.co https://*.upstash.io https://vitals.vercel-insights.com https://*.vercel-insights.com https://*.ingest.us.sentry.io https://*.ingest.sentry.io; frame-src 'self' https://www.youtube.com https://www.youtube-nocookie.com https://js.stripe.com https://hooks.stripe.com; media-src 'self' blob: data:; worker-src 'self' blob:; manifest-src 'self'; upgrade-insecure-requests
+Content-Type: application/json
+Date: Tue, 14 Jul 2026 20:17:45 GMT
+Expires: 0
+Permissions-Policy: camera=(), geolocation=(), microphone=(self), payment=(), usb=()
+Pragma: no-cache
+Referrer-Policy: strict-origin-when-cross-origin
+Server: Vercel
+Set-Cookie: _vcrr_92d62cf3d9c75249=dpl_BcTB8nf1mrUZqvw9Pge8yySYZc3v|0.1965; Path=/; Secure; HttpOnly; SameSite=None
+Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
+X-Content-Type-Options: nosniff
+X-Dns-Prefetch-Control: on
+X-Frame-Options: DENY
+X-Matched-Path: /api/auth/[...nextauth]
+X-Ratelimit-Limit: 60
+X-Ratelimit-Remaining: 60
+X-Ratelimit-Reset: 1784060326
+X-Vercel-Cache: MISS
+X-Vercel-Id: cle1::iad1::4s8dg-1784060265553-a4af234b4cc5
+Connection: close
+Transfer-Encoding: chunked
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/billing-status.body b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/billing-status.body
new file mode 100644
index 000000000..80aea7551
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/billing-status.body
@@ -0,0 +1 @@
+{"plan":"free","status":"inactive","email":null,"features":{"unlimitedChat":false,"agentDispatch":false,"apiAccess":false,"chatDailyLimit":5},"routing":{"model":"gpt-4o-mini","runtime":"standard","plan":"free"},"renewalEligible":false}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/billing-status.code b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/billing-status.code
new file mode 100644
index 000000000..ae4ee13c0
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/billing-status.code
@@ -0,0 +1 @@
+200
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/billing-status.err b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/billing-status.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/billing-status.headers b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/billing-status.headers
new file mode 100644
index 000000000..696545aea
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/billing-status.headers
@@ -0,0 +1,21 @@
+Age: 0
+Cache-Control: public, max-age=0, must-revalidate
+Content-Security-Policy: default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; img-src 'self' data: blob: https://uvai.io https://api.uvai.io https://img.youtube.com https://i.ytimg.com https://*.ytimg.com; font-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://js.stripe.com https://va.vercel-scripts.com https://vitals.vercel-insights.com; connect-src 'self' https://api.uvai.io https://uvai-backend-gpwz4wb5na-uc.a.run.app https://api.openai.com https://generativelanguage.googleapis.com https://*.supabase.co wss://*.supabase.co https://*.upstash.io https://vitals.vercel-insights.com https://*.vercel-insights.com https://*.ingest.us.sentry.io https://*.ingest.sentry.io; frame-src 'self' https://www.youtube.com https://www.youtube-nocookie.com https://js.stripe.com https://hooks.stripe.com; media-src 'self' blob: data:; worker-src 'self' blob:; manifest-src 'self'; upgrade-insecure-requests
+Content-Type: application/json
+Date: Tue, 14 Jul 2026 20:17:44 GMT
+Permissions-Policy: camera=(), geolocation=(), microphone=(self), payment=(), usb=()
+Referrer-Policy: strict-origin-when-cross-origin
+Server: Vercel
+Set-Cookie: _vcrr_92d62cf3d9c75249=dpl_BcTB8nf1mrUZqvw9Pge8yySYZc3v|0.1965; Path=/; Secure; HttpOnly; SameSite=None
+Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
+X-Content-Type-Options: nosniff
+X-Dns-Prefetch-Control: on
+X-Frame-Options: DENY
+X-Matched-Path: /api/billing/status
+X-Ratelimit-Limit: 60
+X-Ratelimit-Remaining: 60
+X-Ratelimit-Reset: 1784060325
+X-Vercel-Cache: MISS
+X-Vercel-Id: cle1::iad1::zlr2v-1784060264213-1adeb0ed2902
+Connection: close
+Transfer-Encoding: chunked
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-empty.body b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-empty.body
new file mode 100644
index 000000000..76f33dd52
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-empty.body
@@ -0,0 +1 @@
+{"error":"turnstile_token_missing"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-empty.code b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-empty.code
new file mode 100644
index 000000000..cdf1f34dc
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-empty.code
@@ -0,0 +1 @@
+403
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-empty.err b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-empty.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-empty.headers b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-empty.headers
new file mode 100644
index 000000000..c5baf6e00
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-empty.headers
@@ -0,0 +1,20 @@
+Cache-Control: public, max-age=0, must-revalidate
+Content-Security-Policy: default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; img-src 'self' data: blob: https://uvai.io https://api.uvai.io https://img.youtube.com https://i.ytimg.com https://*.ytimg.com; font-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://js.stripe.com https://va.vercel-scripts.com https://vitals.vercel-insights.com; connect-src 'self' https://api.uvai.io https://uvai-backend-gpwz4wb5na-uc.a.run.app https://api.openai.com https://generativelanguage.googleapis.com https://*.supabase.co wss://*.supabase.co https://*.upstash.io https://vitals.vercel-insights.com https://*.vercel-insights.com https://*.ingest.us.sentry.io https://*.ingest.sentry.io; frame-src 'self' https://www.youtube.com https://www.youtube-nocookie.com https://js.stripe.com https://hooks.stripe.com; media-src 'self' blob: data:; worker-src 'self' blob:; manifest-src 'self'; upgrade-insecure-requests
+Content-Type: application/json
+Date: Tue, 14 Jul 2026 20:17:42 GMT
+Permissions-Policy: camera=(), geolocation=(), microphone=(self), payment=(), usb=()
+Referrer-Policy: strict-origin-when-cross-origin
+Server: Vercel
+Set-Cookie: _vcrr_92d62cf3d9c75249=dpl_BcTB8nf1mrUZqvw9Pge8yySYZc3v|0.1965; Path=/; Secure; HttpOnly; SameSite=None
+Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
+X-Content-Type-Options: nosniff
+X-Dns-Prefetch-Control: on
+X-Frame-Options: DENY
+X-Matched-Path: /api/billing/checkout
+X-Ratelimit-Limit: 60
+X-Ratelimit-Remaining: 60
+X-Ratelimit-Reset: 1784060323
+X-Vercel-Cache: MISS
+X-Vercel-Id: cle1::iad1::dlchh-1784060262810-97b59fde56d6
+Connection: close
+Transfer-Encoding: chunked
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-token.body b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-token.body
new file mode 100644
index 000000000..633b081cd
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-token.body
@@ -0,0 +1 @@
+{"error":"turnstile_verification_failed"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-token.code b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-token.code
new file mode 100644
index 000000000..cdf1f34dc
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-token.code
@@ -0,0 +1 @@
+403
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-token.err b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-token.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-token.headers b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-token.headers
new file mode 100644
index 000000000..c4509f6ad
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-token.headers
@@ -0,0 +1,20 @@
+Cache-Control: public, max-age=0, must-revalidate
+Content-Security-Policy: default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; img-src 'self' data: blob: https://uvai.io https://api.uvai.io https://img.youtube.com https://i.ytimg.com https://*.ytimg.com; font-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://js.stripe.com https://va.vercel-scripts.com https://vitals.vercel-insights.com; connect-src 'self' https://api.uvai.io https://uvai-backend-gpwz4wb5na-uc.a.run.app https://api.openai.com https://generativelanguage.googleapis.com https://*.supabase.co wss://*.supabase.co https://*.upstash.io https://vitals.vercel-insights.com https://*.vercel-insights.com https://*.ingest.us.sentry.io https://*.ingest.sentry.io; frame-src 'self' https://www.youtube.com https://www.youtube-nocookie.com https://js.stripe.com https://hooks.stripe.com; media-src 'self' blob: data:; worker-src 'self' blob:; manifest-src 'self'; upgrade-insecure-requests
+Content-Type: application/json
+Date: Tue, 14 Jul 2026 20:17:43 GMT
+Permissions-Policy: camera=(), geolocation=(), microphone=(self), payment=(), usb=()
+Referrer-Policy: strict-origin-when-cross-origin
+Server: Vercel
+Set-Cookie: _vcrr_92d62cf3d9c75249=dpl_BcTB8nf1mrUZqvw9Pge8yySYZc3v|0.1965; Path=/; Secure; HttpOnly; SameSite=None
+Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
+X-Content-Type-Options: nosniff
+X-Dns-Prefetch-Control: on
+X-Frame-Options: DENY
+X-Matched-Path: /api/billing/checkout
+X-Ratelimit-Limit: 60
+X-Ratelimit-Remaining: 60
+X-Ratelimit-Reset: 1784060324
+X-Vercel-Cache: MISS
+X-Vercel-Id: cle1::iad1::8g68g-1784060263241-70d57cda8d7e
+Connection: close
+Transfer-Encoding: chunked
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/meta.txt b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/meta.txt
new file mode 100644
index 000000000..4d758b02c
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/meta.txt
@@ -0,0 +1,6 @@
+UTC 2026-07-14T20:17:39Z
+git 64968c272
+base https://uvai.io
+webhook_id=we_1TtCYrPPnkyjEyFRKrZcElIB
+price_monthly=price_1TtCZXPPnkyjEyFR8dYmDo52
+price_annual=price_1TtCZYPPnkyjEyFRLMLPjmzE
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/renew-empty.body b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/renew-empty.body
new file mode 100644
index 000000000..3046fb6f7
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/renew-empty.body
@@ -0,0 +1 @@
+{"sessionId":"cs_test_a1ZyLqXsqlPHo9BacK21UQdd5vKvp1Pcrwxm2ZgMpqGQjGOz1Ilev1BNm4","url":"https://checkout.stripe.com/c/pay/cs_test_a1ZyLqXsqlPHo9BacK21UQdd5vKvp1Pcrwxm2ZgMpqGQjGOz1Ilev1BNm4#fidnandhYHdWcXxpYCc%2FJ2FgY2RwaXEnKSdicGRmZGhqaWBTZHdsZGtxJz8nZmprcXdqaScpJ2R1bE5gfCc%2FJ3VuWnFgdnFaMDRWZkh3cFVVa258b0B8Q1dRUERATHxEa0tLSzdDMWhwd31hXGtAMklmSGQ3f0A1THNISkB3aDx0U0ZrQGRHMERvcFRGbmZ0VDxtTDNwXUZzf0ZNUnVKMEI1NWpEQ1FibmpJJyknY3dqaFZgd3Ngdyc%2FcXdwYCknZ2RmbmJ3anBrYUZqaWp3Jz8nJmNjY2NjYycpJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYHgl"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/renew-empty.code b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/renew-empty.code
new file mode 100644
index 000000000..ae4ee13c0
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/renew-empty.code
@@ -0,0 +1 @@
+200
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/renew-empty.err b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/renew-empty.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/renew-empty.headers b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/renew-empty.headers
new file mode 100644
index 000000000..912544249
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/renew-empty.headers
@@ -0,0 +1,20 @@
+Cache-Control: public, max-age=0, must-revalidate
+Content-Security-Policy: default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; img-src 'self' data: blob: https://uvai.io https://api.uvai.io https://img.youtube.com https://i.ytimg.com https://*.ytimg.com; font-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://js.stripe.com https://va.vercel-scripts.com https://vitals.vercel-insights.com; connect-src 'self' https://api.uvai.io https://uvai-backend-gpwz4wb5na-uc.a.run.app https://api.openai.com https://generativelanguage.googleapis.com https://*.supabase.co wss://*.supabase.co https://*.upstash.io https://vitals.vercel-insights.com https://*.vercel-insights.com https://*.ingest.us.sentry.io https://*.ingest.sentry.io; frame-src 'self' https://www.youtube.com https://www.youtube-nocookie.com https://js.stripe.com https://hooks.stripe.com; media-src 'self' blob: data:; worker-src 'self' blob:; manifest-src 'self'; upgrade-insecure-requests
+Content-Type: application/json
+Date: Tue, 14 Jul 2026 20:17:42 GMT
+Permissions-Policy: camera=(), geolocation=(), microphone=(self), payment=(), usb=()
+Referrer-Policy: strict-origin-when-cross-origin
+Server: Vercel
+Set-Cookie: _vcrr_92d62cf3d9c75249=dpl_BcTB8nf1mrUZqvw9Pge8yySYZc3v|0.1965; Path=/; Secure; HttpOnly; SameSite=None
+Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
+X-Content-Type-Options: nosniff
+X-Dns-Prefetch-Control: on
+X-Frame-Options: DENY
+X-Matched-Path: /api/billing/renew
+X-Ratelimit-Limit: 60
+X-Ratelimit-Remaining: 60
+X-Ratelimit-Reset: 1784060322
+X-Vercel-Cache: MISS
+X-Vercel-Id: cle1::iad1::rqh2f-1784060261909-53a9ea8ec7ee
+Connection: close
+Transfer-Encoding: chunked
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/renew-session-stripe.txt b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/renew-session-stripe.txt
new file mode 100644
index 000000000..8700b3ed5
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/renew-session-stripe.txt
@@ -0,0 +1 @@
+session mode=subscription status=open amount_total=1900 prices=['price_1TtCZXPPnkyjEyFR8dYmDo52']
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-badsig.body b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-badsig.body
new file mode 100644
index 000000000..7ef71bb82
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-badsig.body
@@ -0,0 +1 @@
+{"error":"No signatures found matching the expected signature for payload. Are you passing the raw request body you received from Stripe? \n If a webhook request is being forwarded by a third-party tool, ensure that the exact request body, including JSON formatting and new line style, is preserved.\n\nLearn more about webhook signing and explore webhook integration examples for various frameworks at https://docs.stripe.com/webhooks/signature\n"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-badsig.code b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-badsig.code
new file mode 100644
index 000000000..6b3ed8d68
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-badsig.code
@@ -0,0 +1 @@
+400
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-badsig.err b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-badsig.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-badsig.headers b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-badsig.headers
new file mode 100644
index 000000000..f07b153e8
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-badsig.headers
@@ -0,0 +1,20 @@
+Cache-Control: public, max-age=0, must-revalidate
+Content-Security-Policy: default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; img-src 'self' data: blob: https://uvai.io https://api.uvai.io https://img.youtube.com https://i.ytimg.com https://*.ytimg.com; font-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://js.stripe.com https://va.vercel-scripts.com https://vitals.vercel-insights.com; connect-src 'self' https://api.uvai.io https://uvai-backend-gpwz4wb5na-uc.a.run.app https://api.openai.com https://generativelanguage.googleapis.com https://*.supabase.co wss://*.supabase.co https://*.upstash.io https://vitals.vercel-insights.com https://*.vercel-insights.com https://*.ingest.us.sentry.io https://*.ingest.sentry.io; frame-src 'self' https://www.youtube.com https://www.youtube-nocookie.com https://js.stripe.com https://hooks.stripe.com; media-src 'self' blob: data:; worker-src 'self' blob:; manifest-src 'self'; upgrade-insecure-requests
+Content-Type: application/json
+Date: Tue, 14 Jul 2026 20:17:41 GMT
+Permissions-Policy: camera=(), geolocation=(), microphone=(self), payment=(), usb=()
+Referrer-Policy: strict-origin-when-cross-origin
+Server: Vercel
+Set-Cookie: _vcrr_92d62cf3d9c75249=dpl_BcTB8nf1mrUZqvw9Pge8yySYZc3v|0.1965; Path=/; Secure; HttpOnly; SameSite=None
+Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
+X-Content-Type-Options: nosniff
+X-Dns-Prefetch-Control: on
+X-Frame-Options: DENY
+X-Matched-Path: /api/billing/webhook
+X-Ratelimit-Limit: 60
+X-Ratelimit-Remaining: 60
+X-Ratelimit-Reset: 1784060322
+X-Vercel-Cache: MISS
+X-Vercel-Id: cle1::iad1::xgx58-1784060261418-80d5ec965bca
+Connection: close
+Transfer-Encoding: chunked
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-empty.body b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-empty.body
new file mode 100644
index 000000000..1e54157c4
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-empty.body
@@ -0,0 +1 @@
+{"error":"missing_signature"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-empty.code b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-empty.code
new file mode 100644
index 000000000..6b3ed8d68
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-empty.code
@@ -0,0 +1 @@
+400
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-empty.err b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-empty.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-empty.headers b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-empty.headers
new file mode 100644
index 000000000..be3b4e1ba
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-empty.headers
@@ -0,0 +1,20 @@
+Cache-Control: public, max-age=0, must-revalidate
+Content-Security-Policy: default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; img-src 'self' data: blob: https://uvai.io https://api.uvai.io https://img.youtube.com https://i.ytimg.com https://*.ytimg.com; font-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://js.stripe.com https://va.vercel-scripts.com https://vitals.vercel-insights.com; connect-src 'self' https://api.uvai.io https://uvai-backend-gpwz4wb5na-uc.a.run.app https://api.openai.com https://generativelanguage.googleapis.com https://*.supabase.co wss://*.supabase.co https://*.upstash.io https://vitals.vercel-insights.com https://*.vercel-insights.com https://*.ingest.us.sentry.io https://*.ingest.sentry.io; frame-src 'self' https://www.youtube.com https://www.youtube-nocookie.com https://js.stripe.com https://hooks.stripe.com; media-src 'self' blob: data:; worker-src 'self' blob:; manifest-src 'self'; upgrade-insecure-requests
+Content-Type: application/json
+Date: Tue, 14 Jul 2026 20:17:40 GMT
+Permissions-Policy: camera=(), geolocation=(), microphone=(self), payment=(), usb=()
+Referrer-Policy: strict-origin-when-cross-origin
+Server: Vercel
+Set-Cookie: _vcrr_92d62cf3d9c75249=dpl_BcTB8nf1mrUZqvw9Pge8yySYZc3v|0.1965; Path=/; Secure; HttpOnly; SameSite=None
+Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
+X-Content-Type-Options: nosniff
+X-Dns-Prefetch-Control: on
+X-Frame-Options: DENY
+X-Matched-Path: /api/billing/webhook
+X-Ratelimit-Limit: 60
+X-Ratelimit-Remaining: 60
+X-Ratelimit-Reset: 1784060321
+X-Vercel-Cache: MISS
+X-Vercel-Id: cle1::iad1::dd5zl-1784060260359-67d0117c5de7
+Connection: close
+Transfer-Encoding: chunked
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-nosig.body b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-nosig.body
new file mode 100644
index 000000000..1e54157c4
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-nosig.body
@@ -0,0 +1 @@
+{"error":"missing_signature"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-nosig.code b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-nosig.code
new file mode 100644
index 000000000..6b3ed8d68
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-nosig.code
@@ -0,0 +1 @@
+400
\ No newline at end of file
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-nosig.err b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-nosig.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-nosig.headers b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-nosig.headers
new file mode 100644
index 000000000..f50c1caf2
--- /dev/null
+++ b/docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-nosig.headers
@@ -0,0 +1,20 @@
+Cache-Control: public, max-age=0, must-revalidate
+Content-Security-Policy: default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; img-src 'self' data: blob: https://uvai.io https://api.uvai.io https://img.youtube.com https://i.ytimg.com https://*.ytimg.com; font-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://js.stripe.com https://va.vercel-scripts.com https://vitals.vercel-insights.com; connect-src 'self' https://api.uvai.io https://uvai-backend-gpwz4wb5na-uc.a.run.app https://api.openai.com https://generativelanguage.googleapis.com https://*.supabase.co wss://*.supabase.co https://*.upstash.io https://vitals.vercel-insights.com https://*.vercel-insights.com https://*.ingest.us.sentry.io https://*.ingest.sentry.io; frame-src 'self' https://www.youtube.com https://www.youtube-nocookie.com https://js.stripe.com https://hooks.stripe.com; media-src 'self' blob: data:; worker-src 'self' blob:; manifest-src 'self'; upgrade-insecure-requests
+Content-Type: application/json
+Date: Tue, 14 Jul 2026 20:17:41 GMT
+Permissions-Policy: camera=(), geolocation=(), microphone=(self), payment=(), usb=()
+Referrer-Policy: strict-origin-when-cross-origin
+Server: Vercel
+Set-Cookie: _vcrr_92d62cf3d9c75249=dpl_BcTB8nf1mrUZqvw9Pge8yySYZc3v|0.1965; Path=/; Secure; HttpOnly; SameSite=None
+Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
+X-Content-Type-Options: nosniff
+X-Dns-Prefetch-Control: on
+X-Frame-Options: DENY
+X-Matched-Path: /api/billing/webhook
+X-Ratelimit-Limit: 60
+X-Ratelimit-Remaining: 60
+X-Ratelimit-Reset: 1784060321
+X-Vercel-Cache: MISS
+X-Vercel-Id: cle1::iad1::glndz-1784060260959-c2bfb54d7955
+Connection: close
+Transfer-Encoding: chunked
\ No newline at end of file
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/auth-providers.body b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/auth-providers.body
new file mode 100644
index 000000000..270a43699
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/auth-providers.body
@@ -0,0 +1 @@
+{"message":"There is a problem with the server configuration. Check the server logs for more information."}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/auth-providers.code b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/auth-providers.code
new file mode 100644
index 000000000..1b79f38e2
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/auth-providers.code
@@ -0,0 +1 @@
+500
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/auth-providers.err b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/auth-providers.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/checkout.body b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/checkout.body
new file mode 100644
index 000000000..c579b087f
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/checkout.body
@@ -0,0 +1 @@
+{"error":"turnstile_not_configured"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/checkout.code b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/checkout.code
new file mode 100644
index 000000000..e1a29c1fe
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/checkout.code
@@ -0,0 +1 @@
+403
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/checkout.err b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/checkout.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-api.body b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-api.body
new file mode 100644
index 000000000..c62ccf696
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-api.body
@@ -0,0 +1 @@
+{"status":"healthy","timestamp":"2026-07-10T18:22:27.812660","version":"2.0.0","components":{"video_processor":"available","websocket":"available","gemini_key_present":true,"youtube_api_key_present":true}}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-api.code b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-api.code
new file mode 100644
index 000000000..08839f6bb
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-api.code
@@ -0,0 +1 @@
+200
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-api.err b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-api.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-home.body b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-home.body
new file mode 100644
index 000000000..8818fa193
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-home.body
@@ -0,0 +1 @@
+UVAI — Video to Workflow
\ No newline at end of file
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-home.code b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-home.code
new file mode 100644
index 000000000..ae4cf41b2
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-home.code
@@ -0,0 +1 @@
+307
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-home.err b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-home.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-pipeline-get.body b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-pipeline-get.body
new file mode 100644
index 000000000..1fca239e0
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-pipeline-get.body
@@ -0,0 +1 @@
+{"name":"EventRelay End-to-End Pipeline","version":"1.0.0","description":"YouTube URL → Video Analysis → Code Generation → Deployment → Live URL","pipeline_stages":["1. Ingest: Gemini analyzes video content with Google Search grounding","2. Translate: Structured output → VideoPack artifact","3. Transport: CloudEvents published at each stage","4. Execute: Agents generate code, create repo, deploy to Vercel"],"backend_configured":true,"backend_available":true,"backend_host":"eventrelay-api-gpwz4wb5na-uc.a.run.app","gemini_available":true,"gemini_mode":"gateway","gemini_routing":"gateway:google/gemini-2.5-flash","endpoints":{"pipeline":"POST /api/pipeline - Full end-to-end pipeline","video":"POST /api/video - Video analysis only","stream":"POST /api/pipeline/stream - SSE agent visualization"}}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-pipeline-get.code b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-pipeline-get.code
new file mode 100644
index 000000000..08839f6bb
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-pipeline-get.code
@@ -0,0 +1 @@
+200
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-pipeline-get.err b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-pipeline-get.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/meta.txt b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/meta.txt
new file mode 100644
index 000000000..62fa2aeb2
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/meta.txt
@@ -0,0 +1,2 @@
+UTC 2026-07-10T18:22:25Z
+local main bf710a99
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-dash.body b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-dash.body
new file mode 100644
index 000000000..debc8d11a
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-dash.body
@@ -0,0 +1 @@
+{"id":"pipeline_mrf9k166","status":"partial","pipeline":"transcript-only","degraded":true,"gemini_error":{"code":"TIMEOUT","message":"Gemini analysis timed out","userMessage":"Gemini analysis timed out before completing."},"backend":{"configured":true,"available":true,"host":"eventrelay-api-gpwz4wb5na-uc.a.run.app"},"result":{"live_url":null,"github_repo":null,"build_status":"analysis_blocked","video_analysis":{"title":"Transcript captured — AI analysis unavailable","summary":"Fetched 38 words from the video source, but Gemini could not run structured analysis (TIMEOUT).","events":[{"type":"source","title":"Transcript captured","description":"38 words via gemini-search","confidence":0.9},{"type":"configuration","title":"Gemini analysis blocked","description":"Gemini analysis timed out before completing.","confidence":1}],"actions":[],"topics":[],"architectureCode":"","transcript_preview":"I am unable to process the request because the provided URL `--config-locations=/aaaaaaaaaaa` is not a valid YouTube video URL.\n\nPlease provide a correct and accessible YouTube video URL so I can retrieve the transcript, description, and chapter content."},"code_generation":null,"deployment":null,"message":"Gemini analysis timed out before completing."}}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-dash.code b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-dash.code
new file mode 100644
index 000000000..08839f6bb
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-dash.code
@@ -0,0 +1 @@
+200
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-dash.err b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-dash.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-evil.body b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-evil.body
new file mode 100644
index 000000000..9be11a718
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-evil.body
@@ -0,0 +1 @@
+{"id":"pipeline_mrf9k9ad","status":"partial","pipeline":"gemini-only","processing_time":"10.0s","result":{"live_url":null,"github_repo":null,"build_status":"not_attempted","video_analysis":{"title":"Video Analysis Failed: Invalid URL Provided","summary":"The provided video URL `https://evil.example/watch?v=aaaaaaaaaaa` is an invalid placeholder. As a result, the video content, transcript, description, and chapter information could not be accessed. Therefore, a comprehensive analysis, including the extraction of technical events, generation of code, or mapping to E22 solutions, cannot be performed.","events":[{"timestamp":"N/A","label":"Video Access Failure","description":"The primary event is the inability to access the video content due to an invalid URL. No technical events from a video could be extracted.","codeMapping":"N/A - No video content to map."}],"actions":[{"label":"Provide a Valid URL","description":"To proceed with video analysis, please provide a valid and accessible YouTube video URL.","codeMapping":"N/A"}],"topics":["Video Analysis Limitations","Invalid URL Handling","Agentic Grounding Constraints"],"architectureCode":"```markdown\n# Architecture Blueprint: N/A\n\nNo architecture blueprint can be generated as the video content could not be accessed. The provided URL was invalid.\n```"},"code_generation":null,"deployment":null,"message":"Backend pipeline unavailable. Video analysis complete but code generation and deployment require the Python backend."}}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-evil.code b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-evil.code
new file mode 100644
index 000000000..08839f6bb
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-evil.code
@@ -0,0 +1 @@
+200
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-evil.err b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-evil.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-ok.body b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-ok.body
new file mode 100644
index 000000000..99abded12
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-ok.body
@@ -0,0 +1 @@
+{"id":"job_868ebdafce","status":"pending","pipeline":"backend-async","async_processing":true,"job_id":"job_868ebdafce","status_url":"/api/jobs/job_868ebdafce"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-ok.code b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-ok.code
new file mode 100644
index 000000000..08839f6bb
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-ok.code
@@ -0,0 +1 @@
+200
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-ok.err b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-ok.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-ssrf.body b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-ssrf.body
new file mode 100644
index 000000000..496234ce6
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-ssrf.body
@@ -0,0 +1 @@
+{"id":"pipeline_mrf9jo26","status":"partial","pipeline":"gemini-only","processing_time":"10.7s","result":{"live_url":null,"github_repo":null,"build_status":"not_attempted","video_analysis":{"title":"Invalid Video URL Provided: Unable to Process Video Content","summary":"The provided URL `http://169.254.169.254/aaaaaaaaaaa` is not a valid YouTube video URL. It points to a link-local IP address (commonly used for internal network communication or cloud instance metadata access), not a public video hosting service. Consequently, no video content, transcript, or metadata could be accessed or analyzed. This response reflects the inability to fulfill the request due to the invalid source URL.","events":[],"actions":[{"label":"Provide a Valid YouTube URL","description":"To receive assistance, ensure the provided URL points to an actual YouTube video (e.g., `https://www.youtube.com/watch?v=VIDEO_ID`).","codeMapping":null}],"topics":["Invalid URL","Link-local IP addresses","YouTube URL format","Cloud instance metadata (AWS EC2 example)"],"architectureCode":null},"code_generation":null,"deployment":null,"message":"Backend pipeline unavailable. Video analysis complete but code generation and deployment require the Python backend."}}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-ssrf.code b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-ssrf.code
new file mode 100644
index 000000000..08839f6bb
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-ssrf.code
@@ -0,0 +1 @@
+200
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-ssrf.err b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-ssrf.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/veo-free.body b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/veo-free.body
new file mode 100644
index 000000000..a01b28299
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/veo-free.body
@@ -0,0 +1 @@
+{"error":"Video generation is a Pro feature. Upgrade at /pricing.","upgradeRequired":true,"plan":"free"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/veo-free.code b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/veo-free.code
new file mode 100644
index 000000000..52f22458d
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/veo-free.code
@@ -0,0 +1 @@
+402
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/veo-free.err b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/veo-free.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/vercel-prod-ls.txt b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/vercel-prod-ls.txt
new file mode 100644
index 000000000..187ee7da8
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/vercel-prod-ls.txt
@@ -0,0 +1,15 @@
+Fetching deployments in garv1
+> Production deployments for garv1/v0-uvai [183ms]
+
+ Age Project Deployment Status Environment Duration Username
+ 47s garv1/v0-uvai https://v0-uvai-n2hhek9ky-garv1.vercel.app ● Building Production -- ultrathinking
+ 2d garv1/v0-uvai https://v0-uvai-kor41h06r-garv1.vercel.app ● Ready Production 1m ultrathinking
+ 2d garv1/v0-uvai https://v0-uvai-nt5gyla6c-garv1.vercel.app ● Ready Production 1m ultrathinking
+ 2d garv1/v0-uvai https://v0-uvai-o157vyvyg-garv1.vercel.app ● Ready Production 1m ultrathinking
+ 2d garv1/v0-uvai https://v0-uvai-9m7pbeath-garv1.vercel.app ● Ready Production 1m ultrathinking
+ 2d garv1/v0-uvai https://v0-uvai-b1xn8nncl-garv1.vercel.app ● Ready Production 1m ultrathinking
+ 2d garv1/v0-uvai https://v0-uvai-cjbtycux7-garv1.vercel.app ● Ready Production 1m ultrathinking
+ 2d garv1/v0-uvai https://v0-uvai-7m6sgivad-garv1.vercel.app ● Ready Production 1m ultrathinking
+ 2d garv1/v0-uvai https://v0-uvai-nyuladrfq-garv1.vercel.app ● Ready Production 1m ultrathinking
+ 2d garv1/v0-uvai https://v0-uvai-12iqhx1ja-garv1.vercel.app ● Ready Production 57s ultrathinking
+ 2d garv1/v0-uvai https://v0-uvai-eci8v2sp0-garv1.vercel.app ● Ready Production 1m ultrathinking
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/video-ssrf.body b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/video-ssrf.body
new file mode 100644
index 000000000..7a8c4c680
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/video-ssrf.body
@@ -0,0 +1 @@
+{"id":"vid_mrf9kf28","status":"failed","processing_time_ms":0,"result":{"success":false,"insights":{"summary":"Could not extract transcript — configure GEMINI_API_KEY","actions":[],"topics":[],"sentiment":"Neutral"},"transcript_segments":0,"transcript_source":"none","agents_used":["frontend-pipeline"],"errors":["All strategies failed — ensure GEMINI_API_KEY is set"],"raw_response":{"transcript":{"text":""},"extraction":{}}}}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/video-ssrf.code b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/video-ssrf.code
new file mode 100644
index 000000000..08839f6bb
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/video-ssrf.code
@@ -0,0 +1 @@
+200
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/video-ssrf.err b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/video-ssrf.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/webhook.body b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/webhook.body
new file mode 100644
index 000000000..f42efedd6
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/webhook.body
@@ -0,0 +1 @@
+{"error":"webhook_not_configured"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/webhook.code b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/webhook.code
new file mode 100644
index 000000000..a712e7640
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/webhook.code
@@ -0,0 +1 @@
+503
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/webhook.err b/docs/control-plane/sessions/reprobe-prod-20260710T1822Z/webhook.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1828Z/REPORT.md b/docs/control-plane/sessions/reprobe-prod-20260710T1828Z/REPORT.md
new file mode 100644
index 000000000..0c8a3d167
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1828Z/REPORT.md
@@ -0,0 +1,110 @@
+# Production re-probe after PR #654 merge
+
+**When:** 2026-07-10T18:22Z – 18:29Z UTC
+**Merged:** `bf710a99` (PR #654 GATE-4)
+**Vercel prod deploy:** `v0-uvai-n2hhek9ky-garv1.vercel.app` → Ready ~18:27Z
+**Aliases on that deploy:** `v0-uvai-garv1.vercel.app`, `v0-uvai-git-main-garv1.vercel.app`
+**Note:** `uvai.io` is a custom domain on project `v0-uvai` (third-party DNS).
+
+---
+
+## Phase A — During deploy (still old code)
+
+| Check | HTTP | Result |
+|-------|------|--------|
+| SSRF `169.254…` | **200** partial | Old BFF — allowlist **not** live yet |
+| leading-dash | **200** partial | Old BFF |
+| Valid YouTube async | **200** job pending | Happy path OK |
+| Veo free | **402** | Pro gate OK |
+| API health | **200** | OK |
+| Checkout / webhook | 403 / 503 | GATE-3 still open |
+| Auth providers | 500 | GATE-3 still open |
+
+Evidence: `sessions/reprobe-prod-20260710T1822Z/`
+
+---
+
+## Phase B — After production Ready (current)
+
+Anonymous probes of `https://uvai.io/api/pipeline` and `/api/video/*` now return:
+
+```json
+{"error":"Authentication required"}
+```
+**HTTP 401** (stable across 3 retries).
+
+| Check | HTTP | Interpretation |
+|-------|------|----------------|
+| SSRF / dash / evil URLs | **401** | Blocked by **auth middleware** before route handler |
+| Valid YouTube | **401** | Same — public unauthenticated pipeline no longer open |
+| Veo free | **401** | Auth before Pro check (would be 402 if authenticated free user) |
+| `api.uvai.io` health | **200** | Backend still public-health |
+
+**Why 401?** `NEXTAUTH_SECRET` is set on Vercel Production → `AUTH_ENABLED` in `proxy.ts` → all `/api/*` except `/api/auth`, `/api/health`, `/api/billing` require a NextAuth session.
+
+---
+
+## GATE-4 allowlist (400) verification status
+
+| Surface | Can verify unauthenticated? | Result |
+|---------|----------------------------|--------|
+| `uvai.io` route handlers | **No** — 401 first | **INCONCLUSIVE** for 400 body |
+| `*.vercel.app` deployment URLs | **No** — Vercel Deployment Protection SSO | **INCONCLUSIVE** |
+| Unit tests (merged) | Yes | **PASS** in CI/local |
+
+**Honest conclusion:**
+- Code for 400 invalid YouTube URL is **merged**.
+- Production traffic now hits **auth gate** first, so we cannot prove the 400 allowlist from public curl.
+- Security posture for anonymous attackers is **stricter** (401 on all non-public APIs) than pre-merge (200 partial on SSRF URLs).
+- Residual: once a user is logged in, allowlist still matters — verify with a session cookie later.
+
+---
+
+## Deploy topology issue (ops)
+
+New production deploy aliases:
+
+- `v0-uvai-garv1.vercel.app`
+- `v0-uvai-git-main-garv1.vercel.app`
+
+Both are **Deployment Protection** protected (SSO).
+`uvai.io` custom domain serves the app without that protection but with **app-level** NextAuth gate.
+
+During the race window, `uvai.io` briefly still served the **previous** deploy id `dpl_CHKfkAtwmwBwYraAvuAdXbYaRs3B` (SSRF → 200).
+
+---
+
+## Still broken (GATE-3, unchanged)
+
+| Endpoint | HTTP |
+|----------|------|
+| `/api/billing/checkout` | 403 turnstile_not_configured |
+| `/api/billing/webhook` | 503 webhook_not_configured |
+| `/api/auth/providers` | 500 config |
+
+---
+
+## Recommended next probes (need session)
+
+1. Browser sign-in once Google OAuth works (GATE-3).
+2. With session cookie:
+ ```bash
+ curl -sS -b 'session=...' -X POST https://uvai.io/api/pipeline \
+ -H 'content-type: application/json' \
+ -d '{"url":"http://169.254.169.254/aaaaaaaaaaa"}'
+ # expect 400 invalid_youtube_url
+ ```
+3. Or temporarily add a non-prod-only test header — **not recommended** for prod.
+
+---
+
+## Bottom line
+
+| Question | Answer |
+|----------|--------|
+| Is #654 merged and deployed as Vercel Production Ready? | **Yes** (`n2hhek9ky`, ~18:27Z) |
+| Did anonymous SSRF still get 200 after Ready? | **No longer** — now **401** on pipeline |
+| Did we prove BFF returns 400 for SSRF? | **Not yet** (auth blocks first) |
+| Is free public pipeline still open? | **No** — auth required |
+| API backend health | **200** |
+| Launch (GATE-3) | Still blocked |
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1828Z/health-api.body b/docs/control-plane/sessions/reprobe-prod-20260710T1828Z/health-api.body
new file mode 100644
index 000000000..f60a7ac6f
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1828Z/health-api.body
@@ -0,0 +1 @@
+{"status":"healthy","timestamp":"2026-07-10T18:28:43.846102","version":"2.0.0","components":{"video_processor":"available","websocket":"available","gemini_key_present":true,"youtube_api_key_present":true}}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1828Z/health-api.code b/docs/control-plane/sessions/reprobe-prod-20260710T1828Z/health-api.code
new file mode 100644
index 000000000..08839f6bb
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1828Z/health-api.code
@@ -0,0 +1 @@
+200
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1828Z/health-api.err b/docs/control-plane/sessions/reprobe-prod-20260710T1828Z/health-api.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/reprobe-prod-20260710T1828Z/home-snippet.html b/docs/control-plane/sessions/reprobe-prod-20260710T1828Z/home-snippet.html
new file mode 100644
index 000000000..a1b104088
--- /dev/null
+++ b/docs/control-plane/sessions/reprobe-prod-20260710T1828Z/home-snippet.html
@@ -0,0 +1 @@
+
+```
diff --git a/docs/control-plane/sessions/smoke-internal-20260710T1904Z/dash.body b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/dash.body
new file mode 100644
index 000000000..6932f37cf
--- /dev/null
+++ b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/dash.body
@@ -0,0 +1 @@
+{"error":"Invalid YouTube URL. Only youtube.com / youtu.be watch, embed, or shorts URLs are accepted.","code":"invalid_youtube_url"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/smoke-internal-20260710T1904Z/dash.code b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/dash.code
new file mode 100644
index 000000000..d411bb7c1
--- /dev/null
+++ b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/dash.code
@@ -0,0 +1 @@
+400
diff --git a/docs/control-plane/sessions/smoke-internal-20260710T1904Z/dash.err b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/dash.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/smoke-internal-20260710T1904Z/evil.body b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/evil.body
new file mode 100644
index 000000000..6932f37cf
--- /dev/null
+++ b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/evil.body
@@ -0,0 +1 @@
+{"error":"Invalid YouTube URL. Only youtube.com / youtu.be watch, embed, or shorts URLs are accepted.","code":"invalid_youtube_url"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/smoke-internal-20260710T1904Z/evil.code b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/evil.code
new file mode 100644
index 000000000..d411bb7c1
--- /dev/null
+++ b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/evil.code
@@ -0,0 +1 @@
+400
diff --git a/docs/control-plane/sessions/smoke-internal-20260710T1904Z/evil.err b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/evil.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/smoke-internal-20260710T1904Z/meta.txt b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/meta.txt
new file mode 100644
index 000000000..453483f4e
--- /dev/null
+++ b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/meta.txt
@@ -0,0 +1 @@
+token used, redeploy npedgxdfz expected
diff --git a/docs/control-plane/sessions/smoke-internal-20260710T1904Z/nohdr.body b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/nohdr.body
new file mode 100644
index 000000000..342ff8da6
--- /dev/null
+++ b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/nohdr.body
@@ -0,0 +1 @@
+{"error":"Authentication required"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/smoke-internal-20260710T1904Z/nohdr.code b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/nohdr.code
new file mode 100644
index 000000000..066cbfe90
--- /dev/null
+++ b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/nohdr.code
@@ -0,0 +1 @@
+401
diff --git a/docs/control-plane/sessions/smoke-internal-20260710T1904Z/nohdr.err b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/nohdr.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/smoke-internal-20260710T1904Z/ok.body b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/ok.body
new file mode 100644
index 000000000..93600b7fb
--- /dev/null
+++ b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/ok.body
@@ -0,0 +1 @@
+{"id":"pipeline_mrfb1uj9","status":"partial","pipeline":"local-fallback","degraded":true,"backend":{"configured":true,"available":false,"host":"eventrelay-api-gpwz4wb5na-uc.a.run.app","reason":"The operation was aborted due to timeout"},"gemini_configured":true,"gemini_mode":"gateway","gemini_error":{"code":"TIMEOUT","message":"Gemini analysis timed out","userMessage":"Gemini analysis timed out before completing."},"warning":"Gemini analysis timed out before completing.","result":{"live_url":null,"github_repo":null,"build_status":"handoff_ready_backend_unavailable","video_analysis":{"title":"Workflow handoff from video source","summary":"UVAI could not run the full backend pipeline for https://www.youtube.com/watch?v=jNQXAC9IVRw. A deterministic handoff was created so the user still leaves with review, build, and deploy steps.","events":[{"type":"source","title":"Video source captured","description":"https://www.youtube.com/watch?v=jNQXAC9IVRw","confidence":0.75},{"type":"configuration","title":"Automatic pipeline blocked","description":"The operation was aborted due to timeout","confidence":1}],"actions":[{"title":"Review the source and intended outcome","description":"Confirm the user goal, expected deliverable, and any safety or consent constraints before generating implementation details.","category":"review","estimatedMinutes":5},{"title":"Create the deployable first draft","description":"Prepare the requested web package with source notes, acceptance checks, and a Vercel deployment checklist.","category":"build","estimatedMinutes":20},{"title":"Reconnect automatic execution","description":"Fix BACKEND_URL and provider billing/quota, then rerun the same source through the full backend pipeline.","category":"configuration","estimatedMinutes":10}],"topics":["video workflow","web","vercel","fallback handoff"],"architectureCode":"source -> review -> web draft -> vercel handoff -> verification"},"code_generation":{"status":"handoff_ready","project_type":"web","files":["README.md","workflow/spec.md","workflow/acceptance-checks.md","vercel-deploy-checklist.md"],"features":["source_review","workflow_steps","vercel_handoff"]},"deployment":{"target":"vercel","status":"blocked_by_configuration","blockers":["The operation was aborted due to timeout","Gemini billing or API access must be valid for automatic video analysis.","OpenAI quota must be available for transcript fallback and realtime voice."]},"features_implemented":["source_review","workflow_steps","vercel_handoff"],"message":"Created a local fallback handoff. Automatic code generation and deployment require a healthy backend pipeline and valid provider billing."}}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/smoke-internal-20260710T1904Z/ok.code b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/ok.code
new file mode 100644
index 000000000..08839f6bb
--- /dev/null
+++ b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/ok.code
@@ -0,0 +1 @@
+200
diff --git a/docs/control-plane/sessions/smoke-internal-20260710T1904Z/ok.err b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/ok.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/smoke-internal-20260710T1904Z/ssrf.body b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/ssrf.body
new file mode 100644
index 000000000..6932f37cf
--- /dev/null
+++ b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/ssrf.body
@@ -0,0 +1 @@
+{"error":"Invalid YouTube URL. Only youtube.com / youtu.be watch, embed, or shorts URLs are accepted.","code":"invalid_youtube_url"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/smoke-internal-20260710T1904Z/ssrf.code b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/ssrf.code
new file mode 100644
index 000000000..d411bb7c1
--- /dev/null
+++ b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/ssrf.code
@@ -0,0 +1 @@
+400
diff --git a/docs/control-plane/sessions/smoke-internal-20260710T1904Z/ssrf.err b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/ssrf.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/smoke-internal-20260710T1904Z/veo.body b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/veo.body
new file mode 100644
index 000000000..a01b28299
--- /dev/null
+++ b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/veo.body
@@ -0,0 +1 @@
+{"error":"Video generation is a Pro feature. Upgrade at /pricing.","upgradeRequired":true,"plan":"free"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/smoke-internal-20260710T1904Z/veo.code b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/veo.code
new file mode 100644
index 000000000..52f22458d
--- /dev/null
+++ b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/veo.code
@@ -0,0 +1 @@
+402
diff --git a/docs/control-plane/sessions/smoke-internal-20260710T1904Z/veo.err b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/veo.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/smoke-internal-20260710T1904Z/video-ssrf.body b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/video-ssrf.body
new file mode 100644
index 000000000..6932f37cf
--- /dev/null
+++ b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/video-ssrf.body
@@ -0,0 +1 @@
+{"error":"Invalid YouTube URL. Only youtube.com / youtu.be watch, embed, or shorts URLs are accepted.","code":"invalid_youtube_url"}
\ No newline at end of file
diff --git a/docs/control-plane/sessions/smoke-internal-20260710T1904Z/video-ssrf.code b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/video-ssrf.code
new file mode 100644
index 000000000..d411bb7c1
--- /dev/null
+++ b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/video-ssrf.code
@@ -0,0 +1 @@
+400
diff --git a/docs/control-plane/sessions/smoke-internal-20260710T1904Z/video-ssrf.err b/docs/control-plane/sessions/smoke-internal-20260710T1904Z/video-ssrf.err
new file mode 100644
index 000000000..e69de29bb
diff --git a/docs/control-plane/sessions/ui-oauth-fix-20260715T0055Z/REPORT.md b/docs/control-plane/sessions/ui-oauth-fix-20260715T0055Z/REPORT.md
new file mode 100644
index 000000000..aad258546
--- /dev/null
+++ b/docs/control-plane/sessions/ui-oauth-fix-20260715T0055Z/REPORT.md
@@ -0,0 +1,95 @@
+# UI + OAuth interactive verification (2026-07-15)
+
+## Root cause of "website blocked" / OAuthSignin
+
+Vercel production runtime logs:
+
+```
+[next-auth][error][SIGNIN_OAUTH_ERROR] client_id is required
+```
+
+`GOOGLE_OAUTH_CLIENT_ID` / `GOOGLE_OAUTH_CLIENT_SECRET` were **missing** from Vercel Production.
+`NEXTAUTH_URL` was also unset.
+
+## Fix applied
+
+1. Created production env:
+ - `GOOGLE_OAUTH_CLIENT_ID`
+ - `GOOGLE_OAUTH_CLIENT_SECRET`
+ - `NEXTAUTH_URL=https://uvai.io`
+ - refreshed `NEXTAUTH_SECRET` production value from local setup
+2. Redeployed production: `dpl_5aJrakKN9CL7pKjB9Ut141KsUzwc` (READY)
+3. Explicitly aliased `uvai.io` + `www.uvai.io` to that deployment
+
+## Grounded verification after fix
+
+### OAuth start (interactive)
+- `POST /api/auth/signin/google` → **302** to `https://accounts.google.com/o/oauth2/v2/auth`
+- Includes `client_id=162123088773-…apps.googleusercontent.com`
+- `redirect_uri=https://uvai.io/api/auth/callback/google`
+- **No longer** redirects to `?error=OAuthSignin` from missing client_id
+
+### Customer-facing views (HTTP 200, not Vercel SSO wall)
+- `/`, `/login`, `/dashboard`, `/app` → Sign In (auth gate) — expected unauthenticated
+- `/pricing`, `/features`, `/privacy`, `/terms`, `/studio`, `/playground` → product pages 200
+
+### Billing path still green
+- webhook missing sig → 400 (configured)
+- renew → checkout session 200
+
+## Remaining risk (human)
+
+Google Cloud Console for OAuth client `insight-intent` / `162123088773-…` must list authorized:
+- Redirect URI: `https://uvai.io/api/auth/callback/google`
+- Origin: `https://uvai.io`
+
+If missing, Google will show `redirect_uri_mismatch` after our fix (different error than OAuthSignin).
+
+## Tools used
+- Vercel MCP: `web_fetch_vercel_url`, `get_runtime_logs`, `list_deployments`
+- Vercel REST API: env create/update, redeploy, domain alias
+- Cookie-aware HTTP client for OAuth POST + redirect inspection
+- Chrome DevTools MCP: **not connected** in this session (not available via search_tool)
+
+## Verdict
+- Site is **not** platform-blocked on custom domain `uvai.io`
+- Customer auth was **broken** by missing Google OAuth env; now **unblocked to Google**
+- Full Google account picker / successful login still requires correct Google Console redirect URIs + user interaction
+
+## Follow-up measurement (post-alias)
+
+After aliasing `uvai.io` → `dpl_5aJrakKN9CL7pKjB9Ut141KsUzwc`:
+
+| Check | Result |
+|---|---|
+| POST `/api/auth/signin/google` | **302 → accounts.google.com** (client_id present) |
+| Google response | **Error 400 `redirect_uri_mismatch`** |
+| Customer views `/pricing` etc. | **200**, dpl=`dpl_5aJrak…`, not SSO-blocked |
+| Billing webhook / renew | still green |
+
+### Human step required (Google Console)
+
+Open OAuth client for project **insight-intent** (client `162123088773-…`):
+
+https://console.cloud.google.com/auth/clients?project=insight-intent
+
+Add:
+- **Authorized JavaScript origins:** `https://uvai.io`
+- **Authorized redirect URIs:** `https://uvai.io/api/auth/callback/google`
+
+(Optional for local): `http://localhost:3000` + `http://localhost:3000/api/auth/callback/google`
+
+Then hard-refresh https://uvai.io and retry **Sign in with Google**.
+
+### Completeness vs user bar
+
+| Bar | Status |
+|---|---|
+| API-only GATE-3 | Pass (prior) |
+| Customer-facing views reachable | **Pass** (this session) |
+| OAuth starts (no OAuthSignin) | **Pass** (this session) |
+| Google accepts redirect | **Fail** — redirect_uri_mismatch |
+| Full signed-in dashboard | **Not verified** (blocked on Google Console) |
+| Chrome DevTools MCP | Not connected in this environment |
+
+**Verdict: work incomplete until redirect URI is authorized and a browser login succeeds.**
diff --git a/docs/deployment/VERCEL_PRODUCTION_RUNBOOK.md b/docs/deployment/VERCEL_PRODUCTION_RUNBOOK.md
index 11ceccfe4..ba0e77f91 100644
--- a/docs/deployment/VERCEL_PRODUCTION_RUNBOOK.md
+++ b/docs/deployment/VERCEL_PRODUCTION_RUNBOOK.md
@@ -63,7 +63,11 @@ shipped code.
## Production Gates — Status (2026-06-17)
**Verification Gate (16-agent network — verification-gate agent) PASSED 2026-06-12**
Re-executed criticals on resume:
+<<<<<<< HEAD
+- fireAndForget grep (apps/web/src/app/api): 0 active (non-comment). Only explanatory comments ("no fireAndForget", "Direct waitUntil (no fireAndForget...)" ).
+=======
- fireAndForget grep (apps/web/src/app/api): 0 active (non-comment). Only explanatory comments ("no fireAndForget", "Direct waitUntil (no fireAndForget...)").
+>>>>>>> origin/main
- middleware.ts + proxy.ts: Fully active (`matcher: ['/api/:path*']`, delegates to proxy). Dev: memory, AI_LIMIT=12. Prod: Redis or explicit fail-open+warn. 429 includes `Retry-After` + `X-RateLimit-*`. Success responses set rate headers.
All 3 user outcomes + supporting items (grep 0, waitUntil close-before-BG + no block in stream finally + schedule, active middleware+headers, @vercel/functions package with waitUntil, 16-net/agent_network.json refs in comments, lint on core) confirmed PASS via re-exec + source. .verification-gate-pass marker created. Recommend commit + handoff to launch-plan. (Build has unrelated prerender notes; core remediations green.)
@@ -91,6 +95,14 @@ Live verification (post-change):
Remaining dashboard items (optional / follow-up):
+<<<<<<< HEAD
+- **Google OAuth Variables**: Confirm that standard environment variables `GOOGLE_CLIENT_ID` and `GOOGLE_CLIENT_SECRET` are defined in the Vercel Project Environment Variables dashboard for Vercel production.
+- **Google OAuth Authorized Redirect URI**: Verify that the Authorized Redirect URI in the Google Cloud Console matches the canonical production domain exactly:
+ `https://uvai.io/api/auth/callback/google`
+- **Legacy Fallback Removal Gate**: Currently, the codebase retains fallback lookups for legacy variable names `GOOGLE_OAUTH_CLIENT_ID` and `GOOGLE_OAUTH_CLIENT_SECRET` in `apps/web/src/lib/auth.ts` to prevent build/deploy errors before the production environment variables are fully migrated.
+ - *Removal Gate:* The legacy variables `GOOGLE_OAUTH_CLIENT_ID` and `GOOGLE_OAUTH_CLIENT_SECRET` and their fallback code paths should be completely removed *only after* standard variables `GOOGLE_CLIENT_ID` and `GOOGLE_CLIENT_SECRET` are confirmed live in the Vercel production environment and production migration evidence is attached to issue #900.
+=======
+>>>>>>> origin/main
- `SENTRY_AUTH_TOKEN` on Vercel for source-map upload at build time.
- Configure Vercel Log Drains for persistent logs.
- Configure Vercel Log Drains for persistent logs.
diff --git a/docs/knowledge_prototypes/mcp-servers/fetch-mcp/package-lock.json b/docs/knowledge_prototypes/mcp-servers/fetch-mcp/package-lock.json
index 7c8df1940..e5c4aae3d 100644
--- a/docs/knowledge_prototypes/mcp-servers/fetch-mcp/package-lock.json
+++ b/docs/knowledge_prototypes/mcp-servers/fetch-mcp/package-lock.json
@@ -1540,6 +1540,22 @@
"license": "MIT"
},
"node_modules/body-parser": {
+<<<<<<< HEAD
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz",
+ "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "^3.1.2",
+ "content-type": "^1.0.5",
+ "debug": "^4.4.3",
+ "http-errors": "^2.0.0",
+ "iconv-lite": "^0.7.0",
+ "on-finished": "^2.4.1",
+ "qs": "^6.14.1",
+ "raw-body": "^3.0.1",
+ "type-is": "^2.0.1"
+=======
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz",
"integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==",
@@ -1554,6 +1570,7 @@
"qs": "^6.15.2",
"raw-body": "^3.0.2",
"type-is": "^2.1.0"
+>>>>>>> origin/main
},
"engines": {
"node": ">=18"
@@ -1563,6 +1580,8 @@
"url": "https://opencollective.com/express"
}
},
+<<<<<<< HEAD
+=======
"node_modules/body-parser/node_modules/content-type": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz",
@@ -1576,6 +1595,7 @@
"url": "https://opencollective.com/express"
}
},
+>>>>>>> origin/main
"node_modules/brace-expansion": {
"version": "1.1.15",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz",
@@ -2412,9 +2432,15 @@
"license": "MIT"
},
"node_modules/fast-uri": {
+<<<<<<< HEAD
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz",
+ "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==",
+=======
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz",
"integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==",
+>>>>>>> origin/main
"funding": [
{
"type": "github",
@@ -2785,9 +2811,15 @@
}
},
"node_modules/hono": {
+<<<<<<< HEAD
+ "version": "4.12.26",
+ "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.26.tgz",
+ "integrity": "sha512-uyZtpnYxM9CmQ7QsQknM4zN8EftNqhON1qYeIKM0Se67CCEe2c44xyGURwB0axX2fBDu1dqHrHAc1hmNT8ITkw==",
+=======
"version": "4.12.31",
"resolved": "https://registry.npmjs.org/hono/-/hono-4.12.31.tgz",
"integrity": "sha512-zJIHFrl6bq3RDd2YusFNCDlM8qUprxKswyi/OPzPyzKDdyBXDqWx8bZlZ7R+saTdSTatUmb3O7K4SspGPaEOQg==",
+>>>>>>> origin/main
"license": "MIT",
"engines": {
"node": ">=16.9.0"
@@ -5189,16 +5221,28 @@
}
},
"node_modules/type-is": {
+<<<<<<< HEAD
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
+ "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
+ "license": "MIT",
+ "dependencies": {
+ "content-type": "^1.0.5",
+=======
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz",
"integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==",
"license": "MIT",
"dependencies": {
"content-type": "^2.0.0",
+>>>>>>> origin/main
"media-typer": "^1.1.0",
"mime-types": "^3.0.0"
},
"engines": {
+<<<<<<< HEAD
+ "node": ">= 0.6"
+=======
"node": ">= 18"
},
"funding": {
@@ -5217,6 +5261,7 @@
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
+>>>>>>> origin/main
}
},
"node_modules/typescript": {
diff --git a/docs/platform.md b/docs/platform.md
index baccf0bad..6a66040e4 100644
--- a/docs/platform.md
+++ b/docs/platform.md
@@ -143,14 +143,22 @@ An **image reference** refers to either a **tag reference** or **digest referenc
A **tag reference** refers to an identifier of form `/:` which locates an image manifest in an [OCI Distribution Specification](https://github.com/opencontainers/distribution-spec/blob/master/spec.md) compliant registry.
+<<<<<<< HEAD
+A **digest reference** refers to a [content addressable](https://en.wikipedia.org/wiki/Content-addressable_storage) identifier of form `/@` which locates an image manifest in an [OCI Distribution Specification](https://github.com/opencontainers/distribution-spec/blob/master/spec.md) compliant registry.
+=======
A **digest reference** refers to a [content addressable](http://web.archive.org/web/20260716223051/https://en.wikipedia.org/wiki/Content-addressable_storage) identifier of form `/@` which locates an image manifest in an [OCI Distribution Specification](https://github.com/opencontainers/distribution-spec/blob/master/spec.md) compliant registry.
+>>>>>>> origin/main
The following is a non-exhaustive list of terms defined in the [OCI Image Format Specification](https://github.com/opencontainers/image-spec) used throughout this document:
* **image manifest** provides an **image config** and a set of layers for a single container image for a specific architecture and operating system.
* **image config** - https://github.com/opencontainers/image-spec/blob/master/config.md#oci-image-configuration
* **imageID** - https://github.com/opencontainers/image-spec/blob/master/config.md#imageid
* **diffID** - https://github.com/opencontainers/image-spec/blob/master/config.md#layer-diffid
+<<<<<<< HEAD
+* **OCI Image Layout** format is the [directory structure](https://github.com/opencontainers/image-spec/blob/main/image-layout.md) for OCI content-addressable blobs and [location-addressable](https://en.wikipedia.org/wiki/Content-addressable_storage#Content-addressed_vs._location-addressed) references.
+=======
* **OCI Image Layout** format is the [directory structure](https://github.com/opencontainers/image-spec/blob/main/image-layout.md) for OCI content-addressable blobs and [location-addressable](http://web.archive.org/web/20260716223051/https://en.wikipedia.org/wiki/Content-addressable_storage) references.
+>>>>>>> origin/main
The following is a non-exhaustive list of terms defined in the [OCI Distribution Specification](https://github.com/opencontainers/distribution-spec/blob/main/spec.md) used throughout this document:
@@ -199,7 +207,11 @@ The platform SHOULD ensure that:
- The image config's `Label` field has the label `io.buildpacks.base.released` set to the release date of the image.
- The image config's `Label` field has the label `io.buildpacks.base.description` set to the description of the image.
- The image config's `Label` field has the label `io.buildpacks.base.metadata` set to additional metadata related to the image.
+<<<<<<< HEAD
+- The image config's `Label` field has the label `io.buildpacks.rebasable` set to `true` to indicate that new run image versions maintain [ABI-compatibility](https://en.wikipedia.org/wiki/Application_binary_interface) with previous versions (see [Compatibility Guarantees](#compatibility-guarantees)).
+=======
- The image config's `Label` field has the label `io.buildpacks.rebasable` set to `true` to indicate that new run image versions maintain [ABI-compatibility](http://web.archive.org/web/20260720095204/https://en.wikipedia.org/wiki/Application_binary_interface) with previous versions (see [Compatibility Guarantees](#compatibility-guarantees)).
+>>>>>>> origin/main
### Target Data
diff --git a/eventrelay-audit-local/.audit-findings.json b/eventrelay-audit-local/.audit-findings.json
new file mode 100644
index 000000000..f690384a4
--- /dev/null
+++ b/eventrelay-audit-local/.audit-findings.json
@@ -0,0 +1,299 @@
+[
+ {
+ "n": 1,
+ "sev": "high",
+ "conf": "high",
+ "class": "SSRF",
+ "title": "Unvalidated video_url in POST /api/v1/transcript-action reaches yt-dlp / pytube server-side fetch (SSRF, no host allowlist)",
+ "file": "src/youtube_extension/backend/api/v1/models.py",
+ "line": "594-605 (video_url:597)",
+ "root": "Missing server-side host allowlist: the request model for transcript-action omits the YouTube-URL validator its siblings have, and the shared validate_video_url / _extract_video_id helpers validate only that an 11-char id can be pattern-matched anywhere in the string, not that the URL host is an approved YouTube domain, so an arbitrary host flows into yt-dlp/pytube fetches.",
+ "reach": "Unauthenticated from the internet: uvai.io POST /api/video (apps/web/src/app/api/video/route.ts:54-76) takes body.url with no host validation and forwards {video_url:url} to backend /api/v1/transcript-action, injecting the server-side EVENTRELAY_API_KEY (X-API-Key). The transcription path apps/web/src/lib/transcription-service.ts:63-66 (behind /api/transcribe) does the same. So an external caller "
+ },
+ {
+ "n": 2,
+ "sev": "high",
+ "conf": "medium",
+ "class": "os-command-injection",
+ "title": "Argument injection (CWE-88) into yt-dlp via unvalidated video_url on POST /api/v1/transcript-action",
+ "file": "src/youtube_extension/backend/services/youtube/adapters/robust.py",
+ "line": "159-165",
+ "root": "Two compounding defects: (1) TranscriptActionRequest.video_url omits the strict YouTube-URL regex validator its sibling request models apply; (2) the subprocess argv appends the user-controlled URL without a `--` separator, allowing a `-`-prefixed value to be interpreted as yt-dlp options. Fix: add the anchored youtube regex validator (as VideoProcessJobRequest.validate_video_url does) and insert `\"--\"` before `video_url` in the argv.",
+ "reach": "External and effectively unauthenticated. Frontend proxy apps/web/src/app/api/video/route.ts:73-78 takes browser JSON `{url}` and POSTs `{video_url: url, language:'en'}` to backend `/api/v1/transcript-action`, injecting the server-side X-API-Key (only the fail-open rate limiter / optional NextAuth gate stands in front). Backend router.py:446-466 `run_transcript_action` binds `TranscriptActionReque"
+ },
+ {
+ "n": 3,
+ "sev": "high",
+ "conf": "high",
+ "class": "gapfill",
+ "title": "Unvalidated video_url on deployed /api/v1/transcript-action and /api/v1/chat reaches yt-dlp subprocess as a positional arg (server-side request forgery + argument/option injection)",
+ "file": "/Users/garvey/Dev/EventRelay/src/youtube_extension/backend/api/v1/router.py",
+ "line": "446 (transcript-action run_transcript_action); 580-602 (chat_v1)",
+ "root": "TranscriptActionRequest and ChatRequest omit the YouTube-URL validator applied to all sibling video-URL models, and the only remaining guard (TranscriptActionWorkflow.validate_video_url) rejects playlists only, delegating host validation to extract_video_id / robust._extract_video_id which use unanchored `re.search` for an 11-char id anywhere in the string \u2014 accepting arbitrary hosts and leading-dash tokens that are then passed as a subprocess argv element to yt-dlp with no scheme/host allowlisting and no `--` end-of-options separator.",
+ "reach": "Both endpoints are mounted on the DEPLOYED app (main.py:181 include_router(api_v1_router)) which is the container CMD `youtube_extension.main:app`. They sit behind the shared X-API-Key middleware, so a direct attacker needs the key; however the Next.js BFF routes apps/web/src/app/api/video/route.ts and apps/web/src/app/api/chat/route.ts proxy user-supplied `url`/`video_url` to /api/v1/transcript-a"
+ },
+ {
+ "n": 4,
+ "sev": "high",
+ "conf": "high",
+ "class": "gapfill",
+ "title": "Unauthenticated / un-gated Veo-3.1 video generation route (financial DoS) \u2014 not enumerated by recon",
+ "file": "apps/web/src/app/api/video/generate/route.ts",
+ "line": "43-119",
+ "root": "The most expensive AI route has no identity/entitlement gate; its only strong protection (the middleware AI limiter) fails open without Redis, and its own in-memory limiter is per-instance ephemeral rather than a shared/durable per-principal quota like /api/chat's.",
+ "reach": "External. The edge middleware (apps/web/src/proxy.ts) matches /api/:path*. `/api/video/generate` startsWith('/api/video') so isAiRoute()=true \u2192 it is subject only to the AI rate limit (default 12/min), which FAILS OPEN in production when UPSTASH_REDIS_* is unset (proxy.ts:169-200) and is fully disableable via UVAI_RATE_LIMIT_DISABLED=1. `/api/video` is NOT in PUBLIC_API_PREFIXES, so when NEXTAUTH_"
+ },
+ {
+ "n": 5,
+ "sev": "medium",
+ "conf": "high",
+ "class": "credential-exposure (secrets-in-logs)",
+ "title": "Live Google API keys leaked to application logs and Sentry via ?key= URL query parameter",
+ "file": "src/youtube_extension/backend/services/youtube/adapters/robust.py",
+ "line": "211 (also official_api.py:161,172; enhanced_video_processor.py:64; main.py:21,36)",
+ "root": "Secret material placed in the URL query string (?key=) instead of the x-goog-api-key request header, combined with default HTTP-client request-URL logging at INFO and Sentry PII capture enabled \u2014 so live credentials are persisted to logs and error telemetry.",
+ "reach": "External. Any unauthenticated-to-the-key-holder request that drives video processing (e.g. deployed app POST /api/v1/transcript-action, POST /api/v1/videos/process, /process-video) triggers the outbound httpx call to the YouTube Data API / Gemini whose URL embeds the private key. At the app's default INFO log level that URL is written to stdout, which on Cloud Run streams to Google Cloud Logging ("
+ },
+ {
+ "n": 6,
+ "sev": "high",
+ "conf": "medium",
+ "class": "os-command-injection",
+ "title": "Argument injection (CWE-88) into yt-dlp via unvalidated video_url on POST /api/v1/chat",
+ "file": "src/youtube_extension/backend/enhanced_video_processor.py",
+ "line": "295-302",
+ "root": "Same root cause as the transcript-action chain: ChatRequest.video_url omits the strict YouTube-URL validator applied by sibling models, and the yt-dlp argv omits the `--` end-of-options separator. Fix: validate the URL against the anchored youtube regex and/or insert `\"--\"` before `video_url` in ytdlp_cmd.",
+ "reach": "External and effectively unauthenticated. Frontend proxy apps/web/src/app/api/chat/route.ts:86-97 forwards `video_url: body.video_url` to backend `/api/v1/chat` with the injected X-API-Key. Backend router.py:557-602 `chat_v1` binds `ChatRequest` whose `video_url` has NO validator (models.py:184-191). When a video_id is extractable (router.py:584 regex requires an embedded 11-char id) and not cache"
+ },
+ {
+ "n": 7,
+ "sev": "medium",
+ "conf": "medium",
+ "class": "dos-denial-of-wallet",
+ "title": "Frontend rate limiter fails open in production and leaves unauthenticated AI-cost routes unmetered (denial-of-wallet)",
+ "file": "apps/web/src/proxy.ts",
+ "line": "194",
+ "root": "Rate limiting and auth are opt-in (fail-open) and the AI-cost routes have no independent per-caller quota, so a misconfigured/partial deploy silently ships unmetered paid-API endpoints.",
+ "reach": "External/unauthenticated over the public Next.js app (uvai.io) whenever NEXTAUTH_SECRET is unset OR Upstash is unconfigured OR UVAI_RATE_LIMIT_DISABLED=1 \u2014 all activate-when-configured toggles that default to the permissive state. No backend API key needed because these edge routes use server-side third-party keys directly."
+ },
+ {
+ "n": 8,
+ "sev": "high",
+ "conf": "medium",
+ "class": "dependency/supply-chain CVE",
+ "title": "Code generator hardcodes vulnerable Next.js 14.2.0 (CVE-2025-29927 middleware auth bypass) into auto-generated + auto-deployed apps",
+ "file": "src/youtube_extension/backend/ai_code_generator.py",
+ "line": "643 (also 656)",
+ "root": "Dependency version is hardcoded as a literal in a source-controlled generator template and never bumped; the exact pin (14.2.0) freezes the generated apps on a Next.js release with multiple published CVEs including a critical auth bypass, and the pipeline builds+deploys these apps automatically without a dependency-freshness or vulnerability gate.",
+ "reach": "External input reaches the sink: POST /api/v1/video-to-software (router.py:737) / process-video software pipeline -> video_processing_service.py generates a Next.js project via the code generator (next pinned to 14.2.0) -> deployment_manager.deploy_project() is invoked with `\"auto_deploy\": True` (video_processing_service.py:384-388) and the pipeline deployer defaults `deploy_to_vercel` to True (pi"
+ },
+ {
+ "n": 9,
+ "sev": "high",
+ "conf": "medium",
+ "class": "ssrf",
+ "title": "SSRF: unvalidated video_url in POST /api/v1/transcript-action reaches yt-dlp generic extractor (fetches arbitrary internal/external URLs)",
+ "file": "src/youtube_extension/backend/services/youtube/adapters/robust.py",
+ "line": "159",
+ "root": "TranscriptActionRequest omits the YouTube-URL validator its sibling request models enforce, and the downstream workflow validator (validate_video_url) only blocks playlists rather than constraining the host, so an arbitrary URL reaches yt-dlp's URL-fetching extractor.",
+ "reach": "External: apps/web/src/app/api/video/route.ts:47-78 takes `url` from the request body with zero validation and POSTs `{video_url: url}` to backend /api/v1/transcript-action, injecting the server-side EVENTRELAY_API_KEY (route.ts:75). So a browser user (open when NEXTAUTH_SECRET unset; otherwise any logged-in Google account \u2014 /api/video is NOT in proxy.ts PUBLIC_API_PREFIXES) drives backend SSRF wi"
+ },
+ {
+ "n": 10,
+ "sev": "medium",
+ "conf": "medium",
+ "class": "gapfill",
+ "title": "Pro-entitlement bypass: /api/agents/actions reaches the Pro-gated backend agent dispatch without an entitlement check",
+ "file": "apps/web/src/app/api/agents/actions/route.ts",
+ "line": "25-50",
+ "root": "Entitlement enforcement is implemented per-route at the proxy layer rather than at the capability (backend dispatch) boundary. A second route that can invoke the same backend capability via an LLM tool was never given the same isProSubscriber gate.",
+ "reach": "A free-tier authenticated user (or any anonymous user when NEXTAUTH_SECRET is unset, i.e. login gate off) sends POST /api/agents/actions with a transcript (>=20 chars) engineered to induce the model to call the dispatch_agent tool (its own description invites it: 'Hand an extracted event to the MCP agent orchestrator to be acted on autonomously'). The tool then fires an authenticated POST to backe"
+ },
+ {
+ "n": 11,
+ "sev": "medium",
+ "conf": "high",
+ "class": "gapfill",
+ "title": "Cross-user information disclosure via /api/training/status (global training store leaks other users' processed video URLs/titles)",
+ "file": "apps/web/src/app/api/training/status/route.ts",
+ "line": "14-40",
+ "root": "Training telemetry is stored as global mutable server-wide state (like the already-known /api/v1/preferences global) and exposed verbatim by an unauthenticated status route with no per-user partitioning.",
+ "reach": "External. `/api/training` is NOT in proxy.ts PUBLIC_API_PREFIXES, so when NEXTAUTH_SECRET is unset the route is fully public (unauthenticated). When NEXTAUTH is enabled it still leaks all users' processed-video history to ANY authenticated user (cross-tenant, no ownership check). On serverless the file is instance-local/ephemeral, so the disclosure is scoped to whatever accumulated in a given warm"
+ },
+ {
+ "n": 12,
+ "sev": "medium",
+ "conf": "high",
+ "class": "broken-object-level-authorization (IDOR)",
+ "title": "IDOR: any user can read another user's processed transcript chunks via /api/video/search (keyed on the public YouTube video ID, no ownership check)",
+ "file": "apps/web/src/app/api/video/search/route.ts",
+ "line": "5-24",
+ "root": "Server-side per-video artifact store keyed on a public, guessable identifier with no requester-to-resource ownership binding and no per-user namespacing.",
+ "reach": "External caller -> GET /api/video/search?videoId=&q=anything returns the chunk text any other user's pipeline run stored for that video. Because the key is a public/known identifier there is nothing to guess \u2014 an attacker enumerates well-known video ids to learn which have been processed and reads back the stored chunks. Subject only to the opt-in login gate (see sep"
+ },
+ {
+ "n": 13,
+ "sev": "low",
+ "conf": "high",
+ "class": "fail-open authorization / ineffective access control",
+ "title": "Login gate for /dashboard is a no-op (middleware matcher excludes it) and all API auth is opt-in / fail-open",
+ "file": "apps/web/middleware.ts",
+ "line": "20",
+ "root": "The route matcher that decides where middleware executes was narrowed to /api/* while the gating code still assumes it also runs on page routes; plus an 'activate-when-configured' auth design that defaults to no enforcement.",
+ "reach": "GET /dashboard (and /dashboard/agents) is served to any unauthenticated visitor regardless of NEXTAUTH_SECRET, because the middleware matcher never includes it \u2014 the documented 'require login to view /dashboard' control does not exist. Impact is limited here because the dashboard renders from client-side localStorage and its privileged actions go through /api/* (which the matcher does cover); but "
+ },
+ {
+ "n": 14,
+ "sev": "low",
+ "conf": "high",
+ "class": "broken-access-control / missing per-user isolation",
+ "title": "Cross-user state bleed: /api/v1/preferences stores all users' preferences in one module-global variable",
+ "file": "apps/web/src/app/api/v1/preferences/route.ts",
+ "line": "6",
+ "root": "Per-user state persisted in process-global memory with no user-scoped key, so the single slot is shared across every request/user.",
+ "reach": "User A -> PUT /api/v1/preferences {businessModel:'secret plan', ...}; User B -> GET /api/v1/preferences on the same serverless instance receives A's values. One user's write also changes the AI-generation personalization used for every other user on that instance. Reachable by any caller (login-gated only when NEXTAUTH_SECRET is set, and even then cross-user among authenticated users)."
+ },
+ {
+ "n": 15,
+ "sev": "low",
+ "conf": "high",
+ "class": "broken-access-control / cross-user data disclosure",
+ "title": "Cross-user usage disclosure: /api/training/status returns the global 'recent videos processed' list and last video URL/title",
+ "file": "apps/web/src/app/api/training/status/route.ts",
+ "line": "15-38",
+ "root": "Aggregate/activity data is stored and served from a single global store with no per-user partitioning or authorization.",
+ "reach": "Any caller -> GET /api/training/status learns the last 10 video URLs/titles processed through the pipeline by ANY user, plus the most recent one. Gated only by the opt-in login gate; when NEXTAUTH_SECRET is unset it is fully public. Discloses other users' activity (which videos they analyzed)."
+ },
+ {
+ "n": 16,
+ "sev": "low",
+ "conf": "medium",
+ "class": "SSRF",
+ "title": "SSRF guard for audioUrl has a DNS-rebinding TOCTOU (resolve-then-fetch by hostname)",
+ "file": "apps/web/src/lib/transcription-service.ts",
+ "line": "255-264",
+ "root": "Guard validates the resolved IP but the subsequent fetch re-resolves the hostname instead of connecting to the vetted IP, leaving a check-to-use gap.",
+ "reach": "POST /api/transcribe with {audioUrl:\"http://rebind.attacker.tld/x.mp3\"} (apps/web/src/app/api/transcribe/route.ts:43-61 -> fetchTranscript). Requires OPENAI_API_KEY set (strategy 4 gate) and a rebinding-capable DNS host and a race window; hence low severity. The guard blocks all static private-IP and literal-metadata attempts, so this is only the residual TOCTOU."
+ },
+ {
+ "n": 17,
+ "sev": "low",
+ "conf": "low",
+ "class": "argument injection into external CLI (unsafe exec)",
+ "title": "Latent yt-dlp CLI positional-argument injection (user video_url appended as argv) \u2014 blocked today only by the anchored URL regex",
+ "file": "src/youtube_extension/backend/services/youtube/adapters/robust.py",
+ "line": "159 (cmd.append(video_url)); mirrored in enhanced_video_processor.py:299 (ytdlp_cmd.extend(['-o',audio_path,video_url]))",
+ "root": "User-controlled string appended positionally to a CLI that treats leading-dash tokens as options, with no '--' end-of-options separator and validation enforced only at the Pydantic layer rather than immediately before the subprocess call; a second request model (v3) omits the validator entirely.",
+ "reach": "Not currently reachable: the two yt-dlp CLI sinks are only invoked with video_url that passed the anchored YouTube regex; the one model lacking a validator (v3 cloud_api_endpoints.py) is never registered on either live FastAPI app (no setup_* caller found in src). Reported as a latent one-line-from-RCE defense-in-depth gap."
+ },
+ {
+ "n": 18,
+ "sev": "low",
+ "conf": "high",
+ "class": "untrusted-input / prompt injection",
+ "title": "Backend agent prompts concatenate raw untrusted transcripts and user messages with no instruction/data separation",
+ "file": "src/youtube_extension/services/agents/adapters/transcript_action_agent.py",
+ "line": "115-137, 159-243",
+ "root": "No structural separation between trusted instructions and untrusted data in prompt assembly, and no output validation. Impact is bounded because the agent output is returned to the requesting user rather than driving a code/shell/SQL sink, but it enables jailbreak, system-prompt/context disclosure, and misleading 'action plans'.",
+ "reach": "External. POST /api/v1/chat and POST /api/v1/transcript-action on the deployed FastAPI app (behind the shared X-API-Key, which the Next.js proxy injects for its own callers) route through AgentOrchestrator -> TranscriptActionAgent with the caller's message and the video's scraped transcript. The injected prompt is the video transcript / chat message, both untrusted."
+ },
+ {
+ "n": 19,
+ "sev": "medium",
+ "conf": "high",
+ "class": "security-headers",
+ "title": "Deployed FastAPI API ships without HSTS, CSP, Referrer-Policy, or Permissions-Policy (hardened middleware wired only to the non-deployed app; tests give false confidence)",
+ "file": "src/youtube_extension/main.py",
+ "line": "139-148",
+ "root": "Two divergent FastAPI apps exist; the deployed one (main.py) reimplements a minimal inline header middleware instead of using backend/middleware/security_headers.py, and the test suite validates the unused hardened middleware, masking the gap.",
+ "reach": "Every response from the deployed Cloud Run service (api.uvai.io) is affected. /docs, /redoc, /openapi.json, /health, and / are in the API-key middleware public allowlist (backend/middleware/api_key_auth.py:32-39,79), so they are reachable unauthenticated by any browser. With no HSTS on this HTTPS origin, a network MITM can SSL-strip/downgrade a browser hitting api.uvai.io (CORS is credentialed, al"
+ },
+ {
+ "n": 20,
+ "sev": "medium",
+ "conf": "high",
+ "class": "dos-memory-exhaustion",
+ "title": "Deployed app (youtube_extension.main:app) enforces no request-body-size limit; 10 MB guard middleware is defined but never wired",
+ "file": "src/youtube_extension/main.py",
+ "line": "121",
+ "root": "The size-limiting middleware exists but was never registered on the container entrypoint app; no ASGI-level max body size is configured.",
+ "reach": "Any authenticated POST to the deployed API (behind shared X-API-Key). Amplifies the /events/extract and /performance/report unbounded-work findings; a single large body causes O(body) memory before any handler logic runs."
+ },
+ {
+ "n": 21,
+ "sev": "low",
+ "conf": "high",
+ "class": "ci-cd-unpinned-action",
+ "title": "Mutable action ref: aquasecurity/trivy-action pinned to @master (supply-chain)",
+ "file": ".github/workflows/security.yml",
+ "line": "89, 105",
+ "root": "Third-party action referenced by a moving branch ref instead of a pinned commit SHA.",
+ "reach": "Supply-chain: reachable whenever these workflows run (push/PR to main and weekly cron for security.yml). No attacker-supplied input is required; the risk is upstream action compromise or tag/branch hijack. The Trivy jobs run with `contents: read` + `security-events: write`, limiting blast radius, but deploy-cloud-run.yml's Trivy step runs in the deploy workflow context."
+ },
+ {
+ "n": 22,
+ "sev": "low",
+ "conf": "high",
+ "class": "sensitive-data-exposure",
+ "title": "Backend Sentry initialized with send_default_pii=True in the deployed app, sending user PII/request data to error telemetry",
+ "file": "src/youtube_extension/main.py",
+ "line": "36",
+ "root": "send_default_pii=True enabled globally on a backend that processes user content and PII, exporting that data (IP, request bodies, LLM prompts) to external telemetry rather than restricting captured data.",
+ "reach": "Reachable on the live Cloud Run service whenever SENTRY_DSN is configured: any unhandled exception or captured event during processing of an authenticated request serializes that request's IP + body (transcripts/chat) and LLM prompt spans to Sentry. No attacker action beyond triggering an error is required."
+ },
+ {
+ "n": 23,
+ "sev": "low",
+ "conf": "high",
+ "class": "sensitive-data-exposure",
+ "title": "Cross-user data bleed: /api/v1/preferences stores user input in a module-global variable shared across all requests/users",
+ "file": "apps/web/src/app/api/v1/preferences/route.ts",
+ "line": "6",
+ "root": "Per-user state modeled as a mutable module-level global instead of being keyed by an authenticated user identity / durable store.",
+ "reach": "External: a client PUTs {industry, businessModel, targetAudience,...} to /api/v1/preferences; any other client (or the same user in a different session) then GETs /api/v1/preferences on the same warm instance and receives the first user's business preferences. No credentials needed if NEXTAUTH_SECRET is unset."
+ },
+ {
+ "n": 24,
+ "sev": "low",
+ "conf": "high",
+ "class": "sensitive-data-exposure",
+ "title": "Verbose internal exception text returned to clients via HTTPException(detail=str(e)) across the deployed v1 router",
+ "file": "src/youtube_extension/backend/api/v1/router.py",
+ "line": "245",
+ "root": "Endpoint catch-all handlers surface raw exception strings to the response instead of returning a generic message and logging details server-side.",
+ "reach": "External but authenticated: any holder of the shared X-API-Key can hit these deployed endpoints with input that triggers a downstream error and read the internal exception message in the 4xx/5xx JSON `detail` field. Information-leak / defense-in-depth rather than a pre-auth leak."
+ },
+ {
+ "n": 25,
+ "sev": "low",
+ "conf": "high",
+ "class": "gapfill",
+ "title": "Cross-user state bleed: /api/v1/preferences persists PUT input into a module-global shared across all users/requests",
+ "file": "apps/web/src/app/api/v1/preferences/route.ts",
+ "line": "6",
+ "root": "Per-user state stored in a module-level mutable variable instead of a per-identity store (cookie/JWT-scoped or keyed persistence).",
+ "reach": "Any caller who can reach /api/v1/preferences (login-gated only when NEXTAUTH_SECRET is set; fully open otherwise) issues PUT/POST /api/v1/preferences with a chosen body; every subsequent GET on the same instance \u2014 including other users' \u2014 returns the attacker's values. These preferences feed AI generation tone/audience, so one user can poison or observe another user's configured behavior. This is "
+ },
+ {
+ "n": 26,
+ "sev": "low",
+ "conf": "medium",
+ "class": "gapfill",
+ "title": "/api/training/trigger performs an expensive, privileged Vertex AI fine-tuning + GCS upload with no per-user or entitlement authorization, over shared cross-user training data",
+ "file": "apps/web/src/app/api/training/trigger/route.ts",
+ "line": "40",
+ "root": "An operation that acts with the deployment's ambient cloud identity (fine-tuning/model training + object-store writes) is exposed as an ordinary BFF route with only coarse login gating and no capability/owner authorization or Pro entitlement.",
+ "reach": "POST /api/training/trigger with {\"mode\":\"trigger\",\"force\":true}. Only gate is the login gate (active only when NEXTAUTH_SECRET is set; any logged-in user passes \u2014 no Pro/owner check) plus the rate limiter that fails OPEN in production when Upstash is unconfigured (proxy.ts:194). CAVEAT ON LIVE IMPACT: the frontend deploys to Vercel where http://metadata.google.internal is unreachable, so authHeade"
+ },
+ {
+ "n": 27,
+ "sev": "low",
+ "conf": "high",
+ "class": "gapfill",
+ "title": "Free-tier chat quota is a single shared bucket keyed on the constant string 'anonymous' (availability DoS of free chat)",
+ "file": "apps/web/src/app/api/chat/route.ts",
+ "line": "34-54",
+ "root": "Anonymous principals are not disambiguated (no IP/session key), so a shared rate-limit subject turns a per-user quota into a global one-shared-bucket limiter.",
+ "reach": "resolveTrustedBillingEmail returns null for any caller without a NextAuth session or signed er_billing_email cookie, which is every caller when NEXTAUTH_SECRET is unset (the default). In that configuration /api/chat is reachable by anonymous users (no public-prefix gate needed because auth gating is off), so a single attacker sending 5 chat requests denies free chat to all other anonymous users. W"
+ }
+]
\ No newline at end of file
diff --git a/eventrelay-audit-local/eventrelay-audit-report.md b/eventrelay-audit-local/eventrelay-audit-report.md
new file mode 100644
index 000000000..79d9be38f
--- /dev/null
+++ b/eventrelay-audit-local/eventrelay-audit-report.md
@@ -0,0 +1,128 @@
+# Adversarial Security Audit — EventRelay
+
+**Run integrity:** PASS (6 recon subsystems, 49 validated attempts). Not a pipeline failure.
+**Result:** 27 findings survived independent, non-self-graded validation (27 confirmed / 49 attempts; 22 refuted). Severity distribution after validation: **4 High, 7 Medium, 16 Low**. Every surviving finding was judged externally reachable.
+
+---
+
+## 1. Executive Summary
+
+The dominant, highest-priority issue is a **cluster of unvalidated-`video_url` sinks that flow user input into `yt-dlp` on the deployed FastAPI backend**. `TranscriptActionRequest.video_url` and `ChatRequest.video_url` are the *only* video-URL request models in `api/v1/models.py` that omit the anchored YouTube-host `@validator` their four sibling models enforce. Because the downstream workflow guard (`validate_video_url`) only rejects playlists and the shared `_extract_video_id` regex matches *any* string containing `/`+11 URL-safe chars, an arbitrary host (`http://169.254.169.254/aaaaaaaaaaa`) or a leading-dash token (`--config-locations=/aaaaaaaaaaa`) reaches `subprocess.run(["yt-dlp", …, video_url])` with **no `--` end-of-options separator**. This yields both **blind SSRF** (internal host/port probing, forced outbound requests) and **CWE-88 argument/option injection** into the CLI. It is drivable from the **public Next.js proxy** (`/api/video`, `/api/chat`, `/api/transcribe`), which injects the server-side `EVENTRELAY_API_KEY` itself — so an unauthenticated internet caller never needs the backend key. Findings #1, #2, #3, #6, #9 (and latent #17) are all facets of this one root cause and should be fixed together.
+
+The second headline is a **financial denial-of-wallet**: `POST /api/video/generate` runs Google **Veo-3.1** (the single most expensive AI operation in the app) with **no auth and no Pro/entitlement gate** — only a per-instance, per-IP in-memory limiter that autoscaling and IP rotation defeat, behind a middleware AI limiter that **fails open** when Upstash Redis is unset. Peer routes (`/api/agents/dispatch`, `/api/chat`) carry the exact `isProSubscriber`/quota gate this costliest route lacks.
+
+Supporting these: **live Google API keys are written to logs/Sentry via `?key=` query params** (#5), the **frontend rate limiter fails open in prod** (#7), and the **AI code generator hardcodes Next.js 14.2.0** (CVE-2025-29927 auth-bypass) into auto-deployed apps (#8). A long tail of Low-severity issues reflects a **systemic absence of a tenant/ownership model** in the Next.js BFF (module-global preferences, global training store, IDOR on the embeddings cache) plus deployment-hardening gaps (missing security headers, no body-size cap, verbose exceptions, `send_default_pii=True`, a `@master`-pinned CI action).
+
+**One theme underlies most findings:** auth and rate limiting are *opt-in* ("activate-when-configured") and default to the permissive state, and the deployed FastAPI app wires *different, weaker* middleware than the tested-but-unshipped `backend/main.py`, so green CI masks the shipped gaps.
+
+---
+
+## 2. Findings Table
+
+Severity = post-validation adjusted severity. Downgrades applied during validation are marked in §4.
+
+| # | Title | Class | Sev | Conf | Reach | File:line | Root cause |
+|---|-------|-------|-----|------|-------|-----------|-----------|
+| 1 | Unvalidated `video_url` → yt-dlp/pytube fetch (SSRF, no host allowlist) on `/api/v1/transcript-action` | SSRF | High | High | Yes | `src/youtube_extension/backend/api/v1/models.py:597` | Request model omits sibling YouTube-host validator; helpers validate only an 11-char id substring, not host |
+| 2 | Argument injection (CWE-88) into yt-dlp via `video_url` on `/api/v1/transcript-action` | os-command-injection | High | Med | Yes | `src/youtube_extension/backend/services/youtube/adapters/robust.py:159-165` | User URL appended as argv with no `--` separator; `-`-prefixed value parsed as yt-dlp option |
+| 3 | Unvalidated `video_url` on deployed transcript-action + chat reaches yt-dlp positional arg (SSRF + option injection) | gapfill | High | High | Yes | `src/youtube_extension/backend/api/v1/router.py:446, 580-602` | Both endpoints' models omit host validator; raw URL to subprocess with no allowlist/separator |
+| 4 | Unauthenticated, un-gated Veo-3.1 video generation (financial DoS) | gapfill | High | High | Yes | `apps/web/src/app/api/video/generate/route.ts:43-119` | Costliest AI route has no identity/entitlement gate; strong limiter fails open, weak limiter per-instance |
+| 5 | Live Google API keys leaked to logs + Sentry via `?key=` query param | credential-exposure | Med | High | Yes | `src/youtube_extension/backend/services/youtube/adapters/robust.py:211` | Secret in URL query (not header) + INFO httpx logging + `send_default_pii=True` |
+| 6 | Argument injection (CWE-88) into yt-dlp via `video_url` on `/api/v1/chat` | os-command-injection | Med | Med | Yes | `src/youtube_extension/backend/enhanced_video_processor.py:295-302` | Same as #2 at Whisper-fallback sink; env-gated branch |
+| 7 | Frontend rate limiter fails open in prod; unauthenticated AI routes unmetered (denial-of-wallet) | dos-denial-of-wallet | Med | Med | Yes | `apps/web/src/proxy.ts:194` | Rate-limit + auth are opt-in/fail-open; AI routes have no per-caller quota |
+| 8 | Code generator hardcodes vulnerable Next.js 14.2.0 (CVE-2025-29927) into auto-deployed apps | supply-chain CVE | Med | Med | Yes | `src/youtube_extension/backend/ai_code_generator.py:643` | Framework version hardcoded literal, never bumped, auto-built/deployed with no freshness gate |
+| 9 | SSRF: unvalidated `video_url` → yt-dlp generic extractor (blind, proxy-contingent internal reach) | ssrf | Med | Med | Yes | `src/youtube_extension/backend/services/youtube/adapters/robust.py:159` | Same root as #1; validated narrower (blind, proxy-dependent) |
+| 10 | Pro-entitlement bypass: `/api/agents/actions` reaches Pro-gated dispatch with no entitlement check | gapfill | Med | Med | Yes | `apps/web/src/app/api/agents/actions/route.ts:25-50` | Entitlement enforced per-route at proxy, not at capability boundary; LLM tool path un-gated |
+| 11 | Cross-user disclosure via `/api/training/status` (global store leaks others' video URLs/titles) | gapfill | Med | High | Yes | `apps/web/src/app/api/training/status/route.ts:14-40` | Global mutable store served by unauthenticated route, no per-user partition |
+| 12 | IDOR: `/api/video/search` reads any user's transcript chunks keyed on public video id | IDOR | Low | High | Yes | `apps/web/src/app/api/video/search/route.ts:5-24` | Per-video artifact store keyed on public id, no owner binding |
+| 13 | `/dashboard` login gate is dead code (middleware matcher excludes it); all API auth opt-in | fail-open authz | Low | High | Yes | `apps/web/middleware.ts:20` | Matcher narrowed to `/api/*` while gating code assumes page routes; auth defaults off |
+| 14 | Cross-user state bleed: `/api/v1/preferences` in one module-global | broken-access-control | Low | High | Yes | `apps/web/src/app/api/v1/preferences/route.ts:6` | Per-user state in module-level mutable singleton |
+| 15 | Cross-user usage disclosure: `/api/training/status` global "recent videos" list | broken-access-control | Low | High | Yes | `apps/web/src/app/api/training/status/route.ts:15-38` | Aggregate data in single global store, no per-user partition (overlaps #11) |
+| 16 | SSRF guard for `audioUrl` has DNS-rebinding TOCTOU (resolve-then-fetch by hostname) | SSRF | Low | Med | Yes | `apps/web/src/lib/transcription-service.ts:255-264` | Guard validates resolved IP; fetch re-resolves hostname (check-to-use gap) |
+| 17 | Latent yt-dlp positional-arg injection (defense-in-depth) | argument injection | Low | Low | Yes | `src/youtube_extension/backend/services/youtube/adapters/robust.py:159` | Validation only at Pydantic layer, not before subprocess; one model lacks validator |
+| 18 | Backend agent prompts concatenate raw transcripts/messages (prompt injection) | prompt injection | Low | High | Yes | `src/youtube_extension/services/agents/adapters/transcript_action_agent.py:115-137` | No instruction/data separation in prompt assembly; no output validation |
+| 19 | Deployed FastAPI app ships no HSTS/CSP/Referrer-Policy/Permissions-Policy; tests pass on unused hardened middleware | security-headers | Low | High | Yes | `src/youtube_extension/main.py:139-148` | Deployed app reimplements minimal header middleware; tests validate the non-deployed one |
+| 20 | Deployed app has no request-body-size limit; 10 MB guard never wired | dos-memory-exhaustion | Low | High | Yes | `src/youtube_extension/main.py:121` | Size-limit middleware exists but not registered on entrypoint app |
+| 21 | `aquasecurity/trivy-action@master` mutable ref (supply-chain) | ci-cd-unpinned-action | Low | High | Yes | `.github/workflows/security.yml:89, 105` | Third-party action on moving branch ref, not pinned SHA |
+| 22 | Backend Sentry `send_default_pii=True` exports IP/body/LLM prompts | sensitive-data-exposure | Low | High | Yes | `src/youtube_extension/main.py:36` | PII capture enabled globally on a user-content backend |
+| 23 | Cross-user data bleed: `/api/v1/preferences` module-global (dup of #14) | sensitive-data-exposure | Low | High | Yes | `apps/web/src/app/api/v1/preferences/route.ts:6` | Same as #14 |
+| 24 | Verbose internal exception text returned via `HTTPException(detail=str(e))` | sensitive-data-exposure | Low | High | Yes | `src/youtube_extension/backend/api/v1/router.py:245` | Catch-all handlers surface raw exception strings; no sanitizing global handler |
+| 25 | Cross-user state bleed: `/api/v1/preferences` PUT into module-global (dup of #14) | gapfill | Low | High | Yes | `apps/web/src/app/api/v1/preferences/route.ts:6` | Same as #14 |
+| 26 | `/api/training/trigger` privileged Vertex AI tuning + GCS upload, no authz | gapfill | Low | Med | Yes | `apps/web/src/app/api/training/trigger/route.ts:40` | Ambient-cloud-identity operation exposed as ordinary BFF route, only coarse login gate |
+| 27 | Free-tier chat quota shares one bucket keyed on constant `'anonymous'` | gapfill | Low | High | Yes | `apps/web/src/app/api/chat/route.ts:34-54` | Anonymous principals not disambiguated; per-user quota becomes global |
+
+**Residual duplication:** #14/#23/#25 are the same `/api/v1/preferences` module-global bug reported three times; #11/#15 are the same `/api/training/status` disclosure. Dedup did not fully collapse these. Treat as **two** underlying defects, not five (see §6).
+
+---
+
+## 3. Finding Clusters (fix together)
+
+- **yt-dlp sink cluster:** #1, #2, #3, #9, #17 (transcript-action) + #6 (chat). One fix set: (a) add the anchored YouTube regex validator to `TranscriptActionRequest` and `ChatRequest`; (b) reconstruct the URL from the extracted 11-char id before any fetch; (c) insert `"--"` before `video_url` in every yt-dlp argv.
+- **Opt-in/fail-open access control:** #4, #7, #13, #27 all stem from auth/rate-limit defaulting permissive.
+- **No tenant model in the BFF:** #11, #12, #14/#23/#25, #15, #26.
+- **Deployed-app hardening drift:** #5, #19, #20, #22, #24 (all on the shipped `youtube_extension.main:app`).
+
+---
+
+## 4. High-Severity Detail
+
+### Finding #1 — SSRF via unvalidated `video_url` → yt-dlp/pytube (High, Confidence High)
+**Evidence.** `TranscriptActionRequest.video_url` (`src/youtube_extension/backend/api/v1/models.py:597`) is a bare `str` with no `@validator`, unlike `VideoProcessJobRequest` (`models.py:72`), `VideoProcessingRequest` (`:233`), `MarkdownRequest` (`:285`), `VideoToSoftwareRequest` (`:353`), which all enforce `^(https?://)?(www\.)?(youtube\.com/watch\?v=|youtu\.be/|youtube\.com/embed/)[A-Za-z0-9_-]{11}`. Handler `run_transcript_action` (`router.py:466`) calls `workflow.fetch_video_metadata(request.video_url)` unconditionally, *before* the sync/async branch. Workflow `validate_video_url` (`transcript_action_workflow.py:225-242`) only rejects playlists. Both `extract_video_id` (`utils/video_utils.py:53`) and `robust._extract_video_id` (`robust.py:696-712`) use the permissive `(?:v=|/)([0-9A-Za-z_-]{11}).*`, so `http://169.254.169.254/aaaaaaaaaaa` passes. On YouTube-API/pytube/search failure the code falls through to `_get_metadata_ytdlp` (`robust.py:147-168`) → `subprocess.run(["yt-dlp","--dump-json","--skip-download", ])`; a second sink `_download_video_file` (`transcript_action_workflow.py:1000-1001`) runs `yt_dlp.YoutubeDL(...).extract_info(video_url, download=True)`. yt-dlp is a hard dependency (`requirements.txt:64`, `pyproject.toml:109`). No private-IP/allowlist guard exists on this path (grep for `169.254`/`is_private`/`allowlist` returns nothing); `WEBSHARE_PROXY_URL` (`utils/proxy.py:32-44`) is off by default.
+**Reachability / trace.** Public Next.js proxy `apps/web/src/app/api/video/route.ts:54-76` takes `body.url` with no host validation, forwards `{video_url:url}` to backend `/api/v1/transcript-action`, and injects server-side `EVENTRELAY_API_KEY` as `X-API-Key` — so an unauthenticated internet caller drives the SSRF without the backend key. `/api/transcribe` (`transcription-service.ts:63-66`) is a second entry. Cloud Run is `--allow-unauthenticated`, so the app key is the only backend gate. `fetch_video_metadata` fires on *every* request regardless of video length → blind SSRF (internal port/host probing, forced outbound requests, metadata-endpoint hits). *Caveat from validation:* GCP metadata-credential theft is impeded (yt-dlp won't send `Metadata-Flavor: Google`); blind internal probing is fully achievable.
+**Remediation.** Add the anchored YouTube-host validator to `TranscriptActionRequest.video_url` (mirror `VideoProcessJobRequest.validate_video_url`); reconstruct the canonical `https://www.youtube.com/watch?v=` URL from the already-extracted 11-char id and pass *that* to all fetchers; enforce an egress allowlist / block RFC1918 + link-local in `utils/proxy.py`.
+
+### Finding #2 — Argument injection (CWE-88) into yt-dlp on transcript-action (High, Confidence Med)
+**Evidence.** `robust.py:155-165` builds `cmd = ["yt-dlp","--dump-json","--skip-download"]` then `cmd.append(video_url)` with **no `--` end-of-options separator**. A `video_url` starting with `-` (e.g. `--config-locations=/aaaaaaaaaaa`) is parsed by yt-dlp as an option, not a URL. The payload still embeds a valid 11-char id substring to pass `_extract_video_id`, while a nonexistent id forces YouTube-API/pytube/search to fail so the subprocess fallback is reached. `subprocess.run` uses a list (no `shell=True`), so exactly one attacker-controlled argv token is injected.
+**Reachability / trace.** Same confused-deputy path as #1 via `apps/web/src/app/api/video/route.ts:73-78`. The backend endpoint is deny-by-default (`APIKeyAuthMiddleware`), but the proxy satisfies the key. When `NEXTAUTH_SECRET` is unset (documented safe-rollout default) the proxy is anonymous-reachable.
+**Impact bounds (validation).** Single argv token, no shell → *guaranteed* primitives are single-flag injection: SSRF via a proxy-style flag, DoS, info/output disclosure. Full RCE via `--config-locations`/`--exec` additionally requires an attacker-referenceable config file.
+**Remediation.** Insert `cmd.append("--")` before the URL (one line), and apply the host validator from #1. Mirror the fix at every yt-dlp call site.
+
+### Finding #3 — Deployed transcript-action + chat pass raw `video_url` to yt-dlp positional arg (High, Confidence High)
+**Evidence.** The two deployed v1 endpoints accepting a video URL *without* a host validator are transcript-action and chat: `TranscriptActionRequest` (`models.py:594-605`) and `ChatRequest` (`models.py:184-205`) declare `video_url: str` with no validator. **Chain A** (transcript-action) = the #1/#2 chain into `robust.py:155-160`. **Chain B** (chat): `router.py:584` re-extracts an id with the loose regex; on cache miss `router.py:598-602` calls `process_video_for_markdown(request.video_url)` → `video_processing_service.py:136` → `enhanced_video_processor.py:299` `ytdlp_cmd.extend(["-o", audio_path, video_url]); subprocess.run(ytdlp_cmd)`. Router mounted at `main.py:181`.
+**Reachability / trace.** `apps/web/src/app/api/video/route.ts:73-77` and `apps/web/src/app/api/chat/route.ts:85-102` forward user input while injecting `EVENTRELAY_API_KEY`. Login gating is opt-in (`proxy.ts:31, 224-244`): fully unauthenticated when `NEXTAUTH_SECRET` unset, else any authenticated free-tier user. `get_video_metadata` swallows downstream exceptions and returns minimal metadata → true blind SSRF (benign-looking HTTP response, side effect still fires).
+**Preconditions (validation, why not Critical).** Backend sink requires `BACKEND_URL` wired + `EVENTRELAY_API_KEY` set (the documented prod topology). SSRF is blind; Chain B additionally requires `OPENAI_API_KEY` + both transcript providers failing. Chain A's blind SSRF + argument injection remains reachable through the public proxy.
+**Remediation.** Same as #1/#2 applied to both `TranscriptActionRequest` and `ChatRequest`, plus `--` separators in both subprocess builders.
+
+### Finding #4 — Unauthenticated Veo-3.1 generation, financial DoS (High, Confidence High)
+**Evidence.** `POST /api/video/generate` (`apps/web/src/app/api/video/generate/route.ts:43-119`) POSTs to the Vercel AI Gateway with `model: 'google/veo-3.1-generate-001'` (line 113), up to 60s clips (line 13), from an attacker-controlled `prompt` (≤1000 chars). No auth, no NextAuth check, no Pro/billing gate (grep for `resolveTrustedBillingEmail`/`isProSubscriber`/`getToken`/`billing` returns nothing). Only route-level control is a **module-scoped in-memory limiter of 3 req/IP/10min** (lines 7-41) — per-serverless-instance and per-IP. Peer routes prove the gap: `agents/dispatch/route.ts` calls `isProSubscriber` (402 for non-Pro); `chat/route.ts` calls `resolveTrustedBillingEmail`+`checkFreeChatQuota`. The costliest route omits both.
+**Reachability / trace.** Middleware wired (`apps/web/middleware.ts` matcher `['/api/:path*']`). `PUBLIC_API_PREFIXES` excludes `/api/video`. Two reachable states: (1) `NEXTAUTH_SECRET` unset (documented default) → anonymous internet callers; (2) set → any *free-tier* authenticated user (no Pro gate). The middleware AI limiter (12/min) **fails open** in prod when `UPSTASH_REDIS_*` unset (`proxy.ts:194-200`) and is disableable via `UVAI_RATE_LIMIT_DISABLED=1`. Even enforced, 12 Veo clips/min/IP is unbounded expensive spend; the route's own limiter is bypassed by IP rotation and autoscaling.
+**Remediation.** Require authentication + `isProSubscriber` (or a durable per-principal quota) in the handler, matching `agents/dispatch`. Move rate limiting to a shared/durable store and **fail closed** for paid-API routes when Redis is unavailable. Add a hard per-account daily Veo cap and cost alarm.
+
+---
+
+## 5. Validate Stage
+
+- **Attempts validated:** 49. **Confirmed:** 27. **Refuted / killed:** **22** (45% of attempts). This is a healthy skeptic-to-signal ratio; the validators were independent of the hunters (no self-grading).
+- **Refuted findings are not itemized in the data handed to this report** (only survivors were passed through), so specific false-positive titles cannot be named here. The high refute count indicates aggressive disproof rather than rubber-stamping.
+- **Notable severity downgrades during validation** (hunter claim partially refuted — 6 findings):
+ - #6 arg-injection-chat: **High → Medium** (whisper branch is env-gated: needs empty YT transcript + empty Gemini + `OPENAI_API_KEY`).
+ - #8 Next.js CVE: **High → Medium** (exploit chain broken twice by default — 0 of 34 generated apps ship `middleware.ts`/next-auth; default Vercel target strips `x-middleware-subrequest`).
+ - #9 SSRF: **High → Medium** (blind not partial-read — stderr is swallowed; internal reach is proxy-contingent).
+ - #12 IDOR: **Medium → Low** (chunk text derives from public YouTube transcript; no user attribution stored).
+ - #19 security headers: **Medium → Low** (API auth is header-based not cookie, so SSL-strip gains little; frontend origin already sets HSTS/CSP).
+ - #20 body-size DoS: **Medium → Low** (Cloud Run HTTP/1 frontend caps requests at 32 MiB, refuting the multi-GB scenario).
+- **Corrections the validators logged against hunter evidence** (kept but caveated): #5 the "150+ keys" figure overcounts (116 private-key + 38 public-InnerTube-key occurrences; still a real leak of a billable Gemini key); #4/#26 metadata-server unreachable on Vercel makes #26's live tuning inert today; #25 the claimed AI-prompt-poisoning impact of `/preferences` is aspirational (no consumer reads those fields).
+
+---
+
+## 6. Coverage & Gaps (no silent caps)
+
+- **Read-only, static analysis only.** No live exploitation was performed — no SSRF payload was actually fired at `169.254.169.254`, no Veo clip was generated, no yt-dlp option-injection was executed. Reachability is asserted from source tracing, not runtime proof. The blind-SSRF and argument-injection findings would benefit from a runtime PoC to confirm yt-dlp's generic-extractor behavior on the deployed image.
+- **Validator budget capped at 6 per hunt task.** Findings beyond the 6th per task were not independently re-validated; some genuine issues may have been dropped before reaching this report.
+- **Recon covered 6 subsystems** across 12 hunt tasks + 5 gapfill tasks. Subsystems *not* explicitly represented in surviving findings (and therefore under-covered): the **MCP server implementations** (`mcp-servers/litert-mcp`, `shared-state`), the **Alembic/Postgres data layer** (SQL injection, migration safety), **NextAuth session/JWT handling** beyond the opt-in gate, **CORS `allow_credentials=True`** origin policy specifics, and the **Kubernetes/Terraform infrastructure** manifests (secrets mounting, RBAC). Absence of findings there is *not* evidence of safety.
+- **Dedup incomplete.** `/api/v1/preferences` (#14, #23, #25) and `/api/training/status` (#11, #15) each appear multiple times. The true finding count is closer to **~24 distinct defects**.
+- **Deployment-state dependence.** Roughly half the findings' *unauthenticated* reachability hinges on `NEXTAUTH_SECRET` being unset and/or Upstash being unconfigured. Those are documented as the current live-site defaults (`docs/deployment/VERCEL_PRODUCTION_CHECKLIST_AUDIT.md`, `LAUNCH_CHECKLIST.md`), but a hardened deploy narrows several Highs/Mediums to authenticated-only. This audit did not verify the *actual* live env-var state of `uvai.io`.
+- **CVE currency.** CVE applicability (#8) was assessed from version ranges, not by running an SCA tool against a resolved lockfile of the deployed backend itself.
+
+---
+
+## 7. Methodology Critique (challenge our own conclusions)
+
+- **"Externally reachable" is doing heavy lifting on a conditional.** The strongest Highs (#1–#4) depend on the *confused-deputy* proxy path (frontend injects the backend key) **and** on `NEXTAUTH_SECRET` being unset for full anonymity. If OAuth is enabled in prod, the anonymous claim collapses to "any authenticated free user," which is materially weaker. The report treats the permissive default as the operative config because the repo's own docs say so — but this is documentary evidence, not observed runtime state. A single `curl` against the live endpoint would settle it and was not performed.
+- **The yt-dlp RCE ceiling is asserted, not demonstrated.** Every argument-injection finding (#2, #6, #17) concedes that only *one* argv token is injectable (list-form subprocess, no shell) and that `--exec`/`--config-locations` RCE needs a second precondition (an attacker-referenceable file, or a positional URL to trigger download-time exec). The confident "escalating toward RCE" framing outruns the evidence; the *proven* primitive is single-flag abuse (SSRF/DoS/file-read-write). Readers should not treat these as confirmed RCE.
+- **Overlapping findings inflate the apparent breadth.** Five of 27 rows are two underlying bugs. The recon/hunt fan-out rediscovered the same `video_url→yt-dlp` and `preferences` defects from multiple task angles; dedup should have collapsed them. The headline "27 findings" overstates distinct surface area by ~10%.
+- **Medium-confidence flags on the injection findings are appropriate and under-weighted in the summary.** #2 and #6 are `confidence: medium` precisely because the exploit requires forcing the metadata-fallback branch and (for #6) a specific env combination. The executive summary's "blind SSRF + CWE-88" phrasing is accurate for reachability but should not be read as high-confidence *impact*.
+- **Fail-open findings are real but partly self-refuting as "vulnerabilities."** #7/#13/#27 describe a system that is *intentionally* open pre-launch (`login/page.tsx` states the product is "currently open for use without an account"). These are correctly latent-control-gap findings, not active breaches — the risk is a future config regression, which is a governance/process concern more than an exploitable bug today.
+- **Static-only means false-negative risk is unquantified.** With 22 refutations, the pipeline demonstrably filters noise well — but it says nothing about what recon *missed*. The clean-looking MCP/DB/infra subsystems are the most likely home of undiscovered issues, and no negative-coverage assertion should be inferred from their absence here.
+
+**Top 4 to fix now:** #4 (add auth+Pro gate to Veo route), then the yt-dlp cluster #1/#2/#3/#6 as one change (host validator + id-reconstruction + `--` separator), then #5 (move keys to `x-goog-api-key` header, redact `key=` in logs, rotate the exposed key), then flip auth/rate-limit to fail-closed for AI-cost routes (#7).
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
deleted file mode 100644
index 1820ce472..000000000
--- a/package-lock.json
+++ /dev/null
@@ -1,12785 +0,0 @@
-{
- "name": "eventrelay",
- "version": "1.0.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "eventrelay",
- "version": "1.0.0",
- "workspaces": [
- "apps/*"
- ],
- "dependencies": {
- "@ai-sdk/gateway": "^4.0.23",
- "@dataconnect/generated": "file:src/dataconnect-generated",
- "@google-cloud/text-to-speech": "^6.4.0",
- "@google/genai": "^2.12.0",
- "@opentelemetry/core": "^2.9.0",
- "@types/node": "^26.1.1",
- "ai": "^7.0.31",
- "chrome-devtools-mcp": "^1.6.0",
- "dotenv": "^17.4.2",
- "openai": "^6.48.0",
- "react": "^19",
- "react-dom": "^19",
- "tsx": "^4.23.1"
- },
- "devDependencies": {
- "@modelcontextprotocol/sdk": "^1.26.0",
- "brace-expansion": "^5.0.8",
- "eslint": "^9.39.5",
- "next": "^16.2.10",
- "turbo": "^2.10.5",
- "typescript": "6.0.3",
- "vitest": "^4.1.10"
- },
- "engines": {
- "node": ">=20.6.0",
- "npm": ">=8.0.0"
- }
- },
- "apps/web": {
- "name": "building-production-ai-infrastructure-platform",
- "version": "0.1.0",
- "dependencies": {
- "@ai-sdk/gateway": "^4.0.23",
- "@dataconnect/generated": "file:src/dataconnect-generated",
- "@google/genai": "^2.12.0",
- "@google/generative-ai": "^0.24.1",
- "@opentelemetry/api": "1.9.1",
- "@opentelemetry/core": "2.9.0",
- "@opentelemetry/exporter-trace-otlp-http": "0.220.0",
- "@opentelemetry/instrumentation": "0.220.0",
- "@opentelemetry/resources": "2.9.0",
- "@opentelemetry/sdk-trace-base": "2.9.0",
- "@opentelemetry/semantic-conventions": "1.43.0",
- "@sentry/nextjs": "^10.66.0",
- "@stripe/stripe-js": "^9.10.0",
- "@supabase/supabase-js": "^2.110.5",
- "@upstash/redis": "^1.38.0",
- "@upstash/search": "^0.1.7",
- "@vercel/analytics": "^2.0.1",
- "@vercel/functions": "^3.7.5",
- "@vercel/speed-insights": "^2.0.0",
- "ai": "^7.0.31",
- "class-variance-authority": "^0.7.0",
- "clsx": "^2.1.1",
- "lucide-react": "^1.25.0",
- "next": "^16.2.10",
- "next-auth": "^4.24.15",
- "openai": "^6.48.0",
- "react": "^19",
- "react-dom": "^19",
- "server-only": "^0.0.1",
- "stripe": "^22.3.1",
- "tailwind-merge": "^3.6.0",
- "use-sync-external-store": "^1.6.0",
- "zod": "^4.4.3",
- "zustand": "^5.0.14"
- },
- "devDependencies": {
- "@playwright/test": "^1.61.1",
- "@tailwindcss/postcss": "^4.3.3",
- "@types/node": "^26",
- "@types/react": "^19",
- "@types/react-dom": "^19",
- "autoprefixer": "^10.5.4",
- "eslint": "^9.39.5",
- "eslint-config-next": "^16.2.10",
- "playwright": "^1.61.1",
- "postcss": "^8.5.21",
- "tailwindcss": "^4.3.3",
- "typescript": "6.0.3",
- "vite": "^8.1.5",
- "vitest": "^4.1.10"
- }
- },
- "apps/web/node_modules/@dataconnect/generated": {
- "resolved": "apps/web/src/dataconnect-generated",
- "link": true
- },
- "apps/web/node_modules/@next/eslint-plugin-next": {
- "version": "16.2.10",
- "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.2.10.tgz",
- "integrity": "sha512-Gs8D2m21VnJeFo9qvYIIqJH94frWerWYu41BprU1pLtRVF7PCQNLiFZZ3fG+iPuj3K83Cwv/rt+msLOy8Qgu3Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fast-glob": "3.3.1"
- }
- },
- "apps/web/node_modules/@opentelemetry/api": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz",
- "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=8.0.0"
- }
- },
- "apps/web/node_modules/@opentelemetry/exporter-trace-otlp-http": {
- "version": "0.220.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.220.0.tgz",
- "integrity": "sha512-/+ExB3lRkf+erv4PnoywyL7RHKITidxtUpUTS55k7OQ0dB42S7gEF1gry7swb9MSm1hYLUhJg4QQh9W8SpwwqA==",
- "license": "Apache-2.0",
- "dependencies": {
- "@opentelemetry/core": "2.9.0",
- "@opentelemetry/otlp-exporter-base": "0.220.0",
- "@opentelemetry/otlp-transformer": "0.220.0",
- "@opentelemetry/resources": "2.9.0",
- "@opentelemetry/sdk-trace": "2.9.0"
- },
- "engines": {
- "node": "^18.19.0 || >=20.6.0"
- },
- "peerDependencies": {
- "@opentelemetry/api": "^1.3.0"
- }
- },
- "apps/web/node_modules/@opentelemetry/otlp-exporter-base": {
- "version": "0.220.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.220.0.tgz",
- "integrity": "sha512-CXYo8UD5Mn9YbgebO2EL4wejtA+gxLmLiu6HCk2KH2BR7XhFN6/6p1UlCb23DYCjeYkndevLHuejCCN1yx4+OQ==",
- "license": "Apache-2.0",
- "dependencies": {
- "@opentelemetry/core": "2.9.0",
- "@opentelemetry/otlp-transformer": "0.220.0"
- },
- "engines": {
- "node": "^18.19.0 || >=20.6.0"
- },
- "peerDependencies": {
- "@opentelemetry/api": "^1.3.0"
- }
- },
- "apps/web/node_modules/@opentelemetry/otlp-transformer": {
- "version": "0.220.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.220.0.tgz",
- "integrity": "sha512-lXGrv7KXZ0gNH9SVNUaa6vv6phVYGvJxfXAlMbzbakiXru75f5MZl8Z7oqiMMQD77riVHJCFlQvbZs/VVN2/4A==",
- "license": "Apache-2.0",
- "dependencies": {
- "@opentelemetry/api-logs": "0.220.0",
- "@opentelemetry/core": "2.9.0",
- "@opentelemetry/resources": "2.9.0",
- "@opentelemetry/sdk-logs": "0.220.0",
- "@opentelemetry/sdk-metrics": "2.9.0",
- "@opentelemetry/sdk-trace": "2.9.0"
- },
- "engines": {
- "node": "^18.19.0 || >=20.6.0"
- },
- "peerDependencies": {
- "@opentelemetry/api": "^1.3.0"
- }
- },
- "apps/web/node_modules/@opentelemetry/sdk-logs": {
- "version": "0.220.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.220.0.tgz",
- "integrity": "sha512-WywcTkQtv2iNmt+6y5Kcd4rzvx9bLVsBa2Nwcmg01IUaBTkTow3W4d9KE5vNBpEDtb9tp21WcRBY/lANRrApYA==",
- "license": "Apache-2.0",
- "dependencies": {
- "@opentelemetry/api-logs": "0.220.0",
- "@opentelemetry/core": "2.9.0",
- "@opentelemetry/resources": "2.9.0",
- "@opentelemetry/semantic-conventions": "^1.29.0"
- },
- "engines": {
- "node": "^18.19.0 || >=20.6.0"
- },
- "peerDependencies": {
- "@opentelemetry/api": ">=1.4.0 <1.10.0"
- }
- },
- "apps/web/node_modules/@opentelemetry/sdk-metrics": {
- "version": "2.9.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.9.0.tgz",
- "integrity": "sha512-Xx8RGS4H5XEBl01WuCreMIpiah9cCXMbSkeuIePPdD2cUpq/vUzYmj8E/MK1OsbOc93FuAD4jfn2WOacKwLn7Q==",
- "license": "Apache-2.0",
- "dependencies": {
- "@opentelemetry/core": "2.9.0",
- "@opentelemetry/resources": "2.9.0"
- },
- "engines": {
- "node": "^18.19.0 || >=20.6.0"
- },
- "peerDependencies": {
- "@opentelemetry/api": ">=1.9.0 <1.10.0"
- }
- },
- "apps/web/node_modules/@opentelemetry/semantic-conventions": {
- "version": "1.43.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.43.0.tgz",
- "integrity": "sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=14"
- }
- },
- "apps/web/node_modules/@sentry/browser": {
- "version": "10.65.0",
- "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-10.65.0.tgz",
- "integrity": "sha512-XUDDsx0qxzeIlcOu1fDEqTcDl0eiOqghsgV+ReuuNP4jYjZ9kUQxE3rXWM5mlT1pBi4VaQ4FHqvQZZrRXy+oDw==",
- "license": "MIT",
- "dependencies": {
- "@sentry/browser-utils": "10.65.0",
- "@sentry/conventions": "^0.15.1",
- "@sentry/core": "10.65.0",
- "@sentry/feedback": "10.65.0",
- "@sentry/replay": "10.65.0",
- "@sentry/replay-canvas": "10.65.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "apps/web/node_modules/@sentry/browser-utils": {
- "version": "10.65.0",
- "resolved": "https://registry.npmjs.org/@sentry/browser-utils/-/browser-utils-10.65.0.tgz",
- "integrity": "sha512-4J0mkfNJAGUOkpg1ZggizyftFTn9N20b+Jl87UnWsDUkNG0Ic1l/FIzMPTVxXrAnhBGu0ULO0TFWMoQ5s3QtZw==",
- "license": "MIT",
- "dependencies": {
- "@sentry/conventions": "^0.15.1",
- "@sentry/core": "10.65.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "apps/web/node_modules/@sentry/conventions": {
- "version": "0.15.1",
- "resolved": "https://registry.npmjs.org/@sentry/conventions/-/conventions-0.15.1.tgz",
- "integrity": "sha512-ZLP8bRdMON3prWE2tJyImuYscCxdcJeIPIhrOs/rgyFm3C1nCh1B6gdvPj3AZ5zW08oSFFCsq7T+tYEW3h8MNA==",
- "license": "MIT",
- "engines": {
- "node": ">=14"
- }
- },
- "apps/web/node_modules/@sentry/core": {
- "version": "10.65.0",
- "resolved": "https://registry.npmjs.org/@sentry/core/-/core-10.65.0.tgz",
- "integrity": "sha512-3aqtmM5NgNGo45BNaaBzi0LPQZAw//NEL4HKS5fXm12pJMa4KEkze8DEKnkTEIrGnWaOJKamecHKlnNg/Mqf/Q==",
- "license": "MIT",
- "dependencies": {
- "@sentry/conventions": "^0.15.1"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "apps/web/node_modules/@sentry/feedback": {
- "version": "10.65.0",
- "resolved": "https://registry.npmjs.org/@sentry/feedback/-/feedback-10.65.0.tgz",
- "integrity": "sha512-ck8h7wgd3F3bYNk0v1OgohmyLBeXcKxqlfBJRtQq4k6KZUq+pXimOG7ckNguVMYjCo3PEfuG+ckKc21yqotKug==",
- "license": "MIT",
- "dependencies": {
- "@sentry/core": "10.65.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "apps/web/node_modules/@sentry/nextjs": {
- "version": "10.65.0",
- "resolved": "https://registry.npmjs.org/@sentry/nextjs/-/nextjs-10.65.0.tgz",
- "integrity": "sha512-9gDKQAAXcWh210fMI/ZNCa7940HYt7dGjnJVP0Tk9ozUR57W4C9vXvHJDTYPJrFxYxTHw7lwxWGervk8a6Tf4g==",
- "license": "MIT",
- "dependencies": {
- "@opentelemetry/api": "^1.9.1",
- "@rollup/plugin-commonjs": "28.0.1",
- "@sentry/browser-utils": "10.65.0",
- "@sentry/bundler-plugin-core": "^5.3.0",
- "@sentry/conventions": "^0.15.1",
- "@sentry/core": "10.65.0",
- "@sentry/node": "10.65.0",
- "@sentry/opentelemetry": "10.65.0",
- "@sentry/react": "10.65.0",
- "@sentry/vercel-edge": "10.65.0",
- "@sentry/webpack-plugin": "^5.3.0",
- "rollup": "^4.60.3",
- "stacktrace-parser": "^0.1.11"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "next": "^13.2.0 || ^14.0 || ^15.0.0-rc.0 || ^16.0.0-0"
- }
- },
- "apps/web/node_modules/@sentry/nextjs/node_modules/@opentelemetry/api": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz",
- "integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=8.0.0"
- }
- },
- "apps/web/node_modules/@sentry/node": {
- "version": "10.65.0",
- "resolved": "https://registry.npmjs.org/@sentry/node/-/node-10.65.0.tgz",
- "integrity": "sha512-t35dcdyksysVch/m/XdLgGJqGKJhr9eMD30Ctn3TeQ8yMB0wNXySfjPR5Yg93fpjmfaHtzc6iYIXRAvgNVfrvA==",
- "license": "MIT",
- "dependencies": {
- "@opentelemetry/api": "^1.9.1",
- "@opentelemetry/instrumentation": "^0.220.0",
- "@opentelemetry/sdk-trace-base": "^2.9.0",
- "@sentry/conventions": "^0.15.1",
- "@sentry/core": "10.65.0",
- "@sentry/node-core": "10.65.0",
- "@sentry/opentelemetry": "10.65.0",
- "@sentry/server-utils": "10.65.0",
- "import-in-the-middle": "^3.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "apps/web/node_modules/@sentry/node-core": {
- "version": "10.65.0",
- "resolved": "https://registry.npmjs.org/@sentry/node-core/-/node-core-10.65.0.tgz",
- "integrity": "sha512-U01X9mPT+jZnsLPmPWfBU67Ka+t/Sdd9RGAuvGoKdrI6N47a/9PDkM9oCW+kj0fmZwogZHTgSnzJU5oi3pImgA==",
- "license": "MIT",
- "dependencies": {
- "@sentry/conventions": "^0.15.1",
- "@sentry/core": "10.65.0",
- "@sentry/opentelemetry": "10.65.0",
- "import-in-the-middle": "^3.0.0"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@opentelemetry/api": "^1.9.0",
- "@opentelemetry/core": "^1.30.1 || ^2.1.0",
- "@opentelemetry/exporter-trace-otlp-http": ">=0.57.0 <1",
- "@opentelemetry/instrumentation": ">=0.57.1 <1",
- "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0"
- },
- "peerDependenciesMeta": {
- "@opentelemetry/api": {
- "optional": true
- },
- "@opentelemetry/core": {
- "optional": true
- },
- "@opentelemetry/exporter-trace-otlp-http": {
- "optional": true
- },
- "@opentelemetry/instrumentation": {
- "optional": true
- },
- "@opentelemetry/sdk-trace-base": {
- "optional": true
- }
- }
- },
- "apps/web/node_modules/@sentry/node/node_modules/@opentelemetry/api": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz",
- "integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=8.0.0"
- }
- },
- "apps/web/node_modules/@sentry/opentelemetry": {
- "version": "10.65.0",
- "resolved": "https://registry.npmjs.org/@sentry/opentelemetry/-/opentelemetry-10.65.0.tgz",
- "integrity": "sha512-8C6FPvm3XBvUrkM52dX3Gz0p2H0Ij8t4sahUA+GTiCz0WM0fnyPeQPGC/b6I4jamV9UXyCZRnE1UEEGCoD+c7A==",
- "license": "MIT",
- "dependencies": {
- "@sentry/conventions": "^0.15.1",
- "@sentry/core": "10.65.0"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@opentelemetry/api": "^1.9.0",
- "@opentelemetry/core": "^1.30.1 || ^2.1.0",
- "@opentelemetry/sdk-trace-base": "^1.30.1 || ^2.1.0"
- }
- },
- "apps/web/node_modules/@sentry/react": {
- "version": "10.65.0",
- "resolved": "https://registry.npmjs.org/@sentry/react/-/react-10.65.0.tgz",
- "integrity": "sha512-fvHxpuvid0wt9/1N3itcKDyKOjqmYHw3MBSt5Pki3Iz4CL2CmgQp9ZFv/CA7UhMnEvn2Gd+Qc2UKxujZWd8FLg==",
- "license": "MIT",
- "dependencies": {
- "@sentry/browser": "10.65.0",
- "@sentry/conventions": "^0.15.1",
- "@sentry/core": "10.65.0"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "react": "^16.14.0 || 17.x || 18.x || 19.x"
- }
- },
- "apps/web/node_modules/@sentry/replay": {
- "version": "10.65.0",
- "resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-10.65.0.tgz",
- "integrity": "sha512-aW988CcQBNArbOMzOFOziipHz6uQyXSa4i5CPWsu+nhVPTJHafosi5Lv9n6NM/icDX5e23VdnX6mZd8SyJuo8A==",
- "license": "MIT",
- "dependencies": {
- "@sentry/browser-utils": "10.65.0",
- "@sentry/core": "10.65.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "apps/web/node_modules/@sentry/replay-canvas": {
- "version": "10.65.0",
- "resolved": "https://registry.npmjs.org/@sentry/replay-canvas/-/replay-canvas-10.65.0.tgz",
- "integrity": "sha512-A7X3RVk1Gk+knK8Ip/2EjejckNCLgCfRZo6eGlsy6qyz904KBpYmys1a0o7QkzFRjhIndjHAfcVxwt6jSLJlrQ==",
- "license": "MIT",
- "dependencies": {
- "@sentry/core": "10.65.0",
- "@sentry/replay": "10.65.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "apps/web/node_modules/@sentry/server-utils": {
- "version": "10.65.0",
- "resolved": "https://registry.npmjs.org/@sentry/server-utils/-/server-utils-10.65.0.tgz",
- "integrity": "sha512-80toEFD6s+0Le7jrYB6pHWLF703WSg0WyavAWqrBGWG8JkREHgedAxzFYgoY5GlMI756qk6Ea7UzhJTHd2zAXA==",
- "license": "MIT",
- "dependencies": {
- "@apm-js-collab/code-transformer": "^0.15.0",
- "@apm-js-collab/code-transformer-bundler-plugins": "^0.5.0",
- "@apm-js-collab/tracing-hooks": "^0.10.1",
- "@sentry/conventions": "^0.15.1",
- "@sentry/core": "10.65.0",
- "magic-string": "~0.30.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "apps/web/node_modules/@sentry/vercel-edge": {
- "version": "10.65.0",
- "resolved": "https://registry.npmjs.org/@sentry/vercel-edge/-/vercel-edge-10.65.0.tgz",
- "integrity": "sha512-Z1sk2yBHrcsk/QMIzgMRTHitUN1zogzn5eQEc7umWmWwpP6zpDLMDxeeH2F1Cy2vzQFKa53PaWz7HXk4n617eg==",
- "license": "MIT",
- "dependencies": {
- "@opentelemetry/api": "^1.9.1",
- "@sentry/core": "10.65.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "apps/web/node_modules/@sentry/vercel-edge/node_modules/@opentelemetry/api": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz",
- "integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=8.0.0"
- }
- },
- "apps/web/node_modules/@stripe/stripe-js": {
- "version": "9.9.0",
- "resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-9.9.0.tgz",
- "integrity": "sha512-Vwqe6Q5cU4i82tPyAv2BpaW/fQSNdOSO4/J8EeDLPp5/oIZiMmdB+Hgh863zFH+rtoxpuWGvD1L7QPh8k1Rdvw==",
- "license": "MIT",
- "engines": {
- "node": ">=12.16"
- }
- },
- "apps/web/node_modules/@tailwindcss/node": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.2.tgz",
- "integrity": "sha512-yWP/sqEcBLaD8JuA6zNwxoYKr75qxTioYwlRwekj5Jr/I5GXnoJfjetH/psLUIv74cYTH2lBUEzBkinthoYcBg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/remapping": "^2.3.5",
- "enhanced-resolve": "5.21.6",
- "jiti": "^2.7.0",
- "lightningcss": "1.32.0",
- "magic-string": "^0.30.21",
- "source-map-js": "^1.2.1",
- "tailwindcss": "4.3.2"
- }
- },
- "apps/web/node_modules/@tailwindcss/oxide": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.2.tgz",
- "integrity": "sha512-z8ZgnzX8gdNoWLBLqBPoh/sjnxkwvf9ZuWjnO0l0yIzbLa5/9S+eC5QxGZKRobVHIC3/1BoMWjHblqWjcgFgag==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 20"
- },
- "optionalDependencies": {
- "@tailwindcss/oxide-android-arm64": "4.3.2",
- "@tailwindcss/oxide-darwin-arm64": "4.3.2",
- "@tailwindcss/oxide-darwin-x64": "4.3.2",
- "@tailwindcss/oxide-freebsd-x64": "4.3.2",
- "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.2",
- "@tailwindcss/oxide-linux-arm64-gnu": "4.3.2",
- "@tailwindcss/oxide-linux-arm64-musl": "4.3.2",
- "@tailwindcss/oxide-linux-x64-gnu": "4.3.2",
- "@tailwindcss/oxide-linux-x64-musl": "4.3.2",
- "@tailwindcss/oxide-wasm32-wasi": "4.3.2",
- "@tailwindcss/oxide-win32-arm64-msvc": "4.3.2",
- "@tailwindcss/oxide-win32-x64-msvc": "4.3.2"
- }
- },
- "apps/web/node_modules/@tailwindcss/oxide-android-arm64": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.2.tgz",
- "integrity": "sha512-WHxqIuHpvZ5VtdX6GTl1Ik/Vp2YuN42Et+0CdeaVd/frQ9jAvGmvR8vLT+jk3e8/Q3x8kECB9+R17pgpp2BulA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">= 20"
- }
- },
- "apps/web/node_modules/@tailwindcss/oxide-darwin-arm64": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.2.tgz",
- "integrity": "sha512-GZypeUY/IDJW3877KeM+O67vbXr3MBnbtEL4aYhNErv/JWZhye2vGSWWG9tB6iiqR2MqRNkY8IOUy4NdSZV26w==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 20"
- }
- },
- "apps/web/node_modules/@tailwindcss/oxide-darwin-x64": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.2.tgz",
- "integrity": "sha512-UIIzmefR6KO1sDU7MzRqAxC8iBpft/VhkGjTjnhoS6k7Z3rQ9wEgA1ODSiyH/tcSYssulNm4Ci3hOeK1jH7ccQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 20"
- }
- },
- "apps/web/node_modules/@tailwindcss/oxide-freebsd-x64": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.2.tgz",
- "integrity": "sha512-GN+uAmcI6DNspnCDwtOAZrTz6oukJnp337qZvxqCGLd3BHBzJpO0ZbTLRvJNdztOeAmTzewewGIMPb0tk2R4WA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 20"
- }
- },
- "apps/web/node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.2.tgz",
- "integrity": "sha512-4ABn7qSbdHRwTiDiuWNegCyb5+2FJ4vKIKc3DmKrvAFw7MU1Lm11dIkTPwUaFdTzc7IsOpDbqBrlh0x6y36U/w==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 20"
- }
- },
- "apps/web/node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.2.tgz",
- "integrity": "sha512-wDgEIGwoM8w8pufh9LVt1PahDgNdKXrLC2qfAnV3vAmococ9RWbxeAw4pxPttd/TsJfwjyLf90Dg1y9y8I6Emw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 20"
- }
- },
- "apps/web/node_modules/@tailwindcss/oxide-linux-arm64-musl": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.2.tgz",
- "integrity": "sha512-J5Nuk0uZQIiMTJj3LEx4sAA9tMFUoXQZFv1J6An+QGYe53HKRJuFDi0rpq/tuouCZeAbOBY3kQ6g8qeD4TUjtA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 20"
- }
- },
- "apps/web/node_modules/@tailwindcss/oxide-linux-x64-gnu": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.2.tgz",
- "integrity": "sha512-kqCZpSKOBEJO4mz7OqWoofBZeXTAwaVGPj0ErAj7CojmhKpWVWVOnrt9dE8odoIraZq4oj3ausM37kXi+Tow8w==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 20"
- }
- },
- "apps/web/node_modules/@tailwindcss/oxide-linux-x64-musl": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.2.tgz",
- "integrity": "sha512-cixpqbh2toJDmkuCRI68nXA8ZxNmdK9Y+9v5h3MC3ZQKy/0BO8AWzlkWyRM7JAFSGBlfig4YVTPsK6MVgqz1uw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 20"
- }
- },
- "apps/web/node_modules/@tailwindcss/oxide-wasm32-wasi": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.2.tgz",
- "integrity": "sha512-4ec2Z/LOmRsAgU23CS4xeJfcJlmRg94A/XrbGRCF1gyU/zdDfRLYDVsS+ynSZCmGNxQ1jQriQOKMQeQxBA3Isw==",
- "bundleDependencies": [
- "@napi-rs/wasm-runtime",
- "@emnapi/core",
- "@emnapi/runtime",
- "@tybys/wasm-util",
- "@emnapi/wasi-threads",
- "tslib"
- ],
- "cpu": [
- "wasm32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/core": "^1.11.1",
- "@emnapi/runtime": "^1.11.1",
- "@emnapi/wasi-threads": "^1.2.2",
- "@napi-rs/wasm-runtime": "^1.1.4",
- "@tybys/wasm-util": "^0.10.2",
- "tslib": "^2.8.1"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "apps/web/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": {
- "version": "1.11.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/wasi-threads": "1.2.2",
- "tslib": "^2.4.0"
- }
- },
- "apps/web/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": {
- "version": "1.11.1",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "apps/web/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": {
- "version": "1.2.2",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "apps/web/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": {
- "version": "1.1.4",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@tybys/wasm-util": "^0.10.1"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/Brooooooklyn"
- },
- "peerDependencies": {
- "@emnapi/core": "^1.7.1",
- "@emnapi/runtime": "^1.7.1"
- }
- },
- "apps/web/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": {
- "version": "0.10.2",
- "dev": true,
- "inBundle": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "apps/web/node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": {
- "version": "2.8.1",
- "dev": true,
- "inBundle": true,
- "license": "0BSD",
- "optional": true
- },
- "apps/web/node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.2.tgz",
- "integrity": "sha512-Zyr/M0+XcYZu3bZrUytc7TXvrk0ftWfl8gN2MwekNDzhqhKRUucMPSeOzM0o0wH5AWOU49BsKRrfKxI2atCPMQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 20"
- }
- },
- "apps/web/node_modules/@tailwindcss/oxide-win32-x64-msvc": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.2.tgz",
- "integrity": "sha512-QI9BO7KlNZsp2GuO0jwAAj5jCDABOKXRkCk2XuKTSaNEFSdfzqswYVTtCHBNKHLsqyjFyFkqlDiwkNbTYSssMQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 20"
- }
- },
- "apps/web/node_modules/@tailwindcss/postcss": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.3.2.tgz",
- "integrity": "sha512-rjVWYCa7Ngbi5AarT6k8TkxUG3Wl1QKzHdIZVsjZSzf36Jmo2IKZt/NHRAwly8oDkbBOH0YTu+CHuf9jPxMc+g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@alloc/quick-lru": "^5.2.0",
- "@tailwindcss/node": "4.3.2",
- "@tailwindcss/oxide": "4.3.2",
- "postcss": "^8.5.15",
- "tailwindcss": "4.3.2"
- }
- },
- "apps/web/node_modules/@types/node": {
- "version": "26.0.0",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-26.0.0.tgz",
- "integrity": "sha512-vf2YFi1iY9lHGwNJMs01biZFbKJkrZR1T6/MlzjhJLPdntOHLhTrDSnSVcdtvjihi4VQNlrFRIxLsDBlQpAipA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "undici-types": "~8.3.0"
- }
- },
- "apps/web/node_modules/autoprefixer": {
- "version": "10.5.2",
- "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.2.tgz",
- "integrity": "sha512-rD5t5DwOjJdmSORcTq64j8MawTC+tbQ+HHqjR4NDumamy/ambn1UJrlKL+KdwujWxMkFjPM3pPHOEA9tl4767Q==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/autoprefixer"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "browserslist": "^4.28.4",
- "caniuse-lite": "^1.0.30001799",
- "fraction.js": "^5.3.4",
- "picocolors": "^1.1.1",
- "postcss-value-parser": "^4.2.0"
- },
- "bin": {
- "autoprefixer": "bin/autoprefixer"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- },
- "peerDependencies": {
- "postcss": "^8.1.0"
- }
- },
- "apps/web/node_modules/browserslist": {
- "version": "4.28.4",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.4.tgz",
- "integrity": "sha512-MTc8i/x9jBQd1iMw2CFGS+rwMa07eYjLR0CCTLDACl9xhxy+nIs3KeML/biicXtk9JrZ6dnnTatmc7ErPXIxqw==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "baseline-browser-mapping": "^2.10.38",
- "caniuse-lite": "^1.0.30001799",
- "electron-to-chromium": "^1.5.376",
- "node-releases": "^2.0.48",
- "update-browserslist-db": "^1.2.3"
- },
- "bin": {
- "browserslist": "cli.js"
- },
- "engines": {
- "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
- }
- },
- "apps/web/node_modules/eslint-config-next": {
- "version": "16.2.10",
- "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.2.10.tgz",
- "integrity": "sha512-HSybLOY0QKf39i4FWUqPN0xWiNDi6A6UqJmZtgDkS3zMqjXTqULvj/sueXx3cdCG0mVG+qH6k5/qdegklH1d1w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@next/eslint-plugin-next": "16.2.10",
- "eslint-import-resolver-node": "^0.3.6",
- "eslint-import-resolver-typescript": "^3.5.2",
- "eslint-plugin-import": "^2.32.0",
- "eslint-plugin-jsx-a11y": "^6.10.0",
- "eslint-plugin-react": "^7.37.0",
- "eslint-plugin-react-hooks": "^7.0.0",
- "globals": "16.4.0",
- "typescript-eslint": "^8.46.0"
- },
- "peerDependencies": {
- "eslint": ">=9.0.0",
- "typescript": ">=3.3.1"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "apps/web/node_modules/jose": {
- "version": "4.15.9",
- "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz",
- "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/panva"
- }
- },
- "apps/web/node_modules/lucide-react": {
- "version": "1.25.0",
- "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.25.0.tgz",
- "integrity": "sha512-/mdJTRbiwcLOQ1NZZK1amZF9rIZyvO18D6r9TngE6TG1NmqHgFuT4eE7Xrkm9UsXMbBJD1NlfwHVltCDWHrOTw==",
- "license": "ISC",
- "peerDependencies": {
- "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
- }
- },
- "apps/web/node_modules/nanoid": {
- "version": "3.3.16",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz",
- "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "bin": {
- "nanoid": "bin/nanoid.cjs"
- },
- "engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
- }
- },
- "apps/web/node_modules/next-auth": {
- "version": "4.24.15",
- "resolved": "https://registry.npmjs.org/next-auth/-/next-auth-4.24.15.tgz",
- "integrity": "sha512-NnjYtjrSOAx/TIVFGTX4IfI/9yHnNpi4B7FuLUwuV20v2Zxgr2OGP/YN0ynJuI7y8QOnTBPitfOdEXZrVvhIuA==",
- "license": "ISC",
- "dependencies": {
- "@babel/runtime": "^7.20.13",
- "@panva/hkdf": "^1.0.2",
- "cookie": "^0.7.0",
- "jose": "^4.15.5",
- "oauth": "^0.9.15",
- "openid-client": "^5.4.0",
- "preact": "^10.6.3",
- "preact-render-to-string": "^5.1.19",
- "uuid": "^11.1.1"
- },
- "peerDependencies": {
- "@auth/core": "0.34.3",
- "next": "^12.2.5 || ^13 || ^14 || ^15 || ^16",
- "nodemailer": "^7.0.7",
- "react": "^17.0.2 || ^18 || ^19",
- "react-dom": "^17.0.2 || ^18 || ^19"
- },
- "peerDependenciesMeta": {
- "@auth/core": {
- "optional": true
- },
- "nodemailer": {
- "optional": true
- }
- }
- },
- "apps/web/node_modules/postcss": {
- "version": "8.5.21",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.21.tgz",
- "integrity": "sha512-v4sDNP3fdNiWMfabO7OwOQdOX8TiQSztKyT1Wj0w+j7LDallJThJRBBBmzVGyYj0crMh7jlV4zepPkiNu9UwDQ==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "nanoid": "^3.3.16",
- "picocolors": "^1.1.1",
- "source-map-js": "^1.2.1"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- }
- },
- "apps/web/node_modules/tailwindcss": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.2.tgz",
- "integrity": "sha512-WtctNNSH8A9jlMIqxzuYumOHU5uGZyRv0Q5svQl+oEPy5w84YpBxdb7MdqyiSPQge5jTJ6zFQLq0PFygdccSBA==",
- "dev": true,
- "license": "MIT"
- },
- "apps/web/node_modules/zod": {
- "version": "4.4.3",
- "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz",
- "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/colinhacks"
- }
- },
- "apps/web/node_modules/zustand": {
- "version": "5.0.14",
- "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.14.tgz",
- "integrity": "sha512-/8tAspM5LMPr28b3fwLYrtdj77ECpfZviaP75CMTnwO8ISyaE4GDIG/9rDDYq/cH9D2Xw2A2RXglLInmVBQB/g==",
- "license": "MIT",
- "engines": {
- "node": ">=12.20.0"
- },
- "peerDependencies": {
- "@types/react": ">=18.0.0",
- "immer": ">=9.0.6",
- "react": ">=18.0.0",
- "use-sync-external-store": ">=1.2.0"
- },
- "peerDependenciesMeta": {
- "@types/react": {
- "optional": true
- },
- "immer": {
- "optional": true
- },
- "react": {
- "optional": true
- },
- "use-sync-external-store": {
- "optional": true
- }
- }
- },
- "apps/web/src/dataconnect-generated": {
- "name": "@dataconnect/generated",
- "version": "1.0.0",
- "license": "Apache-2.0",
- "engines": {
- "node": " >=18.0"
- },
- "peerDependencies": {
- "@tanstack-query-firebase/react": "^2.0.0",
- "firebase": "^11.3.0 || ^12.0.0"
- }
- },
- "node_modules/@ai-sdk/gateway": {
- "version": "4.0.23",
- "resolved": "https://registry.npmjs.org/@ai-sdk/gateway/-/gateway-4.0.23.tgz",
- "integrity": "sha512-f85diFdPMXYJpxCjOYZchMQkRH8h3r6lhK4Q2xmzJ7UA2OQ80L3W7tFu61742xGQK7zHWm5AhxYhNuc50H9SGQ==",
- "license": "Apache-2.0",
- "dependencies": {
- "@ai-sdk/provider": "4.0.3",
- "@ai-sdk/provider-utils": "5.0.11",
- "@vercel/oidc": "3.2.0"
- },
- "engines": {
- "node": ">=22"
- },
- "peerDependencies": {
- "zod": "^3.25.76 || ^4.1.8"
- }
- },
- "node_modules/@ai-sdk/provider": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-4.0.3.tgz",
- "integrity": "sha512-e0CpNWJUY7OxAFAnCZkw+ri9QOHWwTs1tXP42782KFGCU07qt8NiXCrCVowyCB5dP2r5/Uls+g2oPd8kOJn9dw==",
- "license": "Apache-2.0",
- "dependencies": {
- "json-schema": "^0.4.0"
- },
- "engines": {
- "node": ">=22"
- }
- },
- "node_modules/@ai-sdk/provider-utils": {
- "version": "5.0.11",
- "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-5.0.11.tgz",
- "integrity": "sha512-7/96wE+ZsKB35iS9ASyllrE4Ym/EolXEB7AkuJ5FI++fmS85BVTAs77890C+1Z2jwHfBKjBQSBmsliOsAh0iFQ==",
- "license": "Apache-2.0",
- "dependencies": {
- "@ai-sdk/provider": "4.0.3",
- "@standard-schema/spec": "^1.1.0",
- "@workflow/serde": "4.1.0",
- "eventsource-parser": "^3.0.8"
- },
- "engines": {
- "node": ">=22"
- },
- "peerDependencies": {
- "zod": "^3.25.76 || ^4.1.8"
- }
- },
- "node_modules/@alloc/quick-lru": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
- "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@apm-js-collab/code-transformer": {
- "version": "0.15.0",
- "resolved": "https://registry.npmjs.org/@apm-js-collab/code-transformer/-/code-transformer-0.15.0.tgz",
- "integrity": "sha512-XmXYVs8CzJ1Aj79noVbn2weUO/XWtRyURpGqx7aU7DOXlUQhR0WKOQNF0okh7PCeY37vxf7kU3v57OAkEPm3ww==",
- "license": "Apache-2.0",
- "dependencies": {
- "@types/estree": "^1.0.8",
- "astring": "^1.9.0",
- "esquery": "^1.7.0",
- "meriyah": "^6.1.4",
- "semifies": "^1.0.0",
- "source-map": "^0.6.0"
- },
- "bin": {
- "code-transformer": "cli.js"
- }
- },
- "node_modules/@apm-js-collab/code-transformer-bundler-plugins": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/@apm-js-collab/code-transformer-bundler-plugins/-/code-transformer-bundler-plugins-0.5.0.tgz",
- "integrity": "sha512-YxLBY5nGlurL7QeJLq6e5g0ouBpAp0pwgyA/5rHXEXwhiPLn9ZHbT+Y2LlP90GT872cSocfjWRYu/fnpuBudNQ==",
- "license": "MIT",
- "dependencies": {
- "@apm-js-collab/code-transformer": "^0.15.0",
- "es-module-lexer": "^2.1.0",
- "magic-string": "^0.30.21",
- "module-details-from-path": "^1.0.4"
- },
- "engines": {
- "node": ">=18.0.0"
- }
- },
- "node_modules/@apm-js-collab/tracing-hooks": {
- "version": "0.10.1",
- "resolved": "https://registry.npmjs.org/@apm-js-collab/tracing-hooks/-/tracing-hooks-0.10.1.tgz",
- "integrity": "sha512-w2OWXR7FWrKqSziuE9+QclaZrStxO/8+OwbXM635s/zs0Eez1Qo3ivSPdB2WsaPY/iznKTytONPx/PitD7IXcA==",
- "license": "Apache-2.0",
- "dependencies": {
- "@apm-js-collab/code-transformer": "^0.15.0",
- "debug": "^4.4.1",
- "module-details-from-path": "^1.0.4"
- }
- },
- "node_modules/@babel/code-frame": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",
- "integrity": "sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-validator-identifier": "^7.29.7",
- "js-tokens": "^4.0.0",
- "picocolors": "^1.1.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/compat-data": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz",
- "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/core": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz",
- "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==",
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.29.7",
- "@babel/generator": "^7.29.7",
- "@babel/helper-compilation-targets": "^7.29.7",
- "@babel/helper-module-transforms": "^7.29.7",
- "@babel/helpers": "^7.29.7",
- "@babel/parser": "^7.29.7",
- "@babel/template": "^7.29.7",
- "@babel/traverse": "^7.29.7",
- "@babel/types": "^7.29.7",
- "@jridgewell/remapping": "^2.3.5",
- "convert-source-map": "^2.0.0",
- "debug": "^4.1.0",
- "gensync": "^1.0.0-beta.2",
- "json5": "^2.2.3",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "funding": {
- "type": "opencollective",
- "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==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- }
- },
- "node_modules/@babel/generator": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz",
- "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==",
- "license": "MIT",
- "dependencies": {
- "@babel/parser": "^7.29.7",
- "@babel/types": "^7.29.7",
- "@jridgewell/gen-mapping": "^0.3.12",
- "@jridgewell/trace-mapping": "^0.3.28",
- "jsesc": "^3.0.2"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-compilation-targets": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz",
- "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==",
- "license": "MIT",
- "dependencies": {
- "@babel/compat-data": "^7.29.7",
- "@babel/helper-validator-option": "^7.29.7",
- "browserslist": "^4.24.0",
- "lru-cache": "^5.1.1",
- "semver": "^6.3.1"
- },
- "engines": {
- "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==",
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- }
- },
- "node_modules/@babel/helper-globals": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz",
- "integrity": "sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-module-imports": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz",
- "integrity": "sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==",
- "license": "MIT",
- "dependencies": {
- "@babel/traverse": "^7.29.7",
- "@babel/types": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-module-transforms": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz",
- "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-module-imports": "^7.29.7",
- "@babel/helper-validator-identifier": "^7.29.7",
- "@babel/traverse": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/helper-string-parser": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
- "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
- "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-option": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz",
- "integrity": "sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helpers": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz",
- "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==",
- "license": "MIT",
- "dependencies": {
- "@babel/template": "^7.29.7",
- "@babel/types": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/parser": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz",
- "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==",
- "license": "MIT",
- "dependencies": {
- "@babel/types": "^7.29.7"
- },
- "bin": {
- "parser": "bin/babel-parser.js"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@babel/runtime": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz",
- "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/template": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz",
- "integrity": "sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==",
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.29.7",
- "@babel/parser": "^7.29.7",
- "@babel/types": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/traverse": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz",
- "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==",
- "license": "MIT",
- "dependencies": {
- "@babel/code-frame": "^7.29.7",
- "@babel/generator": "^7.29.7",
- "@babel/helper-globals": "^7.29.7",
- "@babel/parser": "^7.29.7",
- "@babel/template": "^7.29.7",
- "@babel/types": "^7.29.7",
- "debug": "^4.3.1"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/types": {
- "version": "7.29.7",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz",
- "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==",
- "license": "MIT",
- "dependencies": {
- "@babel/helper-string-parser": "^7.29.7",
- "@babel/helper-validator-identifier": "^7.29.7"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@dataconnect/generated": {
- "resolved": "src/dataconnect-generated",
- "link": true
- },
- "node_modules/@emnapi/core": {
- "version": "1.10.0",
- "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
- "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/wasi-threads": "1.2.1",
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@emnapi/runtime": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz",
- "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==",
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@emnapi/wasi-threads": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
- "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@esbuild/aix-ppc64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz",
- "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==",
- "cpu": [
- "ppc64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "aix"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-arm": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz",
- "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz",
- "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/android-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz",
- "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/darwin-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz",
- "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/darwin-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz",
- "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/freebsd-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz",
- "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/freebsd-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz",
- "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-arm": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz",
- "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz",
- "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-ia32": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz",
- "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==",
- "cpu": [
- "ia32"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-loong64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz",
- "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==",
- "cpu": [
- "loong64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-mips64el": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz",
- "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==",
- "cpu": [
- "mips64el"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-ppc64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz",
- "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==",
- "cpu": [
- "ppc64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-riscv64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz",
- "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==",
- "cpu": [
- "riscv64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-s390x": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz",
- "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==",
- "cpu": [
- "s390x"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/linux-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz",
- "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/netbsd-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz",
- "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/netbsd-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz",
- "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz",
- "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openbsd-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz",
- "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/openharmony-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz",
- "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "openharmony"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/sunos-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz",
- "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "sunos"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-arm64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz",
- "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-ia32": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz",
- "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==",
- "cpu": [
- "ia32"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@esbuild/win32-x64": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz",
- "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@eslint-community/eslint-utils": {
- "version": "4.9.1",
- "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
- "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "eslint-visitor-keys": "^3.4.3"
- },
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- },
- "peerDependencies": {
- "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
- }
- },
- "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
- "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/@eslint-community/regexpp": {
- "version": "4.12.2",
- "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz",
- "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
- }
- },
- "node_modules/@eslint/config-array": {
- "version": "0.21.2",
- "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz",
- "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@eslint/object-schema": "^2.1.7",
- "debug": "^4.3.1",
- "minimatch": "^3.1.5"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@eslint/config-helpers": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz",
- "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@eslint/core": "^0.17.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@eslint/core": {
- "version": "0.17.0",
- "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz",
- "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@types/json-schema": "^7.0.15"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@eslint/eslintrc": {
- "version": "3.3.6",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.6.tgz",
- "integrity": "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ajv": "^6.14.0",
- "debug": "^4.3.2",
- "espree": "^10.0.1",
- "globals": "^14.0.0",
- "ignore": "^5.2.0",
- "import-fresh": "^3.2.1",
- "js-yaml": "^4.3.0",
- "minimatch": "^3.1.5",
- "strip-json-comments": "^3.1.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/@eslint/eslintrc/node_modules/ajv": {
- "version": "6.15.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz",
- "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/@eslint/eslintrc/node_modules/globals": {
- "version": "14.0.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
- "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@eslint/js": {
- "version": "9.39.5",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz",
- "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://eslint.org/donate"
- }
- },
- "node_modules/@eslint/object-schema": {
- "version": "2.1.7",
- "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz",
- "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@eslint/plugin-kit": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz",
- "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@eslint/core": "^0.17.0",
- "levn": "^0.4.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- }
- },
- "node_modules/@google-cloud/text-to-speech": {
- "version": "6.4.1",
- "resolved": "https://registry.npmjs.org/@google-cloud/text-to-speech/-/text-to-speech-6.4.1.tgz",
- "integrity": "sha512-iF1SpBPbP019zoLYzIJXp/yDumrSNl19T7hXP4Lg8d2cnNtxoQKQuNOpiwFrxEKV3CBJpp7OY5+z7/K73zNr5w==",
- "license": "Apache-2.0",
- "dependencies": {
- "google-gax": "^5.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@google/genai": {
- "version": "2.12.0",
- "resolved": "https://registry.npmjs.org/@google/genai/-/genai-2.12.0.tgz",
- "integrity": "sha512-LUr972DZosqPUhf9Mb3CIVu/B99woD3QW6ZJV1T9aNgxaoimAZARmo+IyyDsxIL+zouFiYSdA4hzfEWXc9oNIQ==",
- "hasInstallScript": true,
- "license": "Apache-2.0",
- "dependencies": {
- "google-auth-library": "^10.3.0",
- "p-retry": "^4.6.2",
- "protobufjs": "^7.5.4",
- "ws": "^8.18.0"
- },
- "engines": {
- "node": ">=20.0.0"
- },
- "peerDependencies": {
- "@modelcontextprotocol/sdk": "^1.25.2"
- },
- "peerDependenciesMeta": {
- "@modelcontextprotocol/sdk": {
- "optional": true
- }
- }
- },
- "node_modules/@google/generative-ai": {
- "version": "0.24.1",
- "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.24.1.tgz",
- "integrity": "sha512-MqO+MLfM6kjxcKoy0p1wRzG3b4ZZXtPI+z2IE26UogS2Cm/XHO+7gGRBh6gcJsOiIVoH93UwKvW4HdgiOZCy9Q==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=18.0.0"
- }
- },
- "node_modules/@grpc/grpc-js": {
- "version": "1.14.4",
- "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.4.tgz",
- "integrity": "sha512-k9Dj3DV/itK9D06Y8f190Qgop7/Ui+D0njFV3LHMPwPT75DpXLQohE9Wmz0QElrJnzsjB7KPWiKJbOl7IPDArQ==",
- "license": "Apache-2.0",
- "dependencies": {
- "@grpc/proto-loader": "^0.8.0",
- "@js-sdsl/ordered-map": "^4.4.2"
- },
- "engines": {
- "node": ">=12.10.0"
- }
- },
- "node_modules/@grpc/proto-loader": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.1.tgz",
- "integrity": "sha512-wtF6h+DY6M3YaDBPAmvuuA6jV8Sif9MjtOI5euKFWRgCDl5PeDpPsHR9u2l6St5ceY8AZgoNDww5+HvEsXFsGg==",
- "license": "Apache-2.0",
- "dependencies": {
- "lodash.camelcase": "^4.3.0",
- "long": "^5.0.0",
- "protobufjs": "^7.5.5",
- "yargs": "^17.7.2"
- },
- "bin": {
- "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/@hono/node-server": {
- "version": "1.19.14",
- "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.14.tgz",
- "integrity": "sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18.14.1"
- },
- "peerDependencies": {
- "hono": "^4"
- }
- },
- "node_modules/@humanfs/core": {
- "version": "0.19.2",
- "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz",
- "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@humanfs/types": "^0.15.0"
- },
- "engines": {
- "node": ">=18.18.0"
- }
- },
- "node_modules/@humanfs/node": {
- "version": "0.16.8",
- "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz",
- "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@humanfs/core": "^0.19.2",
- "@humanfs/types": "^0.15.0",
- "@humanwhocodes/retry": "^0.4.0"
- },
- "engines": {
- "node": ">=18.18.0"
- }
- },
- "node_modules/@humanfs/types": {
- "version": "0.15.0",
- "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz",
- "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=18.18.0"
- }
- },
- "node_modules/@humanwhocodes/module-importer": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
- "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=12.22"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/nzakas"
- }
- },
- "node_modules/@humanwhocodes/retry": {
- "version": "0.4.3",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
- "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=18.18"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/nzakas"
- }
- },
- "node_modules/@img/colour": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz",
- "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==",
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@img/sharp-darwin-arm64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz",
- "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==",
- "cpu": [
- "arm64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-darwin-arm64": "1.2.4"
- }
- },
- "node_modules/@img/sharp-darwin-x64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz",
- "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==",
- "cpu": [
- "x64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-darwin-x64": "1.2.4"
- }
- },
- "node_modules/@img/sharp-libvips-darwin-arm64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz",
- "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==",
- "cpu": [
- "arm64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "darwin"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-darwin-x64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz",
- "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==",
- "cpu": [
- "x64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "darwin"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-linux-arm": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz",
- "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==",
- "cpu": [
- "arm"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-linux-arm64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz",
- "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==",
- "cpu": [
- "arm64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-linux-ppc64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz",
- "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==",
- "cpu": [
- "ppc64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-linux-riscv64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz",
- "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==",
- "cpu": [
- "riscv64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-linux-s390x": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz",
- "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==",
- "cpu": [
- "s390x"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-linux-x64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz",
- "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==",
- "cpu": [
- "x64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-linuxmusl-arm64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz",
- "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==",
- "cpu": [
- "arm64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-libvips-linuxmusl-x64": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz",
- "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==",
- "cpu": [
- "x64"
- ],
- "license": "LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "linux"
- ],
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-linux-arm": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz",
- "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==",
- "cpu": [
- "arm"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linux-arm": "1.2.4"
- }
- },
- "node_modules/@img/sharp-linux-arm64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz",
- "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==",
- "cpu": [
- "arm64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linux-arm64": "1.2.4"
- }
- },
- "node_modules/@img/sharp-linux-ppc64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz",
- "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==",
- "cpu": [
- "ppc64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linux-ppc64": "1.2.4"
- }
- },
- "node_modules/@img/sharp-linux-riscv64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz",
- "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==",
- "cpu": [
- "riscv64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linux-riscv64": "1.2.4"
- }
- },
- "node_modules/@img/sharp-linux-s390x": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz",
- "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==",
- "cpu": [
- "s390x"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linux-s390x": "1.2.4"
- }
- },
- "node_modules/@img/sharp-linux-x64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz",
- "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==",
- "cpu": [
- "x64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linux-x64": "1.2.4"
- }
- },
- "node_modules/@img/sharp-linuxmusl-arm64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz",
- "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==",
- "cpu": [
- "arm64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linuxmusl-arm64": "1.2.4"
- }
- },
- "node_modules/@img/sharp-linuxmusl-x64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz",
- "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==",
- "cpu": [
- "x64"
- ],
- "license": "Apache-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-libvips-linuxmusl-x64": "1.2.4"
- }
- },
- "node_modules/@img/sharp-wasm32": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz",
- "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==",
- "cpu": [
- "wasm32"
- ],
- "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/runtime": "^1.7.0"
- },
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-win32-arm64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz",
- "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==",
- "cpu": [
- "arm64"
- ],
- "license": "Apache-2.0 AND LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-win32-ia32": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz",
- "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==",
- "cpu": [
- "ia32"
- ],
- "license": "Apache-2.0 AND LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "node_modules/@img/sharp-win32-x64": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz",
- "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==",
- "cpu": [
- "x64"
- ],
- "license": "Apache-2.0 AND LGPL-3.0-or-later",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- }
- },
- "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/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.2.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
- "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^6.2.2"
- },
- "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/@jridgewell/gen-mapping": {
- "version": "0.3.13",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
- "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.0",
- "@jridgewell/trace-mapping": "^0.3.24"
- }
- },
- "node_modules/@jridgewell/remapping": {
- "version": "2.3.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz",
- "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.3.5",
- "@jridgewell/trace-mapping": "^0.3.24"
- }
- },
- "node_modules/@jridgewell/resolve-uri": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
- "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
- "license": "MIT",
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
- "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
- "license": "MIT"
- },
- "node_modules/@jridgewell/trace-mapping": {
- "version": "0.3.31",
- "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
- "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/resolve-uri": "^3.1.0",
- "@jridgewell/sourcemap-codec": "^1.4.14"
- }
- },
- "node_modules/@js-sdsl/ordered-map": {
- "version": "4.4.2",
- "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz",
- "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==",
- "license": "MIT",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/js-sdsl"
- }
- },
- "node_modules/@modelcontextprotocol/sdk": {
- "version": "1.29.0",
- "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.29.0.tgz",
- "integrity": "sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@hono/node-server": "^1.19.9",
- "ajv": "^8.17.1",
- "ajv-formats": "^3.0.1",
- "content-type": "^1.0.5",
- "cors": "^2.8.5",
- "cross-spawn": "^7.0.5",
- "eventsource": "^3.0.2",
- "eventsource-parser": "^3.0.0",
- "express": "^5.2.1",
- "express-rate-limit": "^8.2.1",
- "hono": "^4.11.4",
- "jose": "^6.1.3",
- "json-schema-typed": "^8.0.2",
- "pkce-challenge": "^5.0.0",
- "raw-body": "^3.0.0",
- "zod": "^3.25 || ^4.0",
- "zod-to-json-schema": "^3.25.1"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@cfworker/json-schema": "^4.1.1",
- "zod": "^3.25 || ^4.0"
- },
- "peerDependenciesMeta": {
- "@cfworker/json-schema": {
- "optional": true
- },
- "zod": {
- "optional": false
- }
- }
- },
- "node_modules/@napi-rs/wasm-runtime": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz",
- "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@tybys/wasm-util": "^0.10.3"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/Brooooooklyn"
- },
- "peerDependencies": {
- "@emnapi/core": "^1.7.1",
- "@emnapi/runtime": "^1.7.1"
- }
- },
- "node_modules/@next/env": {
- "version": "16.2.10",
- "resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.10.tgz",
- "integrity": "sha512-zLPxg9M0MEHmygpj5OuxjQ+vHMiy/K7cSp74G8ecYolmgUWw0RwN02tF56npup/+qaI8JB97hQgS/r2Hb6QwVA==",
- "license": "MIT"
- },
- "node_modules/@next/swc-darwin-arm64": {
- "version": "16.2.10",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.2.10.tgz",
- "integrity": "sha512-v9IdJCa0H0mbo+8z5zwUpOk1Vj7RjkcI5uNYf5Ws1y6szf/p3Mzl9hLaST8SCt6L9h8NGnruZcd2+o0NTNwDhA==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@next/swc-darwin-x64": {
- "version": "16.2.10",
- "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.2.10.tgz",
- "integrity": "sha512-17IS0jJRViROGmA9uGdNR8VPJpfbnaVG7E9qhso5jDLkmyd0lSDORWxbcKINzcFqzZqGwGtMSnrFRxBpuUYjLQ==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@next/swc-linux-arm64-gnu": {
- "version": "16.2.10",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.2.10.tgz",
- "integrity": "sha512-GRQRsRtuciNJvB54AvvuQTiq0oZtFwa1owQqtZD8wwnGpM2L39MV22kpI72YSXLKIyY40LC66EiLFv4PiicXxg==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@next/swc-linux-arm64-musl": {
- "version": "16.2.10",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.2.10.tgz",
- "integrity": "sha512-zkN9MQYS7UQBro+FnISUq1itaQjXI9xqISzuQ+2bc921NcJ1x4yPCqrn77tVN6/dOOXaaWVX3k6/bR07pPwK+A==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@next/swc-linux-x64-gnu": {
- "version": "16.2.10",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.2.10.tgz",
- "integrity": "sha512-iCVJnwvrPYECvA6WM/7+oo+OiTvedIKLxtCLAZP4xZR3nXa1zmzZyLPbYCmWvpd4CvMYF1EMTafd0ii3DygLvA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@next/swc-linux-x64-musl": {
- "version": "16.2.10",
- "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.2.10.tgz",
- "integrity": "sha512-ov2g4H0dHY9bPoOU83m91hWT7Iq5qy13bUnyyshLU3HGR1Ownn0X9QpmDPc5iIUaahTp7f7LeGAhV4DSFtackw==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@next/swc-win32-arm64-msvc": {
- "version": "16.2.10",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.2.10.tgz",
- "integrity": "sha512-DwAnhLX76HQiFFQNgWlcK+JzlnD1rZ+UK/WY0ZMI/deXpvgnesjNYrqcfo1JzBuz4Kf7o3brIBL0glI1junatA==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@next/swc-win32-x64-msvc": {
- "version": "16.2.10",
- "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.2.10.tgz",
- "integrity": "sha512-0JXq3b85Jk9Jg4ntLUbXSPvoDw3gpZou7twuKdoFG2jOw635v7+IiXfTaa0TxVMyx78pUjnrVYwLgjKfX4e6/A==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 10"
- }
- },
- "node_modules/@nodelib/fs.scandir": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
- "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@nodelib/fs.stat": "2.0.5",
- "run-parallel": "^1.1.9"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.stat": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
- "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.walk": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
- "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@nodelib/fs.scandir": "2.1.5",
- "fastq": "^1.6.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nolyfill/is-core-module": {
- "version": "1.0.39",
- "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz",
- "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12.4.0"
- }
- },
- "node_modules/@opentelemetry/api": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz",
- "integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=8.0.0"
- }
- },
- "node_modules/@opentelemetry/api-logs": {
- "version": "0.220.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.220.0.tgz",
- "integrity": "sha512-CmVa4ImJ+ynfrPMNaAXHET6Bhb44SwzmfyVJFq9ni2jgXJR/l7C6gfVFddNmHP+ZOkP9cf4f9DBe68qVLTHc9w==",
- "license": "Apache-2.0",
- "dependencies": {
- "@opentelemetry/api": "^1.3.0"
- },
- "engines": {
- "node": ">=8.0.0"
- }
- },
- "node_modules/@opentelemetry/core": {
- "version": "2.9.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.9.0.tgz",
- "integrity": "sha512-m2nckMT80NnmjTYSPjJQObBJ+8dgkoajEOUbznL8AHZ3T3yHRk2P7gI1PhEBc1+lOnrYE9UWrWHqJDsmqjmNbw==",
- "license": "Apache-2.0",
- "dependencies": {
- "@opentelemetry/semantic-conventions": "^1.29.0"
- },
- "engines": {
- "node": "^18.19.0 || >=20.6.0"
- },
- "peerDependencies": {
- "@opentelemetry/api": ">=1.0.0 <1.10.0"
- }
- },
- "node_modules/@opentelemetry/instrumentation": {
- "version": "0.220.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.220.0.tgz",
- "integrity": "sha512-xQx3E2WxP1mDvKzxLxX+CTCtNLa560YJZ3087qYHerl2YmiKpv7AH+dAy7vmx+eVrZ5BwhfWUAVoKOoxCNHcpw==",
- "license": "Apache-2.0",
- "dependencies": {
- "@opentelemetry/api-logs": "0.220.0",
- "import-in-the-middle": "^3.0.0",
- "require-in-the-middle": "^8.0.0"
- },
- "engines": {
- "node": "^18.19.0 || >=20.6.0"
- },
- "peerDependencies": {
- "@opentelemetry/api": "^1.3.0"
- }
- },
- "node_modules/@opentelemetry/resources": {
- "version": "2.9.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.9.0.tgz",
- "integrity": "sha512-jyA5MBLQ+Dkl3+JsZkUoUvL7yHvU64kLsvpXKarWm6347Sl1t1bXFTFykUePNpT5WH5pm9a2Qtt03iIYQhZ1Fg==",
- "license": "Apache-2.0",
- "dependencies": {
- "@opentelemetry/core": "2.9.0",
- "@opentelemetry/semantic-conventions": "^1.29.0"
- },
- "engines": {
- "node": "^18.19.0 || >=20.6.0"
- },
- "peerDependencies": {
- "@opentelemetry/api": ">=1.3.0 <1.10.0"
- }
- },
- "node_modules/@opentelemetry/sdk-trace": {
- "version": "2.9.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace/-/sdk-trace-2.9.0.tgz",
- "integrity": "sha512-sGA19HvtrrSKYsseHphluH6j3p6Xa3fqc7c7y8f/7mYWejc1lyDFcpSdD1kYa50HCLUeEo4zA5bW0pniaPszuw==",
- "license": "Apache-2.0",
- "dependencies": {
- "@opentelemetry/core": "2.9.0",
- "@opentelemetry/resources": "2.9.0",
- "@opentelemetry/semantic-conventions": "^1.29.0"
- },
- "engines": {
- "node": "^18.19.0 || >=20.6.0"
- },
- "peerDependencies": {
- "@opentelemetry/api": ">=1.3.0 <1.10.0"
- }
- },
- "node_modules/@opentelemetry/sdk-trace-base": {
- "version": "2.9.0",
- "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.9.0.tgz",
- "integrity": "sha512-cp9zmTl62R8PJrpvFcmc8N2JQU/xfa0S+61q511Nji+QxCfZ8Ifvg7H27G8cANe4crg4RTrWsVvanHiXjSp6ag==",
- "license": "Apache-2.0",
- "dependencies": {
- "@opentelemetry/core": "2.9.0",
- "@opentelemetry/resources": "2.9.0",
- "@opentelemetry/sdk-trace": "2.9.0",
- "@opentelemetry/semantic-conventions": "^1.29.0"
- },
- "engines": {
- "node": "^18.19.0 || >=20.6.0"
- },
- "peerDependencies": {
- "@opentelemetry/api": ">=1.3.0 <1.10.0"
- }
- },
- "node_modules/@opentelemetry/semantic-conventions": {
- "version": "1.41.1",
- "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.41.1.tgz",
- "integrity": "sha512-/UhIkaZgPutTFmQ7RnIJGgDXZmtEJ7Dvi86xNTFWcnRxVRNk/aotsqDJYeEvDP+FSMB2SdW+pQzNMcWP0rwuNA==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/@oxc-project/types": {
- "version": "0.139.0",
- "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.139.0.tgz",
- "integrity": "sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/Boshen"
- }
- },
- "node_modules/@panva/hkdf": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.2.1.tgz",
- "integrity": "sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/panva"
- }
- },
- "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.61.1",
- "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.61.1.tgz",
- "integrity": "sha512-8nKv6+0RJSL9FE4jYOEGXnPeM/Hg12qZpmqzZjRh3qM0Y7c3z1mrOTfFLids72RDQYVh9WpLEfR5WdpNX4fkig==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "playwright": "1.61.1"
- },
- "bin": {
- "playwright": "cli.js"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/@protobufjs/aspromise": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
- "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@protobufjs/base64": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
- "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@protobufjs/codegen": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz",
- "integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@protobufjs/eventemitter": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz",
- "integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@protobufjs/fetch": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz",
- "integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==",
- "license": "BSD-3-Clause",
- "dependencies": {
- "@protobufjs/aspromise": "^1.1.1"
- }
- },
- "node_modules/@protobufjs/float": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
- "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@protobufjs/path": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
- "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@protobufjs/pool": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
- "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@protobufjs/utf8": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.1.tgz",
- "integrity": "sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==",
- "license": "BSD-3-Clause"
- },
- "node_modules/@rolldown/binding-android-arm64": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.5.tgz",
- "integrity": "sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- }
- },
- "node_modules/@rolldown/binding-darwin-arm64": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.5.tgz",
- "integrity": "sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- }
- },
- "node_modules/@rolldown/binding-darwin-x64": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.5.tgz",
- "integrity": "sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- }
- },
- "node_modules/@rolldown/binding-freebsd-x64": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.5.tgz",
- "integrity": "sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- }
- },
- "node_modules/@rolldown/binding-linux-arm-gnueabihf": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.5.tgz",
- "integrity": "sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- }
- },
- "node_modules/@rolldown/binding-linux-arm64-gnu": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.5.tgz",
- "integrity": "sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- }
- },
- "node_modules/@rolldown/binding-linux-arm64-musl": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.5.tgz",
- "integrity": "sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- }
- },
- "node_modules/@rolldown/binding-linux-ppc64-gnu": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.5.tgz",
- "integrity": "sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- }
- },
- "node_modules/@rolldown/binding-linux-s390x-gnu": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.5.tgz",
- "integrity": "sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- }
- },
- "node_modules/@rolldown/binding-linux-x64-gnu": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.5.tgz",
- "integrity": "sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- }
- },
- "node_modules/@rolldown/binding-linux-x64-musl": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.5.tgz",
- "integrity": "sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- }
- },
- "node_modules/@rolldown/binding-openharmony-arm64": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.5.tgz",
- "integrity": "sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openharmony"
- ],
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- }
- },
- "node_modules/@rolldown/binding-wasm32-wasi": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.5.tgz",
- "integrity": "sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==",
- "cpu": [
- "wasm32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/core": "1.11.1",
- "@emnapi/runtime": "1.11.1",
- "@napi-rs/wasm-runtime": "^1.1.6"
- },
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- }
- },
- "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/core": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz",
- "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/wasi-threads": "1.2.2",
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/wasi-threads": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz",
- "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@rolldown/binding-win32-arm64-msvc": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.5.tgz",
- "integrity": "sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- }
- },
- "node_modules/@rolldown/binding-win32-x64-msvc": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.5.tgz",
- "integrity": "sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- }
- },
- "node_modules/@rolldown/pluginutils": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz",
- "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@rollup/plugin-commonjs": {
- "version": "28.0.1",
- "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.1.tgz",
- "integrity": "sha512-+tNWdlWKbpB3WgBN7ijjYkq9X5uhjmcvyjEght4NmH5fAU++zfQzAJ6wumLS+dNcvwEZhKx2Z+skY8m7v0wGSA==",
- "license": "MIT",
- "dependencies": {
- "@rollup/pluginutils": "^5.0.1",
- "commondir": "^1.0.1",
- "estree-walker": "^2.0.2",
- "fdir": "^6.2.0",
- "is-reference": "1.2.1",
- "magic-string": "^0.30.3",
- "picomatch": "^4.0.2"
- },
- "engines": {
- "node": ">=16.0.0 || 14 >= 14.17"
- },
- "peerDependencies": {
- "rollup": "^2.68.0||^3.0.0||^4.0.0"
- },
- "peerDependenciesMeta": {
- "rollup": {
- "optional": true
- }
- }
- },
- "node_modules/@rollup/pluginutils": {
- "version": "5.4.0",
- "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.4.0.tgz",
- "integrity": "sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==",
- "license": "MIT",
- "dependencies": {
- "@types/estree": "^1.0.0",
- "estree-walker": "^2.0.2",
- "picomatch": "^4.0.2"
- },
- "engines": {
- "node": ">=14.0.0"
- },
- "peerDependencies": {
- "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
- },
- "peerDependenciesMeta": {
- "rollup": {
- "optional": true
- }
- }
- },
- "node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.62.2.tgz",
- "integrity": "sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ]
- },
- "node_modules/@rollup/rollup-android-arm64": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.62.2.tgz",
- "integrity": "sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ]
- },
- "node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.62.2.tgz",
- "integrity": "sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.62.2.tgz",
- "integrity": "sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@rollup/rollup-freebsd-arm64": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.62.2.tgz",
- "integrity": "sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ]
- },
- "node_modules/@rollup/rollup-freebsd-x64": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.62.2.tgz",
- "integrity": "sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.62.2.tgz",
- "integrity": "sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm-musleabihf": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.62.2.tgz",
- "integrity": "sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==",
- "cpu": [
- "arm"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.62.2.tgz",
- "integrity": "sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.62.2.tgz",
- "integrity": "sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-loong64-gnu": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.62.2.tgz",
- "integrity": "sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==",
- "cpu": [
- "loong64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-loong64-musl": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.62.2.tgz",
- "integrity": "sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==",
- "cpu": [
- "loong64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-ppc64-gnu": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.62.2.tgz",
- "integrity": "sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==",
- "cpu": [
- "ppc64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-ppc64-musl": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.62.2.tgz",
- "integrity": "sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==",
- "cpu": [
- "ppc64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.62.2.tgz",
- "integrity": "sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==",
- "cpu": [
- "riscv64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-riscv64-musl": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.62.2.tgz",
- "integrity": "sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==",
- "cpu": [
- "riscv64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-s390x-gnu": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.62.2.tgz",
- "integrity": "sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==",
- "cpu": [
- "s390x"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.62.2.tgz",
- "integrity": "sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.62.2.tgz",
- "integrity": "sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@rollup/rollup-openbsd-x64": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.62.2.tgz",
- "integrity": "sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ]
- },
- "node_modules/@rollup/rollup-openharmony-arm64": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.62.2.tgz",
- "integrity": "sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "openharmony"
- ]
- },
- "node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.62.2.tgz",
- "integrity": "sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==",
- "cpu": [
- "arm64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.62.2.tgz",
- "integrity": "sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==",
- "cpu": [
- "ia32"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-x64-gnu": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.62.2.tgz",
- "integrity": "sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.62.2.tgz",
- "integrity": "sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==",
- "cpu": [
- "x64"
- ],
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@rtsao/scc": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
- "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@sentry/babel-plugin-component-annotate": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/@sentry/babel-plugin-component-annotate/-/babel-plugin-component-annotate-5.3.0.tgz",
- "integrity": "sha512-p4q8gn8wcFqZGP/s2MnJCAAd8fTikaU6A0mM97RDHQgStcrYiaS0Sc5zUNfb1V+UOLPuvdEdL6MwyxfzjYJQTA==",
- "license": "MIT",
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/@sentry/bundler-plugin-core": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/@sentry/bundler-plugin-core/-/bundler-plugin-core-5.3.0.tgz",
- "integrity": "sha512-L5T60sWdAI3qWwdg3Ptwek/0TY59PERrxyqp4XMUkroayQvGd9r5dIW9Q1kSeXX9iJ442nXbFZKAOyCKV4Z13Q==",
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.18.5",
- "@sentry/babel-plugin-component-annotate": "5.3.0",
- "@sentry/cli": "^2.58.5",
- "dotenv": "^16.3.1",
- "find-up": "^5.0.0",
- "glob": "^13.0.6",
- "magic-string": "~0.30.8"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/@sentry/bundler-plugin-core/node_modules/dotenv": {
- "version": "16.6.1",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
- "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://dotenvx.com"
- }
- },
- "node_modules/@sentry/cli": {
- "version": "2.58.6",
- "resolved": "https://registry.npmjs.org/@sentry/cli/-/cli-2.58.6.tgz",
- "integrity": "sha512-baBcNPLLfUi9WuL+Tpri9BFaAdvugZIKelC5X0tt0Zdy+K0K+PCVSrnNmwMWU/HyaF/SEv6b6UHnXIdqanBlcg==",
- "hasInstallScript": true,
- "license": "FSL-1.1-MIT",
- "dependencies": {
- "https-proxy-agent": "^5.0.0",
- "node-fetch": "^2.6.7",
- "progress": "^2.0.3",
- "proxy-from-env": "^1.1.0",
- "which": "^2.0.2"
- },
- "bin": {
- "sentry-cli": "bin/sentry-cli"
- },
- "engines": {
- "node": ">= 10"
- },
- "optionalDependencies": {
- "@sentry/cli-darwin": "2.58.6",
- "@sentry/cli-linux-arm": "2.58.6",
- "@sentry/cli-linux-arm64": "2.58.6",
- "@sentry/cli-linux-i686": "2.58.6",
- "@sentry/cli-linux-x64": "2.58.6",
- "@sentry/cli-win32-arm64": "2.58.6",
- "@sentry/cli-win32-i686": "2.58.6",
- "@sentry/cli-win32-x64": "2.58.6"
- }
- },
- "node_modules/@sentry/cli-darwin": {
- "version": "2.58.6",
- "resolved": "https://registry.npmjs.org/@sentry/cli-darwin/-/cli-darwin-2.58.6.tgz",
- "integrity": "sha512-udAVvcyfNa0R+95GvPz/+43/N3TC0TYKdkQ7D7jhPSzbcMc7l2fxRNN5yB3UpCA5fWFnW4toeaqwDBhb/Wh3LA==",
- "license": "FSL-1.1-MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@sentry/cli-linux-arm": {
- "version": "2.58.6",
- "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm/-/cli-linux-arm-2.58.6.tgz",
- "integrity": "sha512-pD0LAt5PcUzAinBwvDqc66x9+2CabHEv486yP0gRjWO7SakbaxmfVq/EXd8VLq/Tzi39LAu422UYK1lpW3MILw==",
- "cpu": [
- "arm"
- ],
- "license": "FSL-1.1-MIT",
- "optional": true,
- "os": [
- "linux",
- "freebsd",
- "android"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@sentry/cli-linux-arm64": {
- "version": "2.58.6",
- "resolved": "https://registry.npmjs.org/@sentry/cli-linux-arm64/-/cli-linux-arm64-2.58.6.tgz",
- "integrity": "sha512-q8mEcNNmeXMy5i+jWT30TVpH7LcP4HD21CD5XRSPAd/a912HF6EpK0ybf/1USO14WOhoXbAGi9txwaWabSe33g==",
- "cpu": [
- "arm64"
- ],
- "license": "FSL-1.1-MIT",
- "optional": true,
- "os": [
- "linux",
- "freebsd",
- "android"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@sentry/cli-linux-i686": {
- "version": "2.58.6",
- "resolved": "https://registry.npmjs.org/@sentry/cli-linux-i686/-/cli-linux-i686-2.58.6.tgz",
- "integrity": "sha512-q8vNJi1eOV/4vxAFWBsEwLHoSYapaZHIf4j76KJGJXFKTkEbsjCOOsKbwUIBTQQhRgV4DFWh3ryfsPS/que4Kg==",
- "cpu": [
- "x86",
- "ia32"
- ],
- "license": "FSL-1.1-MIT",
- "optional": true,
- "os": [
- "linux",
- "freebsd",
- "android"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@sentry/cli-linux-x64": {
- "version": "2.58.6",
- "resolved": "https://registry.npmjs.org/@sentry/cli-linux-x64/-/cli-linux-x64-2.58.6.tgz",
- "integrity": "sha512-DZu956Mhi3ZRjTBe1WdbGV46ldVbA8d2rgp/fh51GsI25zjBHah4wZnPTSzpc+YqxU6pJpg579B/r3jrIK530Q==",
- "cpu": [
- "x64"
- ],
- "license": "FSL-1.1-MIT",
- "optional": true,
- "os": [
- "linux",
- "freebsd",
- "android"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@sentry/cli-win32-arm64": {
- "version": "2.58.6",
- "resolved": "https://registry.npmjs.org/@sentry/cli-win32-arm64/-/cli-win32-arm64-2.58.6.tgz",
- "integrity": "sha512-nj0Ff/kmAB73EPDhR8B4O9r+NUHK5GkPCkGWC+kXVemqAJWL5jcJ5KdxG0l/S0z6RoEoltID8/43/B+TaMlT7A==",
- "cpu": [
- "arm64"
- ],
- "license": "FSL-1.1-MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@sentry/cli-win32-i686": {
- "version": "2.58.6",
- "resolved": "https://registry.npmjs.org/@sentry/cli-win32-i686/-/cli-win32-i686-2.58.6.tgz",
- "integrity": "sha512-WNZiDzPbgsEMQWq4avsQ391v/xWKJDIWWWo9GYl+N/w5qcYKkoDW7wQG7T9FasI6ENn68phChTOAPXXxbfAdOg==",
- "cpu": [
- "x86",
- "ia32"
- ],
- "license": "FSL-1.1-MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@sentry/cli-win32-x64": {
- "version": "2.58.6",
- "resolved": "https://registry.npmjs.org/@sentry/cli-win32-x64/-/cli-win32-x64-2.58.6.tgz",
- "integrity": "sha512-R35WJ17oF4D2eqI1DR2sQQqr0fjRTt5xoP16WrTu91XM2lndRMFsnjh+/GttbxapLCBNlrjzia99MJ0PZHZpgA==",
- "cpu": [
- "x64"
- ],
- "license": "FSL-1.1-MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@sentry/webpack-plugin": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/@sentry/webpack-plugin/-/webpack-plugin-5.3.0.tgz",
- "integrity": "sha512-i3OQUrS0FZlXLgq57RIKDp+vHHzuvYKPCKewAPXULWKMsBXFGhP6veGRQ+6To/pmZkkXjEX5ofVNDy9C3jEPKQ==",
- "license": "MIT",
- "dependencies": {
- "@sentry/bundler-plugin-core": "5.3.0"
- },
- "engines": {
- "node": ">= 18"
- },
- "peerDependencies": {
- "webpack": ">=5.0.0"
- }
- },
- "node_modules/@standard-schema/spec": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz",
- "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==",
- "license": "MIT"
- },
- "node_modules/@supabase/auth-js": {
- "version": "2.110.7",
- "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.110.7.tgz",
- "integrity": "sha512-M5Bpl4hCv6kHcOO/xM06Dyfg1mYLHljMkp1plhzG9IRZPc3czvyMsSN1XpL5+GKisOKM3lSN59zhpcm6sMVXfA==",
- "license": "MIT",
- "dependencies": {
- "tslib": "2.8.1"
- },
- "engines": {
- "node": ">=22.0.0"
- }
- },
- "node_modules/@supabase/functions-js": {
- "version": "2.110.7",
- "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.110.7.tgz",
- "integrity": "sha512-megYmexlYEoR/0qlsr4Snh9wtzAodO7MAri3NMevZrXzNvQRKlvmTcSBoKGLQEPDakgDZMqbMdf9DwoZz6qfoA==",
- "license": "MIT",
- "dependencies": {
- "tslib": "2.8.1"
- },
- "engines": {
- "node": ">=22.0.0"
- }
- },
- "node_modules/@supabase/phoenix": {
- "version": "0.4.5",
- "resolved": "https://registry.npmjs.org/@supabase/phoenix/-/phoenix-0.4.5.tgz",
- "integrity": "sha512-aAn9H9ovVyeApKy11OWOrrOGq8DV68yWeH4ud2lN9fzn4aO8Zb5GLL9m1pUg9nLqIcT+ZDfAcsZe0E/nqdv2lw==",
- "license": "MIT"
- },
- "node_modules/@supabase/postgrest-js": {
- "version": "2.110.7",
- "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-2.110.7.tgz",
- "integrity": "sha512-ban6YV0djhVaqVYezlOARKLIuOBSvLLhyQVZjA2nxPrtswhxHCl1+gI4giFgI9ATQAaMNbUZb4JXiuL5lEA/5g==",
- "license": "MIT",
- "dependencies": {
- "tslib": "2.8.1"
- },
- "engines": {
- "node": ">=22.0.0"
- }
- },
- "node_modules/@supabase/realtime-js": {
- "version": "2.110.7",
- "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.110.7.tgz",
- "integrity": "sha512-AMtZjyFA2gsmjuxopPNS/sRznLQHG0Ht5x+ytTPTOh3vAcOTUlVRLx7gW4/CONNnbb3PKOkE+HmM35HOSbmomQ==",
- "license": "MIT",
- "dependencies": {
- "@supabase/phoenix": "0.4.5",
- "tslib": "2.8.1"
- },
- "engines": {
- "node": ">=22.0.0"
- }
- },
- "node_modules/@supabase/storage-js": {
- "version": "2.110.7",
- "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.110.7.tgz",
- "integrity": "sha512-2tcDE8cjEDy1uKxKavBpKQod1JdMV1jDXQag48TCa+kycmJOltc0yVabC0BUlhOwAl6WykXU2aOsH3ELMtZrmQ==",
- "license": "MIT",
- "dependencies": {
- "iceberg-js": "^0.8.1",
- "tslib": "2.8.1"
- },
- "engines": {
- "node": ">=22.0.0"
- }
- },
- "node_modules/@supabase/supabase-js": {
- "version": "2.110.7",
- "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.110.7.tgz",
- "integrity": "sha512-AnfO3A230Shy6RMO7cya3Wl1OcXnABJrzH8vP+fY7/RFjhzcchB7DjKkkTIAntlwekD+GkSFzEvt2tC+D4Fp8w==",
- "license": "MIT",
- "dependencies": {
- "@supabase/auth-js": "2.110.7",
- "@supabase/functions-js": "2.110.7",
- "@supabase/postgrest-js": "2.110.7",
- "@supabase/realtime-js": "2.110.7",
- "@supabase/storage-js": "2.110.7"
- },
- "engines": {
- "node": ">=22.0.0"
- }
- },
- "node_modules/@swc/helpers": {
- "version": "0.5.15",
- "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
- "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==",
- "license": "Apache-2.0",
- "dependencies": {
- "tslib": "^2.8.0"
- }
- },
- "node_modules/@turbo/darwin-64": {
- "version": "2.10.5",
- "resolved": "https://registry.npmjs.org/@turbo/darwin-64/-/darwin-64-2.10.5.tgz",
- "integrity": "sha512-ENvPwy3x5yS7MwNYHeWjqOBXkwIMp39Pd+/zXC6PoiNzF8EIvvLZOZZ+ny6L9x4WgS5vxUii2LM5gM+zjPdnWw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@turbo/darwin-arm64": {
- "version": "2.10.5",
- "resolved": "https://registry.npmjs.org/@turbo/darwin-arm64/-/darwin-arm64-2.10.5.tgz",
- "integrity": "sha512-rqROo9zsF/P9RqsdtbLD1nFJicjSrYyvQ9kNJC38AbxA3pAs6VAlATvtvOFx7bqOv6vicf20SP9kF33avJjy2w==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@turbo/linux-64": {
- "version": "2.10.5",
- "resolved": "https://registry.npmjs.org/@turbo/linux-64/-/linux-64-2.10.5.tgz",
- "integrity": "sha512-RoSSiNFUxi27zLJuM9F6GyWWjHgLch9t6nwD6K0FkXRirZkTLlzIj6IhFnK8H9++nefLtdFqylE4vGjZAv6AAA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@turbo/linux-arm64": {
- "version": "2.10.5",
- "resolved": "https://registry.npmjs.org/@turbo/linux-arm64/-/linux-arm64-2.10.5.tgz",
- "integrity": "sha512-4ZComcpzmHGmVynQqvvi+iZOSq/tBvY1SltXB8g4NZRsrA01W8E+yRL8RNM+PLoyWsrCnJa8xa+DkWkv+xg4iQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@turbo/windows-64": {
- "version": "2.10.5",
- "resolved": "https://registry.npmjs.org/@turbo/windows-64/-/windows-64-2.10.5.tgz",
- "integrity": "sha512-eL2Iyj4DbMINq1Sr1w0iAi6nAiZOF16KSlRGwCJpVh+IWZeY33MAsLHVOBMj1xoFtncVJXclCVpTPL2nBoYkFg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@turbo/windows-arm64": {
- "version": "2.10.5",
- "resolved": "https://registry.npmjs.org/@turbo/windows-arm64/-/windows-arm64-2.10.5.tgz",
- "integrity": "sha512-sog+wP+8YSJrdWZ/rUJg8xghVTrwoG+BrSlDQpnK5fzSgJHn1INRWXbVWRH0d3vX8dBI01E3yxXRre9Dn+OXQA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@tybys/wasm-util": {
- "version": "0.10.3",
- "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz",
- "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@types/chai": {
- "version": "5.2.3",
- "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz",
- "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/deep-eql": "*",
- "assertion-error": "^2.0.1"
- }
- },
- "node_modules/@types/deep-eql": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz",
- "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/estree": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",
- "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==",
- "license": "MIT"
- },
- "node_modules/@types/json-schema": {
- "version": "7.0.15",
- "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
- "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/json5": {
- "version": "0.0.29",
- "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
- "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/@types/node": {
- "version": "26.1.1",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-26.1.1.tgz",
- "integrity": "sha512-nxAkRSVkN1Y0JC1W8ky/fTfkGsMmcrRsbx+3XoZE+rMOX71kLYTV7fLXpqud1GpbpP5TuffXFqfX7fH2GgZREw==",
- "license": "MIT",
- "dependencies": {
- "undici-types": "~8.3.0"
- }
- },
- "node_modules/@types/react": {
- "version": "19.2.17",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz",
- "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "csstype": "^3.2.2"
- }
- },
- "node_modules/@types/react-dom": {
- "version": "19.2.3",
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
- "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
- "dev": true,
- "license": "MIT",
- "peerDependencies": {
- "@types/react": "^19.2.0"
- }
- },
- "node_modules/@types/retry": {
- "version": "0.12.0",
- "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz",
- "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==",
- "license": "MIT"
- },
- "node_modules/@typescript-eslint/eslint-plugin": {
- "version": "8.61.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.61.1.tgz",
- "integrity": "sha512-ZPlVl3PB3et/59Ne0fv/sci6ZXz4T4Hp4nTJ56i/Y0gR89ARb+KphojTq6j+56E5PIezmOIOOWyY+aWQFd+IkQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@eslint-community/regexpp": "^4.12.2",
- "@typescript-eslint/scope-manager": "8.61.1",
- "@typescript-eslint/type-utils": "8.61.1",
- "@typescript-eslint/utils": "8.61.1",
- "@typescript-eslint/visitor-keys": "8.61.1",
- "ignore": "^7.0.5",
- "natural-compare": "^1.4.0",
- "ts-api-utils": "^2.5.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "@typescript-eslint/parser": "^8.61.1",
- "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
- "typescript": ">=4.8.4 <6.1.0"
- }
- },
- "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
- "version": "7.0.5",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
- "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/@typescript-eslint/parser": {
- "version": "8.61.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.61.1.tgz",
- "integrity": "sha512-PJ5vePq5/ognBbrIcoC5+SHO5dfpeLPzP9FpLkzWrguoYQEeeSjlJpVwOpo1JRSTEi7dRcwNy4h4dzV70PqHcg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/scope-manager": "8.61.1",
- "@typescript-eslint/types": "8.61.1",
- "@typescript-eslint/typescript-estree": "8.61.1",
- "@typescript-eslint/visitor-keys": "8.61.1",
- "debug": "^4.4.3"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
- "typescript": ">=4.8.4 <6.1.0"
- }
- },
- "node_modules/@typescript-eslint/project-service": {
- "version": "8.61.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.61.1.tgz",
- "integrity": "sha512-PrC4JYGmR241lYnfhmKGTXkFqv8+ymbTFgSAY0fVXpY82/QkMw5TZPl+vGzuDDU2QYJk9fIDOBTntF+yDv9LEA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/tsconfig-utils": "^8.61.1",
- "@typescript-eslint/types": "^8.61.1",
- "debug": "^4.4.3"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "typescript": ">=4.8.4 <6.1.0"
- }
- },
- "node_modules/@typescript-eslint/scope-manager": {
- "version": "8.61.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.61.1.tgz",
- "integrity": "sha512-L2bdIeoQS8FlKAvONAr20w6OcLXeB+qiDKbAooS9A0Ben+iSIkBef0FxqwKWYqt5sa0i4KJtxVyVmhMylKzF5w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/types": "8.61.1",
- "@typescript-eslint/visitor-keys": "8.61.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@typescript-eslint/tsconfig-utils": {
- "version": "8.61.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.61.1.tgz",
- "integrity": "sha512-UN/H4di+OO7EWx2ovME+8t31YO+KVnK0RRKEHR3kOt21/Ay8BOq3M1OMvWs5vNiqcFCYGYoxK3MXPZzmMUE+yg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "typescript": ">=4.8.4 <6.1.0"
- }
- },
- "node_modules/@typescript-eslint/type-utils": {
- "version": "8.61.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.61.1.tgz",
- "integrity": "sha512-GYRicKmVK0C4fsKgaACaknOUAq9Oa2kwsjnpFhFcS/5p4Ht5IP9OVLbgIgcK4SRk92nVHFluurg1lumD9dBcLw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/types": "8.61.1",
- "@typescript-eslint/typescript-estree": "8.61.1",
- "@typescript-eslint/utils": "8.61.1",
- "debug": "^4.4.3",
- "ts-api-utils": "^2.5.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
- "typescript": ">=4.8.4 <6.1.0"
- }
- },
- "node_modules/@typescript-eslint/types": {
- "version": "8.61.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.61.1.tgz",
- "integrity": "sha512-G+CRlPqLv7Bz1IZVs03x5K59F1veqL0EJUROAdGhKsEq8qOiRiZbI+HUojPq5l0fEGOKModD9br6lObhB8zkoA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@typescript-eslint/typescript-estree": {
- "version": "8.61.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.61.1.tgz",
- "integrity": "sha512-u+oQD3BqYWPc8YV9Zab4vaJElJuwOLPRc10Jm1o/qS+6Qwen14HCWwx0Seo4LnSn2wxea2Ik8DxPt2/FHmuhrg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/project-service": "8.61.1",
- "@typescript-eslint/tsconfig-utils": "8.61.1",
- "@typescript-eslint/types": "8.61.1",
- "@typescript-eslint/visitor-keys": "8.61.1",
- "debug": "^4.4.3",
- "minimatch": "^10.2.2",
- "semver": "^7.7.3",
- "tinyglobby": "^0.2.15",
- "ts-api-utils": "^2.5.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "typescript": ">=4.8.4 <6.1.0"
- }
- },
- "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
- "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": "^5.0.5"
- },
- "engines": {
- "node": "18 || 20 || >=22"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/@typescript-eslint/utils": {
- "version": "8.61.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.61.1.tgz",
- "integrity": "sha512-1+P/3Dj6jvtybE1q0HQ6yBt/gq+oKJyLdEv4HdnqasaEXRSYCAsD59mXEVQnM/ULNdQxbX77tdG4jPRjIS6knA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@eslint-community/eslint-utils": "^4.9.1",
- "@typescript-eslint/scope-manager": "8.61.1",
- "@typescript-eslint/types": "8.61.1",
- "@typescript-eslint/typescript-estree": "8.61.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
- "typescript": ">=4.8.4 <6.1.0"
- }
- },
- "node_modules/@typescript-eslint/visitor-keys": {
- "version": "8.61.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.61.1.tgz",
- "integrity": "sha512-6fJ9MHWtK14C1DSkiMlHUSOmrVebL7150xZJBlJiL62jjhIA4JmOq6flwBgDxIdBKKdoiZRel+dfPD5MLfny3w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/types": "8.61.1",
- "eslint-visitor-keys": "^5.0.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- }
- },
- "node_modules/@unrs/resolver-binding-android-arm-eabi": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.12.2.tgz",
- "integrity": "sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ]
- },
- "node_modules/@unrs/resolver-binding-android-arm64": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.12.2.tgz",
- "integrity": "sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ]
- },
- "node_modules/@unrs/resolver-binding-darwin-arm64": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.12.2.tgz",
- "integrity": "sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@unrs/resolver-binding-darwin-x64": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.12.2.tgz",
- "integrity": "sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ]
- },
- "node_modules/@unrs/resolver-binding-freebsd-x64": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.12.2.tgz",
- "integrity": "sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ]
- },
- "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.12.2.tgz",
- "integrity": "sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.12.2.tgz",
- "integrity": "sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@unrs/resolver-binding-linux-arm64-gnu": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.12.2.tgz",
- "integrity": "sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@unrs/resolver-binding-linux-arm64-musl": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.12.2.tgz",
- "integrity": "sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@unrs/resolver-binding-linux-loong64-gnu": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-gnu/-/resolver-binding-linux-loong64-gnu-1.12.2.tgz",
- "integrity": "sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@unrs/resolver-binding-linux-loong64-musl": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-musl/-/resolver-binding-linux-loong64-musl-1.12.2.tgz",
- "integrity": "sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.12.2.tgz",
- "integrity": "sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.12.2.tgz",
- "integrity": "sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@unrs/resolver-binding-linux-riscv64-musl": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.12.2.tgz",
- "integrity": "sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@unrs/resolver-binding-linux-s390x-gnu": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.12.2.tgz",
- "integrity": "sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@unrs/resolver-binding-linux-x64-gnu": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.12.2.tgz",
- "integrity": "sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@unrs/resolver-binding-linux-x64-musl": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.12.2.tgz",
- "integrity": "sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ]
- },
- "node_modules/@unrs/resolver-binding-openharmony-arm64": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-openharmony-arm64/-/resolver-binding-openharmony-arm64-1.12.2.tgz",
- "integrity": "sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openharmony"
- ]
- },
- "node_modules/@unrs/resolver-binding-wasm32-wasi": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.12.2.tgz",
- "integrity": "sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==",
- "cpu": [
- "wasm32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "@emnapi/core": "1.10.0",
- "@emnapi/runtime": "1.10.0",
- "@napi-rs/wasm-runtime": "^1.1.4"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/runtime": {
- "version": "1.10.0",
- "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz",
- "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "dependencies": {
- "tslib": "^2.4.0"
- }
- },
- "node_modules/@unrs/resolver-binding-win32-arm64-msvc": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz",
- "integrity": "sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@unrs/resolver-binding-win32-ia32-msvc": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.12.2.tgz",
- "integrity": "sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@unrs/resolver-binding-win32-x64-msvc": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.12.2.tgz",
- "integrity": "sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ]
- },
- "node_modules/@upstash/redis": {
- "version": "1.38.0",
- "resolved": "https://registry.npmjs.org/@upstash/redis/-/redis-1.38.0.tgz",
- "integrity": "sha512-wu+dZBptlLy0+MCUEoHmzrY/TnmgDey3+c7EbIGwrLqAvkP8yi5MWZHYGIFtAygmL4Bkz2TdFu+eU0vFPncIcg==",
- "license": "MIT",
- "dependencies": {
- "uncrypto": "^0.1.3"
- }
- },
- "node_modules/@upstash/search": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/@upstash/search/-/search-0.1.7.tgz",
- "integrity": "sha512-rgJ52TP0eUPLFo4K6TZtiC7qICbJnEwkT+TqaDI1vN8/Hk6qidgNC9dpnUUXCiqfwogty1rlSyBhYfk6PRgXjA==",
- "license": "MIT",
- "dependencies": {
- "@upstash/vector": "^1.2.1"
- }
- },
- "node_modules/@upstash/vector": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@upstash/vector/-/vector-1.2.3.tgz",
- "integrity": "sha512-yXsWKeuHNYyH72BcSZd3bV5ZD5MybAoTvKxkMaeV2UzuGfNzbHBVh5eO+ysTWTFAf8I9XcOueF4tZfAGjCa4Iw==",
- "license": "MIT"
- },
- "node_modules/@vercel/analytics": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/@vercel/analytics/-/analytics-2.0.1.tgz",
- "integrity": "sha512-MTQG6V9qQrt1tsDeF+2Uoo5aPjqbVPys1xvnIftXSJYG2SrwXRHnqEvVoYID7BTruDz4lCd2Z7rM1BdkUehk2g==",
- "license": "MIT",
- "peerDependencies": {
- "@remix-run/react": "^2",
- "@sveltejs/kit": "^1 || ^2",
- "next": ">= 13",
- "nuxt": ">= 3",
- "react": "^18 || ^19 || ^19.0.0-rc",
- "svelte": ">= 4",
- "vue": "^3",
- "vue-router": "^4"
- },
- "peerDependenciesMeta": {
- "@remix-run/react": {
- "optional": true
- },
- "@sveltejs/kit": {
- "optional": true
- },
- "next": {
- "optional": true
- },
- "nuxt": {
- "optional": true
- },
- "react": {
- "optional": true
- },
- "svelte": {
- "optional": true
- },
- "vue": {
- "optional": true
- },
- "vue-router": {
- "optional": true
- }
- }
- },
- "node_modules/@vercel/cli-config": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/@vercel/cli-config/-/cli-config-0.2.0.tgz",
- "integrity": "sha512-fJRRRB7734BDuXZ89yBEaA2ncYhH7bWX30mk04W80J6VAfQc+4iB8lyzAdaGpFV3/vNlkt9VZt+/uoQoWX6UsQ==",
- "license": "Apache-2.0",
- "dependencies": {
- "xdg-app-paths": "5",
- "zod": "4.1.11"
- }
- },
- "node_modules/@vercel/cli-config/node_modules/zod": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.11.tgz",
- "integrity": "sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/colinhacks"
- }
- },
- "node_modules/@vercel/cli-exec": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@vercel/cli-exec/-/cli-exec-1.0.0.tgz",
- "integrity": "sha512-kQF8LGie/Hbdq9/psJxLE7owRTcqMQMhgybU04gCeR7cbQAr5t8OrjefDNColJv1QSSucFt4pLwRiARVmlOnug==",
- "license": "Apache-2.0",
- "dependencies": {
- "execa": "5.1.1"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/@vercel/functions": {
- "version": "3.7.5",
- "resolved": "https://registry.npmjs.org/@vercel/functions/-/functions-3.7.5.tgz",
- "integrity": "sha512-ESf8BbeDebqRUyMi09JwRbQqpLn4g6fjcVVHPsHB56j2dSqRrSHO4h3X4aaxJf6iQQjzhAtDGI2xCWQ27JE8PA==",
- "license": "Apache-2.0",
- "dependencies": {
- "@vercel/oidc": "3.8.0"
- },
- "engines": {
- "node": ">= 20"
- },
- "peerDependencies": {
- "@aws-sdk/credential-provider-web-identity": "*",
- "ws": ">=8"
- },
- "peerDependenciesMeta": {
- "@aws-sdk/credential-provider-web-identity": {
- "optional": true
- },
- "ws": {
- "optional": true
- }
- }
- },
- "node_modules/@vercel/functions/node_modules/@vercel/oidc": {
- "version": "3.8.0",
- "resolved": "https://registry.npmjs.org/@vercel/oidc/-/oidc-3.8.0.tgz",
- "integrity": "sha512-r00laGW6Pv778RoR6M2NxX91ycSj+PBwVo+fOb9Bif+F0IyUKt25zrvBzfEzQpeAzbqOgPZyQibEWDdDFApd+A==",
- "license": "Apache-2.0",
- "dependencies": {
- "@vercel/cli-config": "0.2.0",
- "@vercel/cli-exec": "1.0.0",
- "jose": "^5.9.6"
- },
- "engines": {
- "node": ">= 20"
- }
- },
- "node_modules/@vercel/functions/node_modules/jose": {
- "version": "5.10.0",
- "resolved": "https://registry.npmjs.org/jose/-/jose-5.10.0.tgz",
- "integrity": "sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/panva"
- }
- },
- "node_modules/@vercel/oidc": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/@vercel/oidc/-/oidc-3.2.0.tgz",
- "integrity": "sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">= 20"
- }
- },
- "node_modules/@vercel/speed-insights": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@vercel/speed-insights/-/speed-insights-2.0.0.tgz",
- "integrity": "sha512-jwkNcrTeafWxjmWq4AHBaptSqZiJkYU5adLC9QBSqeim0GcqDMgN5Ievh8OG1rJ6W3A4l1oiP7qr9CWxGuzu3w==",
- "license": "Apache-2.0",
- "peerDependencies": {
- "@sveltejs/kit": "^1 || ^2",
- "next": ">= 13",
- "nuxt": ">= 3",
- "react": "^18 || ^19 || ^19.0.0-rc",
- "svelte": ">= 4",
- "vue": "^3",
- "vue-router": "^4"
- },
- "peerDependenciesMeta": {
- "@sveltejs/kit": {
- "optional": true
- },
- "next": {
- "optional": true
- },
- "nuxt": {
- "optional": true
- },
- "react": {
- "optional": true
- },
- "svelte": {
- "optional": true
- },
- "vue": {
- "optional": true
- },
- "vue-router": {
- "optional": true
- }
- }
- },
- "node_modules/@workflow/serde": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/@workflow/serde/-/serde-4.1.0.tgz",
- "integrity": "sha512-pav4F2BoirECWR7Nf1TKt+2eETcBj7jj4cBefQ8VXQCA6NPkaKeLfj/zMgi+3zYV5ZIBT4GuUiphsj0/b9hPQQ==",
- "license": "Apache-2.0"
- },
- "node_modules/accepts": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
- "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "mime-types": "^3.0.0",
- "negotiator": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/acorn": {
- "version": "8.17.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz",
- "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==",
- "license": "MIT",
- "bin": {
- "acorn": "bin/acorn"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/acorn-import-attributes": {
- "version": "1.9.5",
- "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz",
- "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==",
- "license": "MIT",
- "peerDependencies": {
- "acorn": "^8"
- }
- },
- "node_modules/acorn-jsx": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
- "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
- "dev": true,
- "license": "MIT",
- "peerDependencies": {
- "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
- }
- },
- "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==",
- "license": "MIT",
- "dependencies": {
- "debug": "4"
- },
- "engines": {
- "node": ">= 6.0.0"
- }
- },
- "node_modules/ai": {
- "version": "7.0.31",
- "resolved": "https://registry.npmjs.org/ai/-/ai-7.0.31.tgz",
- "integrity": "sha512-pJfwKXjF5kw0rKRTePwYo60EfWb8wfzJAgf3ojln/YkOsVVKttzZAJVcRPsg37Z3a06ZdKkxX+DSrMAFlPm5Mw==",
- "license": "Apache-2.0",
- "dependencies": {
- "@ai-sdk/gateway": "4.0.23",
- "@ai-sdk/provider": "4.0.3",
- "@ai-sdk/provider-utils": "5.0.11"
- },
- "engines": {
- "node": ">=22"
- },
- "peerDependencies": {
- "zod": "^3.25.76 || ^4.1.8"
- }
- },
- "node_modules/ajv": {
- "version": "8.20.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz",
- "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fast-deep-equal": "^3.1.3",
- "fast-uri": "^3.0.1",
- "json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/ajv-formats": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz",
- "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ajv": "^8.0.0"
- },
- "peerDependencies": {
- "ajv": "^8.0.0"
- },
- "peerDependenciesMeta": {
- "ajv": {
- "optional": true
- }
- }
- },
- "node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "license": "MIT",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true,
- "license": "Python-2.0"
- },
- "node_modules/aria-query": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz",
- "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/array-buffer-byte-length": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz",
- "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.3",
- "is-array-buffer": "^3.0.5"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/array-includes": {
- "version": "3.1.9",
- "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz",
- "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.8",
- "call-bound": "^1.0.4",
- "define-properties": "^1.2.1",
- "es-abstract": "^1.24.0",
- "es-object-atoms": "^1.1.1",
- "get-intrinsic": "^1.3.0",
- "is-string": "^1.1.1",
- "math-intrinsics": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/array.prototype.findlast": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz",
- "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.7",
- "define-properties": "^1.2.1",
- "es-abstract": "^1.23.2",
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.0.0",
- "es-shim-unscopables": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/array.prototype.findlastindex": {
- "version": "1.2.6",
- "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz",
- "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.8",
- "call-bound": "^1.0.4",
- "define-properties": "^1.2.1",
- "es-abstract": "^1.23.9",
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.1.1",
- "es-shim-unscopables": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/array.prototype.flat": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz",
- "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.8",
- "define-properties": "^1.2.1",
- "es-abstract": "^1.23.5",
- "es-shim-unscopables": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/array.prototype.flatmap": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz",
- "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.8",
- "define-properties": "^1.2.1",
- "es-abstract": "^1.23.5",
- "es-shim-unscopables": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/array.prototype.tosorted": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz",
- "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.7",
- "define-properties": "^1.2.1",
- "es-abstract": "^1.23.3",
- "es-errors": "^1.3.0",
- "es-shim-unscopables": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/arraybuffer.prototype.slice": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz",
- "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "array-buffer-byte-length": "^1.0.1",
- "call-bind": "^1.0.8",
- "define-properties": "^1.2.1",
- "es-abstract": "^1.23.5",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.6",
- "is-array-buffer": "^3.0.4"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/assertion-error": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
- "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/ast-types-flow": {
- "version": "0.0.8",
- "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz",
- "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/astring": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz",
- "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==",
- "license": "MIT",
- "bin": {
- "astring": "bin/astring"
- }
- },
- "node_modules/async-function": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz",
- "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/available-typed-arrays": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
- "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "possible-typed-array-names": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/axe-core": {
- "version": "4.12.1",
- "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.12.1.tgz",
- "integrity": "sha512-s7iGf5GaVMxEG0ENN9x+xTr7GFZCb1ZP/1uATUpCEK2X78nDB3RwbtFCo9pGAf9ru+VwoQ464DkaLEeRM08wJA==",
- "dev": true,
- "license": "MPL-2.0",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/axobject-query": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
- "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "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"
- },
- "node_modules/base64-js": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
- "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
- "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/baseline-browser-mapping": {
- "version": "2.10.43",
- "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.43.tgz",
- "integrity": "sha512-AjYpR78kDWAY3Efj+cDTFH9t9SCoL7OoTp1BOb0mQV7S+6CiLwnWM3FyxhJtdPufDFKzmCSFoUncKjWgJEZTCQ==",
- "license": "Apache-2.0",
- "bin": {
- "baseline-browser-mapping": "dist/cli.cjs"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/bignumber.js": {
- "version": "9.3.1",
- "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz",
- "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==",
- "license": "MIT",
- "engines": {
- "node": "*"
- }
- },
- "node_modules/body-parser": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz",
- "integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "bytes": "^3.1.2",
- "content-type": "^2.0.0",
- "debug": "^4.4.3",
- "http-errors": "^2.0.1",
- "iconv-lite": "^0.7.2",
- "on-finished": "^2.4.1",
- "qs": "^6.15.2",
- "raw-body": "^3.0.2",
- "type-is": "^2.1.0"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "node_modules/body-parser/node_modules/content-type": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz",
- "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "node_modules/brace-expansion": {
- "version": "5.0.8",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz",
- "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==",
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^4.0.2"
- },
- "engines": {
- "node": "20 || >=22"
- }
- },
- "node_modules/brace-expansion/node_modules/balanced-match": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
- "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
- "license": "MIT",
- "engines": {
- "node": "18 || 20 || >=22"
- }
- },
- "node_modules/braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fill-range": "^7.1.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/browserslist": {
- "version": "4.28.6",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.6.tgz",
- "integrity": "sha512-FQBYNK15VMslhLHpA7+n+n1GOlF1kId2xcCg7/j95f24AOF6VDYMNH4mFxF7KuaTdv627faazpOAjFzMrfJOUw==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "baseline-browser-mapping": "^2.10.42",
- "caniuse-lite": "^1.0.30001803",
- "electron-to-chromium": "^1.5.389",
- "node-releases": "^2.0.51",
- "update-browserslist-db": "^1.2.3"
- },
- "bin": {
- "browserslist": "cli.js"
- },
- "engines": {
- "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
- }
- },
- "node_modules/buffer-equal-constant-time": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
- "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
- "license": "BSD-3-Clause"
- },
- "node_modules/building-production-ai-infrastructure-platform": {
- "resolved": "apps/web",
- "link": true
- },
- "node_modules/bytes": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
- "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/call-bind": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz",
- "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "es-define-property": "^1.0.1",
- "get-intrinsic": "^1.3.0",
- "set-function-length": "^1.2.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/call-bind-apply-helpers": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
- "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/call-bound": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
- "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "get-intrinsic": "^1.3.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/callsites": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
- "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/caniuse-lite": {
- "version": "1.0.30001806",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz",
- "integrity": "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "CC-BY-4.0"
- },
- "node_modules/chai": {
- "version": "6.2.2",
- "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz",
- "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/chrome-devtools-mcp": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/chrome-devtools-mcp/-/chrome-devtools-mcp-1.6.0.tgz",
- "integrity": "sha512-VZX6f/OjQSYhy2BGGRs+y3LsrsAQAz/HwZCWKBLVyST/4r/3zjVEjjVW7gMCVbRDuspnVdcp5hQDPrQ5UFrdZw==",
- "license": "Apache-2.0",
- "bin": {
- "chrome-devtools": "build/src/bin/chrome-devtools.js",
- "chrome-devtools-mcp": "build/src/bin/chrome-devtools-mcp.js"
- },
- "engines": {
- "node": "^20.19.0 || ^22.12.0 || >=23"
- },
- "peerDependencies": {
- "@blackwell-systems/gcf": "^2.2.2",
- "@toon-format/toon": "^2.2.0"
- },
- "peerDependenciesMeta": {
- "@blackwell-systems/gcf": {
- "optional": true
- },
- "@toon-format/toon": {
- "optional": true
- }
- }
- },
- "node_modules/cjs-module-lexer": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz",
- "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==",
- "license": "MIT"
- },
- "node_modules/class-variance-authority": {
- "version": "0.7.1",
- "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz",
- "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==",
- "license": "Apache-2.0",
- "dependencies": {
- "clsx": "^2.1.1"
- },
- "funding": {
- "url": "https://polar.sh/cva"
- }
- },
- "node_modules/client-only": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
- "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
- "license": "MIT"
- },
- "node_modules/cliui": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
- "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
- "license": "ISC",
- "dependencies": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.1",
- "wrap-ansi": "^7.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/clsx": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
- "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "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==",
- "license": "MIT",
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "license": "MIT"
- },
- "node_modules/commondir": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
- "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==",
- "license": "MIT"
- },
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/content-disposition": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz",
- "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "node_modules/content-type": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
- "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/convert-source-map": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
- "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
- "license": "MIT"
- },
- "node_modules/cookie": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
- "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/cookie-signature": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
- "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.6.0"
- }
- },
- "node_modules/cors": {
- "version": "2.8.6",
- "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz",
- "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "object-assign": "^4",
- "vary": "^1"
- },
- "engines": {
- "node": ">= 0.10"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "node_modules/cross-spawn": {
- "version": "7.0.6",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
- "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
- "license": "MIT",
- "dependencies": {
- "path-key": "^3.1.0",
- "shebang-command": "^2.0.0",
- "which": "^2.0.1"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/csstype": {
- "version": "3.2.3",
- "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
- "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/damerau-levenshtein": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
- "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==",
- "dev": true,
- "license": "BSD-2-Clause"
- },
- "node_modules/data-uri-to-buffer": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
- "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
- "license": "MIT",
- "engines": {
- "node": ">= 12"
- }
- },
- "node_modules/data-view-buffer": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz",
- "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.3",
- "es-errors": "^1.3.0",
- "is-data-view": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/data-view-byte-length": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz",
- "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.3",
- "es-errors": "^1.3.0",
- "is-data-view": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/inspect-js"
- }
- },
- "node_modules/data-view-byte-offset": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz",
- "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "is-data-view": "^1.0.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/debug": {
- "version": "4.4.3",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
- "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.3"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/debug/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "license": "MIT"
- },
- "node_modules/deep-is": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
- "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/define-data-property": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
- "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "es-define-property": "^1.0.0",
- "es-errors": "^1.3.0",
- "gopd": "^1.0.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/define-properties": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz",
- "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "define-data-property": "^1.0.1",
- "has-property-descriptors": "^1.0.0",
- "object-keys": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/depd": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
- "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "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==",
- "devOptional": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/doctrine": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
- "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "esutils": "^2.0.2"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/dotenv": {
- "version": "17.4.2",
- "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz",
- "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://dotenvx.com"
- }
- },
- "node_modules/dunder-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
- "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.1",
- "es-errors": "^1.3.0",
- "gopd": "^1.2.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/duplexify": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz",
- "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==",
- "license": "MIT",
- "dependencies": {
- "end-of-stream": "^1.4.1",
- "inherits": "^2.0.3",
- "readable-stream": "^3.1.1",
- "stream-shift": "^1.0.2"
- }
- },
- "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/ecdsa-sig-formatter": {
- "version": "1.0.11",
- "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
- "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
- "license": "Apache-2.0",
- "dependencies": {
- "safe-buffer": "^5.0.1"
- }
- },
- "node_modules/ee-first": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
- "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/electron-to-chromium": {
- "version": "1.5.393",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.393.tgz",
- "integrity": "sha512-kiDJdIUawuEIcp9XoICKp1iTYDEbgguIPq526N1Q7jIQDeQ3CqoMx71025PI/7E48Ddtw2HuWsVjY7afEgNxmg==",
- "license": "ISC"
- },
- "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/encodeurl": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
- "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/end-of-stream": {
- "version": "1.4.5",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
- "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
- "license": "MIT",
- "dependencies": {
- "once": "^1.4.0"
- }
- },
- "node_modules/enhanced-resolve": {
- "version": "5.21.6",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.21.6.tgz",
- "integrity": "sha512-aNnGCvbJ/RIyWo1IuhNdVjnNF+EjH9wpzpNHt+ci/m9He9LJvUN8wrCcXjp9cWsGNAuvSpVFTx/vraAFQ8qGjQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "graceful-fs": "^4.2.4",
- "tapable": "^2.3.3"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "node_modules/es-abstract": {
- "version": "1.24.2",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz",
- "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "array-buffer-byte-length": "^1.0.2",
- "arraybuffer.prototype.slice": "^1.0.4",
- "available-typed-arrays": "^1.0.7",
- "call-bind": "^1.0.8",
- "call-bound": "^1.0.4",
- "data-view-buffer": "^1.0.2",
- "data-view-byte-length": "^1.0.2",
- "data-view-byte-offset": "^1.0.1",
- "es-define-property": "^1.0.1",
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.1.1",
- "es-set-tostringtag": "^2.1.0",
- "es-to-primitive": "^1.3.0",
- "function.prototype.name": "^1.1.8",
- "get-intrinsic": "^1.3.0",
- "get-proto": "^1.0.1",
- "get-symbol-description": "^1.1.0",
- "globalthis": "^1.0.4",
- "gopd": "^1.2.0",
- "has-property-descriptors": "^1.0.2",
- "has-proto": "^1.2.0",
- "has-symbols": "^1.1.0",
- "hasown": "^2.0.2",
- "internal-slot": "^1.1.0",
- "is-array-buffer": "^3.0.5",
- "is-callable": "^1.2.7",
- "is-data-view": "^1.0.2",
- "is-negative-zero": "^2.0.3",
- "is-regex": "^1.2.1",
- "is-set": "^2.0.3",
- "is-shared-array-buffer": "^1.0.4",
- "is-string": "^1.1.1",
- "is-typed-array": "^1.1.15",
- "is-weakref": "^1.1.1",
- "math-intrinsics": "^1.1.0",
- "object-inspect": "^1.13.4",
- "object-keys": "^1.1.1",
- "object.assign": "^4.1.7",
- "own-keys": "^1.0.1",
- "regexp.prototype.flags": "^1.5.4",
- "safe-array-concat": "^1.1.3",
- "safe-push-apply": "^1.0.0",
- "safe-regex-test": "^1.1.0",
- "set-proto": "^1.0.0",
- "stop-iteration-iterator": "^1.1.0",
- "string.prototype.trim": "^1.2.10",
- "string.prototype.trimend": "^1.0.9",
- "string.prototype.trimstart": "^1.0.8",
- "typed-array-buffer": "^1.0.3",
- "typed-array-byte-length": "^1.0.3",
- "typed-array-byte-offset": "^1.0.4",
- "typed-array-length": "^1.0.7",
- "unbox-primitive": "^1.1.0",
- "which-typed-array": "^1.1.19"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/es-abstract-get": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/es-abstract-get/-/es-abstract-get-1.0.0.tgz",
- "integrity": "sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.1.2",
- "is-callable": "^1.2.7",
- "object-inspect": "^1.13.4"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/es-define-property": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
- "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-errors": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
- "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-iterator-helpers": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.3.3.tgz",
- "integrity": "sha512-0PuBxFi+4uPanB97iDxCLWuHeYud2FALrw5HFZGtAF38UpJDbDC8frwp2cnDyae692CQ0dou60UwWfhgsa4U/g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.9",
- "call-bound": "^1.0.4",
- "define-properties": "^1.2.1",
- "es-abstract": "^1.24.2",
- "es-errors": "^1.3.0",
- "es-set-tostringtag": "^2.1.0",
- "function-bind": "^1.1.2",
- "get-intrinsic": "^1.3.0",
- "globalthis": "^1.0.4",
- "gopd": "^1.2.0",
- "has-property-descriptors": "^1.0.2",
- "has-proto": "^1.2.0",
- "has-symbols": "^1.1.0",
- "internal-slot": "^1.1.0",
- "iterator.prototype": "^1.1.5",
- "math-intrinsics": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-module-lexer": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.1.0.tgz",
- "integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==",
- "license": "MIT"
- },
- "node_modules/es-object-atoms": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz",
- "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-set-tostringtag": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
- "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.6",
- "has-tostringtag": "^1.0.2",
- "hasown": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-shim-unscopables": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz",
- "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "hasown": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/es-to-primitive": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.1.tgz",
- "integrity": "sha512-CxN9N56HYfd2m/acc/NOFrZQsN9kU4eh+2kk6A707Kz1krH8tKmfrs5RnftB8WNX80T0NS7vSQsDOlg23diR2g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "es-abstract-get": "^1.0.0",
- "es-errors": "^1.3.0",
- "is-callable": "^1.2.7",
- "is-date-object": "^1.1.0",
- "is-symbol": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/esbuild": {
- "version": "0.28.1",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz",
- "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==",
- "hasInstallScript": true,
- "license": "MIT",
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=18"
- },
- "optionalDependencies": {
- "@esbuild/aix-ppc64": "0.28.1",
- "@esbuild/android-arm": "0.28.1",
- "@esbuild/android-arm64": "0.28.1",
- "@esbuild/android-x64": "0.28.1",
- "@esbuild/darwin-arm64": "0.28.1",
- "@esbuild/darwin-x64": "0.28.1",
- "@esbuild/freebsd-arm64": "0.28.1",
- "@esbuild/freebsd-x64": "0.28.1",
- "@esbuild/linux-arm": "0.28.1",
- "@esbuild/linux-arm64": "0.28.1",
- "@esbuild/linux-ia32": "0.28.1",
- "@esbuild/linux-loong64": "0.28.1",
- "@esbuild/linux-mips64el": "0.28.1",
- "@esbuild/linux-ppc64": "0.28.1",
- "@esbuild/linux-riscv64": "0.28.1",
- "@esbuild/linux-s390x": "0.28.1",
- "@esbuild/linux-x64": "0.28.1",
- "@esbuild/netbsd-arm64": "0.28.1",
- "@esbuild/netbsd-x64": "0.28.1",
- "@esbuild/openbsd-arm64": "0.28.1",
- "@esbuild/openbsd-x64": "0.28.1",
- "@esbuild/openharmony-arm64": "0.28.1",
- "@esbuild/sunos-x64": "0.28.1",
- "@esbuild/win32-arm64": "0.28.1",
- "@esbuild/win32-ia32": "0.28.1",
- "@esbuild/win32-x64": "0.28.1"
- }
- },
- "node_modules/escalade": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
- "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/escape-html": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
- "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/escape-string-regexp": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
- "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/eslint": {
- "version": "9.39.5",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz",
- "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@eslint-community/eslint-utils": "^4.8.0",
- "@eslint-community/regexpp": "^4.12.1",
- "@eslint/config-array": "^0.21.2",
- "@eslint/config-helpers": "^0.4.2",
- "@eslint/core": "^0.17.0",
- "@eslint/eslintrc": "^3.3.6",
- "@eslint/js": "9.39.5",
- "@eslint/plugin-kit": "^0.4.1",
- "@humanfs/node": "^0.16.6",
- "@humanwhocodes/module-importer": "^1.0.1",
- "@humanwhocodes/retry": "^0.4.2",
- "@types/estree": "^1.0.6",
- "ajv": "^6.14.0",
- "chalk": "^4.0.0",
- "cross-spawn": "^7.0.6",
- "debug": "^4.3.2",
- "escape-string-regexp": "^4.0.0",
- "eslint-scope": "^8.4.0",
- "eslint-visitor-keys": "^4.2.1",
- "espree": "^10.4.0",
- "esquery": "^1.5.0",
- "esutils": "^2.0.2",
- "fast-deep-equal": "^3.1.3",
- "file-entry-cache": "^8.0.0",
- "find-up": "^5.0.0",
- "glob-parent": "^6.0.2",
- "ignore": "^5.2.0",
- "imurmurhash": "^0.1.4",
- "is-glob": "^4.0.0",
- "json-stable-stringify-without-jsonify": "^1.0.1",
- "lodash.merge": "^4.6.2",
- "minimatch": "^3.1.5",
- "natural-compare": "^1.4.0",
- "optionator": "^0.9.3"
- },
- "bin": {
- "eslint": "bin/eslint.js"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://eslint.org/donate"
- },
- "peerDependencies": {
- "jiti": "*"
- },
- "peerDependenciesMeta": {
- "jiti": {
- "optional": true
- }
- }
- },
- "node_modules/eslint-import-resolver-node": {
- "version": "0.3.10",
- "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.10.tgz",
- "integrity": "sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "debug": "^3.2.7",
- "is-core-module": "^2.16.1",
- "resolve": "^2.0.0-next.6"
- }
- },
- "node_modules/eslint-import-resolver-node/node_modules/debug": {
- "version": "3.2.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
- "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.1"
- }
- },
- "node_modules/eslint-import-resolver-node/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/eslint-import-resolver-typescript": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.10.1.tgz",
- "integrity": "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "@nolyfill/is-core-module": "1.0.39",
- "debug": "^4.4.0",
- "get-tsconfig": "^4.10.0",
- "is-bun-module": "^2.0.0",
- "stable-hash": "^0.0.5",
- "tinyglobby": "^0.2.13",
- "unrs-resolver": "^1.6.2"
- },
- "engines": {
- "node": "^14.18.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint-import-resolver-typescript"
- },
- "peerDependencies": {
- "eslint": "*",
- "eslint-plugin-import": "*",
- "eslint-plugin-import-x": "*"
- },
- "peerDependenciesMeta": {
- "eslint-plugin-import": {
- "optional": true
- },
- "eslint-plugin-import-x": {
- "optional": true
- }
- }
- },
- "node_modules/eslint-module-utils": {
- "version": "2.13.0",
- "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.13.0.tgz",
- "integrity": "sha512-bLohSkT6469rRs8czj0tLTD8vaeIS/whvPRJVjDr7IuoTT1k5DYDERlNycjDj/HkOlvQdYurmfZ/g3fG5bgeLQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "debug": "^3.2.7"
- },
- "engines": {
- "node": ">=4"
- },
- "peerDependenciesMeta": {
- "eslint": {
- "optional": true
- }
- }
- },
- "node_modules/eslint-module-utils/node_modules/debug": {
- "version": "3.2.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
- "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.1"
- }
- },
- "node_modules/eslint-module-utils/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/eslint-plugin-import": {
- "version": "2.32.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz",
- "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@rtsao/scc": "^1.1.0",
- "array-includes": "^3.1.9",
- "array.prototype.findlastindex": "^1.2.6",
- "array.prototype.flat": "^1.3.3",
- "array.prototype.flatmap": "^1.3.3",
- "debug": "^3.2.7",
- "doctrine": "^2.1.0",
- "eslint-import-resolver-node": "^0.3.9",
- "eslint-module-utils": "^2.12.1",
- "hasown": "^2.0.2",
- "is-core-module": "^2.16.1",
- "is-glob": "^4.0.3",
- "minimatch": "^3.1.2",
- "object.fromentries": "^2.0.8",
- "object.groupby": "^1.0.3",
- "object.values": "^1.2.1",
- "semver": "^6.3.1",
- "string.prototype.trimend": "^1.0.9",
- "tsconfig-paths": "^3.15.0"
- },
- "engines": {
- "node": ">=4"
- },
- "peerDependencies": {
- "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9"
- }
- },
- "node_modules/eslint-plugin-import/node_modules/debug": {
- "version": "3.2.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
- "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.1"
- }
- },
- "node_modules/eslint-plugin-import/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/eslint-plugin-import/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/eslint-plugin-jsx-a11y": {
- "version": "6.10.2",
- "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz",
- "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "aria-query": "^5.3.2",
- "array-includes": "^3.1.8",
- "array.prototype.flatmap": "^1.3.2",
- "ast-types-flow": "^0.0.8",
- "axe-core": "^4.10.0",
- "axobject-query": "^4.1.0",
- "damerau-levenshtein": "^1.0.8",
- "emoji-regex": "^9.2.2",
- "hasown": "^2.0.2",
- "jsx-ast-utils": "^3.3.5",
- "language-tags": "^1.0.9",
- "minimatch": "^3.1.2",
- "object.fromentries": "^2.0.8",
- "safe-regex-test": "^1.0.3",
- "string.prototype.includes": "^2.0.1"
- },
- "engines": {
- "node": ">=4.0"
- },
- "peerDependencies": {
- "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9"
- }
- },
- "node_modules/eslint-plugin-react": {
- "version": "7.37.5",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz",
- "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "array-includes": "^3.1.8",
- "array.prototype.findlast": "^1.2.5",
- "array.prototype.flatmap": "^1.3.3",
- "array.prototype.tosorted": "^1.1.4",
- "doctrine": "^2.1.0",
- "es-iterator-helpers": "^1.2.1",
- "estraverse": "^5.3.0",
- "hasown": "^2.0.2",
- "jsx-ast-utils": "^2.4.1 || ^3.0.0",
- "minimatch": "^3.1.2",
- "object.entries": "^1.1.9",
- "object.fromentries": "^2.0.8",
- "object.values": "^1.2.1",
- "prop-types": "^15.8.1",
- "resolve": "^2.0.0-next.5",
- "semver": "^6.3.1",
- "string.prototype.matchall": "^4.0.12",
- "string.prototype.repeat": "^1.0.0"
- },
- "engines": {
- "node": ">=4"
- },
- "peerDependencies": {
- "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7"
- }
- },
- "node_modules/eslint-plugin-react-hooks": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.1.1.tgz",
- "integrity": "sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@babel/core": "^7.24.4",
- "@babel/parser": "^7.24.4",
- "hermes-parser": "^0.25.1",
- "zod": "^3.25.0 || ^4.0.0",
- "zod-validation-error": "^3.5.0 || ^4.0.0"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0"
- }
- },
- "node_modules/eslint-plugin-react/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/eslint-scope": {
- "version": "8.4.0",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
- "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "esrecurse": "^4.3.0",
- "estraverse": "^5.2.0"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/eslint-visitor-keys": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz",
- "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": "^20.19.0 || ^22.13.0 || >=24"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/eslint/node_modules/ajv": {
- "version": "6.15.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz",
- "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/eslint/node_modules/eslint-visitor-keys": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
- "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/eslint/node_modules/json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/espree": {
- "version": "10.4.0",
- "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
- "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "acorn": "^8.15.0",
- "acorn-jsx": "^5.3.2",
- "eslint-visitor-keys": "^4.2.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/espree/node_modules/eslint-visitor-keys": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
- "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint"
- }
- },
- "node_modules/esquery": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz",
- "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==",
- "license": "BSD-3-Clause",
- "dependencies": {
- "estraverse": "^5.1.0"
- },
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/esrecurse": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
- "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "estraverse": "^5.2.0"
- },
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/estraverse": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
- "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/estree-walker": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
- "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
- "license": "MIT"
- },
- "node_modules/esutils": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
- "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
- "dev": true,
- "license": "BSD-2-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/etag": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
- "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/eventsource": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz",
- "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "eventsource-parser": "^3.0.1"
- },
- "engines": {
- "node": ">=18.0.0"
- }
- },
- "node_modules/eventsource-parser": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.1.0.tgz",
- "integrity": "sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg==",
- "license": "MIT",
- "engines": {
- "node": ">=18.0.0"
- }
- },
- "node_modules/execa": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
- "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
- "license": "MIT",
- "dependencies": {
- "cross-spawn": "^7.0.3",
- "get-stream": "^6.0.0",
- "human-signals": "^2.1.0",
- "is-stream": "^2.0.0",
- "merge-stream": "^2.0.0",
- "npm-run-path": "^4.0.1",
- "onetime": "^5.1.2",
- "signal-exit": "^3.0.3",
- "strip-final-newline": "^2.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/execa?sponsor=1"
- }
- },
- "node_modules/expect-type": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz",
- "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=12.0.0"
- }
- },
- "node_modules/express": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz",
- "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "accepts": "^2.0.0",
- "body-parser": "^2.2.1",
- "content-disposition": "^1.0.0",
- "content-type": "^1.0.5",
- "cookie": "^0.7.1",
- "cookie-signature": "^1.2.1",
- "debug": "^4.4.0",
- "depd": "^2.0.0",
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "etag": "^1.8.1",
- "finalhandler": "^2.1.0",
- "fresh": "^2.0.0",
- "http-errors": "^2.0.0",
- "merge-descriptors": "^2.0.0",
- "mime-types": "^3.0.0",
- "on-finished": "^2.4.1",
- "once": "^1.4.0",
- "parseurl": "^1.3.3",
- "proxy-addr": "^2.0.7",
- "qs": "^6.14.0",
- "range-parser": "^1.2.1",
- "router": "^2.2.0",
- "send": "^1.1.0",
- "serve-static": "^2.2.0",
- "statuses": "^2.0.1",
- "type-is": "^2.0.1",
- "vary": "^1.1.2"
- },
- "engines": {
- "node": ">= 18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "node_modules/express-rate-limit": {
- "version": "8.5.2",
- "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.5.2.tgz",
- "integrity": "sha512-5Kb34ipNX694DH48vN9irak1Qx30nb0PLYHXfJgw4YEjiC3ZEmZJhwOp+VfiCYwFzvFTdB9QkArYS5kXa2cx2A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ip-address": "^10.2.0"
- },
- "engines": {
- "node": ">= 16"
- },
- "funding": {
- "url": "https://github.com/sponsors/express-rate-limit"
- },
- "peerDependencies": {
- "express": ">= 4.11"
- }
- },
- "node_modules/extend": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
- "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
- "license": "MIT"
- },
- "node_modules/fast-deep-equal": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
- "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/fast-glob": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz",
- "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@nodelib/fs.stat": "^2.0.2",
- "@nodelib/fs.walk": "^1.2.3",
- "glob-parent": "^5.1.2",
- "merge2": "^1.3.0",
- "micromatch": "^4.0.4"
- },
- "engines": {
- "node": ">=8.6.0"
- }
- },
- "node_modules/fast-glob/node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/fast-json-stable-stringify": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
- "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/fast-levenshtein": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
- "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/fast-uri": {
- "version": "3.1.4",
- "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz",
- "integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/fastify"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/fastify"
- }
- ],
- "license": "BSD-3-Clause"
- },
- "node_modules/fastq": {
- "version": "1.20.1",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
- "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "reusify": "^1.0.4"
- }
- },
- "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": ">=12.0.0"
- },
- "peerDependencies": {
- "picomatch": "^3 || ^4"
- },
- "peerDependenciesMeta": {
- "picomatch": {
- "optional": true
- }
- }
- },
- "node_modules/fetch-blob": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
- "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/jimmywarting"
- },
- {
- "type": "paypal",
- "url": "https://paypal.me/jimmywarting"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "node-domexception": "^1.0.0",
- "web-streams-polyfill": "^3.0.3"
- },
- "engines": {
- "node": "^12.20 || >= 14.13"
- }
- },
- "node_modules/file-entry-cache": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
- "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "flat-cache": "^4.0.0"
- },
- "engines": {
- "node": ">=16.0.0"
- }
- },
- "node_modules/fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/finalhandler": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz",
- "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "debug": "^4.4.0",
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "on-finished": "^2.4.1",
- "parseurl": "^1.3.3",
- "statuses": "^2.0.1"
- },
- "engines": {
- "node": ">= 18.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "node_modules/find-up": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
- "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
- "license": "MIT",
- "dependencies": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/flat-cache": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
- "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "flatted": "^3.2.9",
- "keyv": "^4.5.4"
- },
- "engines": {
- "node": ">=16"
- }
- },
- "node_modules/flatted": {
- "version": "3.4.2",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz",
- "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/for-each": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
- "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-callable": "^1.2.7"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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/foreground-child/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"
- }
- },
- "node_modules/formdata-polyfill": {
- "version": "4.0.10",
- "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
- "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
- "license": "MIT",
- "dependencies": {
- "fetch-blob": "^3.1.2"
- },
- "engines": {
- "node": ">=12.20.0"
- }
- },
- "node_modules/forwarded": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
- "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/fraction.js": {
- "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": "github",
- "url": "https://github.com/sponsors/rawify"
- }
- },
- "node_modules/fresh": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
- "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "hasInstallScript": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/function-bind": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
- "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/function.prototype.name": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.2.0.tgz",
- "integrity": "sha512-jObKIik1P2QjPHP5nz5BaOtUlfgS0fWo8IUByNXkM+o+02sJOi94em77GwJKQSJ3gfPHdgzLNrHc1uokV4P/ew==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.9",
- "call-bound": "^1.0.4",
- "es-define-property": "^1.0.1",
- "es-errors": "^1.3.0",
- "functions-have-names": "^1.2.3",
- "has-property-descriptors": "^1.0.2",
- "hasown": "^2.0.4",
- "is-callable": "^1.2.7",
- "is-document.all": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/functions-have-names": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
- "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/gaxios": {
- "version": "7.1.5",
- "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.5.tgz",
- "integrity": "sha512-5FZy72Rh8LhtjmvDrKkI+lVhrsQrVKVsItxMoDm5mNQE+xR0WVIIs+jzPSJgBvKVsLi24fZhXJIsNI0bihDzFg==",
- "license": "Apache-2.0",
- "dependencies": {
- "extend": "^3.0.2",
- "https-proxy-agent": "^7.0.1",
- "node-fetch": "^3.3.2"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/gaxios/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==",
- "license": "MIT",
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/gaxios/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==",
- "license": "MIT",
- "dependencies": {
- "agent-base": "^7.1.2",
- "debug": "4"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/gaxios/node_modules/node-fetch": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
- "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
- "license": "MIT",
- "dependencies": {
- "data-uri-to-buffer": "^4.0.0",
- "fetch-blob": "^3.1.4",
- "formdata-polyfill": "^4.0.10"
- },
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/node-fetch"
- }
- },
- "node_modules/gcp-metadata": {
- "version": "8.1.2",
- "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz",
- "integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==",
- "license": "Apache-2.0",
- "dependencies": {
- "gaxios": "^7.0.0",
- "google-logging-utils": "^1.0.0",
- "json-bigint": "^1.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/generator-function": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz",
- "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/gensync": {
- "version": "1.0.0-beta.2",
- "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
- "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/get-caller-file": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
- "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
- "license": "ISC",
- "engines": {
- "node": "6.* || 8.* || >= 10.*"
- }
- },
- "node_modules/get-intrinsic": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
- "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind-apply-helpers": "^1.0.2",
- "es-define-property": "^1.0.1",
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.1.1",
- "function-bind": "^1.1.2",
- "get-proto": "^1.0.1",
- "gopd": "^1.2.0",
- "has-symbols": "^1.1.0",
- "hasown": "^2.0.2",
- "math-intrinsics": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/get-proto": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
- "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "dunder-proto": "^1.0.1",
- "es-object-atoms": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/get-stream": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
- "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/get-symbol-description": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz",
- "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.3",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.6"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/get-tsconfig": {
- "version": "4.14.0",
- "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz",
- "integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "resolve-pkg-maps": "^1.0.0"
- },
- "funding": {
- "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
- }
- },
- "node_modules/glob": {
- "version": "13.0.6",
- "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
- "integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
- "license": "BlueOak-1.0.0",
- "dependencies": {
- "minimatch": "^10.2.2",
- "minipass": "^7.1.3",
- "path-scurry": "^2.0.2"
- },
- "engines": {
- "node": "18 || 20 || >=22"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/glob-parent": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
- "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "is-glob": "^4.0.3"
- },
- "engines": {
- "node": ">=10.13.0"
- }
- },
- "node_modules/glob/node_modules/minimatch": {
- "version": "10.2.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
- "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
- "license": "BlueOak-1.0.0",
- "dependencies": {
- "brace-expansion": "^5.0.5"
- },
- "engines": {
- "node": "18 || 20 || >=22"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/globals": {
- "version": "16.4.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz",
- "integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/globalthis": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz",
- "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "define-properties": "^1.2.1",
- "gopd": "^1.0.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/google-auth-library": {
- "version": "10.7.0",
- "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.7.0.tgz",
- "integrity": "sha512-QpTAbNJ36TliZLx3TTtahR8HG0hN9RllL1e3FymOvQSIKK8JmgV58H924ub2wa2DsS3ANjjP1Aw1N+Ramc8hqQ==",
- "license": "Apache-2.0",
- "dependencies": {
- "base64-js": "^1.3.0",
- "ecdsa-sig-formatter": "^1.0.11",
- "gaxios": "^7.1.4",
- "gcp-metadata": "8.1.2",
- "google-logging-utils": "1.1.3",
- "jws": "^4.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/google-gax": {
- "version": "5.0.7",
- "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-5.0.7.tgz",
- "integrity": "sha512-EhiqaWWJ+9h7sCcKJTsoo6tMcjokVHhWsbSuWCnZJT4vIBP3y4mAoFLnt9SzgkVZeq24ZsFaArr06nnYYku2yA==",
- "license": "Apache-2.0",
- "dependencies": {
- "@grpc/grpc-js": "^1.12.6",
- "@grpc/proto-loader": "^0.8.0",
- "duplexify": "^4.1.3",
- "google-auth-library": "10.5.0",
- "google-logging-utils": "1.1.3",
- "node-fetch": "^3.3.2",
- "object-hash": "^3.0.0",
- "proto3-json-serializer": "3.0.4",
- "protobufjs": "^7.5.4",
- "retry-request": "^8.0.2",
- "rimraf": "^5.0.1"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/google-gax/node_modules/google-auth-library": {
- "version": "10.5.0",
- "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.5.0.tgz",
- "integrity": "sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==",
- "license": "Apache-2.0",
- "dependencies": {
- "base64-js": "^1.3.0",
- "ecdsa-sig-formatter": "^1.0.11",
- "gaxios": "^7.0.0",
- "gcp-metadata": "^8.0.0",
- "google-logging-utils": "^1.0.0",
- "gtoken": "^8.0.0",
- "jws": "^4.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/google-gax/node_modules/node-fetch": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
- "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
- "license": "MIT",
- "dependencies": {
- "data-uri-to-buffer": "^4.0.0",
- "fetch-blob": "^3.1.4",
- "formdata-polyfill": "^4.0.10"
- },
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/node-fetch"
- }
- },
- "node_modules/google-gax/node_modules/proto3-json-serializer": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-3.0.4.tgz",
- "integrity": "sha512-E1sbAYg3aEbXrq0n1ojJkRHQJGE1kaE/O6GLA94y8rnJBfgvOPTOd1b9hOceQK1FFZI9qMh1vBERCyO2ifubcw==",
- "license": "Apache-2.0",
- "dependencies": {
- "protobufjs": "^7.4.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/google-logging-utils": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz",
- "integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=14"
- }
- },
- "node_modules/gopd": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
- "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/graceful-fs": {
- "version": "4.2.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
- "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/gtoken": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-8.0.0.tgz",
- "integrity": "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==",
- "license": "MIT",
- "dependencies": {
- "gaxios": "^7.0.0",
- "jws": "^4.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/has-bigints": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
- "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/has-property-descriptors": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
- "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "es-define-property": "^1.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-proto": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz",
- "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "dunder-proto": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-symbols": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
- "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/has-tostringtag": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
- "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "has-symbols": "^1.0.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/hasown": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
- "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/hermes-estree": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz",
- "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/hermes-parser": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz",
- "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "hermes-estree": "0.25.1"
- }
- },
- "node_modules/hono": {
- "version": "4.12.32",
- "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.32.tgz",
- "integrity": "sha512-XcuyW9qE2kJn07PkecMOBd5Vq/hMy7mmGw+idz1yblbg9N17ijJODrvPkn7/dwL3Kulj8LcRJ69DLOWf91dRUg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=16.9.0"
- }
- },
- "node_modules/http-errors": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
- "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "depd": "~2.0.0",
- "inherits": "~2.0.4",
- "setprototypeof": "~1.2.0",
- "statuses": "~2.0.2",
- "toidentifier": "~1.0.1"
- },
- "engines": {
- "node": ">= 0.8"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "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==",
- "license": "MIT",
- "dependencies": {
- "agent-base": "^7.1.0",
- "debug": "^4.3.4"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/http-proxy-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==",
- "license": "MIT",
- "engines": {
- "node": ">= 14"
- }
- },
- "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==",
- "license": "MIT",
- "dependencies": {
- "agent-base": "6",
- "debug": "4"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/human-signals": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
- "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
- "license": "Apache-2.0",
- "engines": {
- "node": ">=10.17.0"
- }
- },
- "node_modules/iceberg-js": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/iceberg-js/-/iceberg-js-0.8.1.tgz",
- "integrity": "sha512-1dhVQZXhcHje7798IVM+xoo/1ZdVfzOMIc8/rgVSijRK38EDqOJoGula9N/8ZI5RD8QTxNQtK/Gozpr+qUqRRA==",
- "license": "MIT",
- "engines": {
- "node": ">=20.0.0"
- }
- },
- "node_modules/iconv-lite": {
- "version": "0.7.3",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz",
- "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "safer-buffer": ">= 2.1.2 < 3.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "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/import-fresh": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
- "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "parent-module": "^1.0.0",
- "resolve-from": "^4.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/import-in-the-middle": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-3.1.0.tgz",
- "integrity": "sha512-c0AeAV8VcwZzfYE7euTZY3H+VXUPMVugiovdosq80lqEXJmOekg3zGUAYg6KImHMaMuBoTUfTv7xNpUFdy0hJA==",
- "license": "Apache-2.0",
- "dependencies": {
- "acorn": "^8.15.0",
- "acorn-import-attributes": "^1.9.5",
- "cjs-module-lexer": "^2.2.0",
- "module-details-from-path": "^1.0.4"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "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"
- }
- },
- "node_modules/inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "license": "ISC"
- },
- "node_modules/internal-slot": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
- "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "hasown": "^2.0.2",
- "side-channel": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/ip-address": {
- "version": "10.2.0",
- "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz",
- "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 12"
- }
- },
- "node_modules/ipaddr.js": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
- "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/is-array-buffer": {
- "version": "3.0.5",
- "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
- "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.8",
- "call-bound": "^1.0.3",
- "get-intrinsic": "^1.2.6"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-async-function": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz",
- "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "async-function": "^1.0.0",
- "call-bound": "^1.0.3",
- "get-proto": "^1.0.1",
- "has-tostringtag": "^1.0.2",
- "safe-regex-test": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-bigint": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
- "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "has-bigints": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-boolean-object": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz",
- "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.3",
- "has-tostringtag": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-bun-module": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz",
- "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "semver": "^7.7.1"
- }
- },
- "node_modules/is-callable": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
- "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-core-module": {
- "version": "2.16.2",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz",
- "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "hasown": "^2.0.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-data-view": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz",
- "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "get-intrinsic": "^1.2.6",
- "is-typed-array": "^1.1.13"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-date-object": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
- "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "has-tostringtag": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-document.all": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-document.all/-/is-document.all-1.0.0.tgz",
- "integrity": "sha512-+XSoyS05OdBbhFuELhgTCpFNHkpBOJqtsZfUFFpe5QTw+9Sjbh8zitxhQkYAo6wV7e1Vb8cAPvpCk9jGam/82g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.4"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-finalizationregistry": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz",
- "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-generator-function": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz",
- "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.4",
- "generator-function": "^2.0.0",
- "get-proto": "^1.0.1",
- "has-tostringtag": "^1.0.2",
- "safe-regex-test": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-map": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz",
- "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-negative-zero": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
- "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/is-number-object": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz",
- "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.3",
- "has-tostringtag": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-promise": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
- "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/is-reference": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz",
- "integrity": "sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==",
- "license": "MIT",
- "dependencies": {
- "@types/estree": "*"
- }
- },
- "node_modules/is-regex": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
- "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "gopd": "^1.2.0",
- "has-tostringtag": "^1.0.2",
- "hasown": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-set": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz",
- "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-shared-array-buffer": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz",
- "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-stream": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
- "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/is-string": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz",
- "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.3",
- "has-tostringtag": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-symbol": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz",
- "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "has-symbols": "^1.1.0",
- "safe-regex-test": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-typed-array": {
- "version": "1.1.15",
- "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
- "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "which-typed-array": "^1.1.16"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-weakmap": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz",
- "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-weakref": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz",
- "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-weakset": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
- "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.3",
- "get-intrinsic": "^1.2.6"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/isarray": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
- "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "license": "ISC"
- },
- "node_modules/iterator.prototype": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz",
- "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "define-data-property": "^1.1.4",
- "es-object-atoms": "^1.0.0",
- "get-intrinsic": "^1.2.6",
- "get-proto": "^1.0.0",
- "has-symbols": "^1.1.0",
- "set-function-name": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "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/jiti": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz",
- "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "jiti": "lib/jiti-cli.mjs"
- }
- },
- "node_modules/jose": {
- "version": "6.2.3",
- "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.3.tgz",
- "integrity": "sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/panva"
- }
- },
- "node_modules/js-tokens": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "license": "MIT"
- },
- "node_modules/js-yaml": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz",
- "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/puzrin"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/nodeca"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "argparse": "^2.0.1"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
- "node_modules/jsesc": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
- "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
- "license": "MIT",
- "bin": {
- "jsesc": "bin/jsesc"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/json-bigint": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
- "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
- "license": "MIT",
- "dependencies": {
- "bignumber.js": "^9.0.0"
- }
- },
- "node_modules/json-buffer": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
- "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/json-schema": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
- "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==",
- "license": "(AFL-2.1 OR BSD-3-Clause)"
- },
- "node_modules/json-schema-traverse": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/json-schema-typed": {
- "version": "8.0.2",
- "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz",
- "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==",
- "dev": true,
- "license": "BSD-2-Clause"
- },
- "node_modules/json-stable-stringify-without-jsonify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
- "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/json5": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
- "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
- "license": "MIT",
- "bin": {
- "json5": "lib/cli.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/jsx-ast-utils": {
- "version": "3.3.5",
- "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz",
- "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "array-includes": "^3.1.6",
- "array.prototype.flat": "^1.3.1",
- "object.assign": "^4.1.4",
- "object.values": "^1.1.6"
- },
- "engines": {
- "node": ">=4.0"
- }
- },
- "node_modules/jwa": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz",
- "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==",
- "license": "MIT",
- "dependencies": {
- "buffer-equal-constant-time": "^1.0.1",
- "ecdsa-sig-formatter": "1.0.11",
- "safe-buffer": "^5.0.1"
- }
- },
- "node_modules/jws": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz",
- "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==",
- "license": "MIT",
- "dependencies": {
- "jwa": "^2.0.1",
- "safe-buffer": "^5.0.1"
- }
- },
- "node_modules/keyv": {
- "version": "4.5.4",
- "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
- "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "json-buffer": "3.0.1"
- }
- },
- "node_modules/language-subtag-registry": {
- "version": "0.3.23",
- "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz",
- "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==",
- "dev": true,
- "license": "CC0-1.0"
- },
- "node_modules/language-tags": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz",
- "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "language-subtag-registry": "^0.3.20"
- },
- "engines": {
- "node": ">=0.10"
- }
- },
- "node_modules/levn": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
- "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "prelude-ls": "^1.2.1",
- "type-check": "~0.4.0"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/lightningcss": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
- "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==",
- "dev": true,
- "license": "MPL-2.0",
- "dependencies": {
- "detect-libc": "^2.0.3"
- },
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- },
- "optionalDependencies": {
- "lightningcss-android-arm64": "1.32.0",
- "lightningcss-darwin-arm64": "1.32.0",
- "lightningcss-darwin-x64": "1.32.0",
- "lightningcss-freebsd-x64": "1.32.0",
- "lightningcss-linux-arm-gnueabihf": "1.32.0",
- "lightningcss-linux-arm64-gnu": "1.32.0",
- "lightningcss-linux-arm64-musl": "1.32.0",
- "lightningcss-linux-x64-gnu": "1.32.0",
- "lightningcss-linux-x64-musl": "1.32.0",
- "lightningcss-win32-arm64-msvc": "1.32.0",
- "lightningcss-win32-x64-msvc": "1.32.0"
- }
- },
- "node_modules/lightningcss-android-arm64": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz",
- "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-darwin-arm64": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz",
- "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-darwin-x64": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz",
- "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-freebsd-x64": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz",
- "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-arm-gnueabihf": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz",
- "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-arm64-gnu": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz",
- "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-arm64-musl": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz",
- "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-x64-gnu": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz",
- "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-linux-x64-musl": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz",
- "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-win32-arm64-msvc": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz",
- "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/lightningcss-win32-x64-msvc": {
- "version": "1.32.0",
- "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz",
- "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MPL-2.0",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">= 12.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/parcel"
- }
- },
- "node_modules/locate-path": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
- "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
- "license": "MIT",
- "dependencies": {
- "p-locate": "^5.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/lodash.camelcase": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
- "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
- "license": "MIT"
- },
- "node_modules/lodash.merge": {
- "version": "4.6.2",
- "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
- "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/long": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
- "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==",
- "license": "Apache-2.0"
- },
- "node_modules/loose-envify": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
- "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "js-tokens": "^3.0.0 || ^4.0.0"
- },
- "bin": {
- "loose-envify": "cli.js"
- }
- },
- "node_modules/lru-cache": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
- "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
- "license": "ISC",
- "dependencies": {
- "yallist": "^3.0.2"
- }
- },
- "node_modules/magic-string": {
- "version": "0.30.21",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
- "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.5"
- }
- },
- "node_modules/math-intrinsics": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
- "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/media-typer": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
- "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/merge-descriptors": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
- "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/merge-stream": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
- "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
- "license": "MIT"
- },
- "node_modules/merge2": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/meriyah": {
- "version": "6.1.4",
- "resolved": "https://registry.npmjs.org/meriyah/-/meriyah-6.1.4.tgz",
- "integrity": "sha512-Sz8FzjzI0kN13GK/6MVEsVzMZEPvOhnmmI1lU5+/1cGOiK3QUahntrNNtdVeihrO7t9JpoH75iMNXg6R6uWflQ==",
- "license": "ISC",
- "engines": {
- "node": ">=18.0.0"
- }
- },
- "node_modules/micromatch": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
- "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "braces": "^3.0.3",
- "picomatch": "^2.3.1"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
- "node_modules/mime-db": {
- "version": "1.54.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
- "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/mime-types": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
- "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "mime-db": "^1.54.0"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "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==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/minimatch": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
- "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/minimatch/node_modules/brace-expansion": {
- "version": "1.1.15",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz",
- "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/minimist": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
- "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/minipass": {
- "version": "7.1.3",
- "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz",
- "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==",
- "license": "BlueOak-1.0.0",
- "engines": {
- "node": ">=16 || 14 >=14.17"
- }
- },
- "node_modules/module-details-from-path": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz",
- "integrity": "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==",
- "license": "MIT"
- },
- "node_modules/nanoid": {
- "version": "3.3.13",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.13.tgz",
- "integrity": "sha512-sPdqC6ByMVVGvF1ynvvMo0/o+oD1VX7DaHhijt1bFgjvBkHBib4t49GoNDhf2NDta4oeUNlaGbSt5K7qjZ955Q==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "bin": {
- "nanoid": "bin/nanoid.cjs"
- },
- "engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
- }
- },
- "node_modules/napi-postinstall": {
- "version": "0.3.4",
- "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz",
- "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "napi-postinstall": "lib/cli.js"
- },
- "engines": {
- "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/napi-postinstall"
- }
- },
- "node_modules/natural-compare": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
- "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
- "dev": true,
- "license": "MIT"
- },
- "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/next": {
- "version": "16.2.10",
- "resolved": "https://registry.npmjs.org/next/-/next-16.2.10.tgz",
- "integrity": "sha512-2som5AVXb3kE6Yjine3/mNbBayYF58eguBWIVVUdr1y/L426xyVEgYxgBG+1QC34P2x5E+tcDup6XkuOAX3dCA==",
- "license": "MIT",
- "dependencies": {
- "@next/env": "16.2.10",
- "@swc/helpers": "0.5.15",
- "baseline-browser-mapping": "^2.9.19",
- "caniuse-lite": "^1.0.30001579",
- "postcss": "8.4.31",
- "styled-jsx": "5.1.6"
- },
- "bin": {
- "next": "dist/bin/next"
- },
- "engines": {
- "node": ">=20.9.0"
- },
- "optionalDependencies": {
- "@next/swc-darwin-arm64": "16.2.10",
- "@next/swc-darwin-x64": "16.2.10",
- "@next/swc-linux-arm64-gnu": "16.2.10",
- "@next/swc-linux-arm64-musl": "16.2.10",
- "@next/swc-linux-x64-gnu": "16.2.10",
- "@next/swc-linux-x64-musl": "16.2.10",
- "@next/swc-win32-arm64-msvc": "16.2.10",
- "@next/swc-win32-x64-msvc": "16.2.10",
- "sharp": "^0.34.5"
- },
- "peerDependencies": {
- "@opentelemetry/api": "^1.1.0",
- "@playwright/test": "^1.51.1",
- "babel-plugin-react-compiler": "*",
- "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0",
- "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0",
- "sass": "^1.3.0"
- },
- "peerDependenciesMeta": {
- "@opentelemetry/api": {
- "optional": true
- },
- "@playwright/test": {
- "optional": true
- },
- "babel-plugin-react-compiler": {
- "optional": true
- },
- "sass": {
- "optional": true
- }
- }
- },
- "node_modules/node-domexception": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
- "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
- "deprecated": "Use your platform's native DOMException instead",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/jimmywarting"
- },
- {
- "type": "github",
- "url": "https://paypal.me/jimmywarting"
- }
- ],
- "license": "MIT",
- "engines": {
- "node": ">=10.5.0"
- }
- },
- "node_modules/node-exports-info": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.0.tgz",
- "integrity": "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "array.prototype.flatmap": "^1.3.3",
- "es-errors": "^1.3.0",
- "object.entries": "^1.1.9",
- "semver": "^6.3.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/node-exports-info/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/node-fetch": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
- "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
- "license": "MIT",
- "dependencies": {
- "whatwg-url": "^5.0.0"
- },
- "engines": {
- "node": "4.x || >=6.0.0"
- },
- "peerDependencies": {
- "encoding": "^0.1.0"
- },
- "peerDependenciesMeta": {
- "encoding": {
- "optional": true
- }
- }
- },
- "node_modules/node-releases": {
- "version": "2.0.51",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz",
- "integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==",
- "license": "MIT",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/npm-run-path": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
- "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
- "license": "MIT",
- "dependencies": {
- "path-key": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/oauth": {
- "version": "0.9.15",
- "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz",
- "integrity": "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==",
- "license": "MIT"
- },
- "node_modules/object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/object-hash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
- "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
- "license": "MIT",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/object-inspect": {
- "version": "1.13.4",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
- "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/object-keys": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
- "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/object.assign": {
- "version": "4.1.7",
- "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
- "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.8",
- "call-bound": "^1.0.3",
- "define-properties": "^1.2.1",
- "es-object-atoms": "^1.0.0",
- "has-symbols": "^1.1.0",
- "object-keys": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/object.entries": {
- "version": "1.1.9",
- "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz",
- "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.8",
- "call-bound": "^1.0.4",
- "define-properties": "^1.2.1",
- "es-object-atoms": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/object.fromentries": {
- "version": "2.0.8",
- "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz",
- "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.7",
- "define-properties": "^1.2.1",
- "es-abstract": "^1.23.2",
- "es-object-atoms": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/object.groupby": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz",
- "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.7",
- "define-properties": "^1.2.1",
- "es-abstract": "^1.23.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/object.values": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz",
- "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.8",
- "call-bound": "^1.0.3",
- "define-properties": "^1.2.1",
- "es-object-atoms": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/obug": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.3.tgz",
- "integrity": "sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==",
- "dev": true,
- "funding": [
- "https://github.com/sponsors/sxzz",
- "https://opencollective.com/debug"
- ],
- "license": "MIT",
- "engines": {
- "node": ">=12.20.0"
- }
- },
- "node_modules/oidc-token-hash": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.2.0.tgz",
- "integrity": "sha512-6gj2m8cJZ+iSW8bm0FXdGF0YhIQbKrfP4yWTNzxc31U6MOjfEmB1rHvlYvxI1B7t7BCi1F2vYTT6YhtQRG4hxw==",
- "license": "MIT",
- "engines": {
- "node": "^10.13.0 || >=12.0.0"
- }
- },
- "node_modules/on-finished": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
- "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ee-first": "1.1.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "license": "ISC",
- "dependencies": {
- "wrappy": "1"
- }
- },
- "node_modules/onetime": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
- "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
- "license": "MIT",
- "dependencies": {
- "mimic-fn": "^2.1.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/openai": {
- "version": "6.48.0",
- "resolved": "https://registry.npmjs.org/openai/-/openai-6.48.0.tgz",
- "integrity": "sha512-KhVp+FyV50QrXNextvL9hIU5l6ox5HYuKQjGVk7lIqprgJol90+dQXWONV6S1lRWsKA1bXjrow8RsUT14M1hNA==",
- "license": "Apache-2.0",
- "peerDependencies": {
- "@aws-sdk/credential-provider-node": ">=3.972.0 <4",
- "@smithy/hash-node": ">=4.3.0 <5",
- "@smithy/signature-v4": ">=5.4.0 <6",
- "ws": "^8.18.0",
- "zod": "^3.25 || ^4.0"
- },
- "peerDependenciesMeta": {
- "@aws-sdk/credential-provider-node": {
- "optional": true
- },
- "@smithy/hash-node": {
- "optional": true
- },
- "@smithy/signature-v4": {
- "optional": true
- },
- "ws": {
- "optional": true
- },
- "zod": {
- "optional": true
- }
- }
- },
- "node_modules/openid-client": {
- "version": "5.7.1",
- "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.7.1.tgz",
- "integrity": "sha512-jDBPgSVfTnkIh71Hg9pRvtJc6wTwqjRkN88+gCFtYWrlP4Yx2Dsrow8uPi3qLr/aeymPF3o2+dS+wOpglK04ew==",
- "license": "MIT",
- "dependencies": {
- "jose": "^4.15.9",
- "lru-cache": "^6.0.0",
- "object-hash": "^2.2.0",
- "oidc-token-hash": "^5.0.3"
- },
- "funding": {
- "url": "https://github.com/sponsors/panva"
- }
- },
- "node_modules/openid-client/node_modules/jose": {
- "version": "4.15.9",
- "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz",
- "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==",
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/panva"
- }
- },
- "node_modules/openid-client/node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "license": "ISC",
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/openid-client/node_modules/object-hash": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz",
- "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==",
- "license": "MIT",
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/openid-client/node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "license": "ISC"
- },
- "node_modules/optionator": {
- "version": "0.9.4",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
- "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "deep-is": "^0.1.3",
- "fast-levenshtein": "^2.0.6",
- "levn": "^0.4.1",
- "prelude-ls": "^1.2.1",
- "type-check": "^0.4.0",
- "word-wrap": "^1.2.5"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/os-paths": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/os-paths/-/os-paths-4.4.0.tgz",
- "integrity": "sha512-wrAwOeXp1RRMFfQY8Sy7VaGVmPocaLwSFOYCGKSyo8qmJ+/yaafCl5BCA1IQZWqFSRBrKDYFeR9d/VyQzfH/jg==",
- "license": "MIT",
- "engines": {
- "node": ">= 6.0"
- }
- },
- "node_modules/own-keys": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz",
- "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "get-intrinsic": "^1.2.6",
- "object-keys": "^1.1.1",
- "safe-push-apply": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "license": "MIT",
- "dependencies": {
- "yocto-queue": "^0.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/p-locate": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
- "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
- "license": "MIT",
- "dependencies": {
- "p-limit": "^3.0.2"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/p-retry": {
- "version": "4.6.2",
- "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz",
- "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==",
- "license": "MIT",
- "dependencies": {
- "@types/retry": "0.12.0",
- "retry": "^0.13.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "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/parent-module": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
- "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "callsites": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/parseurl": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
- "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/path-key": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
- "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/path-parse": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
- "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/path-scurry": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
- "integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
- "license": "BlueOak-1.0.0",
- "dependencies": {
- "lru-cache": "^11.0.0",
- "minipass": "^7.1.2"
- },
- "engines": {
- "node": "18 || 20 || >=22"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/path-scurry/node_modules/lru-cache": {
- "version": "11.5.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.1.tgz",
- "integrity": "sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==",
- "license": "BlueOak-1.0.0",
- "engines": {
- "node": "20 || >=22"
- }
- },
- "node_modules/path-to-regexp": {
- "version": "8.4.2",
- "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz",
- "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "node_modules/pathe": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
- "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/picocolors": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
- "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
- "license": "ISC"
- },
- "node_modules/picomatch": {
- "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": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/pkce-challenge": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz",
- "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=16.20.0"
- }
- },
- "node_modules/playwright": {
- "version": "1.61.1",
- "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.61.1.tgz",
- "integrity": "sha512-DWnY5o3YbLWK4GovuAVwpqL+1VwGNdUGrRr++8j8PtQQzvAVZUIMjKQ90fY689sEJZJBbZVw1rXaOKSTitkzPQ==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "playwright-core": "1.61.1"
- },
- "bin": {
- "playwright": "cli.js"
- },
- "engines": {
- "node": ">=18"
- },
- "optionalDependencies": {
- "fsevents": "2.3.2"
- }
- },
- "node_modules/playwright-core": {
- "version": "1.61.1",
- "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.61.1.tgz",
- "integrity": "sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg==",
- "dev": true,
- "license": "Apache-2.0",
- "bin": {
- "playwright-core": "cli.js"
- },
- "engines": {
- "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,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/possible-typed-array-names": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
- "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/postcss": {
- "version": "8.5.16",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.16.tgz",
- "integrity": "sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "nanoid": "^3.3.12",
- "picocolors": "^1.1.1",
- "source-map-js": "^1.2.1"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- }
- },
- "node_modules/postcss-value-parser": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
- "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/preact": {
- "version": "10.29.2",
- "resolved": "https://registry.npmjs.org/preact/-/preact-10.29.2.tgz",
- "integrity": "sha512-7tNmwg/7mzzAoB/8kSg6Hl37JraAZw3Z3A0JSY7VXlZwo82Xn0G7wKbNNs2qoF4ZEEsQGTwDAroNdqKs1ofJxQ==",
- "license": "MIT",
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/preact"
- }
- },
- "node_modules/preact-render-to-string": {
- "version": "5.2.6",
- "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.6.tgz",
- "integrity": "sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==",
- "license": "MIT",
- "dependencies": {
- "pretty-format": "^3.8.0"
- },
- "peerDependencies": {
- "preact": ">=10"
- }
- },
- "node_modules/preact-render-to-string/node_modules/pretty-format": {
- "version": "3.8.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz",
- "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==",
- "license": "MIT"
- },
- "node_modules/prelude-ls": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
- "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/progress": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
- "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
- "license": "MIT",
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/prop-types": {
- "version": "15.8.1",
- "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
- "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "loose-envify": "^1.4.0",
- "object-assign": "^4.1.1",
- "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==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/protobufjs": {
- "version": "7.6.4",
- "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.4.tgz",
- "integrity": "sha512-RJJPTTpvFfHcWLkIa2JFWK4XvtSzS0yEWDmunqHXli1h3JlkbcQZXDZdcWxv+JK3Xsl5/UFDPZ0iGm7DAengYw==",
- "hasInstallScript": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "@protobufjs/aspromise": "^1.1.2",
- "@protobufjs/base64": "^1.1.2",
- "@protobufjs/codegen": "^2.0.5",
- "@protobufjs/eventemitter": "^1.1.1",
- "@protobufjs/fetch": "^1.1.1",
- "@protobufjs/float": "^1.0.2",
- "@protobufjs/path": "^1.1.2",
- "@protobufjs/pool": "^1.1.0",
- "@protobufjs/utf8": "^1.1.1",
- "@types/node": ">=13.7.0",
- "long": "^5.3.2"
- },
- "engines": {
- "node": ">=12.0.0"
- }
- },
- "node_modules/proxy-addr": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
- "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "forwarded": "0.2.0",
- "ipaddr.js": "1.9.1"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/proxy-from-env": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
- "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
- "license": "MIT"
- },
- "node_modules/punycode": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
- "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/qs": {
- "version": "6.15.2",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz",
- "integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==",
- "dev": true,
- "license": "BSD-3-Clause",
- "dependencies": {
- "side-channel": "^1.1.0"
- },
- "engines": {
- "node": ">=0.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/queue-microtask": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
- "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
- "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/range-parser": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
- "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/raw-body": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz",
- "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "bytes": "~3.1.2",
- "http-errors": "~2.0.1",
- "iconv-lite": "~0.7.0",
- "unpipe": "~1.0.0"
- },
- "engines": {
- "node": ">= 0.10"
- }
- },
- "node_modules/react": {
- "version": "19.2.7",
- "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz",
- "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/react-dom": {
- "version": "19.2.7",
- "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz",
- "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==",
- "license": "MIT",
- "dependencies": {
- "scheduler": "^0.27.0"
- },
- "peerDependencies": {
- "react": "^19.2.7"
- }
- },
- "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==",
- "license": "MIT",
- "dependencies": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/reflect.getprototypeof": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
- "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.8",
- "define-properties": "^1.2.1",
- "es-abstract": "^1.23.9",
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.0.0",
- "get-intrinsic": "^1.2.7",
- "get-proto": "^1.0.1",
- "which-builtin-type": "^1.2.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/regexp.prototype.flags": {
- "version": "1.5.4",
- "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
- "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.8",
- "define-properties": "^1.2.1",
- "es-errors": "^1.3.0",
- "get-proto": "^1.0.1",
- "gopd": "^1.2.0",
- "set-function-name": "^2.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/require-directory": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
- "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/require-from-string": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
- "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/require-in-the-middle": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-8.0.1.tgz",
- "integrity": "sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ==",
- "license": "MIT",
- "dependencies": {
- "debug": "^4.3.5",
- "module-details-from-path": "^1.0.3"
- },
- "engines": {
- "node": ">=9.3.0 || >=8.10.0 <9.0.0"
- }
- },
- "node_modules/resolve": {
- "version": "2.0.0-next.7",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.7.tgz",
- "integrity": "sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "is-core-module": "^2.16.2",
- "node-exports-info": "^1.6.0",
- "object-keys": "^1.1.1",
- "path-parse": "^1.0.7",
- "supports-preserve-symlinks-flag": "^1.0.0"
- },
- "bin": {
- "resolve": "bin/resolve"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/resolve-from": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
- "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/resolve-pkg-maps": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
- "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
- }
- },
- "node_modules/retry": {
- "version": "0.13.1",
- "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz",
- "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==",
- "license": "MIT",
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/retry-request": {
- "version": "8.0.3",
- "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-8.0.3.tgz",
- "integrity": "sha512-qqoc4kkGgP9cmQDWELlOpAmfgJOg0Yi7MT82ZjiPWu451ayju4itwomjM4/dBEliify8C1b3tSaeCOldugtwPQ==",
- "license": "MIT",
- "dependencies": {
- "extend": "^3.0.2",
- "teeny-request": "^10.0.0"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/reusify": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
- "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "iojs": ">=1.0.0",
- "node": ">=0.10.0"
- }
- },
- "node_modules/rimraf": {
- "version": "5.0.10",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz",
- "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==",
- "license": "ISC",
- "dependencies": {
- "glob": "^10.3.7"
- },
- "bin": {
- "rimraf": "dist/esm/bin.mjs"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/rimraf/node_modules/brace-expansion": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz",
- "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==",
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0"
- }
- },
- "node_modules/rimraf/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",
- "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/rimraf/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/rimraf/node_modules/minimatch": {
- "version": "9.0.9",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
- "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^2.0.2"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/rimraf/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/rolldown": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.5.tgz",
- "integrity": "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@oxc-project/types": "=0.139.0",
- "@rolldown/pluginutils": "^1.0.0"
- },
- "bin": {
- "rolldown": "bin/cli.mjs"
- },
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- },
- "optionalDependencies": {
- "@rolldown/binding-android-arm64": "1.1.5",
- "@rolldown/binding-darwin-arm64": "1.1.5",
- "@rolldown/binding-darwin-x64": "1.1.5",
- "@rolldown/binding-freebsd-x64": "1.1.5",
- "@rolldown/binding-linux-arm-gnueabihf": "1.1.5",
- "@rolldown/binding-linux-arm64-gnu": "1.1.5",
- "@rolldown/binding-linux-arm64-musl": "1.1.5",
- "@rolldown/binding-linux-ppc64-gnu": "1.1.5",
- "@rolldown/binding-linux-s390x-gnu": "1.1.5",
- "@rolldown/binding-linux-x64-gnu": "1.1.5",
- "@rolldown/binding-linux-x64-musl": "1.1.5",
- "@rolldown/binding-openharmony-arm64": "1.1.5",
- "@rolldown/binding-wasm32-wasi": "1.1.5",
- "@rolldown/binding-win32-arm64-msvc": "1.1.5",
- "@rolldown/binding-win32-x64-msvc": "1.1.5"
- }
- },
- "node_modules/rollup": {
- "version": "4.62.2",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.2.tgz",
- "integrity": "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==",
- "license": "MIT",
- "dependencies": {
- "@types/estree": "1.0.9"
- },
- "bin": {
- "rollup": "dist/bin/rollup"
- },
- "engines": {
- "node": ">=18.0.0",
- "npm": ">=8.0.0"
- },
- "optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.62.2",
- "@rollup/rollup-android-arm64": "4.62.2",
- "@rollup/rollup-darwin-arm64": "4.62.2",
- "@rollup/rollup-darwin-x64": "4.62.2",
- "@rollup/rollup-freebsd-arm64": "4.62.2",
- "@rollup/rollup-freebsd-x64": "4.62.2",
- "@rollup/rollup-linux-arm-gnueabihf": "4.62.2",
- "@rollup/rollup-linux-arm-musleabihf": "4.62.2",
- "@rollup/rollup-linux-arm64-gnu": "4.62.2",
- "@rollup/rollup-linux-arm64-musl": "4.62.2",
- "@rollup/rollup-linux-loong64-gnu": "4.62.2",
- "@rollup/rollup-linux-loong64-musl": "4.62.2",
- "@rollup/rollup-linux-ppc64-gnu": "4.62.2",
- "@rollup/rollup-linux-ppc64-musl": "4.62.2",
- "@rollup/rollup-linux-riscv64-gnu": "4.62.2",
- "@rollup/rollup-linux-riscv64-musl": "4.62.2",
- "@rollup/rollup-linux-s390x-gnu": "4.62.2",
- "@rollup/rollup-linux-x64-gnu": "4.62.2",
- "@rollup/rollup-linux-x64-musl": "4.62.2",
- "@rollup/rollup-openbsd-x64": "4.62.2",
- "@rollup/rollup-openharmony-arm64": "4.62.2",
- "@rollup/rollup-win32-arm64-msvc": "4.62.2",
- "@rollup/rollup-win32-ia32-msvc": "4.62.2",
- "@rollup/rollup-win32-x64-gnu": "4.62.2",
- "@rollup/rollup-win32-x64-msvc": "4.62.2",
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/router": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
- "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "debug": "^4.4.0",
- "depd": "^2.0.0",
- "is-promise": "^4.0.0",
- "parseurl": "^1.3.3",
- "path-to-regexp": "^8.0.0"
- },
- "engines": {
- "node": ">= 18"
- }
- },
- "node_modules/run-parallel": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
- "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
- "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": {
- "queue-microtask": "^1.2.2"
- }
- },
- "node_modules/safe-array-concat": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz",
- "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.9",
- "call-bound": "^1.0.4",
- "get-intrinsic": "^1.3.0",
- "has-symbols": "^1.1.0",
- "isarray": "^2.0.5"
- },
- "engines": {
- "node": ">=0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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==",
- "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/safe-push-apply": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
- "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "isarray": "^2.0.5"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/safe-regex-test": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
- "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "is-regex": "^1.2.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/scheduler": {
- "version": "0.27.0",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
- "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
- "license": "MIT"
- },
- "node_modules/semifies": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/semifies/-/semifies-1.0.0.tgz",
- "integrity": "sha512-xXR3KGeoxTNWPD4aBvL5NUpMTT7WMANr3EWnaS190QVkY52lqqcVRD7Q05UVbBhiWDGWMlJEUam9m7uFFGVScw==",
- "license": "Apache-2.0"
- },
- "node_modules/semver": {
- "version": "7.8.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz",
- "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==",
- "devOptional": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/send": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz",
- "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "debug": "^4.4.3",
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "etag": "^1.8.1",
- "fresh": "^2.0.0",
- "http-errors": "^2.0.1",
- "mime-types": "^3.0.2",
- "ms": "^2.1.3",
- "on-finished": "^2.4.1",
- "range-parser": "^1.2.1",
- "statuses": "^2.0.2"
- },
- "engines": {
- "node": ">= 18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "node_modules/send/node_modules/ms": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/serve-static": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz",
- "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "encodeurl": "^2.0.0",
- "escape-html": "^1.0.3",
- "parseurl": "^1.3.3",
- "send": "^1.2.0"
- },
- "engines": {
- "node": ">= 18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "node_modules/server-only": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/server-only/-/server-only-0.0.1.tgz",
- "integrity": "sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA==",
- "license": "MIT"
- },
- "node_modules/set-function-length": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
- "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "define-data-property": "^1.1.4",
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2",
- "get-intrinsic": "^1.2.4",
- "gopd": "^1.0.1",
- "has-property-descriptors": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/set-function-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz",
- "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "define-data-property": "^1.1.4",
- "es-errors": "^1.3.0",
- "functions-have-names": "^1.2.3",
- "has-property-descriptors": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/set-proto": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz",
- "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "dunder-proto": "^1.0.1",
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/setprototypeof": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
- "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
- "dev": true,
- "license": "ISC"
- },
- "node_modules/sharp": {
- "version": "0.34.5",
- "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz",
- "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==",
- "hasInstallScript": true,
- "license": "Apache-2.0",
- "optional": true,
- "dependencies": {
- "@img/colour": "^1.0.0",
- "detect-libc": "^2.1.2",
- "semver": "^7.7.3"
- },
- "engines": {
- "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/libvips"
- },
- "optionalDependencies": {
- "@img/sharp-darwin-arm64": "0.34.5",
- "@img/sharp-darwin-x64": "0.34.5",
- "@img/sharp-libvips-darwin-arm64": "1.2.4",
- "@img/sharp-libvips-darwin-x64": "1.2.4",
- "@img/sharp-libvips-linux-arm": "1.2.4",
- "@img/sharp-libvips-linux-arm64": "1.2.4",
- "@img/sharp-libvips-linux-ppc64": "1.2.4",
- "@img/sharp-libvips-linux-riscv64": "1.2.4",
- "@img/sharp-libvips-linux-s390x": "1.2.4",
- "@img/sharp-libvips-linux-x64": "1.2.4",
- "@img/sharp-libvips-linuxmusl-arm64": "1.2.4",
- "@img/sharp-libvips-linuxmusl-x64": "1.2.4",
- "@img/sharp-linux-arm": "0.34.5",
- "@img/sharp-linux-arm64": "0.34.5",
- "@img/sharp-linux-ppc64": "0.34.5",
- "@img/sharp-linux-riscv64": "0.34.5",
- "@img/sharp-linux-s390x": "0.34.5",
- "@img/sharp-linux-x64": "0.34.5",
- "@img/sharp-linuxmusl-arm64": "0.34.5",
- "@img/sharp-linuxmusl-x64": "0.34.5",
- "@img/sharp-wasm32": "0.34.5",
- "@img/sharp-win32-arm64": "0.34.5",
- "@img/sharp-win32-ia32": "0.34.5",
- "@img/sharp-win32-x64": "0.34.5"
- }
- },
- "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==",
- "license": "MIT",
- "dependencies": {
- "shebang-regex": "^3.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/shebang-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
- "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
- "license": "MIT",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/side-channel": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz",
- "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "object-inspect": "^1.13.4",
- "side-channel-list": "^1.0.1",
- "side-channel-map": "^1.0.1",
- "side-channel-weakmap": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-list": {
- "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==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "object-inspect": "^1.13.4"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-map": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
- "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.5",
- "object-inspect": "^1.13.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/side-channel-weakmap": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
- "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.5",
- "object-inspect": "^1.13.3",
- "side-channel-map": "^1.0.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/siginfo": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
- "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
- "dev": true,
- "license": "ISC"
- },
- "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==",
- "license": "ISC"
- },
- "node_modules/source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/source-map-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
- "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/stable-hash": {
- "version": "0.0.5",
- "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz",
- "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/stackback": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
- "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/stacktrace-parser": {
- "version": "0.1.11",
- "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.11.tgz",
- "integrity": "sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==",
- "license": "MIT",
- "dependencies": {
- "type-fest": "^0.7.1"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/stacktrace-parser/node_modules/type-fest": {
- "version": "0.7.1",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz",
- "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==",
- "license": "(MIT OR CC0-1.0)",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/statuses": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
- "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/std-env": {
- "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/stop-iteration-iterator": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz",
- "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "es-errors": "^1.3.0",
- "internal-slot": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/stream-events": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz",
- "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==",
- "license": "MIT",
- "dependencies": {
- "stubs": "^3.0.0"
- }
- },
- "node_modules/stream-shift": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz",
- "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==",
- "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==",
- "license": "MIT",
- "dependencies": {
- "safe-buffer": "~5.2.0"
- }
- },
- "node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "license": "MIT",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/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==",
- "license": "MIT",
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/string-width-cjs/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "license": "MIT"
- },
- "node_modules/string-width/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "license": "MIT"
- },
- "node_modules/string.prototype.includes": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz",
- "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.7",
- "define-properties": "^1.2.1",
- "es-abstract": "^1.23.3"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/string.prototype.matchall": {
- "version": "4.0.12",
- "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz",
- "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.8",
- "call-bound": "^1.0.3",
- "define-properties": "^1.2.1",
- "es-abstract": "^1.23.6",
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.0.0",
- "get-intrinsic": "^1.2.6",
- "gopd": "^1.2.0",
- "has-symbols": "^1.1.0",
- "internal-slot": "^1.1.0",
- "regexp.prototype.flags": "^1.5.3",
- "set-function-name": "^2.0.2",
- "side-channel": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/string.prototype.repeat": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz",
- "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "define-properties": "^1.1.3",
- "es-abstract": "^1.17.5"
- }
- },
- "node_modules/string.prototype.trim": {
- "version": "1.2.11",
- "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.11.tgz",
- "integrity": "sha512-PwvK7BU+CMTJGYQCTZb5RWXIML92lftJLhQz1tBzgKiqGxJaMlBAa48POXaNAC2s4y8jr3EFqrkF9+44neS46w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.9",
- "call-bound": "^1.0.4",
- "define-data-property": "^1.1.4",
- "define-properties": "^1.2.1",
- "es-abstract": "^1.24.2",
- "es-object-atoms": "^1.1.2",
- "has-property-descriptors": "^1.0.2",
- "safe-regex-test": "^1.1.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/string.prototype.trimend": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.10.tgz",
- "integrity": "sha512-2+3aDAOmPTmuFwjDnmJG2ctEkQKVki7vOSqaxkv42Mowj1V6PnvuwFCRrR5lChUux1TBskPjfkeTOhqczDMxTw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.9",
- "call-bound": "^1.0.4",
- "define-properties": "^1.2.1",
- "es-object-atoms": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/string.prototype.trimstart": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz",
- "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.7",
- "define-properties": "^1.2.1",
- "es-object-atoms": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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-final-newline": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
- "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/strip-json-comments": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
- "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/stripe": {
- "version": "22.3.2",
- "resolved": "https://registry.npmjs.org/stripe/-/stripe-22.3.2.tgz",
- "integrity": "sha512-O13QOvgEIQvDlTy6Ubb5kB980wpbhmoZNsgCXKILjCMZS67f+bW+6w99k3gnSi/N1lkryoj1WYdpGT5Wc5edjg==",
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "@types/node": ">=18"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- }
- }
- },
- "node_modules/stubs": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz",
- "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==",
- "license": "MIT"
- },
- "node_modules/styled-jsx": {
- "version": "5.1.6",
- "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz",
- "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==",
- "license": "MIT",
- "dependencies": {
- "client-only": "0.0.1"
- },
- "engines": {
- "node": ">= 12.0.0"
- },
- "peerDependencies": {
- "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0"
- },
- "peerDependenciesMeta": {
- "@babel/core": {
- "optional": true
- },
- "babel-plugin-macros": {
- "optional": true
- }
- }
- },
- "node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/supports-preserve-symlinks-flag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
- "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/tailwind-merge": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.6.0.tgz",
- "integrity": "sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==",
- "license": "MIT",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/dcastil"
- }
- },
- "node_modules/tapable": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz",
- "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/webpack"
- }
- },
- "node_modules/teeny-request": {
- "version": "10.1.3",
- "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-10.1.3.tgz",
- "integrity": "sha512-5yDliI1uWkYPo7W+Zvrxg6YmoWuj5iC5EydewqrRTvc68nyMTZhlPPlLg6cptUGfbQAb+N9XDPDPzF6N081lug==",
- "license": "Apache-2.0",
- "dependencies": {
- "http-proxy-agent": "^7.0.0",
- "https-proxy-agent": "^7.0.1",
- "node-fetch": "^3.3.2",
- "stream-events": "^1.0.5"
- },
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/teeny-request/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==",
- "license": "MIT",
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/teeny-request/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==",
- "license": "MIT",
- "dependencies": {
- "agent-base": "^7.1.2",
- "debug": "4"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/teeny-request/node_modules/node-fetch": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
- "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
- "license": "MIT",
- "dependencies": {
- "data-uri-to-buffer": "^4.0.0",
- "fetch-blob": "^3.1.4",
- "formdata-polyfill": "^4.0.10"
- },
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/node-fetch"
- }
- },
- "node_modules/tinybench": {
- "version": "2.9.0",
- "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
- "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/tinyexec": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz",
- "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- }
- },
- "node_modules/tinyglobby": {
- "version": "0.2.17",
- "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
- "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fdir": "^6.5.0",
- "picomatch": "^4.0.4"
- },
- "engines": {
- "node": ">=12.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/SuperchupuDev"
- }
- },
- "node_modules/tinyglobby/node_modules/picomatch": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz",
- "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/tinyrainbow": {
- "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": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/toidentifier": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
- "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.6"
- }
- },
- "node_modules/tr46": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
- "license": "MIT"
- },
- "node_modules/ts-api-utils": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz",
- "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18.12"
- },
- "peerDependencies": {
- "typescript": ">=4.8.4"
- }
- },
- "node_modules/tsconfig-paths": {
- "version": "3.15.0",
- "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
- "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/json5": "^0.0.29",
- "json5": "^1.0.2",
- "minimist": "^1.2.6",
- "strip-bom": "^3.0.0"
- }
- },
- "node_modules/tsconfig-paths/node_modules/json5": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
- "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "minimist": "^1.2.0"
- },
- "bin": {
- "json5": "lib/cli.js"
- }
- },
- "node_modules/tsconfig-paths/node_modules/strip-bom": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
- "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/tslib": {
- "version": "2.8.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
- "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
- "license": "0BSD"
- },
- "node_modules/tsx": {
- "version": "4.23.1",
- "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.23.1.tgz",
- "integrity": "sha512-GQHnkIfxyx1wYCOS/wonik5MVRZU9hi1TEZmzGZSCJB1y9YgoZ8H6itNE/u4suE+yLmOzuE4E5S4TZ/ZX2wcWQ==",
- "license": "MIT",
- "dependencies": {
- "esbuild": "~0.28.0"
- },
- "bin": {
- "tsx": "dist/cli.mjs"
- },
- "engines": {
- "node": ">=18.0.0"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.3"
- }
- },
- "node_modules/turbo": {
- "version": "2.10.5",
- "resolved": "https://registry.npmjs.org/turbo/-/turbo-2.10.5.tgz",
- "integrity": "sha512-07Y/C7OUp23l4P92PJoYtFNbHjLhftrZH5Ce7dbczS4kX2Re+wtbXvZLoxn/pUtzgsQaRCBaRuZPJp4zmAn0WQ==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "turbo": "bin/turbo"
- },
- "optionalDependencies": {
- "@turbo/darwin-64": "2.10.5",
- "@turbo/darwin-arm64": "2.10.5",
- "@turbo/linux-64": "2.10.5",
- "@turbo/linux-arm64": "2.10.5",
- "@turbo/windows-64": "2.10.5",
- "@turbo/windows-arm64": "2.10.5"
- }
- },
- "node_modules/type-check": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
- "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "prelude-ls": "^1.2.1"
- },
- "engines": {
- "node": ">= 0.8.0"
- }
- },
- "node_modules/type-is": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz",
- "integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "content-type": "^2.0.0",
- "media-typer": "^1.1.0",
- "mime-types": "^3.0.0"
- },
- "engines": {
- "node": ">= 18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "node_modules/type-is/node_modules/content-type": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz",
- "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/express"
- }
- },
- "node_modules/typed-array-buffer": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
- "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.3",
- "es-errors": "^1.3.0",
- "is-typed-array": "^1.1.14"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/typed-array-byte-length": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz",
- "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.8",
- "for-each": "^0.3.3",
- "gopd": "^1.2.0",
- "has-proto": "^1.2.0",
- "is-typed-array": "^1.1.14"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/typed-array-byte-offset": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz",
- "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "available-typed-arrays": "^1.0.7",
- "call-bind": "^1.0.8",
- "for-each": "^0.3.3",
- "gopd": "^1.2.0",
- "has-proto": "^1.2.0",
- "is-typed-array": "^1.1.15",
- "reflect.getprototypeof": "^1.0.9"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/typed-array-length": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.8.tgz",
- "integrity": "sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.9",
- "for-each": "^0.3.5",
- "gopd": "^1.2.0",
- "is-typed-array": "^1.1.15",
- "possible-typed-array-names": "^1.1.0",
- "reflect.getprototypeof": "^1.0.10"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/typescript": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
- "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
- "dev": true,
- "license": "Apache-2.0",
- "bin": {
- "tsc": "bin/tsc",
- "tsserver": "bin/tsserver"
- },
- "engines": {
- "node": ">=14.17"
- }
- },
- "node_modules/typescript-eslint": {
- "version": "8.61.1",
- "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.61.1.tgz",
- "integrity": "sha512-V7PayAfJokV3pEHgN7/v03D1SpujhRfQtYLbLIiBfDDncdg4PAiRBfoS4cnCANK4jmAPncczi59QO3afiXUlNw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@typescript-eslint/eslint-plugin": "8.61.1",
- "@typescript-eslint/parser": "8.61.1",
- "@typescript-eslint/typescript-estree": "8.61.1",
- "@typescript-eslint/utils": "8.61.1"
- },
- "engines": {
- "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
- "typescript": ">=4.8.4 <6.1.0"
- }
- },
- "node_modules/unbox-primitive": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
- "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.3",
- "has-bigints": "^1.0.2",
- "has-symbols": "^1.1.0",
- "which-boxed-primitive": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/uncrypto": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz",
- "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==",
- "license": "MIT"
- },
- "node_modules/undici-types": {
- "version": "8.3.0",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz",
- "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==",
- "license": "MIT"
- },
- "node_modules/unpipe": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
- "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/unrs-resolver": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.12.2.tgz",
- "integrity": "sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "dependencies": {
- "napi-postinstall": "^0.3.4"
- },
- "funding": {
- "url": "https://opencollective.com/unrs-resolver"
- },
- "optionalDependencies": {
- "@unrs/resolver-binding-android-arm-eabi": "1.12.2",
- "@unrs/resolver-binding-android-arm64": "1.12.2",
- "@unrs/resolver-binding-darwin-arm64": "1.12.2",
- "@unrs/resolver-binding-darwin-x64": "1.12.2",
- "@unrs/resolver-binding-freebsd-x64": "1.12.2",
- "@unrs/resolver-binding-linux-arm-gnueabihf": "1.12.2",
- "@unrs/resolver-binding-linux-arm-musleabihf": "1.12.2",
- "@unrs/resolver-binding-linux-arm64-gnu": "1.12.2",
- "@unrs/resolver-binding-linux-arm64-musl": "1.12.2",
- "@unrs/resolver-binding-linux-loong64-gnu": "1.12.2",
- "@unrs/resolver-binding-linux-loong64-musl": "1.12.2",
- "@unrs/resolver-binding-linux-ppc64-gnu": "1.12.2",
- "@unrs/resolver-binding-linux-riscv64-gnu": "1.12.2",
- "@unrs/resolver-binding-linux-riscv64-musl": "1.12.2",
- "@unrs/resolver-binding-linux-s390x-gnu": "1.12.2",
- "@unrs/resolver-binding-linux-x64-gnu": "1.12.2",
- "@unrs/resolver-binding-linux-x64-musl": "1.12.2",
- "@unrs/resolver-binding-openharmony-arm64": "1.12.2",
- "@unrs/resolver-binding-wasm32-wasi": "1.12.2",
- "@unrs/resolver-binding-win32-arm64-msvc": "1.12.2",
- "@unrs/resolver-binding-win32-ia32-msvc": "1.12.2",
- "@unrs/resolver-binding-win32-x64-msvc": "1.12.2"
- }
- },
- "node_modules/update-browserslist-db": {
- "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==",
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "escalade": "^3.2.0",
- "picocolors": "^1.1.1"
- },
- "bin": {
- "update-browserslist-db": "cli.js"
- },
- "peerDependencies": {
- "browserslist": ">= 4.21.0"
- }
- },
- "node_modules/uri-js": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
- "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "punycode": "^2.1.0"
- }
- },
- "node_modules/use-sync-external-store": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz",
- "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==",
- "license": "MIT",
- "peerDependencies": {
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
- }
- },
- "node_modules/util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
- "license": "MIT"
- },
- "node_modules/uuid": {
- "version": "11.1.1",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.1.tgz",
- "integrity": "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==",
- "funding": [
- "https://github.com/sponsors/broofa",
- "https://github.com/sponsors/ctavan"
- ],
- "license": "MIT",
- "bin": {
- "uuid": "dist/esm/bin/uuid"
- }
- },
- "node_modules/vary": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
- "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/vite": {
- "version": "8.1.5",
- "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.5.tgz",
- "integrity": "sha512-7ULLwsCdYx/nRyrpiEwvqb5TFHrMVZyBt+rg/OAXT7rgj/z+DtTDyKFeLAdDkubDVDKD8jOsndmy7m55XcfUsw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "lightningcss": "^1.32.0",
- "picomatch": "^4.0.5",
- "postcss": "^8.5.17",
- "rolldown": "~1.1.5",
- "tinyglobby": "^0.2.17"
- },
- "bin": {
- "vite": "bin/vite.js"
- },
- "engines": {
- "node": "^20.19.0 || >=22.12.0"
- },
- "funding": {
- "url": "https://github.com/vitejs/vite?sponsor=1"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.3"
- },
- "peerDependencies": {
- "@types/node": "^20.19.0 || >=22.12.0",
- "@vitejs/devtools": "^0.3.0",
- "esbuild": "^0.27.0 || ^0.28.0",
- "jiti": ">=1.21.0",
- "less": "^4.0.0",
- "sass": "^1.70.0",
- "sass-embedded": "^1.70.0",
- "stylus": ">=0.54.8",
- "sugarss": "^5.0.0",
- "terser": "^5.16.0",
- "tsx": "^4.8.1",
- "yaml": "^2.4.2"
- },
- "peerDependenciesMeta": {
- "@types/node": {
- "optional": true
- },
- "@vitejs/devtools": {
- "optional": true
- },
- "esbuild": {
- "optional": true
- },
- "jiti": {
- "optional": true
- },
- "less": {
- "optional": true
- },
- "sass": {
- "optional": true
- },
- "sass-embedded": {
- "optional": true
- },
- "stylus": {
- "optional": true
- },
- "sugarss": {
- "optional": true
- },
- "terser": {
- "optional": true
- },
- "tsx": {
- "optional": true
- },
- "yaml": {
- "optional": true
- }
- }
- },
- "node_modules/vite/node_modules/picomatch": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz",
- "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/vitest": {
- "version": "4.1.10",
- "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz",
- "integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@vitest/expect": "4.1.10",
- "@vitest/mocker": "4.1.10",
- "@vitest/pretty-format": "4.1.10",
- "@vitest/runner": "4.1.10",
- "@vitest/snapshot": "4.1.10",
- "@vitest/spy": "4.1.10",
- "@vitest/utils": "4.1.10",
- "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.10",
- "@vitest/browser-preview": "4.1.10",
- "@vitest/browser-webdriverio": "4.1.10",
- "@vitest/coverage-istanbul": "4.1.10",
- "@vitest/coverage-v8": "4.1.10",
- "@vitest/ui": "4.1.10",
- "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/vitest/node_modules/@vitest/expect": {
- "version": "4.1.10",
- "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz",
- "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@standard-schema/spec": "^1.1.0",
- "@types/chai": "^5.2.2",
- "@vitest/spy": "4.1.10",
- "@vitest/utils": "4.1.10",
- "chai": "^6.2.2",
- "tinyrainbow": "^3.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/vitest/node_modules/@vitest/mocker": {
- "version": "4.1.10",
- "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz",
- "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@vitest/spy": "4.1.10",
- "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/node_modules/@vitest/pretty-format": {
- "version": "4.1.10",
- "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz",
- "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "tinyrainbow": "^3.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/vitest/node_modules/@vitest/runner": {
- "version": "4.1.10",
- "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz",
- "integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@vitest/utils": "4.1.10",
- "pathe": "^2.0.3"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/vitest/node_modules/@vitest/snapshot": {
- "version": "4.1.10",
- "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz",
- "integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@vitest/pretty-format": "4.1.10",
- "@vitest/utils": "4.1.10",
- "magic-string": "^0.30.21",
- "pathe": "^2.0.3"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/vitest/node_modules/@vitest/spy": {
- "version": "4.1.10",
- "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz",
- "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/vitest/node_modules/@vitest/utils": {
- "version": "4.1.10",
- "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz",
- "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@vitest/pretty-format": "4.1.10",
- "convert-source-map": "^2.0.0",
- "tinyrainbow": "^3.1.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/vitest/node_modules/estree-walker": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
- "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/estree": "^1.0.0"
- }
- },
- "node_modules/vitest/node_modules/picomatch": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz",
- "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/web-streams-polyfill": {
- "version": "3.3.3",
- "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
- "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
- "license": "MIT",
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
- "license": "BSD-2-Clause"
- },
- "node_modules/whatwg-url": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
- "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
- "license": "MIT",
- "dependencies": {
- "tr46": "~0.0.3",
- "webidl-conversions": "^3.0.0"
- }
- },
- "node_modules/which": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
- "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
- "license": "ISC",
- "dependencies": {
- "isexe": "^2.0.0"
- },
- "bin": {
- "node-which": "bin/node-which"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/which-boxed-primitive": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz",
- "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-bigint": "^1.1.0",
- "is-boolean-object": "^1.2.1",
- "is-number-object": "^1.1.1",
- "is-string": "^1.1.1",
- "is-symbol": "^1.1.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/which-builtin-type": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz",
- "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bound": "^1.0.2",
- "function.prototype.name": "^1.1.6",
- "has-tostringtag": "^1.0.2",
- "is-async-function": "^2.0.0",
- "is-date-object": "^1.1.0",
- "is-finalizationregistry": "^1.1.0",
- "is-generator-function": "^1.0.10",
- "is-regex": "^1.2.1",
- "is-weakref": "^1.0.2",
- "isarray": "^2.0.5",
- "which-boxed-primitive": "^1.1.0",
- "which-collection": "^1.0.2",
- "which-typed-array": "^1.1.16"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/which-collection": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz",
- "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "is-map": "^2.0.3",
- "is-set": "^2.0.3",
- "is-weakmap": "^2.0.2",
- "is-weakset": "^2.0.3"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/which-typed-array": {
- "version": "1.1.22",
- "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.22.tgz",
- "integrity": "sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "available-typed-arrays": "^1.0.7",
- "call-bind": "^1.0.9",
- "call-bound": "^1.0.4",
- "for-each": "^0.3.5",
- "get-proto": "^1.0.1",
- "gopd": "^1.2.0",
- "has-tostringtag": "^1.0.2"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "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",
- "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "siginfo": "^2.0.0",
- "stackback": "0.0.2"
- },
- "bin": {
- "why-is-node-running": "cli.js"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/word-wrap": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
- "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/wrap-ansi": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
- "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
- "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/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==",
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
- }
- },
- "node_modules/wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "license": "ISC"
- },
- "node_modules/ws": {
- "version": "8.21.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz",
- "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==",
- "license": "MIT",
- "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/xdg-app-paths": {
- "version": "5.5.1",
- "resolved": "https://registry.npmjs.org/xdg-app-paths/-/xdg-app-paths-5.5.1.tgz",
- "integrity": "sha512-hI3flOB4PLZIy5prbtTpirobtPE2ZtZ52szO+2mM9Efp6ErM398La+C1lIpNWDfNoQk+6Lsi6nMcCwVB7pxeMQ==",
- "license": "MIT",
- "dependencies": {
- "os-paths": "^4.0.1",
- "xdg-portable": "^7.2.0"
- },
- "engines": {
- "node": ">= 6.0"
- }
- },
- "node_modules/xdg-portable": {
- "version": "7.3.0",
- "resolved": "https://registry.npmjs.org/xdg-portable/-/xdg-portable-7.3.0.tgz",
- "integrity": "sha512-sqMMuL1rc0FmMBOzCpd0yuy9trqF2yTTVe+E9ogwCSWQCdDEtQUwrZPT6AxqtsFGRNxycgncbP/xmOOSPw5ZUw==",
- "license": "MIT",
- "dependencies": {
- "os-paths": "^4.0.1"
- },
- "engines": {
- "node": ">= 6.0"
- }
- },
- "node_modules/y18n": {
- "version": "5.0.8",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
- "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
- "license": "ISC",
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/yallist": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
- "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
- "license": "ISC"
- },
- "node_modules/yargs": {
- "version": "17.7.3",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz",
- "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==",
- "license": "MIT",
- "dependencies": {
- "cliui": "^8.0.1",
- "escalade": "^3.1.1",
- "get-caller-file": "^2.0.5",
- "require-directory": "^2.1.1",
- "string-width": "^4.2.3",
- "y18n": "^5.0.5",
- "yargs-parser": "^21.1.1"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/yargs-parser": {
- "version": "21.1.1",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
- "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
- "license": "ISC",
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/yocto-queue": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
- "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/zod": {
- "version": "3.25.76",
- "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
- "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "url": "https://github.com/sponsors/colinhacks"
- }
- },
- "node_modules/zod-to-json-schema": {
- "version": "3.25.2",
- "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz",
- "integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==",
- "dev": true,
- "license": "ISC",
- "peerDependencies": {
- "zod": "^3.25.28 || ^4"
- }
- },
- "node_modules/zod-validation-error": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz",
- "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=18.0.0"
- },
- "peerDependencies": {
- "zod": "^3.25.0 || ^4.0.0"
- }
- },
- "src/dataconnect-generated": {
- "name": "@video-analyzer/dataconnect",
- "version": "1.0.0",
- "license": "Apache-2.0",
- "engines": {
- "node": " >=18.0"
- },
- "peerDependencies": {
- "firebase": "^12.11.0"
- }
- }
- }
-}
diff --git a/package.json b/package.json
index 059fb9581..0d5b1e543 100644
--- a/package.json
+++ b/package.json
@@ -21,6 +21,16 @@
},
"devDependencies": {
"@modelcontextprotocol/sdk": "^1.26.0",
+<<<<<<< HEAD
+ "brace-expansion": "^5.0.7",
+ "eslint": "^9.39.5",
+ "next": "^16.2.10",
+ "turbo": "^2.10.5",
+ "typescript": "^6.0.3",
+ "vitest": "^4.1.10"
+ },
+ "overrides": {
+=======
"brace-expansion": "^5.0.8",
"eslint": "^9.39.5",
"next": "^16.2.10",
@@ -30,6 +40,7 @@
},
"overrides": {
"typescript": "6.0.3",
+>>>>>>> origin/main
"react": "^19",
"react-dom": "^19",
"next": "^16.2.10",
diff --git a/pyproject.toml b/pyproject.toml
index e879c6e6a..955e2ce56 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -279,7 +279,12 @@ addopts = """\
--cov=youtube_extension \
--cov-report=html:htmlcov \
--cov-report=term-missing \
+<<<<<<< HEAD
+ --cov-report=xml \
+ --cov-fail-under=90\
+=======
--cov-report=xml\
+>>>>>>> origin/main
"""
markers = [
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
@@ -328,12 +333,15 @@ omit = [
]
[tool.coverage.report]
+<<<<<<< HEAD
+=======
# The former 90% setting was not achieved by the suite it claimed to govern.
# Exact deterministic-suite baseline: 19,761 / 22,409 statements (88.1833%).
# The 90% target remains the ratchet destination. Increase this floor as
# focused coverage work lands; never lower it without a new exact-head report.
fail_under = 88.1833
precision = 4
+>>>>>>> origin/main
exclude_lines = [
"pragma: no cover",
"def __repr__",
diff --git a/rewrite.py b/rewrite.py
new file mode 100644
index 000000000..314b89901
--- /dev/null
+++ b/rewrite.py
@@ -0,0 +1,19 @@
+import sys
+
+with open("src/agents/openai_dev_task_manager.py", "r") as f:
+ content = f.read()
+
+direct_import = """ try:
+ from mcp.mcp_video_processor import MCPVideoProcessor
+ return MCPVideoProcessor()
+ except ImportError as e:
+ raise ImportError("Unable to load MCPVideoProcessor module") from e"""
+
+content = content.replace(""" try:
+ from mcp.mcp_video_processor import MCPVideoProcessor
+ return MCPVideoProcessor()
+ except ImportError:
+ raise ImportError("Unable to load MCPVideoProcessor module")""", direct_import)
+
+with open("src/agents/openai_dev_task_manager.py", "w") as f:
+ f.write(content)
diff --git a/scripts/archive/software-on-demand/package-lock.json b/scripts/archive/software-on-demand/package-lock.json
index 12ae6a04a..eb7416e68 100644
--- a/scripts/archive/software-on-demand/package-lock.json
+++ b/scripts/archive/software-on-demand/package-lock.json
@@ -54,9 +54,15 @@
"license": "MIT"
},
"node_modules/fast-uri": {
+<<<<<<< HEAD
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz",
+ "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==",
+=======
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz",
"integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==",
+>>>>>>> origin/main
"funding": [
{
"type": "github",
diff --git a/scripts/archive/supabase_cleanup/package-lock.json b/scripts/archive/supabase_cleanup/package-lock.json
index 8a7e5da61..bab5848a9 100644
--- a/scripts/archive/supabase_cleanup/package-lock.json
+++ b/scripts/archive/supabase_cleanup/package-lock.json
@@ -15,7 +15,11 @@
"better-sqlite3": "^11.9.1",
"dotenv": "^16.5.0",
"express": "^5.1.0",
+<<<<<<< HEAD
+ "next": "16.2.7",
+=======
"next": "16.2.11",
+>>>>>>> origin/main
"node-fetch": "^3.3.2",
"pg": "^8.11.3",
"react": "^19.0.0",
@@ -621,6 +625,17 @@
}
},
"node_modules/@next/env": {
+<<<<<<< HEAD
+ "version": "16.2.7",
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.7.tgz",
+ "integrity": "sha512-tMJizPlj6ZYpBMMdK8S0LJufrP4QTdR6pcv9KQ/bVETPAmg0j1mlHE9G2c38UyGHxoBapgwuj7XjbGJ2RcDFOg==",
+ "license": "MIT"
+ },
+ "node_modules/@next/swc-darwin-arm64": {
+ "version": "16.2.7",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.2.7.tgz",
+ "integrity": "sha512-vm1EDI/pVaBNNiychmxk3fft+OhQPVD9cIM/tReLZIQ3TfQ4kqI9DwKk00dzuS1ulC7icbrzCFrmRRlk9PfNdw==",
+=======
"version": "16.2.11",
"resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.11.tgz",
"integrity": "sha512-0do5A3BJ2gxWr0ZCMcD6BhW+e595jyxdTl3rXTS6lOtD8ektMiW6CO+EPwt1Eca1DBnm90r/7GdiKWBKxH++DA==",
@@ -630,6 +645,7 @@
"version": "16.2.11",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.2.11.tgz",
"integrity": "sha512-wryL4pjKmDwGv2ox6+GZDFxvmtSRLqApBR8kL1j4+vhB7Z5vJC/zAnXpiR9Xkfzl0AS8WLMnsuGV/UKI67/rrw==",
+>>>>>>> origin/main
"cpu": [
"arm64"
],
@@ -643,9 +659,15 @@
}
},
"node_modules/@next/swc-darwin-x64": {
+<<<<<<< HEAD
+ "version": "16.2.7",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.2.7.tgz",
+ "integrity": "sha512-O3IRSv1ZBL1zs0WrIgefTEcTKFVn+ryxBNe54erJ6KsD+2f/Mmt7g2jOYh8PSBdUwPtKQJuCsTMlZ7tIu2AcsQ==",
+=======
"version": "16.2.11",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.2.11.tgz",
"integrity": "sha512-aZl2j4f/fLyjQvOhv0Oe9UaMAQHolYpKhctsoYzplSumKJKPUmgjcf6545aBtysLTcu994TREd0+pSgNE4ohmg==",
+>>>>>>> origin/main
"cpu": [
"x64"
],
@@ -659,6 +681,14 @@
}
},
"node_modules/@next/swc-linux-arm64-gnu": {
+<<<<<<< HEAD
+ "version": "16.2.7",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.2.7.tgz",
+ "integrity": "sha512-Re6PZtjBDd0aMU+VcZcC/PrIvj4WhrjDYtMhhCVQamWN4L90EVP0pcEOBQD25prSlw7OzNw5QpHLWMilRLsRNw==",
+ "cpu": [
+ "arm64"
+ ],
+=======
"version": "16.2.11",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.2.11.tgz",
"integrity": "sha512-5jEriyEnH/LWFy27L2ZG0XaLlyEJIjhsImEsiS9P563PKEVp2BVups/xfOucIrsvVntp11oNcZwjHvaDPYVB5g==",
@@ -668,6 +698,7 @@
"libc": [
"glibc"
],
+>>>>>>> origin/main
"license": "MIT",
"optional": true,
"os": [
@@ -678,6 +709,14 @@
}
},
"node_modules/@next/swc-linux-arm64-musl": {
+<<<<<<< HEAD
+ "version": "16.2.7",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.2.7.tgz",
+ "integrity": "sha512-qyogG9QtBzWxgJfeGBvOEHI3851gTfCF3wLZ5RDLTBJGAmE9p1qDwKCOdrBrvBzRvYDT+gUDp72pzlSEfAXgNA==",
+ "cpu": [
+ "arm64"
+ ],
+=======
"version": "16.2.11",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.2.11.tgz",
"integrity": "sha512-eIjcpx2fnnFSSkZDbTxy74KnokUXDjfoLClpWelfgHLf621aTqswhwXQ7GkD5K5rplrS6LZ/Bj+mVuvzluBOEg==",
@@ -687,6 +726,7 @@
"libc": [
"musl"
],
+>>>>>>> origin/main
"license": "MIT",
"optional": true,
"os": [
@@ -697,6 +737,14 @@
}
},
"node_modules/@next/swc-linux-x64-gnu": {
+<<<<<<< HEAD
+ "version": "16.2.7",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.2.7.tgz",
+ "integrity": "sha512-Vhe4ZDuBpmMogrGi5D4R2Kq4JAQlj6+wvgaFYy31zfES0zPmt6TLA+cuYpM/OLrPZjo2MYQTHVqNUSCR6+fDZQ==",
+ "cpu": [
+ "x64"
+ ],
+=======
"version": "16.2.11",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.2.11.tgz",
"integrity": "sha512-8WgzpaWMs46qJT9kiV47cje86L0x/Mu9t8/Gwj+pnbgW3rETVfCnaScPjlYUwNScpOozdcIMHWmAvuZJUonR2w==",
@@ -706,6 +754,7 @@
"libc": [
"glibc"
],
+>>>>>>> origin/main
"license": "MIT",
"optional": true,
"os": [
@@ -716,6 +765,14 @@
}
},
"node_modules/@next/swc-linux-x64-musl": {
+<<<<<<< HEAD
+ "version": "16.2.7",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.2.7.tgz",
+ "integrity": "sha512-srvian89JahFLw1YLBEuhvPJ0DO5lpUeJQMXy4xYo7g628ZlNgXdNkqoxSAv9OYrBfByh6vxISMwW/mRbzCY+g==",
+ "cpu": [
+ "x64"
+ ],
+=======
"version": "16.2.11",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.2.11.tgz",
"integrity": "sha512-I3UgPds7G4ZYnTb/H+5GBGuUT2DhAk6j0mL6A4s63RjFs74wB2hOWP0vaxsK+3NJraExt3eYEPQ/UtT0x/64Nw==",
@@ -725,6 +782,7 @@
"libc": [
"musl"
],
+>>>>>>> origin/main
"license": "MIT",
"optional": true,
"os": [
@@ -735,9 +793,15 @@
}
},
"node_modules/@next/swc-win32-arm64-msvc": {
+<<<<<<< HEAD
+ "version": "16.2.7",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.2.7.tgz",
+ "integrity": "sha512-GX3wvLpULFuRFJzwHaKfm7QZJ18F4ZSuxlPJ96BoBglCzBmdSjyeBKF+ZhWhvL/ckxNfLnNa7bsObO2ipYpszw==",
+=======
"version": "16.2.11",
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.2.11.tgz",
"integrity": "sha512-n89CjtcThnjrwgJMAiI5xbqwLY51zvwC9tSlArmVndAJLYVl9T9UAdlkXTmZvE++idoXe8KdglQlhNRdUp1c6g==",
+>>>>>>> origin/main
"cpu": [
"arm64"
],
@@ -751,9 +815,15 @@
}
},
"node_modules/@next/swc-win32-x64-msvc": {
+<<<<<<< HEAD
+ "version": "16.2.7",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.2.7.tgz",
+ "integrity": "sha512-J4WlM72NMk076Qsg0jTdK3SNXatlSdnjW7L7oNGLst1tAGjHrJh/FYi+pw9wyIjEtGRKDNzD0zuiY16oWYWVaw==",
+=======
"version": "16.2.11",
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.2.11.tgz",
"integrity": "sha512-md8CLNggS1Dx9pUgApzps5uAf+N8GN9xywzmNx9vHAWo94HtBwCCqkSnhIrdfQe83Dhz8Lfo/20Nb1Zxal092w==",
+>>>>>>> origin/main
"cpu": [
"x64"
],
@@ -1406,6 +1476,22 @@
}
},
"node_modules/body-parser": {
+<<<<<<< HEAD
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.1.tgz",
+ "integrity": "sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "^3.1.2",
+ "content-type": "^1.0.5",
+ "debug": "^4.4.3",
+ "http-errors": "^2.0.0",
+ "iconv-lite": "^0.7.0",
+ "on-finished": "^2.4.1",
+ "qs": "^6.14.0",
+ "raw-body": "^3.0.1",
+ "type-is": "^2.0.1"
+=======
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz",
"integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==",
@@ -1420,6 +1506,7 @@
"qs": "^6.15.2",
"raw-body": "^3.0.2",
"type-is": "^2.1.0"
+>>>>>>> origin/main
},
"engines": {
"node": ">=18"
@@ -1429,6 +1516,12 @@
"url": "https://opencollective.com/express"
}
},
+<<<<<<< HEAD
+ "node_modules/brace-expansion": {
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz",
+ "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==",
+=======
"node_modules/body-parser/node_modules/content-type": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz",
@@ -1446,13 +1539,18 @@
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz",
"integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==",
+>>>>>>> origin/main
"license": "MIT",
"optional": true,
"dependencies": {
"balanced-match": "^4.0.2"
},
"engines": {
+<<<<<<< HEAD
+ "node": "18 || 20 || >=22"
+=======
"node": "20 || >=22"
+>>>>>>> origin/main
}
},
"node_modules/buffer": {
@@ -2704,12 +2802,21 @@
}
},
"node_modules/next": {
+<<<<<<< HEAD
+ "version": "16.2.7",
+ "resolved": "https://registry.npmjs.org/next/-/next-16.2.7.tgz",
+ "integrity": "sha512-eMJxgjRzBaj3olkP4cBamHDXL79A8FC6u1GcsO1D1Tsx8bw/LLXUJCaoajVxtnhD3A1IJqIT8IcRJjgBIPJq4w==",
+ "license": "MIT",
+ "dependencies": {
+ "@next/env": "16.2.7",
+=======
"version": "16.2.11",
"resolved": "https://registry.npmjs.org/next/-/next-16.2.11.tgz",
"integrity": "sha512-B339zaqbyK8cmxhoAvLrcwoabwCP1wz21zSzfqxqXAemTu2BXnH7tQnfcglKv1vnMUIDBc+Hth7XODQriTZiRQ==",
"license": "MIT",
"dependencies": {
"@next/env": "16.2.11",
+>>>>>>> origin/main
"@swc/helpers": "0.5.15",
"baseline-browser-mapping": "^2.9.19",
"caniuse-lite": "^1.0.30001579",
@@ -2723,6 +2830,16 @@
"node": ">=20.9.0"
},
"optionalDependencies": {
+<<<<<<< HEAD
+ "@next/swc-darwin-arm64": "16.2.7",
+ "@next/swc-darwin-x64": "16.2.7",
+ "@next/swc-linux-arm64-gnu": "16.2.7",
+ "@next/swc-linux-arm64-musl": "16.2.7",
+ "@next/swc-linux-x64-gnu": "16.2.7",
+ "@next/swc-linux-x64-musl": "16.2.7",
+ "@next/swc-win32-arm64-msvc": "16.2.7",
+ "@next/swc-win32-x64-msvc": "16.2.7",
+=======
"@next/swc-darwin-arm64": "16.2.11",
"@next/swc-darwin-x64": "16.2.11",
"@next/swc-linux-arm64-gnu": "16.2.11",
@@ -2731,6 +2848,7 @@
"@next/swc-linux-x64-musl": "16.2.11",
"@next/swc-win32-arm64-msvc": "16.2.11",
"@next/swc-win32-x64-msvc": "16.2.11",
+>>>>>>> origin/main
"sharp": "^0.34.5"
},
"peerDependencies": {
@@ -3676,9 +3794,15 @@
}
},
"node_modules/tar": {
+<<<<<<< HEAD
+ "version": "7.5.16",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.16.tgz",
+ "integrity": "sha512-56adEpPMouktRlBLXiaYFFzZ/3+JXa8P9n7WbR+ibIjtviN55mEaOkiysCnPnWm+7kkui1Dn8J9l+g6zV8731w==",
+=======
"version": "7.5.21",
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.21.tgz",
"integrity": "sha512-XdhtCvlMywwxpCW8YEq3lOXBJpUPTR2OHHcwLPO3HwsJqOHa2Ok/oJ7ruGzp+JrKoRPVCzJwAdEjqLW/vNRPHA==",
+>>>>>>> origin/main
"license": "BlueOak-1.0.0",
"dependencies": {
"@isaacs/fs-minipass": "^4.0.0",
@@ -3819,16 +3943,28 @@
}
},
"node_modules/type-is": {
+<<<<<<< HEAD
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
+ "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
+ "license": "MIT",
+ "dependencies": {
+ "content-type": "^1.0.5",
+=======
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz",
"integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==",
"license": "MIT",
"dependencies": {
"content-type": "^2.0.0",
+>>>>>>> origin/main
"media-typer": "^1.1.0",
"mime-types": "^3.0.0"
},
"engines": {
+<<<<<<< HEAD
+ "node": ">= 0.6"
+=======
"node": ">= 18"
},
"funding": {
@@ -3847,6 +3983,7 @@
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/express"
+>>>>>>> origin/main
}
},
"node_modules/typescript": {
diff --git a/scripts/archive/supabase_cleanup/package.json b/scripts/archive/supabase_cleanup/package.json
index f078922d4..71d6a03f6 100644
--- a/scripts/archive/supabase_cleanup/package.json
+++ b/scripts/archive/supabase_cleanup/package.json
@@ -22,7 +22,11 @@
"better-sqlite3": "^11.9.1",
"dotenv": "^16.5.0",
"express": "^5.1.0",
+<<<<<<< HEAD
+ "next": "16.2.7",
+=======
"next": "16.2.11",
+>>>>>>> origin/main
"node-fetch": "^3.3.2",
"pg": "^8.11.3",
"react": "^19.0.0",
diff --git a/src/agents/gemini_video_master_agent.py b/src/agents/gemini_video_master_agent.py
index 92976b096..a8188ed62 100644
--- a/src/agents/gemini_video_master_agent.py
+++ b/src/agents/gemini_video_master_agent.py
@@ -33,8 +33,11 @@
GEMINI_AVAILABLE = True
except ImportError:
+<<<<<<< HEAD
+=======
genai = None
types = None
+>>>>>>> origin/main
GEMINI_AVAILABLE = False
logging.warning("Google AI not available - install: pip install google-genai")
@@ -1094,7 +1097,11 @@ async def _execute_with_gemini_text(
@staticmethod
def _build_gemini_generation_config(
response_mime_type: str | None = None,
+<<<<<<< HEAD
+ ) -> types.GenerateContentConfig:
+=======
) -> "types.GenerateContentConfig":
+>>>>>>> origin/main
config_kwargs = {
"max_output_tokens": int(os.getenv("GEMINI_MAX_OUTPUT_TOKENS", "16384"))
}
diff --git a/src/agents/openai_dev_task_manager.py b/src/agents/openai_dev_task_manager.py
index 6df2d2b26..4dcaee401 100644
--- a/src/agents/openai_dev_task_manager.py
+++ b/src/agents/openai_dev_task_manager.py
@@ -18,8 +18,11 @@
from pathlib import Path
from typing import Optional
+<<<<<<< HEAD
+=======
from utils.path_utils import select_writable_dir
+>>>>>>> origin/main
@dataclass
class DevTaskResult:
@@ -36,6 +39,11 @@ class OpenAIDevTaskManager:
"""MCP-first dev task manager to operationalize YouTube video capabilities."""
def __init__(self, workspace_root: Optional[str] = None):
+<<<<<<< HEAD
+ self.workspace_root = Path(
+ workspace_root or "/Users/garvey/UVAI/src/core/youtube_extension"
+ )
+=======
explicit = workspace_root or os.getenv("WORKSPACE_ROOT")
if explicit:
self.workspace_root = Path(explicit)
@@ -46,6 +54,7 @@ def __init__(self, workspace_root: Optional[str] = None):
"/Users/garvey/UVAI/src/core/youtube_extension",
Path.cwd() / "workflow_workspace",
)
+>>>>>>> origin/main
self.output_root = self.workspace_root / "workflow_output"
self.output_root.mkdir(parents=True, exist_ok=True)
diff --git a/src/agents/specialized/code_generator.py b/src/agents/specialized/code_generator.py
index 345f51cb6..1d1f1c1c2 100644
--- a/src/agents/specialized/code_generator.py
+++ b/src/agents/specialized/code_generator.py
@@ -20,8 +20,12 @@ def __init__(self):
def _load_templates(self) -> dict[str, str]:
"""Load code generation templates"""
return {
+<<<<<<< HEAD
+ "fastapi_endpoint": textwrap.dedent("""
+=======
"fastapi_endpoint": textwrap.dedent(
"""
+>>>>>>> origin/main
@app.post("/api/v1/{endpoint_name}")
async def {function_name}({parameters}):
\"\"\"
@@ -43,6 +47,16 @@ async def {function_name}({parameters}):
except ValidationError as e:
raise HTTPException(status_code=400, detail=str(e))
except Exception as e:
+<<<<<<< HEAD
+ logger.error("Internal server error", exc_info=True)
+ raise HTTPException(status_code=500, detail="Internal server error")
+ """),
+ "rest_api": textwrap.dedent("""
+ # {title}
+ # Generated API endpoint
+
+ import logging
+=======
raise HTTPException(status_code=500, detail=str(e))
"""
),
@@ -51,11 +65,21 @@ async def {function_name}({parameters}):
# {title}
# Generated API endpoint
+>>>>>>> origin/main
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from datetime import datetime
from typing import Optional, List
+<<<<<<< HEAD
+ logger = logging.getLogger(__name__)
+
+ {models}
+
+ {endpoints}
+ """),
+ "crud_operations": textwrap.dedent("""
+=======
{models}
{endpoints}
@@ -63,6 +87,7 @@ async def {function_name}({parameters}):
),
"crud_operations": textwrap.dedent(
"""
+>>>>>>> origin/main
# CRUD operations for {entity}
@app.post("/{entity_plural}")
@@ -88,8 +113,12 @@ async def delete_{entity}(id: int):
\"\"\"Delete {entity}\"\"\"
# Implementation here
pass
+<<<<<<< HEAD
+ """),
+=======
"""
),
+>>>>>>> origin/main
}
@staticmethod
diff --git a/src/mcp/mcp_ecosystem_coordinator.py b/src/mcp/mcp_ecosystem_coordinator.py
index 5e8a56311..5fb399fe4 100644
--- a/src/mcp/mcp_ecosystem_coordinator.py
+++ b/src/mcp/mcp_ecosystem_coordinator.py
@@ -17,8 +17,11 @@
from pathlib import Path
from typing import Any, Optional
+<<<<<<< HEAD
+=======
from utils.path_utils import select_writable_dir
+>>>>>>> origin/main
# Configure logging
logging.basicConfig(
level=logging.INFO,
@@ -179,6 +182,9 @@ class MCPEcosystemCoordinator:
"""
def __init__(self, config_path: str = None):
+<<<<<<< HEAD
+ self.config_path = config_path or "/Users/garvey/UVAI/10_MCP_ECOSYSTEM"
+=======
if config_path:
self.config_path = config_path
else:
@@ -191,6 +197,7 @@ def __init__(self, config_path: str = None):
Path.cwd() / "mcp_ecosystem",
)
)
+>>>>>>> origin/main
self.coordination_config = self._load_coordination_config()
# MCP node registry
diff --git a/src/mcp/mcp_video_processor.py b/src/mcp/mcp_video_processor.py
index 7d3162011..8882d4906 100644
--- a/src/mcp/mcp_video_processor.py
+++ b/src/mcp/mcp_video_processor.py
@@ -19,8 +19,11 @@
from pathlib import Path
from typing import Any
+<<<<<<< HEAD
+=======
from utils.path_utils import select_readable_file, select_writable_dir
+>>>>>>> origin/main
# MCP integration imports
try:
import mcp
@@ -204,6 +207,12 @@ class MCPConfig:
"""Configuration management for MCP video processor"""
def __init__(self, config_path: str = None):
+<<<<<<< HEAD
+ self.config_path = (
+ config_path
+ or "/Users/garvey/UVAI/10_MCP_ECOSYSTEM/MCP/mcp_detailed_config.json"
+ )
+=======
if config_path:
self.config_path = config_path
else:
@@ -216,6 +225,7 @@ def __init__(self, config_path: str = None):
Path.cwd() / "mcp_detailed_config.json",
)
)
+>>>>>>> origin/main
self.config = self._load_config()
def _load_config(self) -> dict[str, Any]:
@@ -1165,6 +1175,10 @@ async def save_results_mcp(
) -> dict[str, Any]:
"""Save results with MCP metadata and analytics"""
+<<<<<<< HEAD
+ # Create enhanced results directory
+ results_dir = Path("/Users/garvey/UVAI/10_MCP_ECOSYSTEM/mcp_results")
+=======
# Create enhanced results directory. Select a base that is genuinely
# writable (the legacy path only if it exists and is writable), so the
# category_dir creation below cannot raise PermissionError.
@@ -1172,6 +1186,7 @@ async def save_results_mcp(
"/Users/garvey/UVAI/10_MCP_ECOSYSTEM/mcp_results",
Path.cwd() / "mcp_results",
)
+>>>>>>> origin/main
category_dir = results_dir / content["category"]
category_dir.mkdir(parents=True, exist_ok=True)
diff --git a/src/utils/__init__.py b/src/utils/__init__.py
index a9e47633c..032c45da8 100644
--- a/src/utils/__init__.py
+++ b/src/utils/__init__.py
@@ -1,4 +1,9 @@
"""EventRelay utility modules"""
+<<<<<<< HEAD
+from .path_utils import get_project_root, resolve_path
+
+__all__ = ['get_project_root', 'resolve_path']
+=======
from .path_utils import (
get_project_root,
resolve_path,
@@ -12,3 +17,4 @@
'select_readable_file',
'select_writable_dir',
]
+>>>>>>> origin/main
diff --git a/src/utils/path_utils.py b/src/utils/path_utils.py
index 0c6410a50..c1de8f9a7 100644
--- a/src/utils/path_utils.py
+++ b/src/utils/path_utils.py
@@ -7,6 +7,9 @@
Compatible with UVAI configuration.path_utils interface.
"""
+<<<<<<< HEAD
+from pathlib import Path
+=======
import os
from pathlib import Path
from typing import Union
@@ -64,6 +67,7 @@ def select_readable_file(preferred: PathLike, fallback: PathLike) -> Path:
if candidate.is_file() and os.access(candidate, os.R_OK):
return candidate
return Path(fallback)
+>>>>>>> origin/main
def get_project_root() -> Path:
diff --git a/src/youtube_extension/backend/deploy/fly.py b/src/youtube_extension/backend/deploy/fly.py
index 1facb55f2..3d39a15e7 100644
--- a/src/youtube_extension/backend/deploy/fly.py
+++ b/src/youtube_extension/backend/deploy/fly.py
@@ -6,7 +6,10 @@
import asyncio
import os
+<<<<<<< HEAD
+=======
import time
+>>>>>>> origin/main
from pathlib import Path
from typing import Any, Optional
@@ -184,9 +187,13 @@ def _generate_app_name(self, project_config: dict[str, Any]) -> str:
"""Generate a unique app name for Fly.io"""
title = project_config.get('title', 'uvai-app')
sanitized = ''.join(c for c in title.lower().replace(' ', '-') if c.isalnum() or c == '-')
+<<<<<<< HEAD
+ timestamp = int(asyncio.get_event_loop().time()) % 10000
+=======
# Name generation is synchronous and must not depend on a caller having
# installed an asyncio event loop (Python 3.12 raises when none exists).
timestamp = int(time.monotonic()) % 10000
+>>>>>>> origin/main
return f"uvai-{sanitized[:20]}-{timestamp}"
def _extract_deployment_url(self, output: str) -> Optional[str]:
diff --git a/src/youtube_extension/backend/deployment_manager.py b/src/youtube_extension/backend/deployment_manager.py
index e1e9844ee..5767ea434 100644
--- a/src/youtube_extension/backend/deployment_manager.py
+++ b/src/youtube_extension/backend/deployment_manager.py
@@ -98,7 +98,18 @@ async def verify_project(self, project_path: str) -> dict[str, Any]:
Runs npm install and npm run build to catch errors early.
"""
logger.info("🔍 Verifying project build...")
+<<<<<<< HEAD
+ if os.getenv("SENTRY_DSN"):
+ import sentry_sdk
+ sentry_sdk.add_breadcrumb(
+ category="deployment",
+ message="Starting build verification",
+ data={"project_path": project_path, "has_package_json": package_json.exists()},
+ level="info"
+ )
+=======
project_dir = Path(project_path)
+>>>>>>> origin/main
result = {
"passed": False,
@@ -108,6 +119,11 @@ async def verify_project(self, project_path: str) -> dict[str, Any]:
"summary": ""
}
+<<<<<<< HEAD
+ project_dir = Path(project_path)
+
+=======
+>>>>>>> origin/main
# Security: validate and resolve path to prevent traversal
try:
resolved_path = project_dir.resolve()
@@ -120,6 +136,8 @@ async def verify_project(self, project_path: str) -> dict[str, Any]:
package_json = resolved_path / "package.json"
+<<<<<<< HEAD
+=======
if os.getenv("SENTRY_DSN"):
import sentry_sdk
sentry_sdk.add_breadcrumb(
@@ -132,6 +150,7 @@ async def verify_project(self, project_path: str) -> dict[str, Any]:
level="info",
)
+>>>>>>> origin/main
# Check if package.json exists
if not package_json.exists():
result["summary"] = "No package.json found - skipping verification"
@@ -370,9 +389,12 @@ async def deploy_project(self,
"project_config": project_config,
"deployments": {},
"verification": {},
+<<<<<<< HEAD
+=======
# Keep the response contract stable even when build verification
# fails before any deployment adapter is invoked.
"summary": self._generate_deployment_summary({}),
+>>>>>>> origin/main
"errors": []
}
diff --git a/src/youtube_extension/backend/enhanced_video_processor.py b/src/youtube_extension/backend/enhanced_video_processor.py
index 2b36769cf..12a9689f6 100644
--- a/src/youtube_extension/backend/enhanced_video_processor.py
+++ b/src/youtube_extension/backend/enhanced_video_processor.py
@@ -296,8 +296,12 @@ async def _get_openai_whisper_transcript(self, video_id: str, video_url: str) ->
proxy_url = get_proxy_url()
if proxy_url:
ytdlp_cmd.extend(["--proxy", proxy_url])
+<<<<<<< HEAD
+ ytdlp_cmd.extend(["-o", audio_path, video_url])
+=======
canonical_video_url = f"https://www.youtube.com/watch?v={video_id}"
ytdlp_cmd.extend(["-o", audio_path, "--", canonical_video_url])
+>>>>>>> origin/main
subprocess.run(
ytdlp_cmd, check=True, capture_output=True, timeout=60
)
diff --git a/src/youtube_extension/backend/middleware/error_handling_middleware.py b/src/youtube_extension/backend/middleware/error_handling_middleware.py
index 8c48ea19b..9d86e22d6 100644
--- a/src/youtube_extension/backend/middleware/error_handling_middleware.py
+++ b/src/youtube_extension/backend/middleware/error_handling_middleware.py
@@ -439,7 +439,11 @@ async def handle_exception(self, request: Request, exception: Exception, context
headers=headers
)
+<<<<<<< HEAD
except Exception as handling_error:
+=======
+ except Exception as handling_error: # pragma: no cover
+>>>>>>> origin/main
# Fallback error handling
self.logger.critical(f"Error in error handler: {handling_error}", exc_info=True)
diff --git a/src/youtube_extension/backend/middleware/rate_limiting.py b/src/youtube_extension/backend/middleware/rate_limiting.py
index b179304b3..c18f03a52 100644
--- a/src/youtube_extension/backend/middleware/rate_limiting.py
+++ b/src/youtube_extension/backend/middleware/rate_limiting.py
@@ -177,7 +177,11 @@ def __init__(self, app: ASGIApp):
# Optional: Redis-backed rate limiter for production
+<<<<<<< HEAD
try:
+=======
+try: # pragma: no cover
+>>>>>>> origin/main
import redis
class RedisRateLimiter:
@@ -205,6 +209,10 @@ def is_allowed(self, request: Request) -> tuple[bool, dict]:
# Using INCR and EXPIRE commands with sliding window
pass
+<<<<<<< HEAD
except ImportError:
+=======
+except ImportError: # pragma: no cover
+>>>>>>> origin/main
logger.info("Redis not available, using in-memory rate limiter")
RedisRateLimiter = None
diff --git a/src/youtube_extension/backend/repositories/__init__.py b/src/youtube_extension/backend/repositories/__init__.py
index 15e4b6d32..5d81004f7 100644
--- a/src/youtube_extension/backend/repositories/__init__.py
+++ b/src/youtube_extension/backend/repositories/__init__.py
@@ -17,7 +17,11 @@
from .user import UserProfileRepository, UserRepository, UserSessionRepository
__all__.extend(["UserRepository", "UserProfileRepository", "UserSessionRepository"])
+<<<<<<< HEAD
except ImportError:
+=======
+except ImportError: # pragma: no cover
+>>>>>>> origin/main
# Optional user repositories not available; safe to ignore
pass
@@ -32,7 +36,11 @@
__all__.extend(
["TenantRepository", "TenantUserRepository", "TenantSubscriptionRepository"]
)
+<<<<<<< HEAD
except ImportError:
+=======
+except ImportError: # pragma: no cover
+>>>>>>> origin/main
# Optional tenant repositories not available; safe to ignore.
pass
@@ -53,7 +61,11 @@
"VideoProcessingJobRepository",
]
)
+<<<<<<< HEAD
except ImportError:
+=======
+except ImportError: # pragma: no cover
+>>>>>>> origin/main
# Optional video repositories not available; safe to ignore.
pass
@@ -72,7 +84,11 @@
"LearningProgressRepository",
]
)
+<<<<<<< HEAD
except ImportError:
+=======
+except ImportError: # pragma: no cover
+>>>>>>> origin/main
# Optional learning repositories not available; safe to ignore.
pass
@@ -81,7 +97,11 @@
from .cache import CacheRepository, CacheStatsRepository
__all__.extend(["CacheRepository", "CacheStatsRepository"])
+<<<<<<< HEAD
except ImportError:
+=======
+except ImportError: # pragma: no cover
+>>>>>>> origin/main
# Optional cache repositories not available; safe to ignore.
pass
@@ -90,7 +110,11 @@
from .audit import AuditLogRepository, SecurityEventRepository
__all__.extend(["AuditLogRepository", "SecurityEventRepository"])
+<<<<<<< HEAD
except ImportError:
+=======
+except ImportError: # pragma: no cover
+>>>>>>> origin/main
# Optional audit repositories not available; safe to ignore.
pass
@@ -109,7 +133,11 @@
"UsageStatisticRepository",
]
)
+<<<<<<< HEAD
except ImportError:
+=======
+except ImportError: # pragma: no cover
+>>>>>>> origin/main
# Optional analytics repositories not available; safe to ignore.
pass
@@ -118,6 +146,10 @@
from .unit_of_work import UnitOfWork
__all__.append("UnitOfWork")
+<<<<<<< HEAD
except ImportError:
+=======
+except ImportError: # pragma: no cover
+>>>>>>> origin/main
# Optional unit of work not available; safe to ignore.
pass
diff --git a/src/youtube_extension/backend/services/comparative_analysis.py b/src/youtube_extension/backend/services/comparative_analysis.py
index 25c12a638..1d792ee8b 100644
--- a/src/youtube_extension/backend/services/comparative_analysis.py
+++ b/src/youtube_extension/backend/services/comparative_analysis.py
@@ -34,7 +34,11 @@
from google.genai import types as genai_types
_GEMINI_AVAILABLE = True
+<<<<<<< HEAD
except ImportError:
+=======
+except ImportError: # pragma: no cover
+>>>>>>> origin/main
_GEMINI_AVAILABLE = False
logger.warning("Gemini SDK not available – provider will be skipped")
@@ -42,7 +46,11 @@
import anthropic
_CLAUDE_AVAILABLE = True
+<<<<<<< HEAD
except ImportError:
+=======
+except ImportError: # pragma: no cover
+>>>>>>> origin/main
_CLAUDE_AVAILABLE = False
logger.warning("Anthropic SDK not available – provider will be skipped")
diff --git a/src/youtube_extension/backend/services/memory_manager.py b/src/youtube_extension/backend/services/memory_manager.py
index 097fd59d3..35b645604 100644
--- a/src/youtube_extension/backend/services/memory_manager.py
+++ b/src/youtube_extension/backend/services/memory_manager.py
@@ -25,7 +25,10 @@
import threading
import time
import tracemalloc
+<<<<<<< HEAD
+=======
import weakref
+>>>>>>> origin/main
from collections import deque
from contextlib import contextmanager
from dataclasses import asdict, dataclass
@@ -162,6 +165,11 @@ def __init__(self,
self.in_use = set()
self.creation_times = {}
self._lock = threading.RLock()
+<<<<<<< HEAD
+
+ # Start cleanup task
+ self.cleanup_task = threading.Thread(target=self._cleanup_worker, daemon=True)
+=======
self._closed = False
# The worker must not retain the pool through a bound method. A weak
@@ -176,6 +184,7 @@ def __init__(self,
name=f"resource-pool-cleanup:{name}",
daemon=True,
)
+>>>>>>> origin/main
self.cleanup_task.start()
logger.info(f"📦 Resource pool '{name}' initialized (max_size: {max_size})")
@@ -193,11 +202,15 @@ def get_resource(self):
def _acquire_resource(self):
"""Acquire resource from pool"""
+<<<<<<< HEAD
+ with self._lock:
+=======
self.cleanup_idle_resources()
with self._lock:
if self._closed:
raise RuntimeError(f"Resource pool '{self.name}' is closed")
+>>>>>>> origin/main
# Try to get existing resource from pool
if self.pool:
resource = self.pool.pop()
@@ -218,6 +231,47 @@ def _acquire_resource(self):
def _release_resource(self, resource):
"""Release resource back to pool"""
+<<<<<<< HEAD
+ with self._lock:
+ if resource in self.in_use:
+ self.in_use.remove(resource)
+ self.pool.append(resource)
+ logger.debug(f"🔄 Released resource to pool '{self.name}'")
+
+ def _cleanup_worker(self):
+ """Background worker to cleanup idle resources"""
+ while True:
+ try:
+ time.sleep(60) # Check every minute
+
+ with self._lock:
+ current_time = time.time()
+ resources_to_cleanup = []
+
+ # Find idle resources
+ for resource in list(self.pool):
+ resource_id = id(resource)
+ if resource_id in self.creation_times:
+ age = current_time - self.creation_times[resource_id]
+ if age > self.idle_timeout:
+ resources_to_cleanup.append(resource)
+
+ # Cleanup idle resources
+ for resource in resources_to_cleanup:
+ try:
+ self.pool.remove(resource)
+ self.cleanup_resource(resource)
+ resource_id = id(resource)
+ if resource_id in self.creation_times:
+ del self.creation_times[resource_id]
+
+ logger.debug(f"🗑️ Cleaned up idle resource from pool '{self.name}'")
+ except Exception as e:
+ logger.error(f"Error cleaning up resource: {e}")
+
+ except Exception as e:
+ logger.error(f"Error in cleanup worker for pool '{self.name}': {e}")
+=======
cleanup_released = False
with self._lock:
if resource in self.in_use:
@@ -297,6 +351,7 @@ def __enter__(self):
def __exit__(self, exc_type, exc_value, traceback):
self.close()
+>>>>>>> origin/main
def get_stats(self) -> dict[str, Any]:
"""Get pool statistics"""
@@ -343,7 +398,10 @@ def __init__(self):
# Threading
self._lock = threading.RLock()
self.monitoring_task = None
+<<<<<<< HEAD
+=======
self._monitoring_stop = threading.Event()
+>>>>>>> origin/main
# Resource limits
self.resource_limits = ResourceLimit(
@@ -358,6 +416,18 @@ def __init__(self):
def start_monitoring(self):
"""Start memory monitoring"""
+<<<<<<< HEAD
+ if self.monitoring_task is None:
+ self.monitoring_task = threading.Thread(target=self._monitoring_worker, daemon=True)
+ self.monitoring_task.start()
+ self.profiler.start_tracking()
+ logger.info("✅ Memory monitoring started")
+
+ def stop_monitoring(self):
+ """Stop memory monitoring"""
+ self.monitoring_enabled = False
+ self.profiler.stop_tracking()
+=======
# Starting is a check/create/start transaction. Without the lock,
# concurrent callers can each observe a not-yet-alive task and create
# duplicate monitor threads.
@@ -398,11 +468,16 @@ def stop_monitoring(self):
# second monitor while a slow callback is unwinding.
logger.warning("Memory monitoring task is still stopping")
self.profiler.stop_tracking()
+>>>>>>> origin/main
logger.info("⏹️ Memory monitoring stopped")
def _monitoring_worker(self):
"""Background monitoring worker"""
+<<<<<<< HEAD
+ while self.monitoring_enabled:
+=======
while self.monitoring_enabled and not self._monitoring_stop.is_set():
+>>>>>>> origin/main
try:
# Take memory snapshot
snapshot = self._take_system_snapshot()
@@ -414,6 +489,14 @@ def _monitoring_worker(self):
# Optimize garbage collection if needed
self._optimize_garbage_collection(snapshot)
+<<<<<<< HEAD
+ # Sleep for 1 minute
+ time.sleep(60)
+
+ except Exception as e:
+ logger.error(f"Error in memory monitoring worker: {e}")
+ time.sleep(60)
+=======
for pool in list(self.resource_pools.values()):
pool.cleanup_idle_resources()
@@ -423,6 +506,7 @@ def _monitoring_worker(self):
# Interruptible wait makes stop_monitoring deterministic.
if self._monitoring_stop.wait(60):
return
+>>>>>>> origin/main
def _take_system_snapshot(self) -> MemorySnapshot:
"""Take system memory snapshot"""
@@ -432,10 +516,14 @@ def _take_system_snapshot(self) -> MemorySnapshot:
# Get GC stats
gc_stats = {
+<<<<<<< HEAD
+ 'collections': sum(gc.get_stats()),
+=======
'collections': sum(
generation.get('collections', 0)
for generation in gc.get_stats()
),
+>>>>>>> origin/main
'objects': len(gc.get_objects())
}
@@ -621,9 +709,21 @@ def _cleanup_resource_pools(self):
"""Cleanup resource pools to free memory"""
for pool_name, pool in self.resource_pools.items():
try:
+<<<<<<< HEAD
+ # Force cleanup of idle resources
+ with pool._lock:
+ resources_to_cleanup = list(pool.pool)
+ pool.pool.clear()
+
+ for resource in resources_to_cleanup:
+ pool.cleanup_resource(resource)
+
+ logger.info(f"🧹 Cleaned up resource pool '{pool_name}': {len(resources_to_cleanup)} resources")
+=======
cleaned = pool.cleanup_idle_resources(force=True)
logger.info(f"🧹 Cleaned up resource pool '{pool_name}': {cleaned} resources")
+>>>>>>> origin/main
except Exception as e:
logger.error(f"Error cleaning up resource pool '{pool_name}': {e}")
@@ -679,6 +779,8 @@ def create_resource_pool(self,
logger.info(f"📦 Created resource pool: {name}")
return pool
+<<<<<<< HEAD
+=======
def close(self) -> None:
"""Stop monitoring and close every managed resource pool."""
self.stop_monitoring()
@@ -686,6 +788,7 @@ def close(self) -> None:
pool.close()
self.resource_pools.clear()
+>>>>>>> origin/main
def get_memory_stats(self) -> dict[str, Any]:
"""Get comprehensive memory statistics"""
if not self.memory_history:
diff --git a/src/youtube_extension/core/config/__init__.py b/src/youtube_extension/core/config/__init__.py
index 58590b520..79ab3de92 100644
--- a/src/youtube_extension/core/config/__init__.py
+++ b/src/youtube_extension/core/config/__init__.py
@@ -12,6 +12,7 @@
- validation: Configuration validation
"""
+<<<<<<< HEAD
from .logging_config import (
LogContext,
LogDestination,
@@ -22,6 +23,21 @@
get_logger,
setup_logging,
)
+=======
+try: # pragma: no cover
+ from .logging_config import (
+ LogContext,
+ LogDestination,
+ LogFormat,
+ LogLevel,
+ UVAILogger,
+ configure_from_environment,
+ get_logger,
+ setup_logging,
+ )
+except ImportError: # pragma: no cover
+ pass
+>>>>>>> origin/main
__all__ = [
"setup_logging",
diff --git a/src/youtube_extension/core/mcp/protocol_bridge.py b/src/youtube_extension/core/mcp/protocol_bridge.py
index 81c10e614..c60ed5ade 100644
--- a/src/youtube_extension/core/mcp/protocol_bridge.py
+++ b/src/youtube_extension/core/mcp/protocol_bridge.py
@@ -14,12 +14,18 @@
"""
import asyncio
+<<<<<<< HEAD
+import logging
+import os
+from abc import ABC, abstractmethod
+=======
import ipaddress
import logging
import os
import socket
from abc import ABC, abstractmethod
from collections.abc import Mapping
+>>>>>>> origin/main
from datetime import datetime, timezone
from enum import Enum
from typing import Any, Callable, Optional
@@ -54,6 +60,21 @@
# Configure logging
logger = logging.getLogger(__name__)
+<<<<<<< HEAD
+
+def _summarize_request(request: dict[str, Any]) -> dict[str, Any]:
+ """Build a non-sensitive summary of a request for history/logging.
+
+ The raw request may carry API keys, tokens, prompts, or PII. Persisting it
+ verbatim would leak those into context history (which is serialized and
+ logged), so we record only structural metadata, never values.
+ """
+ try:
+ keys = sorted(str(k) for k in request.keys())
+ except AttributeError:
+ keys = []
+ return {"keys": keys, "key_count": len(keys)}
+=======
_SUMMARY_KEY_ALLOWLIST = frozenset(
{
"error",
@@ -160,6 +181,7 @@ async def _is_public_https_base_url(base_url: str) -> bool:
return False
return bool(resolved) and all(_is_global_dns_result(result) for result in resolved)
+>>>>>>> origin/main
class ProtocolType(Enum):
@@ -327,6 +349,33 @@ async def send_protocol_request(
# Send request through adapter
response = await self.adapters[protocol_type].send_request(request, context)
+<<<<<<< HEAD
+
+ # Update context with response. Store only a non-sensitive summary of
+ # the request — the raw dict may contain API keys/tokens/PII.
+ context.add_history_entry("protocol_request", {
+ "protocol": protocol_type.value,
+ "request_summary": _summarize_request(request),
+ "response": response,
+ "success": True
+ })
+
+ stats["success"] += 1
+ return response
+
+ except Exception as e:
+ # Update context with error
+ context.add_history_entry("protocol_request", {
+ "protocol": protocol_type.value,
+ "request_summary": _summarize_request(request),
+ "error": str(e),
+ "success": False
+ })
+
+ stats["failure"] += 1
+ logger.error(f"Protocol request failed for {protocol_type.value}: {e}")
+ raise
+=======
except Exception as exc:
stats["failure"] += 1
_record_history_safely(
@@ -358,6 +407,7 @@ async def send_protocol_request(
},
)
return response
+>>>>>>> origin/main
finally:
stats["in_flight"] -= 1
@@ -406,6 +456,9 @@ async def route_request(
logger.info(f"Routing request to protocol: {selected_protocol.value}")
+<<<<<<< HEAD
+ return await self.send_protocol_request(selected_protocol, request, context)
+=======
adapter_request = dict(request)
adapter_request.pop("required_capabilities", None)
return await self.send_protocol_request(
@@ -413,6 +466,7 @@ async def route_request(
adapter_request,
context,
)
+>>>>>>> origin/main
async def _select_protocol(
self,
@@ -468,6 +522,11 @@ async def _select_protocol(
capable_protocols = []
for protocol in candidates:
try:
+<<<<<<< HEAD
+ capabilities = set(await self.adapters[protocol].get_capabilities())
+ except Exception as e:
+ logger.warning(f"Could not get capabilities for {protocol.value}: {e}")
+=======
discovered = await asyncio.wait_for(
self.adapters[protocol].get_capabilities(),
timeout=_CAPABILITY_DISCOVERY_TIMEOUT_SECONDS,
@@ -479,6 +538,7 @@ async def _select_protocol(
protocol.value,
type(exc).__name__,
)
+>>>>>>> origin/main
continue
if required_capabilities <= capabilities:
capable_protocols.append(protocol)
@@ -608,6 +668,14 @@ async def initialize(self, config: dict[str, Any]) -> bool:
)
return False
+<<<<<<< HEAD
+ # Reject non-HTTPS or hostless base URLs. An attacker-influenced config
+ # could otherwise point requests at internal targets such as the cloud
+ # metadata endpoint (http://169.254.169.254) or file:// URIs (SSRF).
+ parsed = urlparse(base_url)
+ if parsed.scheme != "https" or not parsed.netloc:
+ logger.error("Unsafe OpenAI base_url rejected (must be HTTPS with a host)")
+=======
# DNS validation alone is vulnerable to rebinding between validation
# and the SDK connection. Trust only the official endpoint or an exact
# operator-managed allowlist entry, then retain the public-IP check as
@@ -622,6 +690,7 @@ async def initialize(self, config: dict[str, Any]) -> bool:
logger.error(
"Unsafe OpenAI base_url rejected (must be HTTPS and publicly routable)"
)
+>>>>>>> origin/main
return False
self.base_url = base_url
diff --git a/src/youtube_extension/services/agents/__init__.py b/src/youtube_extension/services/agents/__init__.py
index a811d261d..e87cd1824 100644
--- a/src/youtube_extension/services/agents/__init__.py
+++ b/src/youtube_extension/services/agents/__init__.py
@@ -12,49 +12,81 @@
try:
from .adapters.action_implementer_agent import ActionImplementerAgent
+<<<<<<< HEAD
except ImportError as exc:
+=======
+except ImportError as exc: # pragma: no cover
+>>>>>>> origin/main
ActionImplementerAgent = None
logger.warning("ActionImplementerAgent unavailable: %s", exc)
try:
from .adapters.agent_orchestrator import AgentOrchestrator
+<<<<<<< HEAD
except ImportError as exc:
+=======
+except ImportError as exc: # pragma: no cover
+>>>>>>> origin/main
AgentOrchestrator = None
logger.warning("AgentOrchestrator unavailable: %s", exc)
try:
from .adapters.hybrid_vision_agent import HybridVisionAgent
+<<<<<<< HEAD
except ImportError as exc:
+=======
+except ImportError as exc: # pragma: no cover
+>>>>>>> origin/main
HybridVisionAgent = None
logger.warning("HybridVisionAgent unavailable: %s", exc)
try:
from .adapters.personality_agent import PersonalityAgent
+<<<<<<< HEAD
except ImportError as exc:
+=======
+except ImportError as exc: # pragma: no cover
+>>>>>>> origin/main
PersonalityAgent = None
logger.warning("PersonalityAgent unavailable: %s", exc)
try:
from .adapters.strategy_agent import StrategyAgent
+<<<<<<< HEAD
except ImportError as exc:
+=======
+except ImportError as exc: # pragma: no cover
+>>>>>>> origin/main
StrategyAgent = None
logger.warning("StrategyAgent unavailable: %s", exc)
try:
from .adapters.transcript_action_agent import TranscriptActionAgent
+<<<<<<< HEAD
except ImportError as exc:
+=======
+except ImportError as exc: # pragma: no cover
+>>>>>>> origin/main
TranscriptActionAgent = None
logger.warning("TranscriptActionAgent unavailable: %s", exc)
try:
from .adapters.video_master_agent import VideoMasterAgent
+<<<<<<< HEAD
except ImportError as exc:
+=======
+except ImportError as exc: # pragma: no cover
+>>>>>>> origin/main
VideoMasterAgent = None
logger.warning("VideoMasterAgent unavailable: %s", exc)
try:
from .base_agent import BaseAgent
+<<<<<<< HEAD
except ImportError as exc:
+=======
+except ImportError as exc: # pragma: no cover
+>>>>>>> origin/main
BaseAgent = None
logger.warning("BaseAgent unavailable: %s", exc)
diff --git a/src/youtube_extension/services/mcp/orchestrator.py b/src/youtube_extension/services/mcp/orchestrator.py
index 6c63632b8..66dc5c4db 100644
--- a/src/youtube_extension/services/mcp/orchestrator.py
+++ b/src/youtube_extension/services/mcp/orchestrator.py
@@ -14,8 +14,11 @@
from datetime import datetime
from typing import Any, Optional
+<<<<<<< HEAD
+=======
import aiohttp
+>>>>>>> origin/main
from .registry import MCPServerRegistry, get_registry
from .types import MCPCapability, MCPTask, MCPTaskStatus
@@ -52,7 +55,10 @@ def __init__(self, registry: Optional[MCPServerRegistry] = None):
# Orchestration state
self.orchestration_active = False
self.orchestration_task: Optional[asyncio.Task] = None
+<<<<<<< HEAD
+=======
self._session: Optional[aiohttp.ClientSession] = None
+>>>>>>> origin/main
# Track spawned execution tasks by task_id for cancellation support
self.spawned_tasks: dict[str, asyncio.Task] = {}
@@ -341,11 +347,29 @@ async def _execute_on_server(
) -> dict[str, Any]:
"""
Execute task on a specific server via MCP/JSON-RPC.
+<<<<<<< HEAD
+
+ NOTE: Real MCP server communication is not yet implemented.
+ This method raises NotImplementedError to make it clear that the
+ orchestrator must not be used in production until this path is wired up.
+=======
+>>>>>>> origin/main
"""
config = self.registry.get_server(server_id)
if not config:
raise ValueError(f"Cannot execute task {task.task_id}: MCP server not found: {server_id}")
+<<<<<<< HEAD
+ logger.error(
+ "MCP server execution is not implemented: server_id=%s, task_type=%s",
+ server_id,
+ task.task_type,
+ )
+ raise NotImplementedError(
+ "MCPOrchestrator._execute_on_server is not implemented. "
+ "Wire up real MCP server communication before using this in production."
+ )
+=======
headers = {"Content-Type": "application/json"}
if config.auth_token:
headers["Authorization"] = f"Bearer {config.auth_token}"
@@ -384,6 +408,7 @@ async def _execute_on_server(
finally:
if own_session:
await session.close()
+>>>>>>> origin/main
async def _check_dependencies(self, task_id: str) -> bool:
"""
@@ -439,8 +464,11 @@ async def start_orchestration(self) -> None:
return
self.orchestration_active = True
+<<<<<<< HEAD
+=======
if self._session is None:
self._session = aiohttp.ClientSession()
+>>>>>>> origin/main
self.orchestration_task = asyncio.create_task(self._orchestration_loop())
logger.info("MCP Orchestration started")
@@ -471,10 +499,13 @@ async def stop_orchestration(self) -> None:
except asyncio.CancelledError:
pass
+<<<<<<< HEAD
+=======
if self._session:
await self._session.close()
self._session = None
+>>>>>>> origin/main
logger.info("MCP Orchestration stopped")
async def _orchestration_loop(self) -> None:
diff --git a/status.txt b/status.txt
new file mode 100644
index 000000000..05b4045df
--- /dev/null
+++ b/status.txt
@@ -0,0 +1,343 @@
+A .claude/settings.json
+M .env.example
+A .gitattributes
+A .github/aw/actions-lock.json
+M .github/pull_request_template.md
+M .github/workflows/AUDIT.md
+M .github/workflows/README.md
+M .github/workflows/autonomous-video-processing.yml
+A .github/workflows/canonical-pr-remediator.lock.yml
+A .github/workflows/canonical-pr-remediator.md
+M .github/workflows/ci.yml
+M .github/workflows/coverage.yml
+M .github/workflows/dependabot-auto-merge.yml
+A .github/workflows/eventrelay-ci-investigator.lock.yml
+A .github/workflows/eventrelay-ci-investigator.md
+A .github/workflows/focused-coverage-controller.lock.yml
+A .github/workflows/focused-coverage-controller.md
+A .github/workflows/gh-aw-validation.yml
+M .github/workflows/pr-checks.yml
+A .github/workflows/pr-governance.yml
+A .github/workflows/repository-reconciliation.yml
+M .github/workflows/verification.yml
+M .gitignore
+A .jules/agent_orchestration_sop.md
+M .jules/bolt.md
+A .jules/palette.md
+M .pre-commit-config.yaml
+M .vscode/extensions.json
+M .vscode/settings.json
+M CLAUDE.md
+M CONTRIBUTING.md
+M GEMINI.md
+M LAUNCH_CHECKLIST.md
+A Untitled-1.sql
+M apps/web/.env.example
+M apps/web/package.json
+A apps/web/playwright.config.ts
+A apps/web/playwright/smoke.spec.ts
+M apps/web/src/app/login/GoogleSignInButton.tsx
+M apps/web/src/app/login/page.tsx
+M apps/web/src/components/AgentFlowVisualizer.tsx
+M apps/web/src/components/InteractiveTranscript.tsx
+M apps/web/src/components/TranscriptViewer.tsx
+M apps/web/src/components/dashboard/panels.tsx
+M apps/web/src/components/video-generator.tsx
+A apps/web/src/lib/__tests__/error-handling-stack-safety.test.ts
+A apps/web/src/lib/__tests__/video-generator-accessibility.test.ts
+M apps/web/src/lib/auth.ts
+M apps/web/src/lib/error-handling.ts
+M apps/web/src/proxy.ts
+M docs/TECH_STACK.md
+M docs/agent-completion-truth-gate.md
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/activate-empty.body
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/activate-empty.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/activate-empty.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-csrf.body
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-csrf.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-csrf.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-providers.body
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-providers.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-providers.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-session.body
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-session.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/auth-session.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/billing-status.body
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/billing-status.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/billing-status.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/checkout-empty.body
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/checkout-empty.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/checkout-empty.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/checkout-token.body
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/checkout-token.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/checkout-token.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/meta.txt
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/renew-empty.body
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/renew-empty.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/renew-empty.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-badsig.body
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-badsig.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-badsig.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-empty.body
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-empty.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-empty.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-nosig.body
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-nosig.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T2011Z/webhook-nosig.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/activate-empty.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/activate-empty.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/auth-csrf.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/auth-csrf.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/auth-providers.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/auth-providers.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/auth-session.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/auth-session.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/billing-status.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/billing-status.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/checkout-empty.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/checkout-empty.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/checkout-token.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/checkout-token.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/meta.txt
+A docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/renew-empty.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/renew-empty.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/webhook-badsig.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/webhook-badsig.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/webhook-empty.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/webhook-empty.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/webhook-nosig.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T201717Z/webhook-nosig.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/REPORT.md
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/activate-empty.body
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/activate-empty.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/activate-empty.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/activate-empty.headers
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-csrf.body
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-csrf.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-csrf.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-csrf.headers
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-providers.body
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-providers.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-providers.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-providers.headers
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-session.body
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-session.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-session.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/auth-session.headers
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/billing-status.body
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/billing-status.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/billing-status.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/billing-status.headers
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-empty.body
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-empty.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-empty.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-empty.headers
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-token.body
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-token.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-token.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/checkout-token.headers
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/meta.txt
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/renew-empty.body
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/renew-empty.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/renew-empty.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/renew-empty.headers
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/renew-session-stripe.txt
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-badsig.body
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-badsig.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-badsig.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-badsig.headers
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-empty.body
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-empty.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-empty.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-empty.headers
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-nosig.body
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-nosig.code
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-nosig.err
+A docs/control-plane/sessions/gate3-reprobe-20260714T201739Z/webhook-nosig.headers
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/auth-providers.body
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/auth-providers.code
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/auth-providers.err
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/checkout.body
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/checkout.code
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/checkout.err
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-api.body
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-api.code
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-api.err
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-home.body
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-home.code
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-home.err
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-pipeline-get.body
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-pipeline-get.code
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/health-pipeline-get.err
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/meta.txt
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-dash.body
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-dash.code
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-dash.err
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-evil.body
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-evil.code
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-evil.err
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-ok.body
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-ok.code
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-ok.err
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-ssrf.body
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-ssrf.code
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/pipeline-ssrf.err
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/veo-free.body
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/veo-free.code
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/veo-free.err
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/vercel-prod-ls.txt
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/video-ssrf.body
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/video-ssrf.code
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/video-ssrf.err
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/webhook.body
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/webhook.code
+A docs/control-plane/sessions/reprobe-prod-20260710T1822Z/webhook.err
+A docs/control-plane/sessions/reprobe-prod-20260710T1828Z/REPORT.md
+A docs/control-plane/sessions/reprobe-prod-20260710T1828Z/health-api.body
+A docs/control-plane/sessions/reprobe-prod-20260710T1828Z/health-api.code
+A docs/control-plane/sessions/reprobe-prod-20260710T1828Z/health-api.err
+A docs/control-plane/sessions/reprobe-prod-20260710T1828Z/home-snippet.html
+A docs/control-plane/sessions/reprobe-prod-20260710T1828Z/meta.txt
+A docs/control-plane/sessions/reprobe-prod-20260710T1828Z/pipeline-dash.body
+A docs/control-plane/sessions/reprobe-prod-20260710T1828Z/pipeline-dash.code
+A docs/control-plane/sessions/reprobe-prod-20260710T1828Z/pipeline-dash.err
+A docs/control-plane/sessions/reprobe-prod-20260710T1828Z/pipeline-evil.body
+A docs/control-plane/sessions/reprobe-prod-20260710T1828Z/pipeline-evil.code
+A docs/control-plane/sessions/reprobe-prod-20260710T1828Z/pipeline-evil.err
+A docs/control-plane/sessions/reprobe-prod-20260710T1828Z/pipeline-ok.body
+A docs/control-plane/sessions/reprobe-prod-20260710T1828Z/pipeline-ok.code
+A docs/control-plane/sessions/reprobe-prod-20260710T1828Z/pipeline-ok.err
+A docs/control-plane/sessions/reprobe-prod-20260710T1828Z/pipeline-ssrf.body
+A docs/control-plane/sessions/reprobe-prod-20260710T1828Z/pipeline-ssrf.code
+A docs/control-plane/sessions/reprobe-prod-20260710T1828Z/pipeline-ssrf.err
+A docs/control-plane/sessions/reprobe-prod-20260710T1828Z/veo-free.body
+A docs/control-plane/sessions/reprobe-prod-20260710T1828Z/veo-free.code
+A docs/control-plane/sessions/reprobe-prod-20260710T1828Z/veo-free.err
+A docs/control-plane/sessions/reprobe-prod-20260710T1828Z/video-ssrf.body
+A docs/control-plane/sessions/reprobe-prod-20260710T1828Z/video-ssrf.code
+A docs/control-plane/sessions/reprobe-prod-20260710T1828Z/video-ssrf.err
+A docs/control-plane/sessions/smoke-internal-20260710T1858Z/dash.code
+A docs/control-plane/sessions/smoke-internal-20260710T1858Z/dash.err
+A docs/control-plane/sessions/smoke-internal-20260710T1858Z/evil.code
+A docs/control-plane/sessions/smoke-internal-20260710T1858Z/evil.err
+A docs/control-plane/sessions/smoke-internal-20260710T1858Z/nohdr-ssrf.code
+A docs/control-plane/sessions/smoke-internal-20260710T1858Z/nohdr-ssrf.err
+A docs/control-plane/sessions/smoke-internal-20260710T1858Z/ok.code
+A docs/control-plane/sessions/smoke-internal-20260710T1858Z/ok.err
+A docs/control-plane/sessions/smoke-internal-20260710T1858Z/ssrf.code
+A docs/control-plane/sessions/smoke-internal-20260710T1858Z/ssrf.err
+A docs/control-plane/sessions/smoke-internal-20260710T1858Z/veo.code
+A docs/control-plane/sessions/smoke-internal-20260710T1858Z/veo.err
+A docs/control-plane/sessions/smoke-internal-20260710T1858Z/video-ssrf.code
+A docs/control-plane/sessions/smoke-internal-20260710T1858Z/video-ssrf.err
+A docs/control-plane/sessions/smoke-internal-20260710T1904Z/REPORT.md
+A docs/control-plane/sessions/smoke-internal-20260710T1904Z/dash.body
+A docs/control-plane/sessions/smoke-internal-20260710T1904Z/dash.code
+A docs/control-plane/sessions/smoke-internal-20260710T1904Z/dash.err
+A docs/control-plane/sessions/smoke-internal-20260710T1904Z/evil.body
+A docs/control-plane/sessions/smoke-internal-20260710T1904Z/evil.code
+A docs/control-plane/sessions/smoke-internal-20260710T1904Z/evil.err
+A docs/control-plane/sessions/smoke-internal-20260710T1904Z/meta.txt
+A docs/control-plane/sessions/smoke-internal-20260710T1904Z/nohdr.body
+A docs/control-plane/sessions/smoke-internal-20260710T1904Z/nohdr.code
+A docs/control-plane/sessions/smoke-internal-20260710T1904Z/nohdr.err
+A docs/control-plane/sessions/smoke-internal-20260710T1904Z/ok.body
+A docs/control-plane/sessions/smoke-internal-20260710T1904Z/ok.code
+A docs/control-plane/sessions/smoke-internal-20260710T1904Z/ok.err
+A docs/control-plane/sessions/smoke-internal-20260710T1904Z/ssrf.body
+A docs/control-plane/sessions/smoke-internal-20260710T1904Z/ssrf.code
+A docs/control-plane/sessions/smoke-internal-20260710T1904Z/ssrf.err
+A docs/control-plane/sessions/smoke-internal-20260710T1904Z/veo.body
+A docs/control-plane/sessions/smoke-internal-20260710T1904Z/veo.code
+A docs/control-plane/sessions/smoke-internal-20260710T1904Z/veo.err
+A docs/control-plane/sessions/smoke-internal-20260710T1904Z/video-ssrf.body
+A docs/control-plane/sessions/smoke-internal-20260710T1904Z/video-ssrf.code
+A docs/control-plane/sessions/smoke-internal-20260710T1904Z/video-ssrf.err
+A docs/control-plane/sessions/ui-oauth-fix-20260715T0055Z/REPORT.md
+M docs/deployment/VERCEL_PRODUCTION_RUNBOOK.md
+M docs/knowledge_prototypes/mcp-servers/fetch-mcp/package-lock.json
+M docs/platform.md
+A eventrelay-audit-local/.audit-findings.json
+A eventrelay-audit-local/eventrelay-audit-report.md
+D package-lock.json
+M package.json
+M pyproject.toml
+M scripts/archive/software-on-demand/package-lock.json
+M scripts/archive/supabase_cleanup/package-lock.json
+M scripts/archive/supabase_cleanup/package.json
+A scripts/check_production_readiness.py
+A scripts/ci/autonomous_video_plan.py
+A scripts/ci/autonomous_video_processing.py
+A scripts/ci/autonomous_video_summary.py
+M src/agents/gemini_video_master_agent.py
+M src/agents/openai_dev_task_manager.py
+M src/agents/specialized/code_generator.py
+M src/mcp/mcp_ecosystem_coordinator.py
+M src/mcp/mcp_video_processor.py
+M src/utils/__init__.py
+M src/utils/path_utils.py
+M src/youtube_extension/backend/deploy/fly.py
+M src/youtube_extension/backend/deployment_manager.py
+M src/youtube_extension/backend/enhanced_video_processor.py
+M src/youtube_extension/backend/middleware/error_handling_middleware.py
+M src/youtube_extension/backend/middleware/rate_limiting.py
+M src/youtube_extension/backend/repositories/__init__.py
+M src/youtube_extension/backend/services/comparative_analysis.py
+M src/youtube_extension/backend/services/memory_manager.py
+M src/youtube_extension/core/config/__init__.py
+M src/youtube_extension/core/mcp/protocol_bridge.py
+M src/youtube_extension/services/agents/__init__.py
+M src/youtube_extension/services/mcp/orchestrator.py
+A strategy/bitmovin-ai-scene-analysis-assessment.md
+A strategy/competitive-positioning.md
+M tests/conftest.py
+A tests/load/k6_load_test.js
+M tests/test_gemini_video_master_agent.py
+M tests/test_sdk_python.py
+M tests/test_skills_integration.py
+M tests/testing/test_deployment_pipeline.py
+M tests/testing/test_transcript_action_workflow.py
+M tests/testing/test_video_processing_pipeline.py
+M tests/unit/test_500_info_disclosure.py
+M tests/unit/test_agent_completion_gate.py
+M tests/unit/test_agent_gap_analyzer.py
+M tests/unit/test_agent_monitor.py
+A tests/unit/test_autonomous_video_processing.py
+A tests/unit/test_autonomous_video_processing_workflow.py
+M tests/unit/test_backend_worker.py
+A tests/unit/test_cloud_ai.py
+M tests/unit/test_comparative_analysis.py
+M tests/unit/test_dependabot_automation_workflow.py
+M tests/unit/test_deployment_manager.py
+M tests/unit/test_enhanced_extractor.py
+M tests/unit/test_enhanced_video_processor.py
+M tests/unit/test_error_handling.py
+M tests/unit/test_gemini_grok_failover.py
+A tests/unit/test_gh_aw_workflow_governance.py
+M tests/unit/test_learning_tenant_models.py
+M tests/unit/test_master_roadmap_fixes.py
+M tests/unit/test_mcp_orchestrator.py
+M tests/unit/test_mcp_protocol_bridge.py
+M tests/unit/test_memory_manager.py
+M tests/unit/test_memory_optimizer.py
+M tests/unit/test_misc_services.py
+A tests/unit/test_optional_gemini_import.py
+M tests/unit/test_orchestrator_consumer.py
+M tests/unit/test_performance_benchmark_system.py
+A tests/unit/test_pr_governance_workflow.py
+M tests/unit/test_processors_strategies.py
+A tests/unit/test_production_readiness.py
+A tests/unit/test_proxy.py
+M tests/unit/test_real_processors.py
+A tests/unit/test_repository_reconciliation_workflow.py
+M tests/unit/test_robust_youtube_service.py
+M tests/unit/test_security_middleware.py
+M tests/unit/test_speech_to_text_service.py
+A tests/unit/test_test_harness_safety.py
+M tests/unit/test_transcript_action_workflow.py
+M tests/unit/test_v1_router_extended.py
+M tests/unit/test_video_processing_service.py
+A tests/unit/test_video_processor_facade.py
+M tests/unit/test_video_processor_factory.py
+M tests/unit/test_videopack.py
+?? status.txt
diff --git a/strategy/bitmovin-ai-scene-analysis-assessment.md b/strategy/bitmovin-ai-scene-analysis-assessment.md
new file mode 100644
index 000000000..f8fb21b89
--- /dev/null
+++ b/strategy/bitmovin-ai-scene-analysis-assessment.md
@@ -0,0 +1,142 @@
+# Bitmovin AI Scene Analysis Assessment
+
+Last updated: 2026-06-08
+
+## Decision
+
+Bitmovin AI Scene Analysis brings EventRelay some value, but narrowly.
+
+It should not become a core dependency or roadmap pivot. Its best use is as a reference point and optional upstream metadata source: Bitmovin can produce scene-level video metadata, and EventRelay can turn that kind of metadata into typed events, tasks, evidence, and downstream agent actions.
+
+Recommended priority: low implementation priority, medium strategy value, worth a small validation test.
+
+## Source Basis
+
+This assessment is grounded in:
+
+- Bitmovin's AI Scene Analysis product page: https://bitmovin.com/ai-scene-analysis/
+- Bitmovin AI Scene Analysis developer docs: https://developer.bitmovin.com/encoding/docs/ai-scene-analysis
+- Bitmovin getting-started docs: https://developer.bitmovin.com/encoding/docs/getting-started-with-ai-scene-analysis
+- Bitmovin AI Scene Analysis trial page: https://go.bitmovin.com/aisa_tofu
+- the current EventRelay competitive positioning brief in `docs/strategy/competitive-positioning.md`
+
+## Known Facts
+
+Bitmovin positions AI Scene Analysis as a VOD workflow feature integrated into its VOD Encoder. It generates scene-level metadata during encoding for uses such as contextual ad targeting, automated ad scheduling, highlight generation, recommendations, search, and playback navigation.
+
+Its developer docs say the output is JSON, available via API or storage output, and includes scene-level fields such as:
+
+- start and end timestamps
+- scene title and type
+- summary and verbose summary
+- characters, objects, settings, locations, and brands
+- atmosphere and visual context
+- keywords
+- sensitive topics
+- IAB taxonomies
+- asset-level descriptions, ratings, and classifications
+
+Its getting-started docs say AI Scene Analysis requires Bitmovin VOD Encoder v2.232.0 or later, can be enabled through a no-code VOD wizard or API configuration, and can process MP4, HLS, or DASH inputs.
+
+The trial page says users get 10 hours of AI Scene Analysis included each month, with pay-as-you-go usage at `$0.09` per input minute after that.
+
+## EventRelay Fit
+
+EventRelay is currently positioned around extracting transcripts, typed events, tasks, and agent-ready insights from video. Bitmovin is not the same product category: it is video infrastructure for VOD and streaming monetization.
+
+The useful overlap is not "video AI" in general. The useful overlap is structured, timestamped metadata.
+
+Bitmovin validates that video metadata can be a productized primitive. EventRelay can build on the same primitive without becoming an encoder, ad stack, or streaming platform.
+
+## Value To EventRelay
+
+### 1. Schema Inspiration
+
+Bitmovin's scene output suggests a useful shape for richer EventRelay moment records:
+
+```json
+{
+ "moment_id": "string",
+ "source_video_id": "string",
+ "start_seconds": 0,
+ "end_seconds": 0,
+ "transcript_span": {
+ "start_token": 0,
+ "end_token": 0
+ },
+ "event_type": "decision | task | claim | risk | topic_shift | evidence",
+ "summary": "string",
+ "visual_context": {
+ "objects": [],
+ "brands": [],
+ "settings": [],
+ "characters": [],
+ "atmosphere": []
+ },
+ "topics": [],
+ "sensitive_topics": [],
+ "actionability_score": 0,
+ "evidence": []
+}
+```
+
+This would let EventRelay connect transcript evidence to visual scene context when visual context matters.
+
+### 2. Optional Ingestion Adapter
+
+If a customer already uses Bitmovin, EventRelay could ingest Bitmovin's AI Scene Analysis JSON and treat it as an upstream evidence source.
+
+That avoids rebuilding video scene analysis while keeping EventRelay focused on the downstream value: typed events, tasks, routing, summaries, and agent workflows.
+
+### 3. Better Evaluation Target
+
+The practical question is not whether Bitmovin's output is impressive in isolation. The practical question is whether adding scene-level visual metadata improves EventRelay's current transcript-first extraction.
+
+Possible evaluation metrics:
+
+- higher recall of timestamped moments
+- fewer hallucinated event claims
+- better grounding for visual references
+- better segmentation of long-form videos
+- more useful downstream tasks
+
+## Non-Value
+
+Bitmovin should not be treated as a direct competitor. Their center of gravity is VOD infrastructure, encoding, streaming workflows, ad placement, and content discovery.
+
+Do not copy the ad-tech positioning unless EventRelay intentionally moves into streaming monetization. "IAB targeting", "SCTE markers", and "ad opportunity scoring" are valuable in Bitmovin's market, but they are not currently EventRelay's strongest wedge.
+
+Do not make claims about revenue lift, CPM lift, engagement lift, or better recommendations unless EventRelay has its own measured evidence.
+
+## Recommended Validation Test
+
+Run a small test before committing engineering time.
+
+1. Select three representative videos:
+ - one interview, podcast, or webinar
+ - one creator or market commentary video
+ - one visually dense product/demo video
+2. Run them through Bitmovin AI Scene Analysis using the free trial.
+3. Map the JSON output into the proposed EventRelay `moment` shape.
+4. Compare transcript-only EventRelay output against transcript-plus-scene output.
+5. Keep the integration only if it improves timestamp precision, event recall, visual grounding, or downstream task usefulness.
+
+## Positioning Takeaway
+
+Use this framing:
+
+> Bitmovin turns VOD libraries into scene metadata for streaming monetization. EventRelay turns video evidence into typed events, tasks, and operational follow-through.
+
+Shorter version:
+
+> Bitmovin validates scene metadata. EventRelay owns the downstream action layer.
+
+## Decision Boundary
+
+Build only if one of these becomes true:
+
+- a target customer already uses Bitmovin and wants EventRelay to consume its metadata
+- visual scene context materially improves EventRelay extraction quality in testing
+- EventRelay expands from YouTube/transcript-first workflows into broader VOD asset intelligence
+
+Otherwise, keep this as a useful reference, not a dependency.
diff --git a/strategy/competitive-positioning.md b/strategy/competitive-positioning.md
new file mode 100644
index 000000000..ec0624547
--- /dev/null
+++ b/strategy/competitive-positioning.md
@@ -0,0 +1,192 @@
+# EventRelay Competitive Positioning Brief
+
+Last updated: 2026-06-04
+
+## Objective
+
+Position EventRelay against video-generation tools by shifting the conversation away from "make more videos faster" and toward "extract verified, structured, actionable intelligence from video content."
+
+## Source Basis
+
+This brief is grounded in:
+
+- the current public `EventRelay` README
+- HyperFrames public docs and README
+- limited public third-party descriptions of UVAI, with weak verification
+
+Where competitor evidence is thin, this brief uses category-level critique instead of overconfident brand-specific claims.
+
+Related adjacent-market note: `docs/strategy/bitmovin-ai-scene-analysis-assessment.md` evaluates Bitmovin AI Scene Analysis as a potential metadata source, not a direct competitor.
+
+## Positioning Statement
+
+EventRelay is an AI video transcript capture and event extraction platform for teams that need evidence they can act on, not just more generated media. It turns YouTube content into word-for-word transcripts, typed events, actionable tasks, and agent-ready insights.
+
+## Category Thesis
+
+Most AI video tools optimize for production volume, remixing, or rendering workflow. EventRelay should compete on a different axis:
+
+- generation-first tools help produce content
+- EventRelay helps interpret content
+- generation-first tools promise output volume
+- EventRelay produces structured decisions and downstream actions
+
+This is the core message: more video does not automatically create more operational value.
+
+## What EventRelay Can Verify Today
+
+The following claims are supported by the current public README and should be safe to reuse:
+
+- EventRelay captures word-for-word transcripts from YouTube content.
+- It extracts structured events, actions, and topics using the OpenAI Responses API with strict JSON Schema mode.
+- It runs three Gemini-powered analysis paths for summary, personality mapping, and strategy.
+- It uses OpenAI STT as a fallback when YouTube captions are unavailable.
+- It exposes both a Next.js dashboard and FastAPI endpoints for processing, extraction, agent dispatch, and chat.
+
+## Claims To Avoid Until Proven
+
+Do not claim these without published evidence, benchmarks, or customer proof:
+
+- "best-in-class" extraction accuracy
+- higher conversion, engagement, or ROI than competitors
+- enterprise-grade reliability unless measured and documented
+- superior competitive performance against named tools unless the comparison is reproducible
+- full automation of business workflows beyond the tasks and endpoints the product actually ships today
+
+## Competitive Counter-Position
+
+### Against HyperFrames-style tooling
+
+HyperFrames is a rendering framework. Its value is HTML-first video production and deterministic rendering. That is a real capability, but it solves a different problem.
+
+Use this counter-position:
+
+> Rendering is useful once you already know what to say. EventRelay is for figuring out what matters inside the source material in the first place.
+
+Supporting points:
+
+- HyperFrames helps teams create video assets; EventRelay helps teams extract structured meaning from video inputs.
+- HyperFrames emphasizes authoring and rendering workflows; EventRelay emphasizes transcript fidelity, event extraction, and downstream actionability.
+- If a team needs typed outputs for agents, dashboards, or follow-on automation, EventRelay is closer to the operational bottleneck.
+
+### Against UVAI-style messaging
+
+Use caution here. The current UVAI public evidence is weak and difficult to verify from primary sources. That means the strongest critique is category-level, not brand-level.
+
+Use this counter-position:
+
+> Variant generation is only valuable if the underlying content decisions are sound. EventRelay focuses on extracting the decisions, tasks, and signals before teams spend cycles multiplying content.
+
+Supporting points:
+
+- claims about "uniqueness" or "more versions" are not the same as claims about better decisions
+- output multiplication can increase content volume without improving accuracy, prioritization, or execution
+- EventRelay can position itself as the system that identifies the moments worth operationalizing
+
+## Core Messaging Pillars
+
+### 1. Evidence Before Output
+
+EventRelay starts with the source material and pulls out what was actually said.
+
+Use language like:
+
+- "Start with the transcript, not the pitch."
+- "Ground decisions in the source video."
+- "Extract what happened before you generate what comes next."
+
+### 2. Structured Over Vague
+
+EventRelay does not stop at summaries. It returns typed events, actions, and topics that can feed software systems.
+
+Use language like:
+
+- "From transcript to typed events."
+- "Structured outputs for agents and automation."
+- "JSON you can route, not just prose you can read."
+
+### 3. Actionability Over Volume
+
+The product should be framed as an operational system, not a content toy.
+
+Use language like:
+
+- "Turn long-form video into tasks and signals."
+- "Find the moments that require follow-through."
+- "Move from watching content to executing against it."
+
+## Suggested Homepage Positioning
+
+### Hero Option A
+
+**Turn video into structured decisions.**
+
+Word-for-word transcripts, typed events, actionable tasks, and AI analysis for YouTube content.
+
+### Hero Option B
+
+**Don’t just generate more video. Extract what matters from the video you already have.**
+
+EventRelay converts YouTube content into transcripts, event data, tasks, and agent-ready insights.
+
+### Hero Option C
+
+**From video input to operational output.**
+
+Capture the transcript. Extract the events. Dispatch the next action.
+
+## One-Line Competitive Reframes
+
+- "Video generation creates assets. EventRelay creates usable intelligence."
+- "More variants are not the same as more value."
+- "If the goal is action, structured extraction beats raw content multiplication."
+- "Renderers help you publish. EventRelay helps you decide."
+
+## Audience Fit
+
+EventRelay is strongest for:
+
+- teams processing interviews, podcasts, webinars, or creator content for insights
+- operators who need action items and themes pulled from long-form video
+- agent workflows that need structured outputs instead of freeform summaries
+- product, research, media, or strategy teams that want evidence grounded in transcript data
+
+EventRelay is weaker as a pitch for:
+
+- teams primarily shopping for video rendering infrastructure
+- teams focused on motion design workflows
+- users whose main need is producing ad variants at scale
+
+## Proof-Oriented Comparison Frame
+
+When competitors lean on authority or broad marketing language, use this structure:
+
+Known fact:
+EventRelay documents transcript capture, structured event extraction, agent analysis, and API endpoints.
+
+Inference:
+It is better positioned as an analysis and operationalization layer than as a video creation layer.
+
+Uncertainty:
+There is no published benchmark yet proving extraction quality against competing tools.
+
+Next verification:
+Publish sample inputs and outputs, schema-quality tests, and end-to-end task completion examples.
+
+## Recommended Supporting Evidence To Build Next
+
+To make this positioning materially stronger, publish:
+
+- before-and-after examples: raw YouTube video to transcript to events to tasks
+- schema examples showing exactly what "typed events" means in practice
+- quality evals for extraction consistency
+- latency and failure-mode notes for transcript fallback behavior
+- one or two customer-style workflows that show downstream action, not just analysis
+
+## Internal Summary
+
+The sharpest truthful position is not "we make better videos." It is:
+
+> EventRelay helps teams turn video into structured operational intelligence.
+
+That claim is narrower, more defensible, and better aligned with the product that exists today.
diff --git a/test_direct_import.py b/test_direct_import.py
new file mode 100644
index 000000000..637e3c178
--- /dev/null
+++ b/test_direct_import.py
@@ -0,0 +1,3 @@
+import sys
+from src.mcp.mcp_video_processor import MCPVideoProcessor
+print("Direct import successful!")
diff --git a/test_import.py b/test_import.py
new file mode 100644
index 000000000..8ce2fcd2b
--- /dev/null
+++ b/test_import.py
@@ -0,0 +1,9 @@
+import sys
+from src.agents.openai_dev_task_manager import OpenAIDevTaskManager
+
+try:
+ m = OpenAIDevTaskManager()
+ m._load_mcp_video_processor()
+ print("Success")
+except Exception as e:
+ print(f"Failed: {type(e).__name__}: {e}")
diff --git a/test_script.py b/test_script.py
new file mode 100644
index 000000000..65ca0fc71
--- /dev/null
+++ b/test_script.py
@@ -0,0 +1,11 @@
+import sys
+
+def check_task_description():
+ with open('src/agents/openai_dev_task_manager.py', 'r') as f:
+ lines = f.readlines()
+ print("Lines 10-16 in file:")
+ for i, line in enumerate(lines[9:16]):
+ print(f"{i+10}: {line.strip()}")
+
+if __name__ == "__main__":
+ check_task_description()
diff --git a/tests/conftest.py b/tests/conftest.py
index 9ff9d1699..9602228e6 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -15,6 +15,9 @@
"""
import os
+<<<<<<< HEAD
+import sys
+=======
import socket
import sys
from pathlib import Path
@@ -116,6 +119,7 @@ def pytest_ignore_collect(collection_path: Path, config: object) -> bool:
if not _enabled("RUN_LIVE_E2E"):
return True
return test_path in _LIVE_DEPLOY_TESTS and not _enabled("RUN_LIVE_DEPLOY")
+>>>>>>> origin/main
# Ensure the repository root is importable so `src` resolves as a real package.
_REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@@ -145,6 +149,33 @@ def pytest_ignore_collect(collection_path: Path, config: object) -> bool:
except Exception:
pass
+<<<<<<< HEAD
# Enable dev-mode auth bypass unless the environment already configures auth.
if not os.getenv("EVENTRELAY_API_KEY"):
os.environ.setdefault("ALLOW_UNAUTHENTICATED", "1")
+=======
+# Enable dev-mode auth bypass for tests by default.
+# We set EVENTRELAY_API_KEY to empty string to override any .env file setting,
+# unless it was explicitly configured in the shell environment.
+# Since main.py loads .env with override=False, setting EVENTRELAY_API_KEY to ""
+# in os.environ before main.py imports will prevent it from loading the real key.
+# We also wrap dotenv.load_dotenv in case any module calls it with override=True later.
+if "EVENTRELAY_API_KEY" not in os.environ:
+ os.environ["EVENTRELAY_API_KEY"] = ""
+ os.environ["ALLOW_UNAUTHENTICATED"] = "1"
+
+ try:
+ import dotenv
+ _real_load_dotenv = dotenv.load_dotenv
+
+ def _wrapped_load_dotenv(*args, **kwargs):
+ res = _real_load_dotenv(*args, **kwargs)
+ os.environ["EVENTRELAY_API_KEY"] = ""
+ os.environ["ALLOW_UNAUTHENTICATED"] = "1"
+ return res
+
+ dotenv.load_dotenv = _wrapped_load_dotenv
+ except ImportError:
+ pass
+
+>>>>>>> origin/main
diff --git a/tests/test_gemini_video_master_agent.py b/tests/test_gemini_video_master_agent.py
index 95abb1976..372428205 100644
--- a/tests/test_gemini_video_master_agent.py
+++ b/tests/test_gemini_video_master_agent.py
@@ -8,6 +8,8 @@
from agents import gemini_video_master_agent as master
+<<<<<<< HEAD
+=======
@pytest.fixture(autouse=True)
def _isolate_gemini_sdk_client(monkeypatch):
"""Keep unit tests from constructing the SDK's real HTTP transport."""
@@ -19,6 +21,7 @@ def _isolate_gemini_sdk_client(monkeypatch):
)
+>>>>>>> origin/main
def test_task_delegation_uses_current_gemini_models(monkeypatch):
monkeypatch.delenv("GOOGLE_API_KEY", raising=False)
monkeypatch.delenv("GEMINI_API_KEY", raising=False)
diff --git a/tests/test_sdk_python.py b/tests/test_sdk_python.py
index 01681f8df..409b8d4b2 100644
--- a/tests/test_sdk_python.py
+++ b/tests/test_sdk_python.py
@@ -9,7 +9,10 @@
import sys
from pathlib import Path
+<<<<<<< HEAD
+=======
from unittest.mock import MagicMock
+>>>>>>> origin/main
import pytest
@@ -66,6 +69,8 @@ def handler(request: httpx.Request) -> httpx.Response:
return httpx.MockTransport(handler)
+<<<<<<< HEAD
+=======
def _unconnected_client(**kwargs) -> EventRelayClient:
"""Build a configuration-only client without creating a real transport."""
return EventRelayClient(
@@ -74,6 +79,7 @@ def _unconnected_client(**kwargs) -> EventRelayClient:
)
+>>>>>>> origin/main
# ---------------------------------------------------------------------------
# Type model tests
# ---------------------------------------------------------------------------
@@ -429,6 +435,25 @@ def _make_client(self, routes: dict) -> EventRelayClient:
)
def test_client_default_base_url(self) -> None:
+<<<<<<< HEAD
+ client = EventRelayClient()
+ assert "uvai.io" in client._base_url
+
+ def test_client_custom_base_url(self) -> None:
+ client = EventRelayClient(base_url="http://localhost:9000")
+ assert client._base_url == "http://localhost:9000"
+
+ def test_client_strips_trailing_slash(self) -> None:
+ client = EventRelayClient(base_url="http://localhost:8000/")
+ assert not client._base_url.endswith("/")
+
+ def test_client_api_key_in_headers(self) -> None:
+ client = EventRelayClient(api_key="secret-key")
+ assert client._headers()["X-API-Key"] == "secret-key"
+
+ def test_client_no_api_key_header_absent(self) -> None:
+ client = EventRelayClient(api_key="")
+=======
client = _unconnected_client()
assert "uvai.io" in client._base_url
@@ -446,6 +471,7 @@ def test_client_api_key_in_headers(self) -> None:
def test_client_no_api_key_header_absent(self) -> None:
client = _unconnected_client(api_key="")
+>>>>>>> origin/main
assert "X-API-Key" not in client._headers()
def test_videos_process(self) -> None:
diff --git a/tests/test_skills_integration.py b/tests/test_skills_integration.py
index 560ecd88e..8db132f2a 100644
--- a/tests/test_skills_integration.py
+++ b/tests/test_skills_integration.py
@@ -34,6 +34,25 @@
_agents_pkg.__package__ = "agents"
sys.modules["agents"] = _agents_pkg
+<<<<<<< HEAD
+# Stub youtube_extension.processors to avoid pulling in heavy ML deps
+for _mod_name in [
+ "youtube_extension",
+ "youtube_extension.processors",
+ "youtube_extension.processors.enhanced_extractor",
+]:
+ if _mod_name not in sys.modules:
+ _stub = types.ModuleType(_mod_name)
+ _stub.__path__ = [] # type: ignore[attr-defined]
+ _stub.__package__ = _mod_name
+ # Provide stub classes so the coordinator imports fine
+ if _mod_name == "youtube_extension.processors.enhanced_extractor":
+ _stub.EnhancedVideoExtractor = type("EnhancedVideoExtractor", (), {}) # type: ignore[attr-defined]
+ _stub.VideoContent = type("VideoContent", (), {}) # type: ignore[attr-defined]
+ sys.modules[_mod_name] = _stub
+
+=======
+>>>>>>> origin/main
# Now we can safely import just the coordinator module
from agents.mcp_ecosystem_coordinator import SkillRegistry # noqa: E402
@@ -106,6 +125,8 @@ def test_get_nonexistent_skill_returns_none(self, registry: SkillRegistry) -> No
# ---------------------------------------------------------------------------
+<<<<<<< HEAD
+=======
def test_skill_import_does_not_replace_processor_package() -> None:
"""The integration test must not poison later test-module collection."""
from youtube_extension.processors import strategies
@@ -113,6 +134,7 @@ def test_skill_import_does_not_replace_processor_package() -> None:
assert strategies.__file__ is not None
+>>>>>>> origin/main
class TestSkillTriggerMatching:
"""Verify trigger-based skill discovery."""
diff --git a/tests/testing/test_deployment_pipeline.py b/tests/testing/test_deployment_pipeline.py
index 712df9c0c..921a88ae8 100644
--- a/tests/testing/test_deployment_pipeline.py
+++ b/tests/testing/test_deployment_pipeline.py
@@ -5,6 +5,20 @@
"""
import asyncio
+<<<<<<< HEAD
+import pytest
+import os
+import tempfile
+from pathlib import Path
+from unittest.mock import Mock, patch, AsyncMock
+
+from youtube_extension.services.deployment_manager import DeploymentManager, validate_deployment_environment
+from youtube_extension.backend.deploy.core import EnvironmentValidator, DeploymentError
+from youtube_extension.backend.deploy.vercel import VercelAdapter
+from youtube_extension.backend.deploy.netlify import NetlifyAdapter
+from youtube_extension.backend.deploy.fly import FlyAdapter
+from youtube_extension.backend.deploy import get_adapter_class, list_available_adapters, is_adapter_available
+=======
import os
from unittest.mock import AsyncMock, patch
@@ -24,6 +38,7 @@
validate_deployment_environment,
)
+>>>>>>> origin/main
@pytest.fixture
def sample_project_config():
@@ -186,6 +201,16 @@ def test_app_name_generation_fly(self):
assert result.startswith(f'uvai-{expected_prefix[5:]}'), f"Unexpected result: {result}"
assert len(result) <= 30, f"App name too long: {result}"
+<<<<<<< HEAD
+ @pytest.mark.asyncio
+ async def test_deployment_manager_orchestration(self, sample_project_config, sample_env):
+ """Test deployment manager orchestration"""
+ manager = DeploymentManager()
+
+ # Test deployment with missing tokens (should be skipped gracefully)
+ result = await manager.deploy_project(
+ '/tmp/nonexistent',
+=======
with patch(
'youtube_extension.backend.deploy.fly.time.monotonic',
return_value=12345.67,
@@ -208,6 +233,7 @@ async def test_deployment_manager_orchestration(
# a build or making a real deployment.
result = await manager.deploy_project(
str(tmp_path),
+>>>>>>> origin/main
sample_project_config,
{'target': 'vercel'}
)
@@ -223,6 +249,37 @@ async def test_deployment_manager_orchestration(
assert 'GitHub token not configured' in result['errors']
@pytest.mark.asyncio
+<<<<<<< HEAD
+ async def test_mixed_deployment_scenario(self, sample_project_config, sample_env):
+ """Test mixed deployment scenario with some tokens available"""
+ # Set fake tokens for testing
+ os.environ['VERCEL_TOKEN'] = 'fake_token_for_testing'
+ os.environ['GITHUB_TOKEN'] = 'fake_github_token'
+
+ try:
+ manager = DeploymentManager()
+
+ result = await manager.deploy_project(
+ '/tmp',
+ sample_project_config,
+ {'target': 'vercel'}
+ )
+
+ # Should have attempted both GitHub and Vercel deployments
+ assert 'github' in result['deployments']
+ assert 'vercel' in result['deployments']
+
+ # Vercel should have failed due to invalid token (but not crashed)
+ vercel_result = result['deployments']['vercel']
+ assert 'status' in vercel_result
+
+ finally:
+ # Clean up fake tokens
+ if 'VERCEL_TOKEN' in os.environ:
+ del os.environ['VERCEL_TOKEN']
+ if 'GITHUB_TOKEN' in os.environ:
+ del os.environ['GITHUB_TOKEN']
+=======
async def test_mixed_deployment_scenario(
self, sample_project_config, tmp_path
):
@@ -348,6 +405,7 @@ async def test_early_build_failure_preserves_summary_contract(
]
deploy_github.assert_not_awaited()
deploy_adapter.assert_not_awaited()
+>>>>>>> origin/main
@pytest.mark.asyncio
async def test_error_recovery_and_reporting(self, sample_project_config, sample_env):
@@ -436,7 +494,11 @@ def test_environment_validator_comprehensive(self):
def test_adapter_registry_integrity(self):
"""Test that adapter registry is properly maintained"""
+<<<<<<< HEAD
+ from youtube_extension.backend.deploy import _adapters, _adapter_classes
+=======
from youtube_extension.backend.deploy import _adapter_classes, _adapters
+>>>>>>> origin/main
# Check legacy adapters
assert 'vercel' in _adapters
@@ -449,7 +511,11 @@ def test_adapter_registry_integrity(self):
assert 'fly' in _adapter_classes
# Verify class references are properly formatted
+<<<<<<< HEAD
+ for adapter_name, class_ref in _adapter_classes.items():
+=======
for _adapter_name, class_ref in _adapter_classes.items():
+>>>>>>> origin/main
assert ':' in class_ref
module_path, class_name = class_ref.split(':')
assert module_path.startswith('youtube_extension.backend.deploy.')
diff --git a/tests/testing/test_transcript_action_workflow.py b/tests/testing/test_transcript_action_workflow.py
index eb6b0513b..9c8b51b3f 100644
--- a/tests/testing/test_transcript_action_workflow.py
+++ b/tests/testing/test_transcript_action_workflow.py
@@ -2,6 +2,13 @@
import pytest
+<<<<<<< HEAD
+from youtube_extension.services.workflows.transcript_action_workflow import TranscriptActionWorkflow
+from src.shared.youtube import RobustYouTubeMetadata
+from youtube_extension.services.ai.speech_to_text_service import SpeechToTextResult
+from youtube_extension.services.agents.adapters.agent_orchestrator import OrchestrationResult
+from youtube_extension.services.agents.dto import AgentResult
+=======
from src.shared.youtube import RobustYouTubeMetadata
from youtube_extension.services.agents.adapters.agent_orchestrator import OrchestrationResult
from youtube_extension.services.agents.dto import AgentResult
@@ -27,6 +34,7 @@ def _isolate_skill_builder(monkeypatch, tmp_path):
"youtube_extension.services.workflows.transcript_action_workflow.get_skill_builder",
lambda: skill_builder,
)
+>>>>>>> origin/main
class _StubYouTubeService:
diff --git a/tests/testing/test_video_processing_pipeline.py b/tests/testing/test_video_processing_pipeline.py
index a13adf629..f79a6dc1b 100644
--- a/tests/testing/test_video_processing_pipeline.py
+++ b/tests/testing/test_video_processing_pipeline.py
@@ -1,3 +1,49 @@
+<<<<<<< HEAD
+"""
+Integration tests for the complete video processing pipeline
+Tests end-to-end workflows from video URL input to action generation
+"""
+
+import pytest
+import asyncio
+import json
+from unittest.mock import Mock, patch, AsyncMock
+from types import SimpleNamespace
+import httpx
+from httpx import ASGITransport
+from starlette.testclient import TestClient
+import tempfile
+import os
+from datetime import datetime
+
+# Import components for integration testing
+import sys
+from pathlib import Path
+project_root = Path(__file__).parent.parent.parent
+# REMOVED: sys.path.insert for project_root
+
+# Mock FastAPI app if not available
+try:
+ from src.youtube_extension.backend.main_v2 import app
+ from src.youtube_extension.backend.enhanced_video_processor import EnhancedVideoProcessor
+ from src.youtube_extension.mcp.enterprise_mcp_server import EnterpriseMCPServer
+except ImportError:
+ from fastapi import FastAPI
+ app = FastAPI()
+
+ class EnhancedVideoProcessor:
+ async def process_video(self, url):
+ return {"status": "mock"}
+
+ class EnterpriseMCPServer:
+ async def handle_request(self, request):
+ return {"jsonrpc": "2.0", "result": {}, "id": request.get("id")}
+
+import pytest_asyncio
+
+@pytest_asyncio.fixture
+async def async_client():
+=======
"""Contract tests for the production v1 video-processing HTTP route.
The processing service is replaced at FastAPI's dependency boundary, so these
@@ -49,6 +95,7 @@ def video_service(monkeypatch):
@pytest_asyncio.fixture
async def async_client(video_service):
+>>>>>>> origin/main
"""Create async HTTP client for API testing (httpx >= 0.25)."""
transport = ASGITransport(app=app)
async with httpx.AsyncClient(transport=transport, base_url="http://test") as client:
@@ -94,7 +141,11 @@ def expected_actions():
"title": "Implement Higher Order Component pattern",
"description": "Create a HOC for adding authentication logic",
"category": "Implementation",
+<<<<<<< HEAD
"priority": "medium",
+=======
+ "priority": "medium",
+>>>>>>> origin/main
"estimated_time": "25 minutes",
"timestamp": 300,
"prerequisites": ["action_1"],
@@ -112,6 +163,276 @@ def expected_transcript():
SimpleNamespace(start=16.5, duration=7.1, text="We'll start by creating a new React application")
]
+<<<<<<< HEAD
+class TestVideoProcessingPipeline:
+ """Test complete video processing pipeline integration"""
+
+ @pytest.mark.integration
+ @pytest.mark.asyncio
+ async def test_complete_pipeline_success(self, async_client, sample_video_url, expected_video_data, expected_actions, expected_transcript):
+ """Test successful end-to-end video processing"""
+ metadata_response = {**expected_video_data, 'video_id': expected_video_data['id']}
+
+ with patch('yt_dlp.YoutubeDL') as mock_ydl, \
+ patch('youtube_transcript_api.YouTubeTranscriptApi.fetch') as mock_transcript, \
+ patch('google.generativeai.GenerativeModel') as mock_gemini, \
+ patch('src.youtube_extension.backend.enhanced_video_processor.EnhancedVideoProcessor._analyze_with_gemini', new=AsyncMock(return_value={
+ 'actions': expected_actions,
+ 'Content Summary': 'Comprehensive React patterns tutorial',
+ 'Difficulty Level': 'Intermediate'
+ })) as mock_ai, \
+ patch('src.youtube_extension.backend.enhanced_video_processor.EnhancedVideoProcessor._get_video_metadata', new=AsyncMock(return_value=metadata_response)):
+
+ # Mock external service responses
+ mock_ydl.return_value.extract_info.return_value = expected_video_data
+ mock_ydl.return_value.__enter__.return_value = mock_ydl.return_value
+ mock_ydl.return_value.__enter__.return_value.extract_info.return_value = expected_video_data
+ mock_transcript.return_value = expected_transcript
+ mock_gemini.return_value.generate_content.return_value.text = json.dumps({
+ "actions": expected_actions,
+ "summary": "Comprehensive React patterns tutorial",
+ "difficulty_level": "intermediate"
+ })
+
+ # Make API request
+ response = await async_client.post("/api/v1/process-video", json={
+ "video_url": sample_video_url,
+ "options": {
+ "quality": "high",
+ "generate_actions": True,
+ "include_transcript": True
+ }
+ })
+
+ # Verify response structure
+ assert response.status_code == 200
+ data = response.json()
+
+ assert "video_data" in data
+ assert "actions" in data
+ assert "transcript" in data
+ assert "processing_time" in data
+ assert "quality_score" in data
+
+ # Verify video data
+ video_data = data["video_data"]
+ video_identifier = video_data.get("id") or video_data.get("video_id")
+ assert video_identifier == "jNQXAC9IVRw"
+ assert video_data["title"] == expected_video_data["title"]
+ assert video_data["duration"] == expected_video_data["duration"]
+
+ # Verify actions
+ actions = data["actions"]
+ assert len(actions) == 2
+ assert actions[0]["title"] == "Set up React development environment"
+ assert actions[0]["priority"] == "high"
+
+ # Verify transcript
+ transcript = data["transcript"]
+ assert len(transcript) == 4
+ assert transcript[0]["text"] == "Welcome to this React patterns tutorial"
+
+ # Verify quality metrics
+ assert data["quality_score"] >= 0.8 # High quality threshold
+ processing_time = data["processing_time"]
+ if isinstance(processing_time, (int, float)):
+ assert processing_time > 0
+ else:
+ assert isinstance(processing_time, str)
+ assert processing_time
+
+ @pytest.mark.integration
+ @pytest.mark.asyncio
+ async def test_pipeline_with_caching(self, async_client, sample_video_url):
+ """Test pipeline behavior with caching enabled"""
+ with patch('src.youtube_extension.backend.enhanced_video_processor.EnhancedVideoProcessor.get_cached_result') as mock_cache:
+ cached_result = {
+ "video_data": {"id": "cached_video", "title": "Cached Video"},
+ "actions": [{"id": "cached_action", "title": "Cached Action"}],
+ "transcript": [{"text": "Cached transcript"}],
+ "processing_time": 0.1, # Very fast due to cache
+ "quality_score": 0.95,
+ "cached": True
+ }
+ mock_cache.return_value = cached_result
+
+ response = await async_client.post("/api/v1/process-video", json={
+ "video_url": sample_video_url
+ })
+
+ assert response.status_code == 200
+ data = response.json()
+ assert data["cached"] is True
+ assert data["processing_time"] < 1.0 # Should be very fast
+
+ @pytest.mark.integration
+ @pytest.mark.asyncio
+ async def test_pipeline_error_handling(self, async_client, sample_video_url):
+ """Test pipeline error handling and graceful degradation"""
+ with patch('yt_dlp.YoutubeDL') as mock_ydl:
+ mock_ydl.return_value.extract_info.side_effect = Exception("Video not found")
+ mock_ydl.return_value.__enter__.return_value = mock_ydl.return_value
+ mock_ydl.return_value.__enter__.return_value.extract_info.side_effect = Exception("Video not found")
+
+ response = await async_client.post("/api/v1/process-video", json={
+ "video_url": sample_video_url
+ })
+
+ data = response.json()
+ if response.status_code == 200:
+ # Graceful degradation: minimal metadata, no actions
+ assert data["video_data"]["id"] == "jNQXAC9IVRw"
+ assert data["actions"] == []
+ transcript = data.get("transcript", [])
+ # Robust pipeline may still salvage a small transcript from fallbacks.
+ assert len(transcript) <= 10
+ if transcript:
+ assert all("text" in segment for segment in transcript)
+ assert data["quality_score"] <= 0.8
+ else:
+ assert response.status_code == 400
+ assert "error" in data
+ assert "video not found" in data["error"].lower()
+
+ @pytest.mark.integration
+ @pytest.mark.asyncio
+ async def test_pipeline_partial_failure(self, async_client, sample_video_url, expected_video_data):
+ """Test pipeline with partial service failures"""
+ with patch('yt_dlp.YoutubeDL') as mock_ydl, \
+ patch('youtube_transcript_api.YouTubeTranscriptApi.fetch') as mock_transcript, \
+ patch('google.generativeai.GenerativeModel') as mock_gemini:
+
+ # Video metadata succeeds
+ mock_ydl.return_value.extract_info.return_value = expected_video_data
+ mock_ydl.return_value.__enter__.return_value = mock_ydl.return_value
+ mock_ydl.return_value.__enter__.return_value.extract_info.return_value = expected_video_data
+
+ # Transcript fails
+ from youtube_transcript_api import NoTranscriptFound
+ mock_transcript.side_effect = NoTranscriptFound("jNQXAC9IVRw", [], None)
+
+ # Gemini succeeds but with basic response
+ mock_gemini.return_value.generate_content.return_value.text = json.dumps({
+ "actions": [],
+ "summary": "Could not generate detailed actions without transcript"
+ })
+
+ response = await async_client.post("/api/v1/process-video", json={
+ "video_url": sample_video_url
+ })
+
+ # Should succeed with partial data
+ assert response.status_code == 200
+ data = response.json()
+
+ assert "video_data" in data
+ assert data["video_data"]["id"] == "jNQXAC9IVRw"
+ assert data["transcript"] == [] # Empty due to failure
+ assert len(data["actions"]) == 0 # Basic actions only
+ assert data["quality_score"] < 0.8 # Lower quality due to missing transcript
+
+# class TestWebSocketIntegration:
+# """Test WebSocket integration for real-time updates"""
+
+# @pytest.mark.integration
+# def test_websocket_video_processing_updates(self):
+# """WebSocket basic flow using Starlette TestClient (ping + chat)."""
+# client = httpx.Client(app=app, base_url="http://test")
+# with client.websocket_connect("/ws") as websocket:
+# # Welcome
+# welcome = json.loads(websocket.receive_text())
+# assert welcome["type"] == "connection"
+# assert welcome["status"] == "connected"
+
+# # Ping/Pong
+# websocket.send_text(json.dumps({"type": "ping", "data": {"n": 1}}))
+# pong = json.loads(websocket.receive_text())
+# assert pong["type"] == "pong"
+
+# # Chat
+# websocket.send_text(json.dumps({"type": "chat", "message": "hello"}))
+# reply = json.loads(websocket.receive_text())
+# assert reply["type"] == "chat_response"
+
+# @pytest.mark.integration
+# def test_websocket_error_handling(self):
+# """WebSocket error handling for missing video URL."""
+# client = httpx.Client(app=app, base_url="http://test")
+# with client.websocket_connect("/ws") as websocket:
+# _ = json.loads(websocket.receive_text()) # drain welcome
+# websocket.send_text(json.dumps({"type": "video_processing", "video_url": ""}))
+# error_reply = json.loads(websocket.receive_text())
+# assert error_reply["type"] == "error"
+# assert error_reply["error_type"] == "missing_video_url"
+
+# class TestMCPIntegration:
+# """Test MCP server integration"""
+
+# @pytest.mark.integration
+# @pytest.mark.asyncio
+# async def test_mcp_tools_list(self):
+# """Test MCP tools/list endpoint"""
+# mcp_server = EnterpriseMCPServer()
+
+# request = {
+# "jsonrpc": "2.0",
+# "method": "tools/list",
+# "id": "test_123"
+# }
+
+# response = await mcp_server.handle_request(request)
+
+# assert response["jsonrpc"] == "2.0"
+# assert response["id"] == "test_123"
+# assert "result" in response
+# assert "tools" in response["result"]
+
+# tools = response["result"]["tools"]
+# tool_names = [tool["name"] for tool in tools]
+# assert "process_video" in tool_names
+# assert "get_video_info" in tool_names
+# assert "generate_actions" in tool_names
+
+# @pytest.mark.integration
+# @pytest.mark.asyncio
+# async def test_mcp_process_video_tool(self, expected_video_data, expected_actions):
+# """Test MCP process_video tool"""
+# mcp_server = EnterpriseMCPServer()
+
+# with patch('src.youtube_extension.backend.enhanced_video_processor.EnhancedVideoProcessor.process_video') as mock_process:
+# mock_process.return_value = {
+# "video_data": expected_video_data,
+# "actions": expected_actions,
+# "transcript": [],
+# "quality_score": 0.92
+# }
+
+# request = {
+# "jsonrpc": "2.0",
+# "method": "tools/call",
+# "params": {
+# "name": "process_video",
+# "arguments": {
+# "video_url": "https://youtube.com/watch?v=test123"
+# }
+# },
+# "id": "mcp_test_123"
+# }
+
+# response = await mcp_server.handle_request(request)
+
+# assert response["jsonrpc"] == "2.0"
+# assert response["id"] == "mcp_test_123"
+# assert "result" in response
+
+# result = response["result"]
+# assert result.get("ok") is True
+
+class TestDatabaseIntegration:
+ """Test database integration for storing results"""
+
+
+=======
class TestVideoProcessingApiContract:
"""Verify the public HTTP contract against the real production router."""
@@ -254,11 +575,203 @@ async def test_partial_service_result_is_preserved(
class TestDatabaseIntegration:
"""Test database integration for storing results"""
+>>>>>>> origin/main
@pytest.mark.integration
@pytest.mark.asyncio
@pytest.mark.database
async def test_action_status_update(self, async_client):
+<<<<<<< HEAD
+ """Test updating action completion status"""
+ with patch('src.backend.repositories.action_repository.ActionRepository.update') as mock_update:
+ mock_update.return_value = True
+
+ response = await async_client.put("/api/v1/actions/action_123", json={
+ "completed": True,
+ "notes": "Completed successfully"
+ })
+
+ assert response.status_code == 200
+ data = response.json()
+ assert isinstance(data, dict)
+
+class TestPerformanceIntegration:
+ """Test performance characteristics in integration scenarios"""
+
+ @pytest.mark.integration
+ @pytest.mark.performance
+ @pytest.mark.asyncio
+ async def test_concurrent_video_processing(self, async_client):
+ """Test concurrent video processing requests"""
+ video_urls = [
+ "https://youtube.com/watch?v=test1",
+ "https://youtube.com/watch?v=test2",
+ "https://youtube.com/watch?v=test3",
+ "https://youtube.com/watch?v=test4",
+ "https://youtube.com/watch?v=test5"
+ ]
+
+ with patch('src.youtube_extension.backend.enhanced_video_processor.EnhancedVideoProcessor.process_video') as mock_process:
+ mock_process.return_value = {
+ "video_data": {"id": "test", "title": "Test Video"},
+ "actions": [],
+ "transcript": [],
+ "quality_score": 0.85
+ }
+
+ # Create concurrent requests
+ tasks = []
+ for url in video_urls:
+ task = async_client.post("/api/v1/process-video", json={
+ "video_url": url
+ })
+ tasks.append(task)
+
+ # Execute concurrently
+ responses = await asyncio.gather(*tasks)
+ statuses = [r.status_code for r in responses]
+ assert all(status in (200, 422, 429, 500, 503) for status in statuses)
+ assert len(responses) == 5
+
+ @pytest.mark.skip(reason="Performance test failing, to be addressed in a separate PR")
+ @pytest.mark.integration
+ @pytest.mark.performance
+ @pytest.mark.asyncio
+ async def test_response_time_requirements(self, async_client, sample_video_url):
+ """Test response time meets requirements"""
+ import time
+
+ start_time = time.time()
+ response = await async_client.post("/api/v1/process-video", json={
+ "video_url": sample_video_url
+ })
+ end_time = time.time()
+
+ processing_time = end_time - start_time
+
+ if response.status_code == 200:
+ # Processing should complete within reasonable time
+ assert processing_time < 120 # 2 minutes max
+
+ # API response should be fast even if processing takes time
+ assert processing_time < 5 # API should respond within 5 seconds
+
+class TestQualityAssessmentIntegration:
+ """Test quality assessment integration across pipeline"""
+
+ @pytest.mark.integration
+ @pytest.mark.asyncio
+ async def test_high_quality_processing_detection(self, async_client, sample_video_url):
+ """Test detection of high-quality processing results"""
+ with patch('src.youtube_extension.backend.enhanced_video_processor.EnhancedVideoProcessor.process_video') as mock_process:
+ # High quality result
+ mock_process.return_value = {
+ "video_data": {
+ "id": "test123",
+ "title": "Comprehensive Programming Tutorial",
+ "channel": "Education Hub",
+ "duration": "25:30",
+ "view_count": 250000
+ },
+ "actions": [
+ {
+ "id": "action_1",
+ "title": "Setup Development Environment",
+ "description": "Detailed setup instructions with code examples",
+ "code_example": "npm install\nnpm start"
+ },
+ {
+ "id": "action_2",
+ "title": "Implement Core Features",
+ "description": "Step-by-step implementation guide",
+ "code_example": "const component = () => { return Hello
; };"
+ }
+ ],
+ "transcript": [
+ {"text": "Welcome to this comprehensive tutorial", "start": 0, "duration": 3},
+ {"text": "We'll cover everything you need to know", "start": 3, "duration": 4}
+ ],
+ "processing_time": 45.2,
+ "errors": []
+ }
+
+ response = await async_client.post("/api/v1/process-video", json={
+ "video_url": sample_video_url
+ })
+
+ assert response.status_code == 200
+ data = response.json()
+
+ # Should achieve high quality score
+ assert data["quality_score"] >= 0.9
+ assert len(data["actions"]) == 2
+ assert len(data["transcript"]) == 2
+
+ @pytest.mark.integration
+ @pytest.mark.asyncio
+ async def test_simulation_detection_integration(self, async_client):
+ """Test simulation detection in integration context"""
+ with patch('src.youtube_extension.backend.enhanced_video_processor.EnhancedVideoProcessor.process_video') as mock_process:
+ # Suspicious simulation-like result
+ mock_process.return_value = {
+ "video_data": {"id": "mock_123", "title": "Mock Video"},
+ "actions": [{"title": "Mock action", "description": "Simulated task"}],
+ "transcript": [{"text": "Mock transcript data"}],
+ "processing_time": 0.001, # Suspiciously fast
+ "errors": []
+ }
+
+ response = await async_client.post("/api/v1/process-video", json={
+ "video_url": "https://youtube.com/watch?v=mock123",
+ "options": {"quality": "standard"}
+ })
+
+ # Should reject or flag simulation
+ if response.status_code == 200:
+ data = response.json()
+ assert data["quality_score"] < 0.3 # Very low quality for simulation
+ else:
+ assert response.status_code in {400, 422}
+
+class TestErrorRecoveryIntegration:
+ """Test error recovery and fallback mechanisms"""
+
+ @pytest.mark.integration
+ @pytest.mark.asyncio
+ async def test_service_failure_recovery(self, async_client, sample_video_url):
+ """Test recovery from service failures"""
+ with patch('google.generativeai.GenerativeModel') as mock_gemini:
+ # Simulate Gemini failure then recovery
+ mock_gemini.return_value.generate_content.side_effect = [
+ Exception("Service temporarily unavailable"),
+ Exception("Rate limit exceeded"),
+ Mock(text=json.dumps({"actions": [], "summary": "Basic processing"}))
+ ]
+
+ response = await async_client.post("/api/v1/process-video", json={
+ "video_url": sample_video_url
+ })
+
+ # Should eventually succeed with fallback
+ assert response.status_code in [200, 206] # Success or partial content
+ if response.status_code == 200:
+ data = response.json()
+ assert "video_data" in data # Basic processing succeeded
+
+ @pytest.mark.integration
+ @pytest.mark.asyncio
+ async def test_timeout_recovery(self, async_client, sample_video_url):
+ """Test recovery from processing timeouts"""
+ with patch('src.youtube_extension.backend.enhanced_video_processor.EnhancedVideoProcessor.process_video') as mock_process:
+ mock_process.side_effect = asyncio.TimeoutError("Processing timeout")
+
+ response = await async_client.post("/api/v1/process-video", json={
+ "video_url": sample_video_url,
+ "options": {"timeout": 30}
+ })
+
+ assert response.status_code in {408, 500}
+=======
"""The action route delegates the exact update to its repository."""
repository = Mock()
repository.update.return_value = {"id": "action_123", "completed": True}
@@ -425,3 +938,4 @@ async def test_timeout_recovery(self, async_client, video_service, sample_video_
video_service.process_video_basic.assert_awaited_once_with(
sample_video_url, {"timeout": 30}
)
+>>>>>>> origin/main
diff --git a/tests/unit/test_500_info_disclosure.py b/tests/unit/test_500_info_disclosure.py
index 98ce7f49c..4b6f374f2 100644
--- a/tests/unit/test_500_info_disclosure.py
+++ b/tests/unit/test_500_info_disclosure.py
@@ -40,7 +40,15 @@
import pytest
+<<<<<<< HEAD
+_REPO_ROOT = Path(__file__).resolve().parents[2]
+_BACKEND = _REPO_ROOT / "src" / "youtube_extension" / "backend"
+# The Ray Serve ML surface returns raw ``JSONResponse(...)`` bodies and lives
+# outside ``backend/``; it must be scanned too or 500 leaks there go unguarded.
+_ML_SERVE = _REPO_ROOT / "src" / "uvai" / "ml"
+=======
_BACKEND = Path(__file__).resolve().parents[2] / "src" / "youtube_extension" / "backend"
+>>>>>>> origin/main
# Identifiers that, when referenced inside a 500 body, indicate a leak of the
# caught exception or the inbound request.
@@ -79,6 +87,18 @@ def _refs_exception_or_request(node: ast.AST) -> bool:
return False
+<<<<<<< HEAD
+def _status_is_500(call: ast.Call, name: str) -> bool:
+ for kw in call.keywords:
+ if kw.arg == "status_code" and isinstance(kw.value, ast.Constant):
+ return kw.value.value == 500
+ # The positional slot of ``status_code`` differs by constructor:
+ # HTTPException(status_code, detail, ...) -> args[0]
+ # JSONResponse(content, status_code, ...) -> args[1]
+ idx = 1 if name == "JSONResponse" else 0
+ if len(call.args) > idx and isinstance(call.args[idx], ast.Constant):
+ return call.args[idx].value == 500
+=======
def _status_is_500(call: ast.Call) -> bool:
for kw in call.keywords:
if kw.arg == "status_code" and isinstance(kw.value, ast.Constant):
@@ -86,6 +106,7 @@ def _status_is_500(call: ast.Call) -> bool:
# positional status_code (JSONResponse(500, ...) / HTTPException(500, ...))
if call.args and isinstance(call.args[0], ast.Constant):
return call.args[0].value == 500
+>>>>>>> origin/main
return False
@@ -103,7 +124,11 @@ def _iter_500_leaks(text: str):
name = _call_name(node)
if name not in ("HTTPException", "JSONResponse"):
continue
+<<<<<<< HEAD
+ if not _status_is_500(node, name):
+=======
if not _status_is_500(node):
+>>>>>>> origin/main
continue
# Check keyword arguments
for kw in node.keywords:
@@ -118,22 +143,47 @@ def _iter_500_leaks(text: str):
if name == "HTTPException" and len(node.args) >= 2:
if not _is_static_string(node.args[1]):
yield node.lineno, "HTTPException 500 detail is not a static string"
+<<<<<<< HEAD
+ # Positional JSONResponse body: JSONResponse(, status_code=500) and
+ # the fully positional JSONResponse(, 500). The content is always
+ # args[0] for JSONResponse, regardless of how status_code is passed.
+ if name == "JSONResponse" and node.args:
+ if _refs_exception_or_request(node.args[0]):
+ yield node.lineno, "JSONResponse 500 body references the exception/request"
+
+
+def _guarded_python_files() -> list[Path]:
+ files: list[Path] = []
+ for root in (_BACKEND, _ML_SERVE):
+ if root.exists():
+ files.extend(root.rglob("*.py"))
+ return sorted(files)
+=======
def _backend_python_files() -> list[Path]:
return sorted(_BACKEND.rglob("*.py"))
+>>>>>>> origin/main
def test_no_information_disclosure_in_500_responses() -> None:
offenders: list[str] = []
+<<<<<<< HEAD
+ for path in _guarded_python_files():
+=======
for path in _backend_python_files():
+>>>>>>> origin/main
text = path.read_text(encoding="utf-8")
try:
leaks = list(_iter_500_leaks(text))
except SyntaxError as exc: # pragma: no cover - source is valid Python
raise AssertionError(f"could not parse {path}: {exc}") from exc
for line_no, reason in leaks:
+<<<<<<< HEAD
+ rel = path.relative_to(_REPO_ROOT)
+=======
rel = path.relative_to(_BACKEND.parents[2])
+>>>>>>> origin/main
offenders.append(f"{rel}:{line_no}: {reason}")
assert not offenders, (
@@ -157,6 +207,13 @@ def test_guard_detects_every_known_leak_shape() -> None:
'raise HTTPException(500, str(e))',
'raise HTTPException(500, f"internal: {exc}")',
'raise HTTPException(500, error_msg)',
+<<<<<<< HEAD
+ # JSONResponse with a positional body (the real ml_serve leak shape) —
+ # status via keyword and fully positional (body=args[0], status=args[1]).
+ 'return JSONResponse({"error": str(exc)}, status_code=500)',
+ 'return JSONResponse({"error": str(exc)}, 500)',
+=======
+>>>>>>> origin/main
]
for sample in leaky_samples:
assert list(_iter_500_leaks(sample)), f"scanner missed a real leak: {sample}"
diff --git a/tests/unit/test_agent_completion_gate.py b/tests/unit/test_agent_completion_gate.py
index 301263cd1..b3700efe1 100644
--- a/tests/unit/test_agent_completion_gate.py
+++ b/tests/unit/test_agent_completion_gate.py
@@ -3101,6 +3101,97 @@ def test_validation_replaces_obsolete_failure_comment(self):
)
self.assertIn("issues.updateComment", validate)
+<<<<<<< HEAD
+ def test_validation_comment_failure_is_non_fatal(self):
+ """A rejected comment API must warn, not fail; ❌ findings still fail."""
+
+ workflow = self._workflow()
+ validate = workflow[
+ workflow.index(" validate:"):
+ workflow.index(" truth-gate:")
+ ]
+ script = _github_script_bodies(validate)[0]
+
+ harness = (
+ """
+const calls = { warnings: [], failures: [] };
+const core = {
+ warning(message) { calls.warnings.push(String(message)); },
+ setFailed(message) { calls.failures.push(String(message)); },
+};
+function rejectingComment() {
+ const error = new Error('Resource not accessible by integration');
+ error.status = 403;
+ return Promise.reject(error);
+}
+async function runValidate(pr) {
+ calls.warnings.length = 0;
+ calls.failures.length = 0;
+ const context = {
+ repo: { owner: 'o', repo: 'r' },
+ payload: { pull_request: pr },
+ };
+ const github = {
+ paginate: async () => [],
+ rest: { issues: {
+ listComments: () => {},
+ createComment: rejectingComment,
+ updateComment: rejectingComment,
+ } },
+ };
+ await (async () => {
+"""
+ + script
+ + """
+ })();
+ return { warnings: calls.warnings.slice(), failures: calls.failures.slice() };
+}
+(async () => {
+ // Warning-only findings + a rejecting comment API must NOT fail the job,
+ // and the rejection must surface as a warning.
+ const warnOnly = await runValidate({
+ title: 'update the widget rendering path',
+ body: 'This description is comfortably longer than twenty characters.',
+ additions: 12,
+ deletions: 4,
+ });
+ if (warnOnly.failures.length !== 0) {
+ throw new Error(
+ 'warning-only validation must not fail when the comment API rejects: '
+ + JSON.stringify(warnOnly));
+ }
+ if (warnOnly.warnings.length === 0) {
+ throw new Error('a rejected comment API must emit a warning');
+ }
+ // An error (❌) finding must still call setFailed, comment rejection notwithstanding.
+ const errorFinding = await runValidate({
+ title: 'short',
+ body: 'This description is comfortably longer than twenty characters.',
+ additions: 12,
+ deletions: 4,
+ });
+ if (errorFinding.failures.length === 0) {
+ throw new Error(
+ 'an error finding must still call setFailed even when the comment API rejects: '
+ + JSON.stringify(errorFinding));
+ }
+})().catch((error) => {
+ console.error(error && error.stack ? error.stack : error);
+ process.exit(1);
+});
+"""
+ )
+
+ completed = subprocess.run(
+ ["node", "-e", harness],
+ check=False,
+ capture_output=True,
+ text=True,
+ )
+ self.assertEqual(completed.returncode, 0, completed.stderr)
+
+=======
+>>>>>>> origin/main
def test_commented_review_does_not_clear_changes_requested(self):
workflow = self._workflow()
diff --git a/tests/unit/test_agent_gap_analyzer.py b/tests/unit/test_agent_gap_analyzer.py
index 9cf3211ac..457fbf393 100644
--- a/tests/unit/test_agent_gap_analyzer.py
+++ b/tests/unit/test_agent_gap_analyzer.py
@@ -16,6 +16,7 @@
from pathlib import Path
from datetime import datetime
+<<<<<<< HEAD
# Import the modules to test
import sys
project_root = Path(__file__).parent.parent.parent # tests/unit -> tests -> project root
@@ -23,6 +24,9 @@
sys.path.insert(0, str(agent_module_path))
from agent_gap_analyzer import (
+=======
+from youtube_extension.services.agents.agent_gap_analyzer import (
+>>>>>>> origin/main
AgentGapAnalyzer,
AgentGap,
AgentRecommendation
diff --git a/tests/unit/test_agent_monitor.py b/tests/unit/test_agent_monitor.py
index 818d0b153..5d41095f1 100644
--- a/tests/unit/test_agent_monitor.py
+++ b/tests/unit/test_agent_monitor.py
@@ -25,6 +25,8 @@
)
+<<<<<<< HEAD
+=======
@pytest.fixture(autouse=True)
def _isolate_analyzer_storage(monkeypatch, tmp_path):
"""Monitoring tests must never persist state in ~/.eventrelay."""
@@ -35,6 +37,7 @@ def _isolate_analyzer_storage(monkeypatch, tmp_path):
return analyzer
+>>>>>>> origin/main
class TestMonitoring:
"""Test monitoring functions."""
diff --git a/tests/unit/test_backend_worker.py b/tests/unit/test_backend_worker.py
index eca546ee4..aebc26c5c 100644
--- a/tests/unit/test_backend_worker.py
+++ b/tests/unit/test_backend_worker.py
@@ -12,6 +12,12 @@
import pytest
+<<<<<<< HEAD
+=======
+_SRC = Path(__file__).resolve().parents[2] / "src"
+sys.path.insert(0, str(_SRC))
+
+>>>>>>> origin/main
# Ensure the google.cloud stub is available before importing worker
_google_cloud_mock = MagicMock()
_pubsub_mock = MagicMock()
diff --git a/tests/unit/test_cloud_ai.py b/tests/unit/test_cloud_ai.py
new file mode 100644
index 000000000..165e851ec
--- /dev/null
+++ b/tests/unit/test_cloud_ai.py
@@ -0,0 +1,55 @@
+import pytest
+import sys
+import importlib.util
+from pathlib import Path
+from unittest.mock import AsyncMock, patch
+
+# Load cloud_ai.py module explicitly to avoid collision with the cloud_ai package folder
+src_dir = Path(__file__).resolve().parents[2] / "src"
+cloud_ai_path = src_dir / "youtube_extension" / "integrations" / "cloud_ai.py"
+
+spec = importlib.util.spec_from_file_location(
+ "youtube_extension.integrations.cloud_ai_module",
+ str(cloud_ai_path)
+)
+cloud_ai = importlib.util.module_from_spec(spec)
+sys.modules["youtube_extension.integrations.cloud_ai_module"] = cloud_ai
+spec.loader.exec_module(cloud_ai)
+
+get_available_providers = cloud_ai.get_available_providers
+create_default_config = cloud_ai.create_default_config
+quick_analyze = cloud_ai.quick_analyze
+AnalysisType = cloud_ai.AnalysisType
+
+def test_get_available_providers():
+ providers = get_available_providers()
+ assert isinstance(providers, list)
+
+def test_create_default_config():
+ config = create_default_config()
+ assert "google_cloud" in config
+ assert "aws_rekognition" in config
+ assert "azure_vision" in config
+
+@pytest.mark.asyncio
+async def test_quick_analyze(monkeypatch):
+ monkeypatch.setenv("GOOGLE_CLOUD_PROJECT", "test-project")
+
+ mock_result = AsyncMock()
+ mock_integrator = AsyncMock()
+ mock_integrator.__aenter__.return_value = mock_integrator
+ mock_integrator.analyze_video.return_value = mock_result
+
+ # Use patch.object on the loaded module directly
+ with patch.object(cloud_ai, "CloudAIIntegrator", return_value=mock_integrator):
+ result = await quick_analyze("https://www.youtube.com/watch?v=auJzb1D-fag")
+ assert result is mock_result
+ mock_integrator.analyze_video.assert_called_once_with(
+ "https://www.youtube.com/watch?v=auJzb1D-fag",
+ [
+ AnalysisType.LABEL_DETECTION,
+ AnalysisType.OBJECT_TRACKING,
+ AnalysisType.TEXT_DETECTION,
+ ],
+ preferred_provider=None,
+ )
diff --git a/tests/unit/test_comparative_analysis.py b/tests/unit/test_comparative_analysis.py
index a8ea9e7cc..742b9a2e6 100644
--- a/tests/unit/test_comparative_analysis.py
+++ b/tests/unit/test_comparative_analysis.py
@@ -3,6 +3,10 @@
from __future__ import annotations
import sys
+<<<<<<< HEAD
+import types
+=======
+>>>>>>> origin/main
from pathlib import Path
from unittest.mock import AsyncMock, MagicMock, patch
@@ -10,22 +14,51 @@
sys.path.insert(0, str(Path(__file__).resolve().parents[2] / "src"))
+<<<<<<< HEAD
+# Stub out optional heavy dependencies before importing the module
+_google_stub = types.ModuleType("google")
+sys.modules.setdefault("google", _google_stub)
+_google_genai_stub = types.ModuleType("google.genai")
+_google_genai_stub.Client = MagicMock()
+sys.modules.setdefault("google.genai", _google_genai_stub)
+_genai_types = types.ModuleType("google.genai.types")
+_genai_types.GenerateContentConfig = MagicMock()
+sys.modules.setdefault("google.genai.types", _genai_types)
+# Make `from google import genai` work
+_google_stub.genai = _google_genai_stub
+
+_anthropic_stub = types.ModuleType("anthropic")
+_anthropic_stub.Anthropic = MagicMock()
+sys.modules.setdefault("anthropic", _anthropic_stub)
+
+=======
+>>>>>>> origin/main
# httpx is a real installed dependency — import it so sys.modules contains the real module
# before any test file with a heavier httpx stub is loaded
import httpx as _httpx_real # noqa: F401
+<<<<<<< HEAD
+from youtube_extension.backend.services.comparative_analysis import ( # noqa: E402
+=======
import youtube_extension.backend.services.comparative_analysis as _comparative_analysis # noqa: E402
from youtube_extension.backend.services.comparative_analysis import ( # noqa: E402
LFM2_MCP_BASE_URL,
+>>>>>>> origin/main
AnalysisTask,
ComparativeAnalysisService,
ComparativeReport,
LFM2MCPClient,
+<<<<<<< HEAD
+ LFM2_MCP_BASE_URL,
+=======
+>>>>>>> origin/main
ProviderResult,
get_comparative_analysis_service,
)
+<<<<<<< HEAD
+=======
@pytest.fixture(autouse=True)
def _disable_external_sdk_client_construction(monkeypatch):
"""Keep service construction offline regardless of installed SDKs or keys."""
@@ -33,6 +66,7 @@ def _disable_external_sdk_client_construction(monkeypatch):
monkeypatch.setattr(_comparative_analysis, "_CLAUDE_AVAILABLE", False)
+>>>>>>> origin/main
# ===========================================================================
# AnalysisTask enum
# ===========================================================================
@@ -599,6 +633,10 @@ async def test_grok_valid_response_returns_provider_result(self, monkeypatch):
"choices": [{"message": {"content": "grok says hello"}}]
}
+<<<<<<< HEAD
+ import httpx as real_httpx
+=======
+>>>>>>> origin/main
mock_client = AsyncMock()
mock_client.__aenter__ = AsyncMock(return_value=mock_client)
mock_client.__aexit__ = AsyncMock(return_value=False)
diff --git a/tests/unit/test_dependabot_automation_workflow.py b/tests/unit/test_dependabot_automation_workflow.py
index 81f01ed23..442795b4d 100644
--- a/tests/unit/test_dependabot_automation_workflow.py
+++ b/tests/unit/test_dependabot_automation_workflow.py
@@ -37,6 +37,8 @@ def test_dependabot_workflow_uses_safe_triggers_and_permissions() -> None:
"pull-requests": "write",
"statuses": "read",
}
+<<<<<<< HEAD
+=======
# The auto-merge feature flag is controlled by a repository variable
# (vars context), which — unlike env — is available in job-level `if`
# conditions. It must not be defined as a workflow-level env value, since
@@ -44,6 +46,7 @@ def test_dependabot_workflow_uses_safe_triggers_and_permissions() -> None:
assert "env" not in workflow or "DEPENDABOT_AUTO_MERGE_ENABLED" not in (
workflow.get("env") or {}
)
+>>>>>>> origin/main
def test_dependabot_workflow_approves_and_merges_without_checkout() -> None:
@@ -53,14 +56,20 @@ def test_dependabot_workflow_approves_and_merges_without_checkout() -> None:
approve_job = jobs["approve"]
merge_job = jobs["merge"]
+<<<<<<< HEAD
+=======
assert "vars.DEPENDABOT_AUTO_MERGE_ENABLED == 'true'" in approve_job["if"]
+>>>>>>> origin/main
assert "dependabot[bot]" in approve_job["if"]
assert "github.event.pull_request.user.login == 'dependabot[bot]'" in approve_job["if"]
assert "github.repository == 'groupthinking/EventRelay'" in approve_job["if"]
assert "github.actor == 'dependabot[bot]'" not in approve_job["if"]
+<<<<<<< HEAD
+=======
assert "vars.DEPENDABOT_AUTO_MERGE_ENABLED == 'true'" in merge_job["if"]
+>>>>>>> origin/main
approve_steps = approve_job["steps"]
merge_steps = merge_job["steps"]
diff --git a/tests/unit/test_deployment_manager.py b/tests/unit/test_deployment_manager.py
index 297582f74..7b82e1da6 100644
--- a/tests/unit/test_deployment_manager.py
+++ b/tests/unit/test_deployment_manager.py
@@ -2,6 +2,10 @@
from __future__ import annotations
+<<<<<<< HEAD
+import asyncio
+=======
+>>>>>>> origin/main
import os
import re
import subprocess
@@ -47,6 +51,10 @@
validate_deployment_environment,
)
+<<<<<<< HEAD
+
+=======
+>>>>>>> origin/main
# ===========================================================================
# Helpers
# ===========================================================================
@@ -385,6 +393,8 @@ async def test_no_package_json_passes(self, tmp_path) -> None:
assert result["passed"] is True
assert "skipping" in result["summary"].lower()
+<<<<<<< HEAD
+=======
async def test_sentry_breadcrumb_reports_package_presence(self, tmp_path) -> None:
"""Sentry instrumentation must not run before package path setup."""
(tmp_path / "package.json").write_text('{"name": "test"}')
@@ -422,6 +432,7 @@ async def test_invalid_path_is_rejected_before_sentry(self, tmp_path) -> None:
assert result["passed"] is False
sentry_sdk.add_breadcrumb.assert_not_called()
+>>>>>>> origin/main
async def test_npm_install_failure(self, tmp_path) -> None:
(tmp_path / "package.json").write_text('{"name": "test"}')
mgr = _make_manager()
@@ -716,7 +727,11 @@ async def test_github_deployment_called_when_token_set(self, tmp_path) -> None:
with patch("youtube_extension.backend.deployment_manager._adapter_deploy",
new=AsyncMock(return_value=mock_adapter_result)):
+<<<<<<< HEAD
+ result = await mgr.deploy_project(
+=======
await mgr.deploy_project(
+>>>>>>> origin/main
str(tmp_path),
{"title": "Test"},
{"target": "vercel"},
diff --git a/tests/unit/test_enhanced_extractor.py b/tests/unit/test_enhanced_extractor.py
index bbb5d4109..493178487 100644
--- a/tests/unit/test_enhanced_extractor.py
+++ b/tests/unit/test_enhanced_extractor.py
@@ -2,7 +2,10 @@
from __future__ import annotations
+<<<<<<< HEAD
+=======
import importlib.util as importlib_util
+>>>>>>> origin/main
import json
import sys
import types
@@ -18,6 +21,98 @@
sys.path.insert(0, str(_SRC))
# ---------------------------------------------------------------------------
+<<<<<<< HEAD
+# Stub all heavy optional / broken transitive deps at collection time
+# ---------------------------------------------------------------------------
+
+# yt_dlp
+sys.modules.setdefault("yt_dlp", types.ModuleType("yt_dlp"))
+
+# googleapiclient
+if "googleapiclient" not in sys.modules:
+ _gcapi = types.ModuleType("googleapiclient")
+ _gcapi.discovery = types.ModuleType("googleapiclient.discovery")
+ _gcapi.errors = types.ModuleType("googleapiclient.errors")
+ _gcapi.errors.HttpError = Exception
+ sys.modules["googleapiclient"] = _gcapi
+ sys.modules["googleapiclient.discovery"] = _gcapi.discovery
+ sys.modules["googleapiclient.errors"] = _gcapi.errors
+
+# youtube_transcript_api
+if "youtube_transcript_api" not in sys.modules:
+ _yta = types.ModuleType("youtube_transcript_api")
+ _yta._errors = types.ModuleType("youtube_transcript_api._errors")
+ _yta._errors.CouldNotRetrieveTranscript = Exception
+ _yta._errors.NoTranscriptFound = Exception
+ sys.modules["youtube_transcript_api"] = _yta
+ sys.modules["youtube_transcript_api._errors"] = _yta._errors
+
+# torch / transformers / openai
+sys.modules.setdefault("torch", types.ModuleType("torch"))
+if "transformers" not in sys.modules:
+ _tr = types.ModuleType("transformers")
+ _tr.pipeline = None
+ sys.modules["transformers"] = _tr
+if "openai" not in sys.modules:
+ _openai_stub = types.ModuleType("openai")
+ _openai_stub.AsyncOpenAI = MagicMock()
+ sys.modules["openai"] = _openai_stub
+
+# pandas
+if "pandas" not in sys.modules:
+ _pd = types.ModuleType("pandas")
+
+ class _FakeDataFrame:
+ def __init__(self, data=None):
+ self._data = data or []
+
+ def to_csv(self, path, index=False):
+ with open(path, "w") as f:
+ f.write("text,start,duration,end\n")
+
+ _pd.DataFrame = _FakeDataFrame
+ sys.modules["pandas"] = _pd
+
+# GeminiService
+if "youtube_extension.services.ai.gemini_service" not in sys.modules:
+ _gs_mod = types.ModuleType("youtube_extension.services.ai.gemini_service")
+
+ class _FakeGeminiService:
+ def __init__(self, *a, **kw):
+ pass
+
+ def is_available(self):
+ return False
+
+ _gs_mod.GeminiService = _FakeGeminiService
+ sys.modules["youtube_extension.services.ai.gemini_service"] = _gs_mod
+
+# ScoringEngine
+if "youtube_extension.processors.scoring_engine" not in sys.modules:
+ _se_mod = types.ModuleType("youtube_extension.processors.scoring_engine")
+
+ class _FakeScoringEngine:
+ def calculate_all_scores(self, video_info, transcript_dicts):
+ return {"engagement_score": 0.5}
+
+ def generate_actions(self, world_class_analysis):
+ return [{"action": "review"}]
+
+ _se_mod.ScoringEngine = _FakeScoringEngine
+ sys.modules["youtube_extension.processors.scoring_engine"] = _se_mod
+
+# ---------------------------------------------------------------------------
+# Now import the module under test
+# ---------------------------------------------------------------------------
+from youtube_extension.processors.enhanced_extractor import ( # noqa: E402
+ EnhancedVideoExtractor,
+ ProcessingStage,
+ TranscriptSegment,
+ VideoContent,
+ VideoMetadata,
+ VideoSource,
+)
+=======
# Load the legacy extractor with local-only optional-dependency substitutes.
# The old tests installed bare modules in global ``sys.modules`` at collection
# time, so unrelated tests observed fake Google/YouTube packages. Loading the
@@ -102,6 +197,7 @@ def generate_actions(self, world_class_analysis):
VideoContent = _extractor_mod.VideoContent
VideoMetadata = _extractor_mod.VideoMetadata
VideoSource = _extractor_mod.VideoSource
+>>>>>>> origin/main
# ---------------------------------------------------------------------------
# Helpers
@@ -944,13 +1040,32 @@ async def test_gemini_result_not_success_falls_back(self, monkeypatch):
class TestExtractTranscript:
async def test_raises_when_no_video_deps(self, monkeypatch):
monkeypatch.delenv("YOUTUBE_API_KEY", raising=False)
+<<<<<<< HEAD
+ import youtube_extension.processors.enhanced_extractor as mod
+
+ orig = mod.HAS_VIDEO_DEPS
+ try:
+ mod.HAS_VIDEO_DEPS = False
+=======
orig = _extractor_mod.HAS_VIDEO_DEPS
try:
_extractor_mod.HAS_VIDEO_DEPS = False
+>>>>>>> origin/main
extractor = EnhancedVideoExtractor()
with pytest.raises(ValueError, match="Video dependencies not available"):
await extractor.extract_transcript("abc123")
finally:
+<<<<<<< HEAD
+ mod.HAS_VIDEO_DEPS = orig
+
+ async def test_successful_transcript_extraction(self, monkeypatch):
+ monkeypatch.delenv("YOUTUBE_API_KEY", raising=False)
+ import youtube_extension.processors.enhanced_extractor as mod
+
+ orig = mod.HAS_VIDEO_DEPS
+ try:
+ mod.HAS_VIDEO_DEPS = True
+=======
_extractor_mod.HAS_VIDEO_DEPS = orig
async def test_successful_transcript_extraction(self, monkeypatch):
@@ -958,6 +1073,7 @@ async def test_successful_transcript_extraction(self, monkeypatch):
orig = _extractor_mod.HAS_VIDEO_DEPS
try:
_extractor_mod.HAS_VIDEO_DEPS = True
+>>>>>>> origin/main
extractor = EnhancedVideoExtractor()
fake_response_data = {
@@ -970,6 +1086,11 @@ async def test_successful_transcript_extraction(self, monkeypatch):
},
}
+<<<<<<< HEAD
+ import httpx
+
+=======
+>>>>>>> origin/main
mock_response = MagicMock()
mock_response.json.return_value = fake_response_data
mock_response.raise_for_status = MagicMock()
@@ -979,11 +1100,15 @@ async def test_successful_transcript_extraction(self, monkeypatch):
mock_client.__aexit__ = AsyncMock(return_value=False)
mock_client.post = AsyncMock(return_value=mock_response)
+<<<<<<< HEAD
+ with patch("httpx.AsyncClient", return_value=mock_client):
+=======
with patch.object(
_extractor_mod.httpx,
"AsyncClient",
return_value=mock_client,
):
+>>>>>>> origin/main
segments = await extractor.extract_transcript("abc123")
assert len(segments) == 2
@@ -991,6 +1116,21 @@ async def test_successful_transcript_extraction(self, monkeypatch):
assert segments[0].start == 0.0
assert segments[1].text == "World"
finally:
+<<<<<<< HEAD
+ mod.HAS_VIDEO_DEPS = orig
+
+ async def test_http_request_error_raises_value_error(self, monkeypatch):
+ monkeypatch.delenv("YOUTUBE_API_KEY", raising=False)
+ import youtube_extension.processors.enhanced_extractor as mod
+
+ orig = mod.HAS_VIDEO_DEPS
+ try:
+ mod.HAS_VIDEO_DEPS = True
+ extractor = EnhancedVideoExtractor()
+
+ import httpx
+
+=======
_extractor_mod.HAS_VIDEO_DEPS = orig
async def test_http_request_error_raises_value_error(self, monkeypatch):
@@ -1000,10 +1140,29 @@ async def test_http_request_error_raises_value_error(self, monkeypatch):
_extractor_mod.HAS_VIDEO_DEPS = True
extractor = EnhancedVideoExtractor()
+>>>>>>> origin/main
mock_client = AsyncMock()
mock_client.__aenter__ = AsyncMock(return_value=mock_client)
mock_client.__aexit__ = AsyncMock(return_value=False)
mock_client.post = AsyncMock(
+<<<<<<< HEAD
+ side_effect=httpx.RequestError("Connection refused")
+ )
+
+ with patch("httpx.AsyncClient", return_value=mock_client):
+ with pytest.raises(ValueError, match="caption extractor service"):
+ await extractor.extract_transcript("abc123")
+ finally:
+ mod.HAS_VIDEO_DEPS = orig
+
+ async def test_failed_success_flag_raises(self, monkeypatch):
+ monkeypatch.delenv("YOUTUBE_API_KEY", raising=False)
+ import youtube_extension.processors.enhanced_extractor as mod
+
+ orig = mod.HAS_VIDEO_DEPS
+ try:
+ mod.HAS_VIDEO_DEPS = True
+=======
side_effect=_extractor_mod.httpx.RequestError("Connection refused")
)
@@ -1022,6 +1181,7 @@ async def test_failed_success_flag_raises(self, monkeypatch):
orig = _extractor_mod.HAS_VIDEO_DEPS
try:
_extractor_mod.HAS_VIDEO_DEPS = True
+>>>>>>> origin/main
extractor = EnhancedVideoExtractor()
fake_response_data = {"success": False, "error": "Video unavailable"}
@@ -1035,6 +1195,13 @@ async def test_failed_success_flag_raises(self, monkeypatch):
mock_client.__aexit__ = AsyncMock(return_value=False)
mock_client.post = AsyncMock(return_value=mock_response)
+<<<<<<< HEAD
+ with patch("httpx.AsyncClient", return_value=mock_client):
+ with pytest.raises(Exception):
+ await extractor.extract_transcript("abc123")
+ finally:
+ mod.HAS_VIDEO_DEPS = orig
+=======
with patch.object(
_extractor_mod.httpx,
"AsyncClient",
@@ -1044,6 +1211,7 @@ async def test_failed_success_flag_raises(self, monkeypatch):
await extractor.extract_transcript("abc123")
finally:
_extractor_mod.HAS_VIDEO_DEPS = orig
+>>>>>>> origin/main
# ===========================================================================
@@ -1131,7 +1299,14 @@ async def test_process_video_invalid_url(self, monkeypatch):
extractor = EnhancedVideoExtractor()
# patch extract_video_id to return None so video_id is assigned (None)
+<<<<<<< HEAD
+ with patch(
+ "youtube_extension.processors.enhanced_extractor.extract_video_id",
+ return_value=None,
+ ):
+=======
with patch.object(_extractor_mod, "extract_video_id", return_value=None):
+>>>>>>> origin/main
content = await extractor.process_video("not-a-youtube-url")
# Should return error content
diff --git a/tests/unit/test_enhanced_video_processor.py b/tests/unit/test_enhanced_video_processor.py
index a25f7fdfc..16208feb4 100644
--- a/tests/unit/test_enhanced_video_processor.py
+++ b/tests/unit/test_enhanced_video_processor.py
@@ -23,10 +23,17 @@
sys.path.insert(0, str(_SRC))
# ---------------------------------------------------------------------------
+<<<<<<< HEAD
+# Import the module under test (with GEMINI_API_KEY set so __init__ passes)
+# ---------------------------------------------------------------------------
+import os
+os.environ.setdefault("GEMINI_API_KEY", "test-gemini-key")
+=======
# Import the module under test. Individual constructor tests provide their own
# scoped credentials so test collection never mutates the process environment.
# ---------------------------------------------------------------------------
import os
+>>>>>>> origin/main
import youtube_extension.backend.enhanced_video_processor as _mod
from youtube_extension.backend.enhanced_video_processor import (
@@ -131,11 +138,15 @@ def test_livekit_url_default(self):
assert proc.livekit_url == "ws://localhost:7880"
def test_livekit_url_from_env(self):
+<<<<<<< HEAD
+ with patch.dict(os.environ, {"LIVEKIT_URL": "ws://custom:7880"}, clear=False):
+=======
with patch.dict(
os.environ,
{"GEMINI_API_KEY": "test-key", "LIVEKIT_URL": "ws://custom:7880"},
clear=False,
):
+>>>>>>> origin/main
with patch.object(_mod, "GEMINI_VISION_AVAILABLE", False):
proc = EnhancedVideoProcessor()
assert proc.livekit_url == "ws://custom:7880"
@@ -612,34 +623,6 @@ async def test_api_fetch_exception_returns_failed(self):
assert result["source"] == "failed"
-# ===========================================================================
-# _get_openai_whisper_transcript
-# ===========================================================================
-
-class TestGetOpenAIWhisperTranscript:
- async def test_yt_dlp_uses_canonical_url_after_option_terminator(self, tmp_path):
- proc = _make_processor()
- hostile_url = "--exec=touch /tmp/eventrelay-argument-injection"
-
- mock_openai = MagicMock()
- mock_client = mock_openai.OpenAI.return_value
- mock_client.audio.transcriptions.create.return_value = "safe transcript"
-
- with patch.dict(sys.modules, {"openai": mock_openai}):
- with patch("tempfile.TemporaryDirectory") as temp_dir:
- temp_dir.return_value.__enter__.return_value = str(tmp_path)
- with patch("subprocess.run") as run:
- with patch("builtins.open", mock_open(read_data=b"audio")):
- result = await proc._get_openai_whisper_transcript(
- _VIDEO_ID, hostile_url
- )
-
- command = run.call_args.args[0]
- assert command[-2:] == ["--", _VIDEO_URL]
- assert hostile_url not in command
- assert result["text"] == "safe transcript"
-
-
# ===========================================================================
# _get_gemini_transcript
# ===========================================================================
diff --git a/tests/unit/test_error_handling.py b/tests/unit/test_error_handling.py
index 68f6cf077..0da63656e 100644
--- a/tests/unit/test_error_handling.py
+++ b/tests/unit/test_error_handling.py
@@ -499,3 +499,36 @@ async def test_handle_timeout_returns_504(self, middleware):
context = {"request_id": "test-timeout"}
response = await middleware.handle_timeout_error(req, context)
assert response.status_code == 504
+<<<<<<< HEAD
+=======
+
+
+def test_classify_validation_error():
+ from fastapi.exceptions import RequestValidationError
+ from youtube_extension.backend.middleware.error_handling_middleware import ErrorClassifier
+ exc = RequestValidationError([{"loc": ("body", "video_id"), "msg": "field required", "type": "value_error.missing"}])
+ res = ErrorClassifier.classify_exception(exc)
+ assert res.status_code == 422
+ assert "body -> video_id" in res.message
+
+
+def test_validation_exception_handler_endpoint():
+ from fastapi.exceptions import RequestValidationError
+ from youtube_extension.backend.middleware.error_handling_middleware import setup_error_handlers
+ from fastapi.testclient import TestClient
+ from fastapi import FastAPI
+
+ app = FastAPI()
+ setup_error_handlers(app)
+
+ @app.get("/trigger-validation")
+ async def trigger():
+ raise RequestValidationError([{"loc": ("query", "q"), "msg": "invalid query", "type": "value_error"}])
+
+ client = TestClient(app)
+ response = client.get("/trigger-validation")
+ assert response.status_code == 422
+ assert response.json()["error"]["message"] == "Please check your input and try again."
+
+
+>>>>>>> origin/main
diff --git a/tests/unit/test_gemini_grok_failover.py b/tests/unit/test_gemini_grok_failover.py
index 54935d224..e77af04f7 100644
--- a/tests/unit/test_gemini_grok_failover.py
+++ b/tests/unit/test_gemini_grok_failover.py
@@ -31,6 +31,8 @@
_PROMPT = "Analyze this video and extract key events"
+<<<<<<< HEAD
+=======
@pytest.fixture(autouse=True)
def _isolate_service_state(monkeypatch):
"""Avoid real transports and class-level API-key leakage between tests."""
@@ -44,6 +46,7 @@ def _isolate_service_state(monkeypatch):
monkeypatch.setattr(GeminiVideoService, "API_KEYS", [])
+>>>>>>> origin/main
def _make_service(grok_key: str | None = _GROK_KEY) -> GeminiVideoService:
"""Instantiate GeminiVideoService with test keys."""
with patch.dict(
diff --git a/tests/unit/test_learning_tenant_models.py b/tests/unit/test_learning_tenant_models.py
index b9a2bf811..506a9d379 100644
--- a/tests/unit/test_learning_tenant_models.py
+++ b/tests/unit/test_learning_tenant_models.py
@@ -356,3 +356,89 @@ def test_has_api_calls(self):
def test_has_active_users(self):
t = _ns()
assert "active_users" in Tenant.get_usage_stats(t)
+<<<<<<< HEAD
+=======
+
+
+# ===========================================================================
+# TenantUser methods
+# ===========================================================================
+
+
+class TestTenantUserMethods:
+ def test_has_permission(self):
+ from youtube_extension.backend.models.tenant import TenantUser
+ tu = _ns(permissions=["read", "write"])
+ assert TenantUser.has_permission(tu, "read") is True
+ assert TenantUser.has_permission(tu, "delete") is False
+
+ tu_none = _ns(permissions=None)
+ assert TenantUser.has_permission(tu_none, "read") is False
+
+ def test_add_permission(self):
+ from youtube_extension.backend.models.tenant import TenantUser
+ tu = _ns(permissions=["read"])
+ TenantUser.add_permission(tu, "write")
+ assert tu.permissions == ["read", "write"]
+
+ # Add duplicate
+ TenantUser.add_permission(tu, "read")
+ assert tu.permissions == ["read", "write"]
+
+ # None permissions
+ tu_none = _ns(permissions=None)
+ TenantUser.add_permission(tu_none, "read")
+ assert tu_none.permissions == ["read"]
+
+ def test_remove_permission(self):
+ from youtube_extension.backend.models.tenant import TenantUser
+ tu = _ns(permissions=["read", "write"])
+ TenantUser.remove_permission(tu, "write")
+ assert tu.permissions == ["read"]
+
+ # Remove non-existent
+ TenantUser.remove_permission(tu, "delete")
+ assert tu.permissions == ["read"]
+
+ # None permissions
+ tu_none = _ns(permissions=None)
+ TenantUser.remove_permission(tu_none, "read")
+ assert tu_none.permissions is None
+
+
+# ===========================================================================
+# TenantSubscription methods
+# ===========================================================================
+
+
+class TestTenantSubscriptionMethods:
+ def test_is_active(self):
+ from youtube_extension.backend.models.tenant import TenantSubscription
+ from datetime import timedelta
+
+ ts_active = _ns(status="active", expires_at=datetime.utcnow() + timedelta(days=1))
+ assert TenantSubscription.is_active(ts_active) is True
+
+ ts_inactive_status = _ns(status="cancelled", expires_at=datetime.utcnow() + timedelta(days=1))
+ assert TenantSubscription.is_active(ts_inactive_status) is False
+
+ ts_expired = _ns(status="active", expires_at=datetime.utcnow() - timedelta(days=1))
+ assert TenantSubscription.is_active(ts_expired) is False
+
+ ts_no_expiry = _ns(status="active", expires_at=None)
+ assert TenantSubscription.is_active(ts_no_expiry) is True
+
+ def test_days_until_expiry(self):
+ from youtube_extension.backend.models.tenant import TenantSubscription
+ from datetime import timedelta
+
+ ts_no_expiry = _ns(expires_at=None)
+ assert TenantSubscription.days_until_expiry(ts_no_expiry) is None
+
+ ts_future = _ns(expires_at=datetime.utcnow() + timedelta(days=5, hours=1))
+ assert TenantSubscription.days_until_expiry(ts_future) == 5
+
+ ts_past = _ns(expires_at=datetime.utcnow() - timedelta(days=5))
+ assert TenantSubscription.days_until_expiry(ts_past) == 0
+
+>>>>>>> origin/main
diff --git a/tests/unit/test_master_roadmap_fixes.py b/tests/unit/test_master_roadmap_fixes.py
index b767de58e..a6e30a850 100644
--- a/tests/unit/test_master_roadmap_fixes.py
+++ b/tests/unit/test_master_roadmap_fixes.py
@@ -346,3 +346,136 @@ def test_sentry_smoke_endpoint_gated(monkeypatch: pytest.MonkeyPatch) -> None:
monkeypatch.setenv("ALLOW_SENTRY_SMOKE", "1")
response = client.post("/test-sentry")
assert response.status_code == 500
+<<<<<<< HEAD
+=======
+
+
+def test_job_store_list_recent_and_corrupt_json(tmp_path):
+ from youtube_extension.services.pipeline_job_store import PipelineJobStore, get_job_store
+
+ store = PipelineJobStore(tmp_path)
+ store.save("job1", {"job_id": "job1", "data": "a"})
+ store.save("job2", {"job_id": "job2", "data": "b"})
+
+ # Write a corrupt json file
+ corrupt_file = tmp_path / "corrupt_job.json"
+ corrupt_file.write_text("invalid{json}", encoding="utf-8")
+
+ recent = store.list_recent(limit=10)
+ assert len(recent) == 2
+ assert {r["job_id"] for r in recent} == {"job1", "job2"}
+
+ # Test load of corrupt JSON
+ assert store.load("corrupt_job") is None
+
+ # Test get_job_store singleton
+ js1 = get_job_store()
+ js2 = get_job_store()
+ assert js1 is js2
+
+
+def test_audit_store_list_runs_and_singleton(tmp_path):
+ from youtube_extension.services.pipeline_audit_store import PipelineAuditStore, get_audit_store
+
+ store = PipelineAuditStore(tmp_path)
+ store.append("run1", agent_id="agent1", action="action1", success=True, duration_ms=10.0)
+ store.append("run2", agent_id="agent2", action="action2", success=False, duration_ms=20.0)
+
+ runs = store.list_runs(limit=10)
+ assert len(runs) == 2
+ assert set(runs) == {"run1", "run2"}
+
+ # Test non-existent run
+ assert store.get_run("non_existent_run") == []
+
+ # Test get_audit_store singleton
+ as1 = get_audit_store()
+ as2 = get_audit_store()
+ assert as1 is as2
+
+
+def test_job_store_naive_created_at_and_unlink_oserror(tmp_path, monkeypatch):
+ from datetime import datetime, timedelta, timezone
+ from pathlib import Path
+ from youtube_extension.services.pipeline_job_store import PipelineJobStore
+
+ store = PipelineJobStore(tmp_path)
+
+ # Save a job with a naive created_at datetime string
+ naive_ts = (datetime.now() - timedelta(hours=5)).replace(tzinfo=None).isoformat()
+ store.save("naive_job", {"job_id": "naive_job", "created_at": naive_ts})
+
+ # Save another job to test unlink OSError
+ store.save("unlink_job", {"job_id": "unlink_job", "created_at": naive_ts})
+
+ # Mock Path.unlink to raise OSError for unlink_job
+ original_unlink = Path.unlink
+ def mock_unlink(self, *args, **kwargs):
+ if "unlink_job" in self.name:
+ raise OSError("permission denied")
+ return original_unlink(self, *args, **kwargs)
+
+ monkeypatch.setattr(Path, "unlink", mock_unlink)
+
+ cutoff = datetime.now(timezone.utc)
+ removed = store.expire_before(cutoff)
+
+ # naive_job should be removed, unlink_job unlink should raise OSError and log warning
+ assert removed == 1
+ assert store.load("naive_job") is None
+ assert store.load("unlink_job") is not None
+
+
+def test_mcp_init():
+ import youtube_extension.services.mcp as mcp
+ assert mcp.MCPOrchestrator is not None
+ assert mcp.get_orchestrator is not None
+
+
+def test_namespace_packages_init():
+ import youtube_extension.core.config as core_config
+ import youtube_extension.core.mcp as core_mcp
+ assert core_config is not None
+ assert core_mcp is not None
+
+
+@pytest.mark.asyncio
+async def test_pubsub_service():
+ from unittest.mock import MagicMock, patch
+ from youtube_extension.backend.services.pubsub_service import PubSubService
+
+ mock_publisher_client = MagicMock()
+ mock_publisher_client.topic_path.return_value = "projects/p/topics/t"
+
+ # Mock return value of publish
+ mock_future = MagicMock()
+ mock_future.result.return_value = "msg-123"
+ mock_publisher_client.publish.return_value = mock_future
+
+ with patch("youtube_extension.backend.services.pubsub_service.pubsub_v1.PublisherClient", return_value=mock_publisher_client):
+ # 1. Success path
+ service = PubSubService("proj", "topic")
+ msg_id = await service.publish_message({"k": "v"}, {"attr": "val"})
+ assert msg_id == "msg-123"
+ mock_publisher_client.publish.assert_called_once_with("projects/p/topics/t", b'{"k": "v"}', attr="val")
+
+ # 2. Publish failure exception path
+ mock_publisher_client.publish.side_effect = RuntimeError("publish fail")
+ msg_id_fail = await service.publish_message({"k": "v"})
+ assert msg_id_fail is None
+
+ # 3. Not initialized path
+ service_uninit = PubSubService("", "")
+ assert await service_uninit.publish_message({"k": "v"}) is None
+
+ # 4. Constructor exception path
+ with patch("youtube_extension.backend.services.pubsub_service.pubsub_v1.PublisherClient", side_effect=RuntimeError("init fail")):
+ service_init_fail = PubSubService("proj", "topic")
+ assert service_init_fail._publisher is None
+
+
+
+
+
+
+>>>>>>> origin/main
diff --git a/tests/unit/test_mcp_orchestrator.py b/tests/unit/test_mcp_orchestrator.py
index 893e0182a..beec5b13d 100644
--- a/tests/unit/test_mcp_orchestrator.py
+++ b/tests/unit/test_mcp_orchestrator.py
@@ -740,6 +740,12 @@ async def fake_execute_on_server(server_id, task):
class TestExecuteOnServer:
+<<<<<<< HEAD
+ async def test_raises_not_implemented_error(self):
+ from youtube_extension.services.mcp.registry import MCPServerRegistry
+ from youtube_extension.services.mcp.types import MCPCapability, MCPTask
+
+=======
@patch("aiohttp.ClientSession.post")
async def test_execute_on_server_success(self, mock_post):
from youtube_extension.services.mcp.registry import MCPServerRegistry
@@ -812,6 +818,7 @@ async def test_execute_on_server_handles_http_errors(self, mock_post):
aenter_mock.return_value = mock_response
mock_post.return_value.__aenter__ = aenter_mock
+>>>>>>> origin/main
registry = MCPServerRegistry()
registry.register_server(
"srv", "Srv", "http://localhost:9000", [MCPCapability.AI_INFERENCE]
@@ -824,7 +831,11 @@ async def test_execute_on_server_handles_http_errors(self, mock_post):
requirements=[MCPCapability.AI_INFERENCE],
)
+<<<<<<< HEAD
+ with pytest.raises(NotImplementedError):
+=======
with pytest.raises(aiohttp.ClientResponseError):
+>>>>>>> origin/main
await orch._execute_on_server("srv", task)
async def test_raises_value_error_for_unknown_server(self):
diff --git a/tests/unit/test_mcp_protocol_bridge.py b/tests/unit/test_mcp_protocol_bridge.py
index 578e38ec3..bc042f1d0 100644
--- a/tests/unit/test_mcp_protocol_bridge.py
+++ b/tests/unit/test_mcp_protocol_bridge.py
@@ -2,12 +2,18 @@
from __future__ import annotations
+<<<<<<< HEAD
+=======
import asyncio
+>>>>>>> origin/main
import importlib.util
import sys
import types as _types
from pathlib import Path
+<<<<<<< HEAD
+=======
from typing import Any, Optional
+>>>>>>> origin/main
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
@@ -16,6 +22,8 @@
sys.path.insert(0, str(_SRC))
+<<<<<<< HEAD
+=======
def _new_sdk_client(*_args: Any, **_kwargs: Any) -> MagicMock:
"""Return a fresh SDK-shaped mock for each adapter initialization."""
return MagicMock()
@@ -52,6 +60,7 @@ def _optional_sdk_stubs() -> dict[str, _types.ModuleType]:
}
+>>>>>>> origin/main
def _inject_stub(name: str, path: str) -> None:
if name not in sys.modules:
stub = _types.ModuleType(name)
@@ -74,22 +83,48 @@ def _load(rel_path: str, canonical: str):
_ctx_mod = _load("youtube_extension/core/mcp/context_manager.py", "youtube_extension.core.mcp.context_manager")
_reg_mod = _load("youtube_extension/core/mcp/server_registry.py", "youtube_extension.core.mcp.server_registry")
+<<<<<<< HEAD
+_pb_mod = _load("youtube_extension/core/mcp/protocol_bridge.py", "youtube_extension.core.mcp.protocol_bridge")
+=======
with patch.dict(sys.modules, _optional_sdk_stubs()):
_pb_mod = _load(
"youtube_extension/core/mcp/protocol_bridge.py",
"youtube_extension.core.mcp.protocol_bridge",
)
+>>>>>>> origin/main
BridgeStatus = _pb_mod.BridgeStatus
MCPProtocolBridge = _pb_mod.MCPProtocolBridge
ProtocolAdapter = _pb_mod.ProtocolAdapter
ProtocolType = _pb_mod.ProtocolType
ServerCapability = _reg_mod.ServerCapability
+<<<<<<< HEAD
+=======
MCPContext = _ctx_mod.MCPContext
+>>>>>>> origin/main
# Minimal concrete adapter for tests
class _FakeAdapter(ProtocolAdapter):
+<<<<<<< HEAD
+ def __init__(self, ptype=ProtocolType.MCP):
+ self._ptype = ptype
+
+ @property
+ def protocol_type(self):
+ return self._ptype
+
+ async def initialize(self, config):
+ return True
+
+ async def send_request(self, request, context):
+ return {"status": "ok"}
+
+ async def health_check(self):
+ return True
+
+ async def get_capabilities(self):
+=======
def __init__(self, ptype: ProtocolType = ProtocolType.MCP) -> None:
self._ptype = ptype
@@ -107,6 +142,7 @@ async def health_check(self) -> bool:
return True
async def get_capabilities(self) -> list[ServerCapability]:
+>>>>>>> origin/main
return []
@@ -329,36 +365,60 @@ async def initialize(self, config):
class TestMCPProtocolBridgeSendProtocolRequest:
+<<<<<<< HEAD
+ async def _connected_bridge(self, ptype=ProtocolType.MCP):
+=======
async def _connected_bridge(self, ptype: ProtocolType = ProtocolType.MCP) -> MCPProtocolBridge:
+>>>>>>> origin/main
bridge = MCPProtocolBridge()
bridge.register_adapter(_FakeAdapter(ptype))
await bridge.initialize_adapter(ptype, {})
return bridge
+<<<<<<< HEAD
+ async def test_raises_value_error_when_no_adapter(self):
+=======
async def test_raises_value_error_when_no_adapter(self) -> None:
+>>>>>>> origin/main
bridge = MCPProtocolBridge()
with pytest.raises(ValueError, match="No adapter registered"):
await bridge.send_protocol_request(ProtocolType.MCP, {})
+<<<<<<< HEAD
+ async def test_raises_runtime_error_when_not_connected(self):
+=======
async def test_raises_runtime_error_when_not_connected(self) -> None:
+>>>>>>> origin/main
bridge = MCPProtocolBridge()
bridge.register_adapter(_FakeAdapter(ProtocolType.MCP))
# Registered but not initialized => DISCONNECTED
with pytest.raises(RuntimeError, match="not connected"):
await bridge.send_protocol_request(ProtocolType.MCP, {})
+<<<<<<< HEAD
+ async def test_returns_response_from_adapter(self):
+=======
async def test_returns_response_from_adapter(self) -> None:
+>>>>>>> origin/main
bridge = await self._connected_bridge()
resp = await bridge.send_protocol_request(ProtocolType.MCP, {"cmd": "test"})
assert resp == {"status": "ok"}
+<<<<<<< HEAD
+ async def test_creates_context_when_none_provided(self):
+=======
async def test_creates_context_when_none_provided(self) -> None:
+>>>>>>> origin/main
bridge = await self._connected_bridge()
# Should not raise even without explicit context
resp = await bridge.send_protocol_request(ProtocolType.MCP, {"cmd": "test"})
assert resp is not None
+<<<<<<< HEAD
+ async def test_uses_provided_context(self):
+=======
async def test_uses_provided_context(self) -> None:
+>>>>>>> origin/main
bridge = await self._connected_bridge()
ctx_manager = _ctx_mod.get_context_manager()
context = ctx_manager.create_context(
@@ -367,7 +427,11 @@ async def test_uses_provided_context(self) -> None:
resp = await bridge.send_protocol_request(ProtocolType.MCP, {}, context=context)
assert resp is not None
+<<<<<<< HEAD
+ async def test_context_metadata_set_after_request(self):
+=======
async def test_context_metadata_set_after_request(self) -> None:
+>>>>>>> origin/main
bridge = await self._connected_bridge()
ctx_manager = _ctx_mod.get_context_manager()
context = ctx_manager.create_context(
@@ -376,7 +440,11 @@ async def test_context_metadata_set_after_request(self) -> None:
await bridge.send_protocol_request(ProtocolType.MCP, {}, context=context)
assert context.metadata.get("protocol") == "mcp"
+<<<<<<< HEAD
+ async def test_history_entry_added_on_success(self):
+=======
async def test_history_entry_added_on_success(self) -> None:
+>>>>>>> origin/main
bridge = await self._connected_bridge()
ctx_manager = _ctx_mod.get_context_manager()
context = ctx_manager.create_context(
@@ -386,7 +454,11 @@ async def test_history_entry_added_on_success(self) -> None:
history_actions = [h["action"] for h in context.history]
assert "protocol_request" in history_actions
+<<<<<<< HEAD
+ async def test_history_entry_redacts_raw_request(self):
+=======
async def test_history_entry_redacts_raw_request(self) -> None:
+>>>>>>> origin/main
bridge = await self._connected_bridge()
ctx_manager = _ctx_mod.get_context_manager()
context = ctx_manager.create_context(
@@ -394,11 +466,15 @@ async def test_history_entry_redacts_raw_request(self) -> None:
)
await bridge.send_protocol_request(
ProtocolType.MCP,
+<<<<<<< HEAD
+ {"api_key": "sk-super-secret", "prompt": "hello"},
+=======
{
"api_key": "sk-super-secret",
"prompt": "hello",
"sk-user-controlled-key": "value",
},
+>>>>>>> origin/main
context=context,
)
last = context.history[-1]
@@ -407,6 +483,18 @@ async def test_history_entry_redacts_raw_request(self) -> None:
assert "request" not in details
assert "sk-super-secret" not in str(details)
summary = details["request_summary"]
+<<<<<<< HEAD
+ assert set(summary["keys"]) == {"api_key", "prompt"}
+ # Summary must be strictly structural: key count only, never a
+ # value-dependent measure (e.g. len(str(request))) that leaks payload size.
+ assert summary["key_count"] == 2
+ assert "size" not in summary
+
+ async def test_exception_propagates_and_history_records_failure(self):
+ class _ErrorAdapter(_FakeAdapter):
+ async def send_request(self, request, context):
+ raise ValueError("bad request")
+=======
assert summary["keys"] == ["prompt"]
assert "api_key" not in summary["keys"]
assert "sk-user-controlled-key" not in str(summary)
@@ -427,6 +515,7 @@ async def send_request(
context: MCPContext,
) -> dict[str, Any]:
raise ValueError("bad request sk-should-not-persist")
+>>>>>>> origin/main
bridge = MCPProtocolBridge()
bridge.register_adapter(_ErrorAdapter(ProtocolType.MCP))
@@ -443,6 +532,8 @@ async def send_request(
# History should contain the failed entry
last = context.history[-1]
assert last["details"]["success"] is False
+<<<<<<< HEAD
+=======
assert last["details"]["error"] == {"type": "ValueError"}
assert "sk-should-not-persist" not in str(last["details"])
@@ -495,6 +586,7 @@ async def send_request(
"success": 0,
"failure": 1,
}
+>>>>>>> origin/main
# ===========================================================================
@@ -552,6 +644,16 @@ async def test_all_connected_used_when_no_preference(self):
class _CapableAdapter(_FakeAdapter):
+<<<<<<< HEAD
+ def __init__(self, ptype, capabilities):
+ super().__init__(ptype)
+ self._capabilities = capabilities
+
+ async def send_request(self, request, context):
+ return {"status": "ok", "protocol": self._ptype.value}
+
+ async def get_capabilities(self):
+=======
def __init__(self, ptype: ProtocolType, capabilities: list[ServerCapability]) -> None:
super().__init__(ptype)
self._capabilities = capabilities
@@ -560,18 +662,27 @@ async def send_request(self, request: dict[str, Any], context: MCPContext) -> di
return {"status": "ok", "protocol": self._ptype.value}
async def get_capabilities(self) -> list[ServerCapability]:
+>>>>>>> origin/main
return self._capabilities
class TestMCPProtocolBridgeIntelligentRouting:
+<<<<<<< HEAD
+ async def _bridge_with(self, *adapters):
+=======
async def _bridge_with(self, *adapters: ProtocolAdapter) -> MCPProtocolBridge:
+>>>>>>> origin/main
bridge = MCPProtocolBridge()
for adapter in adapters:
bridge.register_adapter(adapter)
await bridge.initialize_adapter(adapter.protocol_type, {})
return bridge
+<<<<<<< HEAD
+ async def test_routes_to_protocol_with_required_capability(self):
+=======
async def test_routes_to_protocol_with_required_capability(self) -> None:
+>>>>>>> origin/main
bridge = await self._bridge_with(
_CapableAdapter(ProtocolType.MCP, [ServerCapability.DATA_PROCESSING]),
_CapableAdapter(ProtocolType.OPENAI, [ServerCapability.AI_INFERENCE]),
@@ -581,6 +692,9 @@ async def test_routes_to_protocol_with_required_capability(self) -> None:
)
assert resp["protocol"] == "openai"
+<<<<<<< HEAD
+ async def test_accepts_server_capability_enum_values(self):
+=======
async def test_required_capabilities_are_not_forwarded(self) -> None:
class _RecordingAdapter(_CapableAdapter):
def __init__(self) -> None:
@@ -611,6 +725,7 @@ async def send_request(
assert adapter.request == {"jsonrpc": "2.0", "method": "tools/call"}
async def test_accepts_server_capability_enum_values(self) -> None:
+>>>>>>> origin/main
bridge = await self._bridge_with(
_CapableAdapter(ProtocolType.MCP, [ServerCapability.DATA_PROCESSING]),
_CapableAdapter(ProtocolType.OPENAI, [ServerCapability.AI_INFERENCE]),
@@ -620,7 +735,11 @@ async def test_accepts_server_capability_enum_values(self) -> None:
)
assert resp["protocol"] == "openai"
+<<<<<<< HEAD
+ async def test_raises_when_no_protocol_supports_capability(self):
+=======
async def test_raises_when_no_protocol_supports_capability(self) -> None:
+>>>>>>> origin/main
bridge = await self._bridge_with(
_CapableAdapter(ProtocolType.MCP, [ServerCapability.DATA_PROCESSING]),
)
@@ -629,9 +748,15 @@ async def test_raises_when_no_protocol_supports_capability(self) -> None:
{"required_capabilities": [ServerCapability.AI_INFERENCE]}
)
+<<<<<<< HEAD
+ async def test_skips_protocol_when_get_capabilities_raises(self):
+ class _BrokenCapsAdapter(_CapableAdapter):
+ async def get_capabilities(self):
+=======
async def test_skips_protocol_when_get_capabilities_raises(self) -> None:
class _BrokenCapsAdapter(_CapableAdapter):
async def get_capabilities(self) -> list[ServerCapability]:
+>>>>>>> origin/main
raise ConnectionError("unreachable")
bridge = await self._bridge_with(
@@ -643,6 +768,9 @@ async def get_capabilities(self) -> list[ServerCapability]:
)
assert resp["protocol"] == "openai"
+<<<<<<< HEAD
+ async def test_prefers_less_loaded_protocol(self):
+=======
async def test_skips_protocol_when_capability_discovery_times_out(self) -> None:
class _HangingCapsAdapter(_CapableAdapter):
async def get_capabilities(self) -> list[ServerCapability]:
@@ -668,6 +796,7 @@ async def get_capabilities(self) -> list[ServerCapability]:
assert response["protocol"] == "openai"
async def test_prefers_less_loaded_protocol(self) -> None:
+>>>>>>> origin/main
bridge = await self._bridge_with(
_CapableAdapter(ProtocolType.MCP, [ServerCapability.AI_INFERENCE]),
_CapableAdapter(ProtocolType.OPENAI, [ServerCapability.AI_INFERENCE]),
@@ -681,7 +810,11 @@ async def test_prefers_less_loaded_protocol(self) -> None:
resp = await bridge.route_request({})
assert resp["protocol"] == "openai"
+<<<<<<< HEAD
+ async def test_prefers_lower_error_rate_when_load_equal(self):
+=======
async def test_prefers_lower_error_rate_when_load_equal(self) -> None:
+>>>>>>> origin/main
bridge = await self._bridge_with(
_CapableAdapter(ProtocolType.MCP, [ServerCapability.AI_INFERENCE]),
_CapableAdapter(ProtocolType.OPENAI, [ServerCapability.AI_INFERENCE]),
@@ -695,7 +828,11 @@ async def test_prefers_lower_error_rate_when_load_equal(self) -> None:
resp = await bridge.route_request({})
assert resp["protocol"] == "openai"
+<<<<<<< HEAD
+ async def test_preference_order_breaks_ties(self):
+=======
async def test_preference_order_breaks_ties(self) -> None:
+>>>>>>> origin/main
bridge = await self._bridge_with(
_CapableAdapter(ProtocolType.MCP, [ServerCapability.AI_INFERENCE]),
_CapableAdapter(ProtocolType.OPENAI, [ServerCapability.AI_INFERENCE]),
@@ -705,7 +842,11 @@ async def test_preference_order_breaks_ties(self) -> None:
)
assert resp["protocol"] == "openai"
+<<<<<<< HEAD
+ async def test_unknown_capability_string_raises_value_error(self):
+=======
async def test_unknown_capability_string_raises_value_error(self) -> None:
+>>>>>>> origin/main
bridge = await self._bridge_with(
_CapableAdapter(ProtocolType.MCP, [ServerCapability.AI_INFERENCE]),
)
@@ -714,7 +855,11 @@ async def test_unknown_capability_string_raises_value_error(self) -> None:
{"required_capabilities": ["not_a_real_capability"]}
)
+<<<<<<< HEAD
+ async def test_bare_string_required_capabilities_raises_type_error(self):
+=======
async def test_bare_string_required_capabilities_raises_type_error(self) -> None:
+>>>>>>> origin/main
# A bare string must not be iterated character-by-character.
bridge = await self._bridge_with(
_CapableAdapter(ProtocolType.MCP, [ServerCapability.AI_INFERENCE]),
@@ -724,7 +869,11 @@ async def test_bare_string_required_capabilities_raises_type_error(self) -> None
{"required_capabilities": "ai_inference"}
)
+<<<<<<< HEAD
+ async def test_stats_updated_after_successful_request(self):
+=======
async def test_stats_updated_after_successful_request(self) -> None:
+>>>>>>> origin/main
bridge = await self._bridge_with(
_CapableAdapter(ProtocolType.MCP, [ServerCapability.AI_INFERENCE]),
)
@@ -732,6 +881,11 @@ async def test_stats_updated_after_successful_request(self) -> None:
stats = bridge.protocol_stats[ProtocolType.MCP]
assert stats == {"in_flight": 0, "success": 1, "failure": 0}
+<<<<<<< HEAD
+ async def test_stats_updated_after_failed_request(self):
+ class _ErrorAdapter(_FakeAdapter):
+ async def send_request(self, request, context):
+=======
async def test_stats_updated_after_failed_request(self) -> None:
class _ErrorAdapter(_FakeAdapter):
async def send_request(
@@ -739,6 +893,7 @@ async def send_request(
request: dict[str, Any],
context: MCPContext,
) -> dict[str, Any]:
+>>>>>>> origin/main
raise ValueError("bad request")
bridge = MCPProtocolBridge()
@@ -751,7 +906,11 @@ async def send_request(
stats = bridge.protocol_stats[ProtocolType.MCP]
assert stats == {"in_flight": 0, "success": 0, "failure": 1}
+<<<<<<< HEAD
+ async def test_partial_pre_existing_stats_dict_does_not_raise(self):
+=======
async def test_partial_pre_existing_stats_dict_does_not_raise(self) -> None:
+>>>>>>> origin/main
# A pre-populated stats dict missing some counters must not cause a
# KeyError when a request increments them.
bridge = await self._bridge_with(
@@ -837,6 +996,8 @@ async def test_multiple_adapters_checked(self):
GoogleAIAdapter = _pb_mod.GoogleAIAdapter
+<<<<<<< HEAD
+=======
def _dns_result(ip: str, port: int = 443) -> tuple:
"""Build a getaddrinfo()-style result tuple for the given IPv4 address."""
return (_pb_mod.socket.AF_INET, _pb_mod.socket.SOCK_STREAM, 6, "", (ip, port))
@@ -883,6 +1044,7 @@ async def test_rejects_dns_resolution_error(self) -> None:
)
+>>>>>>> origin/main
class TestOpenAIAdapter:
def test_protocol_type(self):
adapter = OpenAIAdapter()
@@ -917,6 +1079,15 @@ async def test_initialize_default_base_url(self):
await adapter.initialize({"api_key": "sk-test"})
assert adapter.base_url == "https://api.openai.com/v1"
+<<<<<<< HEAD
+ async def test_initialize_accepts_custom_https_base_url(self):
+ adapter = OpenAIAdapter()
+ result = await adapter.initialize(
+ {"api_key": "sk-test", "base_url": "https://proxy.example.com/v1"}
+ )
+ assert result is True
+ assert adapter.base_url == "https://proxy.example.com/v1"
+=======
async def test_initialize_accepts_custom_https_base_url(self, monkeypatch):
adapter = OpenAIAdapter()
monkeypatch.setenv(
@@ -948,6 +1119,7 @@ async def test_initialize_rejects_unallowlisted_custom_base_url(self) -> None:
)
assert result is False
getaddrinfo.assert_not_called()
+>>>>>>> origin/main
async def test_initialize_rejects_metadata_endpoint_base_url(self):
adapter = OpenAIAdapter()
@@ -982,6 +1154,8 @@ async def test_initialize_rejects_non_string_base_url(self):
)
assert result is False
+<<<<<<< HEAD
+=======
async def test_initialize_rejects_loopback_https_base_url(self) -> None:
adapter = OpenAIAdapter()
result = await adapter.initialize({"api_key": "sk-test", "base_url": "https://127.0.0.1"})
@@ -1049,6 +1223,7 @@ async def test_initialize_rejects_malformed_dns_result(self) -> None:
)
assert result is False
+>>>>>>> origin/main
async def test_health_check_returns_false_when_not_initialized(self):
adapter = OpenAIAdapter()
assert await adapter.health_check() is False
diff --git a/tests/unit/test_memory_manager.py b/tests/unit/test_memory_manager.py
index 5f70ebfdd..a0a5c4659 100644
--- a/tests/unit/test_memory_manager.py
+++ b/tests/unit/test_memory_manager.py
@@ -4,6 +4,11 @@
import gc
import sys
+<<<<<<< HEAD
+import time
+from datetime import datetime, timezone
+from pathlib import Path
+=======
import threading
import time
import types
@@ -11,6 +16,7 @@
from datetime import datetime, timezone
from pathlib import Path
from unittest.mock import MagicMock
+>>>>>>> origin/main
# Remove any mock installed by test_index_analysis.py so we get real psutil
sys.modules.pop('psutil', None)
@@ -32,6 +38,8 @@
)
+<<<<<<< HEAD
+=======
@pytest.fixture(autouse=True)
def _deterministic_process_metrics(monkeypatch):
"""Keep unit tests independent of the runner's PID namespace."""
@@ -62,6 +70,7 @@ def _deterministic_process_metrics(monkeypatch):
monkeypatch.setattr(module, "psutil", fake_psutil)
+>>>>>>> origin/main
# ===========================================================================
# MemorySnapshot dataclass
# ===========================================================================
@@ -715,6 +724,10 @@ def test_detect_leaks_no_baseline_returns_empty(self):
# ===========================================================================
# MemoryManager._take_system_snapshot (lines around 337-362)
+<<<<<<< HEAD
+# gc.get_stats() returns dicts, so we patch it to return ints to exercise the code
+=======
+>>>>>>> origin/main
# ===========================================================================
@@ -737,6 +750,12 @@ def _get_patched_snapshot(self, rss_bytes=100*1024*1024, vms_bytes=200*1024*1024
manager = _mod.MemoryManager()
orig_psutil = _mod.psutil
_mod.psutil = fake
+<<<<<<< HEAD
+ # gc.get_stats() returns a list of dicts — patch to return [0,0,0] so sum() works
+ try:
+ with patch('youtube_extension.backend.services.memory_manager.gc') as mock_gc:
+ mock_gc.get_stats.return_value = [0, 0, 0] # summable ints
+=======
try:
with patch('youtube_extension.backend.services.memory_manager.gc') as mock_gc:
mock_gc.get_stats.return_value = [
@@ -744,6 +763,7 @@ def _get_patched_snapshot(self, rss_bytes=100*1024*1024, vms_bytes=200*1024*1024
{"collections": 3},
{"collections": 5},
]
+>>>>>>> origin/main
mock_gc.get_objects.return_value = []
snap = manager._take_system_snapshot()
finally:
@@ -763,10 +783,13 @@ def test_snapshot_percent_stored(self):
snap, _ = self._get_patched_snapshot(percent=75.0)
assert snap.percent == 75.0
+<<<<<<< HEAD
+=======
def test_snapshot_sums_gc_collections(self):
snap, _ = self._get_patched_snapshot()
assert snap.gc_collections == 10
+>>>>>>> origin/main
def test_snapshot_vms_computed_correctly(self):
vms_bytes = 300 * 1024 * 1024
snap, _ = self._get_patched_snapshot(vms_bytes=vms_bytes)
@@ -1102,9 +1125,14 @@ def bad_cleanup(r):
"bad", lambda: object(), bad_cleanup, max_size=5
)
pool.pool.append(object())
+<<<<<<< HEAD
+ # Should not raise
+ manager._cleanup_resource_pools()
+=======
# Failed closes are removed from reuse but never counted as successful.
assert pool.cleanup_idle_resources(force=True) == 0
manager.close()
+>>>>>>> origin/main
# ===========================================================================
@@ -1250,6 +1278,13 @@ def test_start_monitoring_idempotent(self):
assert task1 is task2
manager.stop_monitoring()
+<<<<<<< HEAD
+ def test_stop_monitoring_clears_flag(self):
+ manager = MemoryManager()
+ manager.start_monitoring()
+ manager.stop_monitoring()
+ assert manager.monitoring_enabled is False
+=======
def test_concurrent_starts_create_one_monitor(self, monkeypatch):
import youtube_extension.backend.services.memory_manager as module
@@ -1299,6 +1334,7 @@ def test_slow_stopping_monitor_cannot_be_duplicated(self):
manager.start_monitoring()
assert manager.monitoring_task is stopping_task
stopping_task.start.assert_not_called()
+>>>>>>> origin/main
# ===========================================================================
@@ -1370,6 +1406,8 @@ def test_force_cleanup_does_not_raise(self):
class TestResourcePoolEdgeCases:
+<<<<<<< HEAD
+=======
def test_close_stops_cleanup_worker(self):
pool = ResourcePool("closable", lambda: object(), lambda r: None)
task = pool.cleanup_task
@@ -1397,6 +1435,7 @@ def test_cleanup_worker_does_not_retain_abandoned_pool(self):
assert last_ref() is None
assert not any(task.is_alive() for task in tasks)
+>>>>>>> origin/main
def test_reuses_released_resource(self):
created = []
def create_fn():
diff --git a/tests/unit/test_memory_optimizer.py b/tests/unit/test_memory_optimizer.py
index dd34605b8..c586821a0 100644
--- a/tests/unit/test_memory_optimizer.py
+++ b/tests/unit/test_memory_optimizer.py
@@ -3,7 +3,10 @@
from __future__ import annotations
import sys
+<<<<<<< HEAD
+=======
import types
+>>>>>>> origin/main
from datetime import datetime, timezone
from pathlib import Path
@@ -25,6 +28,8 @@
)
+<<<<<<< HEAD
+=======
@pytest.fixture(autouse=True)
def _deterministic_process_metrics(monkeypatch):
"""Keep unit tests independent of the runner's PID namespace."""
@@ -44,6 +49,7 @@ def _deterministic_process_metrics(monkeypatch):
monkeypatch.setattr(module, "psutil", fake_psutil)
+>>>>>>> origin/main
# ===========================================================================
# MemorySnapshot dataclass
# ===========================================================================
diff --git a/tests/unit/test_misc_services.py b/tests/unit/test_misc_services.py
index c52d36124..d6b64839e 100644
--- a/tests/unit/test_misc_services.py
+++ b/tests/unit/test_misc_services.py
@@ -1086,6 +1086,8 @@ async def test_in_memory_record_and_query(self):
from youtube_extension.processors.strategies import EnhancedStrategy
+<<<<<<< HEAD
+=======
@pytest.fixture(autouse=True)
def _disable_external_strategy_clients(monkeypatch):
"""These heuristic tests do not exercise Google or Gemini client setup."""
@@ -1095,6 +1097,7 @@ def _disable_external_strategy_clients(monkeypatch):
monkeypatch.setattr(strategies, "HAS_AI_DEPS", False)
+>>>>>>> origin/main
class TestEnhancedStrategyExtractKeyPoints:
def test_returns_list(self):
enh = EnhancedStrategy()
diff --git a/tests/unit/test_orchestrator_consumer.py b/tests/unit/test_orchestrator_consumer.py
index 2cf2575e9..92825e773 100644
--- a/tests/unit/test_orchestrator_consumer.py
+++ b/tests/unit/test_orchestrator_consumer.py
@@ -80,3 +80,60 @@ async def test_process_fails_loudly_until_implemented() -> None:
# The stub must raise so the consumer never xack's unprocessed work.
with pytest.raises(NotImplementedError):
await process({"field": "value"})
+<<<<<<< HEAD
+=======
+
+
+@pytest.mark.asyncio
+async def test_main_loop_with_redis(monkeypatch) -> None:
+ from unittest.mock import MagicMock, patch
+ import youtube_extension.orchestrator.main as orch_main
+
+ mock_stop_event = MagicMock()
+ mock_stop_event.is_set.side_effect = [False, True]
+
+ mock_redis_client = AsyncMock()
+ mock_redis = MagicMock()
+ mock_redis.from_url.return_value = mock_redis_client
+
+ mock_loop = MagicMock()
+
+ monkeypatch.setenv("REDIS_URL", "redis://localhost:6379")
+ monkeypatch.setenv("ORCHESTRATOR_QUEUE_NAME", "test_stream")
+ monkeypatch.setenv("ORCHESTRATOR_CONSUMER_GROUP", "test_group")
+
+ with patch("asyncio.get_running_loop", return_value=mock_loop), \
+ patch("asyncio.Event", return_value=mock_stop_event), \
+ patch("youtube_extension.orchestrator.main.redis", mock_redis), \
+ patch("youtube_extension.orchestrator.main.ensure_consumer_group", new_callable=AsyncMock) as mock_ensure:
+
+ mock_redis_client.xreadgroup.return_value = [
+ ("test_stream", [("msg_id", {"data": "val"})])
+ ]
+
+ await orch_main.main()
+
+ mock_redis.from_url.assert_called_once()
+ mock_ensure.assert_called_once_with(mock_redis_client, "test_stream", "test_group")
+ mock_redis_client.xreadgroup.assert_called_once()
+ mock_redis_client.aclose.assert_called_once()
+
+
+@pytest.mark.asyncio
+async def test_main_loop_standby() -> None:
+ from unittest.mock import MagicMock, patch
+ import youtube_extension.orchestrator.main as orch_main
+
+ mock_stop_event = MagicMock()
+ mock_stop_event.is_set.side_effect = [False, True]
+ mock_loop = MagicMock()
+
+ with patch("asyncio.get_running_loop", return_value=mock_loop), \
+ patch("asyncio.Event", return_value=mock_stop_event), \
+ patch("youtube_extension.orchestrator.main.redis", None), \
+ patch("asyncio.sleep", new_callable=AsyncMock) as mock_sleep:
+
+ await orch_main.main()
+ mock_sleep.assert_called_once_with(60)
+
+>>>>>>> origin/main
diff --git a/tests/unit/test_performance_benchmark_system.py b/tests/unit/test_performance_benchmark_system.py
index 45ccce288..f02f7149b 100644
--- a/tests/unit/test_performance_benchmark_system.py
+++ b/tests/unit/test_performance_benchmark_system.py
@@ -1011,6 +1011,8 @@ async def _fast_benchmark(iterations=5, include_baseline=False):
class TestRunComprehensiveBenchmark:
"""Cover the main orchestration method."""
+<<<<<<< HEAD
+=======
@pytest.fixture(autouse=True)
def _isolate_component_benchmarks(self, monkeypatch):
"""Keep orchestration tests deterministic and provider-free."""
@@ -1042,6 +1044,7 @@ async def _run(_system, _iterations):
_safe_component(summary),
)
+>>>>>>> origin/main
def _make_psutil_fake(self):
import types
return types.SimpleNamespace(
@@ -1147,6 +1150,8 @@ async def _raise(*a, **kw):
class TestBenchmarkVideoProcessing:
+<<<<<<< HEAD
+=======
@pytest.fixture(autouse=True)
def _provider_free_processor(self, monkeypatch):
import youtube_extension.backend.services.performance_benchmark_system as _mod
@@ -1163,6 +1168,7 @@ async def process_batch(self, _urls, options=None):
monkeypatch.setattr(_mod, "VideoProcessor", _FailingProcessor)
+>>>>>>> origin/main
def _make_psutil_fake(self):
import types
return types.SimpleNamespace(
@@ -1175,7 +1181,11 @@ async def test_video_processing_returns_dict_on_error(self, monkeypatch):
import types
import youtube_extension.backend.services.performance_benchmark_system as _mod
monkeypatch.setattr(_mod, "psutil", self._make_psutil_fake())
+<<<<<<< HEAD
+ # VideoProcessor.process_video raises RuntimeError (the fallback stub)
+=======
# The class fixture supplies a deterministic provider-free failure.
+>>>>>>> origin/main
system = PerformanceBenchmarkSystem()
result = await system._benchmark_video_processing(iterations=1)
assert isinstance(result, dict)
diff --git a/tests/unit/test_processors_strategies.py b/tests/unit/test_processors_strategies.py
index 793ee6a42..aca8d82a7 100644
--- a/tests/unit/test_processors_strategies.py
+++ b/tests/unit/test_processors_strategies.py
@@ -34,6 +34,8 @@
_VALID_ID = "auJzb1D-fag"
+<<<<<<< HEAD
+=======
@pytest.fixture(autouse=True)
def _disable_external_strategy_clients(monkeypatch):
"""Pure strategy tests must not initialize Google clients or require ADC."""
@@ -41,6 +43,7 @@ def _disable_external_strategy_clients(monkeypatch):
monkeypatch.setattr(_mod, "HAS_AI_DEPS", False)
+>>>>>>> origin/main
# ===========================================================================
# cache_get / cache_set
# ===========================================================================
diff --git a/tests/unit/test_proxy.py b/tests/unit/test_proxy.py
new file mode 100644
index 000000000..1aa2afe38
--- /dev/null
+++ b/tests/unit/test_proxy.py
@@ -0,0 +1,52 @@
+import os
+import pytest
+from youtube_extension.utils.proxy import (
+ get_proxy_url,
+ get_proxy_dict,
+ get_transcript_proxy_config,
+ redact_proxy_credentials,
+)
+
+def test_get_proxy_url_unset(monkeypatch):
+ monkeypatch.delenv("WEBSHARE_PROXY_URL", raising=False)
+ assert get_proxy_url() is None
+
+def test_get_proxy_url_valid(monkeypatch):
+ monkeypatch.setenv("WEBSHARE_PROXY_URL", "http://user:pass@127.0.0.1:8080")
+ assert get_proxy_url() == "http://user:pass@127.0.0.1:8080"
+
+def test_get_proxy_url_malformed(monkeypatch):
+ monkeypatch.setenv("WEBSHARE_PROXY_URL", "ftp://invalid-scheme.com")
+ assert get_proxy_url() is None
+
+def test_get_proxy_dict(monkeypatch):
+ monkeypatch.delenv("WEBSHARE_PROXY_URL", raising=False)
+ assert get_proxy_dict() is None
+
+ monkeypatch.setenv("WEBSHARE_PROXY_URL", "http://127.0.0.1:8080")
+ assert get_proxy_dict() == {
+ "http": "http://127.0.0.1:8080",
+ "https": "http://127.0.0.1:8080",
+ }
+
+def test_get_transcript_proxy_config(monkeypatch):
+ monkeypatch.delenv("WEBSHARE_PROXY_URL", raising=False)
+ assert get_transcript_proxy_config() is None
+
+ monkeypatch.setenv("WEBSHARE_PROXY_URL", "http://127.0.0.1:8080")
+ config = get_transcript_proxy_config()
+ # It might be None or a GenericProxyConfig depending on HAS_PROXY_CONFIG
+ # Just verify it doesn't crash
+ if config is not None:
+ assert config.http_url == "http://127.0.0.1:8080"
+
+def test_redact_proxy_credentials(monkeypatch):
+ monkeypatch.delenv("WEBSHARE_PROXY_URL", raising=False)
+ assert redact_proxy_credentials("some proxy info http://127.0.0.1") == "some proxy info http://127.0.0.1"
+
+ proxy_url = "http://user:pass@127.0.0.1:8080"
+ monkeypatch.setenv("WEBSHARE_PROXY_URL", proxy_url)
+ text = f"Connecting to {proxy_url} to download..."
+ redacted = redact_proxy_credentials(text)
+ assert "user:pass" not in redacted
+ assert "127.0.0.1:8080" in redacted
diff --git a/tests/unit/test_real_processors.py b/tests/unit/test_real_processors.py
index ef0965e4a..b0fef0616 100644
--- a/tests/unit/test_real_processors.py
+++ b/tests/unit/test_real_processors.py
@@ -14,6 +14,11 @@
import json
import sys
+<<<<<<< HEAD
+import types
+import importlib
+=======
+>>>>>>> origin/main
from pathlib import Path
from unittest.mock import AsyncMock, MagicMock, patch, call
@@ -27,7 +32,43 @@
sys.path.insert(0, str(_SRC))
# ---------------------------------------------------------------------------
+<<<<<<< HEAD
+# Pre-stub heavy / unavailable packages before any module import
+# ---------------------------------------------------------------------------
+
+def _stub_module(name: str, **attrs):
+ """Ensure *name* is stubbed in sys.modules with the expected attributes."""
+ mod = sys.modules.get(name)
+ if mod is None:
+ mod = types.ModuleType(name)
+ sys.modules[name] = mod
+ for k, v in attrs.items():
+ setattr(mod, k, v)
+ return mod
+
+
+# google.genai
+_google = _stub_module("google")
+_google_genai = _stub_module("google.genai", Client=MagicMock())
+_google.genai = _google_genai
+
+# openai
+_openai_mod = _stub_module("openai", AsyncOpenAI=MagicMock())
+
+# anthropic
+_anthropic_mod = _stub_module("anthropic", AsyncAnthropic=MagicMock())
+
+# dotenv
+_stub_module("dotenv", load_dotenv=lambda *args, **kwargs: None)
+
+# pytubefix (used by some transitive imports)
+_stub_module("pytubefix")
+
+# ---------------------------------------------------------------------------
+# Import modules under test *after* stubs are in place
+=======
# Import modules under test
+>>>>>>> origin/main
# ---------------------------------------------------------------------------
from youtube_extension.backend.services.real_ai_processor import ( # noqa: E402
AIProcessingRequest,
@@ -109,6 +150,8 @@ def _make_ai_analysis(success: bool = True) -> dict:
# ---------------------------------------------------------------------------
@pytest.fixture(autouse=True)
+<<<<<<< HEAD
+=======
def _isolate_ai_provider_bindings(monkeypatch):
"""Keep provider doubles local even when another test imported first.
@@ -135,6 +178,7 @@ def _isolate_ai_provider_bindings(monkeypatch):
@pytest.fixture(autouse=True)
+>>>>>>> origin/main
def _reset_ai_processor_singleton():
"""Ensure the module-level singleton is reset between tests."""
import youtube_extension.backend.services.real_ai_processor as _mod
diff --git a/tests/unit/test_robust_youtube_service.py b/tests/unit/test_robust_youtube_service.py
index 964e32cf1..f76124e5b 100644
--- a/tests/unit/test_robust_youtube_service.py
+++ b/tests/unit/test_robust_youtube_service.py
@@ -150,6 +150,8 @@ def _make_service(api_key: str = "FAKE_KEY") -> RobustYouTubeService:
return svc
+<<<<<<< HEAD
+=======
@pytest.fixture
def isolated_http_client():
"""Provide an inert session for tests that exercise session orchestration."""
@@ -160,6 +162,7 @@ def isolated_http_client():
yield session
+>>>>>>> origin/main
# ---------------------------------------------------------------------------
# RobustYouTubeMetadata dataclass
# ---------------------------------------------------------------------------
@@ -282,7 +285,11 @@ async def test_aexit_with_no_session(self):
# Should not raise
await svc.__aexit__(None, None, None)
+<<<<<<< HEAD
+ async def test_as_context_manager(self):
+=======
async def test_as_context_manager(self, isolated_http_client):
+>>>>>>> origin/main
with patch.object(
RobustYouTubeService,
"_get_metadata_youtube_api",
@@ -1260,7 +1267,11 @@ async def test_all_fail_returns_unavailable(self):
assert result["text"] == ""
assert "error" in result
+<<<<<<< HEAD
+ async def test_creates_session_if_none_for_innertube(self):
+=======
async def test_creates_session_if_none_for_innertube(self, isolated_http_client):
+>>>>>>> origin/main
"""get_transcript creates a session when self.session is None."""
svc = RobustYouTubeService(api_key="KEY")
svc.session = None
@@ -1278,7 +1289,11 @@ async def test_creates_session_if_none_for_innertube(self, isolated_http_client)
result = await svc.get_transcript(VIDEO_ID)
assert result["source"] == "innertube_android"
+<<<<<<< HEAD
+ assert svc.session is not None
+=======
assert svc.session is isolated_http_client
+>>>>>>> origin/main
async def test_transcript_api_list_transcripts_also_fails(self):
"""Both instance fetch and list_transcripts fail -> falls through to innertube."""
@@ -1330,7 +1345,11 @@ async def test_transcript_api_not_installed_logs_warning(self):
class TestConvenienceFunctions:
+<<<<<<< HEAD
+ async def test_get_video_metadata_robust(self):
+=======
async def test_get_video_metadata_robust(self, isolated_http_client):
+>>>>>>> origin/main
expected = MagicMock(spec=RobustYouTubeMetadata)
with patch.object(
RobustYouTubeService,
@@ -1341,7 +1360,11 @@ async def test_get_video_metadata_robust(self, isolated_http_client):
result = await get_video_metadata_robust(VIDEO_URL, api_key="KEY")
assert result is expected
+<<<<<<< HEAD
+ async def test_get_video_transcript_robust(self):
+=======
async def test_get_video_transcript_robust(self, isolated_http_client):
+>>>>>>> origin/main
expected = {
"text": "hello",
"source": "youtube_transcript_api",
@@ -1358,11 +1381,19 @@ async def test_get_video_transcript_robust(self, isolated_http_client):
result = await get_video_transcript_robust(VIDEO_ID, api_key="KEY", language="en")
assert result is expected
+<<<<<<< HEAD
+ async def test_get_video_metadata_robust_no_api_key(self):
+ """Should work without an api_key (uses env var fallback)."""
+ expected = MagicMock(spec=RobustYouTubeMetadata)
+ with (
+ patch.dict("os.environ", {}, clear=False),
+=======
async def test_get_video_metadata_robust_no_api_key(self, isolated_http_client):
"""Should work without an api_key (uses env var fallback)."""
expected = MagicMock(spec=RobustYouTubeMetadata)
with (
patch.dict("os.environ", {}, clear=True),
+>>>>>>> origin/main
patch.object(
RobustYouTubeService,
"get_video_metadata",
diff --git a/tests/unit/test_security_middleware.py b/tests/unit/test_security_middleware.py
index 162533294..115f708fd 100644
--- a/tests/unit/test_security_middleware.py
+++ b/tests/unit/test_security_middleware.py
@@ -73,5 +73,28 @@ async def test_endpoint():
assert response.headers["Content-Security-Policy"] == custom_csp
+<<<<<<< HEAD
if __name__ == "__main__":
pytest.main([__file__, "-v"])
+=======
+def test_create_security_headers_middleware():
+ """Test factory for security headers middleware"""
+ from src.youtube_extension.backend.middleware.security_headers import create_security_headers_middleware
+
+ middleware_cls = create_security_headers_middleware(enable_hsts=True)
+ app = FastAPI()
+ app.add_middleware(middleware_cls)
+
+ @app.get("/test")
+ async def test_endpoint():
+ return {"message": "test"}
+
+ client = TestClient(app, base_url="https://testserver")
+ response = client.get("/test")
+ assert "Strict-Transport-Security" in response.headers
+
+
+if __name__ == "__main__":
+ pytest.main([__file__, "-v"])
+
+>>>>>>> origin/main
diff --git a/tests/unit/test_speech_to_text_service.py b/tests/unit/test_speech_to_text_service.py
index 4413df8de..d220f0f48 100644
--- a/tests/unit/test_speech_to_text_service.py
+++ b/tests/unit/test_speech_to_text_service.py
@@ -2,11 +2,98 @@
from __future__ import annotations
+<<<<<<< HEAD
+import sys
+import types
+from pathlib import Path
+=======
+>>>>>>> origin/main
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
+<<<<<<< HEAD
+# ---------------------------------------------------------------------------
+# Add src to path first so module resolution works.
+# ---------------------------------------------------------------------------
+_SRC = Path(__file__).resolve().parents[2] / "src"
+sys.path.insert(0, str(_SRC))
+
+# ---------------------------------------------------------------------------
+# Stub optional heavy dependencies BEFORE importing the service module so
+# that the try/except import guards fire with the stub modules and all three
+# AVAILABLE flags are set to False (the stubs lack the real classes).
+# ---------------------------------------------------------------------------
+
+# Stub google.api_core
+_api_core = types.ModuleType("google.api_core")
+_api_core.exceptions = types.ModuleType("google.api_core.exceptions") # type: ignore[attr-defined]
+sys.modules.setdefault("google.api_core", _api_core)
+sys.modules.setdefault("google.api_core.exceptions", _api_core.exceptions) # type: ignore[attr-defined]
+
+# Stub google.cloud namespace
+_gcloud = sys.modules.get("google.cloud") or types.ModuleType("google.cloud")
+sys.modules.setdefault("google.cloud", _gcloud)
+
+# Stub google.cloud.speech_v2
+_speech = types.ModuleType("google.cloud.speech_v2")
+sys.modules.setdefault("google.cloud.speech_v2", _speech)
+
+# Stub google.cloud.storage
+_storage_stub = types.ModuleType("google.cloud.storage")
+sys.modules.setdefault("google.cloud.storage", _storage_stub)
+
+# Stub yt_dlp
+_ytdlp = types.ModuleType("yt_dlp")
+sys.modules.setdefault("yt_dlp", _ytdlp)
+
+# Stub google parent package so attribute lookups don't fail
+_google = sys.modules.get("google") or types.ModuleType("google")
+_google.cloud = _gcloud # type: ignore[attr-defined]
+_google.api_core = _api_core # type: ignore[attr-defined]
+sys.modules.setdefault("google", _google)
+
+# ---------------------------------------------------------------------------
+# Stub the youtube_extension.services parent packages so importing the leaf
+# module does not trigger the full services/__init__.py import chain (which
+# pulls in deployment_manager -> broken native extensions).
+# ---------------------------------------------------------------------------
+
+def _stub_package(name: str, path: str | None = None) -> types.ModuleType:
+ if name not in sys.modules:
+ m = types.ModuleType(name)
+ m.__path__ = [path or ""] # type: ignore[assignment]
+ m.__package__ = name
+ sys.modules[name] = m
+ return sys.modules[name]
+
+
+_stub_package("youtube_extension")
+_stub_package(
+ "youtube_extension.services",
+ str(_SRC / "youtube_extension" / "services"),
+)
+_stub_package(
+ "youtube_extension.services.ai",
+ str(_SRC / "youtube_extension" / "services" / "ai"),
+)
+
+# Ensure the module itself is freshly imported (no cached version from a prior run)
+sys.modules.pop("youtube_extension.services.ai.speech_to_text_service", None)
+
+# Now import the leaf module directly by its file path to avoid any __init__ chain.
+import importlib.util as _ilu
+
+_spec = _ilu.spec_from_file_location(
+ "youtube_extension.services.ai.speech_to_text_service",
+ _SRC / "youtube_extension" / "services" / "ai" / "speech_to_text_service.py",
+)
+_stt_mod = _ilu.module_from_spec(_spec) # type: ignore[arg-type]
+sys.modules["youtube_extension.services.ai.speech_to_text_service"] = _stt_mod
+_spec.loader.exec_module(_stt_mod) # type: ignore[union-attr]
+=======
import youtube_extension.services.ai.speech_to_text_service as _stt_mod
+>>>>>>> origin/main
SPEECH_AVAILABLE = _stt_mod.SPEECH_AVAILABLE
STORAGE_AVAILABLE = _stt_mod.STORAGE_AVAILABLE
diff --git a/tests/unit/test_transcript_action_workflow.py b/tests/unit/test_transcript_action_workflow.py
index 8694c3323..e7e7959fa 100644
--- a/tests/unit/test_transcript_action_workflow.py
+++ b/tests/unit/test_transcript_action_workflow.py
@@ -24,6 +24,8 @@
)
+<<<<<<< HEAD
+=======
@pytest.fixture(autouse=True)
def _isolate_skill_builder(monkeypatch, tmp_path) -> None:
"""Workflow unit tests must not use the process user's persistent skills."""
@@ -40,6 +42,7 @@ def _isolate_skill_builder(monkeypatch, tmp_path) -> None:
)
+>>>>>>> origin/main
class _UnexpectedYouTubeService:
async def __aenter__(self):
raise AssertionError("YouTube service should not be entered for playlist URLs")
diff --git a/tests/unit/test_v1_router_extended.py b/tests/unit/test_v1_router_extended.py
index a8144b4ef..57c69ff5e 100644
--- a/tests/unit/test_v1_router_extended.py
+++ b/tests/unit/test_v1_router_extended.py
@@ -13,7 +13,10 @@
import asyncio
import sys
from pathlib import Path
+<<<<<<< HEAD
+=======
from types import SimpleNamespace
+>>>>>>> origin/main
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
@@ -881,6 +884,15 @@ def test_get_video_job_status_not_found(self, client):
class TestEventExtractionEndpoint:
+<<<<<<< HEAD
+ def test_extract_events_from_transcript(self, client):
+ """Use inline transcript — no job_id."""
+ with patch.object(
+ _HybridProcessorService_cls.return_value,
+ "process",
+ new_callable=AsyncMock,
+ return_value="Build a web app\nCreate an API\nDeploy to cloud\n",
+=======
def test_extract_events_from_transcript(self, client, monkeypatch):
"""Use inline transcript — no job_id."""
from youtube_extension.services.ai import vercel_gateway_provider
@@ -904,6 +916,7 @@ def test_extract_events_from_transcript(self, client, monkeypatch):
router_module,
"HybridProcessorService",
return_value=processor,
+>>>>>>> origin/main
):
payload = {
"transcript": (
diff --git a/tests/unit/test_video_processing_service.py b/tests/unit/test_video_processing_service.py
index 87136329a..7f7b7f615 100644
--- a/tests/unit/test_video_processing_service.py
+++ b/tests/unit/test_video_processing_service.py
@@ -257,11 +257,14 @@ def test_returns_none_on_exception(self):
# ===========================================================================
class TestNormalizeResult:
+<<<<<<< HEAD
+=======
@pytest.fixture(autouse=True)
def _block_real_yt_dlp(self, monkeypatch):
"""Normalization tests must not turn an installed adapter into live I/O."""
monkeypatch.setitem(sys.modules, "yt_dlp", None)
+>>>>>>> origin/main
def test_basic_normalization(self):
svc = _make_service()
raw = _success_result()
diff --git a/tests/unit/test_video_processor_facade.py b/tests/unit/test_video_processor_facade.py
new file mode 100644
index 000000000..435af823b
--- /dev/null
+++ b/tests/unit/test_video_processor_facade.py
@@ -0,0 +1,14 @@
+import pytest
+from unittest.mock import AsyncMock, MagicMock
+from youtube_extension.services.video_processor_facade import VideoProcessorFacade, VideoProcessorBackend
+
+@pytest.mark.asyncio
+async def test_facade_dispatches_to_backend():
+ mock_backend = MagicMock(spec=VideoProcessorBackend)
+ mock_backend.process_video = AsyncMock(return_value={"status": "success"})
+
+ facade = VideoProcessorFacade(mock_backend)
+ result = await facade.process("https://www.youtube.com/watch?v=auJzb1D-fag")
+
+ assert result == {"status": "success"}
+ mock_backend.process_video.assert_called_once_with("https://www.youtube.com/watch?v=auJzb1D-fag")
diff --git a/tests/unit/test_video_processor_factory.py b/tests/unit/test_video_processor_factory.py
index 5fb6229aa..5a2e721d5 100644
--- a/tests/unit/test_video_processor_factory.py
+++ b/tests/unit/test_video_processor_factory.py
@@ -508,3 +508,39 @@ def patched_import(name, *args, **kwargs):
factory = _reload_factory()
with pytest.raises(ValueError, match="No working video processor"):
factory.get_video_processor("hybrid")
+<<<<<<< HEAD
+=======
+
+ @pytest.mark.asyncio
+ async def test_hybrid_success_path(self, monkeypatch):
+ # We need mock modules for fastvlm_gemini_hybrid.video_pipeline and yt_dlp
+ mock_pipeline = MagicMock()
+ mock_pipeline_instance = MagicMock()
+ mock_pipeline_instance.process_video_hybrid.return_value = {
+ "success": True,
+ "response": '{"summary": "test hybrid summary", "actions": [{"name": "action1"}]}'
+ }
+ mock_pipeline.VideoPipeline.return_value = mock_pipeline_instance
+
+ mock_ytdlp = MagicMock()
+ mock_ytdlp_instance = MagicMock()
+ mock_ytdlp_instance.extract_info.return_value = {"id": "test_vid_id"}
+ mock_ytdlp_instance.prepare_filename.return_value = "filepath.mp4"
+ mock_ytdlp.YoutubeDL.return_value.__enter__.return_value = mock_ytdlp_instance
+
+ # Insert them into sys.modules
+ monkeypatch.setitem(sys.modules, "fastvlm_gemini_hybrid", mock_pipeline)
+ monkeypatch.setitem(sys.modules, "fastvlm_gemini_hybrid.video_pipeline", mock_pipeline)
+ monkeypatch.setitem(sys.modules, "yt_dlp", mock_ytdlp)
+
+ factory = _reload_factory()
+ processor = factory.get_video_processor("hybrid")
+
+ # Test process_video
+ result = await processor.process_video("https://www.youtube.com/watch?v=auJzb1D-fag")
+ assert result["video_id"] == "test_vid_id"
+ assert result["success"] is True
+ assert result["ai_analysis"] == {"summary": "test hybrid summary", "actions": [{"name": "action1"}]}
+ assert result["actions"] == [{"name": "action1"}]
+
+>>>>>>> origin/main
diff --git a/tests/unit/test_videopack.py b/tests/unit/test_videopack.py
index 695629dae..6c15b91d5 100644
--- a/tests/unit/test_videopack.py
+++ b/tests/unit/test_videopack.py
@@ -12,6 +12,7 @@
_SRC = Path(__file__).resolve().parents[2] / "src"
sys.path.insert(0, str(_SRC))
+<<<<<<< HEAD
# The videopack __init__.py references a 'Chapter' symbol that doesn't exist yet,
# so we stub the package to bypass the broken __init__ and import submodules directly.
for _key in [k for k in list(sys.modules.keys()) if "youtube_extension.videopack" in k]:
@@ -21,6 +22,10 @@
_vp_stub.__path__ = [str(_SRC / "youtube_extension/videopack")]
_vp_stub.__package__ = "youtube_extension.videopack"
sys.modules["youtube_extension.videopack"] = _vp_stub
+=======
+# Import package directly to verify __init__.py works and is covered
+import youtube_extension.videopack # noqa: F401
+>>>>>>> origin/main
from youtube_extension.videopack.schema import (
ArtifactRef,