From ae6776afc3eacdd7865220c1db2eb78818d05891 Mon Sep 17 00:00:00 2001 From: Ali AL OGAILI Date: Mon, 23 Mar 2026 05:16:57 +0100 Subject: [PATCH] feat: initialize trading agents project with FastAPI and essential configurations - Added FastAPI-based API structure with routers for runs and settings management. - Implemented endpoints for creating, listing, and retrieving run configurations. - Introduced settings management with load and update functionality. - Created models for run configurations and settings using Pydantic. - Established a store for managing run states and results. - Enhanced .gitignore to exclude node_modules and results directories. - Added package.json and package-lock.json for frontend dependencies. - Included initial tests for API endpoints and model validations. --- .gitignore | 2 + api/main.py | 7 +- api/models/run.py | 38 + api/models/settings.py | 9 + api/routers/runs.py | 49 +- api/routers/settings.py | 13 + api/services/run_service.py | 61 + api/services/settings_service.py | 18 + api/settings.json | 7 + api/store/runs_store.py | 63 + .../full_states_log_2026-03-22.json | 27 + package-lock.json | 330 + package.json | 31 + pyproject.toml | 3 + tests/__init__.py | 0 tests/api/__init__.py | 0 tests/api/test_models.py | 23 + tests/api/test_run_service.py | 118 + tests/api/test_runs.py | 23 + tests/api/test_settings.py | 29 + tests/api/test_store.py | 28 + tests/api/test_stream_propagate.py | 127 + tests/conftest.py | 2 + tradingagents/graph/trading_graph.py | 110 + tradingagents/llm_clients/anthropic_client.py | 24 +- tradingagents/llm_clients/openai_client.py | 24 +- ui/.gitignore | 41 + ui/AGENTS.md | 5 + ui/CLAUDE.md | 1 + ui/README.md | 36 + ui/__tests__/components/Sidebar.test.tsx | 20 + .../features/history/RunHistoryTable.test.tsx | 24 + .../features/new-run/RunConfigForm.test.tsx | 26 + .../run-detail/PipelineStepper.test.tsx | 29 + .../features/run-detail/useRunStream.test.ts | 48 + ui/app/(dashboard)/history/page.tsx | 40 + ui/app/(dashboard)/layout.tsx | 10 + ui/app/(dashboard)/new-run/page.tsx | 35 + ui/app/(dashboard)/page.tsx | 5 + ui/app/(dashboard)/runs/[id]/page.tsx | 107 + ui/app/(dashboard)/settings/page.tsx | 18 + ui/app/favicon.ico | Bin 0 -> 25931 bytes ui/app/globals.css | 249 + ui/app/layout.tsx | 35 + ui/app/page.tsx | 5 + ui/components/Sidebar.tsx | 154 + ui/eslint.config.mjs | 18 + .../history/components/RunHistoryTable.tsx | 122 + ui/features/history/hooks/useRunHistory.ts | 19 + .../new-run/components/AnalystSelector.tsx | 103 + .../new-run/components/RunConfigForm.tsx | 279 + ui/features/new-run/hooks/useRunSubmit.ts | 26 + ui/features/new-run/types.ts | 21 + .../run-detail/components/AnalystReports.tsx | 227 + .../run-detail/components/DebateView.tsx | 32 + .../run-detail/components/PhaseTabs.tsx | 91 + .../run-detail/components/PipelineStepper.tsx | 136 + .../run-detail/components/TraderPanel.tsx | 18 + .../run-detail/components/VerdictBanner.tsx | 142 + ui/features/run-detail/hooks/useRunStream.ts | 73 + ui/features/run-detail/types.ts | 10 + .../settings/components/SettingsForm.tsx | 99 + ui/features/settings/types.ts | 6 + ui/jest.config.ts | 14 + ui/jest.setup.ts | 1 + ui/next.config.ts | 7 + ui/package-lock.json | 11085 ++++++++++++++++ ui/package.json | 32 + ui/postcss.config.mjs | 7 + ui/public/file.svg | 1 + ui/public/globe.svg | 1 + ui/public/next.svg | 1 + ui/public/vercel.svg | 1 + ui/public/window.svg | 1 + ui/tsconfig.json | 34 + 75 files changed, 14656 insertions(+), 5 deletions(-) create mode 100644 api/models/run.py create mode 100644 api/models/settings.py create mode 100644 api/services/run_service.py create mode 100644 api/services/settings_service.py create mode 100644 api/settings.json create mode 100644 api/store/runs_store.py create mode 100644 eval_results/NVDA/TradingAgentsStrategy_logs/full_states_log_2026-03-22.json create mode 100644 package-lock.json create mode 100644 package.json delete mode 100644 tests/__init__.py delete mode 100644 tests/api/__init__.py create mode 100644 tests/api/test_models.py create mode 100644 tests/api/test_run_service.py create mode 100644 tests/api/test_runs.py create mode 100644 tests/api/test_settings.py create mode 100644 tests/api/test_store.py create mode 100644 tests/api/test_stream_propagate.py create mode 100644 tests/conftest.py create mode 100644 ui/.gitignore create mode 100644 ui/AGENTS.md create mode 100644 ui/CLAUDE.md create mode 100644 ui/README.md create mode 100644 ui/__tests__/components/Sidebar.test.tsx create mode 100644 ui/__tests__/features/history/RunHistoryTable.test.tsx create mode 100644 ui/__tests__/features/new-run/RunConfigForm.test.tsx create mode 100644 ui/__tests__/features/run-detail/PipelineStepper.test.tsx create mode 100644 ui/__tests__/features/run-detail/useRunStream.test.ts create mode 100644 ui/app/(dashboard)/history/page.tsx create mode 100644 ui/app/(dashboard)/layout.tsx create mode 100644 ui/app/(dashboard)/new-run/page.tsx create mode 100644 ui/app/(dashboard)/page.tsx create mode 100644 ui/app/(dashboard)/runs/[id]/page.tsx create mode 100644 ui/app/(dashboard)/settings/page.tsx create mode 100644 ui/app/favicon.ico create mode 100644 ui/app/globals.css create mode 100644 ui/app/layout.tsx create mode 100644 ui/app/page.tsx create mode 100644 ui/components/Sidebar.tsx create mode 100644 ui/eslint.config.mjs create mode 100644 ui/features/history/components/RunHistoryTable.tsx create mode 100644 ui/features/history/hooks/useRunHistory.ts create mode 100644 ui/features/new-run/components/AnalystSelector.tsx create mode 100644 ui/features/new-run/components/RunConfigForm.tsx create mode 100644 ui/features/new-run/hooks/useRunSubmit.ts create mode 100644 ui/features/new-run/types.ts create mode 100644 ui/features/run-detail/components/AnalystReports.tsx create mode 100644 ui/features/run-detail/components/DebateView.tsx create mode 100644 ui/features/run-detail/components/PhaseTabs.tsx create mode 100644 ui/features/run-detail/components/PipelineStepper.tsx create mode 100644 ui/features/run-detail/components/TraderPanel.tsx create mode 100644 ui/features/run-detail/components/VerdictBanner.tsx create mode 100644 ui/features/run-detail/hooks/useRunStream.ts create mode 100644 ui/features/run-detail/types.ts create mode 100644 ui/features/settings/components/SettingsForm.tsx create mode 100644 ui/features/settings/types.ts create mode 100644 ui/jest.config.ts create mode 100644 ui/jest.setup.ts create mode 100644 ui/next.config.ts create mode 100644 ui/package-lock.json create mode 100644 ui/package.json create mode 100644 ui/postcss.config.mjs create mode 100644 ui/public/file.svg create mode 100644 ui/public/globe.svg create mode 100644 ui/public/next.svg create mode 100644 ui/public/vercel.svg create mode 100644 ui/public/window.svg create mode 100644 ui/tsconfig.json diff --git a/.gitignore b/.gitignore index 20fb9795..98fe346e 100644 --- a/.gitignore +++ b/.gitignore @@ -223,3 +223,5 @@ __marimo__/ # Results **/results/ + +node_modules/ \ No newline at end of file diff --git a/api/main.py b/api/main.py index 25dbe5a0..405392b0 100644 --- a/api/main.py +++ b/api/main.py @@ -1,3 +1,6 @@ +from dotenv import load_dotenv +load_dotenv() + from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from api.routers import runs, settings @@ -11,5 +14,5 @@ app.add_middleware( allow_headers=["*"], ) -app.include_router(runs.router, prefix="/runs", tags=["runs"]) -app.include_router(settings.router, prefix="/settings", tags=["settings"]) +app.include_router(runs.router, prefix="/api/runs", tags=["runs"]) +app.include_router(settings.router, prefix="/api/settings", tags=["settings"]) diff --git a/api/models/run.py b/api/models/run.py new file mode 100644 index 00000000..6ce837b6 --- /dev/null +++ b/api/models/run.py @@ -0,0 +1,38 @@ +from enum import Enum +from typing import Literal, Optional +from pydantic import BaseModel, Field + + +class RunStatus(str, Enum): + QUEUED = "queued" + RUNNING = "running" + COMPLETE = "complete" + ERROR = "error" + + +class RunConfig(BaseModel): + ticker: str + date: str # "YYYY-MM-DD" + llm_provider: str = "openai" + deep_think_llm: str = "gpt-5.2" + quick_think_llm: str = "gpt-5-mini" + max_debate_rounds: int = Field(default=1, ge=1, le=5) + max_risk_discuss_rounds: int = Field(default=1, ge=1, le=5) + enabled_analysts: list[str] = Field( + default=["market", "news", "fundamentals", "social"] + ) + + +class RunSummary(BaseModel): + id: str + ticker: str + date: str + status: RunStatus + decision: Optional[Literal["BUY", "SELL", "HOLD"]] = None + created_at: str + + +class RunResult(RunSummary): + config: Optional[RunConfig] = None + reports: dict[str, str] = {} + error: Optional[str] = None diff --git a/api/models/settings.py b/api/models/settings.py new file mode 100644 index 00000000..9960f8fa --- /dev/null +++ b/api/models/settings.py @@ -0,0 +1,9 @@ +from pydantic import BaseModel, Field + + +class Settings(BaseModel): + deep_think_llm: str = "gpt-5.2" + quick_think_llm: str = "gpt-5-mini" + llm_provider: str = "openai" + max_debate_rounds: int = Field(default=1, ge=1, le=5) + max_risk_discuss_rounds: int = Field(default=1, ge=1, le=5) diff --git a/api/routers/runs.py b/api/routers/runs.py index af9233c5..7d799ef3 100644 --- a/api/routers/runs.py +++ b/api/routers/runs.py @@ -1,3 +1,50 @@ -from fastapi import APIRouter +import json +from fastapi import APIRouter, HTTPException +from fastapi.responses import StreamingResponse +from api.models.run import RunConfig, RunResult, RunSummary +from api.services.run_service import RunService +from api.store.runs_store import RunsStore router = APIRouter() +_store = RunsStore() +_service = RunService(_store) + + +@router.post("", response_model=RunSummary) +def create_run(config: RunConfig): + run = _store.create(config) + return run + + +@router.get("", response_model=list[RunSummary]) +def list_runs(): + return _store.list_all() + + +@router.get("/{run_id}", response_model=RunResult) +def get_run(run_id: str): + run = _store.get(run_id) + if not run: + raise HTTPException(status_code=404, detail="Run not found") + return run + + +@router.get("/{run_id}/stream") +def stream_run(run_id: str): + run = _store.get(run_id) + if not run: + raise HTTPException(status_code=404, detail="Run not found") + + def event_generator(): + for event in _service.stream_events(run_id): + data = json.dumps(event["data"]) + yield f"event: {event['event']}\ndata: {data}\n\n" + + return StreamingResponse( + event_generator(), + media_type="text/event-stream", + headers={ + "Cache-Control": "no-cache", + "X-Accel-Buffering": "no", + }, + ) diff --git a/api/routers/settings.py b/api/routers/settings.py index af9233c5..99ace9a2 100644 --- a/api/routers/settings.py +++ b/api/routers/settings.py @@ -1,3 +1,16 @@ from fastapi import APIRouter +from api.models.settings import Settings +from api.services.settings_service import load_settings, save_settings router = APIRouter() + + +@router.get("", response_model=Settings) +def get_settings(): + return load_settings() + + +@router.put("", response_model=Settings) +def update_settings(settings: Settings): + save_settings(settings) + return settings diff --git a/api/services/run_service.py b/api/services/run_service.py new file mode 100644 index 00000000..6c94375d --- /dev/null +++ b/api/services/run_service.py @@ -0,0 +1,61 @@ +import logging +from collections import defaultdict +from typing import Generator +from api.store.runs_store import RunsStore +from api.models.run import RunConfig, RunStatus + +logger = logging.getLogger(__name__) + +try: + from tradingagents.graph.trading_graph import TradingAgentsGraph + from tradingagents.default_config import DEFAULT_CONFIG +except ImportError: + TradingAgentsGraph = None # type: ignore + DEFAULT_CONFIG = {} + + +class RunService: + def __init__(self, store: RunsStore): + self._store = store + + def stream_events(self, run_id: str) -> Generator[dict, None, None]: + run = self._store.get(run_id) + if not run or not run.config: + yield {"event": "run:error", "data": {"message": "Run not found"}} + return + + self._store.update_status(run_id, RunStatus.RUNNING) + config = run.config + + ta_config = DEFAULT_CONFIG.copy() + ta_config["llm_provider"] = config.llm_provider + ta_config["deep_think_llm"] = config.deep_think_llm + ta_config["quick_think_llm"] = config.quick_think_llm + ta_config["max_debate_rounds"] = config.max_debate_rounds + ta_config["max_risk_discuss_rounds"] = config.max_risk_discuss_rounds + + try: + ta = TradingAgentsGraph( + debug=False, + config=ta_config, + selected_analysts=config.enabled_analysts or + ["market", "news", "fundamentals", "social"], + ) + + turn_counts: defaultdict[str, int] = defaultdict(int) + + for step_key, report in ta.stream_propagate(config.ticker, config.date): + turn = turn_counts[step_key] + yield {"event": "agent:start", "data": {"step": step_key, "turn": turn}} + yield {"event": "agent:complete", "data": {"step": step_key, "turn": turn, "report": report}} + self._store.add_report(run_id, f"{step_key}:{turn}", report) + turn_counts[step_key] += 1 + + decision = ta._last_decision or "HOLD" + self._store.update_decision(run_id, decision) + self._store.update_status(run_id, RunStatus.COMPLETE) + yield {"event": "run:complete", "data": {"decision": decision, "run_id": run_id}} + + except Exception as e: + self._store.set_error(run_id, str(e)) + yield {"event": "run:error", "data": {"message": str(e)}} diff --git a/api/services/settings_service.py b/api/services/settings_service.py new file mode 100644 index 00000000..9ddddfd1 --- /dev/null +++ b/api/services/settings_service.py @@ -0,0 +1,18 @@ +import json +import os +from pathlib import Path +from api.models.settings import Settings + +SETTINGS_PATH = Path(os.getenv("SETTINGS_PATH", "api/settings.json")) + + +def load_settings() -> Settings: + if SETTINGS_PATH.exists(): + data = json.loads(SETTINGS_PATH.read_text()) + return Settings(**data) + return Settings() + + +def save_settings(settings: Settings) -> None: + SETTINGS_PATH.parent.mkdir(parents=True, exist_ok=True) + SETTINGS_PATH.write_text(settings.model_dump_json(indent=2)) diff --git a/api/settings.json b/api/settings.json new file mode 100644 index 00000000..857257b4 --- /dev/null +++ b/api/settings.json @@ -0,0 +1,7 @@ +{ + "deep_think_llm": "claude-opus-4-6", + "quick_think_llm": "claude-haiku-4-5-20251001", + "llm_provider": "anthropic", + "max_debate_rounds": 2, + "max_risk_discuss_rounds": 2 +} \ No newline at end of file diff --git a/api/store/runs_store.py b/api/store/runs_store.py new file mode 100644 index 00000000..d6509c53 --- /dev/null +++ b/api/store/runs_store.py @@ -0,0 +1,63 @@ +import uuid +from datetime import datetime, timezone +from threading import Lock +from api.models.run import RunConfig, RunResult, RunStatus +from typing import Optional, Literal + + +class RunsStore: + def __init__(self): + self._runs: dict[str, RunResult] = {} + self._lock = Lock() + + def create(self, config: RunConfig) -> RunResult: + run_id = str(uuid.uuid4())[:8] + run = RunResult( + id=run_id, + ticker=config.ticker, + date=config.date, + status=RunStatus.QUEUED, + created_at=datetime.now(timezone.utc).isoformat(), + config=config, + ) + with self._lock: + self._runs[run_id] = run + return run + + def get(self, run_id: str) -> Optional[RunResult]: + return self._runs.get(run_id) + + def list_all(self) -> list[RunResult]: + return list(self._runs.values()) + + def update_status(self, run_id: str, status: RunStatus) -> None: + with self._lock: + if run_id in self._runs: + self._runs[run_id] = self._runs[run_id].model_copy( + update={"status": status} + ) + + def update_decision( + self, run_id: str, decision: Literal["BUY", "SELL", "HOLD"] + ) -> None: + with self._lock: + if run_id in self._runs: + self._runs[run_id] = self._runs[run_id].model_copy( + update={"decision": decision} + ) + + def add_report(self, run_id: str, step: str, report: str) -> None: + with self._lock: + if run_id in self._runs: + reports = dict(self._runs[run_id].reports) + reports[step] = report + self._runs[run_id] = self._runs[run_id].model_copy( + update={"reports": reports} + ) + + def set_error(self, run_id: str, error: str) -> None: + with self._lock: + if run_id in self._runs: + self._runs[run_id] = self._runs[run_id].model_copy( + update={"status": RunStatus.ERROR, "error": error} + ) diff --git a/eval_results/NVDA/TradingAgentsStrategy_logs/full_states_log_2026-03-22.json b/eval_results/NVDA/TradingAgentsStrategy_logs/full_states_log_2026-03-22.json new file mode 100644 index 00000000..24ef42df --- /dev/null +++ b/eval_results/NVDA/TradingAgentsStrategy_logs/full_states_log_2026-03-22.json @@ -0,0 +1,27 @@ +{ + "2026-03-22": { + "company_of_interest": "NVDA", + "trade_date": "2026-03-22", + "market_report": "FINAL TRANSACTION PROPOSAL: SELL\n\nTop-line summary\n- Technicals are bearish across timeframes and momentum is deteriorating. Price (last close 172.93 on 2026-03-20) is below the short-term 10 EMA (180.14), the medium-term 50 SMA (184.60) and the long-term 200 SMA (178.42). MACD and its histogram are negative and accelerating downward. RSI is weakening (38) but not deeply oversold. VWMA sits above price (181.24), indicating recent volume-weighted activity has been at higher prices. Volatility (ATR \u2248 5.77) is elevated, so downside swings can be meaningful. Recommendation remains to reduce unhedged exposure and avoid fresh longs until objective repair signals appear.\n\nWhy I selected these indicators (complementary, non-redundant)\n- close_10_ema (short-term momentum) \u2014 captures rapid momentum shifts and helps see if short-term sellers remain in control.\n- close_50_sma (medium-term trend) \u2014 identifies the intermediate trend and likely dynamic resistance/support.\n- close_200_sma (long-term trend) \u2014 strategic trend benchmark and confirmation of structural trend change.\n- macd + macdh (momentum structure and strength) \u2014 MACD line shows trend momentum; macdh (histogram) highlights momentum acceleration / deceleration and early divergence.\n- rsi (momentum/extreme readings) \u2014 flags short-term exhaustion/oversold or overbought conditions and divergence with price.\n- vwma (volume-weighted trend) \u2014 integrates volume with price to confirm whether moves are supported by heavy volume.\n- atr (volatility) \u2014 pragmatic for stop sizing and sizing hedges given current realized/trending volatility.\n\nDetailed, fine-grained indicator read and interpretation\n\n1) Price vs moving averages \u2014 context and dynamics\n- Situation: Price (172.93) < 10 EMA (180.14) < 50 SMA (184.60) and also price < 200 SMA (178.42).\n- Interpretation:\n - Short-term: The 10 EMA turned decisively lower over the last several days and price trading ~7\u20139 points below it signals the short-term sellers control the tape.\n - Medium-term: The 50 SMA (~184.6) is acting as a higher resistance; attempts to hold above it in February were followed by sharp distribution. The failure to reclaim the 50 suggests rallies are corrective.\n - Long-term: The 200 SMA (~178.4) had been rising (structural uptrend), but price has now broken below it \u2014 a meaningful psychological and technical weakening of the long-term trend. The slope of the 200 SMA is still upward, but a price failure to reassert above it suggests at least an intermediate corrective phase.\n- Trading implication: Avoid adding unhedged longs. Any re-entry should require sustained reclaim of the 200 & 50 (ideally closing above ~185\u2013186) with confirming momentum.\n\n2) MACD and MACD histogram \u2014 momentum course\n- Reading: MACD = -1.99, macdh = -0.83 and both have been trending more negative since the late-Feb peak.\n- Interpretation:\n - MACD flipped from positive (late-Feb) to negative quickly \u2014 classic loss of momentum and distribution. The histogram indicates increasing negative gap \u2014 momentum is accelerating to the downside, rather than simply drifting.\n - Recent bounce attempts have produced lower MACD highs and the histogram remains negative \u2014 this is bearish divergence behavior.\n- Trading implication: Short/intermediate momentum favors sellers. Use MACD convergence back above zero and a shrinking, then positive histogram as confirmation for a momentum repair.\n\n3) RSI \u2014 current momentum and exhaustion\n- Reading: RSI ~38 (recently fell from ~48\u201351 to 38).\n- Interpretation:\n - Not deeply oversold (i.e., not <30), which means there may be more room to fall before a technical washout. RSI drop without a washout suggests sellers remain active and buyers have not capitulated.\n - Prior RSI spikes (e.g., ~61 on 2026-02-25) show the move up had strong momentum; the present decline is significant and relatively rapid.\n- Trading implication: Because RSI is not extreme, do not anticipate a reliable immediate mean-reversion bounce; wait for RSI to stabilize and rise above 50 alongside price to consider adding.\n\n4) VWMA and on-balance volume context\n- Reading: VWMA (~181.24) is well above the current price.\n- Interpretation:\n - The fact VWMA is above price means heavier trading occurred at higher price levels recently \u2014 distribution. Down moves were accompanied by heavier volume (e.g., late-Feb and recent down days with 300M+ volumes), which confirms bearish conviction.\n- Trading implication: Volume confirms that declines are not low-volume pullbacks; this argues for trimming/hedging rather than holding through further potential downside.\n\n5) ATR \u2014 volatility and sizing\n- Reading: ATR \u2248 5.77.\n- Interpretation:\n - Expect daily swings of roughly \u00b15\u20136 points; two-ATR moves (~11\u201312 points) are plausible in the near term.\n- Trading implication:\n - Stop placement should respect ATR (example: 1.5\u20132\u00d7ATR = ~9\u201312 points) to avoid being whipsawed, but given the structural weakness you may choose tighter risk management for position sizing.\n - Option hedges should account for realized volatility; put spreads or collars are appropriate to cap risk without paying full put premium.\n\nConcrete trading/position guidance (actionable)\n- If you currently hold NVDA (unhedged stock):\n - Trim now: reduce exposure by 30\u201350% (lean to 50% if concentrated or horizon < 12 months).\n - Hedge what's left: buy puts or put spreads sized to cover the remaining stake. Example: 3-month put spread around strikes that bracket current risks (e.g., long 170 / short 150 or long 160 / short 140) depending on cost and desired protection band \u2014 size to the notional you reduced to.\n - Stop/contingency rules:\n - If price breaks and closes below 168 on increased volume: sell another 15\u201325% of original position.\n - If price breaks and holds below 160: exit remaining stock (or be fully hedged).\n- If you do not hold NVDA:\n - Do not buy unhedged shares here.\n - If you want exposure, prefer defined-risk option structures (small call spreads) or wait for a confirmed momentum repair:\n - Momentum repair trigger: sustained daily close above 185\u2013186 with RSI > 50 and MACD turning positive.\n - Base-and-turn trigger: several successful touches/holds in 160\u2013165 with decreasing volume and signs of accumulation (VWMA moving toward price).\n- Tactical short opportunity: For traders who short, consider sizing carefully and manage risk tightly\u2014retracement rallies can be fast given past volatility. Use ATR-based stops.\n\nCatalyst watch and what changes the view\n- What would make me flip to neutral/bullish:\n - Clear positive corporate catalysts (significant upside guidance from NVDA or hyperscaler commentary) that coincide with technical repair: sustained close > 185\u2013186, MACD crossing back above zero and histogram contracting/turning positive, VWMA moving down toward price, RSI > 50.\n- What would reinforce the bearish view:\n - Continued failure to reclaim the 50 SMA and 200 SMA, on-days with volume above recent average (e.g., repeated 200M+ volume down days), and MACD/histogram staying negative or accelerating downward.\n\nSelected indicator snapshot (most recent values)\n- Price (close 2026-03-20): 172.93\n- close_10_ema: 180.14 (price below -> short-term sellers)\n- close_50_sma: 184.60 (resistance)\n- close_200_sma: 178.42 (long-term pivot; price below this is bearish)\n- macd: -1.99 (negative momentum)\n- macdh: -0.83 (histogram negative and expanding)\n- rsi: 38.03 (weak, not oversold)\n- vwma: 181.24 (volume-weighted average above price = distribution)\n- atr: 5.77 (use for stops/position sizing)\n\nConcise trade plan examples (size/stop guidance uses ATR)\n- Example A \u2014 conservative holder with 1000 shares:\n - Sell 500 shares now (reduce exposure to 500).\n - Buy two 3-month put spreads to hedge remaining 500 shares (one spread per 100 shares; structure e.g., long 170 / short 150 sized to your cost/insurance tolerance).\n - Place a trailing hedge review: if price closes above 186 for 3 sessions with MACD positive, trim hedges and consider re-accumulation in tranches.\n- Example B \u2014 builder wanting small exposure:\n - Do not buy shares; instead buy a small 3-month call spread (size to risk tolerance) or a cheap out-of-the-money long-dated call with defined max premium loss.\n - Reassess only if the momentum repair triggers above occur.\n\nRisk note\n- Market structure here shows distribution with a technically valid breakdown below the long-term moving average. Even with great fundamentals, tape and position management govern near-term outcomes. Use explicit size limits and hedges per your risk tolerance.\n\nKey points table (quick reference)\n\n| Topic | Current reading / level | Interpretation | Suggested action |\n|---|---:|---|---|\n| Price (close) | 172.93 | Trading below 10 EMA, 50 SMA, 200 SMA \u2014 broad weakness | Reduce/hedge exposure; no unhedged new buys |\n| 10 EMA | 180.14 | Short-term momentum is down | Use to time short-term rallies for defensive sells or re-hedging |\n| 50 SMA | 184.60 | Medium-term resistance; rallies fail below here | Avoid buying until reclaimed and confirmed |\n| 200 SMA | 178.42 | Price below long-term average \u2014 structural weakness | Must reclaim and hold above ~178\u2013185 for trend repair |\n| MACD / macdh | -1.99 / -0.83 | Momentum negative and accelerating | Require MACD >0 and shrinking histogram for bullish confirmation |\n| RSI | 38.03 | Weak but not oversold \u2014 room to fall | Wait for stabilizing RSI >50 before adding |\n| VWMA | 181.24 | Volume-weighted average above price = distribution | Volume confirms downside; favors trimming/hedging |\n| ATR | 5.77 | Elevated daily volatility | Use 1.5\u20132\u00d7ATR for stop placement; size accordingly |\n\nIf you want I can:\n- Convert the above into specific order-level instructions (limit orders, strike selection, exact hedge quantity) given your position size, time horizon and max acceptable drawdown; or\n- Run a brief scenario analysis for a few hedge spread structures (example strikes, approximate premium\u2014note: I cannot quote live option prices but can recommend strike bands and durations).\n\nWould you like me to size the recommended sell and hedge for a specific portfolio size or to produce the step-by-step execution plan for trimming + hedging?", + "sentiment_report": "Below is a comprehensive situational report on NVIDIA (NVDA) covering the period 2026-03-15 through 2026-03-22. I used the news pull for that date range (items summarized below) and combined that with market context and common social-media narratives around NVDA. Important: I did not directly scrape social platforms in this run (I only retrieved news items via the news tool). Where I provide social-media \u201csentiment\u201d summaries and daily scores, those are estimated / inferred from the news flow and prevailing public narratives (I note where assumptions are used). If you want, I can run a dedicated social-media sentiment scrape next (X/Twitter, StockTwits, Reddit, LinkedIn) to replace estimates with direct counts/quotes.\n\nExecutive summary\n- Macro headlines on 2026-03-22 (markets down, VIX jump to 24, oil >$100) pushed short-term sentiment negative across tech and AI names, including NVDA.\n- Structural, company-specific narratives remain positive: data-center AI demand, NVIDIA\u2019s Blackwell/Rubin roadmap and OEM/cloud relationships keep long-term investor sentiment constructive.\n- Net effect for the week: near-term selling pressure and caution among traders; buy-the-dip/long-term thesis still widely touted by bulls but with more calls for valuation discipline.\n- Key immediate monitoring items: data-center capex signals (cloud customers), NVIDIA guidance / earnings cadence, implied volatility/options flows, and macro risk indicators (VIX, rates, oil). Also watch TSMC capacity commentary and potential demand softness signals.\n\nNews highlights (selected items 2026-03-15 to 2026-03-22)\n- Several market commentary pieces (Motley Fool, others) on March 22 frame a broader market pullback (markets down 5% year-to-date, VIX rise) and discuss implications for AI stocks including NVIDIA.\n- Commentary tying higher oil prices (> $100/bbl) and recession risk to potential capex slowdowns that could indirectly impact NVIDIA demand/rollout.\n- Company/sector analysis (Simply Wall St / Yahoo Finance) reframing NVIDIA\u2019s story around an AI data-center cycle: updated fair-value estimates modestly higher based on anticipated durable data-center demand, Blackwell/Rubin GPU roadmaps, and partnership announcements in cloud/auto.\n- Broader tech supply-chain and semiconductor commentary (TSMC\u2019s market share and importance) appears across outlets\u2014reminding investors of NVIDIA\u2019s supply concentration risk.\n\nPublic / social-media sentiment \u2014 themes and inferred tone\n(Again: these are inferred from news and known social narratives; I did not fetch direct social posts here. I can fetch direct social data on request.)\n- Bullish themes\n - Enduring dominance in AI datacenter GPUs (Blackwell family and roadmap chatter).\n - Strong cloud demand and multi-year OEM/customer relationships (NVIDIA as \u201cmust-have\u201d for generative AI workloads).\n - Strategic product roadmap (Rubin/Blackwell iterations) and expanding vertical partnerships (autonomous vehicles, enterprise AI).\n - Analyst notes raising modeled fair values (e.g., Simply Wall St updating fair-value higher) reinforce long-term upside narratives.\n- Bearish themes / short-term headwinds\n - Macro risk: recent market pullback, rising volatility, and oil >$100 raising recession concerns and potential capex slowdown.\n - Valuation fatigue: calls that NVIDIA is high-priced and sensitive to any softening in data-center orders.\n - Concentration risks: dependency on TSMC and Taiwan for leading-edge wafer supply.\n - Profit-taking and rotation away from mega-cap AI winners into more cyclical or value sectors.\n- Typical social-media tone and actors (inferred)\n - Retail bulls on forums/StockTwits: \u201cbuy the dip\u201d and long-term AI dominance arguments.\n - Traders and hedge funds: increase hedging/put buying or short-term profit taking during volatility spikes.\n - Analysts and financial media: mixed \u2014 short-term cautious, long-term bullish with updated models.\n\nEstimated daily sentiment (approx., scale -1.0 to +1.0) \u2014 rationale included\n- 2026-03-15: +0.20 \u2014 baseline positive sentiment, continuation of structural AI narrative.\n- 2026-03-16: +0.15 \u2014 mild positive but early-week caution.\n- 2026-03-17: +0.10 \u2014 steady, minor profit-taking in some traders.\n- 2026-03-18: +0.10 \u2014 neutral-leaning as no major NVDA-specific news published.\n- 2026-03-19: +0.05 \u2014 slight softening as macro watchers monitor oil and rates.\n- 2026-03-20: +0.05 \u2014 low news volume; traders cautious heading into week\u2019s end.\n- 2026-03-21: 0.00 \u2014 neutral; positioning for weekend headlines.\n- 2026-03-22: -0.35 \u2014 clear negative reaction across AI/tech names due to market down 5%, VIX to 24, and articles warning about macro effects on AI capex (most news items in the dataset are from this date).\nCaveat: these numbers are estimated; direct social-data pulls could shift these magnitudes.\n\nFine-grained trader / investor implications and near-term signals to watch\n1. Data-center capex and cloud orders (most important company-specific near-term signal)\n - Why it matters: NVIDIA\u2019s top-line and margin leverage are driven by data-center GPU demand. A slowdown or weaker guidance from major cloud providers would drive sharp negative re-pricing.\n - How to monitor: vendor calls (AWS, MSFT, GCP), OEM inventories, NVIDIA guidance, and channel checks; watch sequential growth in data-center revenue and unit sell-through.\n\n2. NVIDIA guidance and gross-margin trends\n - Analysts will focus on any margin pressure from product mix or pricing and on supply-cost effects tied to wafer and fab utilization.\n - Watch for guidance changes and inventory commentary.\n\n3. Options market and implied volatility\n - Elevated implied vol suggests supply of downside protection (puts) is in demand \u2014 monitor skew, put/call ratios, and large options trades for directional bets.\n - Tactical trades: consider hedges if you're long (protective puts, collars, or buy-tail hedges around earnings or macro events).\n\n4. Macro triggers: VIX, rates, oil\n - Volatility spikes and higher rates can lead to quick multiple compression for high-growth names like NVDA.\n - Oil shocks (already in the headlines) risk broader economic slowdown and capex pullbacks.\n\n5. Supply chain concentration (TSMC)\n - Any TSMC capacity or geopolitical commentary will reverberate through NVDA sentiment and could cause supply fears / backlog issues.\n\n6. Competitive dynamics\n - AMD, Intel, Google (TPUs/custom chips) announcements or customer wins/losses are immediate sentiment catalysts.\n\nTrading/investment strategies (practical, depending on horizon)\n- Short-term traders (days\u2013weeks)\n - Expect amplified reactions to macro headlines. Use size discipline, trade implied vol, and prefer shorter-dated options for directional trades.\n - Consider hedging longs with puts or buying strangles ahead of macro prints (VIX, Fed commentary, big tech earnings).\n- Medium-term traders (weeks\u2013months)\n - Buy scaled dips if NVDA shows durable revenue/margin guidance; use collars or selling covered calls to monetize holdings while maintaining upside.\n - Monitor delivery: look for 2\u20133 consecutive quarters of data-center order strength to justify overweight.\n- Long-term investors (months\u2013years)\n - Thesis still intact if NVIDIA continues to dominate AI datacenter GPUs and expands into verticals. Dollar-cost averaging reduces timing risk.\n - Valuation discipline: if you buy, size positions with respect to portfolio allocation and be prepared for high volatility.\n- Risk management\n - Set mental/actual stop levels for shorter-term holdings; for core positions use rebalancing strategies (e.g., sell calls on rallies).\n - Watch macro indicators; reduce exposure if capex indicators meaningfully roll over.\n\nPotential catalysts that could flip sentiment quickly\nPositive catalysts\n- Strong guidance from NVIDIA or major cloud customers about continuing or increased data-center GPU orders.\n- Positive fiscal reports confirming robust ASPs and margin expansion.\n- New partnerships or design wins in high-growth verticals (auto, telco, enterprise AI deployments).\n\nNegative catalysts\n- Cloud providers signaling slowed procurement or inventory destocking.\n- Broader market sell-off / VIX surge that leads to multiple compression in tech.\n- Supply interruptions at TSMC or geopolitical events affecting Taiwan supply chains.\n- Evidence that competition (AMD, custom silicon by cloud providers) is eroding NVIDIA pricing power.\n\nSuggested monitoring dashboard (what to watch daily)\n- NVDA press releases and SEC filings (guidance, backlog disclosures).\n- Earnings calls / conference presentations and Q&A (if within horizon).\n- Cloud provider earnings/announcements (AWS/AMZN, MSFT, GCP/GOOGL).\n- Options flow (unusual volume, put/call skew).\n- Macro indicators: VIX, treasury yields, oil price.\n- TSMC updates or Taiwan/semiconductor supply-chain news.\n- Social-media sentiment metrics (volume of mentions, bullish vs bearish ratio, top themes) \u2014 I can fetch if you want.\n\nLimitations of this report\n- Social-media sentiment scores and themes above are inferred from the news flow and general market narratives; I did not fetch raw social-media posts in this run. Direct collection from X/Twitter, StockTwits, Reddit, LinkedIn, and specialized sentiment vendors would produce more precise daily sentiment metrics and verbatim examples.\n- No live price or options data were used; any tactical entry/exit levels should be based on current market quotes.\n\nIf you want next steps\n- I can run a direct social-media scrape (X/Twitter, StockTwits, Reddit r/wallstreetbets & r/stocks, Seeking Alpha comments, LinkedIn posts) for NVDA for the same dates and return:\n - Daily mention volumes\n - Positive/negative sentiment percentages\n - Representative posts and influencer activity\n - Unusual options trades and large-ticket flows (if a data source is available)\n- I can also fetch more analyst notes and firm-specific coverage to expand the news dataset.\n\nSummary table (key points)\n| Item | Takeaway |\n|---|---|\n| Week sentiment (overall) | Mixed-to-cautious: structural long-term bullishness, short-term negative pressure (spike 3/22). |\n| Main positive drivers | Data-center AI demand, Blackwell/Rubin roadmap, partnerships, analysts\u2019 updated fair-value models. |\n| Main negative drivers | Macro setbacks (markets down, VIX spike), oil >$100, valuation sensitivity, TSMC concentration. |\n| Immediate signals to watch | Data-center orders, NVIDIA guidance, options implied vol, cloud providers\u2019 commentary, TSMC updates. |\n| Short-term trader strategy | Hedge longs, trade implied vol, scale-in buys on confirmed dips. |\n| Long-term investor strategy | Dollar-cost average on conviction, maintain valuation discipline, monitor fundamental orders. |\n| Biggest risk | Capex slowdown among cloud providers / supply-chain disruption. |\n| Recommended next analysis | Direct social-media sentiment scrape + options-flow scan + latest NVDA guidance/earnings check. |\n\nWould you like me to (a) pull direct social-media sentiment and representative posts for NVDA for this date range, (b) scan options flow/unusual trades for the week, or (c) fetch more analyst coverage and price-model updates?", + "news_report": "Continuing the NVDA-focused weekly briefing (coverage period: 2026-03-15 through 2026-03-22). Below is a concise, actionable synthesis of the news, macro backdrop, demand / supply dynamics, risk factors, and trading signals that matter for Nvidia (NVDA) and related markets.\n\nExecutive summary\n- The dominant narratives this week: renewed debate over the pace and sustainability of the AI data-center cycle (supporting NVDA long-term) versus near-term macro/cost headwinds (higher oil, higher volatility, recession risk) that could slow capex and increase stock volatility. Analysts and models are being nudged higher for NVDA\u2019s fair value on refreshed AI demand assumptions (example: Simply Wall St. lift from ~$253 \u2192 ~$269 fair value), but market sentiment is jittery (VIX ~24 reported) and general equity performance YTD is weak (~-5%).\n- For traders: expect elevated two-way volatility. Key short-term drivers are NVDA\u2019s data-center revenue prints and guidance, hyperscaler capex signals, TSMC capacity and allocation news, and energy/ macro risk (oil, yields, VIX). For investors: secular AI demand remains the dominant bull case but execution, inventory cycles and macro slowdowns are the primary risks.\n\nWhat happened this week (key items)\n- Market tone / sentiment: Several outlets flagged weaker YTD markets and a spike in the VIX to ~24 \u2014 higher realized/implied volatility across tech names.\n- Analyst narrative: Some valuation models are being revised upward to reflect refreshed expectations for AI data-center demand and roadmap optimism (Blackwell / Rubin GPU generations, partnerships in AV and cloud infrastructure), but revisions are measured (example: a ~6% fair-value bump in one model).\n- Commodities / macro: Oil prices rose above $100/barrel for the first time since 2022. Higher energy costs carry the potential to push operating costs for large data centers and raise recession probabilities that would slow enterprise/cloud capex.\n- Semiconductor supply context: TSMC\u2019s dominant manufacturing share and capacity remains a critical structural constraint; any TSMC news on capacity expansion, allocation, or lead times will materially affect NVDA\u2019s near-term supply delivery profile and ASPs.\n- The AI question at large: Macro/market commentators and some big banks are reiterating that \u201cthe AI payoff\u201d is the key unresolved question for U.S. investors \u2014 i.e., when and how quickly AI-driven capex converts to sustained revenue/margins across the ecosystem.\n\nImplications for Nvidia (NVDA)\nDemand-side (bullish, secular)\n- Continued strong secular tailwinds from generative-AI training and inference workloads. New GPU architectures (Blackwell, Rubin roadmaps mentioned in press) and partnerships expand use-cases (cloud providers, autonomous systems, enterprise AI), supporting longer-term revenue growth and gross-margin leverage.\n- Hyperscaler pull-through remains the primary immediate driver of datacenter revenue. Evidence of higher hyperscaler bookings, increased backlog, or stronger ASPs will validate the higher valuation assumptions.\n\nSupply-side and cost risks (bearish / moderating)\n- TSMC capacity and allocation remain the choke point. Any delays or shortages will push lead times up and could temporarily inflate ASPs or cause missed revenue if NVDA can\u2019t ship.\n- Higher oil (and energy prices) can feed into higher datacenter OPEX and slow cloud capex decisions if customers expect lower margins/environments for ROI on AI systems.\n- Memory/HBM pricing volatility and wafer costs will affect GPU margins.\n\nMacro risks that could blunt demand\n- Equity-market volatility (VIX up) increases risk premia and can accelerate derivative-driven selling in large-cap growth names.\n- Recession risk or a meaningful slowdown would reduce hyperscaler and enterprise discretionary capex, lengthening NVDA\u2019s sales cycle and raising the risk of inventory digestion.\n- Geopolitical and export-control risk (China/Taiwan) remains an overhang for all advanced-node chipmakers; any escalation can disrupt supply and customer access.\n\nCatalysts to watch (time horizons)\n- Near-term (days\u2013weeks)\n - Any NVDA-specific product announcements or commentary from hyperscalers (Amazon, Microsoft, Google) about capex rhythms.\n - TSMC capacity/allocation updates or foundry pricing signals.\n - Macro prints: major US/China economic data, oil price moves, US Treasury yields, and VIX changes.\n - Options implied-volatility moves and notable changes in put/call flow or open interest.\n- Medium-term (1\u20133 months)\n - NVDA quarterly results / guidance (data-center revenue and gross margin tone).\n - Hyperscaler earnings and public guidance about cloud AI capex plans.\n - Memory/HBM pricing and availability trends.\n- Long-term (3\u201324 months)\n - Adoption rates of new NVDA architectures (Blackwell/Rubin) across enterprise/cloud.\n - TSMC capacity expansions and multi-year supply agreements.\n - Competitive product cycles from AMD, Intel, and specialized AI silicon entrants.\n\nTrading and positioning considerations (actionable)\n- Volatility strategies: Given the VIX spike and headline-driven swings, consider volatility-aware structures (calendar spreads, defined-risk debit spreads, or buying protective puts) if holding large delta exposure. If you expect more headline-driven whipsaw, short-dated straddles/strangles are risky \u2014 prefer defined-loss strategies or hedges.\n- Event-driven trades: Use earnings / guidance releases or TSMC announcements as discrete catalyst windows. Consider reducing size ahead of known binary events if gamma risk isn\u2019t desired; alternatively, structure options to capture directional moves while limiting downside.\n- Momentum vs value: Momentum traders can trade near-term directional moves on NVDA but be wary of fat tails. Long-term investors with conviction on AI can view pullbacks as accumulation windows but should size for cyclicality and inventory risk.\n- Pair trades: If worried about broader delta exposure, consider pairs strategies (long NVDA vs short broader semis ETF or a lagging hardware player) to isolate NVDA-specific upside vs industry cyclicality.\n\nKey metrics / data to monitor (specific, measurable)\n- NVDA: Data-center revenue quarter-over-quarter and guidance; gross margin trends; channel inventory statements.\n- Hyperscalers (AMZN, MSFT, GOOGL): Capex/compute commentary, revenue share from cloud AI services.\n- TSMC: Advanced-node capacity growth, lead times, allocation announcements (e.g., wafer starts, 3nm/2nm capacity timelines).\n- Memory markets: HBM prices and lead times (HBM6 adoption pace).\n- Macro: US ISM, payrolls, CPI, 10-yr yield moves, and oil price (WTI/Brent) \u2014 oil >$100 flagged this week.\n- Market micro: NVDA options IV percentile, put-call skew, short interest (as % float), institutional flows.\n\nRisks and red flags\n- Signs of inventory buildup in NVDA channels or persistent downguides from hyperscalers.\n- Any official export-control tightening or Taiwan-related escalation.\n- Sustained macro slowdown or recession signals that cause hyperscalers to cut near-term capex.\n- Rapid increase in energy costs that compress cloud/data-center economics meaningfully.\n\nSuggested monitoring checklist (short list you can automate/watch)\n- NVDA daily implied vol and unusual options flows\n- TSMC press releases and earnings comments for capacity shifts\n- Hyperscaler earnings transcripts for \u201cAI capex\u201d language\n- Oil price > $100 and moves in electricity price indices for major cloud regions\n- VIX and financial conditions index moves\n- Memory/HBM spot price dashboards\n\nBottom-line trade framework (concise)\n- Long-term view: NVDA remains structurally favored by secular AI demand; fair-value models are being nudged higher by renewed data-center assumptions. For multi-year investors, the core bull case remains intact but comes with execution and macro risk.\n- Short-to-medium term: Elevated macro and energy risks mean NVDA is likely to experience higher volatility and episodic downside risk if hyperscaler capex slows or if macro cracks. Trade sizing, volatility hedges, and event-aware positioning are essential.\n\nAppendix \u2014 notable pieces from this week (selected)\n- Simply Wall St.: Reframed AI data-center cycle lifts modeled fair value ~6% \u2014 cites Blackwell/Rubin roadmaps and partnerships.\n- Motley Fool: Several articles noted market weakness and flagged oil >$100 as a factor that affects capex and NVDA indirectly; others discussed seasonal/ historical patterns for NVDA stock performance.\n- Global news: Banks and outlets reiterating that \u201cAI payoff\u201d expectations are the central open question for equities; TSMC still emphasized as central supplier.\n\nMarkdown summary table (key points, implications, and actionable signals)\n\n| Topic | What happened (Mar 15\u201322, 2026) | Market/firm implication for NVDA | Actionable signal / Monitoring |\n|---|---:|---|---|\n| AI data-center cycle | Analysts refreshed models; some fair-value lifts (e.g., ~6%) as demand assumptions rise | Supports higher long-term NVDA revenue and margins if hyperscaler demand continues | Monitor NVDA data-center revenue / guidance and hyperscaler capex commentary |\n| Volatility / sentiment | VIX spiked to ~24; equities down ~5% YTD | Higher option premia and downside risk; greater two-way moves likely | Watch NVDA implied vol percentile; use defined-risk option hedges |\n| Oil & energy costs | Oil > $100/barrel for first time since 2022 | Could raise datacenter OPEX and slow ROI for AI capex; recession risk if sustained | Track oil, electricity price indices for cloud regions; hyperscaler cost commentary |\n| Foundry / supply | TSMC remains dominant; capacity tightness risk | Allocation or lead-time constraints could cap NVDA shipments or push ASPs | Monitor TSMC capacity/wafer-starts news and NVDA shipping cadence |\n| Roadmap / product | Blackwell / Rubin GPU roadmaps referenced; new partnerships | Potential catalyst for revenue expansion and new TAMs (AV, cloud) if adoption is strong | Watch product adoption metrics, partner press releases, H100-->Blackwell transition signals |\n| Macro / banks view | Major banks and outlets highlight \u201cAI payoff\u201d uncertainty | Market will reprice NVDA on proof points; macro can swing demand | Watch macro prints (ISM, payrolls, CPI, yields) and bank research updates |\n| Competitive & geopolitical risk | Export-control & China/Taiwan tensions remain background risk | Could disrupt supply chains / revenue access | Monitor policy announcements and trade restriction headlines |\n| Trading signals | Mixed: some upgrades, seasonal patterns, option flows | Short-term trades need event-aware sizing; long-term investors should expect volatility | Use earnings/event windows for structured trades; track unusual options activity |\n\nIf you want, I can:\n- produce a watchlist dashboard with live tickers and the exact metrics to track for automated alerts (IV percentile, HBM prices, TSMC wafer starts, etc.), or\n- convert the trading ideas into specific option structures (e.g., examples with strikes and expiries) based on your risk tolerance and time horizon.\n\nWhich follow-up would you like?", + "fundamentals_report": "Continuing \u2014 comprehensive fundamental report on NVIDIA (NVDA) using the latest available statements (as of 2026-03-22 / data timestamped 2026-03-23). I synthesize the income statement, balance sheet and cash flow detail returned by the data calls, compute key ratios, highlight drivers/catalysts and risks, and finish with a concise reference table.\n\nExecutive summary\n- NVIDIA is delivering accelerating top-line and bottom-line growth driven by data\u2011center / AI demand. Latest quarter (2026-01-31) revenue was $68.13B (Q/Q +19.5%; Y/Y ~+73%), gross margin ~75% and operating margin ~65% \u2014 extremely high for the semiconductor sector.\n- Profitability and cash conversion are exceptional: latest-quarter net income $42.96B, operating cash flow $36.19B, free cash flow $34.90B. The firm is net-cash (cash & short term investments materially exceed total debt).\n- Balance sheet is very strong: total assets $206.80B, equity $157.29B, working capital $93.44B, current ratio ~3.9; total debt is modest at ~$11.04B.\n- Capital allocation: ongoing buybacks and small dividend; heavy deployments into marketable investments and M&A in the most recent quarter (large purchases of investments and a ~$13.2B business acquisition).\n- Valuation is rich on many metrics (market cap ~ $4.20T; P/B > 26), but forward estimates imply materially higher EPS \u2014 forward PE (~15.5) vs TTM PE (~35.3) reflects analyst expectations of continued earnings expansion.\n- Primary trading implication: fundamentally very strong growth + cash generation, but valuation and concentration of demand into AI/data-center create execution and cyclical risk. Watch next guidance, inventory/receivable trends, M&A integration and data\u2011center GPU demand.\n\nDetailed financial review\n\n1) Income statement \u2014 growth and margins\n- Latest quarter (2026-01-31):\n - Revenue: $68.127B (vs $57.006B prior quarter; +19.5% Q/Q). Versus same quarter a year earlier ($39.331B): +~73% Y/Y.\n - Gross profit: $51.093B \u2192 gross margin \u2248 75.0%.\n - Operating income: $44.299B \u2192 operating margin \u2248 65.0%.\n - Net income: $42.960B \u2192 net margin \u2248 63.1% for the quarter (TTM profit margin from vendor ~55.6%).\n - Diluted EPS (quarter): $1.76; TTM EPS reported = 4.90; forward EPS consensus reported by vendor = 11.13 (large expected step-up).\n- Margin drivers:\n - Very high product mix leverage and pricing power in data\u2011center GPUs and software/services.\n - R&D is growing in absolute terms ($5.512B this quarter) but remains a relatively small % of revenue (~8.1%).\n - SG&A is low (~1.9% of revenue), supporting high operating margin.\n- Takeaway: Revenue growth is robust and margins are expanding \u2014 combination that produces outsized net income growth.\n\n2) Balance sheet \u2014 liquidity, leverage, working capital\n- Key balances (2026-01-31):\n - Total assets: $206.803B\n - Stockholders\u2019 equity: $157.293B\n - Total liabilities: ~$49.51B\n - Total debt: $11.04B (Long-term debt ~ $7.47B; current debt ~$0.999B)\n - Cash & short-term investments (vendor aggregate): $62.556B (cash itself ~$10.605B; other short-term investments ~$51.951B)\n - Receivables: $38.466B (up materially versus prior periods)\n - Inventory: $21.403B (significant build vs prior year)\n - Working capital: $93.442B; current ratio \u2248 3.9\n- Leverage & returns:\n - Debt / Equity \u2248 0.07 (very low leverage).\n - Using vendor TTM net income (~$120.067B) / equity (~$157.293B) \u2192 implied trailing ROE \u2248 76% (vendor ROE figure differs; I computed from supplied totals).\n - ROA (TTM net income / assets) \u2248 58%.\n- Takeaway: Very strong balance sheet \u2014 large liquid assets and very low leverage provide flexibility for buybacks, M&A, investment, and downside protection.\n\n3) Cash flow \u2014 conversion, capex, and investing\n- Latest quarter:\n - Operating cash flow: $36.188B\n - Free cash flow: $34.904B (capex modest at ~$1.284B)\n - Investing cash flow: -$30.861B (driven by large purchases of investments and ~$13.165B purchase of a business)\n - Financing cash flow: -$6.208B (net share repurchases and dividends)\n - Share repurchases: -$3.815B in the latest quarter (prior quarters included larger repurchases)\n- Interpretation:\n - Strong operating cash conversion; capex is a small share of revenue and FCF is very high.\n - The company is actively deploying cash into financial investments and acquisitions \u2014 watch the rationale and ROI on those deployments.\n - Continued buybacks, though quarter-to-quarter amounts vary, remain a component of capital return.\n\n4) Capital allocation & shares\n- Shares outstanding: diluted average ~24.432B (a gradual reduction over time; company consistently repurchases).\n- Dividend: small (quarterly common stock dividend ~$242M); yield reported ~0.02%.\n- Buybacks: meaningful; recent quarters show billions returned via repurchases (cumulative substantial).\n- Takeaway: Preference toward buybacks + strategic M&A; dividends are token relative to FCF.\n\n5) Inventory, receivables and working capital dynamics (important trading signals)\n- Inventory growth: inventory stood at $21.403B, up materially Y/Y (inventory build may reflect production ramp or safety stock for customer demand, but also presents risk if end demand softens).\n- Receivables up to $38.466B \u2014 could indicate strong sales on credit (supporting revenue growth) but also potential for collections risk and working capital drain if cyclical slowdown occurs.\n- Working capital remains strongly positive, but the change in working capital has been a drag on operating cash flow in recent quarters (see prior quarters where changes in receivables and inventory reduced CFO).\n\n6) Valuation and market metrics\n- Market cap (vendor): ~$4.203T\n- P/E (TTM): ~35.3 (vendor). Forward P/E: ~15.5 (vendor) \u2014 reflects expectations of large EPS acceleration.\n- Price to Book: ~26.7 (very high).\n- Beta: 2.375 (high equity volatility).\n- 52-week range: Low $86.62 / High $212.19. Current price sits near the high end (50-day avg ~$184.6; 200-day ~$178.4).\n- Interpretation: Market is pricing high growth; forward multiples assume continued exceptional earnings growth. Returns are sensitive to growth execution and multiple expansion/contraction.\n\n7) Recent corporate actions & uses of cash\n- Large purchases of marketable investments in the latest quarter (~$33.34B) and a $13.165B purchase of a business \u2014 indicates active investment strategy and acquisition-led expansion.\n- Ongoing buybacks continue to reduce shares outstanding (net common stock issuance negative).\n- Minimal net debt issuance; debt profile conservative.\n\n8) Key catalysts traders should monitor\n- Company guidance for next quarter and FY: top-line guidance and margin outlook will be the immediate market mover.\n- Data-center GPU demand: enterprise orders, hyperscaler spending, AI cloud deployments.\n- Inventory and receivables trends: continued buildup could presage either ramp to meet demand or forward-looking stocking; a future slowdown would pressure margins/earnings.\n- M&A and investment returns: integration of purchased business(es) and utilization of investment holdings.\n- Analyst EPS revisions and forward EPS trajectory vs the current forward consensus (vendor shows large step-up to forward EPS ~11.13).\n- Macro/cyclical risks: GPU demand sensitivity to overall IT capex cycles and hyperscaler buying patterns.\n\n9) Key risks\n- Valuation risk: high multiple; any slowdown would likely cause sharp multiple compression.\n- Demand concentration risk: a large portion of growth tied to AI/data center customers (hyperscalers) \u2014 concentration can amplify downside.\n- Execution on supply chain and product roadmap: delay or competition (from other silicon players, custom accelerators or cloud providers\u2019 internal silicon) could hurt results.\n- M&A and investment deployment risk: large near-term cash outflows for investments/business purchases could underperform expectations.\n\n10) Trading / tactical considerations (for traders, not investment advice)\n- Bullish signals: accelerating revenue & margin expansion, very strong FCF and net cash cushion; continued buybacks.\n- Bearish signals: rich valuation, inventory build and receivables growth (monitor for signs of demand moderation), high beta.\n- Short/intermediate approaches:\n - Momentum traders: positive near-term catalysts (strong guide, continued data-center demand) could support price; consider risk controls due to high volatility.\n - Event-driven: watch next earnings/guidance for catalyst-driven moves; trade around guidance or inventory/receivables commentary.\n - Risk-managed longer-term: if buying at current levels, consider scaling in or using options to hedge (protective puts or collars).\n- Longer-term investors should monitor sustainability of the forward EPS ramp: if the company can sustain the assumed growth and margins, valuation may be justified; otherwise risk of drawdown exists.\n\nVendor data notes and minor inconsistencies\n- Some vendor metrics (e.g., vendor \"Debt to Equity\" and \"ROE\") differ from my arithmetic using the raw statement totals returned. I computed key ratios (debt/equity, ROE, ROA) using the reported balances to provide consistent interpretation:\n - Debt / Equity \u2248 0.07 (i.e., very low leverage).\n - TTM Net Income (vendor) / Equity \u2192 ROE \u2248 76% (exceptional).\n - TTM Net Income / Assets \u2192 ROA \u2248 58%.\n- Always cross-check numbers against the company\u2019s 10-Q/10-K if making large trades.\n\nConcise trader-oriented checklist (what to watch next)\n- Next earnings/guidance: topline, gross and operating margin guidance, EPS guidance, data-center commentary.\n- Inventory and AR trends: signs of slowing demand or improving collections.\n- M&A integration updates and return on invested capital for recent acquisitions.\n- Analyst estimate revisions and whether forward EPS consensus holds up.\n- Insider / buyback activity and cash deployment (investment purchases vs return of capital).\n\nSummary judgement (no explicit BUY/HOLD/SELL given here)\n- Fundamental health: extraordinarily strong \u2014 accelerating revenue, best-in-class margins, huge FCF and a strong balance sheet.\n- Valuation risk: market capitalization and multiples are high; forward expectations baked into prices are aggressive.\n- Net: fundamentals support a strong growth narrative; traders should balance momentum and earnings/catalyst risk and closely monitor guidance and inventory/receivables for inflection points.\n\nReference summary table (key items)\n| Item | Latest / Value | Notes |\n|---|---:|---|\n| Market Cap | $4.203T (vendor) | Extremely large; growth priced in |\n| Latest Quarter Revenue | $68.127B | Q/Q +19.5%; Y/Y ~+73% |\n| Revenue (TTM) | $215.94B (vendor) | TTM number from vendor fundamentals |\n| Gross Profit (latest) | $51.093B | Gross margin \u2248 75.0% |\n| Operating Income (latest) | $44.299B | Operating margin \u2248 65.0% |\n| Net Income (latest) | $42.960B | Net margin \u2248 63.1% (quarter) |\n| Net Income (TTM) | $120.067B (vendor) | Used for ROE/ROA calcs |\n| Diluted EPS (quarter) | $1.76 | TTM EPS vendor = 4.90 |\n| Forward EPS (consensus vendor) | 11.13 | Implies big expected profit growth |\n| P/E (TTM) | 35.29 (vendor) | High |\n| Forward P/E | 15.54 (vendor) | Reflects expected earnings ramp |\n| Price/Book | 26.72 (vendor) | Very high |\n| Cash & ST Investments | ~$62.56B (vendor aggregate) | Strong liquidity |\n| Total Debt | ~$11.04B | Low absolute debt |\n| Net Cash (cash-investments - debt) | ~ $51.5B (approx) | Provides cushion |\n| Total Assets | $206.803B | Rapid asset growth year over year |\n| Total Equity | $157.293B | Large book value |\n| Current Ratio | ~3.9 | Strong near-term liquidity |\n| Free Cash Flow (latest qtr) | $34.904B | Very high FCF conversion |\n| Operating Cash Flow (latest) | $36.188B | Strong CFO |\n| Capital Expenditure (latest) | ~$1.284B | Low vs sales |\n| Share Repurchases (latest) | -$3.815B | Ongoing buybacks (prior quarters larger) |\n| Inventory | $21.403B | Significant build Y/Y \u2014 watch closely |\n| Receivables | $38.466B | Increased substantially \u2014 monitor collections |\n| R&D (latest) | $5.512B | ~8.1% of revenue |\n| Dividend (quarter) | ~$242M | Small yield (~0.02%) |\n| Key catalysts | Guidance, data-center demand, M&A outcomes | Monitor quarterly call and analyst revisions |\n| Key risks | Valuation, demand concentration, inventory/AR | Multiple compression risk if growth slows |\n\nIf you want, I can:\n- Produce a short slide-style summary for traders (1\u20132 pages).\n- Build a one-page \u201cwatchlist\u201d with exact numeric triggers (e.g., if revenue guide < X or inventory > Y or AR days > Z) to support trading rules.\n- Pull recent analyst revisions and consensus estimates (if available) to compare to the vendor forward EPS number and quantify risk of EPS disappointment.\n\nWhich of those would you like next?", + "investment_debate_state": { + "bull_history": "\nBull Analyst: Great\u2014let\u2019s debate this tightly. I\u2019ll play the bullish side, directly engage the bear\u2019s technical and macro points, and show why, despite valid short-term risks, NVIDIA (NVDA) is a high-conviction long for investors who manage size and risk.\n\nQuick framing\n- Bear case (summary): price has broken below short/medium/long moving averages, momentum indicators (MACD, RSI) look weak, VWMA shows distribution, volatility is elevated, and macro/capex risks (VIX, oil >$100) + TSMC concentration create legitimate downside. Tactical guidance: trim/hedge; avoid fresh unhedged longs until technical repair.\n- Bull reply (summary): those tactical technicals matter for traders, but the fundamental story is extraordinarily strong and durable \u2014 explosive data\u2011center AI demand, unmatched margins and cash generation, roadmap momentum (Blackwell/Rubin), and a balance sheet that funds buybacks, M&A, and hedges. With disciplined sizing and hedges, pullbacks are buying opportunities, not reasons to permanently exit the thesis.\n\n1) Growth potential \u2014 why the revenue runway is real\n- The numbers speak: latest quarter revenue $68.13B (Q/Q +19.5%; Y/Y +~73%). Data-center is the engine \u2014 enterprise and hyperscaler AI capex is multi-year, not a one-quarter fad. Vendors and analysts are nudging fair values higher off renewed demand assumptions (e.g., Simply Wall St. lift).\n- Forward EPS consensus (vendor) ~11.13 implies large earnings growth baked into forward multiples; the company has already demonstrated how fast it can scale revenue and convert it into earnings and cash (net income in the quarter ~$42.96B, FCF ~$34.9B).\n- TAM expansion: generative AI, inference at scale, enterprise AI deployments, cloud service monetization, and adjacent verticals (autonomous vehicles, telco, enterprise AI appliances) keep the revenue runway wide. Blackwell/Rubin roadmap and design wins materially expand addressable market.\n\nBull counter to bear on growth:\n- Bear: Macro and oil may force capex cuts that slow NVDA.\n- Bull: Hyperscalers prioritize compute for AI \u2014 when AI translates into product differentiation and revenue for cloud providers, capex gets preserved. Even in slower macro phases, cloud providers will prioritize incremental AI capacity. Also, NVDA\u2019s customers often place orders in advance (backlogs), and NVDA\u2019s demonstrated ability to monetize GPUs via software/AI services increases the stickiness and visibility of revenue.\n\n2) Competitive advantages \u2014 moats that matter\n- Product and ecosystem moat: NVDA is not just a chip vendor \u2014 it sells a full stack (hardware, CUDA software ecosystem, libraries, model tooling). The switching cost for customers developing models on NVDA stack is high.\n- Roadmap leadership: successive architecture wins (H100 -> Blackwell/Rubin) maintain technological leadership and ASP power. That drives both revenue and margin leverage.\n- Strategic relationships & supply prioritization: yes, TSMC is a concentration risk \u2014 but NVDA\u2019s size and willingness to pay premiums and strike long-term allocations make it a foundry priority. NVDA\u2019s close cloud/OEM partnerships (AWS, MSFT, Google) help ensure pull-through.\n- Brand and scale: the firm\u2019s enormous install base and the developer ecosystem are durable defenses vs. point competitors or custom silicon entrants.\n\n3) Positive indicators \u2014 fundamentals overpower near-term tape noise\n- Margins & cash: gross margin ~75%, operating margin ~65%, net margin >60% in the latest quarter \u2014 these are phenomenal structural economics. FCF conversion is stellar (FCF ~$34.9B). Net cash ~ $51B (cash & short investments minus debt) provides flexibility.\n- Capital allocation: ongoing buybacks, strategic acquisitions, and investments demonstrate management belief in long-term value and provide support for per-share returns.\n- Analyst sentiment & social: while short-term social sentiment turned negative on 3/22, structural narratives remain bullish and some fair-value models were raised; buy-the-dip narratives remain common among retail and institutional bulls.\n\n4) Addressing the bear\u2019s technical / short-term table stakes\n- Fact: price is below 10 EMA, 50 SMA, 200 SMA; MACD negative, RSI ~38; VWMA > price; ATR elevated. These are real trading constraints.\n- Rebuttal: technicals are short-term and often lag fundamental inflection points. NVDA\u2019s fundamental improvements have historically led to snap-backs after technical weakness \u2014 and the market will re-rate on clear revenue/margin confirms. For investors with horizon >12 months, fundamentals dominate; for traders, respect the bear signals and hedge.\n- Practical middle ground: if you\u2019re a bull but disciplined:\n - Accumulate in tranches on weakness (don\u2019t all-in while technical damage persists).\n - Use hedges (protective puts or collars) to limit drawdown while keeping upside exposure.\n - Consider defined-risk option structures (call spreads or long-dated calls) rather than naked stock at current risk levels.\n\n5) Credible refutations of the bear\u2019s biggest concerns\n\nConcern: Inventory & receivables build signal softening demand.\n- Reality/context: inventory and receivables rose, but revenue and receivables expansion align with massive sales growth and production ramp to meet extraordinary demand for GPUs. NVDA\u2019s working capital is large but backed by record cash flow. Inventory is a watch item \u2014 not an automatic death knell. Watch next guidance and channel/collection metrics; if receivables days spike or inventory days accelerate without sell-through, then act. Until then, build can reflect ramping supply to satisfy backlog.\n\nConcern: TSMC concentration and geopolitical/export risks.\n- Reality/context: genuine risk. But NVDA is among TSMC\u2019s most valuable customers and has commercial leverage (long-term relationships, willingness to pay for allocation). NVDA also invests in secondary sourcing where feasible, and historically has negotiated priority allocations. It\u2019s a risk that merits monitoring, not an immediate reason to abandon the thesis.\n\nConcern: Valuation is rich \u2014 the stock can fall massively on a miss.\n- Reality/context: Yes. But forward P/E ~15.5 (vendor) reflects a huge expected EPS ramp; the question is execution. NVDA has delivered enormous margin expansion and earnings power. If you buy today, size for the valuation risk: limit allocation to a disciplined % of portfolio and hedge around major events (quarterly guidance, hyperscaler earnings, TSMC announcements).\n\nConcern: Macro (oil, VIX, recession risk) will compress multiples.\n- Reality/context: Macro can and will increase volatility. But NVDA\u2019s products are strategic to AI; if AI remains core to enterprise strategy, NVDA is relatively recession-resilient in its addressable niche compared with consumer cyclicals. Still, short-term multiple compression is possible \u2014 therefore hedging and staggered entry are smart.\n\n6) Execution guidance for a bullish, risk-managed investor\n- Long-term investor (multi-year):\n - Core buy: build a position on weakness in tranches (example: 25% now, 25% on 10\u201315% dip, 50% over next 6\u201312 months tied to guidance and data-center booking checks).\n - Size: cap NVDA to 3\u20136% of total portfolio unless you have outsized conviction and a higher risk tolerance.\n - Hedge: buy long-dated (6\u201312 month) protective puts sized to the core position or use collars to reduce cost while preserving upside.\n- Tactical / shorter-term bull:\n - Avoid unhedged large buys at current technicals.\n - Prefer defined-risk bullish option structures (debit call spreads or long-dated calls) and trade earnings/catalyst windows with small size.\n- Example risk rules (practical):\n - Re-evaluate if NVDA revenue guidance misses materially or hyperscalers publicly reduce AI capex.\n - Cut exposure if price decisively breaks and holds below ~160 on accelerating volume (bear\u2019s suggested 160 level is sensible).\n - Trim on signs of inventory destock combined with margin pressure and slowing sequential data-center revenue.\n\n7) Lessons learned and past mistakes (how I would act differently now)\n- Past weakness in bull calls: too often bulls chased momentum without hedges, and failed to respect tape structure during big macro shocks. Lesson: pair conviction with risk controls \u2014 size limits, protective hedges, and objective sell/trim triggers.\n- Over-relying on narrative: prior bullish mistakes came when thesis was strong but evidence of order flow or customer pull-through didn\u2019t arrive. Lesson: use repeatable signals (hyperscaler commentary, sequential data\u2011center revenue, shipment/backlog disclosures) to confirm thesis.\n- Actionable behavioral change: today I would scale in, hedge early, and set clear monitoring triggers (guidance, TSMC allocation news, AR/inventory days). This protects long-term upside while acknowledging short-term technical reality.\n\n8) Concrete events that would flip me (and what I watch)\n- Flip to more cautious/neutral fast if:\n - NVDA guides meaningfully below consensus and data\u2011center revenue declines sequentially.\n - Multiple hyperscalers announce capex slowdowns or inventory destocking.\n - TSMC supply interruptions materially impact deliveries.\n- Flip to bullish/accelerate buys if:\n - NVDA reports strong guidance, gross margin expansion, and data\u2011center bookings that beat expectations.\n - MACD turns positive, price closes and holds >185\u2013186 with RSI >50 (bear\u2019s technical repair triggers) and VWMA moves toward price on accumulation volume.\n\n9) Final pitch \u2014 why own NVDA now (with discipline)\n- If you believe AI is multi-year and that scale + ecosystem + roadmap leadership translates into durable pricing power and gross-margin leverage, NVDA is the single most direct way to own that secular story at scale.\n- NVDA has shown it can turn incremental data-center adoption into outsized earnings and cash flow. The balance sheet and cash flow materially de-risk the position compared to many high-growth names \u2014 NVDA can buybacks, invest, and hedge through cycles.\n- Short-term technicals give you an entry advantage \u2014 a pullback in price while fundamentals remain strong allows disciplined accumulation. But do it with risk controls (position size limits, hedges, and event-based triggers).\n\nIf you want, next I can:\n- Build a specific tranche-based buy-and-hedge execution plan sized to your portfolio (e.g., exact share counts, collar/put strikes/durations and cost estimates).\n- Produce a monitoring dashboard with the exact numeric triggers we discussed (guidance misses, AR/inventory thresholds, TSMC allocation updates).\nWhich would you prefer?", + "bear_history": "\nBear Analyst: Good\u2014let\u2019s do a point\u2011for\u2011point debate. I\u2019ll stay in Bear mode and directly challenge the bull\u2019s assertions with the hard evidence and trading implications in the research you provided. Short version up-front: fundamentals are spectacular, but the stock is risky here\u2014technical breakdown, valuation sensitivity, concentration + supply/geopolitics, inventory/receivable red flags, and macro-driven capex risk make holding large, unhedged long positions reckless. If you\u2019re long, you should be trimming and hedging now; if you\u2019re not, don\u2019t buy unhedged.\n\n1) Technicals aren\u2019t an \u201cannoyance\u201d\u2014they\u2019re signaling a regime change\n- Facts: Last close 172.93 (2026-03-20) is below 10\u2011EMA (180.14), 50\u2011SMA (184.60) and 200\u2011SMA (178.42). MACD = -1.99, macdh = -0.83 and falling. RSI ~38. VWMA (~181.24) sits above price; ATR \u2248 5.77 (elevated).\n- What that means: This is not a tidy dip \u2014 it\u2019s a multi\u2011timeframe breakdown. MACD and expanding negative histogram show accelerating downside momentum, and volume\u2011weighted price (VWMA) above current levels indicates distribution. RSI isn\u2019t deeply oversold (38) so there\u2019s room to run lower without a technical washout. Given ATR, meaningful intra\u2011day downside swings are likely.\n- Bull response and my counter: You say technicals \u201clag fundamentals\u201d \u2014 true sometimes. But technical breakdowns that coincide with volume distribution and accelerating negative momentum frequently precede capital\u2011markets re\u2011rating (multiple compression), especially for richly priced names. Don\u2019t treat the tape as noise; it governs near\u2011term price discovery and risk.\n\n2) Valuation and sensitivity: spectacular fundamentals imply catastrophic downside if execution slips\n- Facts: Market cap \u2248 $4.2T. TTM P/E ~35.3; vendor forward P/E ~15.5 based on forward EPS of ~11.13. Beta \u2248 2.375 (high).\n- Risk: The market is pricing a large EPS ramp. A single quarter of data\u2011center softness, a guidance cut, or even materially slower sell\u2011through would prompt big downward multiple repricing. With a stock this large and this richly valued, volatility + negative headline = outsized drawdowns (your long\u2011horizon thesis doesn\u2019t protect you from a sharp multi\u2011month loss).\n- Bull response and my counter: You argue buy with size discipline and hedges. That\u2019s sensible\u2014 but many bulls fail to size correctly. If forward EPS falls meaningfully, even modest multiple contraction (say P/E from 15 to 10 on disappointed forward expectations) implies very large percent downside. That\u2019s not hypothetical; it\u2019s mathematical leverage. Hedge or reduce size.\n\n3) Demand concentration and supply/geopolitical risk are under\u2011priced\n- Facts/risks: Data\u2011center revenue concentration to hyperscalers makes NVDA extremely dependent on a handful of customers and their capex cycles. TSMC is the single dominant foundry supplier; geopolitical exposure (Taiwan/China tensions, export controls) is a clear overhang.\n- Why this matters now: Macro stress (VIX ~24, oil >$100) raises recession/capex risk. If hyperscalers slow or delay orders, NVDA\u2019s revenue and forward guidance could downshift quickly. Additionally, any TSMC allocation shift or outage would be immediately punitive to shipments and guidance.\n- Bull response and my counter: You point to NVDA\u2019s scale and ability to secure allocations. Scale helps, but it\u2019s not immunity. When allocation gets tight, foundry customers compete on pricing and priority\u2014NVDA\u2019s willingness to pay more helps only to a point and cannot eliminate geopolitical shocks or mandated export controls. This is a convex risk: low probability, high impact.\n\n4) Inventory and receivables dynamics look worrisome, not benign\n- Facts: Inventory ~$21.4B; receivables ~$38.5B; working capital positive but these lines rose materially.\n- Why that\u2019s a red flag: Rapid increases in inventory and receivables during a blowout revenue quarter can be consistent with production ramps, but they\u2019re also the classic early signs of channel stuffing or weaker end\u2011market sell\u2011through. Receivables growth outpacing collections would strain cash conversion and foreshadow future revenue revisions if customers slow payments or return product.\n- Bull response and my counter: You say build could reflect ramp to meet backlog. Sure\u2014but we can\u2019t assume constructive intent without evidence of fast sell\u2011through. Watch DSO, inventory days and subsequent quarter sell-through closely. If AR days or inventory turns tick up again while guidance softens, risk is immediate and severe. Treat these as canaries.\n\n5) Options/volatility and market positioning show that downside protection is in demand\n- Facts: Social and report notes show elevated implied vol and put buying; VIX elevated. VWMA > price indicates distribution on volume.\n- What that signals: Market participants are paying up for downside protection. That\u2019s not a \u201ccontrarian positive\u201d \u2014 it\u2019s a signal that sophisticated market actors see tail risk and are buying insurance.\n- Bull response and my counter: Bulls love to point at retail \u201cbuy the dip\u201d chatter. Retail noise can prop short squeezes, but the options market and institutional hedging are the smarter side of the tape. When institutions hedge aggressively, price action tends to follow.\n\n6) Competition is real and mounting \u2014 don\u2019t dismiss it as fringe risk\n- Facts/risks: AMD, Intel, and hyperscalers building custom accelerators (Google TPUs, cloud internal silicon) are credible threats for price and share in specific workloads (inference/edge, commodity training volumes). Open\u2011source frameworks and growing model portability reduce switching friction over time.\n- Why it matters: NVDA\u2019s moat is strong today, but it\u2019s not impregnable. If hyperscalers decide to diversify supplier mix for cost or strategic reasons (or to reduce TSMC dependency), NVDA\u2019s premium pricing and margins could face pressure. That risk is amplified when the entire market is paying for \u201cfuture dominance\u201d in the price.\n- Bull response and my counter: You point to CUDA and ecosystem lock\u2011in. Lock\u2011in exists, but enterprises increasingly optimize for total cost of ownership and speed\u2014if other solutions materially close performance gaps, customers will apply pressure. Betting on perpetual pricing power without contingency planning is dangerous.\n\n7) Macro tailwinds can flip into headwinds quickly\n- Facts: Oil >$100, VIX spike, broader market weakness YTD (~\u20115%). Cloud capex is discretionary and sensitive to macro sentiment.\n- Why it matters: Even if AI is multi\u2011year, capex phasing matters\u2014cloud providers can defer capacity purchases, prioritize projects, or re\u2011allocate budgets. NVDA\u2019s valuation discounts time and execution risk; delays in capex are not minor timing issues for a forward P/E built on big short\u2011term EPS growth.\n- Bull response and my counter: The bull says hyperscalers will prioritize AI spend \u2014 maybe. But they also run businesses with ROI mandates. If macro squeezes margins or demand at the customer level, compute expansion is a convenient lever to slow. Don\u2019t assume immunity.\n\n8) Execution risk on M&A and huge investment deployments\n- Facts: Latest quarter shows massive purchases of marketable investments (~$33B) and a ~$13.165B acquisition.\n- Why that matters: Management is deploying huge cash into investments and M&A instead of simply returning it. That\u2019s not bad per se, but it introduces execution and integration risk. Buying investments and businesses at inflated prices is a real capital\u2011allocation hazard and increases overall risk if growth disappoints later.\n- Bull response and my counter: You view buybacks and M&A as positive. They can be\u2014if timed correctly. But in a market with stretched multiples, aggressive deployment increases downside when sentiment reverses.\n\n9) Concrete, objective trade / position guidance (practical and uncompromising)\n- If you hold NVDA unhedged:\n - Trim now: reduce exposure 30\u201350% (I lean to 50% if concentrated or horizon < 12 months).\n - Hedge remaining position: buy puts or put spreads sized to remaining shares. Example hedge (practical): 3\u2011month long 170 / short 150 put spread on the remaining exposure (reduces cost vs naked puts but provides meaningful downside protection in a big down move).\n - Hard sell triggers:\n - Close below 168 on increasing volume: sell another 15\u201325% of original.\n - Close and hold below 160: exit remaining stock (or be fully hedged).\n- If you don\u2019t hold NVDA:\n - Do not buy unhedged shares here. Prefer defined\u2011risk option structures (small call spreads or LEAP calls sized to acceptable premium loss) or wait for a confirmed technical repair: sustained closes above 185\u2013186 with MACD turning positive and RSI >50.\n- For traders who short: consider tight sizing, ATR-based stops (1.5\u20132\u00d7ATR \u2248 9\u201312 points), and be mindful that rebounds can be violent.\n\n10) Events that would materially worsen the bear case (i.e., accelerate my sell calls)\n- Hyperscaler guidance cuts or public comments about capex delays.\n- NVDA guidance misses for the next quarter or sequential decline in data\u2011center revenue.\n- Reaccelerating inventory growth alongside slowing sell\u2011through (inventory days rising).\n- TSMC allocation shortfalls, foundry disruptions, or any export\u2011control escalation.\n- Repeated high\u2011volume down days (200M+ volume) with price staying below 50 & 200 SMA.\n\n11) What would cause me to stop being bearish (flip criteria)\n- This is fair: I\u2019ll flip to neutral/bullish only if NVDA:\n - Reclaims and holds above ~185\u2013186 on strong volume, with MACD turning positive and RSI >50,\n - Shows sequential improvement in inventory turns and receivable days,\n - Produces visible evidence of stable/increasing hyperscaler bookings in guidance or public partner commentary.\n- Until those conditions are met, the risk\u2011first posture remains appropriate.\n\n12) Lessons and behavioral discipline\u2014what I\u2019ve learned (and what I\u2019ll do differently)\n- Past mistakes I\u2019ve made: chasing momentum on names with stretched multiples and neglecting hedges; treating \u201cfundamentals only\u201d as a shield against market\u2011wide repricings; waiting too long to trim at the first signs of structural tape damage.\n- How that changes my posture now:\n - Size first: cap single\u2011name exposure to a small, explicitly defined % of portfolio.\n - Hedge early: buy protective puts or use collars when entering large positions at rich valuations.\n - Use objective, pre\u2011specified triggers for trimming/exiting (the 168/160 levels above are examples).\n - Treat tape behavior as data\u2014not noise. When volume distribution aligns with technical breakdowns, be willing to act quickly.\n- I agree with the bull on disciplined tranching and hedging\u2014but the evidence says those measures are required now, not optional.\n\n13) Final, direct challenge to the bull\u2019s core assertions\n- You\u2019re right that the long\u2011term AI TAM can justify ownership. But you\u2019re underestimating three compounding risks today:\n 1) Valuation convexity: forward earnings are embedded in price\u2014small execution misses equal large price moves.\n 2) Technical regime shift: price, momentum, and volume indicate sellers are in control; that changes the odds for new unhedged entries.\n 3) Macro + concentration + supply tail risk: these amplify downside when market sentiment deteriorates.\n- Conclusion: If you are a disciplined bull, accumulate only in hedged, sized tranches and set strict, objective sell/hedge triggers. If you are a risk manager or short/intermediate trader, reduce exposure now and wait for clear signs of technical and fundamental confirmation before adding.\n\nIf helpful, I can:\n- Build the exact hedge size/strike expiries for a given share count or portfolio percentage (e.g., show how many 170/150 3\u2011month put spreads to buy for 1,000 shares).\n- Produce a one\u2011page execution plan with limit orders and stops tied to the technical/triggers above.\nWhich would you like?", + "history": "\nBull Analyst: Great\u2014let\u2019s debate this tightly. I\u2019ll play the bullish side, directly engage the bear\u2019s technical and macro points, and show why, despite valid short-term risks, NVIDIA (NVDA) is a high-conviction long for investors who manage size and risk.\n\nQuick framing\n- Bear case (summary): price has broken below short/medium/long moving averages, momentum indicators (MACD, RSI) look weak, VWMA shows distribution, volatility is elevated, and macro/capex risks (VIX, oil >$100) + TSMC concentration create legitimate downside. Tactical guidance: trim/hedge; avoid fresh unhedged longs until technical repair.\n- Bull reply (summary): those tactical technicals matter for traders, but the fundamental story is extraordinarily strong and durable \u2014 explosive data\u2011center AI demand, unmatched margins and cash generation, roadmap momentum (Blackwell/Rubin), and a balance sheet that funds buybacks, M&A, and hedges. With disciplined sizing and hedges, pullbacks are buying opportunities, not reasons to permanently exit the thesis.\n\n1) Growth potential \u2014 why the revenue runway is real\n- The numbers speak: latest quarter revenue $68.13B (Q/Q +19.5%; Y/Y +~73%). Data-center is the engine \u2014 enterprise and hyperscaler AI capex is multi-year, not a one-quarter fad. Vendors and analysts are nudging fair values higher off renewed demand assumptions (e.g., Simply Wall St. lift).\n- Forward EPS consensus (vendor) ~11.13 implies large earnings growth baked into forward multiples; the company has already demonstrated how fast it can scale revenue and convert it into earnings and cash (net income in the quarter ~$42.96B, FCF ~$34.9B).\n- TAM expansion: generative AI, inference at scale, enterprise AI deployments, cloud service monetization, and adjacent verticals (autonomous vehicles, telco, enterprise AI appliances) keep the revenue runway wide. Blackwell/Rubin roadmap and design wins materially expand addressable market.\n\nBull counter to bear on growth:\n- Bear: Macro and oil may force capex cuts that slow NVDA.\n- Bull: Hyperscalers prioritize compute for AI \u2014 when AI translates into product differentiation and revenue for cloud providers, capex gets preserved. Even in slower macro phases, cloud providers will prioritize incremental AI capacity. Also, NVDA\u2019s customers often place orders in advance (backlogs), and NVDA\u2019s demonstrated ability to monetize GPUs via software/AI services increases the stickiness and visibility of revenue.\n\n2) Competitive advantages \u2014 moats that matter\n- Product and ecosystem moat: NVDA is not just a chip vendor \u2014 it sells a full stack (hardware, CUDA software ecosystem, libraries, model tooling). The switching cost for customers developing models on NVDA stack is high.\n- Roadmap leadership: successive architecture wins (H100 -> Blackwell/Rubin) maintain technological leadership and ASP power. That drives both revenue and margin leverage.\n- Strategic relationships & supply prioritization: yes, TSMC is a concentration risk \u2014 but NVDA\u2019s size and willingness to pay premiums and strike long-term allocations make it a foundry priority. NVDA\u2019s close cloud/OEM partnerships (AWS, MSFT, Google) help ensure pull-through.\n- Brand and scale: the firm\u2019s enormous install base and the developer ecosystem are durable defenses vs. point competitors or custom silicon entrants.\n\n3) Positive indicators \u2014 fundamentals overpower near-term tape noise\n- Margins & cash: gross margin ~75%, operating margin ~65%, net margin >60% in the latest quarter \u2014 these are phenomenal structural economics. FCF conversion is stellar (FCF ~$34.9B). Net cash ~ $51B (cash & short investments minus debt) provides flexibility.\n- Capital allocation: ongoing buybacks, strategic acquisitions, and investments demonstrate management belief in long-term value and provide support for per-share returns.\n- Analyst sentiment & social: while short-term social sentiment turned negative on 3/22, structural narratives remain bullish and some fair-value models were raised; buy-the-dip narratives remain common among retail and institutional bulls.\n\n4) Addressing the bear\u2019s technical / short-term table stakes\n- Fact: price is below 10 EMA, 50 SMA, 200 SMA; MACD negative, RSI ~38; VWMA > price; ATR elevated. These are real trading constraints.\n- Rebuttal: technicals are short-term and often lag fundamental inflection points. NVDA\u2019s fundamental improvements have historically led to snap-backs after technical weakness \u2014 and the market will re-rate on clear revenue/margin confirms. For investors with horizon >12 months, fundamentals dominate; for traders, respect the bear signals and hedge.\n- Practical middle ground: if you\u2019re a bull but disciplined:\n - Accumulate in tranches on weakness (don\u2019t all-in while technical damage persists).\n - Use hedges (protective puts or collars) to limit drawdown while keeping upside exposure.\n - Consider defined-risk option structures (call spreads or long-dated calls) rather than naked stock at current risk levels.\n\n5) Credible refutations of the bear\u2019s biggest concerns\n\nConcern: Inventory & receivables build signal softening demand.\n- Reality/context: inventory and receivables rose, but revenue and receivables expansion align with massive sales growth and production ramp to meet extraordinary demand for GPUs. NVDA\u2019s working capital is large but backed by record cash flow. Inventory is a watch item \u2014 not an automatic death knell. Watch next guidance and channel/collection metrics; if receivables days spike or inventory days accelerate without sell-through, then act. Until then, build can reflect ramping supply to satisfy backlog.\n\nConcern: TSMC concentration and geopolitical/export risks.\n- Reality/context: genuine risk. But NVDA is among TSMC\u2019s most valuable customers and has commercial leverage (long-term relationships, willingness to pay for allocation). NVDA also invests in secondary sourcing where feasible, and historically has negotiated priority allocations. It\u2019s a risk that merits monitoring, not an immediate reason to abandon the thesis.\n\nConcern: Valuation is rich \u2014 the stock can fall massively on a miss.\n- Reality/context: Yes. But forward P/E ~15.5 (vendor) reflects a huge expected EPS ramp; the question is execution. NVDA has delivered enormous margin expansion and earnings power. If you buy today, size for the valuation risk: limit allocation to a disciplined % of portfolio and hedge around major events (quarterly guidance, hyperscaler earnings, TSMC announcements).\n\nConcern: Macro (oil, VIX, recession risk) will compress multiples.\n- Reality/context: Macro can and will increase volatility. But NVDA\u2019s products are strategic to AI; if AI remains core to enterprise strategy, NVDA is relatively recession-resilient in its addressable niche compared with consumer cyclicals. Still, short-term multiple compression is possible \u2014 therefore hedging and staggered entry are smart.\n\n6) Execution guidance for a bullish, risk-managed investor\n- Long-term investor (multi-year):\n - Core buy: build a position on weakness in tranches (example: 25% now, 25% on 10\u201315% dip, 50% over next 6\u201312 months tied to guidance and data-center booking checks).\n - Size: cap NVDA to 3\u20136% of total portfolio unless you have outsized conviction and a higher risk tolerance.\n - Hedge: buy long-dated (6\u201312 month) protective puts sized to the core position or use collars to reduce cost while preserving upside.\n- Tactical / shorter-term bull:\n - Avoid unhedged large buys at current technicals.\n - Prefer defined-risk bullish option structures (debit call spreads or long-dated calls) and trade earnings/catalyst windows with small size.\n- Example risk rules (practical):\n - Re-evaluate if NVDA revenue guidance misses materially or hyperscalers publicly reduce AI capex.\n - Cut exposure if price decisively breaks and holds below ~160 on accelerating volume (bear\u2019s suggested 160 level is sensible).\n - Trim on signs of inventory destock combined with margin pressure and slowing sequential data-center revenue.\n\n7) Lessons learned and past mistakes (how I would act differently now)\n- Past weakness in bull calls: too often bulls chased momentum without hedges, and failed to respect tape structure during big macro shocks. Lesson: pair conviction with risk controls \u2014 size limits, protective hedges, and objective sell/trim triggers.\n- Over-relying on narrative: prior bullish mistakes came when thesis was strong but evidence of order flow or customer pull-through didn\u2019t arrive. Lesson: use repeatable signals (hyperscaler commentary, sequential data\u2011center revenue, shipment/backlog disclosures) to confirm thesis.\n- Actionable behavioral change: today I would scale in, hedge early, and set clear monitoring triggers (guidance, TSMC allocation news, AR/inventory days). This protects long-term upside while acknowledging short-term technical reality.\n\n8) Concrete events that would flip me (and what I watch)\n- Flip to more cautious/neutral fast if:\n - NVDA guides meaningfully below consensus and data\u2011center revenue declines sequentially.\n - Multiple hyperscalers announce capex slowdowns or inventory destocking.\n - TSMC supply interruptions materially impact deliveries.\n- Flip to bullish/accelerate buys if:\n - NVDA reports strong guidance, gross margin expansion, and data\u2011center bookings that beat expectations.\n - MACD turns positive, price closes and holds >185\u2013186 with RSI >50 (bear\u2019s technical repair triggers) and VWMA moves toward price on accumulation volume.\n\n9) Final pitch \u2014 why own NVDA now (with discipline)\n- If you believe AI is multi-year and that scale + ecosystem + roadmap leadership translates into durable pricing power and gross-margin leverage, NVDA is the single most direct way to own that secular story at scale.\n- NVDA has shown it can turn incremental data-center adoption into outsized earnings and cash flow. The balance sheet and cash flow materially de-risk the position compared to many high-growth names \u2014 NVDA can buybacks, invest, and hedge through cycles.\n- Short-term technicals give you an entry advantage \u2014 a pullback in price while fundamentals remain strong allows disciplined accumulation. But do it with risk controls (position size limits, hedges, and event-based triggers).\n\nIf you want, next I can:\n- Build a specific tranche-based buy-and-hedge execution plan sized to your portfolio (e.g., exact share counts, collar/put strikes/durations and cost estimates).\n- Produce a monitoring dashboard with the exact numeric triggers we discussed (guidance misses, AR/inventory thresholds, TSMC allocation updates).\nWhich would you prefer?\nBear Analyst: Good\u2014let\u2019s do a point\u2011for\u2011point debate. I\u2019ll stay in Bear mode and directly challenge the bull\u2019s assertions with the hard evidence and trading implications in the research you provided. Short version up-front: fundamentals are spectacular, but the stock is risky here\u2014technical breakdown, valuation sensitivity, concentration + supply/geopolitics, inventory/receivable red flags, and macro-driven capex risk make holding large, unhedged long positions reckless. If you\u2019re long, you should be trimming and hedging now; if you\u2019re not, don\u2019t buy unhedged.\n\n1) Technicals aren\u2019t an \u201cannoyance\u201d\u2014they\u2019re signaling a regime change\n- Facts: Last close 172.93 (2026-03-20) is below 10\u2011EMA (180.14), 50\u2011SMA (184.60) and 200\u2011SMA (178.42). MACD = -1.99, macdh = -0.83 and falling. RSI ~38. VWMA (~181.24) sits above price; ATR \u2248 5.77 (elevated).\n- What that means: This is not a tidy dip \u2014 it\u2019s a multi\u2011timeframe breakdown. MACD and expanding negative histogram show accelerating downside momentum, and volume\u2011weighted price (VWMA) above current levels indicates distribution. RSI isn\u2019t deeply oversold (38) so there\u2019s room to run lower without a technical washout. Given ATR, meaningful intra\u2011day downside swings are likely.\n- Bull response and my counter: You say technicals \u201clag fundamentals\u201d \u2014 true sometimes. But technical breakdowns that coincide with volume distribution and accelerating negative momentum frequently precede capital\u2011markets re\u2011rating (multiple compression), especially for richly priced names. Don\u2019t treat the tape as noise; it governs near\u2011term price discovery and risk.\n\n2) Valuation and sensitivity: spectacular fundamentals imply catastrophic downside if execution slips\n- Facts: Market cap \u2248 $4.2T. TTM P/E ~35.3; vendor forward P/E ~15.5 based on forward EPS of ~11.13. Beta \u2248 2.375 (high).\n- Risk: The market is pricing a large EPS ramp. A single quarter of data\u2011center softness, a guidance cut, or even materially slower sell\u2011through would prompt big downward multiple repricing. With a stock this large and this richly valued, volatility + negative headline = outsized drawdowns (your long\u2011horizon thesis doesn\u2019t protect you from a sharp multi\u2011month loss).\n- Bull response and my counter: You argue buy with size discipline and hedges. That\u2019s sensible\u2014 but many bulls fail to size correctly. If forward EPS falls meaningfully, even modest multiple contraction (say P/E from 15 to 10 on disappointed forward expectations) implies very large percent downside. That\u2019s not hypothetical; it\u2019s mathematical leverage. Hedge or reduce size.\n\n3) Demand concentration and supply/geopolitical risk are under\u2011priced\n- Facts/risks: Data\u2011center revenue concentration to hyperscalers makes NVDA extremely dependent on a handful of customers and their capex cycles. TSMC is the single dominant foundry supplier; geopolitical exposure (Taiwan/China tensions, export controls) is a clear overhang.\n- Why this matters now: Macro stress (VIX ~24, oil >$100) raises recession/capex risk. If hyperscalers slow or delay orders, NVDA\u2019s revenue and forward guidance could downshift quickly. Additionally, any TSMC allocation shift or outage would be immediately punitive to shipments and guidance.\n- Bull response and my counter: You point to NVDA\u2019s scale and ability to secure allocations. Scale helps, but it\u2019s not immunity. When allocation gets tight, foundry customers compete on pricing and priority\u2014NVDA\u2019s willingness to pay more helps only to a point and cannot eliminate geopolitical shocks or mandated export controls. This is a convex risk: low probability, high impact.\n\n4) Inventory and receivables dynamics look worrisome, not benign\n- Facts: Inventory ~$21.4B; receivables ~$38.5B; working capital positive but these lines rose materially.\n- Why that\u2019s a red flag: Rapid increases in inventory and receivables during a blowout revenue quarter can be consistent with production ramps, but they\u2019re also the classic early signs of channel stuffing or weaker end\u2011market sell\u2011through. Receivables growth outpacing collections would strain cash conversion and foreshadow future revenue revisions if customers slow payments or return product.\n- Bull response and my counter: You say build could reflect ramp to meet backlog. Sure\u2014but we can\u2019t assume constructive intent without evidence of fast sell\u2011through. Watch DSO, inventory days and subsequent quarter sell-through closely. If AR days or inventory turns tick up again while guidance softens, risk is immediate and severe. Treat these as canaries.\n\n5) Options/volatility and market positioning show that downside protection is in demand\n- Facts: Social and report notes show elevated implied vol and put buying; VIX elevated. VWMA > price indicates distribution on volume.\n- What that signals: Market participants are paying up for downside protection. That\u2019s not a \u201ccontrarian positive\u201d \u2014 it\u2019s a signal that sophisticated market actors see tail risk and are buying insurance.\n- Bull response and my counter: Bulls love to point at retail \u201cbuy the dip\u201d chatter. Retail noise can prop short squeezes, but the options market and institutional hedging are the smarter side of the tape. When institutions hedge aggressively, price action tends to follow.\n\n6) Competition is real and mounting \u2014 don\u2019t dismiss it as fringe risk\n- Facts/risks: AMD, Intel, and hyperscalers building custom accelerators (Google TPUs, cloud internal silicon) are credible threats for price and share in specific workloads (inference/edge, commodity training volumes). Open\u2011source frameworks and growing model portability reduce switching friction over time.\n- Why it matters: NVDA\u2019s moat is strong today, but it\u2019s not impregnable. If hyperscalers decide to diversify supplier mix for cost or strategic reasons (or to reduce TSMC dependency), NVDA\u2019s premium pricing and margins could face pressure. That risk is amplified when the entire market is paying for \u201cfuture dominance\u201d in the price.\n- Bull response and my counter: You point to CUDA and ecosystem lock\u2011in. Lock\u2011in exists, but enterprises increasingly optimize for total cost of ownership and speed\u2014if other solutions materially close performance gaps, customers will apply pressure. Betting on perpetual pricing power without contingency planning is dangerous.\n\n7) Macro tailwinds can flip into headwinds quickly\n- Facts: Oil >$100, VIX spike, broader market weakness YTD (~\u20115%). Cloud capex is discretionary and sensitive to macro sentiment.\n- Why it matters: Even if AI is multi\u2011year, capex phasing matters\u2014cloud providers can defer capacity purchases, prioritize projects, or re\u2011allocate budgets. NVDA\u2019s valuation discounts time and execution risk; delays in capex are not minor timing issues for a forward P/E built on big short\u2011term EPS growth.\n- Bull response and my counter: The bull says hyperscalers will prioritize AI spend \u2014 maybe. But they also run businesses with ROI mandates. If macro squeezes margins or demand at the customer level, compute expansion is a convenient lever to slow. Don\u2019t assume immunity.\n\n8) Execution risk on M&A and huge investment deployments\n- Facts: Latest quarter shows massive purchases of marketable investments (~$33B) and a ~$13.165B acquisition.\n- Why that matters: Management is deploying huge cash into investments and M&A instead of simply returning it. That\u2019s not bad per se, but it introduces execution and integration risk. Buying investments and businesses at inflated prices is a real capital\u2011allocation hazard and increases overall risk if growth disappoints later.\n- Bull response and my counter: You view buybacks and M&A as positive. They can be\u2014if timed correctly. But in a market with stretched multiples, aggressive deployment increases downside when sentiment reverses.\n\n9) Concrete, objective trade / position guidance (practical and uncompromising)\n- If you hold NVDA unhedged:\n - Trim now: reduce exposure 30\u201350% (I lean to 50% if concentrated or horizon < 12 months).\n - Hedge remaining position: buy puts or put spreads sized to remaining shares. Example hedge (practical): 3\u2011month long 170 / short 150 put spread on the remaining exposure (reduces cost vs naked puts but provides meaningful downside protection in a big down move).\n - Hard sell triggers:\n - Close below 168 on increasing volume: sell another 15\u201325% of original.\n - Close and hold below 160: exit remaining stock (or be fully hedged).\n- If you don\u2019t hold NVDA:\n - Do not buy unhedged shares here. Prefer defined\u2011risk option structures (small call spreads or LEAP calls sized to acceptable premium loss) or wait for a confirmed technical repair: sustained closes above 185\u2013186 with MACD turning positive and RSI >50.\n- For traders who short: consider tight sizing, ATR-based stops (1.5\u20132\u00d7ATR \u2248 9\u201312 points), and be mindful that rebounds can be violent.\n\n10) Events that would materially worsen the bear case (i.e., accelerate my sell calls)\n- Hyperscaler guidance cuts or public comments about capex delays.\n- NVDA guidance misses for the next quarter or sequential decline in data\u2011center revenue.\n- Reaccelerating inventory growth alongside slowing sell\u2011through (inventory days rising).\n- TSMC allocation shortfalls, foundry disruptions, or any export\u2011control escalation.\n- Repeated high\u2011volume down days (200M+ volume) with price staying below 50 & 200 SMA.\n\n11) What would cause me to stop being bearish (flip criteria)\n- This is fair: I\u2019ll flip to neutral/bullish only if NVDA:\n - Reclaims and holds above ~185\u2013186 on strong volume, with MACD turning positive and RSI >50,\n - Shows sequential improvement in inventory turns and receivable days,\n - Produces visible evidence of stable/increasing hyperscaler bookings in guidance or public partner commentary.\n- Until those conditions are met, the risk\u2011first posture remains appropriate.\n\n12) Lessons and behavioral discipline\u2014what I\u2019ve learned (and what I\u2019ll do differently)\n- Past mistakes I\u2019ve made: chasing momentum on names with stretched multiples and neglecting hedges; treating \u201cfundamentals only\u201d as a shield against market\u2011wide repricings; waiting too long to trim at the first signs of structural tape damage.\n- How that changes my posture now:\n - Size first: cap single\u2011name exposure to a small, explicitly defined % of portfolio.\n - Hedge early: buy protective puts or use collars when entering large positions at rich valuations.\n - Use objective, pre\u2011specified triggers for trimming/exiting (the 168/160 levels above are examples).\n - Treat tape behavior as data\u2014not noise. When volume distribution aligns with technical breakdowns, be willing to act quickly.\n- I agree with the bull on disciplined tranching and hedging\u2014but the evidence says those measures are required now, not optional.\n\n13) Final, direct challenge to the bull\u2019s core assertions\n- You\u2019re right that the long\u2011term AI TAM can justify ownership. But you\u2019re underestimating three compounding risks today:\n 1) Valuation convexity: forward earnings are embedded in price\u2014small execution misses equal large price moves.\n 2) Technical regime shift: price, momentum, and volume indicate sellers are in control; that changes the odds for new unhedged entries.\n 3) Macro + concentration + supply tail risk: these amplify downside when market sentiment deteriorates.\n- Conclusion: If you are a disciplined bull, accumulate only in hedged, sized tranches and set strict, objective sell/hedge triggers. If you are a risk manager or short/intermediate trader, reduce exposure now and wait for clear signs of technical and fundamental confirmation before adding.\n\nIf helpful, I can:\n- Build the exact hedge size/strike expiries for a given share count or portfolio percentage (e.g., show how many 170/150 3\u2011month put spreads to buy for 1,000 shares).\n- Produce a one\u2011page execution plan with limit orders and stops tied to the technical/triggers above.\nWhich would you like?", + "current_response": "Key points from both sides, stripped to what really matters\n\nBull\u2019s strongest points\n- Fundamentals are exceptional: explosive data-center growth, very high margins, and huge free cash flow. The argument is that this isn\u2019t a fad; it\u2019s a multi-year AI buildout with NVIDIA as the prime beneficiary.\n- Moat is real: CUDA/software ecosystem + full-stack platform and an aggressive roadmap (Blackwell/Rubin) support pricing power and customer stickiness.\n- Balance sheet/cash flow give flexibility: buybacks, investment, and the ability to ride out volatility.\n- Even the bull concedes the tape is damaged, but frames that as an opportunity if you scale in and hedge rather than chase.\n\nBear\u2019s strongest points\n- The stock is in a technical breakdown right now: below 10/50/200-day levels, MACD negative and worsening, RSI ~38 (not washed out), VWMA above price (distribution), ATR elevated. That\u2019s a concrete \u201crisk is to the downside\u201d setup for the next weeks/months.\n- Valuation convexity: even if \u201cforward P/E looks low,\u201d it\u2019s low only because the market is assuming a big EPS ramp. If that ramp wobbles, the stock can re-rate hard. With high beta, drawdowns can be large and fast.\n- Concentration/tail risks are live: hyperscaler capex concentration, TSMC/geopolitics/export controls are asymmetric risks that can\u2019t be diversified away inside the single name.\n- Working capital (inventory/receivables) could be benign, but it\u2019s a legitimate early warning sign; you don\u2019t get to assume it\u2019s fine without confirmation.\n- Practical trade guidance is clearer and more actionable: trim/hedge now; don\u2019t add unhedged until technical repair.\n\nMy decision: Sell (risk-reduce now; re-enter only on defined confirmation)\n\nRationale (why I\u2019m siding with the bear)\nYou\u2019re not deciding whether NVIDIA is a great company. You\u2019re deciding what to do with the stock at this moment, with this setup. The bear wins on timing and risk management: the debate\u2019s hardest evidence is the multi-timeframe technical breakdown plus elevated volatility, combined with valuation sensitivity. In similar high-multiple/great-story names, a common mistake is \u201cstaying long because fundamentals are awesome\u201d while the market is actively repricing the risk premium. That\u2019s how you sit through a 25\u201340% drawdown you didn\u2019t need to take.\n\nThe bull\u2019s plan (scale in + hedge) is reasonable for someone underinvested who must own it structurally. But as a portfolio manager making a definitive call, the most robust action based on the evidence presented is to reduce exposure first, then demand confirmation before re-adding. The bear\u2019s triggers (185\u2013186 reclaim for repair; 168/160 downside levels) provide a cleaner framework than \u201cbuy the dip because the thesis is intact.\u201d\n\nStrategic actions (a detailed, concrete investment plan)\n\n1) Immediately reduce directional risk\n- If currently long shares: sell 30\u201350% of the position now.\n - Use 50% if NVDA is a top-3 position, if your horizon is <12 months, or if you\u2019re not running portfolio-level hedges.\n - Use 30% if it\u2019s already a modest position (say <3% of portfolio) and you\u2019re comfortable actively hedging.\n\n2) Hedge the remaining position (don\u2019t leave it naked)\n- Implement a 3-month put spread hedge on the remaining shares, similar to what the bear suggested:\n - Example structure: buy the 170 put / sell the 150 put (or nearest strikes with similar delta), sized to cover most of the remaining share exposure.\n - Goal: cap the damage if the breakdown extends, while keeping some upside participation if there\u2019s a snap-back.\n- If you prefer collars to reduce hedge cost:\n - Buy a protective put (e.g., ~170) and sell an out-of-the-money call (choose a strike near a level you\u2019d be happy trimming anyway, such as ~190\u2013200 depending on chain pricing).\n - This turns \u201cuncertain tape\u201d into a defined-risk hold.\n\n3) Hard risk triggers (non-negotiable)\n- If the stock closes below ~168 on rising volume: cut another 15\u201325% of the original position (or increase hedge notional).\n- If the stock closes and holds below ~160: exit the remaining shares (or ensure the hedge fully covers the residual exposure).\nThese are there to prevent the classic mistake of \u201cwaiting for it to come back\u201d while a downtrend accelerates.\n\n4) Rules for re-entry (so you\u2019re not permanently bearish)\nOnly re-add meaningful long exposure if at least one of these happens:\n- Technical repair: sustained closes back above ~185\u2013186 with momentum improving (MACD turning up/positive and RSI back above ~50), ideally on constructive volume.\nAnd/or\n- Fundamental confirmation: next guidance/partner commentary supports stable-to-rising hyperscaler AI spend and no evidence that inventory/receivables are turning into a sell-through problem (watch DSO and inventory days trend).\n\n5) If you don\u2019t currently own it (or after you sell)\n- Do not buy unhedged shares while it\u2019s below the major moving averages with negative momentum.\n- If you must express a bullish view, use defined-risk structures:\n - Small debit call spreads (so max loss is premium)\n - Or smaller starter equity position paired immediately with a put (synthetic \u201crisk-defined\u201d stock)\n\n6) Position sizing going forward (to avoid repeat errors)\n- Cap NVDA at a preset portfolio limit (typical: 3\u20136% max for most diversified portfolios; less if volatility is already high elsewhere).\n- No \u201cadd to losers\u201d unless a pre-defined technical/fundamental confirmation condition is met. This is the behavior that most often turns a manageable drawdown into portfolio damage in crowded mega-cap leaders.\n\nNet: The company can be outstanding and the stock can still be a sell right now. The debate\u2019s strongest, most actionable evidence points to near-term downside risk overwhelming the benefit of staying fully exposed. Reduce first, define the risk on what remains, and earn the right to re-buy on confirmation rather than hope.", + "judge_decision": "Key points from both sides, stripped to what really matters\n\nBull\u2019s strongest points\n- Fundamentals are exceptional: explosive data-center growth, very high margins, and huge free cash flow. The argument is that this isn\u2019t a fad; it\u2019s a multi-year AI buildout with NVIDIA as the prime beneficiary.\n- Moat is real: CUDA/software ecosystem + full-stack platform and an aggressive roadmap (Blackwell/Rubin) support pricing power and customer stickiness.\n- Balance sheet/cash flow give flexibility: buybacks, investment, and the ability to ride out volatility.\n- Even the bull concedes the tape is damaged, but frames that as an opportunity if you scale in and hedge rather than chase.\n\nBear\u2019s strongest points\n- The stock is in a technical breakdown right now: below 10/50/200-day levels, MACD negative and worsening, RSI ~38 (not washed out), VWMA above price (distribution), ATR elevated. That\u2019s a concrete \u201crisk is to the downside\u201d setup for the next weeks/months.\n- Valuation convexity: even if \u201cforward P/E looks low,\u201d it\u2019s low only because the market is assuming a big EPS ramp. If that ramp wobbles, the stock can re-rate hard. With high beta, drawdowns can be large and fast.\n- Concentration/tail risks are live: hyperscaler capex concentration, TSMC/geopolitics/export controls are asymmetric risks that can\u2019t be diversified away inside the single name.\n- Working capital (inventory/receivables) could be benign, but it\u2019s a legitimate early warning sign; you don\u2019t get to assume it\u2019s fine without confirmation.\n- Practical trade guidance is clearer and more actionable: trim/hedge now; don\u2019t add unhedged until technical repair.\n\nMy decision: Sell (risk-reduce now; re-enter only on defined confirmation)\n\nRationale (why I\u2019m siding with the bear)\nYou\u2019re not deciding whether NVIDIA is a great company. You\u2019re deciding what to do with the stock at this moment, with this setup. The bear wins on timing and risk management: the debate\u2019s hardest evidence is the multi-timeframe technical breakdown plus elevated volatility, combined with valuation sensitivity. In similar high-multiple/great-story names, a common mistake is \u201cstaying long because fundamentals are awesome\u201d while the market is actively repricing the risk premium. That\u2019s how you sit through a 25\u201340% drawdown you didn\u2019t need to take.\n\nThe bull\u2019s plan (scale in + hedge) is reasonable for someone underinvested who must own it structurally. But as a portfolio manager making a definitive call, the most robust action based on the evidence presented is to reduce exposure first, then demand confirmation before re-adding. The bear\u2019s triggers (185\u2013186 reclaim for repair; 168/160 downside levels) provide a cleaner framework than \u201cbuy the dip because the thesis is intact.\u201d\n\nStrategic actions (a detailed, concrete investment plan)\n\n1) Immediately reduce directional risk\n- If currently long shares: sell 30\u201350% of the position now.\n - Use 50% if NVDA is a top-3 position, if your horizon is <12 months, or if you\u2019re not running portfolio-level hedges.\n - Use 30% if it\u2019s already a modest position (say <3% of portfolio) and you\u2019re comfortable actively hedging.\n\n2) Hedge the remaining position (don\u2019t leave it naked)\n- Implement a 3-month put spread hedge on the remaining shares, similar to what the bear suggested:\n - Example structure: buy the 170 put / sell the 150 put (or nearest strikes with similar delta), sized to cover most of the remaining share exposure.\n - Goal: cap the damage if the breakdown extends, while keeping some upside participation if there\u2019s a snap-back.\n- If you prefer collars to reduce hedge cost:\n - Buy a protective put (e.g., ~170) and sell an out-of-the-money call (choose a strike near a level you\u2019d be happy trimming anyway, such as ~190\u2013200 depending on chain pricing).\n - This turns \u201cuncertain tape\u201d into a defined-risk hold.\n\n3) Hard risk triggers (non-negotiable)\n- If the stock closes below ~168 on rising volume: cut another 15\u201325% of the original position (or increase hedge notional).\n- If the stock closes and holds below ~160: exit the remaining shares (or ensure the hedge fully covers the residual exposure).\nThese are there to prevent the classic mistake of \u201cwaiting for it to come back\u201d while a downtrend accelerates.\n\n4) Rules for re-entry (so you\u2019re not permanently bearish)\nOnly re-add meaningful long exposure if at least one of these happens:\n- Technical repair: sustained closes back above ~185\u2013186 with momentum improving (MACD turning up/positive and RSI back above ~50), ideally on constructive volume.\nAnd/or\n- Fundamental confirmation: next guidance/partner commentary supports stable-to-rising hyperscaler AI spend and no evidence that inventory/receivables are turning into a sell-through problem (watch DSO and inventory days trend).\n\n5) If you don\u2019t currently own it (or after you sell)\n- Do not buy unhedged shares while it\u2019s below the major moving averages with negative momentum.\n- If you must express a bullish view, use defined-risk structures:\n - Small debit call spreads (so max loss is premium)\n - Or smaller starter equity position paired immediately with a put (synthetic \u201crisk-defined\u201d stock)\n\n6) Position sizing going forward (to avoid repeat errors)\n- Cap NVDA at a preset portfolio limit (typical: 3\u20136% max for most diversified portfolios; less if volatility is already high elsewhere).\n- No \u201cadd to losers\u201d unless a pre-defined technical/fundamental confirmation condition is met. This is the behavior that most often turns a manageable drawdown into portfolio damage in crowded mega-cap leaders.\n\nNet: The company can be outstanding and the stock can still be a sell right now. The debate\u2019s strongest, most actionable evidence points to near-term downside risk overwhelming the benefit of staying fully exposed. Reduce first, define the risk on what remains, and earn the right to re-buy on confirmation rather than hope." + }, + "trader_investment_decision": "Summary judgment\n- I agree with the provided plan: this is a tactical SELL (reduce exposure now, hedge what remains, re-enter only on defined confirmation). The reasoning: multi-timeframe technical breakdown + elevated volatility and valuation sensitivity make timing risk dominant vs. long-term fundamentals.\n\nImmediate actions (execute within the next trading session)\n1) Reduce directional exposure now\n- If NVDA is a top-3 position or your horizon <12 months: sell 50% of shares.\n- If NVDA is a modest holding (<~3% of portfolio) and you actively hedge: sell 30% of shares.\n- Use limit orders, scale out in 1\u20133 tranches to avoid market-impact; if volatility is extreme use VWAP or adaptive algos.\n\n2) Hedge the remaining position (3-month window)\n- Preferred: buy a put spread sized to cover the remaining shares.\n - Example structure (use nearest liquid strikes): buy the 170 put / sell the 150 put, sized so notional \u2248 remaining share exposure (1 option contract = 100 shares).\n - Purpose: materially cap downside while retaining some upside.\n- Alternative (if you want lower cost): collar \u2014 buy a protective put (\u2248170) and sell an OTM call (e.g., ~190\u2013200) sized to the position. Choose the call strike consistent with a price you\u2019d be happy to trim to.\n- If you prefer full protection and can pay: buy outright protective puts instead of a spread.\n\nHard, non-negotiable risk triggers (actionable stop rules)\n- If NVDA closes below ~168 on rising volume: immediately sell an additional 15\u201325% of the original position (or increase hedge notional to cover that chunk).\n- If NVDA closes and holds below ~160: exit the remaining shares (or ensure the hedge becomes full coverage to net-zero delta).\n- Do not \u201chope\u201d through these levels\u2014these are to prevent the common mistake of letting a large drawdown eat portfolio capital.\n\nRe-entry rules (must meet at least one)\n- Technical repair: sustained closes back above ~185\u2013186 with improving momentum (MACD turning up/positive, RSI >50) and constructive volume.\n- Fundamental confirmation: next earnings/guidance or partner commentary clearly shows hyperscaler AI spend intact and no inventory/receivables sell-through concerns.\n- Only re-add with defined risk (collars, spreads, or small initial sizes), and cap NVDA to a preset portfolio limit (recommend 3\u20136% max for diversified portfolios).\n\nIf you don\u2019t currently own shares\n- Do not initiate unhedged long exposure while NVDA remains below major moving averages with negative momentum.\n- If you must express a bullish stance, use defined-risk structures: small debit call spreads or a starter equity position paired immediately with a protective put.\n\nExecution & risk-control notes (practical)\n- Size options to round lots (100 shares/contract) and account for commissions/assignment risk for short calls/puts.\n- Prefer liquid strikes (open interest/volume) to minimize slippage.\n- Monitor news/TSMC/geopolitics and hyperscaler commentary\u2014these are the asymmetric tail risks that can overwhelm technical repair.\n- Review position sizing after this action to ensure NVDA no longer threatens portfolio concentration.\n\nLearning reminder (behavioral rule)\n- Don\u2019t add to losers without pre-defined technical/fundamental confirmation. Define maximum acceptable drawdown and hedge early; trim when a name becomes disproportionately large.\n\nFirm decision\n- Reduce exposure now, hedge the remainder, and only re-enter on the triggers above.\n\nFINAL TRANSACTION PROPOSAL: **SELL**", + "risk_debate_state": { + "aggressive_history": "\nAggressive Analyst: You didn\u2019t include the conservative or neutral analysts\u2019 last arguments, so I won\u2019t invent them. I\u2019ll focus on why the trader\u2019s SELL / hedge-now approach, while prudent, is overly conservative and likely to miss asymmetric upside. I\u2019ll pick apart the assumptions behind a forced reduce-and-wait posture and lay out aggressive, high-upside alternatives\u2014each tied to the data in your reports.\n\nQuick thesis: NVDA\u2019s near-term tape is noisy and risky, yes\u2014but fundamentals and catalyst optionality create extreme upside asymmetry that a strict \u201ctrim + hedge and only re-enter after technical repair\u201d regime can permanently miss. If you have a high risk tolerance or a long horizon, accept intentional, sized risk to capture multi-quarter re-rating driven by data-center pull-through, product adoption (Blackwell/Rubin), TSMC allocation wins, or hyperscaler guidance. Use leveraged, defined-risk or premium-funded option structures and selective selling to increase upside exposure while keeping behavioral controls.\n\nWhy the conservative SELL-first logic may be wrong for aggressive players\n- The fundamentals are not \u201cfragile.\u201d Latest quarter: revenue $68B, gross margin ~75%, operating margin ~65%, net income and free cash flow gigantic. Net-cash cushion (~$50B+) and continued buybacks mean the company can execute through cycles. Those numbers justify materially higher valuation if growth holds.\n- Tactical technicals can flip fast on a single positive catalyst. The market is pricing AI optionality; one hyperscaler guide-up, a TSMC allocation update, or proof of end-customer sell-through could trigger a fast 20\u201340% re-rate. Waiting for 3 closes above 185\u2013186 risks catching only the late innings of those moves.\n- Hedging costs and hedges that cap upside reduce asymmetry. Buying protective put spreads or collars now preserves downside but also caps uncapped upside that could occur if guidance or orders materially surprise to the upside. For aggressive players, there are better ways to preserve optionality.\n\nData-driven counters to the SELL plan\u2019s main assumptions\n- \u201cPrice below 200 SMA = structural breakdown\u201d \u2014 True short-term, but fundamentals show revenue and margin trajectories that can force technical repair quickly. With forward EPS consensus implying a step-up to EPS ~11.13, multiples can compress or expand rapidly; technicals alone don\u2019t refute the secular thesis.\n- \u201cVolatility makes timing risk dominant\u201d \u2014 Elevated ATR and a VIX near 24 increase cost of plain protective puts, but they also inflate call values and create rich premium to harvest via selling strategies (puts/calls) or to use for buying longer-dated, cheaper optionality (LEAPS).\n- \u201cInventory/receivables risk\u201d \u2014 inventory and AR are elevated and deserve monitoring, but NVDA has the balance-sheet firepower and strong FCF to manage a temporary digestion. That reduces existential downside relative to many high-growth peers.\n\nConcrete aggressive alternatives (ranked by aggressiveness and asymmetric payoff)\n\n1) Aggressive long-term asymmetric play (highest upside, managed cost)\n- Action: Buy 12\u201324 month LEAPS calls sized to increase effective exposure while only using a fraction of notional capital.\n- Rationale: Captures multi-quarter revenue and margin realization (Blackwell/Rubin adoption, hyperscaler pull-through) without being stopped out by short-term technical dust-ups. With fundamentals implying a much higher forward EPS, long-dated calls offer leverage to that re-rating.\n- Risk control: Keep position size meaningful but not dominant\u2014target total NVDA exposure (stock + options delta) at the high end of your allowed allocation (e.g., 6\u201310% for aggressive accounts). Ladder entry across expiries to reduce timing risk.\n\n2) Premium-funded accumulation (buy the dip with downside acceptance)\n- Action: Sell cash-secured OTM puts at strikes where you\u2019d be happy to own more NVDA (e.g., strikes below current price that reflect ~1\u20132\u00d7ATR moves), collect premium and either (a) get put-to and add materially at lower cost, or (b) use premium to buy calls.\n- Rationale: You\u2019re effectively getting paid to set a lower-cost basis. If you\u2019re confident in NVDA\u2019s multi-year growth, owning more on weakness is the highest-expected-value move.\n- Risk: If a severe macro / demand shock occurs you can be assigned at a level you already accepted; manage size and capital to remain cash-secured.\n\n3) High-conviction event-driven long (targeted leverage around catalysts)\n- Action: Ahead of hyperscaler/TSMC/earnings catalysts, buy concentrated 3\u20136 month call spreads (e.g., a nearer strike buy / higher strike sell) sized to deliver 3\u20135x directional upside on a positive surprise.\n- Rationale: Captures binary re-rates without paying full IV for naked calls (sell higher strike to offset cost). If the print is strong, upside is large; if negative, loss is limited to premium.\n- Risk: Short-dated IV pops can widen spreads, but defined loss limits behavioral pain.\n\n4) Risk-reversal / skew play (aggressive directional with financing)\n- Action: Sell an OTM put and use premium to buy OTM calls (or a call spread). You accept conditional downside in exchange for asymmetric upside exposure.\n- Rationale: With elevated implied vol and demand for puts, you can finance significant upside exposure. This is higher risk but optimizes dollar-for-dollar upside if you\u2019re confident in fundamentals.\n- Risk management: Size strongly and choose put strikes you can live with being assigned on; avoid if portfolio can\u2019t absorb assignment.\n\n5) Selective trimming + levered optional replacement (compromise vs SELL)\n- If you currently hold a top-3 position and the trader recommends selling 50%: instead sell 20\u201330% to lock partial gains, then take proceeds to buy LEAPS or buy call spreads that replicate the remaining position\u2019s upside at lower capital.\n- Why this is better: You monetize portion of exposure to reduce absolute dollar risk while maintaining upside optionality. It\u2019s not capitulation; it\u2019s converting outright equity into leveraged upside.\n\nDirect rebuttals to the trader\u2019s specific tactical rules\n- Trader rule: \u201cSell 50% if top-3 or horizon <12 months.\u201d Counter: If horizon >12 months, don\u2019t mechanically sell 50%. Instead, scale to 20\u201330% and convert some capital to LEAPS. The balance between pure stock and options controls downside while preserving upside optionality. This boots the upside asymmetry rather than neutering it via collars.\n- Trader rule: \u201cBuy a protective put spread (e.g., 170/150) for 3 months.\u201d Counter: Buying that spread materially reduces upside for modest protection. Instead, consider:\n - Buying longer-dated puts as catastrophic insurance (rare but cheaper per unit of time), or\n - Selling premium (OTM puts or calls) to fund upside call purchases, or\n - Using a cheap broken-wing call spread to skew payoff to the upside while limiting one-sided bad draws.\n- Trader rule: \u201cNon-negotiable stop at 168 / exit at 160.\u201d Counter: Hard stops are predictable and can trigger selling into panics. For an aggressive account, prefer a dynamic rebalancing policy tied to fundamentals (e.g., re-evaluate only if sequential data-center revenue decelerates materially or guidance is cut) rather than mechanical intraday closes; if you must use mechanicals, set them wider (respect ATR) and size accordingly.\n\nWhere the conservative caution is likely overly pessimistic\n- They overweight tape structure and underweight balance sheet and revenue runway. NVDA is running enormous margins, cash flow, and strategic lock-in with hyperscalers\u2014those characteristics create an asymmetric payoff where a success blows the top off short-term technicals.\n- They assume options cost to hedge is acceptable; but current IV is an opportunity for aggressive players to sell premium or buy time-levered options instead of bluntly paying full insurance.\n- They underprice catalyst velocity. Historically, NVDA\u2019s re-ratings can be rapid and non-linear\u2014missing early re-entries because you waited for multiple technical confirmations is a real opportunity cost.\n\nPractical execution suggestions (aggressive, but controlled)\n- If you hold NVDA and are willing to be aggressive:\n - Sell 20\u201330% of shares now to lock gains.\n - Use proceeds to buy 12\u201318 month LEAPS calls equal to ~50% of sold exposure (delta-adjusted) \u2014 keeps upside with less capital.\n - Simultaneously sell 1\u20132 OTM cash-secured puts at strikes you\u2019d accept assignment at to fund more calls or reduce net cost.\n- If you do not hold NVDA and are aggressive:\n - Avoid buying unhedged near-term stock. Instead buy 9\u201318 month call spreads sized to the account (e.g., buy 200/300 call spread or similar depending on strike selection and risk tolerance).\n - If you want to be very aggressive, sell a put at a lower strike to fund the call spread (risk-managed via cash-secured leg).\n- Size rules: Keep net delta exposure within a high-risk tolerance band\u2014target aggregate NVDA exposure (stock + option delta) to no more than 6\u201310% of portfolio for aggressive accounts; lower for swing traders.\n\nFinal push: Why aggressive risk wins here\n- The company\u2019s fundamentals produce optionality: massive margins, extraordinary FCF, huge buybacks, and dominant platform position. Those qualities are classic \u201cconvex\u201d payoffs where riding volatility with leverage and time can dramatically outperform cautious trimming.\n- Technical breakdowns can be whipsawed by one or two positive data points; if you exit too early, you hand the accelerated re-rate to fast money.\n- The market\u2019s elevated IV is an opportunity, not only a cost: efficient option structures can buy leverage or generate yield to fund upside exposure.\n\nIf you want, I\u2019ll convert any of the four aggressive trade concepts above into precise, executable sets for your account size (exact strike bands, suggested expiries, delta targets, contract counts, and cash-secured leg sizing). Tell me whether you\u2019re: (A) high-conviction long-term holder, (B) event-driven trader, or (C) willing to use premium-funded structures\u2014plus your portfolio size and max % allocation\u2014and I\u2019ll produce a step-by-step execution plan.", + "conservative_history": "\nConservative Analyst: Short version: I disagree with the Aggressive Analyst\u2019s framework for this account. The data show a technically confirmed distribution, elevated realized/implied volatility, meaningful inventory/AR buildup, and large valuation sensitivity \u2014 a combination that favors protecting capital and limiting portfolio concentration now, not increasing convex long exposure or writing premium that can leave the firm exposed to left\u2011tail outcomes. Below I rebut the aggressive points directly, highlight where they underweight real risks, and offer safer, practical alternatives consistent with the trader\u2019s SELL recommendation.\n\n1) \u201cFundamentals make technicals irrelevant\u201d \u2014 not how market risk works\n- Fact-check: Fundamentals are very strong (latest quarter revenue $68.1B, gross margin ~75%, huge FCF and net-cash ~+$50B). But the market is already pricing that growth: market cap \u2248 $4.2T, TTM P/E ~35, forward EPS implies aggressive expectations. That makes the security extremely sensitive to any demand or guidance slip.\n- Why this matters: High valuation + high beta (\u22482.38) + VIX \u224824 = severe downside convexity. A small miss or macro shock can produce outsized drawdowns even if the long\u2011term thesis remains intact. Protecting capital matters more for the firm than chasing optional upside.\n\n2) \u201cCatalysts can re-rate quickly, so don\u2019t trim\u201d \u2014 that\u2019s timing risk, not an edge for a risk manager\n- Reality: Yes, catalysts can cause big upmoves. They also cause big downmoves. Technicals are currently bearish across timeframes: price 172.93 < 10 EMA 180.14 < 50 SMA 184.60 and below the 200 SMA 178.42; MACD negative (-1.99), RSI ~38, VWMA 181.24 > price (distribution), ATR \u2248 5.77. Volume confirms distribution.\n- Implication: Waiting for the \u201cone positive catalyst\u201d is asymmetric: you may get a fast upmove, but you\u2019re much more likely to get a fast downmove that damages capital before fundamentals can vindicate you. For a firm whose objective is capital preservation and steady growth, avoiding that exposure is the prudent choice.\n\n3) \u201cSell puts / risk reversals / LEAPS to increase convexity\u201d \u2014 these add risk the firm may not be able to absorb\n- Selling cash\u2011secured puts: in normal times this is fine. Today, assignment risk equals concentrated long exposure at a moment of technical weakness, inventory build ($21.4B) and receivables ($38.5B) that could presage a digest cycle. Getting put\u2011to at a lower strike can double down into a concentrated bet the firm may not want.\n- Risk reversals (sell put / buy call): they finance upsides by taking left\u2011tail risk. That is exactly the exposure you should be minimizing when macro (oil >$100), supply (TSMC concentration), and geopolitical tail risks exist.\n- LEAPS calls: they can lose 100% of premium in a sustained market drawdown or if the re-rating is delayed. They are leverage, not insurance. For a firm prioritizing steady growth and volatility control, replacing equity with long premium is not a substitute for disciplined position-size reduction + hedging.\n\n4) \u201cHedges cap upside \u2014 avoid them\u201d \u2014 that\u2019s precisely why you need them\n- Hedges cost money, but the alternative is open\u2011ended downside that can take years to recover. With ATR ~5.8 and potential two\u2011ATR moves of ~11\u201312 points, unhedged large positions expose the portfolio to meaningful single\u2011session losses.\n- Practical point: put spreads or collars (structured correctly) materially limit downside while permitting participation on a measured basis. That\u2019s consistent with protecting capital and maintaining optional upside in a controlled way.\n\n5) Inventory / receivables and concentration risk are non-trivial \u2014 the Aggressive Analyst downplays them\n- Inventory at $21.4B and receivables at $38.5B increased materially. That can reflect either a true ramp or channel stuffing/stock build ahead of slowing sell\u2011through. With hyperscaler capex the dominant demand driver, any sequential softness or channel digestion would rapidly reprice the stock.\n- TSMC concentration and geopolitical risk remain live tail risks for supply. These aren\u2019t abstract: they are asymmetric downside drivers that can swamp a technical repair.\n\n6) Technical stop rules are not \u201cpredictable weakness\u201d \u2014 they are loss\u2011limiting rules\n- The trader\u2019s hard triggers (close below ~168 on rising volume \u2192 sell another 15\u201325%; close and hold below ~160 \u2192 exit remaining) are practical guardrails that prevent a small mistake from becoming a portfolio\u2011level drawdown. ATR\u2011aware stops are smarter than looser, ideologically driven \u201cwe\u2019ll wait for fundamentals\u201d rules that often become emotional hopes in a crash.\n\nPractical conservative counter\u2011proposals (what to do instead of the aggressive playbook)\n- If NVDA is a top-3 holding or horizon <12 months: follow the trader\u2019s guidance \u2014 sell 50% now. Don\u2019t trade away the capital by holding through a drawdown.\n- Hedge the remainder: buy a 3\u2011month put spread (example using liquid strikes around 170/150) sized to remaining shares. It caps near-term downside while retaining upside. If you must lower cost, use a collar only if the short call strike is a level you are comfortable being forced to sell into.\n- Avoid putting on new uncovered short puts or selling naked premium in bulk. If you use put writing at all, limit size to a tiny % of capital and ensure cash\u2011secured and pre\u2011approved assignment levels that respect the portfolio cap (3\u20136%).\n- Do not replace sold shares with LEAPS unless you are explicitly designated a high\u2011risk mandate. If the firm is long\u2011term but conservative, better alternatives: scale in via defined\u2011risk debit spreads (buy calls/sell higher calls) with small notional; or buy longer\u2011dated protective puts as catastrophic insurance.\n- Enforce portfolio caps: limit NVDA exposure to 3\u20136% of total portfolio (as the trader suggests). Aggressive proposals that target 6\u201310% or allow assignment could produce concentration risk inconsistent with the mandate.\n- Execution discipline: scale out in 1\u20133 tranches using limit orders; if market impact is a concern, use VWAP/adaptive algos; size hedges to round lots and account for assignment risk.\n\nPoint\u2011by\u2011point rebuttal of the Aggressive\u2019s proposed trades\n- LEAPS purchase to increase exposure: LEAPS are a long gamma play that can be wiped out by a multi\u2011month bear cycle. They do not protect against valuation compression and may amplify realized volatility for the account because they convert capital into a high\u2011volatility instrument. Conservative alternative: reduce equity exposure first, then buy modest, defined\u2011risk call spreads (shorter-dated) only after the tape shows stabilizing breadth and improving momentum.\n- Selling cash\u2011secured puts to \u201cget paid to set a basis\u201d: in a high\u2011IV, distribution phase, you may get assigned into a materially larger, concentrated position at a poor time. If you insist on selling puts, cap total potential assignment to a small, funded percentage of the portfolio and only at strikes you\u2019d actually be content to own as part of your 3\u20136% cap.\n- Risk reversals / selling premium to finance calls: this transfers downside to the firm in exchange for upside optionality. If the macro or geopolitical tail hits, losses from assignment or deep OTM put exposure can be large and permanent. Do not use financed structures that materially increase left\u2011tail exposure for the firm.\n- Narrow trimming (sell 20\u201330% and buy LEAPS): partial monetization is sensible, but the proposed sizes understate near\u2011term risk. If you reduce only 20\u201330% when NVDA is a top\u20113 holding and valued aggressively, you still have unacceptable concentration. Conservative compromise: sell 50% if top\u20113; if you must keep upside optionality buy limited call spreads sized small relative to capital freed by the sale.\n\nWhy the trader\u2019s SELL + hedge + re\u2011entry rules are superior for risk control\n- They combine immediate de\u2011risking (reduce exposure now), defined protection for the remainder (put spread or collar), and objective re\u2011entry triggers (sustained close >185\u2013186 + momentum/fundamental confirmation). That structure prevents emotional doubling down, enforces drawdown limits, and keeps upside optionality while preserving capital.\n- They use technical, volatility and fundamental signals together (not only one) \u2014 this is prudent when valuation is rich and macro/supply tail risks are present.\n\nConclusion \u2014 firm recommendation for a conservative mandate\n- Follow the trader\u2019s SELL decision as written: reduce now (50% if top\u20113 or horizon <12 months; 30% if modest and you already hedge), hedge the remainder with defined\u2011risk structures (prefer put spreads or protective puts if funds allow), adhere to the hard stop triggers (168/160 on rising volume), cap NVDA to 3\u20136% of portfolio, and only re\u2011enter on multi\u2011factor confirmation (technical and fundamental).\n- Do not adopt the aggressive tactics of selling large amounts of premium, funding asymmetric upside with downside exposure, or replacing sold stock with LEAPS at scale. Those strategies increase tail risk and can produce permanent capital loss \u2014 the exact outcome a conservative mandate must avoid.\n\nIf you want, I will:\n- convert the SELL + hedge rule set into explicit order-level instructions for a given portfolio size (how many shares to sell, how many put\u2011spread contracts to buy, strikes/expiries consistent with liquidity and ATR), or\n- produce a short scenario analysis (P/L profiles) comparing the conservative hedge approach vs. the aggressive LEAPS/risk\u2011reversal outcomes at different NVDA price paths.\n\nWhich follow-up would you prefer?", + "neutral_history": "\nNeutral Analyst: Good\u2014this is a useful debate. I\u2019ll pick apart the Aggressive and Conservative positions, show where each over- and under-weights the facts in the reports, and then propose a practical, moderate execution path that preserves upside optionality without leaving the portfolio exposed to the clear near-term risks.\n\nTop-line calibration (facts we both must live with)\n- Technicals are weak: last close ~172.93; price < 10 EMA (180), < 50 SMA (184.6) and below the 200 SMA (~178.4). MACD is negative and accelerating; RSI ~38; VWMA ~181 is above price \u2192 distribution. ATR \u2248 5.8 (expect large daily swings).\n- Fundamentals are unusually strong: huge recent quarter ($68B revenue), gross margin ~75%, massive operating/cash flow and a net-cash cushion (~$50B+). Forward EPS consensus implies a large earnings step-up, which is why valuation is very rich (market cap ~ $4.2T).\n- Key risks are real: inventory ($21.4B) and receivables ($38.5B) have grown materially; hyperscaler capex sensitivity, TSMC concentration and macro shocks (VIX ~24, oil >$100) are credible asymmetric downside drivers.\n\nWhere the Aggressive Analyst is too optimistic\n- Overweights fundamentals to the point of downplaying valuation convexity. Yes, NVDA has enormous FCF and platform advantages, but the market has priced much of that in \u2014 a small demand hiccup or guidance disappointment can produce a large multiple compression because beta is high and sentiment is fragile.\n- Underestimates inventory/AR risk. A large inventory build and rising ARs can be either benign (planned ramp) or a leading indicator of channel digestion. Aggressive LEAPS and risk-reversals treat that as negligible; they aren\u2019t.\n- Minimizes assignment/left-tail risk of financed structures. Selling puts or risk-reversals to finance upside materially increases the portfolio\u2019s downside exposure if macro/geopolitical gets worse \u2014 exactly the scenarios the Conservative Analyst fears.\n- Paints IV only as an \u201copportunity.\u201d Elevated IV makes calls more expensive too; LEAPS are levered and can still expire worthless if the re-rate is delayed.\n\nWhere the Conservative Analyst is too cautious\n- May be giving up significant expected upside and real optionality. NVDA\u2019s fundamental momentum and the possibility of quick positive catalysts (hyperscaler guidance, TSMC allocation news, product/Blackwell adoption) argue you shouldn\u2019t fully sterilize upside for a small reduction in short-term drawdown.\n- Hard mechanical stops can be self\u2011fulfilling and cause selling into panic. A purely mechanical close-below rule without ATR\u2011aware tolerance and context (volume, macro prints) can force bad execution and crystallize losses at the worst times.\n- Treats all premium-writing as reckless \u2014 when done small, cash-secured, and sized to allocation limits, selling puts can be a constructive way to lower basis if you genuinely want more exposure at lower levels.\n- May overpay for pure insurance if it forces large collars that eliminate meaningful upside; there are hybrid hedging tactics that cost less yet materially reduce risk.\n\nA neutral, practical synthesis \u2014 balance the upside optionality and the downside protection\nPrinciples guiding the compromise\n- Reduce absolute dollar concentration now (de-risk) but preserve controlled upside optionality.\n- Hedge the remaining exposure in layered, time-staggered fashion to balance cost vs protection.\n- Use objective, ATR-aware mechanical rules combined with fundamental checkpoints (not pure price-only stops).\n- Limit any premium-financing or assignment risk to a clearly small, pre-defined share of the portfolio.\n\nConcrete moderate strategy (execution-ready, adaptable to portfolio size)\n1) Reduce exposure now (immediate / next session)\n- If NVDA is a top-3 holding or your horizon <12 months: sell 40% of shares now (compromise between 50% conservative and 20\u201330% aggressive). Rationale: meaningful de-risk while retaining upside.\n- If NVDA is a modest holding (<~3%): sell 25\u201330% now, or hold but immediately hedge (below).\n- Use limit orders, scale out in 1\u20133 tranches; if markets are chaotic use VWAP/adaptive algos.\n\n2) Hedge the remainder (layered, sized to remaining shares)\n- Short-term tactical protection (3 months): buy a put spread sized to cover the post-trim holdings (e.g., long 170 / short 150 as a reference structure). This materially caps near-term downside but reduces hedge premium vs naked protective puts.\n- Stagger longer-dated catastrophic insurance (9\u201312 months): buy a longer-dated protective put (deeper OTM) or a cheap out-of-the-money LEAP put to protect the tail. That keeps a safety net if the right-tail re-rate takes longer than expected.\n- Cost-reducing option: if you accept defined trimming levels, sell a small number of OTM covered calls or implement a collar on a fraction of the remaining shares at strikes you\u2019d be content to sell into (e.g., near the 190\u2013200 zone if that aligns with your willingness to trim). Keep covered-call sizing modest so you don\u2019t fully cap upside.\n- Operational notes: size options in 100-share lots, prefer liquid strikes/expiries, account for assignment risk on sold calls/puts.\n\n3) Limited, conditional premium-funded tactics (only if you actively manage assignment risk)\n- If you are comfortable with being assigned and only up to a small allocation: sell a modest amount of cash\u2011secured OTM puts equal to no more than 10\u201315% of the original position (not the remaining position). Choose strikes roughly 1\u20132\u00d7ATR below current (~ ~162\u2013162? adjust to live quote) or at price levels where you\u2019d be happy to increase exposure. Use this to collect premium to buy LEAPS or reduce net hedge cost.\n- Don\u2019t size put-selling to a level that, if assigned, would push the stock to a top-3 position or above your portfolio cap.\n\n4) Hard triggers and dynamic risk control (blend of price, ATR, volume, and fundamentals)\n- Keep the trader\u2019s structured triggers but make them ATR-aware and contextual:\n - If NVDA closes below ~168 on rising volume (consistent with trader): increase hedge notional to cover an additional 15\u201325% of the original position OR sell an additional 10\u201315% (if still above your minimum holding), depending on whether you want to turn protection into realized reduction.\n - If NVDA closes and holds below ~160: this is a clear risk state \u2014 either exit remaining shares or ensure hedge makes net delta ~0 (i.e., be fully protected). Implement within one trading session.\n - Stop spacings and execution: use 1.5\u20132\u00d7ATR (~9\u201312 points) as a guide for avoiding whipsaws; if price action is violent, prefer hedging increases over immediate forced market sells.\n- Add a fundamental stop-latch: if hyperscaler guidance sequentially decelerates (data center revenue guidance miss or cloud customers explicitly slow orders), treat that as equivalent to the 160 trigger and de-risk aggressively.\n\n5) Re-entry rules (balanced, staged)\n- Require two-factor confirmation for larger re-entries (reduces whipsaw risk): sustained technical repair (daily closes above ~185\u2013186 with MACD turning up and RSI >50) AND a positive fundamental signal (stronger-than-expected data-center revenue/guidance or hyperscaler commentary confirming sell-through).\n- Allow small, hedged tactical re-entries on technical-only signals: if price clears 185\u2013186 but fundamental signals are neutral, re-enter in small tranches (e.g., add 10\u201320% of target allocation) and keep protection (collars/put spreads) until fundamentals catch up.\n- Cap rebuilt NVDA allocation to 3\u20135% for most diversified portfolios; allow 5\u20136% only for higher-conviction sleeves with explicit risk budgets.\n\nWhy this middle path works\n- It captures upside optionality without full exposure: trimming 40% frees capital and cuts concentration, while LEAPS/call components preserve upside optionality on the remainder.\n- It materially limits left-tail risk through layered hedges (short-term put spreads + long-term tail put), yet keeps hedge cost reasonable via spreads/collars and the small, conditional premium-funded tactics.\n- It avoids reflexive selling into panic by using ATR-aware spacing and a combination of technical + fundamental triggers.\n- It respects both analysts\u2019 valid points: the Conservative Analyst\u2019s emphasis on inventory/valuation/tail risk and the Aggressive Analyst\u2019s point that fundamentals and catalysts can re-rate NVDA quickly.\n\nMonitoring checklist (what to watch daily/weekly)\n- NVDA: data-center revenue cadence and guidance; inventory and receivables trends (days sales outstanding).\n- Hyperscalers (AMZN/MSFT/GOOGL): cloud capex/guidance commentary.\n- TSMC updates: capacity, lead times, allocation notes.\n- Options market: IV percentile, skew, unusual flow (large put buys or big call blocks).\n- Macro: VIX, oil moves above $100, yields \u2014 these change risk premia quickly.\n- Volume context on price moves: confirm moves are supported by heavy or light volume.\n\nExample scenarios (illustrative)\n- If NVDA gaps down 15% on macro shock to ~147: with the proposed plan you\u2019ve sold a portion (40%), your immediate put-spread hedge cushions the remainder, and the long-dated tail put limits catastrophic loss. You also have dry powder and optionality to buy in a measured way if fundamentals remain intact.\n- If NVDA gaps up 20% on hyperscaler upside to ~207: you retain upside via remaining shares and any purchased LEAPS/call spreads; modest covered-call/collar usage has limited only a fraction of upside but overall you\u2019ve retained a sizable participation (and you sold down to reduce concentration risk).\n\nPractical next steps I\u2019d recommend now\n- Decide your target NVDA allocation cap (I recommend 3\u20135% for most diversified mandates; pick upper bound if you have higher conviction).\n- Execute the trim: sell 40% (if top-3 / short horizon) or 25\u201330% (if modest). Scale over 1\u20133 tranches.\n- Immediately buy a 3-month put spread sized to the remaining shares (e.g., long 170 / short 150 band as a hedge example), and simultaneously buy a single longer-dated OTM put (9\u201312 months) for tail protection.\n- If you want to lower hedge cost: implement a partial collar (sell a small number of OTM calls) only on shares you are comfortable selling at that strike.\n- Set monitoring alerts for the triggers above (close <168 with rising vol; close <160) and the fundamental indicators (hyperscaler commentary, TSMC).\n\nFinal debate-style takeaway\n- To the Aggressive Analyst: you\u2019re right that the long-term optionality is huge and that waiting for perfect technical repair can cause missed upside; but you downplay real left-tail risks (inventory, macro, TSMC/geopolitics) and the cost of being assigned into concentration at the wrong time. Include limiters and small-size premium-funded tactics only as conditional tools.\n- To the Conservative Analyst: you\u2019re right that capital preservation and defined hedges are essential given valuation and technical breakdown; but being overly sterilized (large collars that eliminate meaningful upside or rigid, mechanical stops that sell into panic) will likely forfeit value and may be unnecessary if hedges are layered thoughtfully and re-entry rules are clear.\n- The balanced approach I\u2019ve given attempts to capture the best of both: meaningful de-risking now, layered and cost-aware protection, limited and conditional premium-financing if desired, ATR-aware risk controls, and staged re-entry tied to both momentum and fundamentals.\n\nIf you\u2019d like, I can convert this into exact order-level instructions (how many shares to sell, how many contracts for the 170/150 put spread and the long-dated put, suggested call strikes for a collar, and precise ATR stop bands) given your portfolio size and the exact number of shares you hold. Which would you prefer?", + "history": "\nAggressive Analyst: You didn\u2019t include the conservative or neutral analysts\u2019 last arguments, so I won\u2019t invent them. I\u2019ll focus on why the trader\u2019s SELL / hedge-now approach, while prudent, is overly conservative and likely to miss asymmetric upside. I\u2019ll pick apart the assumptions behind a forced reduce-and-wait posture and lay out aggressive, high-upside alternatives\u2014each tied to the data in your reports.\n\nQuick thesis: NVDA\u2019s near-term tape is noisy and risky, yes\u2014but fundamentals and catalyst optionality create extreme upside asymmetry that a strict \u201ctrim + hedge and only re-enter after technical repair\u201d regime can permanently miss. If you have a high risk tolerance or a long horizon, accept intentional, sized risk to capture multi-quarter re-rating driven by data-center pull-through, product adoption (Blackwell/Rubin), TSMC allocation wins, or hyperscaler guidance. Use leveraged, defined-risk or premium-funded option structures and selective selling to increase upside exposure while keeping behavioral controls.\n\nWhy the conservative SELL-first logic may be wrong for aggressive players\n- The fundamentals are not \u201cfragile.\u201d Latest quarter: revenue $68B, gross margin ~75%, operating margin ~65%, net income and free cash flow gigantic. Net-cash cushion (~$50B+) and continued buybacks mean the company can execute through cycles. Those numbers justify materially higher valuation if growth holds.\n- Tactical technicals can flip fast on a single positive catalyst. The market is pricing AI optionality; one hyperscaler guide-up, a TSMC allocation update, or proof of end-customer sell-through could trigger a fast 20\u201340% re-rate. Waiting for 3 closes above 185\u2013186 risks catching only the late innings of those moves.\n- Hedging costs and hedges that cap upside reduce asymmetry. Buying protective put spreads or collars now preserves downside but also caps uncapped upside that could occur if guidance or orders materially surprise to the upside. For aggressive players, there are better ways to preserve optionality.\n\nData-driven counters to the SELL plan\u2019s main assumptions\n- \u201cPrice below 200 SMA = structural breakdown\u201d \u2014 True short-term, but fundamentals show revenue and margin trajectories that can force technical repair quickly. With forward EPS consensus implying a step-up to EPS ~11.13, multiples can compress or expand rapidly; technicals alone don\u2019t refute the secular thesis.\n- \u201cVolatility makes timing risk dominant\u201d \u2014 Elevated ATR and a VIX near 24 increase cost of plain protective puts, but they also inflate call values and create rich premium to harvest via selling strategies (puts/calls) or to use for buying longer-dated, cheaper optionality (LEAPS).\n- \u201cInventory/receivables risk\u201d \u2014 inventory and AR are elevated and deserve monitoring, but NVDA has the balance-sheet firepower and strong FCF to manage a temporary digestion. That reduces existential downside relative to many high-growth peers.\n\nConcrete aggressive alternatives (ranked by aggressiveness and asymmetric payoff)\n\n1) Aggressive long-term asymmetric play (highest upside, managed cost)\n- Action: Buy 12\u201324 month LEAPS calls sized to increase effective exposure while only using a fraction of notional capital.\n- Rationale: Captures multi-quarter revenue and margin realization (Blackwell/Rubin adoption, hyperscaler pull-through) without being stopped out by short-term technical dust-ups. With fundamentals implying a much higher forward EPS, long-dated calls offer leverage to that re-rating.\n- Risk control: Keep position size meaningful but not dominant\u2014target total NVDA exposure (stock + options delta) at the high end of your allowed allocation (e.g., 6\u201310% for aggressive accounts). Ladder entry across expiries to reduce timing risk.\n\n2) Premium-funded accumulation (buy the dip with downside acceptance)\n- Action: Sell cash-secured OTM puts at strikes where you\u2019d be happy to own more NVDA (e.g., strikes below current price that reflect ~1\u20132\u00d7ATR moves), collect premium and either (a) get put-to and add materially at lower cost, or (b) use premium to buy calls.\n- Rationale: You\u2019re effectively getting paid to set a lower-cost basis. If you\u2019re confident in NVDA\u2019s multi-year growth, owning more on weakness is the highest-expected-value move.\n- Risk: If a severe macro / demand shock occurs you can be assigned at a level you already accepted; manage size and capital to remain cash-secured.\n\n3) High-conviction event-driven long (targeted leverage around catalysts)\n- Action: Ahead of hyperscaler/TSMC/earnings catalysts, buy concentrated 3\u20136 month call spreads (e.g., a nearer strike buy / higher strike sell) sized to deliver 3\u20135x directional upside on a positive surprise.\n- Rationale: Captures binary re-rates without paying full IV for naked calls (sell higher strike to offset cost). If the print is strong, upside is large; if negative, loss is limited to premium.\n- Risk: Short-dated IV pops can widen spreads, but defined loss limits behavioral pain.\n\n4) Risk-reversal / skew play (aggressive directional with financing)\n- Action: Sell an OTM put and use premium to buy OTM calls (or a call spread). You accept conditional downside in exchange for asymmetric upside exposure.\n- Rationale: With elevated implied vol and demand for puts, you can finance significant upside exposure. This is higher risk but optimizes dollar-for-dollar upside if you\u2019re confident in fundamentals.\n- Risk management: Size strongly and choose put strikes you can live with being assigned on; avoid if portfolio can\u2019t absorb assignment.\n\n5) Selective trimming + levered optional replacement (compromise vs SELL)\n- If you currently hold a top-3 position and the trader recommends selling 50%: instead sell 20\u201330% to lock partial gains, then take proceeds to buy LEAPS or buy call spreads that replicate the remaining position\u2019s upside at lower capital.\n- Why this is better: You monetize portion of exposure to reduce absolute dollar risk while maintaining upside optionality. It\u2019s not capitulation; it\u2019s converting outright equity into leveraged upside.\n\nDirect rebuttals to the trader\u2019s specific tactical rules\n- Trader rule: \u201cSell 50% if top-3 or horizon <12 months.\u201d Counter: If horizon >12 months, don\u2019t mechanically sell 50%. Instead, scale to 20\u201330% and convert some capital to LEAPS. The balance between pure stock and options controls downside while preserving upside optionality. This boots the upside asymmetry rather than neutering it via collars.\n- Trader rule: \u201cBuy a protective put spread (e.g., 170/150) for 3 months.\u201d Counter: Buying that spread materially reduces upside for modest protection. Instead, consider:\n - Buying longer-dated puts as catastrophic insurance (rare but cheaper per unit of time), or\n - Selling premium (OTM puts or calls) to fund upside call purchases, or\n - Using a cheap broken-wing call spread to skew payoff to the upside while limiting one-sided bad draws.\n- Trader rule: \u201cNon-negotiable stop at 168 / exit at 160.\u201d Counter: Hard stops are predictable and can trigger selling into panics. For an aggressive account, prefer a dynamic rebalancing policy tied to fundamentals (e.g., re-evaluate only if sequential data-center revenue decelerates materially or guidance is cut) rather than mechanical intraday closes; if you must use mechanicals, set them wider (respect ATR) and size accordingly.\n\nWhere the conservative caution is likely overly pessimistic\n- They overweight tape structure and underweight balance sheet and revenue runway. NVDA is running enormous margins, cash flow, and strategic lock-in with hyperscalers\u2014those characteristics create an asymmetric payoff where a success blows the top off short-term technicals.\n- They assume options cost to hedge is acceptable; but current IV is an opportunity for aggressive players to sell premium or buy time-levered options instead of bluntly paying full insurance.\n- They underprice catalyst velocity. Historically, NVDA\u2019s re-ratings can be rapid and non-linear\u2014missing early re-entries because you waited for multiple technical confirmations is a real opportunity cost.\n\nPractical execution suggestions (aggressive, but controlled)\n- If you hold NVDA and are willing to be aggressive:\n - Sell 20\u201330% of shares now to lock gains.\n - Use proceeds to buy 12\u201318 month LEAPS calls equal to ~50% of sold exposure (delta-adjusted) \u2014 keeps upside with less capital.\n - Simultaneously sell 1\u20132 OTM cash-secured puts at strikes you\u2019d accept assignment at to fund more calls or reduce net cost.\n- If you do not hold NVDA and are aggressive:\n - Avoid buying unhedged near-term stock. Instead buy 9\u201318 month call spreads sized to the account (e.g., buy 200/300 call spread or similar depending on strike selection and risk tolerance).\n - If you want to be very aggressive, sell a put at a lower strike to fund the call spread (risk-managed via cash-secured leg).\n- Size rules: Keep net delta exposure within a high-risk tolerance band\u2014target aggregate NVDA exposure (stock + option delta) to no more than 6\u201310% of portfolio for aggressive accounts; lower for swing traders.\n\nFinal push: Why aggressive risk wins here\n- The company\u2019s fundamentals produce optionality: massive margins, extraordinary FCF, huge buybacks, and dominant platform position. Those qualities are classic \u201cconvex\u201d payoffs where riding volatility with leverage and time can dramatically outperform cautious trimming.\n- Technical breakdowns can be whipsawed by one or two positive data points; if you exit too early, you hand the accelerated re-rate to fast money.\n- The market\u2019s elevated IV is an opportunity, not only a cost: efficient option structures can buy leverage or generate yield to fund upside exposure.\n\nIf you want, I\u2019ll convert any of the four aggressive trade concepts above into precise, executable sets for your account size (exact strike bands, suggested expiries, delta targets, contract counts, and cash-secured leg sizing). Tell me whether you\u2019re: (A) high-conviction long-term holder, (B) event-driven trader, or (C) willing to use premium-funded structures\u2014plus your portfolio size and max % allocation\u2014and I\u2019ll produce a step-by-step execution plan.\nConservative Analyst: Short version: I disagree with the Aggressive Analyst\u2019s framework for this account. The data show a technically confirmed distribution, elevated realized/implied volatility, meaningful inventory/AR buildup, and large valuation sensitivity \u2014 a combination that favors protecting capital and limiting portfolio concentration now, not increasing convex long exposure or writing premium that can leave the firm exposed to left\u2011tail outcomes. Below I rebut the aggressive points directly, highlight where they underweight real risks, and offer safer, practical alternatives consistent with the trader\u2019s SELL recommendation.\n\n1) \u201cFundamentals make technicals irrelevant\u201d \u2014 not how market risk works\n- Fact-check: Fundamentals are very strong (latest quarter revenue $68.1B, gross margin ~75%, huge FCF and net-cash ~+$50B). But the market is already pricing that growth: market cap \u2248 $4.2T, TTM P/E ~35, forward EPS implies aggressive expectations. That makes the security extremely sensitive to any demand or guidance slip.\n- Why this matters: High valuation + high beta (\u22482.38) + VIX \u224824 = severe downside convexity. A small miss or macro shock can produce outsized drawdowns even if the long\u2011term thesis remains intact. Protecting capital matters more for the firm than chasing optional upside.\n\n2) \u201cCatalysts can re-rate quickly, so don\u2019t trim\u201d \u2014 that\u2019s timing risk, not an edge for a risk manager\n- Reality: Yes, catalysts can cause big upmoves. They also cause big downmoves. Technicals are currently bearish across timeframes: price 172.93 < 10 EMA 180.14 < 50 SMA 184.60 and below the 200 SMA 178.42; MACD negative (-1.99), RSI ~38, VWMA 181.24 > price (distribution), ATR \u2248 5.77. Volume confirms distribution.\n- Implication: Waiting for the \u201cone positive catalyst\u201d is asymmetric: you may get a fast upmove, but you\u2019re much more likely to get a fast downmove that damages capital before fundamentals can vindicate you. For a firm whose objective is capital preservation and steady growth, avoiding that exposure is the prudent choice.\n\n3) \u201cSell puts / risk reversals / LEAPS to increase convexity\u201d \u2014 these add risk the firm may not be able to absorb\n- Selling cash\u2011secured puts: in normal times this is fine. Today, assignment risk equals concentrated long exposure at a moment of technical weakness, inventory build ($21.4B) and receivables ($38.5B) that could presage a digest cycle. Getting put\u2011to at a lower strike can double down into a concentrated bet the firm may not want.\n- Risk reversals (sell put / buy call): they finance upsides by taking left\u2011tail risk. That is exactly the exposure you should be minimizing when macro (oil >$100), supply (TSMC concentration), and geopolitical tail risks exist.\n- LEAPS calls: they can lose 100% of premium in a sustained market drawdown or if the re-rating is delayed. They are leverage, not insurance. For a firm prioritizing steady growth and volatility control, replacing equity with long premium is not a substitute for disciplined position-size reduction + hedging.\n\n4) \u201cHedges cap upside \u2014 avoid them\u201d \u2014 that\u2019s precisely why you need them\n- Hedges cost money, but the alternative is open\u2011ended downside that can take years to recover. With ATR ~5.8 and potential two\u2011ATR moves of ~11\u201312 points, unhedged large positions expose the portfolio to meaningful single\u2011session losses.\n- Practical point: put spreads or collars (structured correctly) materially limit downside while permitting participation on a measured basis. That\u2019s consistent with protecting capital and maintaining optional upside in a controlled way.\n\n5) Inventory / receivables and concentration risk are non-trivial \u2014 the Aggressive Analyst downplays them\n- Inventory at $21.4B and receivables at $38.5B increased materially. That can reflect either a true ramp or channel stuffing/stock build ahead of slowing sell\u2011through. With hyperscaler capex the dominant demand driver, any sequential softness or channel digestion would rapidly reprice the stock.\n- TSMC concentration and geopolitical risk remain live tail risks for supply. These aren\u2019t abstract: they are asymmetric downside drivers that can swamp a technical repair.\n\n6) Technical stop rules are not \u201cpredictable weakness\u201d \u2014 they are loss\u2011limiting rules\n- The trader\u2019s hard triggers (close below ~168 on rising volume \u2192 sell another 15\u201325%; close and hold below ~160 \u2192 exit remaining) are practical guardrails that prevent a small mistake from becoming a portfolio\u2011level drawdown. ATR\u2011aware stops are smarter than looser, ideologically driven \u201cwe\u2019ll wait for fundamentals\u201d rules that often become emotional hopes in a crash.\n\nPractical conservative counter\u2011proposals (what to do instead of the aggressive playbook)\n- If NVDA is a top-3 holding or horizon <12 months: follow the trader\u2019s guidance \u2014 sell 50% now. Don\u2019t trade away the capital by holding through a drawdown.\n- Hedge the remainder: buy a 3\u2011month put spread (example using liquid strikes around 170/150) sized to remaining shares. It caps near-term downside while retaining upside. If you must lower cost, use a collar only if the short call strike is a level you are comfortable being forced to sell into.\n- Avoid putting on new uncovered short puts or selling naked premium in bulk. If you use put writing at all, limit size to a tiny % of capital and ensure cash\u2011secured and pre\u2011approved assignment levels that respect the portfolio cap (3\u20136%).\n- Do not replace sold shares with LEAPS unless you are explicitly designated a high\u2011risk mandate. If the firm is long\u2011term but conservative, better alternatives: scale in via defined\u2011risk debit spreads (buy calls/sell higher calls) with small notional; or buy longer\u2011dated protective puts as catastrophic insurance.\n- Enforce portfolio caps: limit NVDA exposure to 3\u20136% of total portfolio (as the trader suggests). Aggressive proposals that target 6\u201310% or allow assignment could produce concentration risk inconsistent with the mandate.\n- Execution discipline: scale out in 1\u20133 tranches using limit orders; if market impact is a concern, use VWAP/adaptive algos; size hedges to round lots and account for assignment risk.\n\nPoint\u2011by\u2011point rebuttal of the Aggressive\u2019s proposed trades\n- LEAPS purchase to increase exposure: LEAPS are a long gamma play that can be wiped out by a multi\u2011month bear cycle. They do not protect against valuation compression and may amplify realized volatility for the account because they convert capital into a high\u2011volatility instrument. Conservative alternative: reduce equity exposure first, then buy modest, defined\u2011risk call spreads (shorter-dated) only after the tape shows stabilizing breadth and improving momentum.\n- Selling cash\u2011secured puts to \u201cget paid to set a basis\u201d: in a high\u2011IV, distribution phase, you may get assigned into a materially larger, concentrated position at a poor time. If you insist on selling puts, cap total potential assignment to a small, funded percentage of the portfolio and only at strikes you\u2019d actually be content to own as part of your 3\u20136% cap.\n- Risk reversals / selling premium to finance calls: this transfers downside to the firm in exchange for upside optionality. If the macro or geopolitical tail hits, losses from assignment or deep OTM put exposure can be large and permanent. Do not use financed structures that materially increase left\u2011tail exposure for the firm.\n- Narrow trimming (sell 20\u201330% and buy LEAPS): partial monetization is sensible, but the proposed sizes understate near\u2011term risk. If you reduce only 20\u201330% when NVDA is a top\u20113 holding and valued aggressively, you still have unacceptable concentration. Conservative compromise: sell 50% if top\u20113; if you must keep upside optionality buy limited call spreads sized small relative to capital freed by the sale.\n\nWhy the trader\u2019s SELL + hedge + re\u2011entry rules are superior for risk control\n- They combine immediate de\u2011risking (reduce exposure now), defined protection for the remainder (put spread or collar), and objective re\u2011entry triggers (sustained close >185\u2013186 + momentum/fundamental confirmation). That structure prevents emotional doubling down, enforces drawdown limits, and keeps upside optionality while preserving capital.\n- They use technical, volatility and fundamental signals together (not only one) \u2014 this is prudent when valuation is rich and macro/supply tail risks are present.\n\nConclusion \u2014 firm recommendation for a conservative mandate\n- Follow the trader\u2019s SELL decision as written: reduce now (50% if top\u20113 or horizon <12 months; 30% if modest and you already hedge), hedge the remainder with defined\u2011risk structures (prefer put spreads or protective puts if funds allow), adhere to the hard stop triggers (168/160 on rising volume), cap NVDA to 3\u20136% of portfolio, and only re\u2011enter on multi\u2011factor confirmation (technical and fundamental).\n- Do not adopt the aggressive tactics of selling large amounts of premium, funding asymmetric upside with downside exposure, or replacing sold stock with LEAPS at scale. Those strategies increase tail risk and can produce permanent capital loss \u2014 the exact outcome a conservative mandate must avoid.\n\nIf you want, I will:\n- convert the SELL + hedge rule set into explicit order-level instructions for a given portfolio size (how many shares to sell, how many put\u2011spread contracts to buy, strikes/expiries consistent with liquidity and ATR), or\n- produce a short scenario analysis (P/L profiles) comparing the conservative hedge approach vs. the aggressive LEAPS/risk\u2011reversal outcomes at different NVDA price paths.\n\nWhich follow-up would you prefer?\nNeutral Analyst: Good\u2014this is a useful debate. I\u2019ll pick apart the Aggressive and Conservative positions, show where each over- and under-weights the facts in the reports, and then propose a practical, moderate execution path that preserves upside optionality without leaving the portfolio exposed to the clear near-term risks.\n\nTop-line calibration (facts we both must live with)\n- Technicals are weak: last close ~172.93; price < 10 EMA (180), < 50 SMA (184.6) and below the 200 SMA (~178.4). MACD is negative and accelerating; RSI ~38; VWMA ~181 is above price \u2192 distribution. ATR \u2248 5.8 (expect large daily swings).\n- Fundamentals are unusually strong: huge recent quarter ($68B revenue), gross margin ~75%, massive operating/cash flow and a net-cash cushion (~$50B+). Forward EPS consensus implies a large earnings step-up, which is why valuation is very rich (market cap ~ $4.2T).\n- Key risks are real: inventory ($21.4B) and receivables ($38.5B) have grown materially; hyperscaler capex sensitivity, TSMC concentration and macro shocks (VIX ~24, oil >$100) are credible asymmetric downside drivers.\n\nWhere the Aggressive Analyst is too optimistic\n- Overweights fundamentals to the point of downplaying valuation convexity. Yes, NVDA has enormous FCF and platform advantages, but the market has priced much of that in \u2014 a small demand hiccup or guidance disappointment can produce a large multiple compression because beta is high and sentiment is fragile.\n- Underestimates inventory/AR risk. A large inventory build and rising ARs can be either benign (planned ramp) or a leading indicator of channel digestion. Aggressive LEAPS and risk-reversals treat that as negligible; they aren\u2019t.\n- Minimizes assignment/left-tail risk of financed structures. Selling puts or risk-reversals to finance upside materially increases the portfolio\u2019s downside exposure if macro/geopolitical gets worse \u2014 exactly the scenarios the Conservative Analyst fears.\n- Paints IV only as an \u201copportunity.\u201d Elevated IV makes calls more expensive too; LEAPS are levered and can still expire worthless if the re-rate is delayed.\n\nWhere the Conservative Analyst is too cautious\n- May be giving up significant expected upside and real optionality. NVDA\u2019s fundamental momentum and the possibility of quick positive catalysts (hyperscaler guidance, TSMC allocation news, product/Blackwell adoption) argue you shouldn\u2019t fully sterilize upside for a small reduction in short-term drawdown.\n- Hard mechanical stops can be self\u2011fulfilling and cause selling into panic. A purely mechanical close-below rule without ATR\u2011aware tolerance and context (volume, macro prints) can force bad execution and crystallize losses at the worst times.\n- Treats all premium-writing as reckless \u2014 when done small, cash-secured, and sized to allocation limits, selling puts can be a constructive way to lower basis if you genuinely want more exposure at lower levels.\n- May overpay for pure insurance if it forces large collars that eliminate meaningful upside; there are hybrid hedging tactics that cost less yet materially reduce risk.\n\nA neutral, practical synthesis \u2014 balance the upside optionality and the downside protection\nPrinciples guiding the compromise\n- Reduce absolute dollar concentration now (de-risk) but preserve controlled upside optionality.\n- Hedge the remaining exposure in layered, time-staggered fashion to balance cost vs protection.\n- Use objective, ATR-aware mechanical rules combined with fundamental checkpoints (not pure price-only stops).\n- Limit any premium-financing or assignment risk to a clearly small, pre-defined share of the portfolio.\n\nConcrete moderate strategy (execution-ready, adaptable to portfolio size)\n1) Reduce exposure now (immediate / next session)\n- If NVDA is a top-3 holding or your horizon <12 months: sell 40% of shares now (compromise between 50% conservative and 20\u201330% aggressive). Rationale: meaningful de-risk while retaining upside.\n- If NVDA is a modest holding (<~3%): sell 25\u201330% now, or hold but immediately hedge (below).\n- Use limit orders, scale out in 1\u20133 tranches; if markets are chaotic use VWAP/adaptive algos.\n\n2) Hedge the remainder (layered, sized to remaining shares)\n- Short-term tactical protection (3 months): buy a put spread sized to cover the post-trim holdings (e.g., long 170 / short 150 as a reference structure). This materially caps near-term downside but reduces hedge premium vs naked protective puts.\n- Stagger longer-dated catastrophic insurance (9\u201312 months): buy a longer-dated protective put (deeper OTM) or a cheap out-of-the-money LEAP put to protect the tail. That keeps a safety net if the right-tail re-rate takes longer than expected.\n- Cost-reducing option: if you accept defined trimming levels, sell a small number of OTM covered calls or implement a collar on a fraction of the remaining shares at strikes you\u2019d be content to sell into (e.g., near the 190\u2013200 zone if that aligns with your willingness to trim). Keep covered-call sizing modest so you don\u2019t fully cap upside.\n- Operational notes: size options in 100-share lots, prefer liquid strikes/expiries, account for assignment risk on sold calls/puts.\n\n3) Limited, conditional premium-funded tactics (only if you actively manage assignment risk)\n- If you are comfortable with being assigned and only up to a small allocation: sell a modest amount of cash\u2011secured OTM puts equal to no more than 10\u201315% of the original position (not the remaining position). Choose strikes roughly 1\u20132\u00d7ATR below current (~ ~162\u2013162? adjust to live quote) or at price levels where you\u2019d be happy to increase exposure. Use this to collect premium to buy LEAPS or reduce net hedge cost.\n- Don\u2019t size put-selling to a level that, if assigned, would push the stock to a top-3 position or above your portfolio cap.\n\n4) Hard triggers and dynamic risk control (blend of price, ATR, volume, and fundamentals)\n- Keep the trader\u2019s structured triggers but make them ATR-aware and contextual:\n - If NVDA closes below ~168 on rising volume (consistent with trader): increase hedge notional to cover an additional 15\u201325% of the original position OR sell an additional 10\u201315% (if still above your minimum holding), depending on whether you want to turn protection into realized reduction.\n - If NVDA closes and holds below ~160: this is a clear risk state \u2014 either exit remaining shares or ensure hedge makes net delta ~0 (i.e., be fully protected). Implement within one trading session.\n - Stop spacings and execution: use 1.5\u20132\u00d7ATR (~9\u201312 points) as a guide for avoiding whipsaws; if price action is violent, prefer hedging increases over immediate forced market sells.\n- Add a fundamental stop-latch: if hyperscaler guidance sequentially decelerates (data center revenue guidance miss or cloud customers explicitly slow orders), treat that as equivalent to the 160 trigger and de-risk aggressively.\n\n5) Re-entry rules (balanced, staged)\n- Require two-factor confirmation for larger re-entries (reduces whipsaw risk): sustained technical repair (daily closes above ~185\u2013186 with MACD turning up and RSI >50) AND a positive fundamental signal (stronger-than-expected data-center revenue/guidance or hyperscaler commentary confirming sell-through).\n- Allow small, hedged tactical re-entries on technical-only signals: if price clears 185\u2013186 but fundamental signals are neutral, re-enter in small tranches (e.g., add 10\u201320% of target allocation) and keep protection (collars/put spreads) until fundamentals catch up.\n- Cap rebuilt NVDA allocation to 3\u20135% for most diversified portfolios; allow 5\u20136% only for higher-conviction sleeves with explicit risk budgets.\n\nWhy this middle path works\n- It captures upside optionality without full exposure: trimming 40% frees capital and cuts concentration, while LEAPS/call components preserve upside optionality on the remainder.\n- It materially limits left-tail risk through layered hedges (short-term put spreads + long-term tail put), yet keeps hedge cost reasonable via spreads/collars and the small, conditional premium-funded tactics.\n- It avoids reflexive selling into panic by using ATR-aware spacing and a combination of technical + fundamental triggers.\n- It respects both analysts\u2019 valid points: the Conservative Analyst\u2019s emphasis on inventory/valuation/tail risk and the Aggressive Analyst\u2019s point that fundamentals and catalysts can re-rate NVDA quickly.\n\nMonitoring checklist (what to watch daily/weekly)\n- NVDA: data-center revenue cadence and guidance; inventory and receivables trends (days sales outstanding).\n- Hyperscalers (AMZN/MSFT/GOOGL): cloud capex/guidance commentary.\n- TSMC updates: capacity, lead times, allocation notes.\n- Options market: IV percentile, skew, unusual flow (large put buys or big call blocks).\n- Macro: VIX, oil moves above $100, yields \u2014 these change risk premia quickly.\n- Volume context on price moves: confirm moves are supported by heavy or light volume.\n\nExample scenarios (illustrative)\n- If NVDA gaps down 15% on macro shock to ~147: with the proposed plan you\u2019ve sold a portion (40%), your immediate put-spread hedge cushions the remainder, and the long-dated tail put limits catastrophic loss. You also have dry powder and optionality to buy in a measured way if fundamentals remain intact.\n- If NVDA gaps up 20% on hyperscaler upside to ~207: you retain upside via remaining shares and any purchased LEAPS/call spreads; modest covered-call/collar usage has limited only a fraction of upside but overall you\u2019ve retained a sizable participation (and you sold down to reduce concentration risk).\n\nPractical next steps I\u2019d recommend now\n- Decide your target NVDA allocation cap (I recommend 3\u20135% for most diversified mandates; pick upper bound if you have higher conviction).\n- Execute the trim: sell 40% (if top-3 / short horizon) or 25\u201330% (if modest). Scale over 1\u20133 tranches.\n- Immediately buy a 3-month put spread sized to the remaining shares (e.g., long 170 / short 150 band as a hedge example), and simultaneously buy a single longer-dated OTM put (9\u201312 months) for tail protection.\n- If you want to lower hedge cost: implement a partial collar (sell a small number of OTM calls) only on shares you are comfortable selling at that strike.\n- Set monitoring alerts for the triggers above (close <168 with rising vol; close <160) and the fundamental indicators (hyperscaler commentary, TSMC).\n\nFinal debate-style takeaway\n- To the Aggressive Analyst: you\u2019re right that the long-term optionality is huge and that waiting for perfect technical repair can cause missed upside; but you downplay real left-tail risks (inventory, macro, TSMC/geopolitics) and the cost of being assigned into concentration at the wrong time. Include limiters and small-size premium-funded tactics only as conditional tools.\n- To the Conservative Analyst: you\u2019re right that capital preservation and defined hedges are essential given valuation and technical breakdown; but being overly sterilized (large collars that eliminate meaningful upside or rigid, mechanical stops that sell into panic) will likely forfeit value and may be unnecessary if hedges are layered thoughtfully and re-entry rules are clear.\n- The balanced approach I\u2019ve given attempts to capture the best of both: meaningful de-risking now, layered and cost-aware protection, limited and conditional premium-financing if desired, ATR-aware risk controls, and staged re-entry tied to both momentum and fundamentals.\n\nIf you\u2019d like, I can convert this into exact order-level instructions (how many shares to sell, how many contracts for the 170/150 put spread and the long-dated put, suggested call strikes for a collar, and precise ATR stop bands) given your portfolio size and the exact number of shares you hold. Which would you prefer?", + "judge_decision": "## Recommendation: **Sell** (reduce exposure now; keep a smaller, defined-risk \u201ctoe-hold\u201d only if you must)\n\n### 1) Key arguments (what actually matters)\n\n**Aggressive (best points)**\n- Fundamentals/FCF/moat are exceptional and can overwhelm technicals fast: *\u201cfundamentals and catalyst optionality create extreme upside asymmetry\u2026 a fast 20\u201340% re-rate.\u201d*\n- Warns that rigid \u201cwait for technical repair\u201d can miss the move: *\u201cWaiting for 3 closes above 185\u2013186 risks catching only the late innings.\u201d*\n- Suggests options to preserve upside while limiting capital at risk (LEAPS/call spreads).\n\n**Conservative (best points)**\n- Near-term risk is quantifiably bearish: *\u201ctechnically confirmed distribution\u2026 price < 10 EMA < 50 SMA and below the 200 SMA; MACD negative\u2026 RSI ~38\u2026 VWMA above price\u2026 ATR elevated.\u201d*\n- Valuation sensitivity + beta + macro volatility implies sharp drawdowns are plausible: *\u201cHigh valuation + high beta (\u22482.38) + VIX \u224824 = severe downside convexity.\u201d*\n- Rejects left-tail exposure from financed structures: *\u201crisk reversals\u2026 take left-tail risk\u2026 exactly the exposure you should be minimizing.\u201d*\n- Endorses clear de-risk + hedge + triggers: *\u201csell 50%\u2026 hedge the remainder\u2026 adhere to hard stop triggers (168/160).\u201d*\n\n**Neutral (best points)**\n- Confirms both realities: weak tape + very strong fundamentals + real tail risks.\n- Proposes a compromise trim (40%) plus layered hedging and ATR-aware triggers (more execution-savvy), but still admits the setup is risk-first: *\u201cTechnicals are weak\u2026 key risks are real\u2026 credible asymmetric downside drivers.\u201d*\n\n### 2) Rationale (why the decision is **Sell**, using direct debate evidence)\n\nThis is a timing/risk decision, not a \u201cis NVDA a great company\u201d decision. The most *objective* evidence in the debate is the technical/volatility regime plus valuation convexity. The Conservative and Neutral analysts both anchor on the same hard facts:\n\n- *\u201cTechnically confirmed distribution\u201d* with price below key moving averages, negative MACD, and VWMA above price (distribution).\n- Elevated volatility (ATR ~5.8) and macro risk (VIX ~24), which increases the probability of air-pockets.\n- Specific balance-sheet \u201cyellow flags\u201d (inventory/AR build) that can become a catalyst for repricing if guidance/sell-through disappoints.\n\nAggressive is directionally right about long-term optionality, but the proposed ways to express it (LEAPS, risk-reversals, put-selling) **increase** the exact risk the other two warn about: getting paid small premium while being exposed to large left-tail outcomes, or paying premium that can still go to zero if repricing persists. Even Neutral\u2014who tries to preserve upside\u2014still starts with **reducing exposure now** because the near-term setup is unfavorable.\n\nSo the most robust, least regret-prone action is: **Sell to reduce exposure first**, then re-enter only when the market stops actively repricing the risk premium (technical repair and/or fundamental confirmation).\n\n### 3) Refine the trader\u2019s original plan (keep what works, simplify what matters)\n\nYour original plan was already coherent. I\u2019d tighten it into a single decisive \u201crisk-reduction first\u201d playbook, borrowing Neutral\u2019s execution realism but keeping Conservative\u2019s mandate discipline.\n\n**A. Immediate action (today/next session): SELL to reduce**\n- **Base case:** sell **40\u201350%** of shares now.\n - Use **50%** if NVDA is a top-3 holding or your horizon is <12 months (aligns with Conservative).\n - Use **40%** if you want a modest \u201ctoe-hold\u201d for upside optionality (Neutral compromise).\n\n**B. Protect what remains (defined risk; don\u2019t over-engineer)**\n- Hedge remaining shares with a **~3-month put spread** (example from debate: **170/150** or nearest liquid strikes).\n- If you refuse to hedge, then you\u2019re implicitly choosing to accept the \u201ctechnical breakdown + high beta\u201d drawdown risk the Conservative flagged\u2014don\u2019t pretend it\u2019s controlled.\n\n**C. Non-negotiable downside triggers (keep them)**\n- The trader\u2019s framework was strong because it prevents hope-based holding:\n - **Close < ~168 on rising volume:** cut another **15\u201325% of original** exposure *or* increase hedge notional materially.\n - **Close and hold < ~160:** **exit remaining** (or fully delta-hedge so net exposure is near zero).\n\n**D. Re-entry (don\u2019t marry the position; earn it back)**\nRe-add only when at least one of these happens:\n- **Technical repair:** sustained reclaim of **~185\u2013186** with momentum improving (MACD up, RSI >50).\n- **Fundamental confirmation:** hyperscaler commentary/guidance confirms continued AI spend and inventory/AR do not look like digestion.\n\n### 4) Learn from past mistakes (applied here to avoid a bad call)\n\nThe key \u201cpast mistake\u201d embedded in the debate is explicitly called out in your own text and echoed by Conservative/Neutral: **staying long a \u201cgreat story\u201d through a clear tape breakdown and volatility expansion**, then suffering a large, avoidable drawdown. Your original note nailed it: *\u201cThat\u2019s how you sit through a 25\u201340% drawdown you didn\u2019t need to take.\u201d*\n\nTo not repeat that mistake:\n- Don\u2019t let \u201cexceptional fundamentals\u201d override **current** market evidence of repricing.\n- Don\u2019t use \u201cHold\u201d as a comfort blanket when the tape is signaling distribution and the downside is unbounded.\n- Don\u2019t finance upside with left-tail risk (risk reversals / heavy put-selling) in a regime explicitly defined by elevated volatility and tail risks.\n\n## Final, actionable decision\n**SELL** (reduce exposure now). \nThen **hedge the remainder** with a 3\u2011month put spread and follow the **168/160** risk triggers. Re-enter only on defined technical repair and/or fundamental confirmation." + }, + "investment_plan": "Key points from both sides, stripped to what really matters\n\nBull\u2019s strongest points\n- Fundamentals are exceptional: explosive data-center growth, very high margins, and huge free cash flow. The argument is that this isn\u2019t a fad; it\u2019s a multi-year AI buildout with NVIDIA as the prime beneficiary.\n- Moat is real: CUDA/software ecosystem + full-stack platform and an aggressive roadmap (Blackwell/Rubin) support pricing power and customer stickiness.\n- Balance sheet/cash flow give flexibility: buybacks, investment, and the ability to ride out volatility.\n- Even the bull concedes the tape is damaged, but frames that as an opportunity if you scale in and hedge rather than chase.\n\nBear\u2019s strongest points\n- The stock is in a technical breakdown right now: below 10/50/200-day levels, MACD negative and worsening, RSI ~38 (not washed out), VWMA above price (distribution), ATR elevated. That\u2019s a concrete \u201crisk is to the downside\u201d setup for the next weeks/months.\n- Valuation convexity: even if \u201cforward P/E looks low,\u201d it\u2019s low only because the market is assuming a big EPS ramp. If that ramp wobbles, the stock can re-rate hard. With high beta, drawdowns can be large and fast.\n- Concentration/tail risks are live: hyperscaler capex concentration, TSMC/geopolitics/export controls are asymmetric risks that can\u2019t be diversified away inside the single name.\n- Working capital (inventory/receivables) could be benign, but it\u2019s a legitimate early warning sign; you don\u2019t get to assume it\u2019s fine without confirmation.\n- Practical trade guidance is clearer and more actionable: trim/hedge now; don\u2019t add unhedged until technical repair.\n\nMy decision: Sell (risk-reduce now; re-enter only on defined confirmation)\n\nRationale (why I\u2019m siding with the bear)\nYou\u2019re not deciding whether NVIDIA is a great company. You\u2019re deciding what to do with the stock at this moment, with this setup. The bear wins on timing and risk management: the debate\u2019s hardest evidence is the multi-timeframe technical breakdown plus elevated volatility, combined with valuation sensitivity. In similar high-multiple/great-story names, a common mistake is \u201cstaying long because fundamentals are awesome\u201d while the market is actively repricing the risk premium. That\u2019s how you sit through a 25\u201340% drawdown you didn\u2019t need to take.\n\nThe bull\u2019s plan (scale in + hedge) is reasonable for someone underinvested who must own it structurally. But as a portfolio manager making a definitive call, the most robust action based on the evidence presented is to reduce exposure first, then demand confirmation before re-adding. The bear\u2019s triggers (185\u2013186 reclaim for repair; 168/160 downside levels) provide a cleaner framework than \u201cbuy the dip because the thesis is intact.\u201d\n\nStrategic actions (a detailed, concrete investment plan)\n\n1) Immediately reduce directional risk\n- If currently long shares: sell 30\u201350% of the position now.\n - Use 50% if NVDA is a top-3 position, if your horizon is <12 months, or if you\u2019re not running portfolio-level hedges.\n - Use 30% if it\u2019s already a modest position (say <3% of portfolio) and you\u2019re comfortable actively hedging.\n\n2) Hedge the remaining position (don\u2019t leave it naked)\n- Implement a 3-month put spread hedge on the remaining shares, similar to what the bear suggested:\n - Example structure: buy the 170 put / sell the 150 put (or nearest strikes with similar delta), sized to cover most of the remaining share exposure.\n - Goal: cap the damage if the breakdown extends, while keeping some upside participation if there\u2019s a snap-back.\n- If you prefer collars to reduce hedge cost:\n - Buy a protective put (e.g., ~170) and sell an out-of-the-money call (choose a strike near a level you\u2019d be happy trimming anyway, such as ~190\u2013200 depending on chain pricing).\n - This turns \u201cuncertain tape\u201d into a defined-risk hold.\n\n3) Hard risk triggers (non-negotiable)\n- If the stock closes below ~168 on rising volume: cut another 15\u201325% of the original position (or increase hedge notional).\n- If the stock closes and holds below ~160: exit the remaining shares (or ensure the hedge fully covers the residual exposure).\nThese are there to prevent the classic mistake of \u201cwaiting for it to come back\u201d while a downtrend accelerates.\n\n4) Rules for re-entry (so you\u2019re not permanently bearish)\nOnly re-add meaningful long exposure if at least one of these happens:\n- Technical repair: sustained closes back above ~185\u2013186 with momentum improving (MACD turning up/positive and RSI back above ~50), ideally on constructive volume.\nAnd/or\n- Fundamental confirmation: next guidance/partner commentary supports stable-to-rising hyperscaler AI spend and no evidence that inventory/receivables are turning into a sell-through problem (watch DSO and inventory days trend).\n\n5) If you don\u2019t currently own it (or after you sell)\n- Do not buy unhedged shares while it\u2019s below the major moving averages with negative momentum.\n- If you must express a bullish view, use defined-risk structures:\n - Small debit call spreads (so max loss is premium)\n - Or smaller starter equity position paired immediately with a put (synthetic \u201crisk-defined\u201d stock)\n\n6) Position sizing going forward (to avoid repeat errors)\n- Cap NVDA at a preset portfolio limit (typical: 3\u20136% max for most diversified portfolios; less if volatility is already high elsewhere).\n- No \u201cadd to losers\u201d unless a pre-defined technical/fundamental confirmation condition is met. This is the behavior that most often turns a manageable drawdown into portfolio damage in crowded mega-cap leaders.\n\nNet: The company can be outstanding and the stock can still be a sell right now. The debate\u2019s strongest, most actionable evidence points to near-term downside risk overwhelming the benefit of staying fully exposed. Reduce first, define the risk on what remains, and earn the right to re-buy on confirmation rather than hope.", + "final_trade_decision": "## Recommendation: **Sell** (reduce exposure now; keep a smaller, defined-risk \u201ctoe-hold\u201d only if you must)\n\n### 1) Key arguments (what actually matters)\n\n**Aggressive (best points)**\n- Fundamentals/FCF/moat are exceptional and can overwhelm technicals fast: *\u201cfundamentals and catalyst optionality create extreme upside asymmetry\u2026 a fast 20\u201340% re-rate.\u201d*\n- Warns that rigid \u201cwait for technical repair\u201d can miss the move: *\u201cWaiting for 3 closes above 185\u2013186 risks catching only the late innings.\u201d*\n- Suggests options to preserve upside while limiting capital at risk (LEAPS/call spreads).\n\n**Conservative (best points)**\n- Near-term risk is quantifiably bearish: *\u201ctechnically confirmed distribution\u2026 price < 10 EMA < 50 SMA and below the 200 SMA; MACD negative\u2026 RSI ~38\u2026 VWMA above price\u2026 ATR elevated.\u201d*\n- Valuation sensitivity + beta + macro volatility implies sharp drawdowns are plausible: *\u201cHigh valuation + high beta (\u22482.38) + VIX \u224824 = severe downside convexity.\u201d*\n- Rejects left-tail exposure from financed structures: *\u201crisk reversals\u2026 take left-tail risk\u2026 exactly the exposure you should be minimizing.\u201d*\n- Endorses clear de-risk + hedge + triggers: *\u201csell 50%\u2026 hedge the remainder\u2026 adhere to hard stop triggers (168/160).\u201d*\n\n**Neutral (best points)**\n- Confirms both realities: weak tape + very strong fundamentals + real tail risks.\n- Proposes a compromise trim (40%) plus layered hedging and ATR-aware triggers (more execution-savvy), but still admits the setup is risk-first: *\u201cTechnicals are weak\u2026 key risks are real\u2026 credible asymmetric downside drivers.\u201d*\n\n### 2) Rationale (why the decision is **Sell**, using direct debate evidence)\n\nThis is a timing/risk decision, not a \u201cis NVDA a great company\u201d decision. The most *objective* evidence in the debate is the technical/volatility regime plus valuation convexity. The Conservative and Neutral analysts both anchor on the same hard facts:\n\n- *\u201cTechnically confirmed distribution\u201d* with price below key moving averages, negative MACD, and VWMA above price (distribution).\n- Elevated volatility (ATR ~5.8) and macro risk (VIX ~24), which increases the probability of air-pockets.\n- Specific balance-sheet \u201cyellow flags\u201d (inventory/AR build) that can become a catalyst for repricing if guidance/sell-through disappoints.\n\nAggressive is directionally right about long-term optionality, but the proposed ways to express it (LEAPS, risk-reversals, put-selling) **increase** the exact risk the other two warn about: getting paid small premium while being exposed to large left-tail outcomes, or paying premium that can still go to zero if repricing persists. Even Neutral\u2014who tries to preserve upside\u2014still starts with **reducing exposure now** because the near-term setup is unfavorable.\n\nSo the most robust, least regret-prone action is: **Sell to reduce exposure first**, then re-enter only when the market stops actively repricing the risk premium (technical repair and/or fundamental confirmation).\n\n### 3) Refine the trader\u2019s original plan (keep what works, simplify what matters)\n\nYour original plan was already coherent. I\u2019d tighten it into a single decisive \u201crisk-reduction first\u201d playbook, borrowing Neutral\u2019s execution realism but keeping Conservative\u2019s mandate discipline.\n\n**A. Immediate action (today/next session): SELL to reduce**\n- **Base case:** sell **40\u201350%** of shares now.\n - Use **50%** if NVDA is a top-3 holding or your horizon is <12 months (aligns with Conservative).\n - Use **40%** if you want a modest \u201ctoe-hold\u201d for upside optionality (Neutral compromise).\n\n**B. Protect what remains (defined risk; don\u2019t over-engineer)**\n- Hedge remaining shares with a **~3-month put spread** (example from debate: **170/150** or nearest liquid strikes).\n- If you refuse to hedge, then you\u2019re implicitly choosing to accept the \u201ctechnical breakdown + high beta\u201d drawdown risk the Conservative flagged\u2014don\u2019t pretend it\u2019s controlled.\n\n**C. Non-negotiable downside triggers (keep them)**\n- The trader\u2019s framework was strong because it prevents hope-based holding:\n - **Close < ~168 on rising volume:** cut another **15\u201325% of original** exposure *or* increase hedge notional materially.\n - **Close and hold < ~160:** **exit remaining** (or fully delta-hedge so net exposure is near zero).\n\n**D. Re-entry (don\u2019t marry the position; earn it back)**\nRe-add only when at least one of these happens:\n- **Technical repair:** sustained reclaim of **~185\u2013186** with momentum improving (MACD up, RSI >50).\n- **Fundamental confirmation:** hyperscaler commentary/guidance confirms continued AI spend and inventory/AR do not look like digestion.\n\n### 4) Learn from past mistakes (applied here to avoid a bad call)\n\nThe key \u201cpast mistake\u201d embedded in the debate is explicitly called out in your own text and echoed by Conservative/Neutral: **staying long a \u201cgreat story\u201d through a clear tape breakdown and volatility expansion**, then suffering a large, avoidable drawdown. Your original note nailed it: *\u201cThat\u2019s how you sit through a 25\u201340% drawdown you didn\u2019t need to take.\u201d*\n\nTo not repeat that mistake:\n- Don\u2019t let \u201cexceptional fundamentals\u201d override **current** market evidence of repricing.\n- Don\u2019t use \u201cHold\u201d as a comfort blanket when the tape is signaling distribution and the downside is unbounded.\n- Don\u2019t finance upside with left-tail risk (risk reversals / heavy put-selling) in a regime explicitly defined by elevated volatility and tail risks.\n\n## Final, actionable decision\n**SELL** (reduce exposure now). \nThen **hedge the remainder** with a 3\u2011month put spread and follow the **168/160** risk triggers. Re-enter only on defined technical repair and/or fundamental confirmation." + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..cbab4b77 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,330 @@ +{ + "name": "tradingagents", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "tradingagents", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "concurrently": "^9.2.1" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/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/chalk/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/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/concurrently": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.1.tgz", + "integrity": "sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "4.1.2", + "rxjs": "7.8.2", + "shell-quote": "1.8.3", + "supports-color": "8.1.1", + "tree-kill": "1.2.2", + "yargs": "17.7.2" + }, + "bin": { + "conc": "dist/bin/concurrently.js", + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/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/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..370fe86f --- /dev/null +++ b/package.json @@ -0,0 +1,31 @@ +{ + "name": "tradingagents", + "version": "1.0.0", + "description": "

\r \r

", + "main": "index.js", + "directories": { + "doc": "docs", + "test": "tests" + }, + "scripts": { + "dev": "concurrently \"venv\\\\Scripts\\\\python.exe -m uvicorn api.main:app --reload --port 8000\" \"cd ui && npm run dev\"", + "dev:api": "venv\\Scripts\\python.exe -m uvicorn api.main:app --reload --port 8000", + "dev:ui": "cd ui && npm run dev", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/TauricResearch/TradingAgents.git" + }, + "keywords": [], + "author": "", + "license": "ISC", + "type": "commonjs", + "bugs": { + "url": "https://github.com/TauricResearch/TradingAgents/issues" + }, + "homepage": "https://github.com/TauricResearch/TradingAgents#readme", + "devDependencies": { + "concurrently": "^9.2.1" + } +} diff --git a/pyproject.toml b/pyproject.toml index e95cd447..0f47105d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,3 +38,6 @@ tradingagents = "cli.main:app" [tool.setuptools.packages.find] include = ["tradingagents*", "cli*"] + +[tool.pytest.ini_options] +asyncio_mode = "auto" diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/api/__init__.py b/tests/api/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/api/test_models.py b/tests/api/test_models.py new file mode 100644 index 00000000..007e93b2 --- /dev/null +++ b/tests/api/test_models.py @@ -0,0 +1,23 @@ +import pytest +from api.models.run import RunConfig, RunSummary, RunStatus +from api.models.settings import Settings + + +def test_run_config_defaults(): + config = RunConfig(ticker="NVDA", date="2024-05-10") + assert config.llm_provider == "openai" + assert config.max_debate_rounds == 1 + + +def test_run_summary_has_decision(): + summary = RunSummary( + id="abc123", ticker="NVDA", date="2024-05-10", + status=RunStatus.COMPLETE, decision="BUY", created_at="2026-03-23T09:00:00" + ) + assert summary.decision == "BUY" + + +def test_settings_defaults(): + s = Settings() + assert s.deep_think_llm == "gpt-5.2" + assert s.max_debate_rounds == 1 diff --git a/tests/api/test_run_service.py b/tests/api/test_run_service.py new file mode 100644 index 00000000..81297717 --- /dev/null +++ b/tests/api/test_run_service.py @@ -0,0 +1,118 @@ +import pytest +from collections import defaultdict +from unittest.mock import patch, MagicMock +from api.services.run_service import RunService +from api.store.runs_store import RunsStore +from api.models.run import RunConfig, RunStatus + + +@pytest.fixture +def store(): + return RunsStore() + + +@pytest.fixture +def service(store): + return RunService(store) + + +def _mock_graph(stream_yields, decision="BUY"): + """Return a mock TradingAgentsGraph instance for stream_propagate tests.""" + mock = MagicMock() + mock.stream_propagate.return_value = iter(stream_yields) + mock._last_decision = decision + return mock + + +def test_emits_agent_start_and_complete_per_step(service, store): + config = RunConfig(ticker="NVDA", date="2026-03-23") + run = store.create(config) + yields = [ + ("market_analyst", "bullish"), + ("news_analyst", "stable"), + ] + with patch("api.services.run_service.TradingAgentsGraph") as MockGraph: + MockGraph.return_value = _mock_graph(yields) + events = list(service.stream_events(run.id)) + + starts = [e for e in events if e["event"] == "agent:start"] + completes = [e for e in events if e["event"] == "agent:complete"] + assert len(starts) == 2 + assert len(completes) == 2 + assert starts[0]["data"]["step"] == "market_analyst" + assert starts[0]["data"]["turn"] == 0 + assert completes[0]["data"]["report"] == "bullish" + + +def test_turn_increments_for_repeat_steps(service, store): + config = RunConfig(ticker="NVDA", date="2026-03-23") + run = store.create(config) + yields = [ + ("bull_researcher", "bull round 1"), + ("bear_researcher", "bear round 1"), + ("bull_researcher", "bull round 2"), + ] + with patch("api.services.run_service.TradingAgentsGraph") as MockGraph: + MockGraph.return_value = _mock_graph(yields) + events = list(service.stream_events(run.id)) + + bull_completes = [e for e in events + if e["event"] == "agent:complete" and e["data"]["step"] == "bull_researcher"] + assert len(bull_completes) == 2 + assert bull_completes[0]["data"]["turn"] == 0 + assert bull_completes[1]["data"]["turn"] == 1 + + +def test_run_complete_emitted_with_decision(service, store): + config = RunConfig(ticker="NVDA", date="2026-03-23") + run = store.create(config) + with patch("api.services.run_service.TradingAgentsGraph") as MockGraph: + MockGraph.return_value = _mock_graph([("trader", "buy signal")], decision="SELL") + events = list(service.stream_events(run.id)) + + complete = next(e for e in events if e["event"] == "run:complete") + assert complete["data"]["decision"] == "SELL" + + +def test_store_status_set_to_complete(service, store): + config = RunConfig(ticker="NVDA", date="2026-03-23") + run = store.create(config) + with patch("api.services.run_service.TradingAgentsGraph") as MockGraph: + MockGraph.return_value = _mock_graph([]) + list(service.stream_events(run.id)) + + assert store.get(run.id).status == RunStatus.COMPLETE + + +def test_error_during_stream_emits_run_error(service, store): + config = RunConfig(ticker="NVDA", date="2026-03-23") + run = store.create(config) + + def bad_stream(*args, **kwargs): + yield ("market_analyst", "ok") + raise RuntimeError("LLM network error") + + with patch("api.services.run_service.TradingAgentsGraph") as MockGraph: + mock = MagicMock() + mock.stream_propagate.side_effect = bad_stream + MockGraph.return_value = mock + events = list(service.stream_events(run.id)) + + error_events = [e for e in events if e["event"] == "run:error"] + assert len(error_events) == 1 + assert "LLM network error" in error_events[0]["data"]["message"] + # Also verify the store recorded the error + assert store.get(run.id).error is not None + assert "LLM network error" in store.get(run.id).error + + +def test_selected_analysts_passed_to_graph(service, store): + config = RunConfig(ticker="NVDA", date="2026-03-23", + enabled_analysts=["market", "news"]) + run = store.create(config) + with patch("api.services.run_service.TradingAgentsGraph") as MockGraph: + MockGraph.return_value = _mock_graph([]) + list(service.stream_events(run.id)) + + call_kwargs = MockGraph.call_args.kwargs + assert call_kwargs.get("selected_analysts") == ["market", "news"] diff --git a/tests/api/test_runs.py b/tests/api/test_runs.py new file mode 100644 index 00000000..7a1faacd --- /dev/null +++ b/tests/api/test_runs.py @@ -0,0 +1,23 @@ +import pytest +from httpx import AsyncClient, ASGITransport +from api.main import app + +@pytest.mark.asyncio +async def test_create_run_returns_run_id(): + async with AsyncClient( + transport=ASGITransport(app=app), base_url="http://test" + ) as client: + response = await client.post("/runs", json={ + "ticker": "NVDA", "date": "2024-05-10" + }) + assert response.status_code == 200 + assert "id" in response.json() + +@pytest.mark.asyncio +async def test_list_runs_empty_initially(): + async with AsyncClient( + transport=ASGITransport(app=app), base_url="http://test" + ) as client: + response = await client.get("/runs") + assert response.status_code == 200 + assert isinstance(response.json(), list) diff --git a/tests/api/test_settings.py b/tests/api/test_settings.py new file mode 100644 index 00000000..592bd2c3 --- /dev/null +++ b/tests/api/test_settings.py @@ -0,0 +1,29 @@ +import pytest +from httpx import AsyncClient, ASGITransport +from api.main import app + +@pytest.mark.asyncio +async def test_get_settings_returns_defaults(): + async with AsyncClient( + transport=ASGITransport(app=app), base_url="http://test" + ) as client: + response = await client.get("/settings") + assert response.status_code == 200 + data = response.json() + assert "deep_think_llm" in data + assert "max_debate_rounds" in data + +@pytest.mark.asyncio +async def test_put_settings_updates_values(): + async with AsyncClient( + transport=ASGITransport(app=app), base_url="http://test" + ) as client: + response = await client.put("/settings", json={ + "deep_think_llm": "claude-opus-4-6", + "quick_think_llm": "claude-haiku-4-5-20251001", + "llm_provider": "anthropic", + "max_debate_rounds": 2, + "max_risk_discuss_rounds": 2, + }) + assert response.status_code == 200 + assert response.json()["deep_think_llm"] == "claude-opus-4-6" diff --git a/tests/api/test_store.py b/tests/api/test_store.py new file mode 100644 index 00000000..a8607d57 --- /dev/null +++ b/tests/api/test_store.py @@ -0,0 +1,28 @@ +import pytest +from api.store.runs_store import RunsStore +from api.models.run import RunConfig, RunStatus + + +def test_create_and_get_run(): + store = RunsStore() + config = RunConfig(ticker="NVDA", date="2024-05-10") + run = store.create(config) + assert run.id is not None + assert run.status == RunStatus.QUEUED + fetched = store.get(run.id) + assert fetched.ticker == "NVDA" + + +def test_list_runs(): + store = RunsStore() + store.create(RunConfig(ticker="NVDA", date="2024-05-10")) + store.create(RunConfig(ticker="AAPL", date="2024-05-09")) + runs = store.list_all() + assert len(runs) == 2 + + +def test_update_run_status(): + store = RunsStore() + run = store.create(RunConfig(ticker="NVDA", date="2024-05-10")) + store.update_status(run.id, RunStatus.RUNNING) + assert store.get(run.id).status == RunStatus.RUNNING diff --git a/tests/api/test_stream_propagate.py b/tests/api/test_stream_propagate.py new file mode 100644 index 00000000..ebdc4570 --- /dev/null +++ b/tests/api/test_stream_propagate.py @@ -0,0 +1,127 @@ +import pytest +from unittest.mock import MagicMock, patch, PropertyMock +from tradingagents.graph.trading_graph import TradingAgentsGraph + + +def _make_graph(chunks): + """Helper: build a mocked TradingAgentsGraph whose graph.stream yields chunks.""" + with patch.object(TradingAgentsGraph, '__init__', lambda self, *a, **kw: None): + ta = TradingAgentsGraph.__new__(TradingAgentsGraph) + ta.graph = MagicMock() + ta.graph.stream.return_value = iter(chunks) + ta.graph.get_state.return_value = MagicMock(next=None) # no checkpoint to resume + ta.quick_thinking_llm = MagicMock() + ta.signal_processor = MagicMock() + ta.signal_processor.process_signal.return_value = "BUY" + ta.config = {"llm_provider": "openai", "deep_think_llm": "gpt-4", + "quick_think_llm": "gpt-4-mini", "max_debate_rounds": 1, + "max_risk_discuss_rounds": 1, "results_dir": "./results"} + ta._last_decision = None + ta.selected_analysts = ["market", "news", "fundamentals", "social"] + # propagator needed by stream_propagate for initial state and graph args + ta.propagator = MagicMock() + ta.propagator.create_initial_state.return_value = { + "messages": [], "company_of_interest": "NVDA", "trade_date": "2026-03-23", + "investment_debate_state": { + "bull_history": "", "bear_history": "", "history": "", + "current_response": "", "judge_decision": "", "count": 0 + }, + "risk_debate_state": { + "aggressive_history": "", "conservative_history": "", "neutral_history": "", + "history": "", "latest_speaker": "", "current_aggressive_response": "", + "current_conservative_response": "", "current_neutral_response": "", + "judge_decision": "", "count": 0 + }, + "market_report": "", "fundamentals_report": "", + "sentiment_report": "", "news_report": "", + } + ta.propagator.get_graph_args.return_value = { + "stream_mode": "updates", + "config": {"configurable": {"thread_id": "test-thread"}, "recursion_limit": 100}, + } + # _log_state writes to disk — mock it out in all tests + ta._log_state = MagicMock() + return ta + + +def test_yields_known_node(): + ta = _make_graph([ + {"Market Analyst": {"market_report": "bullish outlook"}}, + ]) + results = list(ta.stream_propagate("NVDA", "2026-03-23")) + assert results == [("market_analyst", "bullish outlook")] + + +def test_skips_tool_nodes(): + ta = _make_graph([ + {"tools_market": {"messages": []}}, + {"Market Analyst": {"market_report": "ok"}}, + ]) + results = list(ta.stream_propagate("NVDA", "2026-03-23")) + assert len(results) == 1 + assert results[0][0] == "market_analyst" + + +def test_skips_msg_clear_nodes(): + ta = _make_graph([ + {"Msg Clear Market": {}}, + {"News Analyst": {"news_report": "stable"}}, + ]) + results = list(ta.stream_propagate("NVDA", "2026-03-23")) + assert len(results) == 1 + assert results[0][0] == "news_analyst" + + +def test_skips_unknown_nodes_with_warning(caplog): + import logging + ta = _make_graph([ + {"Unknown Future Node": {"some_field": "value"}}, + {"Trader": {"trader_investment_plan": "buy 100 shares"}}, + ]) + with caplog.at_level(logging.WARNING): + results = list(ta.stream_propagate("NVDA", "2026-03-23")) + assert len(results) == 1 + assert results[0][0] == "trader" + assert any("Unknown Future Node" in r.message for r in caplog.records) + + +def test_last_decision_set_after_exhaustion(): + ta = _make_graph([ + {"Risk Judge": {"risk_debate_state": {"judge_decision": "SELL signal strong"}}}, + ]) + # graph.get_state() is called post-loop to fetch the full final snapshot + ta.graph.get_state.return_value = MagicMock( + next=None, + values={"final_trade_decision": "strong SELL signal from risk team"} + ) + + list(ta.stream_propagate("NVDA", "2026-03-23")) + # signal_processor returns "BUY" from mock setup; _last_decision should be set + assert ta._last_decision == "BUY" + + +def test_bull_researcher_extracts_bull_history(): + ta = _make_graph([ + {"Bull Researcher": {"investment_debate_state": { + "bull_history": "bullish case round 1", "bear_history": "", + "history": "", "current_response": "", "judge_decision": "", "count": 1 + }}}, + ]) + results = list(ta.stream_propagate("NVDA", "2026-03-23")) + assert results[0] == ("bull_researcher", "bullish case round 1") + + +def test_research_manager_extracts_investment_plan(): + ta = _make_graph([ + {"Research Manager": {"investment_plan": "Invest 20% in NVDA"}}, + ]) + results = list(ta.stream_propagate("NVDA", "2026-03-23")) + assert results[0] == ("research_manager", "Invest 20% in NVDA") + + +def test_missing_field_yields_empty_string(): + ta = _make_graph([ + {"Market Analyst": {}}, # no market_report key + ]) + results = list(ta.stream_propagate("NVDA", "2026-03-23")) + assert results[0] == ("market_analyst", "") diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 00000000..c576642b --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,2 @@ +# This file prevents asyncio-mode issues with pytest-asyncio +# when running non-async tests diff --git a/tradingagents/graph/trading_graph.py b/tradingagents/graph/trading_graph.py index 0d12988c..2dded9a4 100644 --- a/tradingagents/graph/trading_graph.py +++ b/tradingagents/graph/trading_graph.py @@ -3,11 +3,14 @@ import os import sqlite3 import hashlib +import logging from pathlib import Path import json from datetime import date from typing import Dict, Any, Tuple, List, Optional +logger = logging.getLogger(__name__) + from langgraph.prebuilt import ToolNode from langgraph.checkpoint.sqlite import SqliteSaver @@ -43,6 +46,24 @@ from .reflection import Reflector from .signal_processing import SignalProcessor +_NODE_TO_STEP = { + "Market Analyst": "market_analyst", + "News Analyst": "news_analyst", + "Fundamentals Analyst": "fundamentals_analyst", + "Social Analyst": "social_analyst", + "Bull Researcher": "bull_researcher", + "Bear Researcher": "bear_researcher", + "Research Manager": "research_manager", + "Trader": "trader", + "Aggressive Analyst": "aggressive_analyst", + "Conservative Analyst": "conservative_analyst", + "Neutral Analyst": "neutral_analyst", + "Risk Judge": "risk_judge", +} + +_SKIP_NODES = {"tools_market", "tools_news", "tools_fundamentals", "tools_social"} + + class TradingAgentsGraph: """Main class that orchestrates the trading agents framework.""" @@ -286,6 +307,95 @@ class TradingAgentsGraph: # Return decision and processed signal return final_state, self.process_signal(final_state["final_trade_decision"]) + @staticmethod + def _extract_report(step_key: str, update: dict) -> str: + """Extract the relevant report string from a node's state update.""" + extractors = { + "market_analyst": lambda u: u.get("market_report", ""), + "news_analyst": lambda u: u.get("news_report", ""), + "fundamentals_analyst": lambda u: u.get("fundamentals_report", ""), + "social_analyst": lambda u: u.get("sentiment_report", ""), + "bull_researcher": lambda u: (u.get("investment_debate_state") or {}).get("bull_history", ""), + "bear_researcher": lambda u: (u.get("investment_debate_state") or {}).get("bear_history", ""), + "research_manager": lambda u: u.get("investment_plan", ""), + "trader": lambda u: u.get("trader_investment_plan", ""), + "aggressive_analyst": lambda u: (u.get("risk_debate_state") or {}).get("current_aggressive_response", ""), + "conservative_analyst": lambda u: (u.get("risk_debate_state") or {}).get("current_conservative_response", ""), + "neutral_analyst": lambda u: (u.get("risk_debate_state") or {}).get("current_neutral_response", ""), + "risk_judge": lambda u: (u.get("risk_debate_state") or {}).get("judge_decision", ""), + } + return extractors[step_key](update) or "" + + def stream_propagate(self, company_name: str, trade_date: str, thread_id=None): + """Stream trading analysis events as each agent node completes. + + Yields: + (step_key, report) tuples for each meaningful node completion. + + After the generator is exhausted, self._last_decision is set to the + normalized decision string ("BUY", "SELL", or "HOLD"). + """ + self.ticker = company_name + self._last_decision = None + + if thread_id is None: + payload = json.dumps( + { + "ticker": company_name.strip().upper(), + "trade_date": str(trade_date), + "analysts": sorted(self.selected_analysts), + "llm_provider": self.config.get("llm_provider"), + "deep_think_llm": self.config.get("deep_think_llm"), + "quick_think_llm": self.config.get("quick_think_llm"), + "max_debate_rounds": self.config.get("max_debate_rounds"), + "max_risk_discuss_rounds": self.config.get("max_risk_discuss_rounds"), + }, + sort_keys=True, + ).encode() + thread_id = "ta_prog_" + hashlib.sha256(payload).hexdigest()[:24] + + init_agent_state = self.propagator.create_initial_state(company_name, trade_date) + args = self.propagator.get_graph_args(thread_id=thread_id) + args["stream_mode"] = "updates" # stream per-node deltas, not full state snapshots + + thread_config = {"configurable": {"thread_id": thread_id}} + snap = self.graph.get_state(thread_config) + stream_input = None if snap.next else init_agent_state + + for chunk in self.graph.stream(stream_input, **args): + node_name, update = next(iter(chunk.items())) + + # Filter: skip list first, then known nodes, else warn and skip + if node_name in _SKIP_NODES or node_name.startswith("Msg Clear"): + continue + if node_name not in _NODE_TO_STEP: + logger.warning("stream_propagate: unknown node '%s' — skipping", node_name) + continue + + step_key = _NODE_TO_STEP[node_name] + report = TradingAgentsGraph._extract_report(step_key, update) + + yield step_key, report + + # Post-loop: fetch the complete final state snapshot (all fields populated). + # stream_mode="updates" gives only deltas — use get_state() for the full picture + # needed by _log_state and process_signal. + final_snap = self.graph.get_state(thread_config) + final_state = final_snap.values if hasattr(final_snap, "values") else {} + + raw_signal = final_state.get("final_trade_decision", "") + try: + raw_decision = self.process_signal(raw_signal) + decision = raw_decision.strip().upper() + if decision not in {"BUY", "SELL", "HOLD"}: + logger.warning("stream_propagate: unexpected decision '%s' — defaulting to HOLD", decision) + decision = "HOLD" + except Exception: + raise # propagate to run_service for run:error handling + + self._last_decision = decision + self._log_state(trade_date, final_state) + def _log_state(self, trade_date, final_state): """Log the final state to a JSON file.""" self.log_states_dict[str(trade_date)] = { diff --git a/tradingagents/llm_clients/anthropic_client.py b/tradingagents/llm_clients/anthropic_client.py index 8539c752..24681130 100644 --- a/tradingagents/llm_clients/anthropic_client.py +++ b/tradingagents/llm_clients/anthropic_client.py @@ -6,6 +6,28 @@ from .base_client import BaseLLMClient from .validators import validate_model +class NormalizedChatAnthropic(ChatAnthropic): + """ChatAnthropic with normalized content output. + + Newer Claude models can return content as a list of content blocks. + This normalizes to a plain string for consistent downstream handling. + """ + + def _normalize_content(self, response): + content = response.content + if isinstance(content, list): + texts = [ + item.get("text", "") if isinstance(item, dict) and item.get("type") == "text" + else item if isinstance(item, str) else "" + for item in content + ] + response.content = "\n".join(t for t in texts if t) + return response + + def invoke(self, input, config=None, **kwargs): + return self._normalize_content(super().invoke(input, config, **kwargs)) + + class AnthropicClient(BaseLLMClient): """Client for Anthropic Claude models.""" @@ -20,7 +42,7 @@ class AnthropicClient(BaseLLMClient): if key in self.kwargs: llm_kwargs[key] = self.kwargs[key] - return ChatAnthropic(**llm_kwargs) + return NormalizedChatAnthropic(**llm_kwargs) def validate_model(self) -> bool: """Validate model for Anthropic.""" diff --git a/tradingagents/llm_clients/openai_client.py b/tradingagents/llm_clients/openai_client.py index c314d077..9f6510a0 100644 --- a/tradingagents/llm_clients/openai_client.py +++ b/tradingagents/llm_clients/openai_client.py @@ -6,6 +6,28 @@ from langchain_openai import ChatOpenAI from .base_client import BaseLLMClient from .validators import validate_model + +class NormalizedChatOpenAI(ChatOpenAI): + """ChatOpenAI with normalized content output. + + Some OpenAI-compatible providers (e.g. Responses API) can return content + as a list of content blocks. This normalizes to a plain string. + """ + + def _normalize_content(self, response): + content = response.content + if isinstance(content, list): + texts = [ + item.get("text", "") if isinstance(item, dict) and item.get("type") == "text" + else item if isinstance(item, str) else "" + for item in content + ] + response.content = "\n".join(t for t in texts if t) + return response + + def invoke(self, input, config=None, **kwargs): + return self._normalize_content(super().invoke(input, config, **kwargs)) + # Kwargs forwarded from user config to ChatOpenAI _PASSTHROUGH_KWARGS = ( "timeout", "max_retries", "reasoning_effort", @@ -66,7 +88,7 @@ class OpenAIClient(BaseLLMClient): if self.provider == "openai": llm_kwargs["use_responses_api"] = True - return ChatOpenAI(**llm_kwargs) + return NormalizedChatOpenAI(**llm_kwargs) def validate_model(self) -> bool: """Validate model for the provider.""" diff --git a/ui/.gitignore b/ui/.gitignore new file mode 100644 index 00000000..5ef6a520 --- /dev/null +++ b/ui/.gitignore @@ -0,0 +1,41 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files (can opt-in for committing if needed) +.env* + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/ui/AGENTS.md b/ui/AGENTS.md new file mode 100644 index 00000000..8bd0e390 --- /dev/null +++ b/ui/AGENTS.md @@ -0,0 +1,5 @@ + +# This is NOT the Next.js you know + +This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices. + diff --git a/ui/CLAUDE.md b/ui/CLAUDE.md new file mode 100644 index 00000000..43c994c2 --- /dev/null +++ b/ui/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md diff --git a/ui/README.md b/ui/README.md new file mode 100644 index 00000000..e215bc4c --- /dev/null +++ b/ui/README.md @@ -0,0 +1,36 @@ +This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). + +## Getting Started + +First, run the development server: + +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +# or +bun dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. + +This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. diff --git a/ui/__tests__/components/Sidebar.test.tsx b/ui/__tests__/components/Sidebar.test.tsx new file mode 100644 index 00000000..542d455d --- /dev/null +++ b/ui/__tests__/components/Sidebar.test.tsx @@ -0,0 +1,20 @@ +import { render, screen } from '@testing-library/react' +import Sidebar from '@/components/Sidebar' + +jest.mock('next/navigation', () => ({ + usePathname: () => '/new-run', +})) + +test('renders all nav links', () => { + render() + expect(screen.getByText('New Run')).toBeInTheDocument() + expect(screen.getByText('History')).toBeInTheDocument() + expect(screen.getByText('Settings')).toBeInTheDocument() +}) + +test('marks active link for current path', () => { + render() + const newRunLink = screen.getByText('New Run').closest('a') + // Active link has vault primary colour class + expect(newRunLink?.className).toContain('text-[#adc6ff]') +}) diff --git a/ui/__tests__/features/history/RunHistoryTable.test.tsx b/ui/__tests__/features/history/RunHistoryTable.test.tsx new file mode 100644 index 00000000..2c692497 --- /dev/null +++ b/ui/__tests__/features/history/RunHistoryTable.test.tsx @@ -0,0 +1,24 @@ +import { render, screen } from '@testing-library/react' +import RunHistoryTable from '@/features/history/components/RunHistoryTable' + +const runs = [ + { id: 'abc', ticker: 'NVDA', date: '2024-05-10', status: 'complete' as const, + decision: 'BUY' as const, created_at: '2026-03-23T09:00:00' }, + { id: 'def', ticker: 'AAPL', date: '2024-05-09', status: 'complete' as const, + decision: 'HOLD' as const, created_at: '2026-03-22T16:00:00' }, +] + +test('renders ticker and decision for each run', () => { + render() + expect(screen.getByText('NVDA')).toBeInTheDocument() + expect(screen.getByText('BUY')).toBeInTheDocument() + expect(screen.getByText('AAPL')).toBeInTheDocument() + expect(screen.getByText('HOLD')).toBeInTheDocument() +}) + +test('renders View Report links for each run', () => { + render() + const links = screen.getAllByText('View Report →') + expect(links).toHaveLength(2) + expect(links[0].closest('a')).toHaveAttribute('href', '/runs/abc') +}) diff --git a/ui/__tests__/features/new-run/RunConfigForm.test.tsx b/ui/__tests__/features/new-run/RunConfigForm.test.tsx new file mode 100644 index 00000000..d2881a7c --- /dev/null +++ b/ui/__tests__/features/new-run/RunConfigForm.test.tsx @@ -0,0 +1,26 @@ +import { render, screen, fireEvent, waitFor } from '@testing-library/react' +import RunConfigForm from '@/features/new-run/components/RunConfigForm' + +const mockPush = jest.fn() +jest.mock('next/navigation', () => ({ useRouter: () => ({ push: mockPush }) })) +jest.mock('@/lib/api-client', () => ({ + createRun: jest.fn().mockResolvedValue({ id: 'test123' }), +})) + +test('renders ticker and date inputs', () => { + render() + expect(screen.getByPlaceholderText('e.g. NVDA')).toBeInTheDocument() + expect(screen.getByLabelText(/trade date/i)).toBeInTheDocument() +}) + +test('submitting navigates to run detail page', async () => { + render() + fireEvent.change(screen.getByPlaceholderText('e.g. NVDA'), { + target: { value: 'NVDA' }, + }) + fireEvent.change(screen.getByLabelText(/trade date/i), { + target: { value: '2024-05-10' }, + }) + fireEvent.click(screen.getByText(/run analysis/i)) + await waitFor(() => expect(mockPush).toHaveBeenCalledWith('/runs/test123')) +}) diff --git a/ui/__tests__/features/run-detail/PipelineStepper.test.tsx b/ui/__tests__/features/run-detail/PipelineStepper.test.tsx new file mode 100644 index 00000000..a7bd1ba2 --- /dev/null +++ b/ui/__tests__/features/run-detail/PipelineStepper.test.tsx @@ -0,0 +1,29 @@ +import { render, screen } from '@testing-library/react' +import PipelineStepper from '@/features/run-detail/components/PipelineStepper' +import { AGENT_STEPS } from '@/lib/types/run' +import type { StepStatus } from '@/lib/types/agents' + +function makeSteps(overrides: Partial> = {}) { + return Object.fromEntries( + AGENT_STEPS.map((s) => [s, overrides[s] ?? 'pending' as StepStatus]) + ) as Record +} + +test('renders 4 phase labels', () => { + render() + expect(screen.getByText('Analysts')).toBeInTheDocument() + expect(screen.getByText('Researchers')).toBeInTheDocument() + expect(screen.getByText('Trader')).toBeInTheDocument() + expect(screen.getByText('Risk')).toBeInTheDocument() +}) + +test('phase is done when all its steps are done', () => { + const steps = makeSteps({ + market_analyst: 'done', news_analyst: 'done', + fundamentals_analyst: 'done', social_analyst: 'done', + }) + const { container } = render() + // The Analysts phase dot should have done styling (text-[#adc6ff]) + // We verify by checking the component renders without error and has 4 phases + expect(screen.getAllByText(/Analysts|Researchers|Trader|Risk/).length).toBeGreaterThanOrEqual(4) +}) diff --git a/ui/__tests__/features/run-detail/useRunStream.test.ts b/ui/__tests__/features/run-detail/useRunStream.test.ts new file mode 100644 index 00000000..3edc2898 --- /dev/null +++ b/ui/__tests__/features/run-detail/useRunStream.test.ts @@ -0,0 +1,48 @@ +import { renderHook, act } from '@testing-library/react' +import { useRunStream } from '@/features/run-detail/hooks/useRunStream' + +jest.mock('@/lib/sse', () => ({ + createSSEConnection: jest.fn((url: string, handlers: Record void>) => { + setTimeout(() => { + // First turn of bull_researcher + handlers.onAgentStart?.({ step: 'bull_researcher', turn: 0 }) + handlers.onAgentComplete?.({ step: 'bull_researcher', turn: 0, report: 'Bull case round 1' }) + // Second turn of bull_researcher + handlers.onAgentStart?.({ step: 'bull_researcher', turn: 1 }) + handlers.onAgentComplete?.({ step: 'bull_researcher', turn: 1, report: 'Bull case round 2' }) + handlers.onRunComplete?.({ decision: 'BUY', run_id: 'abc' }) + }, 0) + return jest.fn() + }), +})) + +jest.mock('@/lib/api-client', () => ({ + getRunStreamUrl: (id: string) => `/api/runs/${id}/stream`, +})) + +test('appends multiple turns for same step', async () => { + const { result } = renderHook(() => useRunStream('abc')) + await act(async () => { await new Promise((r) => setTimeout(r, 10)) }) + expect(result.current.reports['bull_researcher']).toEqual([ + 'Bull case round 1', + 'Bull case round 2', + ]) +}) + +test('step status stays done after multiple turns', async () => { + const { result } = renderHook(() => useRunStream('abc')) + await act(async () => { await new Promise((r) => setTimeout(r, 10)) }) + expect(result.current.steps['bull_researcher']).toBe('done') +}) + +test('verdict and status set on run:complete', async () => { + const { result } = renderHook(() => useRunStream('abc')) + await act(async () => { await new Promise((r) => setTimeout(r, 10)) }) + expect(result.current.verdict).toBe('BUY') + expect(result.current.status).toBe('complete') +}) + +test('initial reports are empty arrays', () => { + const { result } = renderHook(() => useRunStream('abc')) + expect(result.current.reports['market_analyst']).toEqual([]) +}) diff --git a/ui/app/(dashboard)/history/page.tsx b/ui/app/(dashboard)/history/page.tsx new file mode 100644 index 00000000..5864bb4b --- /dev/null +++ b/ui/app/(dashboard)/history/page.tsx @@ -0,0 +1,40 @@ +'use client' +import Link from 'next/link' +import { useRunHistory } from '@/features/history/hooks/useRunHistory' +import RunHistoryTable from '@/features/history/components/RunHistoryTable' + +export default function HistoryPage() { + const { runs, loading, error } = useRunHistory() + return ( +
+
+
+

+ Run History +

+

+ Comprehensive log of all agent execution cycles +

+
+ + + New Analysis + +
+ + {loading && ( +

+ Loading... +

+ )} + {error && ( +

+ {error} +

+ )} + {!loading && } +
+ ) +} diff --git a/ui/app/(dashboard)/layout.tsx b/ui/app/(dashboard)/layout.tsx new file mode 100644 index 00000000..f25fca27 --- /dev/null +++ b/ui/app/(dashboard)/layout.tsx @@ -0,0 +1,10 @@ +import Sidebar from '@/components/Sidebar' + +export default function DashboardLayout({ children }: { children: React.ReactNode }) { + return ( +
+ +
{children}
+
+ ) +} diff --git a/ui/app/(dashboard)/new-run/page.tsx b/ui/app/(dashboard)/new-run/page.tsx new file mode 100644 index 00000000..12528e7d --- /dev/null +++ b/ui/app/(dashboard)/new-run/page.tsx @@ -0,0 +1,35 @@ +import RunConfigForm from '@/features/new-run/components/RunConfigForm' + +export default function NewRunPage() { + return ( +
+ {/* Page header */} +
+
+ Intelligence Engine +
+

+ New Analysis +

+

+ Configure a multi-agent analysis run. Your AI team will research market data, + debate investment thesis, and deliver a structured decision. +

+
+ + +
+ ) +} diff --git a/ui/app/(dashboard)/page.tsx b/ui/app/(dashboard)/page.tsx new file mode 100644 index 00000000..d560bec1 --- /dev/null +++ b/ui/app/(dashboard)/page.tsx @@ -0,0 +1,5 @@ +import { redirect } from 'next/navigation' + +export default function RootPage() { + redirect('/new-run') +} diff --git a/ui/app/(dashboard)/runs/[id]/page.tsx b/ui/app/(dashboard)/runs/[id]/page.tsx new file mode 100644 index 00000000..501b8ce2 --- /dev/null +++ b/ui/app/(dashboard)/runs/[id]/page.tsx @@ -0,0 +1,107 @@ +'use client' +import { use, useEffect, useState } from 'react' +import { useRunStream } from '@/features/run-detail/hooks/useRunStream' +import PipelineStepper from '@/features/run-detail/components/PipelineStepper' +import VerdictBanner from '@/features/run-detail/components/VerdictBanner' +import PhaseTabs from '@/features/run-detail/components/PhaseTabs' +import { getRun } from '@/lib/api-client' +import type { RunSummary } from '@/lib/types/run' + +const STATUS_CONFIG: Record = { + connecting: { bg: 'var(--bg-elevated)', color: 'var(--text-mid)', dot: 'var(--text-low)', label: 'Connecting' }, + running: { bg: 'var(--hold-bg)', color: 'var(--hold)', dot: 'var(--hold)', label: 'Running' }, + complete: { bg: 'var(--buy-bg)', color: 'var(--buy)', dot: 'var(--buy)', label: 'Complete' }, + error: { bg: 'var(--error-bg)', color: 'var(--error)', dot: 'var(--error)', label: 'Error' }, +} + +export default function RunDetailPage({ params }: { params: Promise<{ id: string }> }) { + const { id } = use(params) + const { steps, reports, verdict, status, error } = useRunStream(id) + const [run, setRun] = useState(null) + + useEffect(() => { + getRun(id).then(setRun).catch(() => {}) + }, [id]) + + const sc = STATUS_CONFIG[status] ?? STATUS_CONFIG.connecting + + return ( +
+ + {/* Header */} +
+
+
+ Analysis Run +
+

+ {run ? ( + <> + {run.ticker} + · + {run.date} + + ) : ( + Loading… + )} +

+
+ + {/* Status badge */} +
+
+ {sc.label} +
+
+ + {/* Pipeline */} + + + {/* Error */} + {error && ( +
+ Error: {error} +
+ )} + + {/* Verdict */} + {verdict && run && ( + + )} + + {/* Phase tabs + reports */} + + +
+ ) +} diff --git a/ui/app/(dashboard)/settings/page.tsx b/ui/app/(dashboard)/settings/page.tsx new file mode 100644 index 00000000..b5fe3e72 --- /dev/null +++ b/ui/app/(dashboard)/settings/page.tsx @@ -0,0 +1,18 @@ +import SettingsForm from '@/features/settings/components/SettingsForm' + +export default function SettingsPage() { + return ( +
+

+ Settings +

+

+ Configure default values for new analysis runs. API keys are managed via server environment variables. +

+ +
+ ) +} diff --git a/ui/app/favicon.ico b/ui/app/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..718d6fea4835ec2d246af9800eddb7ffb276240c GIT binary patch literal 25931 zcmeHv30#a{`}aL_*G&7qml|y<+KVaDM2m#dVr!KsA!#An?kSQM(q<_dDNCpjEux83 zLb9Z^XxbDl(w>%i@8hT6>)&Gu{h#Oeyszu?xtw#Zb1mO{pgX9699l+Qppw7jXaYf~-84xW z)w4x8?=youko|}Vr~(D$UXIbiXABHh`p1?nn8Po~fxRJv}|0e(BPs|G`(TT%kKVJAdg5*Z|x0leQq0 zkdUBvb#>9F()jo|T~kx@OM8$9wzs~t2l;K=woNssA3l6|sx2r3+kdfVW@e^8e*E}v zA1y5{bRi+3Z`uD3{F7LgFJDdvm;nJilkzDku>BwXH(8ItVCXk*-lSJnR?-2UN%hJ){&rlvg`CDTj z)Bzo!3v7Ou#83zEDEFcKt(f1E0~=rqeEbTnMvWR#{+9pg%7G8y>u1OVRUSoox-ovF z2Ydma(;=YuBY(eI|04{hXzZD6_f(v~H;C~y5=DhAC{MMS>2fm~1H_t2$56pc$NH8( z5bH|<)71dV-_oCHIrzrT`2s-5w_+2CM0$95I6X8p^r!gHp+j_gd;9O<1~CEQQGS8) zS9Qh3#p&JM-G8rHekNmKVewU;pJRcTAog68KYo^dRo}(M>36U4Us zfgYWSiHZL3;lpWT=zNAW>Dh#mB!_@Lg%$ms8N-;aPqMn+C2HqZgz&9~Eu z4|Kp<`$q)Uw1R?y(~S>ePdonHxpV1#eSP1B;Ogo+-Pk}6#0GsZZ5!||ev2MGdh}_m z{DeR7?0-1^zVs&`AV6Vt;r3`I`OI_wgs*w=eO%_#7Kepl{B@xiyCANc(l zzIyd4y|c6PXWq9-|KM8(zIk8LPk(>a)zyFWjhT!$HJ$qX1vo@d25W<fvZQ2zUz5WRc(UnFMKHwe1| zWmlB1qdbiA(C0jmnV<}GfbKtmcu^2*P^O?MBLZKt|As~ge8&AAO~2K@zbXelK|4T<{|y4`raF{=72kC2Kn(L4YyenWgrPiv z@^mr$t{#X5VuIMeL!7Ab6_kG$&#&5p*Z{+?5U|TZ`B!7llpVmp@skYz&n^8QfPJzL z0G6K_OJM9x+Wu2gfN45phANGt{7=C>i34CV{Xqlx(fWpeAoj^N0Biu`w+MVcCUyU* zDZuzO0>4Z6fbu^T_arWW5n!E45vX8N=bxTVeFoep_G#VmNlQzAI_KTIc{6>c+04vr zx@W}zE5JNSU>!THJ{J=cqjz+4{L4A{Ob9$ZJ*S1?Ggg3klFp!+Y1@K+pK1DqI|_gq z5ZDXVpge8-cs!o|;K73#YXZ3AShj50wBvuq3NTOZ`M&qtjj#GOFfgExjg8Gn8>Vq5 z`85n+9|!iLCZF5$HJ$Iu($dm?8~-ofu}tEc+-pyke=3!im#6pk_Wo8IA|fJwD&~~F zc16osQ)EBo58U7XDuMexaPRjU@h8tXe%S{fA0NH3vGJFhuyyO!Uyl2^&EOpX{9As0 zWj+P>{@}jxH)8|r;2HdupP!vie{sJ28b&bo!8`D^x}TE$%zXNb^X1p@0PJ86`dZyj z%ce7*{^oo+6%&~I!8hQy-vQ7E)0t0ybH4l%KltWOo~8cO`T=157JqL(oq_rC%ea&4 z2NcTJe-HgFjNg-gZ$6!Y`SMHrlj}Etf7?r!zQTPPSv}{so2e>Fjs1{gzk~LGeesX%r(Lh6rbhSo_n)@@G-FTQy93;l#E)hgP@d_SGvyCp0~o(Y;Ee8{ zdVUDbHm5`2taPUOY^MAGOw*>=s7=Gst=D+p+2yON!0%Hk` zz5mAhyT4lS*T3LS^WSxUy86q&GnoHxzQ6vm8)VS}_zuqG?+3td68_x;etQAdu@sc6 zQJ&5|4(I?~3d-QOAODHpZ=hlSg(lBZ!JZWCtHHSj`0Wh93-Uk)_S%zsJ~aD>{`A0~ z9{AG(e|q3g5B%wYKRxiL2Y$8(4w6bzchKuloQW#e&S3n+P- z8!ds-%f;TJ1>)v)##>gd{PdS2Oc3VaR`fr=`O8QIO(6(N!A?pr5C#6fc~Ge@N%Vvu zaoAX2&(a6eWy_q&UwOhU)|P3J0Qc%OdhzW=F4D|pt0E4osw;%<%Dn58hAWD^XnZD= z>9~H(3bmLtxpF?a7su6J7M*x1By7YSUbxGi)Ot0P77`}P3{)&5Un{KD?`-e?r21!4vTTnN(4Y6Lin?UkSM z`MXCTC1@4A4~mvz%Rh2&EwY))LeoT=*`tMoqcEXI>TZU9WTP#l?uFv+@Dn~b(>xh2 z;>B?;Tz2SR&KVb>vGiBSB`@U7VIWFSo=LDSb9F{GF^DbmWAfpms8Sx9OX4CnBJca3 zlj9(x!dIjN?OG1X4l*imJNvRCk}F%!?SOfiOq5y^mZW)jFL@a|r-@d#f7 z2gmU8L3IZq0ynIws=}~m^#@&C%J6QFo~Mo4V`>v7MI-_!EBMMtb%_M&kvAaN)@ZVw z+`toz&WG#HkWDjnZE!6nk{e-oFdL^$YnbOCN}JC&{$#$O27@|Tn-skXr)2ml2~O!5 zX+gYoxhoc7qoU?C^3~&!U?kRFtnSEecWuH0B0OvLodgUAi}8p1 zrO6RSXHH}DMc$&|?D004DiOVMHV8kXCP@7NKB zgaZq^^O<7PoKEp72kby@W0Z!Y*Ay{&vfg#C&gG@YVR9g?FEocMUi1gSN$+V+ayF45{a zuDZDTN}mS|;BO%gEf}pjBfN2-gIrU#G5~cucA;dokXW89%>AyXJJI z9X4UlIWA|ZYHgbI z5?oFk@A=Ik7lrEQPDH!H+b`7_Y~aDb_qa=B2^Y&Ow41cU=4WDd40dp5(QS-WMN-=Y z9g;6_-JdNU;|6cPwf$ak*aJIcwL@1n$#l~zi{c{EW?T;DaW*E8DYq?Umtz{nJ&w-M zEMyTDrC&9K$d|kZe2#ws6)L=7K+{ zQw{XnV6UC$6-rW0emqm8wJoeZK)wJIcV?dST}Z;G0Arq{dVDu0&4kd%N!3F1*;*pW zR&qUiFzK=@44#QGw7k1`3t_d8&*kBV->O##t|tonFc2YWrL7_eqg+=+k;!F-`^b8> z#KWCE8%u4k@EprxqiV$VmmtiWxDLgnGu$Vs<8rppV5EajBXL4nyyZM$SWVm!wnCj-B!Wjqj5-5dNXukI2$$|Bu3Lrw}z65Lc=1G z^-#WuQOj$hwNGG?*CM_TO8Bg-1+qc>J7k5c51U8g?ZU5n?HYor;~JIjoWH-G>AoUP ztrWWLbRNqIjW#RT*WqZgPJXU7C)VaW5}MiijYbABmzoru6EmQ*N8cVK7a3|aOB#O& zBl8JY2WKfmj;h#Q!pN%9o@VNLv{OUL?rixHwOZuvX7{IJ{(EdPpuVFoQqIOa7giLVkBOKL@^smUA!tZ1CKRK}#SSM)iQHk)*R~?M!qkCruaS!#oIL1c z?J;U~&FfH#*98^G?i}pA{ z9Jg36t4=%6mhY(quYq*vSxptes9qy|7xSlH?G=S@>u>Ebe;|LVhs~@+06N<4CViBk zUiY$thvX;>Tby6z9Y1edAMQaiH zm^r3v#$Q#2T=X>bsY#D%s!bhs^M9PMAcHbCc0FMHV{u-dwlL;a1eJ63v5U*?Q_8JO zT#50!RD619#j_Uf))0ooADz~*9&lN!bBDRUgE>Vud-i5ck%vT=r^yD*^?Mp@Q^v+V zG#-?gKlr}Eeqifb{|So?HM&g91P8|av8hQoCmQXkd?7wIJwb z_^v8bbg`SAn{I*4bH$u(RZ6*xUhuA~hc=8czK8SHEKTzSxgbwi~9(OqJB&gwb^l4+m`k*Q;_?>Y-APi1{k zAHQ)P)G)f|AyjSgcCFps)Fh6Bca*Xznq36!pV6Az&m{O8$wGFD? zY&O*3*J0;_EqM#jh6^gMQKpXV?#1?>$ml1xvh8nSN>-?H=V;nJIwB07YX$e6vLxH( zqYwQ>qxwR(i4f)DLd)-$P>T-no_c!LsN@)8`e;W@)-Hj0>nJ-}Kla4-ZdPJzI&Mce zv)V_j;(3ERN3_@I$N<^|4Lf`B;8n+bX@bHbcZTopEmDI*Jfl)-pFDvo6svPRoo@(x z);_{lY<;);XzT`dBFpRmGrr}z5u1=pC^S-{ce6iXQlLGcItwJ^mZx{m$&DA_oEZ)B{_bYPq-HA zcH8WGoBG(aBU_j)vEy+_71T34@4dmSg!|M8Vf92Zj6WH7Q7t#OHQqWgFE3ARt+%!T z?oLovLVlnf?2c7pTc)~cc^($_8nyKwsN`RA-23ed3sdj(ys%pjjM+9JrctL;dy8a( z@en&CQmnV(()bu|Y%G1-4a(6x{aLytn$T-;(&{QIJB9vMox11U-1HpD@d(QkaJdEb zG{)+6Dos_L+O3NpWo^=gR?evp|CqEG?L&Ut#D*KLaRFOgOEK(Kq1@!EGcTfo+%A&I z=dLbB+d$u{sh?u)xP{PF8L%;YPPW53+@{>5W=Jt#wQpN;0_HYdw1{ksf_XhO4#2F= zyPx6Lx2<92L-;L5PD`zn6zwIH`Jk($?Qw({erA$^bC;q33hv!d!>%wRhj# zal^hk+WGNg;rJtb-EB(?czvOM=H7dl=vblBwAv>}%1@{}mnpUznfq1cE^sgsL0*4I zJ##!*B?=vI_OEVis5o+_IwMIRrpQyT_Sq~ZU%oY7c5JMIADzpD!Upz9h@iWg_>>~j zOLS;wp^i$-E?4<_cp?RiS%Rd?i;f*mOz=~(&3lo<=@(nR!_Rqiprh@weZlL!t#NCc zO!QTcInq|%#>OVgobj{~ixEUec`E25zJ~*DofsQdzIa@5^nOXj2T;8O`l--(QyU^$t?TGY^7#&FQ+2SS3B#qK*k3`ye?8jUYSajE5iBbJls75CCc(m3dk{t?- zopcER9{Z?TC)mk~gpi^kbbu>b-+a{m#8-y2^p$ka4n60w;Sc2}HMf<8JUvhCL0B&Btk)T`ctE$*qNW8L$`7!r^9T+>=<=2qaq-;ll2{`{Rg zc5a0ZUI$oG&j-qVOuKa=*v4aY#IsoM+1|c4Z)<}lEDvy;5huB@1RJPquU2U*U-;gu z=En2m+qjBzR#DEJDO`WU)hdd{Vj%^0V*KoyZ|5lzV87&g_j~NCjwv0uQVqXOb*QrQ zy|Qn`hxx(58c70$E;L(X0uZZ72M1!6oeg)(cdKO ze0gDaTz+ohR-#d)NbAH4x{I(21yjwvBQfmpLu$)|m{XolbgF!pmsqJ#D}(ylp6uC> z{bqtcI#hT#HW=wl7>p!38sKsJ`r8}lt-q%Keqy%u(xk=yiIJiUw6|5IvkS+#?JTBl z8H5(Q?l#wzazujH!8o>1xtn8#_w+397*_cy8!pQGP%K(Ga3pAjsaTbbXJlQF_+m+-UpUUent@xM zg%jqLUExj~o^vQ3Gl*>wh=_gOr2*|U64_iXb+-111aH}$TjeajM+I20xw(((>fej-@CIz4S1pi$(#}P7`4({6QS2CaQS4NPENDp>sAqD z$bH4KGzXGffkJ7R>V>)>tC)uax{UsN*dbeNC*v}#8Y#OWYwL4t$ePR?VTyIs!wea+ z5Urmc)X|^`MG~*dS6pGSbU+gPJoq*^a=_>$n4|P^w$sMBBy@f*Z^Jg6?n5?oId6f{ z$LW4M|4m502z0t7g<#Bx%X;9<=)smFolV&(V^(7Cv2-sxbxopQ!)*#ZRhTBpx1)Fc zNm1T%bONzv6@#|dz(w02AH8OXe>kQ#1FMCzO}2J_mST)+ExmBr9cva-@?;wnmWMOk z{3_~EX_xadgJGv&H@zK_8{(x84`}+c?oSBX*Ge3VdfTt&F}yCpFP?CpW+BE^cWY0^ zb&uBN!Ja3UzYHK-CTyA5=L zEMW{l3Usky#ly=7px648W31UNV@K)&Ub&zP1c7%)`{);I4b0Q<)B}3;NMG2JH=X$U zfIW4)4n9ZM`-yRj67I)YSLDK)qfUJ_ij}a#aZN~9EXrh8eZY2&=uY%2N0UFF7<~%M zsB8=erOWZ>Ct_#^tHZ|*q`H;A)5;ycw*IcmVxi8_0Xk}aJA^ath+E;xg!x+As(M#0=)3!NJR6H&9+zd#iP(m0PIW8$ z1Y^VX`>jm`W!=WpF*{ioM?C9`yOR>@0q=u7o>BP-eSHqCgMDj!2anwH?s%i2p+Q7D zzszIf5XJpE)IG4;d_(La-xenmF(tgAxK`Y4sQ}BSJEPs6N_U2vI{8=0C_F?@7<(G; zo$~G=8p+076G;`}>{MQ>t>7cm=zGtfbdDXm6||jUU|?X?CaE?(<6bKDYKeHlz}DA8 zXT={X=yp_R;HfJ9h%?eWvQ!dRgz&Su*JfNt!Wu>|XfU&68iRikRrHRW|ZxzRR^`eIGt zIeiDgVS>IeExKVRWW8-=A=yA`}`)ZkWBrZD`hpWIxBGkh&f#ijr449~m`j6{4jiJ*C!oVA8ZC?$1RM#K(_b zL9TW)kN*Y4%^-qPpMP7d4)o?Nk#>aoYHT(*g)qmRUb?**F@pnNiy6Fv9rEiUqD(^O zzyS?nBrX63BTRYduaG(0VVG2yJRe%o&rVrLjbxTaAFTd8s;<<@Qs>u(<193R8>}2_ zuwp{7;H2a*X7_jryzriZXMg?bTuegABb^87@SsKkr2)0Gyiax8KQWstw^v#ix45EVrcEhr>!NMhprl$InQMzjSFH54x5k9qHc`@9uKQzvL4ihcq{^B zPrVR=o_ic%Y>6&rMN)hTZsI7I<3&`#(nl+3y3ys9A~&^=4?PL&nd8)`OfG#n zwAMN$1&>K++c{^|7<4P=2y(B{jJsQ0a#U;HTo4ZmWZYvI{+s;Td{Yzem%0*k#)vjpB zia;J&>}ICate44SFYY3vEelqStQWFihx%^vQ@Do(sOy7yR2@WNv7Y9I^yL=nZr3mb zXKV5t@=?-Sk|b{XMhA7ZGB@2hqsx}4xwCW!in#C zI@}scZlr3-NFJ@NFaJlhyfcw{k^vvtGl`N9xSo**rDW4S}i zM9{fMPWo%4wYDG~BZ18BD+}h|GQKc-g^{++3MY>}W_uq7jGHx{mwE9fZiPCoxN$+7 zrODGGJrOkcPQUB(FD5aoS4g~7#6NR^ma7-!>mHuJfY5kTe6PpNNKC9GGRiu^L31uG z$7v`*JknQHsYB!Tm_W{a32TM099djW%5e+j0Ve_ct}IM>XLF1Ap+YvcrLV=|CKo6S zb+9Nl3_YdKP6%Cxy@6TxZ>;4&nTneadr z_ES90ydCev)LV!dN=#(*f}|ZORFdvkYBni^aLbUk>BajeWIOcmHP#8S)*2U~QKI%S zyrLmtPqb&TphJ;>yAxri#;{uyk`JJqODDw%(Z=2`1uc}br^V%>j!gS)D*q*f_-qf8&D;W1dJgQMlaH5er zN2U<%Smb7==vE}dDI8K7cKz!vs^73o9f>2sgiTzWcwY|BMYHH5%Vn7#kiw&eItCqa zIkR2~Q}>X=Ar8W|^Ms41Fm8o6IB2_j60eOeBB1Br!boW7JnoeX6Gs)?7rW0^5psc- zjS16yb>dFn>KPOF;imD}e!enuIniFzv}n$m2#gCCv4jM#ArwlzZ$7@9&XkFxZ4n!V zj3dyiwW4Ki2QG{@i>yuZXQizw_OkZI^-3otXC{!(lUpJF33gI60ak;Uqitp74|B6I zgg{b=Iz}WkhCGj1M=hu4#Aw173YxIVbISaoc z-nLZC*6Tgivd5V`K%GxhBsp@SUU60-rfc$=wb>zdJzXS&-5(NRRodFk;Kxk!S(O(a0e7oY=E( zAyS;Ow?6Q&XA+cnkCb{28_1N8H#?J!*$MmIwLq^*T_9-z^&UE@A(z9oGYtFy6EZef LrJugUA?W`A8`#=m literal 0 HcmV?d00001 diff --git a/ui/app/globals.css b/ui/app/globals.css new file mode 100644 index 00000000..d371ca42 --- /dev/null +++ b/ui/app/globals.css @@ -0,0 +1,249 @@ +@import "tailwindcss"; + +/* ─── APEX Design Tokens ────────────────────────────────────────── */ +:root { + /* Backgrounds */ + --bg-base: #040C1A; + --bg-surface: #070F1C; + --bg-card: #0C1628; + --bg-elevated: #121E30; + --bg-hover: #182338; + --bg-active: #1E2E42; + --bg-sidebar: #030810; + + /* Borders */ + --border: rgba(82, 122, 196, 0.10); + --border-raised: rgba(82, 122, 196, 0.18); + --border-active: rgba(68, 128, 255, 0.40); + --border-accent: rgba(68, 128, 255, 0.60); + + /* Text */ + --text-high: #E0E8FF; + --text-mid: #7A8FAD; + --text-low: #354869; + --text-faint: #1C2A40; + + /* Accent Blue */ + --accent: #4480FF; + --accent-light: #8AAFFF; + --accent-dim: #1A3A88; + --accent-glow: rgba(68, 128, 255, 0.14); + --accent-glow2: rgba(68, 128, 255, 0.06); + + /* Semantic */ + --buy: #00CE68; + --buy-bg: rgba(0, 206, 104, 0.08); + --buy-ring: rgba(0, 206, 104, 0.25); + --sell: #FF3355; + --sell-bg: rgba(255, 51, 85, 0.08); + --sell-ring:rgba(255, 51, 85, 0.25); + --hold: #F59E0B; + --hold-bg: rgba(245, 158, 11, 0.08); + --hold-ring:rgba(245, 158, 11, 0.25); + --error: #FF4444; + --error-bg: rgba(255, 68, 68, 0.08); + + /* Status */ + --status-running: #F59E0B; + --status-done: #4480FF; + --status-pending: #1C2A40; +} + +/* ─── Animations ─────────────────────────────────────────────────── */ +@keyframes fadeUp { + from { opacity: 0; transform: translateY(10px); } + to { opacity: 1; transform: translateY(0); } +} + +@keyframes fadeIn { + from { opacity: 0; } + to { opacity: 1; } +} + +@keyframes shimmer { + 0%, 100% { opacity: 0.35; } + 50% { opacity: 0.9; } +} + +@keyframes spin-slow { + to { transform: rotate(360deg); } +} + +@keyframes pulse-glow { + 0%, 100% { box-shadow: 0 0 0 0 var(--accent-glow); } + 50% { box-shadow: 0 0 0 6px var(--accent-glow); } +} + +@keyframes scan-line { + from { transform: translateX(-100%); } + to { transform: translateX(200%); } +} + +/* ─── Base ───────────────────────────────────────────────────────── */ +*, *::before, *::after { box-sizing: border-box; } + +html, body { + background-color: var(--bg-base); + color: var(--text-high); + font-family: var(--font-manrope, 'Manrope'), sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + font-feature-settings: "cv02", "cv03", "cv04", "cv11"; +} + +/* ─── Typography ─────────────────────────────────────────────────── */ +.apex-display { + font-family: var(--font-manrope, 'Manrope'), sans-serif; + font-weight: 700; + letter-spacing: -0.03em; + color: var(--text-high); +} + +.apex-label { + font-size: 10px; + font-weight: 600; + letter-spacing: 0.12em; + text-transform: uppercase; + color: var(--text-mid); + font-family: var(--font-manrope, 'Manrope'), sans-serif; +} + +/* ─── Cards ──────────────────────────────────────────────────────── */ +.apex-card { + background: var(--bg-card); + border: 1px solid var(--border); + border-radius: 10px; +} + +.apex-card-elevated { + background: var(--bg-elevated); + border: 1px solid var(--border-raised); + border-radius: 10px; +} + +/* ─── Buttons ────────────────────────────────────────────────────── */ +.btn-primary { + position: relative; + overflow: hidden; + display: inline-flex; + align-items: center; + gap: 6px; + background: var(--accent); + color: #fff; + font-weight: 600; + font-size: 13px; + letter-spacing: 0.01em; + border-radius: 8px; + padding: 9px 20px; + transition: background 0.15s, opacity 0.15s, box-shadow 0.15s; + font-family: var(--font-manrope, 'Manrope'), sans-serif; + cursor: pointer; +} +.btn-primary::after { + content: ''; + position: absolute; + inset: 0; + background: linear-gradient(135deg, rgba(255,255,255,0.12) 0%, transparent 60%); + pointer-events: none; +} +.btn-primary:hover { + background: #5590FF; + box-shadow: 0 4px 16px rgba(68,128,255,0.35); +} +.btn-primary:active { opacity: 0.85; } +.btn-primary:disabled { + opacity: 0.35; + cursor: not-allowed; + box-shadow: none; +} + +.btn-secondary { + display: inline-flex; + align-items: center; + gap: 6px; + background: var(--bg-elevated); + color: var(--text-mid); + font-weight: 500; + font-size: 13px; + border: 1px solid var(--border-raised); + border-radius: 8px; + padding: 8px 16px; + transition: background 0.15s, color 0.15s, border-color 0.15s; + font-family: var(--font-manrope, 'Manrope'), sans-serif; + cursor: pointer; +} +.btn-secondary:hover { + background: var(--bg-hover); + color: var(--text-high); + border-color: var(--border-active); +} + +/* backwards compat aliases */ +.btn-ghost { @apply btn-secondary; } + +/* ─── Inputs ─────────────────────────────────────────────────────── */ +.vault-input { + width: 100%; + background: var(--bg-elevated); + color: var(--text-high); + font-size: 13px; + border: 1px solid var(--border-raised); + border-radius: 6px; + padding: 9px 12px; + outline: none; + transition: border-color 0.15s, background 0.15s, box-shadow 0.15s; + font-family: var(--font-manrope, 'Manrope'), sans-serif; +} +.vault-input::placeholder { color: var(--text-low); } +.vault-input:focus { + border-color: var(--border-active); + background: var(--bg-hover); + box-shadow: 0 0 0 3px var(--accent-glow); +} +.vault-input option { background: var(--bg-elevated); } + +/* ─── Badges ─────────────────────────────────────────────────────── */ +.badge-buy { + display: inline-flex; align-items: center; + background: var(--buy-bg); + color: var(--buy); + border: 1px solid var(--buy-ring); + font-size: 11px; font-weight: 700; + padding: 2px 9px; border-radius: 99px; + letter-spacing: 0.04em; + font-family: var(--font-manrope, 'Manrope'), sans-serif; +} +.badge-sell { + display: inline-flex; align-items: center; + background: var(--sell-bg); + color: var(--sell); + border: 1px solid var(--sell-ring); + font-size: 11px; font-weight: 700; + padding: 2px 9px; border-radius: 99px; + letter-spacing: 0.04em; + font-family: var(--font-manrope, 'Manrope'), sans-serif; +} +.badge-hold { + display: inline-flex; align-items: center; + background: var(--hold-bg); + color: var(--hold); + border: 1px solid var(--hold-ring); + font-size: 11px; font-weight: 700; + padding: 2px 9px; border-radius: 99px; + letter-spacing: 0.04em; + font-family: var(--font-manrope, 'Manrope'), sans-serif; +} + +/* ─── Scrollbar ──────────────────────────────────────────────────── */ +::-webkit-scrollbar { width: 5px; height: 5px; } +::-webkit-scrollbar-track { background: transparent; } +::-webkit-scrollbar-thumb { background: var(--border-raised); border-radius: 99px; } +::-webkit-scrollbar-thumb:hover { background: var(--border-active); } + +/* ─── Selection ──────────────────────────────────────────────────── */ +::selection { background: var(--accent-glow); color: var(--text-high); } + +/* ─── Fade animations for components ────────────────────────────── */ +.animate-fade-up { animation: fadeUp 0.3s ease-out both; } +.animate-fade-in { animation: fadeIn 0.25s ease-out both; } +.animate-shimmer { animation: shimmer 1.6s ease-in-out infinite; } diff --git a/ui/app/layout.tsx b/ui/app/layout.tsx new file mode 100644 index 00000000..176faeab --- /dev/null +++ b/ui/app/layout.tsx @@ -0,0 +1,35 @@ +import type { Metadata } from 'next' +import { Manrope, Inter } from 'next/font/google' +import './globals.css' + +const manrope = Manrope({ + variable: '--font-manrope', + subsets: ['latin'], + weight: ['400', '500', '600', '700', '800'], +}) + +const inter = Inter({ + variable: '--font-inter', + subsets: ['latin'], + weight: ['400', '500', '600'], +}) + +export const metadata: Metadata = { + title: 'TradingAgents', + description: 'Multi-agent trading analysis', +} + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode +}>) { + return ( + + {children} + + ) +} diff --git a/ui/app/page.tsx b/ui/app/page.tsx new file mode 100644 index 00000000..85a40e96 --- /dev/null +++ b/ui/app/page.tsx @@ -0,0 +1,5 @@ +import { redirect } from 'next/navigation' + +export default function Home() { + redirect('/new-run') +} diff --git a/ui/components/Sidebar.tsx b/ui/components/Sidebar.tsx new file mode 100644 index 00000000..d8d7a4a8 --- /dev/null +++ b/ui/components/Sidebar.tsx @@ -0,0 +1,154 @@ +'use client' +import Link from 'next/link' +import { usePathname } from 'next/navigation' + +const NAV = [ + { + href: '/new-run', + label: 'New Analysis', + icon: ( + + + + + ), + }, + { + href: '/history', + label: 'Run History', + icon: ( + + + + + + ), + }, + { + href: '/settings', + label: 'Settings', + icon: ( + + + + + ), + }, +] + +export default function Sidebar() { + const path = usePathname() + + return ( + + ) +} diff --git a/ui/eslint.config.mjs b/ui/eslint.config.mjs new file mode 100644 index 00000000..05e726d1 --- /dev/null +++ b/ui/eslint.config.mjs @@ -0,0 +1,18 @@ +import { defineConfig, globalIgnores } from "eslint/config"; +import nextVitals from "eslint-config-next/core-web-vitals"; +import nextTs from "eslint-config-next/typescript"; + +const eslintConfig = defineConfig([ + ...nextVitals, + ...nextTs, + // Override default ignores of eslint-config-next. + globalIgnores([ + // Default ignores of eslint-config-next: + ".next/**", + "out/**", + "build/**", + "next-env.d.ts", + ]), +]); + +export default eslintConfig; diff --git a/ui/features/history/components/RunHistoryTable.tsx b/ui/features/history/components/RunHistoryTable.tsx new file mode 100644 index 00000000..e6ab6391 --- /dev/null +++ b/ui/features/history/components/RunHistoryTable.tsx @@ -0,0 +1,122 @@ +import Link from 'next/link' +import type { RunSummary } from '@/lib/types/run' + +type Props = { runs: RunSummary[] } + +function DecisionBadge({ decision }: { decision: string }) { + const lower = decision.toLowerCase() + if (lower === 'buy') return {decision} + if (lower === 'sell') return {decision} + if (lower === 'hold') return {decision} + return ( + + {decision} + + ) +} + +export default function RunHistoryTable({ runs }: Props) { + if (runs.length === 0) { + return ( +
+

+ No runs yet. Start a new analysis. +

+
+ ) + } + return ( +
+ + + + + + + + + + + {runs.map((run) => ( + + (e.currentTarget.style.backgroundColor = 'var(--bg-hover)') + } + onMouseLeave={(e) => + (e.currentTarget.style.backgroundColor = '') + } + > + + + + + + + ))} + +
+ Ticker + + Date + + Decision + + Created + +
+ {run.ticker} + + {run.date} + + {run.decision ? ( + + ) : ( + — + )} + + {new Date(run.created_at).toLocaleString()} + + + (e.currentTarget.style.color = 'var(--accent-light)') + } + onMouseLeave={(e) => + (e.currentTarget.style.color = 'var(--accent)') + } + > + View Report → + +
+
+ ) +} diff --git a/ui/features/history/hooks/useRunHistory.ts b/ui/features/history/hooks/useRunHistory.ts new file mode 100644 index 00000000..f4397f1c --- /dev/null +++ b/ui/features/history/hooks/useRunHistory.ts @@ -0,0 +1,19 @@ +'use client' +import { useEffect, useState } from 'react' +import { listRuns } from '@/lib/api-client' +import type { RunSummary } from '@/lib/types/run' + +export function useRunHistory() { + const [runs, setRuns] = useState([]) + const [loading, setLoading] = useState(true) + const [error, setError] = useState(null) + + useEffect(() => { + listRuns() + .then(setRuns) + .catch((e) => setError(e.message)) + .finally(() => setLoading(false)) + }, []) + + return { runs, loading, error } +} diff --git a/ui/features/new-run/components/AnalystSelector.tsx b/ui/features/new-run/components/AnalystSelector.tsx new file mode 100644 index 00000000..cb0c8b30 --- /dev/null +++ b/ui/features/new-run/components/AnalystSelector.tsx @@ -0,0 +1,103 @@ +'use client' + +const ANALYSTS = [ + { + id: 'market', + label: 'Market', + full: 'Market Analyst', + desc: 'Price action & technicals', + dot: '#4480FF', + }, + { + id: 'news', + label: 'News', + full: 'News Analyst', + desc: 'Sentiment & headlines', + dot: '#A78BFA', + }, + { + id: 'fundamentals', + label: 'Fundamentals', + full: 'Fundamentals Analyst', + desc: 'Earnings & financials', + dot: '#00CE68', + }, + { + id: 'social', + label: 'Social', + full: 'Social Analyst', + desc: 'Social media signals', + dot: '#F59E0B', + }, +] + +type Props = { + selected: string[] + onChange: (selected: string[]) => void +} + +export default function AnalystSelector({ selected, onChange }: Props) { + const toggle = (id: string) => { + onChange(selected.includes(id) ? selected.filter((s) => s !== id) : [...selected, id]) + } + + return ( +
+ {ANALYSTS.map(({ id, label, desc, dot, full }) => { + const active = selected.includes(id) + return ( + + ) + })} +
+ ) +} diff --git a/ui/features/new-run/components/RunConfigForm.tsx b/ui/features/new-run/components/RunConfigForm.tsx new file mode 100644 index 00000000..12eb0197 --- /dev/null +++ b/ui/features/new-run/components/RunConfigForm.tsx @@ -0,0 +1,279 @@ +'use client' +import { useState } from 'react' +import AnalystSelector from './AnalystSelector' +import { useRunSubmit } from '../hooks/useRunSubmit' +import { DEFAULT_FORM } from '../types' +import type { NewRunFormState } from '../types' + +function SectionHeader({ step, title, subtitle }: { step: number; title: string; subtitle?: string }) { + return ( +
+
+ {step} +
+
+
+ {title} +
+ {subtitle && ( +
+ {subtitle} +
+ )} +
+
+ ) +} + +export default function RunConfigForm() { + const [form, setForm] = useState(DEFAULT_FORM) + const { submit, loading, error } = useRunSubmit() + const set = (k: keyof NewRunFormState, v: unknown) => + setForm((f) => ({ ...f, [k]: v })) + + return ( +
{ e.preventDefault(); submit(form) }} + className="space-y-3" + > + {/* Error banner */} + {error && ( +
+ {error} +
+ )} + + {/* ── Section 1: Target ──────────────────────────────────────── */} +
+ +
+
+ + set('ticker', e.target.value.toUpperCase())} + required + /> +
+
+ + set('date', e.target.value)} + required + /> +
+
+
+ + {/* ── Section 2: Model ───────────────────────────────────────── */} +
+ +
+
+ + +
+
+
+ + set('deep_think_llm', e.target.value)} + /> +
+
+ + set('quick_think_llm', e.target.value)} + /> +
+
+ + set('max_debate_rounds', Number(e.target.value))} + /> +
+
+ + set('max_risk_discuss_rounds', Number(e.target.value))} + /> +
+
+
+ + {/* ── Section 3: Analysts ────────────────────────────────────── */} +
+ + set('enabled_analysts', v)} + /> +
+ + {/* ── Submit ──────────────────────────────────────────────────── */} +
+

+ Analysis takes 2–5 minutes depending on model and configuration. +

+ +
+
+ ) +} diff --git a/ui/features/new-run/hooks/useRunSubmit.ts b/ui/features/new-run/hooks/useRunSubmit.ts new file mode 100644 index 00000000..39543710 --- /dev/null +++ b/ui/features/new-run/hooks/useRunSubmit.ts @@ -0,0 +1,26 @@ +'use client' +import { useState } from 'react' +import { useRouter } from 'next/navigation' +import { createRun } from '@/lib/api-client' +import type { NewRunFormState } from '../types' + +export function useRunSubmit() { + const router = useRouter() + const [loading, setLoading] = useState(false) + const [error, setError] = useState(null) + + const submit = async (form: NewRunFormState) => { + setLoading(true) + setError(null) + try { + const run = await createRun(form) + router.push(`/runs/${run.id}`) + } catch (e) { + setError(e instanceof Error ? e.message : 'Failed to start run') + } finally { + setLoading(false) + } + } + + return { submit, loading, error } +} diff --git a/ui/features/new-run/types.ts b/ui/features/new-run/types.ts new file mode 100644 index 00000000..88bef434 --- /dev/null +++ b/ui/features/new-run/types.ts @@ -0,0 +1,21 @@ +export type NewRunFormState = { + ticker: string + date: string + llm_provider: string + deep_think_llm: string + quick_think_llm: string + max_debate_rounds: number + max_risk_discuss_rounds: number + enabled_analysts: string[] +} + +export const DEFAULT_FORM: NewRunFormState = { + ticker: '', + date: '', + llm_provider: 'openai', + deep_think_llm: 'gpt-5.2', + quick_think_llm: 'gpt-5-mini', + max_debate_rounds: 1, + max_risk_discuss_rounds: 1, + enabled_analysts: ['market', 'news', 'fundamentals', 'social'], +} diff --git a/ui/features/run-detail/components/AnalystReports.tsx b/ui/features/run-detail/components/AnalystReports.tsx new file mode 100644 index 00000000..7f4be69b --- /dev/null +++ b/ui/features/run-detail/components/AnalystReports.tsx @@ -0,0 +1,227 @@ +import { AGENT_STEPS, AGENT_STEP_LABELS, STEP_PHASE } from '@/lib/types/run' +import type { AgentStep } from '@/lib/types/run' +import type { StepStatus } from '@/lib/types/agents' + +type Phase = 'analysts' | 'researchers' | 'trader' | 'risk' + +const MULTI_TURN_STEPS = new Set([ + 'bull_researcher', 'bear_researcher', + 'aggressive_analyst', 'conservative_analyst', 'neutral_analyst', +]) + +// Color accent per step for visual differentiation +const STEP_ACCENT: Record = { + market_analyst: '#4480FF', + news_analyst: '#A78BFA', + fundamentals_analyst: '#00CE68', + social_analyst: '#F59E0B', + bull_researcher: '#00CE68', + bear_researcher: '#FF3355', + research_manager: '#4480FF', + trader: '#F59E0B', + aggressive_analyst: '#FF3355', + conservative_analyst: '#4480FF', + neutral_analyst: '#A78BFA', + risk_judge: '#F59E0B', +} + +type Props = { + phase: Phase + steps: Record + reports: Record +} + +export default function AnalystReports({ phase, steps, reports }: Props) { + const phaseSteps = AGENT_STEPS.filter((s) => STEP_PHASE[s] === phase) + + return ( +
+ {phaseSteps.map((step) => { + const stepStatus = steps[step] ?? 'pending' + const turns = reports[step] ?? [] + const isRunning = stepStatus === 'running' + const isDone = stepStatus === 'done' + const isMulti = MULTI_TURN_STEPS.has(step) + const accent = STEP_ACCENT[step] + + return ( +
+ {/* ── Completed turns ─────────────────────────────── */} + {turns.map((report, i) => ( +
+ {/* Header */} +
+
+
+ + {AGENT_STEP_LABELS[step]} + + {isMulti && ( + + Turn {i + 1} + + )} +
+
+
+ Done +
+
+ + {/* Report text */} +

+ {report} +

+
+ ))} + + {/* ── Running spinner ──────────────────────────────── */} + {isRunning && ( +
+
+
+
+ + {AGENT_STEP_LABELS[step]} + + {isMulti && turns.length > 0 && ( + + Turn {turns.length + 1} + + )} +
+
+
+ Analyzing +
+
+ + {/* Shimmer lines */} +
+
+
+
+
+
+ )} + + {/* ── Pending placeholder ──────────────────────────── */} + {turns.length === 0 && !isRunning && ( +
+
+
+
+ + {AGENT_STEP_LABELS[step]} + +
+ + Queued + +
+
+
+ )} +
+ ) + })} +
+ ) +} diff --git a/ui/features/run-detail/components/DebateView.tsx b/ui/features/run-detail/components/DebateView.tsx new file mode 100644 index 00000000..75d5458e --- /dev/null +++ b/ui/features/run-detail/components/DebateView.tsx @@ -0,0 +1,32 @@ +type Props = { content: string; speakerA: string; speakerB: string } + +export default function DebateView({ content, speakerA, speakerB }: Props) { + if (!content) { + return

Waiting for debate to complete…

+ } + const turns = content.split(/\n{2,}/).filter(Boolean) + return ( +
+ {turns.map((turn, i) => { + const isA = i % 2 === 0 + return ( +
+
+ {isA ? speakerA : speakerB} +
+

{turn}

+
+ ) + })} +
+ ) +} diff --git a/ui/features/run-detail/components/PhaseTabs.tsx b/ui/features/run-detail/components/PhaseTabs.tsx new file mode 100644 index 00000000..e2a1a237 --- /dev/null +++ b/ui/features/run-detail/components/PhaseTabs.tsx @@ -0,0 +1,91 @@ +'use client' +import { useState } from 'react' +import { AGENT_STEPS, STEP_PHASE } from '@/lib/types/run' +import type { AgentStep } from '@/lib/types/run' +import type { StepStatus } from '@/lib/types/agents' +import AnalystReports from './AnalystReports' + +type Phase = 'analysts' | 'researchers' | 'trader' | 'risk' + +const TABS: { label: string; phase: Phase; desc: string }[] = [ + { label: 'Analysts', phase: 'analysts', desc: '4 agents' }, + { label: 'Researchers', phase: 'researchers', desc: '3 agents' }, + { label: 'Trader', phase: 'trader', desc: '1 agent' }, + { label: 'Risk', phase: 'risk', desc: '4 agents' }, +] + +type Props = { + steps: Record + reports: Record +} + +function getPhaseCompletion(phase: Phase, steps: Record): number { + const phaseSteps = AGENT_STEPS.filter((s) => STEP_PHASE[s] === phase) + const done = phaseSteps.filter((s) => steps[s as AgentStep] === 'done').length + return phaseSteps.length > 0 ? Math.round((done / phaseSteps.length) * 100) : 0 +} + +export default function PhaseTabs({ steps, reports }: Props) { + const [active, setActive] = useState('analysts') + + return ( +
+ {/* Section label */} +
+ Agent Reports +
+ + {/* Tab bar */} +
+ {TABS.map(({ label, phase }) => { + const isActive = active === phase + const completion = getPhaseCompletion(phase, steps) + const allDone = completion === 100 + + return ( + + ) + })} +
+ + {/* Reports */} + +
+ ) +} diff --git a/ui/features/run-detail/components/PipelineStepper.tsx b/ui/features/run-detail/components/PipelineStepper.tsx new file mode 100644 index 00000000..8cd0539b --- /dev/null +++ b/ui/features/run-detail/components/PipelineStepper.tsx @@ -0,0 +1,136 @@ +import { AGENT_STEPS, STEP_PHASE } from '@/lib/types/run' +import type { AgentStep } from '@/lib/types/run' +import type { StepStatus } from '@/lib/types/agents' + +type Phase = 'analysts' | 'researchers' | 'trader' | 'risk' +type Props = { steps: Record } + +const PHASES: Phase[] = ['analysts', 'researchers', 'trader', 'risk'] +const PHASE_LABELS: Record = { + analysts: 'Analysts', researchers: 'Researchers', trader: 'Trader', risk: 'Risk', +} +const PHASE_NUMS: Record = { + analysts: '01', researchers: '02', trader: '03', risk: '04', +} + +function phaseStatus(phase: Phase, steps: Record): StepStatus { + const phaseSteps = AGENT_STEPS.filter((s) => STEP_PHASE[s as AgentStep] === phase) + if (phaseSteps.every((s) => steps[s] === 'done')) return 'done' + if (phaseSteps.some((s) => steps[s] === 'running')) return 'running' + return 'pending' +} + +export default function PipelineStepper({ steps }: Props) { + return ( +
+
+ Pipeline +
+
+ {PHASES.map((phase, i) => { + const status = phaseStatus(phase, steps) + const isDone = status === 'done' + const isRunning = status === 'running' + const isPending = status === 'pending' + + return ( +
+ {/* Step node */} +
+ {/* Circle */} +
+ {isDone ? ( + + + + ) : isRunning ? ( +
+ ) : ( + + {PHASE_NUMS[phase]} + + )} +
+ + {/* Label */} + + {PHASE_LABELS[phase]} + +
+ + {/* Connector */} + {i < PHASES.length - 1 && ( +
+ {isRunning && ( +
+ )} +
+ )} +
+ ) + })} +
+
+ ) +} diff --git a/ui/features/run-detail/components/TraderPanel.tsx b/ui/features/run-detail/components/TraderPanel.tsx new file mode 100644 index 00000000..6526a900 --- /dev/null +++ b/ui/features/run-detail/components/TraderPanel.tsx @@ -0,0 +1,18 @@ +type Props = { content: string } + +export default function TraderPanel({ content }: Props) { + if (!content) { + return

Waiting for trader analysis…

+ } + return ( +
+

+ Investment Plan +

+

{content}

+
+ ) +} diff --git a/ui/features/run-detail/components/VerdictBanner.tsx b/ui/features/run-detail/components/VerdictBanner.tsx new file mode 100644 index 00000000..83d825df --- /dev/null +++ b/ui/features/run-detail/components/VerdictBanner.tsx @@ -0,0 +1,142 @@ +import type { Decision } from '@/lib/types/agents' + +type Props = { verdict: Decision | null; ticker: string; date: string } + +const VERDICT_CONFIG: Record = { + BUY: { + color: 'var(--buy)', + colorBg: 'var(--buy-bg)', + colorRing: 'var(--buy-ring)', + label: 'BUY', + sublabel: 'Long position recommended', + arrow: '↑', + }, + SELL: { + color: 'var(--sell)', + colorBg: 'var(--sell-bg)', + colorRing: 'var(--sell-ring)', + label: 'SELL', + sublabel: 'Exit position recommended', + arrow: '↓', + }, + HOLD: { + color: 'var(--hold)', + colorBg: 'var(--hold-bg)', + colorRing: 'var(--hold-ring)', + label: 'HOLD', + sublabel: 'Maintain current position', + arrow: '→', + }, +} + +export default function VerdictBanner({ verdict, ticker, date }: Props) { + if (!verdict || !VERDICT_CONFIG[verdict]) return null + const cfg = VERDICT_CONFIG[verdict] + + return ( +
+ {/* Background glow */} +
+ +
+ {/* Left: metadata */} +
+
+ Analysis Complete +
+
+ {ticker} +
+
+ {date} +
+
+ + {/* Divider */} +
+ + {/* Right: verdict */} +
+
+
+ {cfg.sublabel} +
+
+ AI consensus decision +
+
+ + {/* Big verdict */} +
+ + {cfg.arrow} + + + {cfg.label} + +
+
+
+
+ ) +} diff --git a/ui/features/run-detail/hooks/useRunStream.ts b/ui/features/run-detail/hooks/useRunStream.ts new file mode 100644 index 00000000..999311f2 --- /dev/null +++ b/ui/features/run-detail/hooks/useRunStream.ts @@ -0,0 +1,73 @@ +'use client' +import { useEffect, useReducer } from 'react' +import { createSSEConnection } from '@/lib/sse' +import { getRunStreamUrl } from '@/lib/api-client' +import { AGENT_STEPS } from '@/lib/types/run' +import type { AgentStep } from '@/lib/types/run' +import type { RunStreamState } from '../types' + +const initialState: RunStreamState = { + status: 'connecting', + steps: Object.fromEntries(AGENT_STEPS.map((s) => [s, 'pending'])) as RunStreamState['steps'], + reports: Object.fromEntries(AGENT_STEPS.map((s) => [s, []])) as RunStreamState['reports'], + verdict: null, + error: null, +} + +type Action = + | { type: 'AGENT_START'; step: AgentStep; turn: number } + | { type: 'AGENT_COMPLETE'; step: AgentStep; turn: number; report: string } + | { type: 'RUN_COMPLETE'; decision: string } + | { type: 'RUN_ERROR'; message: string } + | { type: 'CONNECTED' } + +function reducer(state: RunStreamState, action: Action): RunStreamState { + switch (action.type) { + case 'CONNECTED': + return { ...state, status: 'running' } + + case 'AGENT_START': + // Only transition to 'running' on first turn (don't regress from 'done') + if (state.steps[action.step] !== 'pending') return state + return { ...state, steps: { ...state.steps, [action.step]: 'running' } } + + case 'AGENT_COMPLETE': + return { + ...state, + steps: { ...state.steps, [action.step]: 'done' }, + reports: { + ...state.reports, + [action.step]: [...(state.reports[action.step] ?? []), action.report], + }, + } + + case 'RUN_COMPLETE': + return { ...state, status: 'complete', verdict: action.decision as RunStreamState['verdict'] } + + case 'RUN_ERROR': + return { ...state, status: 'error', error: action.message } + + default: + return state + } +} + +export function useRunStream(runId: string): RunStreamState { + const [state, dispatch] = useReducer(reducer, initialState) + + useEffect(() => { + const url = getRunStreamUrl(runId) + const close = createSSEConnection(url, { + onOpen: () => dispatch({ type: 'CONNECTED' }), + onAgentStart: ({ step, turn }) => + dispatch({ type: 'AGENT_START', step: step as AgentStep, turn }), + onAgentComplete: ({ step, turn, report }) => + dispatch({ type: 'AGENT_COMPLETE', step: step as AgentStep, turn, report }), + onRunComplete: ({ decision }) => dispatch({ type: 'RUN_COMPLETE', decision }), + onRunError: ({ message }) => dispatch({ type: 'RUN_ERROR', message }), + }) + return close + }, [runId]) + + return state +} diff --git a/ui/features/run-detail/types.ts b/ui/features/run-detail/types.ts new file mode 100644 index 00000000..cd099543 --- /dev/null +++ b/ui/features/run-detail/types.ts @@ -0,0 +1,10 @@ +import type { AgentStep, RunStatus } from '@/lib/types/run' +import type { Decision, StepStatus } from '@/lib/types/agents' + +export type RunStreamState = { + status: RunStatus | 'connecting' + steps: Record + reports: Record + verdict: Decision | null + error: string | null +} diff --git a/ui/features/settings/components/SettingsForm.tsx b/ui/features/settings/components/SettingsForm.tsx new file mode 100644 index 00000000..f4d68ab6 --- /dev/null +++ b/ui/features/settings/components/SettingsForm.tsx @@ -0,0 +1,99 @@ +'use client' +import { useEffect, useState } from 'react' +import { getSettings, updateSettings } from '@/lib/api-client' +import type { SettingsFormState } from '../types' + +const DEFAULTS: SettingsFormState = { + deep_think_llm: 'gpt-5.2', + quick_think_llm: 'gpt-5-mini', + max_debate_rounds: 1, + max_risk_discuss_rounds: 1, +} + +export default function SettingsForm() { + const [form, setForm] = useState(DEFAULTS) + const [saved, setSaved] = useState(false) + const set = (k: keyof SettingsFormState, v: unknown) => + setForm((f) => ({ ...f, [k]: v })) + + useEffect(() => { getSettings().then(setForm).catch(() => {}) }, []) + + const save = async (e: React.FormEvent) => { + e.preventDefault() + await updateSettings(form) + setSaved(true) + setTimeout(() => setSaved(false), 2000) + } + + return ( +
+ + {/* ── Model Configuration ─────────────────────────────────── */} +
+

+ Model Configuration +

+ {(['deep_think_llm', 'quick_think_llm'] as const).map((key) => ( +
+ + set(key, e.target.value)} + /> +
+ ))} +
+ + {/* ── Analysis Parameters ─────────────────────────────────── */} +
+

+ Analysis Parameters +

+ {(['max_debate_rounds', 'max_risk_discuss_rounds'] as const).map((key) => ( +
+ + set(key, Number(e.target.value))} + /> +
+ ))} +
+ + {/* ── Security notice ─────────────────────────────────────── */} +
+ API keys and secrets are configured via .env on the server and are not editable here. +
+ + {/* ── Actions ─────────────────────────────────────────────── */} +
+ + +
+
+ ) +} diff --git a/ui/features/settings/types.ts b/ui/features/settings/types.ts new file mode 100644 index 00000000..6b6a16c0 --- /dev/null +++ b/ui/features/settings/types.ts @@ -0,0 +1,6 @@ +export type SettingsFormState = { + deep_think_llm: string + quick_think_llm: string + max_debate_rounds: number + max_risk_discuss_rounds: number +} diff --git a/ui/jest.config.ts b/ui/jest.config.ts new file mode 100644 index 00000000..1c3d4505 --- /dev/null +++ b/ui/jest.config.ts @@ -0,0 +1,14 @@ +import type { Config } from 'jest' +import nextJest from 'next/jest.js' + +const createJestConfig = nextJest({ dir: './' }) + +const config: Config = { + testEnvironment: 'jsdom', + setupFilesAfterEnv: ['/jest.setup.ts'], + moduleNameMapper: { + '^@/(.*)$': '/$1', + }, +} + +export default createJestConfig(config) diff --git a/ui/jest.setup.ts b/ui/jest.setup.ts new file mode 100644 index 00000000..c44951a6 --- /dev/null +++ b/ui/jest.setup.ts @@ -0,0 +1 @@ +import '@testing-library/jest-dom' diff --git a/ui/next.config.ts b/ui/next.config.ts new file mode 100644 index 00000000..e9ffa308 --- /dev/null +++ b/ui/next.config.ts @@ -0,0 +1,7 @@ +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = { + /* config options here */ +}; + +export default nextConfig; diff --git a/ui/package-lock.json b/ui/package-lock.json new file mode 100644 index 00000000..42cfcdda --- /dev/null +++ b/ui/package-lock.json @@ -0,0 +1,11085 @@ +{ + "name": "ui", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "ui", + "version": "0.1.0", + "dependencies": { + "next": "16.2.1", + "react": "19.2.4", + "react-dom": "19.2.4" + }, + "devDependencies": { + "@tailwindcss/postcss": "^4", + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/react": "^16.3.2", + "@testing-library/user-event": "^14.6.1", + "@types/node": "^20", + "@types/react": "^19", + "@types/react-dom": "^19", + "eslint": "^9", + "eslint-config-next": "16.2.1", + "jest": "^30.3.0", + "jest-environment-jsdom": "^30.3.0", + "tailwindcss": "^4", + "ts-jest": "^29.4.6", + "typescript": "^5" + } + }, + "node_modules/@adobe/css-tools": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz", + "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==", + "dev": true, + "license": "MIT" + }, + "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/@asamuzakjp/css-color": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", + "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^2.1.3", + "@csstools/css-color-parser": "^3.0.9", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "lru-cache": "^10.4.3" + } + }, + "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "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/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@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.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", + "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", + "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz", + "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", + "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@csstools/color-helpers": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", + "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", + "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", + "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^5.1.0", + "@csstools/css-calc": "^2.1.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@emnapi/core": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.1.tgz", + "integrity": "sha512-mukuNALVsoix/w1BJwFzwXBN/dHeejQtuVzcDsfOEsdpCumXb/E9j8w11h5S54tT1xhifGfbbSm/ICrObRb3KA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.1.tgz", + "integrity": "sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.0.tgz", + "integrity": "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "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.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", + "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", + "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.1.1", + "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/js": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", + "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", + "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/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.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==", + "dev": true, + "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/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.3.0.tgz", + "integrity": "sha512-PAwCvFJ4696XP2qZj+LAn1BWjZaJ6RjG6c7/lkMaUJnkyMS34ucuIsfqYvfskVNvUI27R/u4P1HMYFnlVXG/Ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.3.0", + "@types/node": "*", + "chalk": "^4.1.2", + "jest-message-util": "30.3.0", + "jest-util": "30.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/core": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.3.0.tgz", + "integrity": "sha512-U5mVPsBxLSO6xYbf+tgkymLx+iAhvZX43/xI1+ej2ZOPnPdkdO1CzDmFKh2mZBn2s4XZixszHeQnzp1gm/DIxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "30.3.0", + "@jest/pattern": "30.0.1", + "@jest/reporters": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", + "@types/node": "*", + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "exit-x": "^0.2.2", + "graceful-fs": "^4.2.11", + "jest-changed-files": "30.3.0", + "jest-config": "30.3.0", + "jest-haste-map": "30.3.0", + "jest-message-util": "30.3.0", + "jest-regex-util": "30.0.1", + "jest-resolve": "30.3.0", + "jest-resolve-dependencies": "30.3.0", + "jest-runner": "30.3.0", + "jest-runtime": "30.3.0", + "jest-snapshot": "30.3.0", + "jest-util": "30.3.0", + "jest-validate": "30.3.0", + "jest-watcher": "30.3.0", + "pretty-format": "30.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/jest-config": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.3.0.tgz", + "integrity": "sha512-WPMAkMAtNDY9P/oKObtsRG/6KTrhtgPJoBTmk20uDn4Uy6/3EJnnaZJre/FMT1KVRx8cve1r7/FlMIOfRVWL4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@jest/get-type": "30.1.0", + "@jest/pattern": "30.0.1", + "@jest/test-sequencer": "30.3.0", + "@jest/types": "30.3.0", + "babel-jest": "30.3.0", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "deepmerge": "^4.3.1", + "glob": "^10.5.0", + "graceful-fs": "^4.2.11", + "jest-circus": "30.3.0", + "jest-docblock": "30.2.0", + "jest-environment-node": "30.3.0", + "jest-regex-util": "30.0.1", + "jest-resolve": "30.3.0", + "jest-runner": "30.3.0", + "jest-util": "30.3.0", + "jest-validate": "30.3.0", + "parse-json": "^5.2.0", + "pretty-format": "30.3.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "esbuild-register": ">=3.4.0", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "esbuild-register": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/@jest/core/node_modules/pretty-format": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/core/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jest/diff-sequences": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.3.0.tgz", + "integrity": "sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/environment": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.3.0.tgz", + "integrity": "sha512-SlLSF4Be735yQXyh2+mctBOzNDx5s5uLv88/j8Qn1wH679PDcwy67+YdADn8NJnGjzlXtN62asGH/T4vWOkfaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "30.3.0", + "@jest/types": "30.3.0", + "@types/node": "*", + "jest-mock": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/environment-jsdom-abstract": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/environment-jsdom-abstract/-/environment-jsdom-abstract-30.3.0.tgz", + "integrity": "sha512-0hNFs5N6We3DMCwobzI0ydhkY10sT1tZSC0AAiy+0g2Dt/qEWgrcV5BrMxPczhe41cxW4qm6X+jqZaUdpZIajA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "30.3.0", + "@jest/fake-timers": "30.3.0", + "@jest/types": "30.3.0", + "@types/jsdom": "^21.1.7", + "@types/node": "*", + "jest-mock": "30.3.0", + "jest-util": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "canvas": "^3.0.0", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/@jest/expect": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.3.0.tgz", + "integrity": "sha512-76Nlh4xJxk2D/9URCn3wFi98d2hb19uWE1idLsTt2ywhvdOldbw3S570hBgn25P4ICUZ/cBjybrBex2g17IDbg==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "30.3.0", + "jest-snapshot": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.3.0.tgz", + "integrity": "sha512-j0+W5iQQ8hBh7tHZkTQv3q2Fh/M7Je72cIsYqC4OaktgtO7v1So9UTjp6uPBHIaB6beoF/RRsCgMJKvti0wADA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.3.0.tgz", + "integrity": "sha512-WUQDs8SOP9URStX1DzhD425CqbN/HxUYCTwVrT8sTVBfMvFqYt/s61EK5T05qnHu0po6RitXIvP9otZxYDzTGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.3.0", + "@sinonjs/fake-timers": "^15.0.0", + "@types/node": "*", + "jest-message-util": "30.3.0", + "jest-mock": "30.3.0", + "jest-util": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/get-type": { + "version": "30.1.0", + "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", + "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.3.0.tgz", + "integrity": "sha512-+owLCBBdfpgL3HU+BD5etr1SvbXpSitJK0is1kiYjJxAAJggYMRQz5hSdd5pq1sSggfxPbw2ld71pt4x5wwViA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "30.3.0", + "@jest/expect": "30.3.0", + "@jest/types": "30.3.0", + "jest-mock": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/pattern": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", + "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-regex-util": "30.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.3.0.tgz", + "integrity": "sha512-a09z89S+PkQnL055bVj8+pe2Caed2PBOaczHcXCykW5ngxX9EWx/1uAwncxc/HiU0oZqfwseMjyhxgRjS49qPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", + "@jridgewell/trace-mapping": "^0.3.25", + "@types/node": "*", + "chalk": "^4.1.2", + "collect-v8-coverage": "^1.0.2", + "exit-x": "^0.2.2", + "glob": "^10.5.0", + "graceful-fs": "^4.2.11", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^5.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "30.3.0", + "jest-util": "30.3.0", + "jest-worker": "30.3.0", + "slash": "^3.0.0", + "string-length": "^4.0.2", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/schemas": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", + "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/snapshot-utils": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.3.0.tgz", + "integrity": "sha512-ORbRN9sf5PP82v3FXNSwmO1OTDR2vzR2YTaR+E3VkSBZ8zadQE6IqYdYEeFH1NIkeB2HIGdF02dapb6K0Mj05g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.3.0", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "natural-compare": "^1.4.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz", + "integrity": "sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "callsites": "^3.1.0", + "graceful-fs": "^4.2.11" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.3.0.tgz", + "integrity": "sha512-e/52nJGuD74AKTSe0P4y5wFRlaXP0qmrS17rqOMHeSwm278VyNyXE3gFO/4DTGF9w+65ra3lo3VKj0LBrzmgdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "30.3.0", + "@jest/types": "30.3.0", + "@types/istanbul-lib-coverage": "^2.0.6", + "collect-v8-coverage": "^1.0.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.3.0.tgz", + "integrity": "sha512-dgbWy9b8QDlQeRZcv7LNF+/jFiiYHTKho1xirauZ7kVwY7avjFF6uTT0RqlgudB5OuIPagFdVtfFMosjVbk1eA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "30.3.0", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.3.0.tgz", + "integrity": "sha512-TLKY33fSLVd/lKB2YI1pH69ijyUblO/BQvCj566YvnwuzoTNr648iE0j22vRvVNk2HsPwByPxATg3MleS3gf5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@jest/types": "30.3.0", + "@jridgewell/trace-mapping": "^0.3.25", + "babel-plugin-istanbul": "^7.0.1", + "chalk": "^4.1.2", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.3.0", + "jest-regex-util": "30.0.1", + "jest-util": "30.3.0", + "pirates": "^4.0.7", + "slash": "^3.0.0", + "write-file-atomic": "^5.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/types": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.3.0.tgz", + "integrity": "sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/pattern": "30.0.1", + "@jest/schemas": "30.0.5", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", + "@types/node": "*", + "@types/yargs": "^17.0.33", + "chalk": "^4.1.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, + "node_modules/@next/env": { + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.1.tgz", + "integrity": "sha512-n8P/HCkIWW+gVal2Z8XqXJ6aB3J0tuM29OcHpCsobWlChH/SITBs1DFBk/HajgrwDkqqBXPbuUuzgDvUekREPg==", + "license": "MIT" + }, + "node_modules/@next/eslint-plugin-next": { + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.2.1.tgz", + "integrity": "sha512-r0epZGo24eT4g08jJlg2OEryBphXqO8aL18oajoTKLzHJ6jVr6P6FI58DLMug04MwD3j8Fj0YK0slyzneKVyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "3.3.1" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.2.1.tgz", + "integrity": "sha512-BwZ8w8YTaSEr2HIuXLMLxIdElNMPvY9fLqb20LX9A9OMGtJilhHLbCL3ggyd0TwjmMcTxi0XXt+ur1vWUoxj2Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.2.1.tgz", + "integrity": "sha512-/vrcE6iQSJq3uL3VGVHiXeaKbn8Es10DGTGRJnRZlkNQQk3kaNtAJg8Y6xuAlrx/6INKVjkfi5rY0iEXorZ6uA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.2.1.tgz", + "integrity": "sha512-uLn+0BK+C31LTVbQ/QU+UaVrV0rRSJQ8RfniQAHPghDdgE+SlroYqcmFnO5iNjNfVWCyKZHYrs3Nl0mUzWxbBw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.2.1.tgz", + "integrity": "sha512-ssKq6iMRnHdnycGp9hCuGnXJZ0YPr4/wNwrfE5DbmvEcgl9+yv97/Kq3TPVDfYome1SW5geciLB9aiEqKXQjlQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.2.1.tgz", + "integrity": "sha512-HQm7SrHRELJ30T1TSmT706IWovFFSRGxfgUkyWJZF/RKBMdbdRWJuFrcpDdE5vy9UXjFOx6L3mRdqH04Mmx0hg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.2.1.tgz", + "integrity": "sha512-aV2iUaC/5HGEpbBkE+4B8aHIudoOy5DYekAKOMSHoIYQ66y/wIVeaRx8MS2ZMdxe/HIXlMho4ubdZs/J8441Tg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.2.1.tgz", + "integrity": "sha512-IXdNgiDHaSk0ZUJ+xp0OQTdTgnpx1RCfRTalhn3cjOP+IddTMINwA7DXZrwTmGDO8SUr5q2hdP/du4DcrB1GxA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.2.1.tgz", + "integrity": "sha512-qvU+3a39Hay+ieIztkGSbF7+mccbbg1Tk25hc4JDylf8IHjYmY/Zm64Qq1602yPyQqvie+vf5T/uPwNxDNIoeg==", + "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/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", + "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, + "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/@sinclair/typebox": { + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.1.1.tgz", + "integrity": "sha512-cO5W33JgAPbOh07tvZjUOJ7oWhtaqGHiZw+11DPbyqh2kHTBc3eF/CjJDeQ4205RLQsX6rxCuYOroFQwl7JDRw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1" + } + }, + "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/@tailwindcss/node": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.2.tgz", + "integrity": "sha512-pXS+wJ2gZpVXqFaUEjojq7jzMpTGf8rU6ipJz5ovJV6PUGmlJ+jvIwGrzdHdQ80Sg+wmQxUFuoW1UAAwHNEdFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.19.0", + "jiti": "^2.6.1", + "lightningcss": "1.32.0", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.2.2" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.2.tgz", + "integrity": "sha512-qEUA07+E5kehxYp9BVMpq9E8vnJuBHfJEC0vPC5e7iL/hw7HR61aDKoVoKzrG+QKp56vhNZe4qwkRmMC0zDLvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.2.2", + "@tailwindcss/oxide-darwin-arm64": "4.2.2", + "@tailwindcss/oxide-darwin-x64": "4.2.2", + "@tailwindcss/oxide-freebsd-x64": "4.2.2", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.2", + "@tailwindcss/oxide-linux-arm64-gnu": "4.2.2", + "@tailwindcss/oxide-linux-arm64-musl": "4.2.2", + "@tailwindcss/oxide-linux-x64-gnu": "4.2.2", + "@tailwindcss/oxide-linux-x64-musl": "4.2.2", + "@tailwindcss/oxide-wasm32-wasi": "4.2.2", + "@tailwindcss/oxide-win32-arm64-msvc": "4.2.2", + "@tailwindcss/oxide-win32-x64-msvc": "4.2.2" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.2.tgz", + "integrity": "sha512-dXGR1n+P3B6748jZO/SvHZq7qBOqqzQ+yFrXpoOWWALWndF9MoSKAT3Q0fYgAzYzGhxNYOoysRvYlpixRBBoDg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.2.tgz", + "integrity": "sha512-iq9Qjr6knfMpZHj55/37ouZeykwbDqF21gPFtfnhCCKGDcPI/21FKC9XdMO/XyBM7qKORx6UIhGgg6jLl7BZlg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.2.tgz", + "integrity": "sha512-BlR+2c3nzc8f2G639LpL89YY4bdcIdUmiOOkv2GQv4/4M0vJlpXEa0JXNHhCHU7VWOKWT/CjqHdTP8aUuDJkuw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.2.tgz", + "integrity": "sha512-YUqUgrGMSu2CDO82hzlQ5qSb5xmx3RUrke/QgnoEx7KvmRJHQuZHZmZTLSuuHwFf0DJPybFMXMYf+WJdxHy/nQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.2.tgz", + "integrity": "sha512-FPdhvsW6g06T9BWT0qTwiVZYE2WIFo2dY5aCSpjG/S/u1tby+wXoslXS0kl3/KXnULlLr1E3NPRRw0g7t2kgaQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.2.tgz", + "integrity": "sha512-4og1V+ftEPXGttOO7eCmW7VICmzzJWgMx+QXAJRAhjrSjumCwWqMfkDrNu1LXEQzNAwz28NCUpucgQPrR4S2yw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.2.tgz", + "integrity": "sha512-oCfG/mS+/+XRlwNjnsNLVwnMWYH7tn/kYPsNPh+JSOMlnt93mYNCKHYzylRhI51X+TbR+ufNhhKKzm6QkqX8ag==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.2.tgz", + "integrity": "sha512-rTAGAkDgqbXHNp/xW0iugLVmX62wOp2PoE39BTCGKjv3Iocf6AFbRP/wZT/kuCxC9QBh9Pu8XPkv/zCZB2mcMg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.2.tgz", + "integrity": "sha512-XW3t3qwbIwiSyRCggeO2zxe3KWaEbM0/kW9e8+0XpBgyKU4ATYzcVSMKteZJ1iukJ3HgHBjbg9P5YPRCVUxlnQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.2.tgz", + "integrity": "sha512-eKSztKsmEsn1O5lJ4ZAfyn41NfG7vzCg496YiGtMDV86jz1q/irhms5O0VrY6ZwTUkFy/EKG3RfWgxSI3VbZ8Q==", + "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.8.1", + "@emnapi/runtime": "^1.8.1", + "@emnapi/wasi-threads": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.1.1", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.2.tgz", + "integrity": "sha512-qPmaQM4iKu5mxpsrWZMOZRgZv1tOZpUm+zdhhQP0VhJfyGGO3aUKdbh3gDZc/dPLQwW4eSqWGrrcWNBZWUWaXQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.2.tgz", + "integrity": "sha512-1T/37VvI7WyH66b+vqHj/cLwnCxt7Qt3WFu5Q8hk65aOvlwAhs7rAp1VkulBJw/N4tMirXjVnylTR72uI0HGcA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/postcss": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.2.2.tgz", + "integrity": "sha512-n4goKQbW8RVXIbNKRB/45LzyUqN451deQK0nzIeauVEqjlI49slUlgKYJM2QyUzap/PcpnS7kzSUmPb1sCRvYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "@tailwindcss/node": "4.2.2", + "@tailwindcss/oxide": "4.2.2", + "postcss": "^8.5.6", + "tailwindcss": "4.2.2" + } + }, + "node_modules/@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/dom/node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", + "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "picocolors": "^1.1.1", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@testing-library/react": { + "version": "16.3.2", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.2.tgz", + "integrity": "sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@testing-library/dom": "^10.0.0", + "@types/react": "^18.0.0 || ^19.0.0", + "@types/react-dom": "^18.0.0 || ^19.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@testing-library/user-event": { + "version": "14.6.1", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz", + "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jsdom": { + "version": "21.1.7", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-21.1.7.tgz", + "integrity": "sha512-yOriVnggzrnQ3a9OKOCxaVuSug3w3/SbOj5i7VwXWZEyUNl3bLF9V3MfxGbZKuwqJOQyRfqXyROBB1CoZLFWzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/tough-cookie": "*", + "parse5": "^7.0.0" + } + }, + "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": "20.19.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.37.tgz", + "integrity": "sha512-8kzdPJ3FsNsVIurqBs7oodNnCEVbni9yUEkaHbgptDACOPW04jimGagZ51E6+lXUwJjgnBw+hyko/lkFWCldqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/react": { + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", + "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", + "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/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/tough-cookie": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", + "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/yargs": { + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", + "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.1.tgz", + "integrity": "sha512-Gn3aqnvNl4NGc6x3/Bqk1AOn0thyTU9bqDRhiRnUWezgvr2OnhYCWCgC8zXXRVqBsIL1pSDt7T9nJUe0oM0kDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.57.1", + "@typescript-eslint/type-utils": "8.57.1", + "@typescript-eslint/utils": "8.57.1", + "@typescript-eslint/visitor-keys": "8.57.1", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.4.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.57.1", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.0.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.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.57.1.tgz", + "integrity": "sha512-k4eNDan0EIMTT/dUKc/g+rsJ6wcHYhNPdY19VoX/EOtaAG8DLtKCykhrUnuHPYvinn5jhAPgD2Qw9hXBwrahsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.57.1", + "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/typescript-estree": "8.57.1", + "@typescript-eslint/visitor-keys": "8.57.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.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.57.1.tgz", + "integrity": "sha512-vx1F37BRO1OftsYlmG9xay1TqnjNVlqALymwWVuYTdo18XuKxtBpCj1QlzNIEHlvlB27osvXFWptYiEWsVdYsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.57.1", + "@typescript-eslint/types": "^8.57.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.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.57.1.tgz", + "integrity": "sha512-hs/QcpCwlwT2L5S+3fT6gp0PabyGk4Q0Rv2doJXA0435/OpnSR3VRgvrp8Xdoc3UAYSg9cyUjTeFXZEPg/3OKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/visitor-keys": "8.57.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.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.57.1.tgz", + "integrity": "sha512-0lgOZB8cl19fHO4eI46YUx2EceQqhgkPSuCGLlGi79L2jwYY1cxeYc1Nae8Aw1xjgW3PKVDLlr3YJ6Bxx8HkWg==", + "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.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.57.1.tgz", + "integrity": "sha512-+Bwwm0ScukFdyoJsh2u6pp4S9ktegF98pYUU0hkphOOqdMB+1sNQhIz8y5E9+4pOioZijrkfNO/HUJVAFFfPKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/typescript-estree": "8.57.1", + "@typescript-eslint/utils": "8.57.1", + "debug": "^4.4.3", + "ts-api-utils": "^2.4.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.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.57.1.tgz", + "integrity": "sha512-S29BOBPJSFUiblEl6RzPPjJt6w25A6XsBqRVDt53tA/tlL8q7ceQNZHTjPeONt/3S7KRI4quk+yP9jK2WjBiPQ==", + "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.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.57.1.tgz", + "integrity": "sha512-ybe2hS9G6pXpqGtPli9Gx9quNV0TWLOmh58ADlmZe9DguLq0tiAKVjirSbtM1szG6+QH6rVXyU6GTLQbWnMY+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.57.1", + "@typescript-eslint/tsconfig-utils": "8.57.1", + "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/visitor-keys": "8.57.1", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.4.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.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.57.1.tgz", + "integrity": "sha512-XUNSJ/lEVFttPMMoDVA2r2bwrl8/oPx8cURtczkSEswY5T3AeLmCy+EKWQNdL4u0MmAHOjcWrqJp2cdvgjn8dQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.57.1", + "@typescript-eslint/types": "8.57.1", + "@typescript-eslint/typescript-estree": "8.57.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.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.57.1.tgz", + "integrity": "sha512-YWnmJkXbofiz9KbnbbwuA2rpGkFPLbAIetcCNO6mJ8gdhdZ/v7WDXsoGFAJuM6ikUFKTlSQnjWnVO4ux+UzS6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.57.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/@typescript-eslint/visitor-keys/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/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "dev": true, + "license": "ISC" + }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", + "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", + "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", + "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", + "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", + "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", + "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", + "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", + "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", + "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", + "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", + "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", + "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", + "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", + "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", + "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", + "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.11" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", + "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", + "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", + "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/acorn": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "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": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "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/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "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/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/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.11.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.1.tgz", + "integrity": "sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A==", + "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/babel-jest": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.3.0.tgz", + "integrity": "sha512-gRpauEU2KRrCox5Z296aeVHR4jQ98BCnu0IO332D/xpHNOsIH/bgSRk9k6GbKIbBw8vFeN6ctuu6tV8WOyVfYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/transform": "30.3.0", + "@types/babel__core": "^7.20.5", + "babel-plugin-istanbul": "^7.0.1", + "babel-preset-jest": "30.3.0", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "slash": "^3.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0 || ^8.0.0-0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", + "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", + "dev": true, + "license": "BSD-3-Clause", + "workspaces": [ + "test/babel-8" + ], + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-instrument": "^6.0.2", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.3.0.tgz", + "integrity": "sha512-+TRkByhsws6sfPjVaitzadk1I0F5sPvOVUH5tyTSzhePpsGIVrdeunHSw/C36QeocS95OOk8lunc4rlu5Anwsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/babel__core": "^7.20.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", + "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/babel-preset-jest": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.3.0.tgz", + "integrity": "sha512-6ZcUbWHC+dMz2vfzdNwi87Z1gQsLNK2uLuK1Q89R11xdvejcivlYYwDlEv0FHX3VwEXpbBQ9uufB/MUNpZGfhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "30.3.0", + "babel-preset-current-node-syntax": "^1.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.11.0 || ^8.0.0-beta.1" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.10", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.10.tgz", + "integrity": "sha512-sUoJ3IMxx4AyRqO4MLeHlnGDkyXRoUG0/AI9fjK+vS72ekpV0yWVY7O0BVjmBcRtkNcsAO2QDZ4tdKKGoI6YaQ==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "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.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "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.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "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/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001780", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001780.tgz", + "integrity": "sha512-llngX0E7nQci5BPJDqoZSbuZ5Bcs9F5db7EtgfwBerX9XGtkkiO4NwfDDIRzHTTwcYC8vC7bmeUEPGrKlR/TkQ==", + "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/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/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/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==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", + "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", + "dev": true, + "license": "MIT" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/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/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cssstyle": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz", + "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^3.2.0", + "rrweb-cssom": "^0.8.0" + }, + "engines": { + "node": ">=18" + } + }, + "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-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/dedent": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", + "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "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/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "devOptional": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "license": "MIT", + "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/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT", + "peer": true + }, + "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/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.321", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.321.tgz", + "integrity": "sha512-L2C7Q279W2D/J4PLZLk7sebOILDSWos7bMsMNN06rK482umHUrh/3lM8G7IlHFOYip2oAg5nha1rCMxr/rs6ZQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/enhanced-resolve": { + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz", + "integrity": "sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz", + "integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==", + "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-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.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.3.1.tgz", + "integrity": "sha512-zWwRvqWiuBPr0muUG/78cW3aHROFCNIQ3zpmYDpwdbnt2m+xlNyRWpHBpa2lJjSBit7BQ+RXA1iwbSmu5yJ/EQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.1", + "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", + "safe-array-concat": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "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.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", + "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", + "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.5", + "@eslint/js": "9.39.4", + "@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-config-next": { + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.2.1.tgz", + "integrity": "sha512-qhabwjQZ1Mk53XzXvmogf8KQ0tG0CQXF0CZ56+2/lVhmObgmaqj7x5A1DSrWdZd3kwI7GTPGUjFne+krRxYmFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@next/eslint-plugin-next": "16.2.1", + "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 + } + } + }, + "node_modules/eslint-config-next/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/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "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-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.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", + "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-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-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.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.0.1.tgz", + "integrity": "sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==", + "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" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.6", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.6.tgz", + "integrity": "sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "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/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": "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/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/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "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/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "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/execa/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/exit-x": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/exit-x/-/exit-x-0.2.2.tgz", + "integrity": "sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-30.3.0.tgz", + "integrity": "sha512-1zQrciTiQfRdo7qJM1uG4navm8DayFa2TgCSRlzUyNkhcJ6XUZF3hjnpkyr3VhAqPH7i/9GkG7Tv5abz6fqz0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "30.3.0", + "@jest/get-type": "30.1.0", + "jest-matcher-utils": "30.3.0", + "jest-message-util": "30.3.0", + "jest-mock": "30.3.0", + "jest-util": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "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/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/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bser": "2.1.1" + } + }, + "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/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==", + "dev": true, + "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==", + "dev": true, + "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/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/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.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "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/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==", + "dev": true, + "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==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "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==", + "dev": true, + "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.13.7", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.7.tgz", + "integrity": "sha512-7tN6rFgBlMgpBML5j8typ92BKFi2sFQvIdpAqLA2beia5avZDrMs0FLZiM5etShWq5irVyGcGMEA1jcDaK7A/Q==", + "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": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/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/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/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/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/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/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "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.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "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/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/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==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/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/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-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-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-bun-module/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/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.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "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-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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "license": "ISC" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "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/jest": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-30.3.0.tgz", + "integrity": "sha512-AkXIIFcaazymvey2i/+F94XRnM6TsVLZDhBMLsd1Sf/W0wzsvvpjeyUrCZD6HGG4SDYPgDJDBKeiJTBb10WzMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "30.3.0", + "@jest/types": "30.3.0", + "import-local": "^3.2.0", + "jest-cli": "30.3.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.3.0.tgz", + "integrity": "sha512-B/7Cny6cV5At6M25EWDgf9S617lHivamL8vl6KEpJqkStauzcG4e+WPfDgMMF+H4FVH4A2PLRyvgDJan4441QA==", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^5.1.1", + "jest-util": "30.3.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-circus": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.3.0.tgz", + "integrity": "sha512-PyXq5szeSfR/4f1lYqCmmQjh0vqDkURUYi9N6whnHjlRz4IUQfMcXkGLeEoiJtxtyPqgUaUUfyQlApXWBSN1RA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "30.3.0", + "@jest/expect": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/types": "30.3.0", + "@types/node": "*", + "chalk": "^4.1.2", + "co": "^4.6.0", + "dedent": "^1.6.0", + "is-generator-fn": "^2.1.0", + "jest-each": "30.3.0", + "jest-matcher-utils": "30.3.0", + "jest-message-util": "30.3.0", + "jest-runtime": "30.3.0", + "jest-snapshot": "30.3.0", + "jest-util": "30.3.0", + "p-limit": "^3.1.0", + "pretty-format": "30.3.0", + "pure-rand": "^7.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.6" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/pretty-format": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-circus/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-cli": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.3.0.tgz", + "integrity": "sha512-l6Tqx+j1fDXJEW5bqYykDQQ7mQg+9mhWXtnj+tQZrTWYHyHoi6Be8HPumDSA+UiX2/2buEgjA58iJzdj146uCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/types": "30.3.0", + "chalk": "^4.1.2", + "exit-x": "^0.2.2", + "import-local": "^3.2.0", + "jest-config": "30.3.0", + "jest-util": "30.3.0", + "jest-validate": "30.3.0", + "yargs": "^17.7.2" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-cli/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/jest-config": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.3.0.tgz", + "integrity": "sha512-WPMAkMAtNDY9P/oKObtsRG/6KTrhtgPJoBTmk20uDn4Uy6/3EJnnaZJre/FMT1KVRx8cve1r7/FlMIOfRVWL4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@jest/get-type": "30.1.0", + "@jest/pattern": "30.0.1", + "@jest/test-sequencer": "30.3.0", + "@jest/types": "30.3.0", + "babel-jest": "30.3.0", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "deepmerge": "^4.3.1", + "glob": "^10.5.0", + "graceful-fs": "^4.2.11", + "jest-circus": "30.3.0", + "jest-docblock": "30.2.0", + "jest-environment-node": "30.3.0", + "jest-regex-util": "30.0.1", + "jest-resolve": "30.3.0", + "jest-runner": "30.3.0", + "jest-util": "30.3.0", + "jest-validate": "30.3.0", + "parse-json": "^5.2.0", + "pretty-format": "30.3.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "esbuild-register": ">=3.4.0", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "esbuild-register": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-cli/node_modules/pretty-format": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-cli/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-diff": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.3.0.tgz", + "integrity": "sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/diff-sequences": "30.3.0", + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "pretty-format": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/pretty-format": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-diff/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-docblock": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.2.0.tgz", + "integrity": "sha512-tR/FFgZKS1CXluOQzZvNH3+0z9jXr3ldGSD8bhyuxvlVUwbeLOGynkunvlTMxchC5urrKndYiwCFC0DLVjpOCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-newline": "^3.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-each": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.3.0.tgz", + "integrity": "sha512-V8eMndg/aZ+3LnCJgSm13IxS5XSBM22QSZc9BtPK8Dek6pm+hfUNfwBdvsB3d342bo1q7wnSkC38zjX259qZNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "@jest/types": "30.3.0", + "chalk": "^4.1.2", + "jest-util": "30.3.0", + "pretty-format": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/pretty-format": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-each/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-environment-jsdom": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-30.3.0.tgz", + "integrity": "sha512-RLEOJy6ip1lpw0yqJ8tB3i88FC7VBz7i00Zvl2qF71IdxjS98gC9/0SPWYIBVXHm5hgCYK0PAlSlnHGGy9RoMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "30.3.0", + "@jest/environment-jsdom-abstract": "30.3.0", + "jsdom": "^26.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jest-environment-node": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.3.0.tgz", + "integrity": "sha512-4i6HItw/JSiJVsC5q0hnKIe/hbYfZLVG9YJ/0pU9Hz2n/9qZe3Rhn5s5CUZA5ORZlcdT/vmAXRMyONXJwPrmYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "30.3.0", + "@jest/fake-timers": "30.3.0", + "@jest/types": "30.3.0", + "@types/node": "*", + "jest-mock": "30.3.0", + "jest-util": "30.3.0", + "jest-validate": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.3.0.tgz", + "integrity": "sha512-mMi2oqG4KRU0R9QEtscl87JzMXfUhbKaFqOxmjb2CKcbHcUGFrJCBWHmnTiUqi6JcnzoBlO4rWfpdl2k/RfLCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.3.0", + "@types/node": "*", + "anymatch": "^3.1.3", + "fb-watchman": "^2.0.2", + "graceful-fs": "^4.2.11", + "jest-regex-util": "30.0.1", + "jest-util": "30.3.0", + "jest-worker": "30.3.0", + "picomatch": "^4.0.3", + "walker": "^1.0.8" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.3" + } + }, + "node_modules/jest-haste-map/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-leak-detector": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.3.0.tgz", + "integrity": "sha512-cuKmUUGIjfXZAiGJ7TbEMx0bcqNdPPI6P1V+7aF+m/FUJqFDxkFR4JqkTu8ZOiU5AaX/x0hZ20KaaIPXQzbMGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "pretty-format": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-leak-detector/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-leak-detector/node_modules/pretty-format": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-leak-detector/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-matcher-utils": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.3.0.tgz", + "integrity": "sha512-HEtc9uFQgaUHkC7nLSlQL3Tph4Pjxt/yiPvkIrrDCt9jhoLIgxaubo1G+CFOnmHYMxHwwdaSN7mkIFs6ZK8OhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "jest-diff": "30.3.0", + "pretty-format": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/pretty-format": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-message-util": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.3.0.tgz", + "integrity": "sha512-Z/j4Bo+4ySJ+JPJN3b2Qbl9hDq3VrXmnjjGEWD/x0BCXeOXPTV1iZYYzl2X8c1MaCOL+ewMyNBcm88sboE6YWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@jest/types": "30.3.0", + "@types/stack-utils": "^2.0.3", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "picomatch": "^4.0.3", + "pretty-format": "30.3.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.6" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-message-util/node_modules/pretty-format": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-message-util/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-mock": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.3.0.tgz", + "integrity": "sha512-OTzICK8CpE+t4ndhKrwlIdbM6Pn8j00lvmSmq5ejiO+KxukbLjgOflKWMn3KE34EZdQm5RqTuKj+5RIEniYhog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.3.0", + "@types/node": "*", + "jest-util": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", + "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.3.0.tgz", + "integrity": "sha512-NRtTAHQlpd15F9rUR36jqwelbrDV/dY4vzNte3S2kxCKUJRYNd5/6nTSbYiak1VX5g8IoFF23Uj5TURkUW8O5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.3.0", + "jest-pnp-resolver": "^1.2.3", + "jest-util": "30.3.0", + "jest-validate": "30.3.0", + "slash": "^3.0.0", + "unrs-resolver": "^1.7.11" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.3.0.tgz", + "integrity": "sha512-9ev8s3YN6Hsyz9LV75XUwkCVFlwPbaFn6Wp75qnI0wzAINYWY8Fb3+6y59Rwd3QaS3kKXffHXsZMziMavfz/nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-regex-util": "30.0.1", + "jest-snapshot": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-runner": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.3.0.tgz", + "integrity": "sha512-gDv6C9LGKWDPLia9TSzZwf4h3kMQCqyTpq+95PODnTRDO0g9os48XIYYkS6D236vjpBir2fF63YmJFtqkS5Duw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "30.3.0", + "@jest/environment": "30.3.0", + "@jest/test-result": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", + "@types/node": "*", + "chalk": "^4.1.2", + "emittery": "^0.13.1", + "exit-x": "^0.2.2", + "graceful-fs": "^4.2.11", + "jest-docblock": "30.2.0", + "jest-environment-node": "30.3.0", + "jest-haste-map": "30.3.0", + "jest-leak-detector": "30.3.0", + "jest-message-util": "30.3.0", + "jest-resolve": "30.3.0", + "jest-runtime": "30.3.0", + "jest-util": "30.3.0", + "jest-watcher": "30.3.0", + "jest-worker": "30.3.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.3.0.tgz", + "integrity": "sha512-CgC+hIBJbuh78HEffkhNKcbXAytQViplcl8xupqeIWyKQF50kCQA8J7GeJCkjisC6hpnC9Muf8jV5RdtdFbGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "30.3.0", + "@jest/fake-timers": "30.3.0", + "@jest/globals": "30.3.0", + "@jest/source-map": "30.0.1", + "@jest/test-result": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", + "@types/node": "*", + "chalk": "^4.1.2", + "cjs-module-lexer": "^2.1.0", + "collect-v8-coverage": "^1.0.2", + "glob": "^10.5.0", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.3.0", + "jest-message-util": "30.3.0", + "jest-mock": "30.3.0", + "jest-regex-util": "30.0.1", + "jest-resolve": "30.3.0", + "jest-snapshot": "30.3.0", + "jest-util": "30.3.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-runtime/node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.3.0.tgz", + "integrity": "sha512-f14c7atpb4O2DeNhwcvS810Y63wEn8O1HqK/luJ4F6M4NjvxmAKQwBUWjbExUtMxWJQ0wVgmCKymeJK6NZMnfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@babel/generator": "^7.27.5", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1", + "@babel/types": "^7.27.3", + "@jest/expect-utils": "30.3.0", + "@jest/get-type": "30.1.0", + "@jest/snapshot-utils": "30.3.0", + "@jest/transform": "30.3.0", + "@jest/types": "30.3.0", + "babel-preset-current-node-syntax": "^1.2.0", + "chalk": "^4.1.2", + "expect": "30.3.0", + "graceful-fs": "^4.2.11", + "jest-diff": "30.3.0", + "jest-matcher-utils": "30.3.0", + "jest-message-util": "30.3.0", + "jest-util": "30.3.0", + "pretty-format": "30.3.0", + "semver": "^7.7.2", + "synckit": "^0.11.8" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/pretty-format": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-util": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.3.0.tgz", + "integrity": "sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.3.0", + "@types/node": "*", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "graceful-fs": "^4.2.11", + "picomatch": "^4.0.3" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-util/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-validate": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.3.0.tgz", + "integrity": "sha512-I/xzC8h5G+SHCb2P2gWkJYrNiTbeL47KvKeW5EzplkyxzBRBw1ssSHlI/jXec0ukH2q7x2zAWQm7015iusg62Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0", + "@jest/types": "30.3.0", + "camelcase": "^6.3.0", + "chalk": "^4.1.2", + "leven": "^3.1.0", + "pretty-format": "30.3.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-validate/node_modules/pretty-format": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.3.0.tgz", + "integrity": "sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-validate/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-watcher": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.3.0.tgz", + "integrity": "sha512-PJ1d9ThtTR8aMiBWUdcownq9mDdLXsQzJayTk4kmaBRHKvwNQn+ANveuhEBUyNI2hR1TVhvQ8D5kHubbzBHR/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "30.3.0", + "@jest/types": "30.3.0", + "@types/node": "*", + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "emittery": "^0.13.1", + "jest-util": "30.3.0", + "string-length": "^4.0.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-worker": { + "version": "30.3.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.3.0.tgz", + "integrity": "sha512-DrCKkaQwHexjRUFTmPzs7sHQe0TSj9nvDALKGdwmK5mW9v7j90BudWirKAJHt3QQ9Dhrg1F7DogPzhChppkJpQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@ungap/structured-clone": "^1.3.0", + "jest-util": "30.3.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.1.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdom": { + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz", + "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssstyle": "^4.2.1", + "data-urls": "^5.0.0", + "decimal.js": "^10.5.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.16", + "parse5": "^7.2.1", + "rrweb-cssom": "^0.8.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^5.1.1", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.1.1", + "ws": "^8.18.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "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-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "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/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==", + "dev": true, + "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/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/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true, + "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/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==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "lz-string": "bin/bin.js" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tmpl": "1.0.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/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==", + "dev": true, + "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/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/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "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/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", + "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/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/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "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/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/next": { + "version": "16.2.1", + "resolved": "https://registry.npmjs.org/next/-/next-16.2.1.tgz", + "integrity": "sha512-VaChzNL7o9rbfdt60HUj8tev4m6d7iC1igAy157526+cJlXOQu5LzsBXNT+xaJnTP/k+utSX5vMv7m0G+zKH+Q==", + "license": "MIT", + "dependencies": { + "@next/env": "16.2.1", + "@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.1", + "@next/swc-darwin-x64": "16.2.1", + "@next/swc-linux-arm64-gnu": "16.2.1", + "@next/swc-linux-arm64-musl": "16.2.1", + "@next/swc-linux-x64-gnu": "16.2.1", + "@next/swc-linux-x64-musl": "16.2.1", + "@next/swc-win32-arm64-msvc": "16.2.1", + "@next/swc-win32-x64-msvc": "16.2.1", + "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/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "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.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "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-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.36", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", + "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/nwsapi": { + "version": "2.2.23", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.23.tgz", + "integrity": "sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==", + "dev": true, + "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-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/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/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==", + "dev": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "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/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/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": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "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": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "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.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "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.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "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/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/pretty-format/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/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/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/pure-rand": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz", + "integrity": "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "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/react": { + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", + "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", + "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.4" + } + }, + "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/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.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-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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/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/rrweb-cssom": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", + "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", + "dev": true, + "license": "MIT" + }, + "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.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "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/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/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/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/sharp/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "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.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "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/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-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/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "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/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "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/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-length/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "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/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/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==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/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.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "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": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/strip-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/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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/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/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/synckit": { + "version": "0.11.12", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz", + "integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.2.9" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/synckit" + } + }, + "node_modules/tailwindcss": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.2.tgz", + "integrity": "sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/tldts": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", + "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^6.1.86" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", + "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true, + "license": "BSD-3-Clause" + }, + "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/tough-cookie": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", + "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^6.1.32" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", + "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, + "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/ts-jest": { + "version": "29.4.6", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.6.tgz", + "integrity": "sha512-fSpWtOO/1AjSNQguk43hb/JCo16oJDnMJf3CdEGNkqsEX3t0KX96xvyX1D7PfLCpVoKu4MfVrqUkFyblYoY4lA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bs-logger": "^0.2.6", + "fast-json-stable-stringify": "^2.1.0", + "handlebars": "^4.7.8", + "json5": "^2.2.3", + "lodash.memoize": "^4.1.2", + "make-error": "^1.3.6", + "semver": "^7.7.3", + "type-fest": "^4.41.0", + "yargs-parser": "^21.1.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/transform": "^29.0.0 || ^30.0.0", + "@jest/types": "^29.0.0 || ^30.0.0", + "babel-jest": "^29.0.0 || ^30.0.0", + "jest": "^29.0.0 || ^30.0.0", + "jest-util": "^29.0.0 || ^30.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/transform": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jest-util": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/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/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-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.57.1.tgz", + "integrity": "sha512-fLvZWf+cAGw3tqMCYzGIU6yR8K+Y9NT2z23RwOjlNFF2HwSB3KhdEFI5lSBv8tNmFkkBShSjsCjzx1vahZfISA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.57.1", + "@typescript-eslint/parser": "8.57.1", + "@typescript-eslint/typescript-estree": "8.57.1", + "@typescript-eslint/utils": "8.57.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.0.0" + } + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.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/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/unrs-resolver": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", + "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.0" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.11.1", + "@unrs/resolver-binding-android-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-x64": "1.11.1", + "@unrs/resolver-binding-freebsd-x64": "1.11.1", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", + "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-musl": "1.11.1", + "@unrs/resolver-binding-wasm32-wasi": "1.11.1", + "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", + "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", + "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" + } + }, + "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==", + "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": { + "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/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/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.20", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", + "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "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/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/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "license": "MIT" + }, + "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==", + "dev": true, + "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/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-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==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/ws": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", + "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", + "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "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" + } + } + } +} diff --git a/ui/package.json b/ui/package.json new file mode 100644 index 00000000..8654e481 --- /dev/null +++ b/ui/package.json @@ -0,0 +1,32 @@ +{ + "name": "ui", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "eslint" + }, + "dependencies": { + "next": "16.2.1", + "react": "19.2.4", + "react-dom": "19.2.4" + }, + "devDependencies": { + "@tailwindcss/postcss": "^4", + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/react": "^16.3.2", + "@testing-library/user-event": "^14.6.1", + "@types/node": "^20", + "@types/react": "^19", + "@types/react-dom": "^19", + "eslint": "^9", + "eslint-config-next": "16.2.1", + "jest": "^30.3.0", + "jest-environment-jsdom": "^30.3.0", + "tailwindcss": "^4", + "ts-jest": "^29.4.6", + "typescript": "^5" + } +} diff --git a/ui/postcss.config.mjs b/ui/postcss.config.mjs new file mode 100644 index 00000000..61e36849 --- /dev/null +++ b/ui/postcss.config.mjs @@ -0,0 +1,7 @@ +const config = { + plugins: { + "@tailwindcss/postcss": {}, + }, +}; + +export default config; diff --git a/ui/public/file.svg b/ui/public/file.svg new file mode 100644 index 00000000..004145cd --- /dev/null +++ b/ui/public/file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/public/globe.svg b/ui/public/globe.svg new file mode 100644 index 00000000..567f17b0 --- /dev/null +++ b/ui/public/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/public/next.svg b/ui/public/next.svg new file mode 100644 index 00000000..5174b28c --- /dev/null +++ b/ui/public/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/public/vercel.svg b/ui/public/vercel.svg new file mode 100644 index 00000000..77053960 --- /dev/null +++ b/ui/public/vercel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/public/window.svg b/ui/public/window.svg new file mode 100644 index 00000000..b2b2a44f --- /dev/null +++ b/ui/public/window.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/ui/tsconfig.json b/ui/tsconfig.json new file mode 100644 index 00000000..3a13f90a --- /dev/null +++ b/ui/tsconfig.json @@ -0,0 +1,34 @@ +{ + "compilerOptions": { + "target": "ES2017", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "react-jsx", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./*"] + } + }, + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts", + ".next/dev/types/**/*.ts", + "**/*.mts" + ], + "exclude": ["node_modules"] +}