From 2a0c490c9ed618bf2064aa5f1bdfe21fb58cccda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Boschi?= Date: Mon, 22 Dec 2025 11:05:23 +0100 Subject: [PATCH] feat: extensions (#54) --- docker/standalone/Dockerfile | 31 +- hindsight-api/hindsight_api/__init__.py | 2 + hindsight-api/hindsight_api/alembic/env.py | 25 +- ...9f6a3b4c5e2_rename_bank_to_interactions.py | 18 +- .../e0a1b2c3d4e5_disposition_to_3_traits.py | 67 +- .../rename_personality_to_disposition.py | 25 +- hindsight-api/hindsight_api/api/http.py | 445 +- hindsight-api/hindsight_api/api/mcp.py | 17 +- .../hindsight_api/engine/__init__.py | 13 +- .../hindsight_api/engine/entity_resolver.py | 75 +- .../hindsight_api/engine/interface.py | 592 ++ .../hindsight_api/engine/llm_wrapper.py | 12 +- .../hindsight_api/engine/memory_engine.py | 1207 +++- .../hindsight_api/engine/retain/bank_utils.py | 25 +- .../engine/retain/chunk_storage.py | 5 +- .../engine/retain/fact_storage.py | 17 +- .../hindsight_api/engine/retain/link_utils.py | 33 +- .../engine/retain/observation_regeneration.py | 33 +- .../engine/retain/orchestrator.py | 5 +- .../hindsight_api/engine/retain/types.py | 33 +- .../engine/search/graph_retrieval.py | 11 +- .../engine/search/mpfp_retrieval.py | 15 +- .../hindsight_api/engine/search/retrieval.py | 23 +- .../engine/search/think_utils.py | 2 +- .../hindsight_api/engine/search/tracer.py | 2 +- .../hindsight_api/extensions/__init__.py | 66 + .../hindsight_api/extensions/base.py | 81 + .../extensions/builtin/__init__.py | 18 + .../extensions/builtin/tenant.py | 33 + .../hindsight_api/extensions/context.py | 110 + .../hindsight_api/extensions/http.py | 89 + .../hindsight_api/extensions/loader.py | 125 + .../extensions/operation_validator.py | 325 + .../hindsight_api/extensions/tenant.py | 63 + hindsight-api/hindsight_api/main.py | 2 +- hindsight-api/hindsight_api/mcp_local.py | 8 +- hindsight-api/hindsight_api/migrations.py | 64 +- hindsight-api/hindsight_api/models.py | 15 + hindsight-api/hindsight_api/pg0.py | 2 +- hindsight-api/pyproject.toml | 26 + hindsight-api/tests/conftest.py | 8 +- hindsight-api/tests/test_agents_api.py | 71 +- hindsight-api/tests/test_batch_chunking.py | 10 +- hindsight-api/tests/test_combined_scoring.py | 23 +- hindsight-api/tests/test_document_tracking.py | 44 +- hindsight-api/tests/test_extensions.py | 796 +++ .../tests/test_fact_extraction_quality.py | 47 +- hindsight-api/tests/test_fact_ordering.py | 28 +- hindsight-api/tests/test_observations.py | 46 +- hindsight-api/tests/test_retain.py | 261 +- hindsight-api/tests/test_schema_isolation.py | 406 ++ hindsight-api/tests/test_search_trace.py | 16 +- hindsight-api/tests/test_sql_schema_safety.py | 136 + hindsight-api/tests/test_temporal_ranges.py | 16 +- hindsight-api/tests/test_think.py | 16 +- hindsight-cli/src/api.rs | 21 +- hindsight-cli/src/config.rs | 50 +- hindsight-cli/src/main.rs | 41 +- hindsight-cli/src/utils.rs | 2 +- .../hindsight_client/hindsight_client.py | 9 +- hindsight-clients/typescript/src/index.ts | 14 + .../benchmarks/common/benchmark_runner.py | 547 +- .../benchmarks/locomo/locomo_benchmark.py | 239 +- .../longmemeval/longmemeval_benchmark.py | 410 +- hindsight-dev/benchmarks/visualizer/main.py | 903 ++- .../hindsight_dev/generate_changelog.py | 17 +- .../hindsight_dev/generate_openapi.py | 17 +- hindsight-dev/hindsight_dev/sync_cookbook.py | 28 +- hindsight-dev/pyproject.toml | 55 + hindsight-docs/docusaurus.config.ts | 13 +- hindsight-docs/package.json | 1 + hindsight-docs/src/css/custom.css | 306 + package-lock.json | 6332 +++-------------- scripts/hooks/lint-node.sh | 22 - scripts/hooks/lint-python.sh | 22 - scripts/hooks/lint.sh | 76 + uv.lock | 39 + 77 files changed, 7624 insertions(+), 7224 deletions(-) create mode 100644 hindsight-api/hindsight_api/engine/interface.py create mode 100644 hindsight-api/hindsight_api/extensions/__init__.py create mode 100644 hindsight-api/hindsight_api/extensions/base.py create mode 100644 hindsight-api/hindsight_api/extensions/builtin/__init__.py create mode 100644 hindsight-api/hindsight_api/extensions/builtin/tenant.py create mode 100644 hindsight-api/hindsight_api/extensions/context.py create mode 100644 hindsight-api/hindsight_api/extensions/http.py create mode 100644 hindsight-api/hindsight_api/extensions/loader.py create mode 100644 hindsight-api/hindsight_api/extensions/operation_validator.py create mode 100644 hindsight-api/hindsight_api/extensions/tenant.py create mode 100644 hindsight-api/tests/test_extensions.py create mode 100644 hindsight-api/tests/test_schema_isolation.py create mode 100644 hindsight-api/tests/test_sql_schema_safety.py delete mode 100755 scripts/hooks/lint-node.sh delete mode 100755 scripts/hooks/lint-python.sh create mode 100755 scripts/hooks/lint.sh diff --git a/docker/standalone/Dockerfile b/docker/standalone/Dockerfile index c655343f..a6847111 100644 --- a/docker/standalone/Dockerfile +++ b/docker/standalone/Dockerfile @@ -2,16 +2,19 @@ # Supports building API-only, Control Plane-only, or both # # Build args: -# INCLUDE_API=true/false - Include API (default: true) -# INCLUDE_CP=true/false - Include Control Plane (default: true) +# INCLUDE_API=true/false - Include API (default: true) +# INCLUDE_CP=true/false - Include Control Plane (default: true) +# PRELOAD_ML_MODELS=true/false - Pre-download ML models during build (default: true) # # Examples: -# docker build -t hindsight . # Both (standalone) -# docker build -t hindsight-api --build-arg INCLUDE_CP=false . # API only -# docker build -t hindsight-cp --build-arg INCLUDE_API=false . # Control Plane only +# docker build -t hindsight . # Both (standalone) +# docker build -t hindsight-api --build-arg INCLUDE_CP=false . # API only +# docker build -t hindsight-cp --build-arg INCLUDE_API=false . # Control Plane only +# docker build -t hindsight --build-arg PRELOAD_ML_MODELS=false . # Skip ML model preload ARG INCLUDE_API=true ARG INCLUDE_CP=true +ARG PRELOAD_ML_MODELS=true # ============================================================================= # Stage: API Builder @@ -159,14 +162,17 @@ ENV PG0_HOME=/home/hindsight/.pg0-cache ENV PG0_HOME=/home/hindsight/.pg0 -# Pre-download ML models to avoid runtime download -RUN /app/api/.venv/bin/python -c "\ +# Pre-download ML models to avoid runtime download (conditional) +ARG PRELOAD_ML_MODELS +RUN if [ "$PRELOAD_ML_MODELS" = "true" ]; then \ + /app/api/.venv/bin/python -c "\ from sentence_transformers import SentenceTransformer, CrossEncoder; \ print('Downloading embedding model...'); \ SentenceTransformer('BAAI/bge-small-en-v1.5'); \ print('Downloading cross-encoder model...'); \ CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2'); \ -print('Models cached successfully')" +print('Models cached successfully')"; \ + else echo "Skipping ML model preload"; fi EXPOSE 8888 @@ -277,14 +283,17 @@ print('PostgreSQL pre-cached to PG0_HOME')" || echo "Pre-download skipped" ENV PG0_HOME=/home/hindsight/.pg0 -# Pre-download ML models to avoid runtime download -RUN /app/api/.venv/bin/python -c "\ +# Pre-download ML models to avoid runtime download (conditional) +ARG PRELOAD_ML_MODELS +RUN if [ "$PRELOAD_ML_MODELS" = "true" ]; then \ + /app/api/.venv/bin/python -c "\ from sentence_transformers import SentenceTransformer, CrossEncoder; \ print('Downloading embedding model...'); \ SentenceTransformer('BAAI/bge-small-en-v1.5'); \ print('Downloading cross-encoder model...'); \ CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2'); \ -print('Models cached successfully')" +print('Models cached successfully')"; \ + else echo "Skipping ML model preload"; fi EXPOSE 8888 9999 diff --git a/hindsight-api/hindsight_api/__init__.py b/hindsight-api/hindsight_api/__init__.py index fa5d10cc..6440e593 100644 --- a/hindsight-api/hindsight_api/__init__.py +++ b/hindsight-api/hindsight_api/__init__.py @@ -21,9 +21,11 @@ from .engine.search.trace import ( WeightComponents, ) from .engine.search.tracer import SearchTracer +from .models import RequestContext __all__ = [ "MemoryEngine", + "RequestContext", "HindsightConfig", "get_config", "SearchTrace", diff --git a/hindsight-api/hindsight_api/alembic/env.py b/hindsight-api/hindsight_api/alembic/env.py index a610a3d1..80dd804c 100644 --- a/hindsight-api/hindsight_api/alembic/env.py +++ b/hindsight-api/hindsight_api/alembic/env.py @@ -109,6 +109,9 @@ def run_migrations_online() -> None: get_database_url() # Process and set the database URL in config + # Check if we're targeting a specific schema (for multi-tenant isolation) + target_schema = config.get_main_option("target_schema") + connectable = engine_from_config( config.get_section(config.config_ini_section, {}), prefix="sqlalchemy.", @@ -121,14 +124,34 @@ def run_migrations_online() -> None: def set_read_write_mode(dbapi_connection, connection_record): cursor = dbapi_connection.cursor() cursor.execute("SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE") + # If targeting a specific schema, set search_path + # Include public in search_path for access to shared extensions (pgvector) + if target_schema: + cursor.execute(f'CREATE SCHEMA IF NOT EXISTS "{target_schema}"') + cursor.execute(f'SET search_path TO "{target_schema}", public') cursor.close() with connectable.connect() as connection: # Also explicitly set read-write mode on this connection connection.execute(text("SET SESSION CHARACTERISTICS AS TRANSACTION READ WRITE")) + + # If targeting a specific schema, set search_path + # Include public in search_path for access to shared extensions (pgvector) + if target_schema: + connection.execute(text(f'CREATE SCHEMA IF NOT EXISTS "{target_schema}"')) + connection.execute(text(f'SET search_path TO "{target_schema}", public')) + connection.commit() # Commit the SET command - context.configure(connection=connection, target_metadata=target_metadata) + # Configure context with version_table_schema if using a specific schema + context_opts = { + "connection": connection, + "target_metadata": target_metadata, + } + if target_schema: + context_opts["version_table_schema"] = target_schema + + context.configure(**context_opts) with context.begin_transaction(): context.run_migrations() diff --git a/hindsight-api/hindsight_api/alembic/versions/d9f6a3b4c5e2_rename_bank_to_interactions.py b/hindsight-api/hindsight_api/alembic/versions/d9f6a3b4c5e2_rename_bank_to_interactions.py index a60371db..bd04fcd7 100644 --- a/hindsight-api/hindsight_api/alembic/versions/d9f6a3b4c5e2_rename_bank_to_interactions.py +++ b/hindsight-api/hindsight_api/alembic/versions/d9f6a3b4c5e2_rename_bank_to_interactions.py @@ -6,7 +6,7 @@ Create Date: 2024-12-04 15:00:00.000000 """ -from alembic import op +from alembic import context, op # revision identifiers, used by Alembic. revision = "d9f6a3b4c5e2" @@ -15,14 +15,22 @@ branch_labels = None depends_on = None +def _get_schema_prefix() -> str: + """Get schema prefix for table names (e.g., 'tenant_x.' or '' for public).""" + schema = context.config.get_main_option("target_schema") + return f'"{schema}".' if schema else "" + + def upgrade(): + schema = _get_schema_prefix() + # Drop old check constraint FIRST (before updating data) op.drop_constraint("memory_units_fact_type_check", "memory_units", type_="check") # Update existing 'bank' values to 'experience' - op.execute("UPDATE memory_units SET fact_type = 'experience' WHERE fact_type = 'bank'") + op.execute(f"UPDATE {schema}memory_units SET fact_type = 'experience' WHERE fact_type = 'bank'") # Also update any 'interactions' values (in case of partial migration) - op.execute("UPDATE memory_units SET fact_type = 'experience' WHERE fact_type = 'interactions'") + op.execute(f"UPDATE {schema}memory_units SET fact_type = 'experience' WHERE fact_type = 'interactions'") # Create new check constraint with 'experience' instead of 'bank' op.create_check_constraint( @@ -31,11 +39,13 @@ def upgrade(): def downgrade(): + schema = _get_schema_prefix() + # Drop new check constraint FIRST op.drop_constraint("memory_units_fact_type_check", "memory_units", type_="check") # Update 'experience' back to 'bank' - op.execute("UPDATE memory_units SET fact_type = 'bank' WHERE fact_type = 'experience'") + op.execute(f"UPDATE {schema}memory_units SET fact_type = 'bank' WHERE fact_type = 'experience'") # Recreate old check constraint op.create_check_constraint( diff --git a/hindsight-api/hindsight_api/alembic/versions/e0a1b2c3d4e5_disposition_to_3_traits.py b/hindsight-api/hindsight_api/alembic/versions/e0a1b2c3d4e5_disposition_to_3_traits.py index 130cf39a..8db391ab 100644 --- a/hindsight-api/hindsight_api/alembic/versions/e0a1b2c3d4e5_disposition_to_3_traits.py +++ b/hindsight-api/hindsight_api/alembic/versions/e0a1b2c3d4e5_disposition_to_3_traits.py @@ -12,7 +12,7 @@ system (skepticism, literalism, empathy with 1-5 integer values). from collections.abc import Sequence import sqlalchemy as sa -from alembic import op +from alembic import context, op # revision identifiers, used by Alembic. revision: str = "e0a1b2c3d4e5" @@ -21,9 +21,36 @@ branch_labels: str | Sequence[str] | None = None depends_on: str | Sequence[str] | None = None +def _get_schema_prefix() -> str: + """Get schema prefix for table names (e.g., 'tenant_x.' or '' for public).""" + schema = context.config.get_main_option("target_schema") + return f'"{schema}".' if schema else "" + + +def _get_target_schema() -> str: + """Get the target schema name (tenant schema or 'public').""" + schema = context.config.get_main_option("target_schema") + return schema if schema else "public" + + def upgrade() -> None: """Convert Big Five disposition to 3-trait disposition.""" conn = op.get_bind() + schema = _get_schema_prefix() + target_schema = _get_target_schema() + + # Check if disposition column exists (should have been created by previous migration) + result = conn.execute( + sa.text(""" + SELECT column_name + FROM information_schema.columns + WHERE table_schema = :schema AND table_name = 'banks' AND column_name = 'disposition' + """), + {"schema": target_schema}, + ) + if not result.fetchone(): + # Column doesn't exist yet (shouldn't happen but be safe) + return # Update all existing banks to use the new disposition format # Convert from old format to new format with reasonable mappings: @@ -32,18 +59,18 @@ def upgrade() -> None: # - empathy: derived from agreeableness + inverse of neuroticism # Default all to 3 (neutral) for simplicity conn.execute( - sa.text(""" - UPDATE banks - SET disposition = '{"skepticism": 3, "literalism": 3, "empathy": 3}'::jsonb + sa.text(f""" + UPDATE {schema}banks + SET disposition = '{{"skepticism": 3, "literalism": 3, "empathy": 3}}'::jsonb WHERE disposition IS NOT NULL """) ) # Update the default for new banks conn.execute( - sa.text(""" - ALTER TABLE banks - ALTER COLUMN disposition SET DEFAULT '{"skepticism": 3, "literalism": 3, "empathy": 3}'::jsonb + sa.text(f""" + ALTER TABLE {schema}banks + ALTER COLUMN disposition SET DEFAULT '{{"skepticism": 3, "literalism": 3, "empathy": 3}}'::jsonb """) ) @@ -51,20 +78,34 @@ def upgrade() -> None: def downgrade() -> None: """Convert back to Big Five disposition.""" conn = op.get_bind() + schema = _get_schema_prefix() + target_schema = _get_target_schema() + + # Check if disposition column exists + result = conn.execute( + sa.text(""" + SELECT column_name + FROM information_schema.columns + WHERE table_schema = :schema AND table_name = 'banks' AND column_name = 'disposition' + """), + {"schema": target_schema}, + ) + if not result.fetchone(): + return # Revert to Big Five format with default values conn.execute( - sa.text(""" - UPDATE banks - SET disposition = '{"openness": 0.5, "conscientiousness": 0.5, "extraversion": 0.5, "agreeableness": 0.5, "neuroticism": 0.5, "bias_strength": 0.5}'::jsonb + sa.text(f""" + UPDATE {schema}banks + SET disposition = '{{"openness": 0.5, "conscientiousness": 0.5, "extraversion": 0.5, "agreeableness": 0.5, "neuroticism": 0.5, "bias_strength": 0.5}}'::jsonb WHERE disposition IS NOT NULL """) ) # Update the default for new banks conn.execute( - sa.text(""" - ALTER TABLE banks - ALTER COLUMN disposition SET DEFAULT '{"openness": 0.5, "conscientiousness": 0.5, "extraversion": 0.5, "agreeableness": 0.5, "neuroticism": 0.5, "bias_strength": 0.5}'::jsonb + sa.text(f""" + ALTER TABLE {schema}banks + ALTER COLUMN disposition SET DEFAULT '{{"openness": 0.5, "conscientiousness": 0.5, "extraversion": 0.5, "agreeableness": 0.5, "neuroticism": 0.5, "bias_strength": 0.5}}'::jsonb """) ) diff --git a/hindsight-api/hindsight_api/alembic/versions/rename_personality_to_disposition.py b/hindsight-api/hindsight_api/alembic/versions/rename_personality_to_disposition.py index 45ab69fc..6a711458 100644 --- a/hindsight-api/hindsight_api/alembic/versions/rename_personality_to_disposition.py +++ b/hindsight-api/hindsight_api/alembic/versions/rename_personality_to_disposition.py @@ -9,7 +9,7 @@ Create Date: 2024-12-04 from collections.abc import Sequence import sqlalchemy as sa -from alembic import op +from alembic import context, op from sqlalchemy.dialects import postgresql # revision identifiers, used by Alembic. @@ -19,17 +19,25 @@ branch_labels: str | Sequence[str] | None = None depends_on: str | Sequence[str] | None = None +def _get_target_schema() -> str: + """Get the target schema name (tenant schema or 'public').""" + schema = context.config.get_main_option("target_schema") + return schema if schema else "public" + + def upgrade() -> None: """Rename personality column to disposition in banks table (if it exists).""" conn = op.get_bind() + target_schema = _get_target_schema() # Check if 'personality' column exists (old database) result = conn.execute( sa.text(""" SELECT column_name FROM information_schema.columns - WHERE table_name = 'banks' AND column_name = 'personality' - """) + WHERE table_schema = :schema AND table_name = 'banks' AND column_name = 'personality' + """), + {"schema": target_schema}, ) has_personality = result.fetchone() is not None @@ -38,8 +46,9 @@ def upgrade() -> None: sa.text(""" SELECT column_name FROM information_schema.columns - WHERE table_name = 'banks' AND column_name = 'disposition' - """) + WHERE table_schema = :schema AND table_name = 'banks' AND column_name = 'disposition' + """), + {"schema": target_schema}, ) has_disposition = result.fetchone() is not None @@ -63,12 +72,14 @@ def upgrade() -> None: def downgrade() -> None: """Revert disposition column back to personality.""" conn = op.get_bind() + target_schema = _get_target_schema() result = conn.execute( sa.text(""" SELECT column_name FROM information_schema.columns - WHERE table_name = 'banks' AND column_name = 'disposition' - """) + WHERE table_schema = :schema AND table_name = 'banks' AND column_name = 'disposition' + """), + {"schema": target_schema}, ) if result.fetchone(): op.alter_column("banks", "disposition", new_column_name="personality") diff --git a/hindsight-api/hindsight_api/api/http.py b/hindsight-api/hindsight_api/api/http.py index e2666b09..d22460c9 100644 --- a/hindsight-api/hindsight_api/api/http.py +++ b/hindsight-api/hindsight_api/api/http.py @@ -12,7 +12,7 @@ from contextlib import asynccontextmanager from datetime import datetime from typing import Any -from fastapi import FastAPI, HTTPException, Query +from fastapi import Depends, FastAPI, Header, HTTPException, Query def _parse_metadata(metadata: Any) -> dict[str, Any]: @@ -33,9 +33,11 @@ from pydantic import BaseModel, ConfigDict, Field from hindsight_api import MemoryEngine from hindsight_api.engine.db_utils import acquire_with_retry -from hindsight_api.engine.memory_engine import Budget +from hindsight_api.engine.memory_engine import Budget, fq_table from hindsight_api.engine.response_models import VALID_RECALL_FACT_TYPES +from hindsight_api.extensions import HttpExtension, load_extension from hindsight_api.metrics import create_metrics_collector, get_metrics_collector, initialize_metrics +from hindsight_api.models import RequestContext logger = logging.getLogger(__name__) @@ -337,7 +339,7 @@ class RetainResponse(BaseModel): success: bool bank_id: str items_count: int - async_: bool = Field( + is_async: bool = Field( alias="async", serialization_alias="async", description="Whether the operation was processed asynchronously" ) @@ -706,7 +708,11 @@ class DeleteResponse(BaseModel): deleted_count: int | None = None -def create_app(memory: MemoryEngine, initialize_memory: bool = True) -> FastAPI: +def create_app( + memory: MemoryEngine, + initialize_memory: bool = True, + http_extension: HttpExtension | None = None, +) -> FastAPI: """ Create and configure the FastAPI application. @@ -714,6 +720,8 @@ def create_app(memory: MemoryEngine, initialize_memory: bool = True) -> FastAPI: memory: MemoryEngine instance (already initialized with required parameters). Migrations are controlled by the MemoryEngine's run_migrations parameter. initialize_memory: Whether to initialize memory system on startup (default: True) + http_extension: Optional HTTP extension to mount custom endpoints under /extension/. + If None, attempts to load from HINDSIGHT_API_HTTP_EXTENSION env var. Returns: Configured FastAPI application @@ -723,6 +731,11 @@ def create_app(memory: MemoryEngine, initialize_memory: bool = True) -> FastAPI: In that case, you should call memory.initialize() manually before starting the server and memory.close() when shutting down. """ + # Load HTTP extension from environment if not provided + if http_extension is None: + http_extension = load_extension("HTTP", HttpExtension) + if http_extension: + logging.info(f"Loaded HTTP extension: {http_extension.__class__.__name__}") @asynccontextmanager async def lifespan(app: FastAPI): @@ -746,8 +759,18 @@ def create_app(memory: MemoryEngine, initialize_memory: bool = True) -> FastAPI: await memory.initialize() logging.info("Memory system initialized") + # Call HTTP extension startup hook + if http_extension: + await http_extension.on_startup() + logging.info("HTTP extension started") + yield + # Call HTTP extension shutdown hook + if http_extension: + await http_extension.on_shutdown() + logging.info("HTTP extension stopped") + # Shutdown: Cleanup memory system await memory.close() logging.info("Memory system closed") @@ -775,12 +798,36 @@ def create_app(memory: MemoryEngine, initialize_memory: bool = True) -> FastAPI: # Register all routes _register_routes(app) + # Mount HTTP extension router if available + if http_extension: + extension_router = http_extension.get_router(memory) + app.include_router(extension_router, prefix="/ext", tags=["Extension"]) + logging.info("HTTP extension router mounted at /ext/") + return app def _register_routes(app: FastAPI): """Register all API routes on the given app instance.""" + def get_request_context(authorization: str | None = Header(default=None)) -> RequestContext: + """ + Extract request context from Authorization header. + + Supports: + - Bearer token: "Bearer " + - Direct API key: "" + + Returns RequestContext with extracted API key (may be None if no auth header). + """ + api_key = None + if authorization: + if authorization.lower().startswith("bearer "): + api_key = authorization[7:].strip() + else: + api_key = authorization.strip() + return RequestContext(api_key=api_key) + @app.get( "/health", summary="Health check endpoint", @@ -821,10 +868,12 @@ def _register_routes(app: FastAPI): operation_id="get_graph", tags=["Memory"], ) - async def api_graph(bank_id: str, type: str | None = None): + async def api_graph( + bank_id: str, type: str | None = None, request_context: RequestContext = Depends(get_request_context) + ): """Get graph data from database, filtered by bank_id and optionally by type.""" try: - data = await app.state.memory.get_graph_data(bank_id, type) + data = await app.state.memory.get_graph_data(bank_id, type, request_context=request_context) return data except Exception as e: import traceback @@ -841,7 +890,14 @@ def _register_routes(app: FastAPI): operation_id="list_memories", tags=["Memory"], ) - async def api_list(bank_id: str, type: str | None = None, q: str | None = None, limit: int = 100, offset: int = 0): + async def api_list( + bank_id: str, + type: str | None = None, + q: str | None = None, + limit: int = 100, + offset: int = 0, + request_context: RequestContext = Depends(get_request_context), + ): """ List memory units for table view with optional full-text search. @@ -857,7 +913,12 @@ def _register_routes(app: FastAPI): """ try: data = await app.state.memory.list_memory_units( - bank_id=bank_id, fact_type=type, search_query=q, limit=limit, offset=offset + bank_id=bank_id, + fact_type=type, + search_query=q, + limit=limit, + offset=offset, + request_context=request_context, ) return data except Exception as e: @@ -880,7 +941,9 @@ def _register_routes(app: FastAPI): operation_id="recall_memories", tags=["Memory"], ) - async def api_recall(bank_id: str, request: RecallRequest): + async def api_recall( + bank_id: str, request: RecallRequest, request_context: RequestContext = Depends(get_request_context) + ): """Run a recall and return results with trace.""" metrics = get_metrics_collector() @@ -923,6 +986,7 @@ def _register_routes(app: FastAPI): max_entity_tokens=max_entity_tokens, include_chunks=include_chunks, max_chunk_tokens=max_chunk_tokens, + request_context=request_context, ) # Convert core MemoryFact objects to API RecallResult objects (excluding internal metrics) @@ -995,14 +1059,20 @@ def _register_routes(app: FastAPI): operation_id="reflect", tags=["Memory"], ) - async def api_reflect(bank_id: str, request: ReflectRequest): + async def api_reflect( + bank_id: str, request: ReflectRequest, request_context: RequestContext = Depends(get_request_context) + ): metrics = get_metrics_collector() try: # Use the memory system's reflect_async method (record metrics) with metrics.record_operation("reflect", bank_id=bank_id, budget=request.budget.value): core_result = await app.state.memory.reflect_async( - bank_id=bank_id, query=request.query, budget=request.budget, context=request.context + bank_id=bank_id, + query=request.query, + budget=request.budget, + context=request.context, + request_context=request_context, ) # Convert core MemoryFact objects to API ReflectFact objects if facts are requested @@ -1041,10 +1111,10 @@ def _register_routes(app: FastAPI): operation_id="list_banks", tags=["Banks"], ) - async def api_list_banks(): + async def api_list_banks(request_context: RequestContext = Depends(get_request_context)): """Get list of all banks with their profiles.""" try: - banks = await app.state.memory.list_banks() + banks = await app.state.memory.list_banks(request_context=request_context) return BankListResponse(banks=banks) except Exception as e: import traceback @@ -1067,9 +1137,9 @@ def _register_routes(app: FastAPI): async with acquire_with_retry(pool) as conn: # Get node counts by fact_type node_stats = await conn.fetch( - """ + f""" SELECT fact_type, COUNT(*) as count - FROM memory_units + FROM {fq_table("memory_units")} WHERE bank_id = $1 GROUP BY fact_type """, @@ -1078,10 +1148,10 @@ def _register_routes(app: FastAPI): # Get link counts by link_type link_stats = await conn.fetch( - """ + f""" SELECT ml.link_type, COUNT(*) as count - FROM memory_links ml - JOIN memory_units mu ON ml.from_unit_id = mu.id + FROM {fq_table("memory_links")} ml + JOIN {fq_table("memory_units")} mu ON ml.from_unit_id = mu.id WHERE mu.bank_id = $1 GROUP BY ml.link_type """, @@ -1090,10 +1160,10 @@ def _register_routes(app: FastAPI): # Get link counts by fact_type (from nodes) link_fact_type_stats = await conn.fetch( - """ + f""" SELECT mu.fact_type, COUNT(*) as count - FROM memory_links ml - JOIN memory_units mu ON ml.from_unit_id = mu.id + FROM {fq_table("memory_links")} ml + JOIN {fq_table("memory_units")} mu ON ml.from_unit_id = mu.id WHERE mu.bank_id = $1 GROUP BY mu.fact_type """, @@ -1102,10 +1172,10 @@ def _register_routes(app: FastAPI): # Get link counts by fact_type AND link_type link_breakdown_stats = await conn.fetch( - """ + f""" SELECT mu.fact_type, ml.link_type, COUNT(*) as count - FROM memory_links ml - JOIN memory_units mu ON ml.from_unit_id = mu.id + FROM {fq_table("memory_links")} ml + JOIN {fq_table("memory_units")} mu ON ml.from_unit_id = mu.id WHERE mu.bank_id = $1 GROUP BY mu.fact_type, ml.link_type """, @@ -1114,9 +1184,9 @@ def _register_routes(app: FastAPI): # Get pending and failed operations counts ops_stats = await conn.fetch( - """ + f""" SELECT status, COUNT(*) as count - FROM async_operations + FROM {fq_table("async_operations")} WHERE bank_id = $1 GROUP BY status """, @@ -1128,9 +1198,9 @@ def _register_routes(app: FastAPI): # Get document count doc_count_result = await conn.fetchrow( - """ + f""" SELECT COUNT(*) as count - FROM documents + FROM {fq_table("documents")} WHERE bank_id = $1 """, bank_id, @@ -1184,11 +1254,13 @@ def _register_routes(app: FastAPI): tags=["Entities"], ) async def api_list_entities( - bank_id: str, limit: int = Query(default=100, description="Maximum number of entities to return") + bank_id: str, + limit: int = Query(default=100, description="Maximum number of entities to return"), + request_context: RequestContext = Depends(get_request_context), ): """List entities for a memory bank.""" try: - entities = await app.state.memory.list_entities(bank_id, limit=limit) + entities = await app.state.memory.list_entities(bank_id, limit=limit, request_context=request_context) return EntityListResponse(items=[EntityListItem(**e) for e in entities]) except Exception as e: import traceback @@ -1205,37 +1277,26 @@ def _register_routes(app: FastAPI): operation_id="get_entity", tags=["Entities"], ) - async def api_get_entity(bank_id: str, entity_id: str): + async def api_get_entity( + bank_id: str, entity_id: str, request_context: RequestContext = Depends(get_request_context) + ): """Get entity details with observations.""" try: - # First get the entity metadata - pool = await app.state.memory._get_pool() - async with acquire_with_retry(pool) as conn: - entity_row = await conn.fetchrow( - """ - SELECT id, canonical_name, mention_count, first_seen, last_seen, metadata - FROM entities - WHERE bank_id = $1 AND id = $2 - """, - bank_id, - uuid.UUID(entity_id), - ) + entity = await app.state.memory.get_entity(bank_id, entity_id, request_context=request_context) - if not entity_row: + if entity is None: raise HTTPException(status_code=404, detail=f"Entity {entity_id} not found") - # Get observations for the entity - observations = await app.state.memory.get_entity_observations(bank_id, entity_id, limit=20) - return EntityDetailResponse( - id=str(entity_row["id"]), - canonical_name=entity_row["canonical_name"], - mention_count=entity_row["mention_count"], - first_seen=entity_row["first_seen"].isoformat() if entity_row["first_seen"] else None, - last_seen=entity_row["last_seen"].isoformat() if entity_row["last_seen"] else None, - metadata=_parse_metadata(entity_row["metadata"]), + id=entity["id"], + canonical_name=entity["canonical_name"], + mention_count=entity["mention_count"], + first_seen=entity["first_seen"], + last_seen=entity["last_seen"], + metadata=_parse_metadata(entity["metadata"]), observations=[ - EntityObservationResponse(text=obs.text, mentioned_at=obs.mentioned_at) for obs in observations + EntityObservationResponse(text=obs.text, mentioned_at=obs.mentioned_at) + for obs in entity["observations"] ], ) except HTTPException: @@ -1255,42 +1316,40 @@ def _register_routes(app: FastAPI): operation_id="regenerate_entity_observations", tags=["Entities"], ) - async def api_regenerate_entity_observations(bank_id: str, entity_id: str): + async def api_regenerate_entity_observations( + bank_id: str, + entity_id: str, + request_context: RequestContext = Depends(get_request_context), + ): """Regenerate observations for an entity.""" try: - # First get the entity metadata - pool = await app.state.memory._get_pool() - async with acquire_with_retry(pool) as conn: - entity_row = await conn.fetchrow( - """ - SELECT id, canonical_name, mention_count, first_seen, last_seen, metadata - FROM entities - WHERE bank_id = $1 AND id = $2 - """, - bank_id, - uuid.UUID(entity_id), - ) + # Get the entity to verify it exists and get canonical_name + entity = await app.state.memory.get_entity(bank_id, entity_id, request_context=request_context) - if not entity_row: + if entity is None: raise HTTPException(status_code=404, detail=f"Entity {entity_id} not found") # Regenerate observations await app.state.memory.regenerate_entity_observations( - bank_id=bank_id, entity_id=entity_id, entity_name=entity_row["canonical_name"] + bank_id=bank_id, + entity_id=entity_id, + entity_name=entity["canonical_name"], + request_context=request_context, ) - # Get updated observations - observations = await app.state.memory.get_entity_observations(bank_id, entity_id, limit=20) + # Get updated entity with new observations + entity = await app.state.memory.get_entity(bank_id, entity_id, request_context=request_context) return EntityDetailResponse( - id=str(entity_row["id"]), - canonical_name=entity_row["canonical_name"], - mention_count=entity_row["mention_count"], - first_seen=entity_row["first_seen"].isoformat() if entity_row["first_seen"] else None, - last_seen=entity_row["last_seen"].isoformat() if entity_row["last_seen"] else None, - metadata=_parse_metadata(entity_row["metadata"]), + id=entity["id"], + canonical_name=entity["canonical_name"], + mention_count=entity["mention_count"], + first_seen=entity["first_seen"], + last_seen=entity["last_seen"], + metadata=_parse_metadata(entity["metadata"]), observations=[ - EntityObservationResponse(text=obs.text, mentioned_at=obs.mentioned_at) for obs in observations + EntityObservationResponse(text=obs.text, mentioned_at=obs.mentioned_at) + for obs in entity["observations"] ], ) except HTTPException: @@ -1310,7 +1369,13 @@ def _register_routes(app: FastAPI): operation_id="list_documents", tags=["Documents"], ) - async def api_list_documents(bank_id: str, q: str | None = None, limit: int = 100, offset: int = 0): + async def api_list_documents( + bank_id: str, + q: str | None = None, + limit: int = 100, + offset: int = 0, + request_context: RequestContext = Depends(get_request_context), + ): """ List documents for a memory bank with optional search. @@ -1321,7 +1386,9 @@ def _register_routes(app: FastAPI): offset: Offset for pagination (default: 0) """ try: - data = await app.state.memory.list_documents(bank_id=bank_id, search_query=q, limit=limit, offset=offset) + data = await app.state.memory.list_documents( + bank_id=bank_id, search_query=q, limit=limit, offset=offset, request_context=request_context + ) return data except Exception as e: import traceback @@ -1338,7 +1405,9 @@ def _register_routes(app: FastAPI): operation_id="get_document", tags=["Documents"], ) - async def api_get_document(bank_id: str, document_id: str): + async def api_get_document( + bank_id: str, document_id: str, request_context: RequestContext = Depends(get_request_context) + ): """ Get a specific document with its original text. @@ -1347,7 +1416,7 @@ def _register_routes(app: FastAPI): document_id: Document ID (from path) """ try: - document = await app.state.memory.get_document(document_id, bank_id) + document = await app.state.memory.get_document(document_id, bank_id, request_context=request_context) if not document: raise HTTPException(status_code=404, detail="Document not found") return document @@ -1368,7 +1437,7 @@ def _register_routes(app: FastAPI): operation_id="get_chunk", tags=["Documents"], ) - async def api_get_chunk(chunk_id: str): + async def api_get_chunk(chunk_id: str, request_context: RequestContext = Depends(get_request_context)): """ Get a specific chunk with its text. @@ -1376,7 +1445,7 @@ def _register_routes(app: FastAPI): chunk_id: Chunk ID (from path, format: bank_id_document_id_chunk_index) """ try: - chunk = await app.state.memory.get_chunk(chunk_id) + chunk = await app.state.memory.get_chunk(chunk_id, request_context=request_context) if not chunk: raise HTTPException(status_code=404, detail="Chunk not found") return chunk @@ -1401,7 +1470,9 @@ def _register_routes(app: FastAPI): operation_id="delete_document", tags=["Documents"], ) - async def api_delete_document(bank_id: str, document_id: str): + async def api_delete_document( + bank_id: str, document_id: str, request_context: RequestContext = Depends(get_request_context) + ): """ Delete a document and all its associated memory units and links. @@ -1410,7 +1481,7 @@ def _register_routes(app: FastAPI): document_id: Document ID to delete (from path) """ try: - result = await app.state.memory.delete_document(document_id, bank_id) + result = await app.state.memory.delete_document(document_id, bank_id, request_context=request_context) if result["document_deleted"] == 0: raise HTTPException(status_code=404, detail="Document not found") @@ -1437,45 +1508,14 @@ def _register_routes(app: FastAPI): operation_id="list_operations", tags=["Operations"], ) - async def api_list_operations(bank_id: str): + async def api_list_operations(bank_id: str, request_context: RequestContext = Depends(get_request_context)): """List all async operations (pending and failed) for a memory bank.""" try: - pool = await app.state.memory._get_pool() - async with acquire_with_retry(pool) as conn: - operations = await conn.fetch( - """ - SELECT operation_id, bank_id, operation_type, created_at, status, error_message, result_metadata - FROM async_operations - WHERE bank_id = $1 - ORDER BY created_at DESC - """, - bank_id, - ) - - def parse_metadata(metadata): - """Parse result_metadata which may be a string or dict.""" - if metadata is None: - return {} - if isinstance(metadata, str): - return json.loads(metadata) - return metadata - - return { - "bank_id": bank_id, - "operations": [ - { - "id": str(row["operation_id"]), - "task_type": row["operation_type"], - "items_count": parse_metadata(row["result_metadata"]).get("items_count", 0), - "document_id": parse_metadata(row["result_metadata"]).get("document_id"), - "created_at": row["created_at"].isoformat(), - "status": row["status"], - "error_message": row["error_message"], - } - for row in operations - ], - } - + operations = await app.state.memory.list_operations(bank_id, request_context=request_context) + return { + "bank_id": bank_id, + "operations": operations, + } except Exception as e: import traceback @@ -1490,39 +1530,21 @@ def _register_routes(app: FastAPI): operation_id="cancel_operation", tags=["Operations"], ) - async def api_cancel_operation(bank_id: str, operation_id: str): + async def api_cancel_operation( + bank_id: str, operation_id: str, request_context: RequestContext = Depends(get_request_context) + ): """Cancel a pending async operation.""" try: # Validate UUID format try: - op_uuid = uuid.UUID(operation_id) + uuid.UUID(operation_id) except ValueError: raise HTTPException(status_code=400, detail=f"Invalid operation_id format: {operation_id}") - pool = await app.state.memory._get_pool() - async with acquire_with_retry(pool) as conn: - # Check if operation exists and belongs to this memory bank - result = await conn.fetchrow( - "SELECT bank_id FROM async_operations WHERE operation_id = $1 AND bank_id = $2", op_uuid, bank_id - ) - - if not result: - raise HTTPException( - status_code=404, detail=f"Operation {operation_id} not found for memory bank {bank_id}" - ) - - # Delete the operation - await conn.execute("DELETE FROM async_operations WHERE operation_id = $1", op_uuid) - - return { - "success": True, - "message": f"Operation {operation_id} cancelled", - "operation_id": operation_id, - "bank_id": bank_id, - } - - except HTTPException: - raise + result = await app.state.memory.cancel_operation(bank_id, operation_id, request_context=request_context) + return result + except ValueError as e: + raise HTTPException(status_code=404, detail=str(e)) except Exception as e: import traceback @@ -1538,10 +1560,10 @@ def _register_routes(app: FastAPI): operation_id="get_bank_profile", tags=["Banks"], ) - async def api_get_bank_profile(bank_id: str): + async def api_get_bank_profile(bank_id: str, request_context: RequestContext = Depends(get_request_context)): """Get memory bank profile (disposition + background).""" try: - profile = await app.state.memory.get_bank_profile(bank_id) + profile = await app.state.memory.get_bank_profile(bank_id, request_context=request_context) # Convert DispositionTraits object to dict for Pydantic disposition_dict = ( profile["disposition"].model_dump() @@ -1569,14 +1591,18 @@ def _register_routes(app: FastAPI): operation_id="update_bank_disposition", tags=["Banks"], ) - async def api_update_bank_disposition(bank_id: str, request: UpdateDispositionRequest): + async def api_update_bank_disposition( + bank_id: str, request: UpdateDispositionRequest, request_context: RequestContext = Depends(get_request_context) + ): """Update bank disposition traits.""" try: # Update disposition - await app.state.memory.update_bank_disposition(bank_id, request.disposition.model_dump()) + await app.state.memory.update_bank_disposition( + bank_id, request.disposition.model_dump(), request_context=request_context + ) # Get updated profile - profile = await app.state.memory.get_bank_profile(bank_id) + profile = await app.state.memory.get_bank_profile(bank_id, request_context=request_context) disposition_dict = ( profile["disposition"].model_dump() if hasattr(profile["disposition"], "model_dump") @@ -1603,11 +1629,13 @@ def _register_routes(app: FastAPI): operation_id="add_bank_background", tags=["Banks"], ) - async def api_add_bank_background(bank_id: str, request: AddBackgroundRequest): + async def api_add_bank_background( + bank_id: str, request: AddBackgroundRequest, request_context: RequestContext = Depends(get_request_context) + ): """Add or merge bank background information. Optionally infer disposition traits.""" try: result = await app.state.memory.merge_bank_background( - bank_id, request.content, update_disposition=request.update_disposition + bank_id, request.content, update_disposition=request.update_disposition, request_context=request_context ) response = BackgroundResponse(background=result["background"]) @@ -1630,51 +1658,31 @@ def _register_routes(app: FastAPI): operation_id="create_or_update_bank", tags=["Banks"], ) - async def api_create_or_update_bank(bank_id: str, request: CreateBankRequest): + async def api_create_or_update_bank( + bank_id: str, request: CreateBankRequest, request_context: RequestContext = Depends(get_request_context) + ): """Create or update an agent with disposition and background.""" try: - # Get existing profile or create with defaults - profile = await app.state.memory.get_bank_profile(bank_id) + # Ensure bank exists by getting profile (auto-creates with defaults) + await app.state.memory.get_bank_profile(bank_id, request_context=request_context) - # Update name if provided - if request.name is not None: - pool = await app.state.memory._get_pool() - async with acquire_with_retry(pool) as conn: - await conn.execute( - """ - UPDATE banks - SET name = $2, - updated_at = NOW() - WHERE bank_id = $1 - """, - bank_id, - request.name, - ) - profile["name"] = request.name + # Update name and/or background if provided + if request.name is not None or request.background is not None: + await app.state.memory.update_bank( + bank_id, + name=request.name, + background=request.background, + request_context=request_context, + ) # Update disposition if provided if request.disposition is not None: - await app.state.memory.update_bank_disposition(bank_id, request.disposition.model_dump()) - profile["disposition"] = request.disposition.model_dump() - - # Update background if provided (replace, not merge) - if request.background is not None: - pool = await app.state.memory._get_pool() - async with acquire_with_retry(pool) as conn: - await conn.execute( - """ - UPDATE banks - SET background = $2, - updated_at = NOW() - WHERE bank_id = $1 - """, - bank_id, - request.background, - ) - profile["background"] = request.background + await app.state.memory.update_bank_disposition( + bank_id, request.disposition.model_dump(), request_context=request_context + ) # Get final profile - final_profile = await app.state.memory.get_bank_profile(bank_id) + final_profile = await app.state.memory.get_bank_profile(bank_id, request_context=request_context) disposition_dict = ( final_profile["disposition"].model_dump() if hasattr(final_profile["disposition"], "model_dump") @@ -1702,10 +1710,10 @@ def _register_routes(app: FastAPI): operation_id="delete_bank", tags=["Banks"], ) - async def api_delete_bank(bank_id: str): + async def api_delete_bank(bank_id: str, request_context: RequestContext = Depends(get_request_context)): """Delete an entire memory bank and all its data.""" try: - result = await app.state.memory.delete_bank(bank_id) + result = await app.state.memory.delete_bank(bank_id, request_context=request_context) return DeleteResponse( success=True, message=f"Bank '{bank_id}' and all associated data deleted successfully", @@ -1745,7 +1753,9 @@ def _register_routes(app: FastAPI): operation_id="retain_memories", tags=["Memory"], ) - async def api_retain(bank_id: str, request: RetainRequest): + async def api_retain( + bank_id: str, request: RetainRequest, request_context: RequestContext = Depends(get_request_context) + ): """Retain memories with optional async processing.""" metrics = get_metrics_collector() @@ -1766,43 +1776,25 @@ def _register_routes(app: FastAPI): if request.async_: # Async processing: queue task and return immediately - operation_id = uuid.uuid4() - - # Insert operation record into database - pool = await app.state.memory._get_pool() - async with acquire_with_retry(pool) as conn: - await conn.execute( - """ - INSERT INTO async_operations (operation_id, bank_id, operation_type, result_metadata) - VALUES ($1, $2, $3, $4) - """, - operation_id, - bank_id, - "retain", - json.dumps({"items_count": len(contents)}), - ) - - # Submit task to background queue - await app.state.memory._task_backend.submit_task( + result = await app.state.memory.submit_async_retain(bank_id, contents, request_context=request_context) + return RetainResponse.model_validate( { - "type": "batch_retain", - "operation_id": str(operation_id), + "success": True, "bank_id": bank_id, - "contents": contents, + "items_count": result["items_count"], + "async": True, } ) - - logging.info( - f"Retain task queued for bank_id={bank_id}, {len(contents)} items, operation_id={operation_id}" - ) - - return RetainResponse(success=True, bank_id=bank_id, items_count=len(contents), async_=True) else: # Synchronous processing: wait for completion (record metrics) with metrics.record_operation("retain", bank_id=bank_id): - result = await app.state.memory.retain_batch_async(bank_id=bank_id, contents=contents) + result = await app.state.memory.retain_batch_async( + bank_id=bank_id, contents=contents, request_context=request_context + ) - return RetainResponse(success=True, bank_id=bank_id, items_count=len(contents), async_=False) + return RetainResponse.model_validate( + {"success": True, "bank_id": bank_id, "items_count": len(contents), "async": False} + ) except Exception as e: import traceback @@ -1832,10 +1824,11 @@ def _register_routes(app: FastAPI): async def api_clear_bank_memories( bank_id: str, type: str | None = Query(None, description="Optional fact type filter (world, experience, opinion)"), + request_context: RequestContext = Depends(get_request_context), ): """Clear memories for a memory bank, optionally filtered by type.""" try: - await app.state.memory.delete_bank(bank_id, fact_type=type) + await app.state.memory.delete_bank(bank_id, fact_type=type, request_context=request_context) return DeleteResponse(success=True) except Exception as e: diff --git a/hindsight-api/hindsight_api/api/mcp.py b/hindsight-api/hindsight_api/api/mcp.py index 9c7fe2fe..f3a7bd04 100644 --- a/hindsight-api/hindsight_api/api/mcp.py +++ b/hindsight-api/hindsight_api/api/mcp.py @@ -9,6 +9,7 @@ from fastmcp import FastMCP from hindsight_api import MemoryEngine from hindsight_api.engine.response_models import VALID_RECALL_FACT_TYPES +from hindsight_api.models import RequestContext # Configure logging from HINDSIGHT_API_LOG_LEVEL environment variable _log_level_str = os.environ.get("HINDSIGHT_API_LOG_LEVEL", "info").lower() @@ -67,7 +68,11 @@ def create_mcp_server(memory: MemoryEngine) -> FastMCP: """ try: bank_id = get_current_bank_id() - await memory.retain_batch_async(bank_id=bank_id, contents=[{"content": content, "context": context}]) + if bank_id is None: + return "Error: No bank_id configured" + await memory.retain_batch_async( + bank_id=bank_id, contents=[{"content": content, "context": context}], request_context=RequestContext() + ) return "Memory stored successfully" except Exception as e: logger.error(f"Error storing memory: {e}", exc_info=True) @@ -90,10 +95,16 @@ def create_mcp_server(memory: MemoryEngine) -> FastMCP: """ try: bank_id = get_current_bank_id() + if bank_id is None: + return "Error: No bank_id configured" from hindsight_api.engine.memory_engine import Budget search_result = await memory.recall_async( - bank_id=bank_id, query=query, fact_type=list(VALID_RECALL_FACT_TYPES), budget=Budget.LOW + bank_id=bank_id, + query=query, + fact_type=list(VALID_RECALL_FACT_TYPES), + budget=Budget.LOW, + request_context=RequestContext(), ) results = [ @@ -102,7 +113,7 @@ def create_mcp_server(memory: MemoryEngine) -> FastMCP: "text": fact.text, "type": fact.fact_type, "context": fact.context, - "event_date": fact.event_date, + "occurred_start": fact.occurred_start, } for fact in search_result.results[:max_results] ] diff --git a/hindsight-api/hindsight_api/engine/__init__.py b/hindsight-api/hindsight_api/engine/__init__.py index 9333c385..0e7b4836 100644 --- a/hindsight-api/hindsight_api/engine/__init__.py +++ b/hindsight-api/hindsight_api/engine/__init__.py @@ -11,7 +11,13 @@ from .cross_encoder import CrossEncoderModel, LocalSTCrossEncoder, RemoteTEICros from .db_utils import acquire_with_retry from .embeddings import Embeddings, LocalSTEmbeddings, RemoteTEIEmbeddings from .llm_wrapper import LLMConfig -from .memory_engine import MemoryEngine +from .memory_engine import ( + MemoryEngine, + UnqualifiedTableError, + fq_table, + get_current_schema, + validate_sql_schema, +) from .response_models import MemoryFact, RecallResult, ReflectResult from .search.trace import ( EntryPoint, @@ -49,4 +55,9 @@ __all__ = [ "RecallResult", "ReflectResult", "MemoryFact", + # Schema safety utilities + "fq_table", + "get_current_schema", + "validate_sql_schema", + "UnqualifiedTableError", ] diff --git a/hindsight-api/hindsight_api/engine/entity_resolver.py b/hindsight-api/hindsight_api/engine/entity_resolver.py index f45779d5..88fd3700 100644 --- a/hindsight-api/hindsight_api/engine/entity_resolver.py +++ b/hindsight-api/hindsight_api/engine/entity_resolver.py @@ -11,6 +11,7 @@ from difflib import SequenceMatcher import asyncpg from .db_utils import acquire_with_retry +from .memory_engine import fq_table # Load spaCy model (singleton) _nlp = None @@ -68,9 +69,9 @@ class EntityResolver: ) -> list[str]: # Query ALL candidates for this bank all_entities = await conn.fetch( - """ + f""" SELECT canonical_name, id, metadata, last_seen, mention_count - FROM entities + FROM {fq_table("entities")} WHERE bank_id = $1 """, bank_id, @@ -82,11 +83,11 @@ class EntityResolver: # Query ALL co-occurrences for this bank's entities in one query # This builds a map of entity_id -> set of co-occurring entity names all_cooccurrences = await conn.fetch( - """ + f""" SELECT ec.entity_id_1, ec.entity_id_2, ec.cooccurrence_count - FROM entity_cooccurrences ec - WHERE ec.entity_id_1 IN (SELECT id FROM entities WHERE bank_id = $1) - OR ec.entity_id_2 IN (SELECT id FROM entities WHERE bank_id = $1) + FROM {fq_table("entity_cooccurrences")} ec + WHERE ec.entity_id_1 IN (SELECT id FROM {fq_table("entities")} WHERE bank_id = $1) + OR ec.entity_id_2 IN (SELECT id FROM {fq_table("entities")} WHERE bank_id = $1) """, bank_id, ) @@ -195,8 +196,8 @@ class EntityResolver: # Batch update existing entities if entities_to_update: await conn.executemany( - """ - UPDATE entities SET + f""" + UPDATE {fq_table("entities")} SET mention_count = mention_count + 1, last_seen = $2 WHERE id = $1::uuid @@ -232,13 +233,13 @@ class EntityResolver: # Batch INSERT ... ON CONFLICT with RETURNING # This is much faster than individual inserts rows = await conn.fetch( - """ - INSERT INTO entities (bank_id, canonical_name, first_seen, last_seen, mention_count) + f""" + INSERT INTO {fq_table("entities")} (bank_id, canonical_name, first_seen, last_seen, mention_count) SELECT $1, name, event_date, event_date, 1 FROM unnest($2::text[], $3::timestamptz[]) AS t(name, event_date) ON CONFLICT (bank_id, LOWER(canonical_name)) DO UPDATE SET - mention_count = entities.mention_count + 1, + mention_count = {fq_table("entities")}.mention_count + 1, last_seen = EXCLUDED.last_seen RETURNING id """, @@ -279,9 +280,9 @@ class EntityResolver: async with acquire_with_retry(self.pool) as conn: # Find candidate entities with similar name candidates = await conn.fetch( - """ + f""" SELECT id, canonical_name, metadata, last_seen - FROM entities + FROM {fq_table("entities")} WHERE bank_id = $1 AND ( canonical_name ILIKE $2 @@ -326,10 +327,10 @@ class EntityResolver: # Get entities that co-occurred with this candidate before # Use the materialized co-occurrence cache for fast lookup co_entity_rows = await conn.fetch( - """ + f""" SELECT e.canonical_name, ec.cooccurrence_count - FROM entity_cooccurrences ec - JOIN entities e ON ( + FROM {fq_table("entity_cooccurrences")} ec + JOIN {fq_table("entities")} e ON ( CASE WHEN ec.entity_id_1 = $1 THEN ec.entity_id_2 WHEN ec.entity_id_2 = $1 THEN ec.entity_id_1 @@ -365,8 +366,8 @@ class EntityResolver: if best_score > threshold: # Update entity await conn.execute( - """ - UPDATE entities + f""" + UPDATE {fq_table("entities")} SET mention_count = mention_count + 1, last_seen = $1 WHERE id = $2 @@ -402,12 +403,12 @@ class EntityResolver: Entity ID """ entity_id = await conn.fetchval( - """ - INSERT INTO entities (bank_id, canonical_name, first_seen, last_seen, mention_count) + f""" + INSERT INTO {fq_table("entities")} (bank_id, canonical_name, first_seen, last_seen, mention_count) VALUES ($1, $2, $3, $4, 1) ON CONFLICT (bank_id, LOWER(canonical_name)) DO UPDATE SET - mention_count = entities.mention_count + 1, + mention_count = {fq_table("entities")}.mention_count + 1, last_seen = EXCLUDED.last_seen RETURNING id """, @@ -430,8 +431,8 @@ class EntityResolver: async with acquire_with_retry(self.pool) as conn: # Insert unit-entity link await conn.execute( - """ - INSERT INTO unit_entities (unit_id, entity_id) + f""" + INSERT INTO {fq_table("unit_entities")} (unit_id, entity_id) VALUES ($1, $2) ON CONFLICT DO NOTHING """, @@ -441,9 +442,9 @@ class EntityResolver: # Update co-occurrence cache: find other entities in this unit rows = await conn.fetch( - """ + f""" SELECT entity_id - FROM unit_entities + FROM {fq_table("unit_entities")} WHERE unit_id = $1 AND entity_id != $2 """, unit_id, @@ -472,12 +473,12 @@ class EntityResolver: entity_id_1, entity_id_2 = entity_id_2, entity_id_1 await conn.execute( - """ - INSERT INTO entity_cooccurrences (entity_id_1, entity_id_2, cooccurrence_count, last_cooccurred) + f""" + INSERT INTO {fq_table("entity_cooccurrences")} (entity_id_1, entity_id_2, cooccurrence_count, last_cooccurred) VALUES ($1, $2, 1, NOW()) ON CONFLICT (entity_id_1, entity_id_2) DO UPDATE SET - cooccurrence_count = entity_cooccurrences.cooccurrence_count + 1, + cooccurrence_count = {fq_table("entity_cooccurrences")}.cooccurrence_count + 1, last_cooccurred = NOW() """, entity_id_1, @@ -506,8 +507,8 @@ class EntityResolver: async def _link_units_to_entities_batch_impl(self, conn, unit_entity_pairs: list[tuple[str, str]]): # Batch insert all unit-entity links await conn.executemany( - """ - INSERT INTO unit_entities (unit_id, entity_id) + f""" + INSERT INTO {fq_table("unit_entities")} (unit_id, entity_id) VALUES ($1, $2) ON CONFLICT DO NOTHING """, @@ -541,12 +542,12 @@ class EntityResolver: if cooccurrence_pairs: now = datetime.now(UTC) await conn.executemany( - """ - INSERT INTO entity_cooccurrences (entity_id_1, entity_id_2, cooccurrence_count, last_cooccurred) + f""" + INSERT INTO {fq_table("entity_cooccurrences")} (entity_id_1, entity_id_2, cooccurrence_count, last_cooccurred) VALUES ($1, $2, $3, $4) ON CONFLICT (entity_id_1, entity_id_2) DO UPDATE SET - cooccurrence_count = entity_cooccurrences.cooccurrence_count + 1, + cooccurrence_count = {fq_table("entity_cooccurrences")}.cooccurrence_count + 1, last_cooccurred = EXCLUDED.last_cooccurred """, [(e1, e2, 1, now) for e1, e2 in cooccurrence_pairs], @@ -565,9 +566,9 @@ class EntityResolver: """ async with acquire_with_retry(self.pool) as conn: rows = await conn.fetch( - """ + f""" SELECT unit_id - FROM unit_entities + FROM {fq_table("unit_entities")} WHERE entity_id = $1 ORDER BY unit_id LIMIT $2 @@ -594,8 +595,8 @@ class EntityResolver: """ async with acquire_with_retry(self.pool) as conn: row = await conn.fetchrow( - """ - SELECT id FROM entities + f""" + SELECT id FROM {fq_table("entities")} WHERE bank_id = $1 AND canonical_name ILIKE $2 ORDER BY mention_count DESC diff --git a/hindsight-api/hindsight_api/engine/interface.py b/hindsight-api/hindsight_api/engine/interface.py new file mode 100644 index 00000000..937f8ab3 --- /dev/null +++ b/hindsight-api/hindsight_api/engine/interface.py @@ -0,0 +1,592 @@ +"""Abstract interface for MemoryEngine public methods. + +This module defines the public API that HTTP endpoints and extensions should use +to interact with the memory system. All methods require a RequestContext for +authentication when a TenantExtension is configured. +""" + +from abc import ABC, abstractmethod +from datetime import datetime +from typing import TYPE_CHECKING, Any + +if TYPE_CHECKING: + from hindsight_api.engine.memory_engine import Budget + from hindsight_api.engine.response_models import RecallResult, ReflectResult + from hindsight_api.models import RequestContext + + +class MemoryEngineInterface(ABC): + """ + Abstract interface for the Memory Engine. + + This defines the public API that should be used by HTTP endpoints and extensions. + All methods require a RequestContext for authentication. + """ + + # ========================================================================= + # Health & Status + # ========================================================================= + + @abstractmethod + async def health_check(self) -> dict: + """ + Check the health of the memory system. + + Returns: + Dict with 'status' key ('healthy' or 'unhealthy') and additional info. + """ + ... + + # ========================================================================= + # Core Memory Operations + # ========================================================================= + + @abstractmethod + async def retain_batch_async( + self, + bank_id: str, + contents: list[dict[str, Any]], + *, + request_context: "RequestContext", + ) -> dict[str, Any]: + """ + Retain a batch of memory items. + + Args: + bank_id: The memory bank ID. + contents: List of content dicts with 'content', optional 'event_date', + 'context', 'metadata', 'document_id'. + request_context: Request context for authentication. + + Returns: + Dict with processing results. + """ + ... + + @abstractmethod + async def recall_async( + self, + bank_id: str, + query: str, + *, + budget: "Budget | None" = None, + max_tokens: int = 4096, + enable_trace: bool = False, + fact_type: list[str] | None = None, + question_date: datetime | None = None, + include_entities: bool = False, + max_entity_tokens: int = 500, + include_chunks: bool = False, + max_chunk_tokens: int = 8192, + request_context: "RequestContext", + ) -> "RecallResult": + """ + Recall memories relevant to a query. + + Args: + bank_id: The memory bank ID. + query: The search query. + budget: Search budget (LOW, MID, HIGH). + max_tokens: Maximum tokens in response. + enable_trace: Include trace information. + fact_type: Filter by fact types. + question_date: Context date for temporal relevance. + include_entities: Include entity observations. + max_entity_tokens: Max tokens for entity observations. + include_chunks: Include raw chunks. + max_chunk_tokens: Max tokens for chunks. + request_context: Request context for authentication. + + Returns: + RecallResult with matching memories. + """ + ... + + @abstractmethod + async def reflect_async( + self, + bank_id: str, + query: str, + *, + budget: "Budget | None" = None, + context: str | None = None, + request_context: "RequestContext", + ) -> "ReflectResult": + """ + Reflect on a query and generate a thoughtful response. + + Args: + bank_id: The memory bank ID. + query: The question to reflect on. + budget: Search budget for retrieving context. + context: Additional context for the reflection. + request_context: Request context for authentication. + + Returns: + ReflectResult with generated response and supporting facts. + """ + ... + + # ========================================================================= + # Bank Management + # ========================================================================= + + @abstractmethod + async def list_banks( + self, + *, + request_context: "RequestContext", + ) -> list[dict[str, Any]]: + """ + List all memory banks. + + Args: + request_context: Request context for authentication. + + Returns: + List of bank info dicts. + """ + ... + + @abstractmethod + async def get_bank_profile( + self, + bank_id: str, + *, + request_context: "RequestContext", + ) -> dict[str, Any]: + """ + Get bank profile including disposition and background. + + Args: + bank_id: The memory bank ID. + request_context: Request context for authentication. + + Returns: + Bank profile dict. + """ + ... + + @abstractmethod + async def update_bank_disposition( + self, + bank_id: str, + disposition: dict[str, int], + *, + request_context: "RequestContext", + ) -> None: + """ + Update bank disposition traits. + + Args: + bank_id: The memory bank ID. + disposition: Dict with trait values. + request_context: Request context for authentication. + """ + ... + + @abstractmethod + async def merge_bank_background( + self, + bank_id: str, + new_info: str, + *, + update_disposition: bool = True, + request_context: "RequestContext", + ) -> dict[str, Any]: + """ + Merge new background information into bank profile. + + Args: + bank_id: The memory bank ID. + new_info: New background information to merge. + update_disposition: Whether to infer disposition from background. + request_context: Request context for authentication. + + Returns: + Updated background info. + """ + ... + + @abstractmethod + async def delete_bank( + self, + bank_id: str, + *, + fact_type: str | None = None, + request_context: "RequestContext", + ) -> dict[str, int]: + """ + Delete a bank or its memories. + + Args: + bank_id: The memory bank ID. + fact_type: If specified, only delete memories of this type. + request_context: Request context for authentication. + + Returns: + Dict with deletion counts. + """ + ... + + # ========================================================================= + # Memory Units + # ========================================================================= + + @abstractmethod + async def list_memory_units( + self, + bank_id: str, + *, + fact_type: str | None = None, + search_query: str | None = None, + limit: int = 100, + offset: int = 0, + request_context: "RequestContext", + ) -> dict[str, Any]: + """ + List memory units with pagination. + + Args: + bank_id: The memory bank ID. + fact_type: Filter by fact type. + search_query: Full-text search query. + limit: Maximum results. + offset: Pagination offset. + request_context: Request context for authentication. + + Returns: + Dict with 'items', 'total', 'limit', 'offset'. + """ + ... + + @abstractmethod + async def delete_memory_unit( + self, + unit_id: str, + *, + request_context: "RequestContext", + ) -> dict[str, Any]: + """ + Delete a specific memory unit. + + Args: + unit_id: The memory unit ID. + request_context: Request context for authentication. + + Returns: + Deletion result. + """ + ... + + @abstractmethod + async def get_graph_data( + self, + bank_id: str, + *, + fact_type: str | None = None, + request_context: "RequestContext", + ) -> dict[str, Any]: + """ + Get graph data for visualization. + + Args: + bank_id: The memory bank ID. + fact_type: Filter by fact type. + request_context: Request context for authentication. + + Returns: + Dict with nodes, edges, table_rows, total_units. + """ + ... + + # ========================================================================= + # Documents + # ========================================================================= + + @abstractmethod + async def list_documents( + self, + bank_id: str, + *, + search_query: str | None = None, + limit: int = 100, + offset: int = 0, + request_context: "RequestContext", + ) -> dict[str, Any]: + """ + List documents with pagination. + + Args: + bank_id: The memory bank ID. + search_query: Search query. + limit: Maximum results. + offset: Pagination offset. + request_context: Request context for authentication. + + Returns: + Dict with 'items', 'total', 'limit', 'offset'. + """ + ... + + @abstractmethod + async def get_document( + self, + document_id: str, + bank_id: str, + *, + request_context: "RequestContext", + ) -> dict[str, Any] | None: + """ + Get a specific document. + + Args: + document_id: The document ID. + bank_id: The memory bank ID. + request_context: Request context for authentication. + + Returns: + Document dict or None if not found. + """ + ... + + @abstractmethod + async def delete_document( + self, + document_id: str, + bank_id: str, + *, + request_context: "RequestContext", + ) -> dict[str, int]: + """ + Delete a document and its memory units. + + Args: + document_id: The document ID. + bank_id: The memory bank ID. + request_context: Request context for authentication. + + Returns: + Dict with deletion counts. + """ + ... + + @abstractmethod + async def get_chunk( + self, + chunk_id: str, + *, + request_context: "RequestContext", + ) -> dict[str, Any] | None: + """ + Get a specific chunk. + + Args: + chunk_id: The chunk ID. + request_context: Request context for authentication. + + Returns: + Chunk dict or None if not found. + """ + ... + + # ========================================================================= + # Entities + # ========================================================================= + + @abstractmethod + async def list_entities( + self, + bank_id: str, + *, + limit: int = 100, + request_context: "RequestContext", + ) -> list[dict[str, Any]]: + """ + List entities for a bank. + + Args: + bank_id: The memory bank ID. + limit: Maximum results. + request_context: Request context for authentication. + + Returns: + List of entity dicts. + """ + ... + + @abstractmethod + async def get_entity_observations( + self, + bank_id: str, + entity_id: str, + *, + limit: int = 10, + request_context: "RequestContext", + ) -> list[Any]: + """ + Get observations for an entity. + + Args: + bank_id: The memory bank ID. + entity_id: The entity ID. + limit: Maximum observations. + request_context: Request context for authentication. + + Returns: + List of EntityObservation objects. + """ + ... + + @abstractmethod + async def regenerate_entity_observations( + self, + bank_id: str, + entity_id: str, + entity_name: str, + *, + request_context: "RequestContext", + ) -> None: + """ + Regenerate observations for an entity. + + Args: + bank_id: The memory bank ID. + entity_id: The entity ID. + entity_name: The entity's canonical name. + request_context: Request context for authentication. + """ + ... + + # ========================================================================= + # Statistics & Operations + # ========================================================================= + + @abstractmethod + async def get_bank_stats( + self, + bank_id: str, + *, + request_context: "RequestContext", + ) -> dict[str, Any]: + """ + Get statistics about memory nodes and links for a bank. + + Args: + bank_id: The memory bank ID. + request_context: Request context for authentication. + + Returns: + Dict with node_counts, link_counts, link_counts_by_fact_type, + link_breakdown, and operations stats. + """ + ... + + @abstractmethod + async def get_entity( + self, + bank_id: str, + entity_id: str, + *, + request_context: "RequestContext", + ) -> dict[str, Any] | None: + """ + Get entity details including metadata and observations. + + Args: + bank_id: The memory bank ID. + entity_id: The entity ID. + request_context: Request context for authentication. + + Returns: + Entity dict with id, canonical_name, mention_count, first_seen, + last_seen, metadata, and observations. None if not found. + """ + ... + + @abstractmethod + async def list_operations( + self, + bank_id: str, + *, + request_context: "RequestContext", + ) -> list[dict[str, Any]]: + """ + List async operations for a bank. + + Args: + bank_id: The memory bank ID. + request_context: Request context for authentication. + + Returns: + List of operation dicts with id, task_type, status, etc. + """ + ... + + @abstractmethod + async def cancel_operation( + self, + bank_id: str, + operation_id: str, + *, + request_context: "RequestContext", + ) -> dict[str, Any]: + """ + Cancel a pending async operation. + + Args: + bank_id: The memory bank ID. + operation_id: The operation ID to cancel. + request_context: Request context for authentication. + + Returns: + Dict with success status and message. + + Raises: + ValueError: If operation not found. + """ + ... + + @abstractmethod + async def update_bank( + self, + bank_id: str, + *, + name: str | None = None, + background: str | None = None, + request_context: "RequestContext", + ) -> dict[str, Any]: + """ + Update bank name and/or background. + + Args: + bank_id: The memory bank ID. + name: New bank name (optional). + background: New background text (optional, replaces existing). + request_context: Request context for authentication. + + Returns: + Updated bank profile dict. + """ + ... + + @abstractmethod + async def submit_async_retain( + self, + bank_id: str, + contents: list[dict[str, Any]], + *, + request_context: "RequestContext", + ) -> dict[str, Any]: + """ + Submit a batch retain operation to run asynchronously. + + Args: + bank_id: The memory bank ID. + contents: List of content dicts to retain. + request_context: Request context for authentication. + + Returns: + Dict with operation_id and items_count. + """ + ... diff --git a/hindsight-api/hindsight_api/engine/llm_wrapper.py b/hindsight-api/hindsight_api/engine/llm_wrapper.py index b0cb2755..bbeb3a87 100644 --- a/hindsight-api/hindsight_api/engine/llm_wrapper.py +++ b/hindsight-api/hindsight_api/engine/llm_wrapper.py @@ -96,7 +96,7 @@ class LLMProvider: client_kwargs = {"api_key": self.api_key, "max_retries": 0} if self.base_url: client_kwargs["base_url"] = self.base_url - self._client = AsyncOpenAI(**client_kwargs) + self._client = AsyncOpenAI(**client_kwargs) # type: ignore[invalid-argument-type] - dict kwargs self._gemini_client = None async def verify_connection(self) -> None: @@ -467,6 +467,8 @@ class LLMProvider: """Create provider for memory operations from environment variables.""" provider = os.getenv("HINDSIGHT_API_LLM_PROVIDER", "groq") api_key = os.getenv("HINDSIGHT_API_LLM_API_KEY") + if not api_key: + raise ValueError("HINDSIGHT_API_LLM_API_KEY environment variable is required") base_url = os.getenv("HINDSIGHT_API_LLM_BASE_URL", "") model = os.getenv("HINDSIGHT_API_LLM_MODEL", "openai/gpt-oss-120b") @@ -477,6 +479,10 @@ class LLMProvider: """Create provider for answer generation. Falls back to memory config if not set.""" provider = os.getenv("HINDSIGHT_API_ANSWER_LLM_PROVIDER", os.getenv("HINDSIGHT_API_LLM_PROVIDER", "groq")) api_key = os.getenv("HINDSIGHT_API_ANSWER_LLM_API_KEY", os.getenv("HINDSIGHT_API_LLM_API_KEY")) + if not api_key: + raise ValueError( + "HINDSIGHT_API_LLM_API_KEY or HINDSIGHT_API_ANSWER_LLM_API_KEY environment variable is required" + ) base_url = os.getenv("HINDSIGHT_API_ANSWER_LLM_BASE_URL", os.getenv("HINDSIGHT_API_LLM_BASE_URL", "")) model = os.getenv("HINDSIGHT_API_ANSWER_LLM_MODEL", os.getenv("HINDSIGHT_API_LLM_MODEL", "openai/gpt-oss-120b")) @@ -487,6 +493,10 @@ class LLMProvider: """Create provider for judge/evaluator operations. Falls back to memory config if not set.""" provider = os.getenv("HINDSIGHT_API_JUDGE_LLM_PROVIDER", os.getenv("HINDSIGHT_API_LLM_PROVIDER", "groq")) api_key = os.getenv("HINDSIGHT_API_JUDGE_LLM_API_KEY", os.getenv("HINDSIGHT_API_LLM_API_KEY")) + if not api_key: + raise ValueError( + "HINDSIGHT_API_LLM_API_KEY or HINDSIGHT_API_JUDGE_LLM_API_KEY environment variable is required" + ) base_url = os.getenv("HINDSIGHT_API_JUDGE_LLM_BASE_URL", os.getenv("HINDSIGHT_API_LLM_BASE_URL", "")) model = os.getenv("HINDSIGHT_API_JUDGE_LLM_MODEL", os.getenv("HINDSIGHT_API_LLM_MODEL", "openai/gpt-oss-120b")) diff --git a/hindsight-api/hindsight_api/engine/memory_engine.py b/hindsight-api/hindsight_api/engine/memory_engine.py index 65c9e483..f5b3d514 100644 --- a/hindsight-api/hindsight_api/engine/memory_engine.py +++ b/hindsight-api/hindsight_api/engine/memory_engine.py @@ -10,11 +10,110 @@ This implements a sophisticated memory architecture that combines: """ import asyncio +import contextvars import logging import time import uuid from datetime import UTC, datetime, timedelta -from typing import TYPE_CHECKING, Any, TypedDict +from typing import TYPE_CHECKING, Any + +# Context variable for current schema (async-safe, per-task isolation) +_current_schema: contextvars.ContextVar[str] = contextvars.ContextVar("current_schema", default="public") + + +def get_current_schema() -> str: + """Get the current schema from context (default: 'public').""" + return _current_schema.get() + + +def fq_table(table_name: str) -> str: + """ + Get fully-qualified table name with current schema. + + Example: + fq_table("memory_units") -> "public.memory_units" + fq_table("memory_units") -> "tenant_xyz.memory_units" (if schema is set) + """ + return f"{get_current_schema()}.{table_name}" + + +# Tables that must be schema-qualified (for runtime validation) +_PROTECTED_TABLES = frozenset( + [ + "memory_units", + "memory_links", + "unit_entities", + "entities", + "entity_cooccurrences", + "banks", + "documents", + "chunks", + "async_operations", + ] +) + +# Enable runtime SQL validation (can be disabled in production for performance) +_VALIDATE_SQL_SCHEMAS = True + + +class UnqualifiedTableError(Exception): + """Raised when SQL contains unqualified table references.""" + + pass + + +def validate_sql_schema(sql: str) -> None: + """ + Validate that SQL doesn't contain unqualified table references. + + This is a runtime safety check to prevent cross-tenant data access. + Raises UnqualifiedTableError if any protected table is referenced + without a schema prefix. + + Args: + sql: The SQL query to validate + + Raises: + UnqualifiedTableError: If unqualified table reference found + """ + if not _VALIDATE_SQL_SCHEMAS: + return + + import re + + sql_upper = sql.upper() + + for table in _PROTECTED_TABLES: + table_upper = table.upper() + + # Pattern: SQL keyword followed by unqualified table name + # Matches: FROM memory_units, JOIN memory_units, INTO memory_units, UPDATE memory_units + patterns = [ + rf"FROM\s+{table_upper}(?:\s|$|,|\)|;)", + rf"JOIN\s+{table_upper}(?:\s|$|,|\)|;)", + rf"INTO\s+{table_upper}(?:\s|$|\()", + rf"UPDATE\s+{table_upper}(?:\s|$)", + rf"DELETE\s+FROM\s+{table_upper}(?:\s|$|;)", + ] + + for pattern in patterns: + match = re.search(pattern, sql_upper) + if match: + # Check if it's actually qualified (preceded by schema.) + # Look backwards from match to see if there's a dot + start = match.start() + # Find the table name position in the match + table_pos = sql_upper.find(table_upper, start) + if table_pos > 0: + # Check character before table name (skip whitespace) + prefix = sql[:table_pos].rstrip() + if not prefix.endswith("."): + raise UnqualifiedTableError( + f"Unqualified table reference '{table}' in SQL. " + f"Use fq_table('{table}') for schema safety. " + f"SQL snippet: ...{sql[max(0, start - 10) : start + 50]}..." + ) + import asyncpg import numpy as np @@ -22,27 +121,11 @@ from pydantic import BaseModel, Field from .cross_encoder import CrossEncoderModel from .embeddings import Embeddings, create_embeddings_from_env +from .interface import MemoryEngineInterface if TYPE_CHECKING: - pass - - -class RetainContentDict(TypedDict, total=False): - """Type definition for content items in retain_batch_async. - - Fields: - content: Text content to store (required) - context: Context about the content (optional) - event_date: When the content occurred (optional, defaults to now) - metadata: Custom key-value metadata (optional) - document_id: Document ID for this content item (optional) - """ - - content: str # Required - context: str - event_date: datetime - metadata: dict[str, str] - document_id: str + from hindsight_api.extensions import OperationValidatorExtension, TenantExtension + from hindsight_api.models import RequestContext from enum import Enum @@ -54,6 +137,7 @@ from .query_analyzer import QueryAnalyzer from .response_models import VALID_RECALL_FACT_TYPES, EntityObservation, EntityState, MemoryFact, ReflectResult from .response_models import RecallResult as RecallResultModel from .retain import bank_utils, embedding_utils +from .retain.types import RetainContentDict from .search import observation_utils, think_utils from .search.reranking import CrossEncoderReranker from .task_backend import AsyncIOQueueBackend, TaskBackend @@ -91,7 +175,7 @@ def _get_tiktoken_encoding(): return _TIKTOKEN_ENCODING -class MemoryEngine: +class MemoryEngine(MemoryEngineInterface): """ Advanced memory system using temporal and semantic linking with PostgreSQL. @@ -116,6 +200,8 @@ class MemoryEngine: pool_max_size: int = 100, task_backend: TaskBackend | None = None, run_migrations: bool = True, + operation_validator: "OperationValidatorExtension | None" = None, + tenant_extension: "TenantExtension | None" = None, ): """ Initialize the temporal + semantic memory system. @@ -137,6 +223,10 @@ class MemoryEngine: pool_max_size: Maximum number of connections in the pool (default: 100) task_backend: Custom task backend. If not provided, uses AsyncIOQueueBackend. run_migrations: Whether to run database migrations during initialize(). Default: True + operation_validator: Optional extension to validate operations before execution. + If provided, retain/recall/reflect operations will be validated. + tenant_extension: Optional extension for multi-tenancy and API key authentication. + If provided, operations require a RequestContext for authentication. """ # Load config from environment for any missing parameters from ..config import get_config @@ -147,6 +237,8 @@ class MemoryEngine: db_url = db_url or config.database_url memory_llm_provider = memory_llm_provider or config.llm_provider memory_llm_api_key = memory_llm_api_key or config.llm_api_key + if not memory_llm_api_key: + raise ValueError("LLM API key is required. Set HINDSIGHT_API_LLM_API_KEY environment variable.") memory_llm_model = memory_llm_model or config.llm_model memory_llm_base_url = memory_llm_base_url or config.get_llm_base_url() or None # Track pg0 instance (if used) @@ -243,6 +335,60 @@ class MemoryEngine: # initialize encoding eagerly to avoid delaying the first time _get_tiktoken_encoding() + # Store operation validator extension (optional) + self._operation_validator = operation_validator + + # Store tenant extension (optional) + self._tenant_extension = tenant_extension + + async def _validate_operation(self, validation_coro) -> None: + """ + Run validation if an operation validator is configured. + + Args: + validation_coro: Coroutine that returns a ValidationResult + + Raises: + OperationValidationError: If validation fails + """ + if self._operation_validator is None: + return + + from hindsight_api.extensions import OperationValidationError + + result = await validation_coro + if not result.allowed: + raise OperationValidationError(result.reason or "Operation not allowed") + + async def _authenticate_tenant(self, request_context: "RequestContext | None") -> str: + """ + Authenticate tenant and set schema in context variable. + + The schema is stored in a contextvar for async-safe, per-task isolation. + Use fq_table(table_name) to get fully-qualified table names. + + Args: + request_context: The request context with API key. Required if tenant_extension is configured. + + Returns: + Schema name that was set in the context. + + Raises: + AuthenticationError: If authentication fails or request_context is missing when required. + """ + if self._tenant_extension is None: + _current_schema.set("public") + return "public" + + from hindsight_api.extensions import AuthenticationError + + if request_context is None: + raise AuthenticationError("RequestContext is required when tenant extension is configured") + + tenant_context = await self._tenant_extension.authenticate(request_context) + _current_schema.set(tenant_context.schema_name) + return tenant_context.schema_name + async def _handle_access_count_update(self, task_dict: dict[str, Any]): """ Handler for access count update tasks. @@ -260,7 +406,8 @@ class MemoryEngine: uuid_list = [uuid.UUID(nid) for nid in node_ids] async with acquire_with_retry(pool) as conn: await conn.execute( - "UPDATE memory_units SET access_count = access_count + 1 WHERE id = ANY($1::uuid[])", uuid_list + f"UPDATE {fq_table('memory_units')} SET access_count = access_count + 1 WHERE id = ANY($1::uuid[])", + uuid_list, ) except Exception as e: logger.error(f"Access count handler: Error updating access counts: {e}") @@ -274,13 +421,19 @@ class MemoryEngine: """ try: bank_id = task_dict.get("bank_id") + if not bank_id: + raise ValueError("bank_id is required for batch retain task") contents = task_dict.get("contents", []) logger.info( f"[BATCH_RETAIN_TASK] Starting background batch retain for bank_id={bank_id}, {len(contents)} items" ) - await self.retain_batch_async(bank_id=bank_id, contents=contents) + # Use internal request context for background tasks + from hindsight_api.models import RequestContext + + internal_context = RequestContext() + await self.retain_batch_async(bank_id=bank_id, contents=contents, request_context=internal_context) logger.info(f"[BATCH_RETAIN_TASK] Completed background batch retain for bank_id={bank_id}") except Exception as e: @@ -311,7 +464,8 @@ class MemoryEngine: pool = await self._get_pool() async with acquire_with_retry(pool) as conn: result = await conn.fetchrow( - "SELECT operation_id FROM async_operations WHERE operation_id = $1", uuid.UUID(operation_id) + f"SELECT operation_id FROM {fq_table('async_operations')} WHERE operation_id = $1", + uuid.UUID(operation_id), ) if not result: # Operation was cancelled, skip processing @@ -369,7 +523,9 @@ class MemoryEngine: try: pool = await self._get_pool() async with acquire_with_retry(pool) as conn: - await conn.execute("DELETE FROM async_operations WHERE operation_id = $1", uuid.UUID(operation_id)) + await conn.execute( + f"DELETE FROM {fq_table('async_operations')} WHERE operation_id = $1", uuid.UUID(operation_id) + ) except Exception as e: logger.error(f"Failed to delete async operation record {operation_id}: {e}") @@ -383,8 +539,8 @@ class MemoryEngine: async with acquire_with_retry(pool) as conn: await conn.execute( - """ - UPDATE async_operations + f""" + UPDATE {fq_table("async_operations")} SET status = 'failed', error_message = $2 WHERE operation_id = $1 """, @@ -413,7 +569,7 @@ class MemoryEngine: kwargs = {"name": self._pg0_instance_name} if self._pg0_port is not None: kwargs["port"] = self._pg0_port - pg0 = EmbeddedPostgres(**kwargs) + pg0 = EmbeddedPostgres(**kwargs) # type: ignore[invalid-argument-type] - dict kwargs # Check if pg0 is already running before we start it was_already_running = await pg0.is_running() self.db_url = await pg0.ensure_running() @@ -460,6 +616,8 @@ class MemoryEngine: if self._run_migrations: from ..migrations import run_migrations + if not self.db_url: + raise ValueError("Database URL is required for migrations") logger.info("Running database migrations...") run_migrations(self.db_url) @@ -628,9 +786,9 @@ class MemoryEngine: fetch_start = time_mod.time() existing_facts = await conn.fetch( - """ + f""" SELECT id, text, embedding - FROM memory_units + FROM {fq_table("memory_units")} WHERE bank_id = $1 AND event_date BETWEEN $2 AND $3 """, @@ -692,6 +850,7 @@ class MemoryEngine: content: str, context: str = "", event_date: datetime | None = None, + request_context: "RequestContext | None" = None, ) -> list[str]: """ Store content as memory units (synchronous wrapper). @@ -704,12 +863,16 @@ class MemoryEngine: content: Text content to store context: Context about when/why this memory was formed event_date: When the event occurred (defaults to now) + request_context: Request context for authentication (optional, uses internal context if not provided) Returns: List of created unit IDs """ # Run async version synchronously - return asyncio.run(self.retain_async(bank_id, content, context, event_date)) + from hindsight_api.models import RequestContext as RC + + ctx = request_context if request_context is not None else RC() + return asyncio.run(self.retain_async(bank_id, content, context, event_date, request_context=ctx)) async def retain_async( self, @@ -720,6 +883,8 @@ class MemoryEngine: document_id: str | None = None, fact_type_override: str | None = None, confidence_score: float | None = None, + *, + request_context: "RequestContext", ) -> list[str]: """ Store content as memory units with temporal and semantic links (ASYNC version). @@ -734,12 +899,15 @@ class MemoryEngine: document_id: Optional document ID for tracking (always upserts if document already exists) fact_type_override: Override fact type ('world', 'experience', 'opinion') confidence_score: Confidence score for opinions (0.0 to 1.0) + request_context: Request context for authentication. Returns: List of created unit IDs """ # Build content dict - content_dict: RetainContentDict = {"content": content, "context": context, "event_date": event_date} + content_dict: RetainContentDict = {"content": content, "context": context} # type: ignore[typeddict-item] - building incrementally + if event_date: + content_dict["event_date"] = event_date if document_id: content_dict["document_id"] = document_id @@ -747,6 +915,7 @@ class MemoryEngine: result = await self.retain_batch_async( bank_id=bank_id, contents=[content_dict], + request_context=request_context, fact_type_override=fact_type_override, confidence_score=confidence_score, ) @@ -758,6 +927,8 @@ class MemoryEngine: self, bank_id: str, contents: list[RetainContentDict], + *, + request_context: "RequestContext", document_id: str | None = None, fact_type_override: str | None = None, confidence_score: float | None = None, @@ -813,6 +984,24 @@ class MemoryEngine: if not contents: return [] + # Authenticate tenant and set schema in context (for fq_table()) + await self._authenticate_tenant(request_context) + + # Validate operation if validator is configured + contents_copy = [dict(c) for c in contents] # Convert TypedDict to regular dict for extension + if self._operation_validator: + from hindsight_api.extensions import RetainContext + + ctx = RetainContext( + bank_id=bank_id, + contents=contents_copy, + request_context=request_context, + document_id=document_id, + fact_type_override=fact_type_override, + confidence_score=confidence_score, + ) + await self._validate_operation(self._operation_validator.validate_retain(ctx)) + # Apply batch-level document_id to contents that don't have their own (backwards compatibility) if document_id: for item in contents: @@ -876,17 +1065,39 @@ class MemoryEngine: logger.info( f"RETAIN_BATCH_ASYNC (chunked) COMPLETE: {len(all_results)} results from {len(contents)} contents in {total_time:.3f}s" ) - return all_results + result = all_results + else: + # Small batch - use internal method directly + result = await self._retain_batch_async_internal( + bank_id=bank_id, + contents=contents, + document_id=document_id, + is_first_batch=True, + fact_type_override=fact_type_override, + confidence_score=confidence_score, + ) - # Small batch - use internal method directly - return await self._retain_batch_async_internal( - bank_id=bank_id, - contents=contents, - document_id=document_id, - is_first_batch=True, - fact_type_override=fact_type_override, - confidence_score=confidence_score, - ) + # Call post-operation hook if validator is configured + if self._operation_validator: + from hindsight_api.extensions import RetainResult + + result_ctx = RetainResult( + bank_id=bank_id, + contents=contents_copy, + request_context=request_context, + document_id=document_id, + fact_type_override=fact_type_override, + confidence_score=confidence_score, + unit_ids=result, + success=True, + error=None, + ) + try: + await self._operation_validator.on_retain_complete(result_ctx) + except Exception as e: + logger.warning(f"Post-retain hook error (non-fatal): {e}") + + return result async def _retain_batch_async_internal( self, @@ -961,22 +1172,36 @@ class MemoryEngine: Returns: Tuple of (results, trace) """ - # Run async version synchronously - return asyncio.run(self.recall_async(bank_id, query, [fact_type], budget, max_tokens, enable_trace)) + # Run async version synchronously - deprecated sync method, passing None for request_context + from hindsight_api.models import RequestContext + + return asyncio.run( + self.recall_async( + bank_id, + query, + budget=budget, + max_tokens=max_tokens, + enable_trace=enable_trace, + fact_type=[fact_type], + request_context=RequestContext(), + ) + ) async def recall_async( self, bank_id: str, query: str, - fact_type: list[str], - budget: Budget = Budget.MID, + *, + budget: Budget | None = None, max_tokens: int = 4096, enable_trace: bool = False, + fact_type: list[str] | None = None, question_date: datetime | None = None, include_entities: bool = False, - max_entity_tokens: int = 1024, + max_entity_tokens: int = 500, include_chunks: bool = False, max_chunk_tokens: int = 8192, + request_context: "RequestContext", ) -> RecallResultModel: """ Recall memories using N*4-way parallel retrieval (N fact types × 4 retrieval methods). @@ -1010,6 +1235,13 @@ class MemoryEngine: - entities: Optional dict of entity states (if include_entities=True) - chunks: Optional dict of chunks (if include_chunks=True) """ + # Authenticate tenant and set schema in context (for fq_table()) + await self._authenticate_tenant(request_context) + + # Default to all fact types if not specified + if fact_type is None: + fact_type = list(VALID_RECALL_FACT_TYPES) + # Validate fact types early invalid_types = set(fact_type) - VALID_RECALL_FACT_TYPES if invalid_types: @@ -1018,17 +1250,40 @@ class MemoryEngine: f"Must be one of: {', '.join(sorted(VALID_RECALL_FACT_TYPES))}" ) - # Map budget enum to thinking_budget number + # Validate operation if validator is configured + if self._operation_validator: + from hindsight_api.extensions import RecallContext + + ctx = RecallContext( + bank_id=bank_id, + query=query, + request_context=request_context, + budget=budget, + max_tokens=max_tokens, + enable_trace=enable_trace, + fact_types=list(fact_type), + question_date=question_date, + include_entities=include_entities, + max_entity_tokens=max_entity_tokens, + include_chunks=include_chunks, + max_chunk_tokens=max_chunk_tokens, + ) + await self._validate_operation(self._operation_validator.validate_recall(ctx)) + + # Map budget enum to thinking_budget number (default to MID if None) budget_mapping = {Budget.LOW: 100, Budget.MID: 300, Budget.HIGH: 1000} - thinking_budget = budget_mapping[budget] + effective_budget = budget if budget is not None else Budget.MID + thinking_budget = budget_mapping[effective_budget] # Backpressure: limit concurrent recalls to prevent overwhelming the database + result = None + error_msg = None async with self._search_semaphore: # Retry loop for connection errors max_retries = 3 for attempt in range(max_retries + 1): try: - return await self._search_with_retries( + result = await self._search_with_retries( bank_id, query, fact_type, @@ -1040,7 +1295,9 @@ class MemoryEngine: max_entity_tokens, include_chunks, max_chunk_tokens, + request_context, ) + break # Success - exit retry loop except Exception as e: # Check if it's a connection error is_connection_error = ( @@ -1058,9 +1315,89 @@ class MemoryEngine: ) await asyncio.sleep(wait_time) else: - # Not a connection error or out of retries - raise + # Not a connection error or out of retries - call post-hook and raise + error_msg = str(e) + if self._operation_validator: + from hindsight_api.extensions.operation_validator import RecallResult + + result_ctx = RecallResult( + bank_id=bank_id, + query=query, + request_context=request_context, + budget=budget, + max_tokens=max_tokens, + enable_trace=enable_trace, + fact_types=list(fact_type), + question_date=question_date, + include_entities=include_entities, + max_entity_tokens=max_entity_tokens, + include_chunks=include_chunks, + max_chunk_tokens=max_chunk_tokens, + result=None, + success=False, + error=error_msg, + ) + try: + await self._operation_validator.on_recall_complete(result_ctx) + except Exception as hook_err: + logger.warning(f"Post-recall hook error (non-fatal): {hook_err}") raise - raise Exception("Exceeded maximum retries for search due to connection errors.") + else: + # Exceeded max retries + error_msg = "Exceeded maximum retries for search due to connection errors." + if self._operation_validator: + from hindsight_api.extensions.operation_validator import RecallResult + + result_ctx = RecallResult( + bank_id=bank_id, + query=query, + request_context=request_context, + budget=budget, + max_tokens=max_tokens, + enable_trace=enable_trace, + fact_types=list(fact_type), + question_date=question_date, + include_entities=include_entities, + max_entity_tokens=max_entity_tokens, + include_chunks=include_chunks, + max_chunk_tokens=max_chunk_tokens, + result=None, + success=False, + error=error_msg, + ) + try: + await self._operation_validator.on_recall_complete(result_ctx) + except Exception as hook_err: + logger.warning(f"Post-recall hook error (non-fatal): {hook_err}") + raise Exception(error_msg) + + # Call post-operation hook for success + if self._operation_validator and result is not None: + from hindsight_api.extensions.operation_validator import RecallResult + + result_ctx = RecallResult( + bank_id=bank_id, + query=query, + request_context=request_context, + budget=budget, + max_tokens=max_tokens, + enable_trace=enable_trace, + fact_types=list(fact_type), + question_date=question_date, + include_entities=include_entities, + max_entity_tokens=max_entity_tokens, + include_chunks=include_chunks, + max_chunk_tokens=max_chunk_tokens, + result=result, + success=True, + error=None, + ) + try: + await self._operation_validator.on_recall_complete(result_ctx) + except Exception as e: + logger.warning(f"Post-recall hook error (non-fatal): {e}") + + return result async def _search_with_retries( self, @@ -1075,6 +1412,7 @@ class MemoryEngine: max_entity_tokens: int = 500, include_chunks: bool = False, max_chunk_tokens: int = 8192, + request_context: "RequestContext" = None, ) -> RecallResultModel: """ Search implementation with modular retrieval and reranking. @@ -1465,10 +1803,10 @@ class MemoryEngine: if unit_ids: async with acquire_with_retry(pool) as entity_conn: entity_rows = await entity_conn.fetch( - """ + f""" SELECT ue.unit_id, e.id as entity_id, e.canonical_name - FROM unit_entities ue - JOIN entities e ON ue.entity_id = e.id + FROM {fq_table("unit_entities")} ue + JOIN {fq_table("entities")} e ON ue.entity_id = e.id WHERE ue.unit_id = ANY($1::uuid[]) """, unit_ids, @@ -1534,7 +1872,9 @@ class MemoryEngine: if total_entity_tokens >= max_entity_tokens: break - observations = await self.get_entity_observations(bank_id, entity_id, limit=5) + observations = await self.get_entity_observations( + bank_id, entity_id, limit=5, request_context=request_context + ) # Calculate tokens for this entity's observations entity_tokens = 0 @@ -1572,9 +1912,9 @@ class MemoryEngine: # Fetch chunk data from database using chunk_ids (no ORDER BY to preserve input order) async with acquire_with_retry(pool) as conn: chunks_rows = await conn.fetch( - """ + f""" SELECT chunk_id, chunk_text, chunk_index - FROM chunks + FROM {fq_table("chunks")} WHERE chunk_id = ANY($1::text[]) """, chunk_ids_ordered, @@ -1671,25 +2011,33 @@ class MemoryEngine: return filtered_results, total_tokens - async def get_document(self, document_id: str, bank_id: str) -> dict[str, Any] | None: + async def get_document( + self, + document_id: str, + bank_id: str, + *, + request_context: "RequestContext", + ) -> dict[str, Any] | None: """ Retrieve document metadata and statistics. Args: document_id: Document ID to retrieve bank_id: bank ID that owns the document + request_context: Request context for authentication. Returns: Dictionary with document info or None if not found """ + await self._authenticate_tenant(request_context) pool = await self._get_pool() async with acquire_with_retry(pool) as conn: doc = await conn.fetchrow( - """ + f""" SELECT d.id, d.bank_id, d.original_text, d.content_hash, d.created_at, d.updated_at, COUNT(mu.id) as unit_count - FROM documents d - LEFT JOIN memory_units mu ON mu.document_id = d.id + FROM {fq_table("documents")} d + LEFT JOIN {fq_table("memory_units")} mu ON mu.document_id = d.id WHERE d.id = $1 AND d.bank_id = $2 GROUP BY d.id, d.bank_id, d.original_text, d.content_hash, d.created_at, d.updated_at """, @@ -1706,37 +2054,52 @@ class MemoryEngine: "original_text": doc["original_text"], "content_hash": doc["content_hash"], "memory_unit_count": doc["unit_count"], - "created_at": doc["created_at"], - "updated_at": doc["updated_at"], + "created_at": doc["created_at"].isoformat() if doc["created_at"] else None, + "updated_at": doc["updated_at"].isoformat() if doc["updated_at"] else None, } - async def delete_document(self, document_id: str, bank_id: str) -> dict[str, int]: + async def delete_document( + self, + document_id: str, + bank_id: str, + *, + request_context: "RequestContext", + ) -> dict[str, int]: """ Delete a document and all its associated memory units and links. Args: document_id: Document ID to delete bank_id: bank ID that owns the document + request_context: Request context for authentication. Returns: Dictionary with counts of deleted items """ + await self._authenticate_tenant(request_context) pool = await self._get_pool() async with acquire_with_retry(pool) as conn: async with conn.transaction(): # Count units before deletion units_count = await conn.fetchval( - "SELECT COUNT(*) FROM memory_units WHERE document_id = $1", document_id + f"SELECT COUNT(*) FROM {fq_table('memory_units')} WHERE document_id = $1", document_id ) # Delete document (cascades to memory_units and all their links) deleted = await conn.fetchval( - "DELETE FROM documents WHERE id = $1 AND bank_id = $2 RETURNING id", document_id, bank_id + f"DELETE FROM {fq_table('documents')} WHERE id = $1 AND bank_id = $2 RETURNING id", + document_id, + bank_id, ) return {"document_deleted": 1 if deleted else 0, "memory_units_deleted": units_count if deleted else 0} - async def delete_memory_unit(self, unit_id: str) -> dict[str, Any]: + async def delete_memory_unit( + self, + unit_id: str, + *, + request_context: "RequestContext", + ) -> dict[str, Any]: """ Delete a single memory unit and all its associated links. @@ -1747,15 +2110,19 @@ class MemoryEngine: Args: unit_id: UUID of the memory unit to delete + request_context: Request context for authentication. Returns: Dictionary with deletion result """ + await self._authenticate_tenant(request_context) pool = await self._get_pool() async with acquire_with_retry(pool) as conn: async with conn.transaction(): # Delete the memory unit (cascades to links and associations) - deleted = await conn.fetchval("DELETE FROM memory_units WHERE id = $1 RETURNING id", unit_id) + deleted = await conn.fetchval( + f"DELETE FROM {fq_table('memory_units')} WHERE id = $1 RETURNING id", unit_id + ) return { "success": deleted is not None, @@ -1765,7 +2132,13 @@ class MemoryEngine: else "Memory unit not found", } - async def delete_bank(self, bank_id: str, fact_type: str | None = None) -> dict[str, int]: + async def delete_bank( + self, + bank_id: str, + fact_type: str | None = None, + *, + request_context: "RequestContext", + ) -> dict[str, int]: """ Delete all data for a specific agent (multi-tenant cleanup). @@ -1780,10 +2153,12 @@ class MemoryEngine: Args: bank_id: bank ID to delete fact_type: Optional fact type filter (world, experience, opinion). If provided, only deletes memories of that type. + request_context: Request context for authentication. Returns: Dictionary with counts of deleted items """ + await self._authenticate_tenant(request_context) pool = await self._get_pool() async with acquire_with_retry(pool) as conn: # Ensure connection is not in read-only mode (can happen with connection poolers) @@ -1793,12 +2168,14 @@ class MemoryEngine: if fact_type: # Delete only memories of a specific fact type units_count = await conn.fetchval( - "SELECT COUNT(*) FROM memory_units WHERE bank_id = $1 AND fact_type = $2", + f"SELECT COUNT(*) FROM {fq_table('memory_units')} WHERE bank_id = $1 AND fact_type = $2", bank_id, fact_type, ) await conn.execute( - "DELETE FROM memory_units WHERE bank_id = $1 AND fact_type = $2", bank_id, fact_type + f"DELETE FROM {fq_table('memory_units')} WHERE bank_id = $1 AND fact_type = $2", + bank_id, + fact_type, ) # Note: We don't delete entities when fact_type is specified, @@ -1807,26 +2184,26 @@ class MemoryEngine: else: # Delete all data for the bank units_count = await conn.fetchval( - "SELECT COUNT(*) FROM memory_units WHERE bank_id = $1", bank_id + f"SELECT COUNT(*) FROM {fq_table('memory_units')} WHERE bank_id = $1", bank_id ) entities_count = await conn.fetchval( - "SELECT COUNT(*) FROM entities WHERE bank_id = $1", bank_id + f"SELECT COUNT(*) FROM {fq_table('entities')} WHERE bank_id = $1", bank_id ) documents_count = await conn.fetchval( - "SELECT COUNT(*) FROM documents WHERE bank_id = $1", bank_id + f"SELECT COUNT(*) FROM {fq_table('documents')} WHERE bank_id = $1", bank_id ) # Delete documents (cascades to chunks) - await conn.execute("DELETE FROM documents WHERE bank_id = $1", bank_id) + await conn.execute(f"DELETE FROM {fq_table('documents')} WHERE bank_id = $1", bank_id) # Delete memory units (cascades to unit_entities, memory_links) - await conn.execute("DELETE FROM memory_units WHERE bank_id = $1", bank_id) + await conn.execute(f"DELETE FROM {fq_table('memory_units')} WHERE bank_id = $1", bank_id) # Delete entities (cascades to unit_entities, entity_cooccurrences, memory_links with entity_id) - await conn.execute("DELETE FROM entities WHERE bank_id = $1", bank_id) + await conn.execute(f"DELETE FROM {fq_table('entities')} WHERE bank_id = $1", bank_id) # Delete the bank profile itself - await conn.execute("DELETE FROM banks WHERE bank_id = $1", bank_id) + await conn.execute(f"DELETE FROM {fq_table('banks')} WHERE bank_id = $1", bank_id) return { "memory_units_deleted": units_count, @@ -1838,17 +2215,25 @@ class MemoryEngine: except Exception as e: raise Exception(f"Failed to delete agent data: {str(e)}") - async def get_graph_data(self, bank_id: str | None = None, fact_type: str | None = None): + async def get_graph_data( + self, + bank_id: str | None = None, + fact_type: str | None = None, + *, + request_context: "RequestContext", + ): """ Get graph data for visualization. Args: bank_id: Filter by bank ID fact_type: Filter by fact type (world, experience, opinion) + request_context: Request context for authentication. Returns: Dict with nodes, edges, and table_rows """ + await self._authenticate_tenant(request_context) pool = await self._get_pool() async with acquire_with_retry(pool) as conn: # Get memory units, optionally filtered by bank_id and fact_type @@ -1871,7 +2256,7 @@ class MemoryEngine: units = await conn.fetch( f""" SELECT id, text, event_date, context, occurred_start, occurred_end, mentioned_at, document_id, chunk_id, fact_type - FROM memory_units + FROM {fq_table("memory_units")} {where_clause} ORDER BY mentioned_at DESC NULLS LAST, event_date DESC LIMIT 1000 @@ -1884,15 +2269,15 @@ class MemoryEngine: unit_ids = [row["id"] for row in units] if unit_ids: links = await conn.fetch( - """ + f""" SELECT DISTINCT ON (LEAST(ml.from_unit_id, ml.to_unit_id), GREATEST(ml.from_unit_id, ml.to_unit_id), ml.link_type, COALESCE(ml.entity_id, '00000000-0000-0000-0000-000000000000'::uuid)) ml.from_unit_id, ml.to_unit_id, ml.link_type, ml.weight, e.canonical_name as entity_name - FROM memory_links ml - LEFT JOIN entities e ON ml.entity_id = e.id + FROM {fq_table("memory_links")} ml + LEFT JOIN {fq_table("entities")} e ON ml.entity_id = e.id WHERE ml.from_unit_id = ANY($1::uuid[]) AND ml.to_unit_id = ANY($1::uuid[]) ORDER BY LEAST(ml.from_unit_id, ml.to_unit_id), GREATEST(ml.from_unit_id, ml.to_unit_id), ml.link_type, COALESCE(ml.entity_id, '00000000-0000-0000-0000-000000000000'::uuid), ml.weight DESC """, @@ -1902,10 +2287,10 @@ class MemoryEngine: links = [] # Get entity information - unit_entities = await conn.fetch(""" + unit_entities = await conn.fetch(f""" SELECT ue.unit_id, e.canonical_name - FROM unit_entities ue - JOIN entities e ON ue.entity_id = e.id + FROM {fq_table("unit_entities")} ue + JOIN {fq_table("entities")} e ON ue.entity_id = e.id ORDER BY ue.unit_id """) @@ -2017,11 +2402,13 @@ class MemoryEngine: async def list_memory_units( self, - bank_id: str | None = None, + bank_id: str, + *, fact_type: str | None = None, search_query: str | None = None, limit: int = 100, offset: int = 0, + request_context: "RequestContext", ): """ List memory units for table view with optional full-text search. @@ -2032,10 +2419,12 @@ class MemoryEngine: search_query: Full-text search query (searches text and context fields) limit: Maximum number of results to return offset: Offset for pagination + request_context: Request context for authentication. Returns: Dict with items (list of memory units) and total count """ + await self._authenticate_tenant(request_context) pool = await self._get_pool() async with acquire_with_retry(pool) as conn: # Build query conditions @@ -2064,7 +2453,7 @@ class MemoryEngine: # Get total count count_query = f""" SELECT COUNT(*) as total - FROM memory_units + FROM {fq_table("memory_units")} {where_clause} """ count_result = await conn.fetchrow(count_query, *query_params) @@ -2082,7 +2471,7 @@ class MemoryEngine: units = await conn.fetch( f""" SELECT id, text, event_date, context, fact_type, mentioned_at, occurred_start, occurred_end, chunk_id - FROM memory_units + FROM {fq_table("memory_units")} {where_clause} ORDER BY mentioned_at DESC NULLS LAST, created_at DESC LIMIT {limit_param} OFFSET {offset_param} @@ -2094,10 +2483,10 @@ class MemoryEngine: if units: unit_ids = [row["id"] for row in units] unit_entities = await conn.fetch( - """ + f""" SELECT ue.unit_id, e.canonical_name - FROM unit_entities ue - JOIN entities e ON ue.entity_id = e.id + FROM {fq_table("unit_entities")} ue + JOIN {fq_table("entities")} e ON ue.entity_id = e.id WHERE ue.unit_id = ANY($1::uuid[]) ORDER BY ue.unit_id """, @@ -2138,7 +2527,15 @@ class MemoryEngine: return {"items": items, "total": total, "limit": limit, "offset": offset} - async def list_documents(self, bank_id: str, search_query: str | None = None, limit: int = 100, offset: int = 0): + async def list_documents( + self, + bank_id: str, + *, + search_query: str | None = None, + limit: int = 100, + offset: int = 0, + request_context: "RequestContext", + ): """ List documents with optional search and pagination. @@ -2147,10 +2544,12 @@ class MemoryEngine: search_query: Search in document ID limit: Maximum number of results offset: Offset for pagination + request_context: Request context for authentication. Returns: Dict with items (list of documents without original_text) and total count """ + await self._authenticate_tenant(request_context) pool = await self._get_pool() async with acquire_with_retry(pool) as conn: # Build query conditions @@ -2173,7 +2572,7 @@ class MemoryEngine: # Get total count count_query = f""" SELECT COUNT(*) as total - FROM documents + FROM {fq_table("documents")} {where_clause} """ count_result = await conn.fetchrow(count_query, *query_params) @@ -2198,7 +2597,7 @@ class MemoryEngine: updated_at, LENGTH(original_text) as text_length, retain_params - FROM documents + FROM {fq_table("documents")} {where_clause} ORDER BY created_at DESC LIMIT {limit_param} OFFSET {offset_param} @@ -2224,7 +2623,7 @@ class MemoryEngine: unit_counts = await conn.fetch( f""" SELECT document_id, bank_id, COUNT(*) as unit_count - FROM memory_units + FROM {fq_table("memory_units")} WHERE {where_clause_count} GROUP BY document_id, bank_id """, @@ -2258,75 +2657,27 @@ class MemoryEngine: return {"items": items, "total": total, "limit": limit, "offset": offset} - async def get_document(self, document_id: str, bank_id: str): - """ - Get a specific document including its original_text. - - Args: - document_id: Document ID - bank_id: bank ID - - Returns: - Dict with document details including original_text, or None if not found - """ - pool = await self._get_pool() - async with acquire_with_retry(pool) as conn: - doc = await conn.fetchrow( - """ - SELECT - id, - bank_id, - original_text, - content_hash, - created_at, - updated_at, - retain_params - FROM documents - WHERE id = $1 AND bank_id = $2 - """, - document_id, - bank_id, - ) - - if not doc: - return None - - # Get memory unit count - unit_count_row = await conn.fetchrow( - """ - SELECT COUNT(*) as unit_count - FROM memory_units - WHERE document_id = $1 AND bank_id = $2 - """, - document_id, - bank_id, - ) - - return { - "id": doc["id"], - "bank_id": doc["bank_id"], - "original_text": doc["original_text"], - "content_hash": doc["content_hash"], - "created_at": doc["created_at"].isoformat() if doc["created_at"] else "", - "updated_at": doc["updated_at"].isoformat() if doc["updated_at"] else "", - "memory_unit_count": unit_count_row["unit_count"] if unit_count_row else 0, - "retain_params": doc["retain_params"] if doc["retain_params"] else None, - } - - async def get_chunk(self, chunk_id: str): + async def get_chunk( + self, + chunk_id: str, + *, + request_context: "RequestContext", + ): """ Get a specific chunk by its ID. Args: chunk_id: Chunk ID (format: bank_id_document_id_chunk_index) + request_context: Request context for authentication. Returns: Dict with chunk details including chunk_text, or None if not found """ + await self._authenticate_tenant(request_context) pool = await self._get_pool() async with acquire_with_retry(pool) as conn: chunk = await conn.fetchrow( - """ + f""" SELECT chunk_id, document_id, @@ -2334,7 +2685,7 @@ class MemoryEngine: chunk_index, chunk_text, created_at - FROM chunks + FROM {fq_table("chunks")} WHERE chunk_id = $1 """, chunk_id, @@ -2500,11 +2851,11 @@ Guidelines: async with acquire_with_retry(pool) as conn: # Find all opinions related to these entities opinions = await conn.fetch( - """ + f""" SELECT DISTINCT mu.id, mu.text, mu.confidence_score, e.canonical_name - FROM memory_units mu - JOIN unit_entities ue ON mu.id = ue.unit_id - JOIN entities e ON ue.entity_id = e.id + FROM {fq_table("memory_units")} mu + JOIN {fq_table("unit_entities")} ue ON mu.id = ue.unit_id + JOIN {fq_table("entities")} e ON ue.entity_id = e.id WHERE mu.bank_id = $1 AND mu.fact_type = 'opinion' AND e.canonical_name = ANY($2::text[]) @@ -2559,8 +2910,8 @@ Guidelines: if evaluation["action"] == "update" and evaluation["new_text"]: # Update both text and confidence await conn.execute( - """ - UPDATE memory_units + f""" + UPDATE {fq_table("memory_units")} SET text = $1, confidence_score = $2, updated_at = NOW() WHERE id = $3 """, @@ -2571,8 +2922,8 @@ Guidelines: else: # Only update confidence await conn.execute( - """ - UPDATE memory_units + f""" + UPDATE {fq_table("memory_units")} SET confidence_score = $1, updated_at = NOW() WHERE id = $2 """, @@ -2591,32 +2942,61 @@ Guidelines: # ==================== bank profile Methods ==================== - async def get_bank_profile(self, bank_id: str) -> "bank_utils.BankProfile": + async def get_bank_profile( + self, + bank_id: str, + *, + request_context: "RequestContext", + ) -> dict[str, Any]: """ Get bank profile (name, disposition + background). Auto-creates agent with default values if not exists. Args: bank_id: bank IDentifier + request_context: Request context for authentication. Returns: - BankProfile with name, typed DispositionTraits, and background + Dict with name, disposition traits, and background """ + await self._authenticate_tenant(request_context) pool = await self._get_pool() - return await bank_utils.get_bank_profile(pool, bank_id) + profile = await bank_utils.get_bank_profile(pool, bank_id) + disposition = profile["disposition"] + return { + "bank_id": bank_id, + "name": profile["name"], + "disposition": disposition, + "background": profile["background"], + } - async def update_bank_disposition(self, bank_id: str, disposition: dict[str, int]) -> None: + async def update_bank_disposition( + self, + bank_id: str, + disposition: dict[str, int], + *, + request_context: "RequestContext", + ) -> None: """ Update bank disposition traits. Args: bank_id: bank IDentifier disposition: Dict with skepticism, literalism, empathy (all 1-5) + request_context: Request context for authentication. """ + await self._authenticate_tenant(request_context) pool = await self._get_pool() await bank_utils.update_bank_disposition(pool, bank_id, disposition) - async def merge_bank_background(self, bank_id: str, new_info: str, update_disposition: bool = True) -> dict: + async def merge_bank_background( + self, + bank_id: str, + new_info: str, + *, + update_disposition: bool = True, + request_context: "RequestContext", + ) -> dict[str, Any]: """ Merge new background information with existing background using LLM. Normalizes to first person ("I") and resolves conflicts. @@ -2626,20 +3006,30 @@ Guidelines: bank_id: bank IDentifier new_info: New background information to add/merge update_disposition: If True, infer Big Five traits from background (default: True) + request_context: Request context for authentication. Returns: Dict with 'background' (str) and optionally 'disposition' (dict) keys """ + await self._authenticate_tenant(request_context) pool = await self._get_pool() return await bank_utils.merge_bank_background(pool, self._llm_config, bank_id, new_info, update_disposition) - async def list_banks(self) -> list: + async def list_banks( + self, + *, + request_context: "RequestContext", + ) -> list[dict[str, Any]]: """ List all agents in the system. + Args: + request_context: Request context for authentication. + Returns: List of dicts with bank_id, name, disposition, background, created_at, updated_at """ + await self._authenticate_tenant(request_context) pool = await self._get_pool() return await bank_utils.list_banks(pool) @@ -2649,8 +3039,10 @@ Guidelines: self, bank_id: str, query: str, - budget: Budget = Budget.LOW, - context: str = None, + *, + budget: Budget | None = None, + context: str | None = None, + request_context: "RequestContext", ) -> ReflectResult: """ Reflect and formulate an answer using bank identity, world facts, and opinions. @@ -2679,6 +3071,22 @@ Guidelines: if self._llm_config is None: raise ValueError("Memory LLM API key not set. Set HINDSIGHT_API_LLM_API_KEY environment variable.") + # Authenticate tenant and set schema in context (for fq_table()) + await self._authenticate_tenant(request_context) + + # Validate operation if validator is configured + if self._operation_validator: + from hindsight_api.extensions import ReflectContext + + ctx = ReflectContext( + bank_id=bank_id, + query=query, + request_context=request_context, + budget=budget, + context=context, + ) + await self._validate_operation(self._operation_validator.validate_reflect(ctx)) + reflect_start = time.time() reflect_id = f"{bank_id[:8]}-{int(time.time() * 1000) % 100000}" log_buffer = [] @@ -2694,6 +3102,7 @@ Guidelines: enable_trace=False, fact_type=["experience", "world", "opinion"], include_entities=True, + request_context=request_context, ) recall_time = time.time() - recall_start @@ -2714,7 +3123,7 @@ Guidelines: opinion_facts_text = think_utils.format_facts_for_prompt(opinion_results) # Get bank profile (name, disposition + background) - profile = await self.get_bank_profile(bank_id) + profile = await self.get_bank_profile(bank_id, request_context=request_context) name = profile["name"] disposition = profile["disposition"] # Typed as DispositionTraits background = profile["background"] @@ -2758,12 +3167,33 @@ Guidelines: logger.info("\n" + "\n".join(log_buffer)) # Return response with facts split by type - return ReflectResult( + result = ReflectResult( text=answer_text, based_on={"world": world_results, "experience": agent_results, "opinion": opinion_results}, new_opinions=[], # Opinions are being extracted asynchronously ) + # Call post-operation hook if validator is configured + if self._operation_validator: + from hindsight_api.extensions.operation_validator import ReflectResultContext + + result_ctx = ReflectResultContext( + bank_id=bank_id, + query=query, + request_context=request_context, + budget=budget, + context=context, + result=result, + success=True, + error=None, + ) + try: + await self._operation_validator.on_reflect_complete(result_ctx) + except Exception as e: + logger.warning(f"Post-reflect hook error (non-fatal): {e}") + + return result + async def _extract_and_store_opinions_async(self, bank_id: str, answer_text: str, query: str): """ Background task to extract and store opinions from think response. @@ -2784,6 +3214,10 @@ Guidelines: from datetime import datetime current_time = datetime.now(UTC) + # Use internal request context for background tasks + from hindsight_api.models import RequestContext + + internal_context = RequestContext() for opinion in new_opinions: await self.retain_async( bank_id=bank_id, @@ -2792,12 +3226,20 @@ Guidelines: event_date=current_time, fact_type_override="opinion", confidence_score=opinion.confidence, + request_context=internal_context, ) except Exception as e: logger.warning(f"[REFLECT] Failed to extract/store opinions: {str(e)}") - async def get_entity_observations(self, bank_id: str, entity_id: str, limit: int = 10) -> list[EntityObservation]: + async def get_entity_observations( + self, + bank_id: str, + entity_id: str, + *, + limit: int = 10, + request_context: "RequestContext", + ) -> list[Any]: """ Get observations linked to an entity. @@ -2805,17 +3247,19 @@ Guidelines: bank_id: bank IDentifier entity_id: Entity UUID to get observations for limit: Maximum number of observations to return + request_context: Request context for authentication. Returns: List of EntityObservation objects """ + await self._authenticate_tenant(request_context) pool = await self._get_pool() async with acquire_with_retry(pool) as conn: rows = await conn.fetch( - """ + f""" SELECT mu.text, mu.mentioned_at - FROM memory_units mu - JOIN unit_entities ue ON mu.id = ue.unit_id + FROM {fq_table("memory_units")} mu + JOIN {fq_table("unit_entities")} ue ON mu.id = ue.unit_id WHERE mu.bank_id = $1 AND mu.fact_type = 'observation' AND ue.entity_id = $2 @@ -2833,23 +3277,31 @@ Guidelines: observations.append(EntityObservation(text=row["text"], mentioned_at=mentioned_at)) return observations - async def list_entities(self, bank_id: str, limit: int = 100) -> list[dict[str, Any]]: + async def list_entities( + self, + bank_id: str, + *, + limit: int = 100, + request_context: "RequestContext", + ) -> list[dict[str, Any]]: """ List all entities for a bank. Args: bank_id: bank IDentifier limit: Maximum number of entities to return + request_context: Request context for authentication. Returns: List of entity dicts with id, canonical_name, mention_count, first_seen, last_seen """ + await self._authenticate_tenant(request_context) pool = await self._get_pool() async with acquire_with_retry(pool) as conn: rows = await conn.fetch( - """ + f""" SELECT id, canonical_name, mention_count, first_seen, last_seen, metadata - FROM entities + FROM {fq_table("entities")} WHERE bank_id = $1 ORDER BY mention_count DESC, last_seen DESC LIMIT $2 @@ -2884,7 +3336,15 @@ Guidelines: ) return entities - async def get_entity_state(self, bank_id: str, entity_id: str, entity_name: str, limit: int = 10) -> EntityState: + async def get_entity_state( + self, + bank_id: str, + entity_id: str, + entity_name: str, + *, + limit: int = 10, + request_context: "RequestContext", + ) -> EntityState: """ Get the current state (mental model) of an entity. @@ -2893,16 +3353,26 @@ Guidelines: entity_id: Entity UUID entity_name: Canonical name of the entity limit: Maximum number of observations to include + request_context: Request context for authentication. Returns: EntityState with observations """ - observations = await self.get_entity_observations(bank_id, entity_id, limit) + observations = await self.get_entity_observations( + bank_id, entity_id, limit=limit, request_context=request_context + ) return EntityState(entity_id=entity_id, canonical_name=entity_name, observations=observations) async def regenerate_entity_observations( - self, bank_id: str, entity_id: str, entity_name: str, version: str | None = None, conn=None - ) -> list[str]: + self, + bank_id: str, + entity_id: str, + entity_name: str, + *, + version: str | None = None, + conn=None, + request_context: "RequestContext", + ) -> None: """ Regenerate observations for an entity by: 1. Checking version for deduplication (if provided) @@ -2917,10 +3387,9 @@ Guidelines: entity_name: Canonical name of the entity version: Entity's last_seen timestamp when task was created (for deduplication) conn: Optional database connection (for transactional atomicity with caller) - - Returns: - List of created observation IDs + request_context: Request context for authentication. """ + await self._authenticate_tenant(request_context) pool = await self._get_pool() entity_uuid = uuid.UUID(entity_id) @@ -2942,9 +3411,9 @@ Guidelines: # Step 1: Check version for deduplication if version: current_last_seen = await fetchval_with_conn( - """ + f""" SELECT last_seen - FROM entities + FROM {fq_table("entities")} WHERE id = $1 AND bank_id = $2 """, entity_uuid, @@ -2956,10 +3425,10 @@ Guidelines: # Step 2: Get all facts mentioning this entity (exclude observations themselves) rows = await fetch_with_conn( - """ + f""" SELECT mu.id, mu.text, mu.context, mu.occurred_start, mu.fact_type - FROM memory_units mu - JOIN unit_entities ue ON mu.id = ue.unit_id + FROM {fq_table("memory_units")} mu + JOIN {fq_table("unit_entities")} ue ON mu.id = ue.unit_id WHERE mu.bank_id = $1 AND ue.entity_id = $2 AND mu.fact_type IN ('world', 'experience') @@ -2999,12 +3468,12 @@ Guidelines: async def do_db_operations(db_conn): # Delete old observations for this entity await db_conn.execute( - """ - DELETE FROM memory_units + f""" + DELETE FROM {fq_table("memory_units")} WHERE id IN ( SELECT mu.id - FROM memory_units mu - JOIN unit_entities ue ON mu.id = ue.unit_id + FROM {fq_table("memory_units")} mu + JOIN {fq_table("unit_entities")} ue ON mu.id = ue.unit_id WHERE mu.bank_id = $1 AND mu.fact_type = 'observation' AND ue.entity_id = $2 @@ -3023,8 +3492,8 @@ Guidelines: for obs_text, embedding in zip(observations, embeddings): result = await db_conn.fetchrow( - """ - INSERT INTO memory_units ( + f""" + INSERT INTO {fq_table("memory_units")} ( bank_id, text, embedding, context, event_date, occurred_start, occurred_end, mentioned_at, fact_type, access_count @@ -3046,8 +3515,8 @@ Guidelines: # Link observation to entity await db_conn.execute( - """ - INSERT INTO unit_entities (unit_id, entity_id) + f""" + INSERT INTO {fq_table("unit_entities")} (unit_id, entity_id) VALUES ($1, $2) """, uuid.UUID(obs_id), @@ -3066,7 +3535,12 @@ Guidelines: return await do_db_operations(acquired_conn) async def _regenerate_observations_sync( - self, bank_id: str, entity_ids: list[str], min_facts: int = 5, conn=None + self, + bank_id: str, + entity_ids: list[str], + min_facts: int = 5, + conn=None, + request_context: "RequestContext | None" = None, ) -> None: """ Regenerate observations for entities synchronously (called during retain). @@ -3089,8 +3563,8 @@ Guidelines: if conn is not None: # Use the provided connection (transactional with caller) entity_rows = await conn.fetch( - """ - SELECT id, canonical_name FROM entities + f""" + SELECT id, canonical_name FROM {fq_table("entities")} WHERE id = ANY($1) AND bank_id = $2 """, entity_uuids, @@ -3099,10 +3573,10 @@ Guidelines: entity_names = {row["id"]: row["canonical_name"] for row in entity_rows} fact_counts = await conn.fetch( - """ + f""" SELECT ue.entity_id, COUNT(*) as cnt - FROM unit_entities ue - JOIN memory_units mu ON ue.unit_id = mu.id + FROM {fq_table("unit_entities")} ue + JOIN {fq_table("memory_units")} mu ON ue.unit_id = mu.id WHERE ue.entity_id = ANY($1) AND mu.bank_id = $2 GROUP BY ue.entity_id """, @@ -3115,8 +3589,8 @@ Guidelines: pool = await self._get_pool() async with pool.acquire() as acquired_conn: entity_rows = await acquired_conn.fetch( - """ - SELECT id, canonical_name FROM entities + f""" + SELECT id, canonical_name FROM {fq_table("entities")} WHERE id = ANY($1) AND bank_id = $2 """, entity_uuids, @@ -3125,10 +3599,10 @@ Guidelines: entity_names = {row["id"]: row["canonical_name"] for row in entity_rows} fact_counts = await acquired_conn.fetch( - """ + f""" SELECT ue.entity_id, COUNT(*) as cnt - FROM unit_entities ue - JOIN memory_units mu ON ue.unit_id = mu.id + FROM {fq_table("unit_entities")} ue + JOIN {fq_table("memory_units")} mu ON ue.unit_id = mu.id WHERE ue.entity_id = ANY($1) AND mu.bank_id = $2 GROUP BY ue.entity_id """, @@ -3150,10 +3624,17 @@ Guidelines: if not entities_to_process: return + # Use internal context if not provided (for internal/background calls) + from hindsight_api.models import RequestContext as RC + + ctx = request_context if request_context is not None else RC() + # Process all entities in PARALLEL (LLM calls are the bottleneck) async def process_entity(entity_id: str, entity_name: str): try: - await self.regenerate_entity_observations(bank_id, entity_id, entity_name, version=None, conn=conn) + await self.regenerate_entity_observations( + bank_id, entity_id, entity_name, version=None, conn=conn, request_context=ctx + ) except Exception as e: logger.error(f"[OBSERVATIONS] Error processing entity {entity_id}: {e}") @@ -3170,6 +3651,10 @@ Guidelines: """ try: bank_id = task_dict.get("bank_id") + # Use internal request context for background tasks + from hindsight_api.models import RequestContext + + internal_context = RequestContext() # New format: multiple entity_ids if "entity_ids" in task_dict: @@ -3192,7 +3677,7 @@ Guidelines: # First check if entity exists entity_exists = await conn.fetchrow( - "SELECT canonical_name FROM entities WHERE id = $1 AND bank_id = $2", + f"SELECT canonical_name FROM {fq_table('entities')} WHERE id = $1 AND bank_id = $2", entity_uuid, bank_id, ) @@ -3206,14 +3691,17 @@ Guidelines: # Count facts linked to this entity fact_count = ( await conn.fetchval( - "SELECT COUNT(*) FROM unit_entities WHERE entity_id = $1", entity_uuid + f"SELECT COUNT(*) FROM {fq_table('unit_entities')} WHERE entity_id = $1", + entity_uuid, ) or 0 ) # Only regenerate if entity has enough facts if fact_count >= min_facts: - await self.regenerate_entity_observations(bank_id, entity_id, entity_name, version=None) + await self.regenerate_entity_observations( + bank_id, entity_id, entity_name, version=None, request_context=internal_context + ) else: logger.debug( f"[OBSERVATIONS] Skipping {entity_name} ({fact_count} facts < {min_facts} threshold)" @@ -3233,10 +3721,297 @@ Guidelines: logger.error(f"[OBSERVATIONS] Missing required fields in task: {task_dict}") return - await self.regenerate_entity_observations(bank_id, entity_id, entity_name, version) + # Type assertions after validation + assert isinstance(bank_id, str) and isinstance(entity_id, str) and isinstance(entity_name, str) + await self.regenerate_entity_observations( + bank_id, entity_id, entity_name, version=version, request_context=internal_context + ) except Exception as e: logger.error(f"[OBSERVATIONS] Error regenerating observations: {e}") import traceback traceback.print_exc() + + # ========================================================================= + # Statistics & Operations (for HTTP API layer) + # ========================================================================= + + async def get_bank_stats( + self, + bank_id: str, + *, + request_context: "RequestContext", + ) -> dict[str, Any]: + """Get statistics about memory nodes and links for a bank.""" + await self._authenticate_tenant(request_context) + pool = await self._get_pool() + + async with acquire_with_retry(pool) as conn: + # Get node counts by fact_type + node_stats = await conn.fetch( + f""" + SELECT fact_type, COUNT(*) as count + FROM {fq_table("memory_units")} + WHERE bank_id = $1 + GROUP BY fact_type + """, + bank_id, + ) + + # Get link counts by link_type + link_stats = await conn.fetch( + f""" + SELECT ml.link_type, COUNT(*) as count + FROM {fq_table("memory_links")} ml + JOIN {fq_table("memory_units")} mu ON ml.from_unit_id = mu.id + WHERE mu.bank_id = $1 + GROUP BY ml.link_type + """, + bank_id, + ) + + # Get link counts by fact_type (from nodes) + link_fact_type_stats = await conn.fetch( + f""" + SELECT mu.fact_type, COUNT(*) as count + FROM {fq_table("memory_links")} ml + JOIN {fq_table("memory_units")} mu ON ml.from_unit_id = mu.id + WHERE mu.bank_id = $1 + GROUP BY mu.fact_type + """, + bank_id, + ) + + # Get link counts by fact_type AND link_type + link_breakdown_stats = await conn.fetch( + f""" + SELECT mu.fact_type, ml.link_type, COUNT(*) as count + FROM {fq_table("memory_links")} ml + JOIN {fq_table("memory_units")} mu ON ml.from_unit_id = mu.id + WHERE mu.bank_id = $1 + GROUP BY mu.fact_type, ml.link_type + """, + bank_id, + ) + + # Get pending and failed operations counts + ops_stats = await conn.fetch( + f""" + SELECT status, COUNT(*) as count + FROM {fq_table("async_operations")} + WHERE bank_id = $1 + GROUP BY status + """, + bank_id, + ) + + return { + "bank_id": bank_id, + "node_counts": {row["fact_type"]: row["count"] for row in node_stats}, + "link_counts": {row["link_type"]: row["count"] for row in link_stats}, + "link_counts_by_fact_type": {row["fact_type"]: row["count"] for row in link_fact_type_stats}, + "link_breakdown": [ + {"fact_type": row["fact_type"], "link_type": row["link_type"], "count": row["count"]} + for row in link_breakdown_stats + ], + "operations": {row["status"]: row["count"] for row in ops_stats}, + } + + async def get_entity( + self, + bank_id: str, + entity_id: str, + *, + request_context: "RequestContext", + ) -> dict[str, Any] | None: + """Get entity details including metadata and observations.""" + await self._authenticate_tenant(request_context) + pool = await self._get_pool() + + async with acquire_with_retry(pool) as conn: + entity_row = await conn.fetchrow( + f""" + SELECT id, canonical_name, mention_count, first_seen, last_seen, metadata + FROM {fq_table("entities")} + WHERE bank_id = $1 AND id = $2 + """, + bank_id, + uuid.UUID(entity_id), + ) + + if not entity_row: + return None + + # Get observations for the entity + observations = await self.get_entity_observations(bank_id, entity_id, limit=20, request_context=request_context) + + return { + "id": str(entity_row["id"]), + "canonical_name": entity_row["canonical_name"], + "mention_count": entity_row["mention_count"], + "first_seen": entity_row["first_seen"].isoformat() if entity_row["first_seen"] else None, + "last_seen": entity_row["last_seen"].isoformat() if entity_row["last_seen"] else None, + "metadata": entity_row["metadata"] or {}, + "observations": observations, + } + + async def list_operations( + self, + bank_id: str, + *, + request_context: "RequestContext", + ) -> list[dict[str, Any]]: + """List async operations for a bank.""" + await self._authenticate_tenant(request_context) + pool = await self._get_pool() + + async with acquire_with_retry(pool) as conn: + operations = await conn.fetch( + f""" + SELECT operation_id, bank_id, operation_type, created_at, status, error_message, result_metadata + FROM {fq_table("async_operations")} + WHERE bank_id = $1 + ORDER BY created_at DESC + """, + bank_id, + ) + + def parse_metadata(metadata): + if metadata is None: + return {} + if isinstance(metadata, str): + import json + + return json.loads(metadata) + return metadata + + return [ + { + "id": str(row["operation_id"]), + "task_type": row["operation_type"], + "items_count": parse_metadata(row["result_metadata"]).get("items_count", 0), + "document_id": parse_metadata(row["result_metadata"]).get("document_id"), + "created_at": row["created_at"].isoformat(), + "status": row["status"], + "error_message": row["error_message"], + } + for row in operations + ] + + async def cancel_operation( + self, + bank_id: str, + operation_id: str, + *, + request_context: "RequestContext", + ) -> dict[str, Any]: + """Cancel a pending async operation.""" + await self._authenticate_tenant(request_context) + pool = await self._get_pool() + + op_uuid = uuid.UUID(operation_id) + + async with acquire_with_retry(pool) as conn: + # Check if operation exists and belongs to this memory bank + result = await conn.fetchrow( + f"SELECT bank_id FROM {fq_table('async_operations')} WHERE operation_id = $1 AND bank_id = $2", + op_uuid, + bank_id, + ) + + if not result: + raise ValueError(f"Operation {operation_id} not found for bank {bank_id}") + + # Delete the operation + await conn.execute(f"DELETE FROM {fq_table('async_operations')} WHERE operation_id = $1", op_uuid) + + return { + "success": True, + "message": f"Operation {operation_id} cancelled", + "operation_id": operation_id, + "bank_id": bank_id, + } + + async def update_bank( + self, + bank_id: str, + *, + name: str | None = None, + background: str | None = None, + request_context: "RequestContext", + ) -> dict[str, Any]: + """Update bank name and/or background.""" + await self._authenticate_tenant(request_context) + pool = await self._get_pool() + + async with acquire_with_retry(pool) as conn: + if name is not None: + await conn.execute( + f""" + UPDATE {fq_table("banks")} + SET name = $2, updated_at = NOW() + WHERE bank_id = $1 + """, + bank_id, + name, + ) + + if background is not None: + await conn.execute( + f""" + UPDATE {fq_table("banks")} + SET background = $2, updated_at = NOW() + WHERE bank_id = $1 + """, + bank_id, + background, + ) + + # Return updated profile + return await self.get_bank_profile(bank_id, request_context=request_context) + + async def submit_async_retain( + self, + bank_id: str, + contents: list[dict[str, Any]], + *, + request_context: "RequestContext", + ) -> dict[str, Any]: + """Submit a batch retain operation to run asynchronously.""" + await self._authenticate_tenant(request_context) + pool = await self._get_pool() + + import json + + operation_id = uuid.uuid4() + + # Insert operation record into database + async with acquire_with_retry(pool) as conn: + await conn.execute( + f""" + INSERT INTO {fq_table("async_operations")} (operation_id, bank_id, operation_type, result_metadata) + VALUES ($1, $2, $3, $4) + """, + operation_id, + bank_id, + "retain", + json.dumps({"items_count": len(contents)}), + ) + + # Submit task to background queue + await self._task_backend.submit_task( + { + "type": "batch_retain", + "operation_id": str(operation_id), + "bank_id": bank_id, + "contents": contents, + } + ) + + logger.info(f"Retain task queued for bank_id={bank_id}, {len(contents)} items, operation_id={operation_id}") + + return { + "operation_id": str(operation_id), + "items_count": len(contents), + } diff --git a/hindsight-api/hindsight_api/engine/retain/bank_utils.py b/hindsight-api/hindsight_api/engine/retain/bank_utils.py index 03f46f7a..f9cac1f9 100644 --- a/hindsight-api/hindsight_api/engine/retain/bank_utils.py +++ b/hindsight-api/hindsight_api/engine/retain/bank_utils.py @@ -10,6 +10,7 @@ from typing import TypedDict from pydantic import BaseModel, Field from ..db_utils import acquire_with_retry +from ..memory_engine import fq_table from ..response_models import DispositionTraits logger = logging.getLogger(__name__) @@ -51,9 +52,9 @@ async def get_bank_profile(pool, bank_id: str) -> BankProfile: async with acquire_with_retry(pool) as conn: # Try to get existing bank row = await conn.fetchrow( - """ + f""" SELECT name, disposition, background - FROM banks WHERE bank_id = $1 + FROM {fq_table("banks")} WHERE bank_id = $1 """, bank_id, ) @@ -70,8 +71,8 @@ async def get_bank_profile(pool, bank_id: str) -> BankProfile: # Bank doesn't exist, create with defaults await conn.execute( - """ - INSERT INTO banks (bank_id, name, disposition, background) + f""" + INSERT INTO {fq_table("banks")} (bank_id, name, disposition, background) VALUES ($1, $2, $3::jsonb, $4) ON CONFLICT (bank_id) DO NOTHING """, @@ -98,8 +99,8 @@ async def update_bank_disposition(pool, bank_id: str, disposition: dict[str, int async with acquire_with_retry(pool) as conn: await conn.execute( - """ - UPDATE banks + f""" + UPDATE {fq_table("banks")} SET disposition = $2::jsonb, updated_at = NOW() WHERE bank_id = $1 @@ -140,8 +141,8 @@ async def merge_bank_background(pool, llm_config, bank_id: str, new_info: str, u if inferred_disposition: # Update both background and disposition await conn.execute( - """ - UPDATE banks + f""" + UPDATE {fq_table("banks")} SET background = $2, disposition = $3::jsonb, updated_at = NOW() @@ -154,8 +155,8 @@ async def merge_bank_background(pool, llm_config, bank_id: str, new_info: str, u else: # Update only background await conn.execute( - """ - UPDATE banks + f""" + UPDATE {fq_table("banks")} SET background = $2, updated_at = NOW() WHERE bank_id = $1 @@ -361,9 +362,9 @@ async def list_banks(pool) -> list: """ async with acquire_with_retry(pool) as conn: rows = await conn.fetch( - """ + f""" SELECT bank_id, name, disposition, background, created_at, updated_at - FROM banks + FROM {fq_table("banks")} ORDER BY updated_at DESC """ ) diff --git a/hindsight-api/hindsight_api/engine/retain/chunk_storage.py b/hindsight-api/hindsight_api/engine/retain/chunk_storage.py index c4871c27..34941a10 100644 --- a/hindsight-api/hindsight_api/engine/retain/chunk_storage.py +++ b/hindsight-api/hindsight_api/engine/retain/chunk_storage.py @@ -6,6 +6,7 @@ Handles storage of document chunks in the database. import logging +from ..memory_engine import fq_table from .types import ChunkMetadata logger = logging.getLogger(__name__) @@ -42,8 +43,8 @@ async def store_chunks_batch(conn, bank_id: str, document_id: str, chunks: list[ # Batch insert all chunks await conn.execute( - """ - INSERT INTO chunks (chunk_id, document_id, bank_id, chunk_text, chunk_index) + f""" + INSERT INTO {fq_table("chunks")} (chunk_id, document_id, bank_id, chunk_text, chunk_index) SELECT * FROM unnest($1::text[], $2::text[], $3::text[], $4::text[], $5::integer[]) """, chunk_ids, diff --git a/hindsight-api/hindsight_api/engine/retain/fact_storage.py b/hindsight-api/hindsight_api/engine/retain/fact_storage.py index 68cfb1ed..9122204b 100644 --- a/hindsight-api/hindsight_api/engine/retain/fact_storage.py +++ b/hindsight-api/hindsight_api/engine/retain/fact_storage.py @@ -7,6 +7,7 @@ Handles insertion of facts into the database. import json import logging +from ..memory_engine import fq_table from .types import ProcessedFact logger = logging.getLogger(__name__) @@ -67,8 +68,8 @@ async def insert_facts_batch( # Batch insert all facts results = await conn.fetch( - """ - INSERT INTO memory_units (bank_id, text, embedding, event_date, occurred_start, occurred_end, mentioned_at, + f""" + INSERT INTO {fq_table("memory_units")} (bank_id, text, embedding, event_date, occurred_start, occurred_end, mentioned_at, context, fact_type, confidence_score, access_count, metadata, chunk_id, document_id) SELECT $1, * FROM unnest( $2::text[], $3::vector[], $4::timestamptz[], $5::timestamptz[], $6::timestamptz[], $7::timestamptz[], @@ -107,8 +108,8 @@ async def ensure_bank_exists(conn, bank_id: str) -> None: bank_id: Bank identifier """ await conn.execute( - """ - INSERT INTO banks (bank_id, disposition, background) + f""" + INSERT INTO {fq_table("banks")} (bank_id, disposition, background) VALUES ($1, $2::jsonb, $3) ON CONFLICT (bank_id) DO UPDATE SET updated_at = NOW() @@ -141,12 +142,14 @@ async def handle_document_tracking( # Always delete old document first if it exists (cascades to units and links) # Only delete on the first batch to avoid deleting data we just inserted if is_first_batch: - await conn.fetchval("DELETE FROM documents WHERE id = $1 AND bank_id = $2 RETURNING id", document_id, bank_id) + await conn.fetchval( + f"DELETE FROM {fq_table('documents')} WHERE id = $1 AND bank_id = $2 RETURNING id", document_id, bank_id + ) # Insert document (or update if exists from concurrent operations) await conn.execute( - """ - INSERT INTO documents (id, bank_id, original_text, content_hash, metadata, retain_params) + f""" + INSERT INTO {fq_table("documents")} (id, bank_id, original_text, content_hash, metadata, retain_params) VALUES ($1, $2, $3, $4, $5, $6) ON CONFLICT (id, bank_id) DO UPDATE SET original_text = EXCLUDED.original_text, diff --git a/hindsight-api/hindsight_api/engine/retain/link_utils.py b/hindsight-api/hindsight_api/engine/retain/link_utils.py index b2f21e42..19aa310e 100644 --- a/hindsight-api/hindsight_api/engine/retain/link_utils.py +++ b/hindsight-api/hindsight_api/engine/retain/link_utils.py @@ -7,6 +7,7 @@ import time from datetime import UTC, datetime, timedelta from uuid import UUID +from ..memory_engine import fq_table from .types import EntityLink logger = logging.getLogger(__name__) @@ -290,9 +291,9 @@ async def extract_entities_batch_optimized( entity_id_list = [uuid.UUID(eid) if isinstance(eid, str) else eid for eid in all_entity_ids] rows = await conn.fetch( - """ + f""" SELECT entity_id, unit_id - FROM unit_entities + FROM {fq_table("unit_entities")} WHERE entity_id = ANY($1::uuid[]) """, entity_id_list, @@ -413,9 +414,9 @@ async def create_temporal_links_batch_per_fact( # Get the event_date for each new unit fetch_dates_start = time_mod.time() rows = await conn.fetch( - """ + f""" SELECT id, event_date - FROM memory_units + FROM {fq_table("memory_units")} WHERE id::text = ANY($1) """, unit_ids, @@ -432,9 +433,9 @@ async def create_temporal_links_batch_per_fact( fetch_neighbors_start = time_mod.time() all_candidates = await conn.fetch( - """ + f""" SELECT id, event_date - FROM memory_units + FROM {fq_table("memory_units")} WHERE bank_id = $1 AND event_date BETWEEN $2 AND $3 AND id::text != ALL($4) @@ -479,8 +480,8 @@ async def create_temporal_links_batch_per_fact( if links: insert_start = time_mod.time() await conn.executemany( - """ - INSERT INTO memory_links (from_unit_id, to_unit_id, link_type, weight, entity_id) + f""" + INSERT INTO {fq_table("memory_links")} (from_unit_id, to_unit_id, link_type, weight, entity_id) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (from_unit_id, to_unit_id, link_type, COALESCE(entity_id, '00000000-0000-0000-0000-000000000000'::uuid)) DO NOTHING """, @@ -535,9 +536,9 @@ async def create_semantic_links_batch( # Fetch ALL existing units with embeddings in ONE query fetch_start = time_mod.time() all_existing = await conn.fetch( - """ + f""" SELECT id, embedding - FROM memory_units + FROM {fq_table("memory_units")} WHERE bank_id = $1 AND embedding IS NOT NULL AND id::text != ALL($2) @@ -644,8 +645,8 @@ async def create_semantic_links_batch( if all_links: insert_start = time_mod.time() await conn.executemany( - """ - INSERT INTO memory_links (from_unit_id, to_unit_id, link_type, weight, entity_id) + f""" + INSERT INTO {fq_table("memory_links")} (from_unit_id, to_unit_id, link_type, weight, entity_id) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (from_unit_id, to_unit_id, link_type, COALESCE(entity_id, '00000000-0000-0000-0000-000000000000'::uuid)) DO NOTHING """, @@ -721,8 +722,8 @@ async def insert_entity_links_batch(conn, links: list[EntityLink], chunk_size: i # Insert from temp table with ON CONFLICT (single query for all rows) insert_start = time_mod.time() - await conn.execute(""" - INSERT INTO memory_links (from_unit_id, to_unit_id, link_type, weight, entity_id) + await conn.execute(f""" + INSERT INTO {fq_table("memory_links")} (from_unit_id, to_unit_id, link_type, weight, entity_id) SELECT from_unit_id, to_unit_id, link_type, weight, entity_id FROM _temp_entity_links ON CONFLICT (from_unit_id, to_unit_id, link_type, COALESCE(entity_id, '00000000-0000-0000-0000-000000000000'::uuid)) DO NOTHING @@ -808,8 +809,8 @@ async def create_causal_links_batch( insert_start = time_mod.time() try: await conn.executemany( - """ - INSERT INTO memory_links (from_unit_id, to_unit_id, link_type, weight, entity_id) + f""" + INSERT INTO {fq_table("memory_links")} (from_unit_id, to_unit_id, link_type, weight, entity_id) VALUES ($1, $2, $3, $4, $5) ON CONFLICT (from_unit_id, to_unit_id, link_type, COALESCE(entity_id, '00000000-0000-0000-0000-000000000000'::uuid)) DO NOTHING """, diff --git a/hindsight-api/hindsight_api/engine/retain/observation_regeneration.py b/hindsight-api/hindsight_api/engine/retain/observation_regeneration.py index f1128d1c..2e829723 100644 --- a/hindsight-api/hindsight_api/engine/retain/observation_regeneration.py +++ b/hindsight-api/hindsight_api/engine/retain/observation_regeneration.py @@ -9,6 +9,7 @@ import time import uuid from datetime import UTC, datetime +from ..memory_engine import fq_table from ..search import observation_utils from . import embedding_utils from .types import EntityLink @@ -75,8 +76,8 @@ async def regenerate_observations_batch( # Batch query for entity names entity_rows = await conn.fetch( - """ - SELECT id, canonical_name FROM entities + f""" + SELECT id, canonical_name FROM {fq_table("entities")} WHERE id = ANY($1) AND bank_id = $2 """, entity_uuids, @@ -86,10 +87,10 @@ async def regenerate_observations_batch( # Batch query for fact counts fact_counts = await conn.fetch( - """ + f""" SELECT ue.entity_id, COUNT(*) as cnt - FROM unit_entities ue - JOIN memory_units mu ON ue.unit_id = mu.id + FROM {fq_table("unit_entities")} ue + JOIN {fq_table("memory_units")} mu ON ue.unit_id = mu.id WHERE ue.entity_id = ANY($1) AND mu.bank_id = $2 GROUP BY ue.entity_id """, @@ -154,10 +155,10 @@ async def _regenerate_entity_observations( # Get all facts mentioning this entity (exclude observations themselves) rows = await conn.fetch( - """ + f""" SELECT mu.id, mu.text, mu.context, mu.occurred_start, mu.fact_type - FROM memory_units mu - JOIN unit_entities ue ON mu.id = ue.unit_id + FROM {fq_table("memory_units")} mu + JOIN {fq_table("unit_entities")} ue ON mu.id = ue.unit_id WHERE mu.bank_id = $1 AND ue.entity_id = $2 AND mu.fact_type IN ('world', 'experience') @@ -193,12 +194,12 @@ async def _regenerate_entity_observations( # Delete old observations for this entity await conn.execute( - """ - DELETE FROM memory_units + f""" + DELETE FROM {fq_table("memory_units")} WHERE id IN ( SELECT mu.id - FROM memory_units mu - JOIN unit_entities ue ON mu.id = ue.unit_id + FROM {fq_table("memory_units")} mu + JOIN {fq_table("unit_entities")} ue ON mu.id = ue.unit_id WHERE mu.bank_id = $1 AND mu.fact_type = 'observation' AND ue.entity_id = $2 @@ -217,8 +218,8 @@ async def _regenerate_entity_observations( for obs_text, embedding in zip(observations, embeddings): result = await conn.fetchrow( - """ - INSERT INTO memory_units ( + f""" + INSERT INTO {fq_table("memory_units")} ( bank_id, text, embedding, context, event_date, occurred_start, occurred_end, mentioned_at, fact_type, access_count @@ -240,8 +241,8 @@ async def _regenerate_entity_observations( # Link observation to entity await conn.execute( - """ - INSERT INTO unit_entities (unit_id, entity_id) + f""" + INSERT INTO {fq_table("unit_entities")} (unit_id, entity_id) VALUES ($1, $2) """, uuid.UUID(obs_id), diff --git a/hindsight-api/hindsight_api/engine/retain/orchestrator.py b/hindsight-api/hindsight_api/engine/retain/orchestrator.py index 172c9c59..26ccbd4f 100644 --- a/hindsight-api/hindsight_api/engine/retain/orchestrator.py +++ b/hindsight-api/hindsight_api/engine/retain/orchestrator.py @@ -8,7 +8,6 @@ import logging import time import uuid from datetime import UTC, datetime -from typing import Any from ..db_utils import acquire_with_retry from . import bank_utils @@ -29,7 +28,7 @@ from . import ( link_creation, observation_regeneration, ) -from .types import ExtractedFact, ProcessedFact, RetainContent +from .types import ExtractedFact, ProcessedFact, RetainContent, RetainContentDict logger = logging.getLogger(__name__) @@ -43,7 +42,7 @@ async def retain_batch( format_date_fn, duplicate_checker_fn, bank_id: str, - contents_dicts: list[dict[str, Any]], + contents_dicts: list[RetainContentDict], document_id: str | None = None, is_first_batch: bool = True, fact_type_override: str | None = None, diff --git a/hindsight-api/hindsight_api/engine/retain/types.py b/hindsight-api/hindsight_api/engine/retain/types.py index 6b22110f..d6b5df1c 100644 --- a/hindsight-api/hindsight_api/engine/retain/types.py +++ b/hindsight-api/hindsight_api/engine/retain/types.py @@ -7,9 +7,33 @@ from content input to fact storage. from dataclasses import dataclass, field from datetime import UTC, datetime +from typing import TypedDict from uuid import UUID +class RetainContentDict(TypedDict, total=False): + """Type definition for content items in retain_batch_async. + + Fields: + content: Text content to store (required) + context: Context about the content (optional) + event_date: When the content occurred (optional, defaults to now) + metadata: Custom key-value metadata (optional) + document_id: Document ID for this content item (optional) + """ + + content: str # Required + context: str + event_date: datetime + metadata: dict[str, str] + document_id: str + + +def _now_utc() -> datetime: + """Factory function for default event_date.""" + return datetime.now(UTC) + + @dataclass class RetainContent: """ @@ -20,16 +44,9 @@ class RetainContent: content: str context: str = "" - event_date: datetime | None = None + event_date: datetime = field(default_factory=_now_utc) metadata: dict[str, str] = field(default_factory=dict) - def __post_init__(self): - """Ensure event_date is set.""" - if self.event_date is None: - from datetime import datetime - - self.event_date = datetime.now(UTC) - @dataclass class ChunkMetadata: diff --git a/hindsight-api/hindsight_api/engine/search/graph_retrieval.py b/hindsight-api/hindsight_api/engine/search/graph_retrieval.py index 4c056314..88e94b3a 100644 --- a/hindsight-api/hindsight_api/engine/search/graph_retrieval.py +++ b/hindsight-api/hindsight_api/engine/search/graph_retrieval.py @@ -10,6 +10,7 @@ import logging from abc import ABC, abstractmethod from ..db_utils import acquire_with_retry +from ..memory_engine import fq_table from .types import RetrievalResult logger = logging.getLogger(__name__) @@ -139,11 +140,11 @@ class BFSGraphRetriever(GraphRetriever): # Step 1: Find entry points entry_points = await conn.fetch( - """ + f""" SELECT id, text, context, event_date, occurred_start, occurred_end, mentioned_at, access_count, embedding, fact_type, document_id, chunk_id, 1 - (embedding <=> $1::vector) AS similarity - FROM memory_units + FROM {fq_table("memory_units")} WHERE bank_id = $2 AND embedding IS NOT NULL AND fact_type = $3 @@ -188,13 +189,13 @@ class BFSGraphRetriever(GraphRetriever): if batch_nodes and budget_remaining > 0: max_neighbors = len(batch_nodes) * 20 neighbors = await conn.fetch( - """ + f""" SELECT mu.id, mu.text, mu.context, mu.occurred_start, mu.occurred_end, mu.mentioned_at, mu.access_count, mu.embedding, mu.fact_type, mu.document_id, mu.chunk_id, ml.weight, ml.link_type, ml.from_unit_id - FROM memory_links ml - JOIN memory_units mu ON ml.to_unit_id = mu.id + FROM {fq_table("memory_links")} ml + JOIN {fq_table("memory_units")} mu ON ml.to_unit_id = mu.id WHERE ml.from_unit_id = ANY($1::uuid[]) AND ml.weight >= $2 AND mu.fact_type = $3 diff --git a/hindsight-api/hindsight_api/engine/search/mpfp_retrieval.py b/hindsight-api/hindsight_api/engine/search/mpfp_retrieval.py index 7936326e..cb717f2e 100644 --- a/hindsight-api/hindsight_api/engine/search/mpfp_retrieval.py +++ b/hindsight-api/hindsight_api/engine/search/mpfp_retrieval.py @@ -20,6 +20,7 @@ from collections import defaultdict from dataclasses import dataclass, field from ..db_utils import acquire_with_retry +from ..memory_engine import fq_table from .graph_retrieval import GraphRetriever from .types import RetrievalResult @@ -217,10 +218,10 @@ async def load_typed_adjacency(pool, bank_id: str) -> TypedAdjacency: """ async with acquire_with_retry(pool) as conn: rows = await conn.fetch( - """ + f""" SELECT ml.from_unit_id, ml.to_unit_id, ml.link_type, ml.weight - FROM memory_links ml - JOIN memory_units mu ON ml.from_unit_id = mu.id + FROM {fq_table("memory_links")} ml + JOIN {fq_table("memory_units")} mu ON ml.from_unit_id = mu.id WHERE mu.bank_id = $1 AND ml.weight >= 0.1 ORDER BY ml.from_unit_id, ml.weight DESC @@ -252,10 +253,10 @@ async def fetch_memory_units_by_ids( async with acquire_with_retry(pool) as conn: rows = await conn.fetch( - """ + f""" SELECT id, text, context, event_date, occurred_start, occurred_end, mentioned_at, access_count, embedding, fact_type, document_id, chunk_id - FROM memory_units + FROM {fq_table("memory_units")} WHERE id = ANY($1::uuid[]) AND fact_type = $2 """, @@ -418,9 +419,9 @@ class MPFPGraphRetriever(GraphRetriever): """Fallback: find semantic seeds via embedding search.""" async with acquire_with_retry(pool) as conn: rows = await conn.fetch( - """ + f""" SELECT id, 1 - (embedding <=> $1::vector) AS similarity - FROM memory_units + FROM {fq_table("memory_units")} WHERE bank_id = $2 AND embedding IS NOT NULL AND fact_type = $3 diff --git a/hindsight-api/hindsight_api/engine/search/retrieval.py b/hindsight-api/hindsight_api/engine/search/retrieval.py index 5f4ba144..dc75f3f3 100644 --- a/hindsight-api/hindsight_api/engine/search/retrieval.py +++ b/hindsight-api/hindsight_api/engine/search/retrieval.py @@ -16,6 +16,7 @@ from typing import Optional from ...config import get_config from ..db_utils import acquire_with_retry +from ..memory_engine import fq_table from .graph_retrieval import BFSGraphRetriever, GraphRetriever from .mpfp_retrieval import MPFPGraphRetriever from .types import RetrievalResult @@ -80,10 +81,10 @@ async def retrieve_semantic( List of RetrievalResult objects """ results = await conn.fetch( - """ + f""" SELECT id, text, context, event_date, occurred_start, occurred_end, mentioned_at, access_count, embedding, fact_type, document_id, chunk_id, 1 - (embedding <=> $1::vector) AS similarity - FROM memory_units + FROM {fq_table("memory_units")} WHERE bank_id = $2 AND embedding IS NOT NULL AND fact_type = $3 @@ -131,10 +132,10 @@ async def retrieve_bm25(conn, query_text: str, bank_id: str, fact_type: str, lim query_tsquery = " | ".join(tokens) results = await conn.fetch( - """ + f""" SELECT id, text, context, event_date, occurred_start, occurred_end, mentioned_at, access_count, embedding, fact_type, document_id, chunk_id, ts_rank_cd(search_vector, to_tsquery('english', $1)) AS bm25_score - FROM memory_units + FROM {fq_table("memory_units")} WHERE bank_id = $2 AND fact_type = $3 AND search_vector @@ to_tsquery('english', $1) @@ -188,10 +189,10 @@ async def retrieve_temporal( end_date = end_date.replace(tzinfo=UTC) entry_points = await conn.fetch( - """ + f""" SELECT id, text, context, event_date, occurred_start, occurred_end, mentioned_at, access_count, embedding, fact_type, document_id, chunk_id, 1 - (embedding <=> $1::vector) AS similarity - FROM memory_units + FROM {fq_table("memory_units")} WHERE bank_id = $2 AND fact_type = $3 AND embedding IS NOT NULL @@ -272,12 +273,12 @@ async def retrieve_temporal( # Get neighbors via temporal and causal links if budget_remaining > 0: neighbors = await conn.fetch( - """ + f""" SELECT mu.id, mu.text, mu.context, mu.event_date, mu.occurred_start, mu.occurred_end, mu.mentioned_at, mu.access_count, mu.embedding, mu.fact_type, mu.document_id, mu.chunk_id, ml.weight, ml.link_type, 1 - (mu.embedding <=> $1::vector) AS similarity - FROM memory_links ml - JOIN memory_units mu ON ml.to_unit_id = mu.id + FROM {fq_table("memory_links")} ml + JOIN {fq_table("memory_units")} mu ON ml.to_unit_id = mu.id WHERE ml.from_unit_id = $2 AND ml.link_type IN ('temporal', 'causes', 'caused_by', 'enables', 'prevents') AND ml.weight >= 0.1 @@ -546,11 +547,11 @@ async def _get_temporal_entry_points( end_date = end_date.replace(tzinfo=UTC) rows = await conn.fetch( - """ + f""" SELECT id, text, context, event_date, occurred_start, occurred_end, mentioned_at, access_count, embedding, fact_type, document_id, chunk_id, 1 - (embedding <=> $1::vector) AS similarity - FROM memory_units + FROM {fq_table("memory_units")} WHERE bank_id = $2 AND fact_type = $3 AND embedding IS NOT NULL diff --git a/hindsight-api/hindsight_api/engine/search/think_utils.py b/hindsight-api/hindsight_api/engine/search/think_utils.py index ca51b433..f8722605 100644 --- a/hindsight-api/hindsight_api/engine/search/think_utils.py +++ b/hindsight-api/hindsight_api/engine/search/think_utils.py @@ -101,7 +101,7 @@ def build_think_prompt( name: str, disposition: DispositionTraits, background: str, - context: str = None, + context: str | None = None, ) -> str: """Build the think prompt for the LLM.""" disposition_desc = build_disposition_description(disposition) diff --git a/hindsight-api/hindsight_api/engine/search/tracer.py b/hindsight-api/hindsight_api/engine/search/tracer.py index 9715e085..ef695ad0 100644 --- a/hindsight-api/hindsight_api/engine/search/tracer.py +++ b/hindsight-api/hindsight_api/engine/search/tracer.py @@ -115,7 +115,7 @@ class SearchTracer: node_id: str, text: str, context: str, - event_date: datetime, + event_date: datetime | None, access_count: int, is_entry_point: bool, parent_node_id: str | None, diff --git a/hindsight-api/hindsight_api/extensions/__init__.py b/hindsight-api/hindsight_api/extensions/__init__.py new file mode 100644 index 00000000..fd84a272 --- /dev/null +++ b/hindsight-api/hindsight_api/extensions/__init__.py @@ -0,0 +1,66 @@ +""" +Hindsight Extensions System. + +Extensions allow customizing and extending Hindsight behavior without modifying core code. +Extensions are loaded via environment variables pointing to implementation classes. + +Example: + HINDSIGHT_API_OPERATION_VALIDATOR_EXTENSION=mypackage.validators:MyValidator + HINDSIGHT_API_OPERATION_VALIDATOR_MAX_RETRIES=3 + + HINDSIGHT_API_HTTP_EXTENSION=mypackage.http:MyHttpExtension + HINDSIGHT_API_HTTP_SOME_CONFIG=value + +Extensions receive an ExtensionContext that provides a controlled API for interacting +with the system (e.g., running migrations for tenant schemas). +""" + +from hindsight_api.extensions.base import Extension +from hindsight_api.extensions.builtin import ApiKeyTenantExtension +from hindsight_api.extensions.context import DefaultExtensionContext, ExtensionContext +from hindsight_api.extensions.http import HttpExtension +from hindsight_api.extensions.loader import load_extension +from hindsight_api.extensions.operation_validator import ( + OperationValidationError, + OperationValidatorExtension, + RecallContext, + RecallResult, + ReflectContext, + ReflectResultContext, + RetainContext, + RetainResult, + ValidationResult, +) +from hindsight_api.extensions.tenant import ( + AuthenticationError, + TenantContext, + TenantExtension, +) +from hindsight_api.models import RequestContext + +__all__ = [ + # Base + "Extension", + "load_extension", + # Context + "ExtensionContext", + "DefaultExtensionContext", + # HTTP Extension + "HttpExtension", + # Operation Validator + "OperationValidationError", + "OperationValidatorExtension", + "RecallContext", + "RecallResult", + "ReflectContext", + "ReflectResultContext", + "RetainContext", + "RetainResult", + "ValidationResult", + # Tenant/Auth + "ApiKeyTenantExtension", + "AuthenticationError", + "RequestContext", + "TenantContext", + "TenantExtension", +] diff --git a/hindsight-api/hindsight_api/extensions/base.py b/hindsight-api/hindsight_api/extensions/base.py new file mode 100644 index 00000000..76e0df6a --- /dev/null +++ b/hindsight-api/hindsight_api/extensions/base.py @@ -0,0 +1,81 @@ +"""Base Extension class for all Hindsight extensions.""" + +from abc import ABC +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from hindsight_api.extensions.context import ExtensionContext + + +class Extension(ABC): + """ + Base class for all Hindsight extensions. + + Extensions are loaded via environment variables and receive configuration + from prefixed environment variables. + + Example: + HINDSIGHT_API_MY_EXTENSION=mypackage.ext:MyExtension + HINDSIGHT_API_MY_SOME_CONFIG=value + + The extension receives: {"some_config": "value"} + + Extensions also receive an ExtensionContext that provides a controlled API + for interacting with the system (e.g., running migrations for tenant schemas). + """ + + def __init__(self, config: dict[str, str]): + """ + Initialize the extension with configuration. + + Args: + config: Dictionary of configuration values from environment variables. + Keys are lowercased with the prefix stripped. + """ + self.config = config + self._context: "ExtensionContext | None" = None + + def set_context(self, context: "ExtensionContext") -> None: + """ + Set the extension context. + + Called by the extension loader after instantiation. + Extensions should not call this directly. + + Args: + context: The ExtensionContext providing system APIs. + """ + self._context = context + + @property + def context(self) -> "ExtensionContext": + """ + Get the extension context. + + Returns: + The ExtensionContext providing system APIs. + + Raises: + RuntimeError: If context has not been set yet. + """ + if self._context is None: + raise RuntimeError( + "Extension context not set. Context is available after the extension is loaded by the system." + ) + return self._context + + async def on_startup(self) -> None: + """ + Called when the application starts. + + Override to perform initialization tasks like connecting to external services. + """ + pass + + async def on_shutdown(self) -> None: + """ + Called when the application shuts down. + + Override to perform cleanup tasks like closing connections. + """ + pass diff --git a/hindsight-api/hindsight_api/extensions/builtin/__init__.py b/hindsight-api/hindsight_api/extensions/builtin/__init__.py new file mode 100644 index 00000000..703f531c --- /dev/null +++ b/hindsight-api/hindsight_api/extensions/builtin/__init__.py @@ -0,0 +1,18 @@ +""" +Built-in extension implementations. + +These are ready-to-use implementations of the extension interfaces. +They can be used directly or serve as examples for custom implementations. + +Available built-in extensions: + - ApiKeyTenantExtension: Simple API key validation with public schema + +Example usage: + HINDSIGHT_API_TENANT_EXTENSION=hindsight_api.extensions.builtin.tenant:ApiKeyTenantExtension +""" + +from hindsight_api.extensions.builtin.tenant import ApiKeyTenantExtension + +__all__ = [ + "ApiKeyTenantExtension", +] diff --git a/hindsight-api/hindsight_api/extensions/builtin/tenant.py b/hindsight-api/hindsight_api/extensions/builtin/tenant.py new file mode 100644 index 00000000..a5a1b80a --- /dev/null +++ b/hindsight-api/hindsight_api/extensions/builtin/tenant.py @@ -0,0 +1,33 @@ +"""Built-in tenant extension implementations.""" + +from hindsight_api.extensions.tenant import AuthenticationError, TenantContext, TenantExtension +from hindsight_api.models import RequestContext + + +class ApiKeyTenantExtension(TenantExtension): + """ + Built-in tenant extension that validates API key against an environment variable. + + This is a simple implementation that: + 1. Validates the API key matches HINDSIGHT_API_TENANT_API_KEY + 2. Returns 'public' as the schema for all authenticated requests + + Configuration: + HINDSIGHT_API_TENANT_EXTENSION=hindsight_api.extensions.builtin.tenant:ApiKeyTenantExtension + HINDSIGHT_API_TENANT_API_KEY=your-secret-key + + For multi-tenant setups with separate schemas per tenant, implement a custom + TenantExtension that looks up the schema based on the API key or token claims. + """ + + def __init__(self, config: dict[str, str]): + super().__init__(config) + self.expected_api_key = config.get("api_key") + if not self.expected_api_key: + raise ValueError("HINDSIGHT_API_TENANT_API_KEY is required when using ApiKeyTenantExtension") + + async def authenticate(self, context: RequestContext) -> TenantContext: + """Validate API key and return public schema context.""" + if context.api_key != self.expected_api_key: + raise AuthenticationError("Invalid API key") + return TenantContext(schema_name="public") diff --git a/hindsight-api/hindsight_api/extensions/context.py b/hindsight-api/hindsight_api/extensions/context.py new file mode 100644 index 00000000..03e5726a --- /dev/null +++ b/hindsight-api/hindsight_api/extensions/context.py @@ -0,0 +1,110 @@ +"""Extension context providing a controlled API for extensions to interact with the system.""" + +from abc import ABC, abstractmethod +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from hindsight_api.engine.interface import MemoryEngineInterface + + +class ExtensionContext(ABC): + """ + Abstract context providing a controlled API for extensions. + + Extensions receive this context instead of direct access to internal + components like MemoryEngine or database connections. This provides: + - A stable API that won't break when internals change + - Security by limiting what extensions can access + - Clear documentation of what extensions can do + + Built-in implementation: + hindsight_api.extensions.builtin.context.DefaultExtensionContext + + Example usage in an extension: + class MyTenantExtension(TenantExtension): + async def on_startup(self) -> None: + # Run migrations for a new tenant schema + await self.context.run_migration("tenant_acme") + + class MyHttpExtension(HttpExtension): + def get_router(self, memory): + # Use memory engine for custom endpoints + engine = self.context.get_memory_engine() + ... + """ + + @abstractmethod + async def run_migration(self, schema: str) -> None: + """ + Run database migrations for a specific schema. + + This creates the schema if it doesn't exist and runs all pending + migrations. Uses advisory locks to coordinate between distributed workers. + + Args: + schema: PostgreSQL schema name (e.g., "tenant_acme"). + The schema will be created if it doesn't exist. + + Raises: + RuntimeError: If migrations fail to complete. + + Example: + # Provision a new tenant schema + await context.run_migration("tenant_acme") + """ + ... + + @abstractmethod + def get_memory_engine(self) -> "MemoryEngineInterface": + """ + Get the memory engine interface. + + Returns the MemoryEngineInterface for performing memory operations + like retain, recall, reflect, and entity/document management. + + Returns: + MemoryEngineInterface instance. + + Example: + engine = context.get_memory_engine() + result = await engine.recall_async(bank_id, query) + """ + ... + + +class DefaultExtensionContext(ExtensionContext): + """ + Default implementation of ExtensionContext. + + Uses the system's database URL and migration infrastructure. + """ + + def __init__( + self, + database_url: str, + memory_engine: "MemoryEngineInterface | None" = None, + ): + """ + Initialize the context. + + Args: + database_url: SQLAlchemy database URL for migrations. + memory_engine: Optional MemoryEngine instance for memory operations. + """ + self._database_url = database_url + self._memory_engine = memory_engine + + async def run_migration(self, schema: str) -> None: + """Run migrations for a specific schema.""" + from hindsight_api.migrations import run_migrations + + run_migrations(self._database_url, schema=schema) + + def get_memory_engine(self) -> "MemoryEngineInterface": + """Get the memory engine interface.""" + if self._memory_engine is None: + raise RuntimeError( + "Memory engine not configured in ExtensionContext. " + "Ensure the context was created with a memory_engine parameter." + ) + return self._memory_engine diff --git a/hindsight-api/hindsight_api/extensions/http.py b/hindsight-api/hindsight_api/extensions/http.py new file mode 100644 index 00000000..a64816f7 --- /dev/null +++ b/hindsight-api/hindsight_api/extensions/http.py @@ -0,0 +1,89 @@ +""" +HTTP Extension for adding custom endpoints to the Hindsight API. + +This extension allows adding custom HTTP endpoints under the /ext/ path prefix. +The extension provides a FastAPI router that is mounted on the main application. +""" + +from abc import ABC, abstractmethod +from typing import TYPE_CHECKING + +from fastapi import APIRouter + +from hindsight_api.extensions.base import Extension + +if TYPE_CHECKING: + from hindsight_api import MemoryEngine + + +class HttpExtension(Extension, ABC): + """ + Base class for HTTP extensions that add custom API endpoints. + + HTTP extensions provide a FastAPI router that gets mounted under /ext/. + The extension has full control over the routes, request/response models, and handlers. + + Example: + ```python + from fastapi import APIRouter + from hindsight_api.extensions import HttpExtension + + class MyHttpExtension(HttpExtension): + def get_router(self, memory: MemoryEngine) -> APIRouter: + router = APIRouter() + + @router.get("/hello") + async def hello(): + return {"message": "Hello from extension!"} + + @router.post("/custom/{bank_id}/action") + async def custom_action(bank_id: str): + # Access memory engine for database operations + pool = await memory._get_pool() + # ... custom logic + return {"status": "ok"} + + return router + ``` + + The routes will be available at: + - GET /ext/hello + - POST /ext/custom/{bank_id}/action + + Configuration via environment variables: + HINDSIGHT_API_HTTP_EXTENSION=mypackage.ext:MyHttpExtension + HINDSIGHT_API_HTTP_SOME_CONFIG=value + + The extension receives config: {"some_config": "value"} + """ + + @abstractmethod + def get_router(self, memory: "MemoryEngine") -> APIRouter: + """ + Return a FastAPI router with custom endpoints. + + The router will be mounted at /ext/ on the main application. + All routes defined in the router will be prefixed with /ext/. + + Args: + memory: The MemoryEngine instance for database access and core operations. + Use this to access the connection pool, run queries, or call + memory operations like retain, recall, etc. + + Returns: + A FastAPI APIRouter with the custom endpoints defined. + + Example: + ```python + def get_router(self, memory: MemoryEngine) -> APIRouter: + router = APIRouter(tags=["My Extension"]) + + @router.get("/status") + async def status(): + health = await memory.health_check() + return {"extension": "healthy", "memory": health} + + return router + ``` + """ + pass diff --git a/hindsight-api/hindsight_api/extensions/loader.py b/hindsight-api/hindsight_api/extensions/loader.py new file mode 100644 index 00000000..67595314 --- /dev/null +++ b/hindsight-api/hindsight_api/extensions/loader.py @@ -0,0 +1,125 @@ +"""Extension loader utilities.""" + +import importlib +import logging +import os +from typing import TYPE_CHECKING, TypeVar + +from hindsight_api.extensions.base import Extension + +if TYPE_CHECKING: + from hindsight_api.extensions.context import ExtensionContext + +logger = logging.getLogger(__name__) + +T = TypeVar("T", bound=Extension) + + +class ExtensionLoadError(Exception): + """Raised when an extension fails to load.""" + + pass + + +def load_extension( + prefix: str, + base_class: type[T], + env_prefix: str = "HINDSIGHT_API", + context: "ExtensionContext | None" = None, +) -> T | None: + """ + Load an extension from environment variable configuration. + + The extension class is specified via {env_prefix}_{prefix}_EXTENSION environment + variable in the format "module.path:ClassName". + + Configuration for the extension is collected from all environment variables + matching {env_prefix}_{prefix}_* (excluding the EXTENSION variable itself). + + Args: + prefix: The extension prefix (e.g., "OPERATION_VALIDATOR"). + base_class: The base class that the extension must inherit from. + env_prefix: The environment variable prefix (default: "HINDSIGHT_API"). + context: Optional ExtensionContext to provide system APIs to the extension. + + Returns: + An instance of the extension, or None if not configured. + + Raises: + ExtensionLoadError: If the extension fails to load or validate. + + Example: + HINDSIGHT_API_OPERATION_VALIDATOR_EXTENSION=mypackage.validators:MyValidator + HINDSIGHT_API_OPERATION_VALIDATOR_MAX_REQUESTS=100 + + ext = load_extension("OPERATION_VALIDATOR", OperationValidatorExtension) + # ext.config == {"max_requests": "100"} + """ + env_var = f"{env_prefix}_{prefix}_EXTENSION" + ext_path = os.getenv(env_var) + + if not ext_path: + logger.debug(f"No extension configured for {env_var}") + return None + + logger.info(f"Loading extension from {env_var}={ext_path}") + + # Parse "module.path:ClassName" + if ":" not in ext_path: + raise ExtensionLoadError(f"Invalid extension path '{ext_path}'. Expected format: 'module.path:ClassName'") + + module_path, class_name = ext_path.rsplit(":", 1) + + # Import the module + try: + module = importlib.import_module(module_path) + except ImportError as e: + raise ExtensionLoadError(f"Failed to import extension module '{module_path}': {e}") from e + + # Get the class + try: + ext_class = getattr(module, class_name) + except AttributeError as e: + raise ExtensionLoadError(f"Extension class '{class_name}' not found in module '{module_path}'") from e + + # Validate inheritance + if not isinstance(ext_class, type) or not issubclass(ext_class, base_class): + raise ExtensionLoadError(f"Extension class '{ext_class.__name__}' must inherit from '{base_class.__name__}'") + + # Collect configuration from environment variables + config = _collect_config(env_prefix, prefix) + + logger.info(f"Loaded extension {ext_class.__name__} with config keys: {list(config.keys())}") + + # Instantiate the extension + try: + extension = ext_class(config) + except Exception as e: + raise ExtensionLoadError(f"Failed to instantiate extension '{ext_class.__name__}': {e}") from e + + # Set the context if provided + if context is not None: + extension.set_context(context) + logger.debug(f"Set context on extension {ext_class.__name__}") + + return extension + + +def _collect_config(env_prefix: str, prefix: str) -> dict[str, str]: + """ + Collect configuration from environment variables. + + Collects all variables matching {env_prefix}_{prefix}_* except for + {env_prefix}_{prefix}_EXTENSION, strips the prefix, and lowercases keys. + """ + config = {} + full_prefix = f"{env_prefix}_{prefix}_" + extension_var = f"{full_prefix}EXTENSION" + + for key, value in os.environ.items(): + if key.startswith(full_prefix) and key != extension_var: + # Strip prefix and lowercase the key + config_key = key[len(full_prefix) :].lower() + config[config_key] = value + + return config diff --git a/hindsight-api/hindsight_api/extensions/operation_validator.py b/hindsight-api/hindsight_api/extensions/operation_validator.py new file mode 100644 index 00000000..cd862ce5 --- /dev/null +++ b/hindsight-api/hindsight_api/extensions/operation_validator.py @@ -0,0 +1,325 @@ +"""Operation Validator Extension for validating retain/recall/reflect operations.""" + +from abc import ABC, abstractmethod +from dataclasses import dataclass, field +from datetime import datetime +from typing import TYPE_CHECKING, Any + +from hindsight_api.extensions.base import Extension + +if TYPE_CHECKING: + from hindsight_api.engine.memory_engine import Budget + from hindsight_api.engine.response_models import RecallResult as RecallResultModel + from hindsight_api.engine.response_models import ReflectResult + from hindsight_api.models import RequestContext + + +class OperationValidationError(Exception): + """Raised when an operation fails validation.""" + + def __init__(self, reason: str): + self.reason = reason + super().__init__(f"Operation validation failed: {reason}") + + +@dataclass +class ValidationResult: + """Result of an operation validation.""" + + allowed: bool + reason: str | None = None + + @classmethod + def accept(cls) -> "ValidationResult": + """Create an accepted validation result.""" + return cls(allowed=True) + + @classmethod + def reject(cls, reason: str) -> "ValidationResult": + """Create a rejected validation result with a reason.""" + return cls(allowed=False, reason=reason) + + +# ============================================================================= +# Pre-operation Contexts (all user-provided parameters) +# ============================================================================= + + +@dataclass +class RetainContext: + """Context for a retain operation validation (pre-operation). + + Contains ALL user-provided parameters for the retain operation. + """ + + bank_id: str + contents: list[dict] # List of {content, context, event_date, document_id} + request_context: "RequestContext" + document_id: str | None = None + fact_type_override: str | None = None + confidence_score: float | None = None + + +@dataclass +class RecallContext: + """Context for a recall operation validation (pre-operation). + + Contains ALL user-provided parameters for the recall operation. + """ + + bank_id: str + query: str + request_context: "RequestContext" + budget: "Budget | None" = None + max_tokens: int = 4096 + enable_trace: bool = False + fact_types: list[str] = field(default_factory=list) + question_date: datetime | None = None + include_entities: bool = False + max_entity_tokens: int = 500 + include_chunks: bool = False + max_chunk_tokens: int = 8192 + + +@dataclass +class ReflectContext: + """Context for a reflect operation validation (pre-operation). + + Contains ALL user-provided parameters for the reflect operation. + """ + + bank_id: str + query: str + request_context: "RequestContext" + budget: "Budget | None" = None + context: str | None = None + + +# ============================================================================= +# Post-operation Contexts (includes results) +# ============================================================================= + + +@dataclass +class RetainResult: + """Result context for post-retain hook. + + Contains the operation parameters and the result. + """ + + bank_id: str + contents: list[dict] + request_context: "RequestContext" + document_id: str | None + fact_type_override: str | None + confidence_score: float | None + # Result + unit_ids: list[list[str]] # List of unit IDs per content item + success: bool = True + error: str | None = None + + +@dataclass +class RecallResult: + """Result context for post-recall hook. + + Contains the operation parameters and the result. + """ + + bank_id: str + query: str + request_context: "RequestContext" + budget: "Budget | None" + max_tokens: int + enable_trace: bool + fact_types: list[str] + question_date: datetime | None + include_entities: bool + max_entity_tokens: int + include_chunks: bool + max_chunk_tokens: int + # Result + result: "RecallResultModel | None" = None + success: bool = True + error: str | None = None + + +@dataclass +class ReflectResultContext: + """Result context for post-reflect hook. + + Contains the operation parameters and the result. + """ + + bank_id: str + query: str + request_context: "RequestContext" + budget: "Budget | None" + context: str | None + # Result + result: "ReflectResult | None" = None + success: bool = True + error: str | None = None + + +class OperationValidatorExtension(Extension, ABC): + """ + Validates and hooks into retain/recall/reflect operations. + + This extension allows implementing custom logic such as: + - Rate limiting (pre-operation) + - Quota enforcement (pre-operation) + - Permission checks (pre-operation) + - Content filtering (pre-operation) + - Usage tracking (post-operation) + - Audit logging (post-operation) + - Metrics collection (post-operation) + + Enable via environment variable: + HINDSIGHT_API_OPERATION_VALIDATOR_EXTENSION=mypackage.validators:MyValidator + + Configuration is passed from prefixed environment variables: + HINDSIGHT_API_OPERATION_VALIDATOR_MAX_REQUESTS=100 + -> config = {"max_requests": "100"} + + Hook execution order: + 1. validate_retain/validate_recall/validate_reflect (pre-operation) + 2. [operation executes] + 3. on_retain_complete/on_recall_complete/on_reflect_complete (post-operation) + """ + + # ========================================================================= + # Pre-operation validation hooks (abstract - must be implemented) + # ========================================================================= + + @abstractmethod + async def validate_retain(self, ctx: RetainContext) -> ValidationResult: + """ + Validate a retain operation before execution. + + Called before the retain operation is processed. Return ValidationResult.reject() + to prevent the operation from executing. + + Args: + ctx: Context containing all user-provided parameters: + - bank_id: Bank identifier + - contents: List of content dicts + - request_context: Request context with auth info + - document_id: Optional document ID + - fact_type_override: Optional fact type override + - confidence_score: Optional confidence score + + Returns: + ValidationResult indicating whether the operation is allowed. + """ + ... + + @abstractmethod + async def validate_recall(self, ctx: RecallContext) -> ValidationResult: + """ + Validate a recall operation before execution. + + Called before the recall operation is processed. Return ValidationResult.reject() + to prevent the operation from executing. + + Args: + ctx: Context containing all user-provided parameters: + - bank_id: Bank identifier + - query: Search query + - request_context: Request context with auth info + - budget: Budget level + - max_tokens: Maximum tokens to return + - enable_trace: Whether to include trace info + - fact_types: List of fact types to search + - question_date: Optional date context for query + - include_entities: Whether to include entity data + - max_entity_tokens: Max tokens for entities + - include_chunks: Whether to include chunks + - max_chunk_tokens: Max tokens for chunks + + Returns: + ValidationResult indicating whether the operation is allowed. + """ + ... + + @abstractmethod + async def validate_reflect(self, ctx: ReflectContext) -> ValidationResult: + """ + Validate a reflect operation before execution. + + Called before the reflect operation is processed. Return ValidationResult.reject() + to prevent the operation from executing. + + Args: + ctx: Context containing all user-provided parameters: + - bank_id: Bank identifier + - query: Question to answer + - request_context: Request context with auth info + - budget: Budget level + - context: Optional additional context + + Returns: + ValidationResult indicating whether the operation is allowed. + """ + ... + + # ========================================================================= + # Post-operation hooks (optional - override to implement) + # ========================================================================= + + async def on_retain_complete(self, result: RetainResult) -> None: + """ + Called after a retain operation completes (success or failure). + + Override this method to implement post-operation logic such as: + - Usage tracking + - Audit logging + - Metrics collection + - Notifications + + Args: + result: Result context containing: + - All original operation parameters + - unit_ids: List of created unit IDs (if success) + - success: Whether the operation succeeded + - error: Error message (if failed) + """ + pass + + async def on_recall_complete(self, result: RecallResult) -> None: + """ + Called after a recall operation completes (success or failure). + + Override this method to implement post-operation logic such as: + - Usage tracking + - Audit logging + - Metrics collection + - Query analytics + + Args: + result: Result context containing: + - All original operation parameters + - result: RecallResultModel (if success) + - success: Whether the operation succeeded + - error: Error message (if failed) + """ + pass + + async def on_reflect_complete(self, result: ReflectResultContext) -> None: + """ + Called after a reflect operation completes (success or failure). + + Override this method to implement post-operation logic such as: + - Usage tracking + - Audit logging + - Metrics collection + - Response analytics + + Args: + result: Result context containing: + - All original operation parameters + - result: ReflectResult (if success) + - success: Whether the operation succeeded + - error: Error message (if failed) + """ + pass diff --git a/hindsight-api/hindsight_api/extensions/tenant.py b/hindsight-api/hindsight_api/extensions/tenant.py new file mode 100644 index 00000000..6b178a32 --- /dev/null +++ b/hindsight-api/hindsight_api/extensions/tenant.py @@ -0,0 +1,63 @@ +"""Tenant Extension for multi-tenancy and API key authentication.""" + +from abc import ABC, abstractmethod +from dataclasses import dataclass + +from hindsight_api.extensions.base import Extension +from hindsight_api.models import RequestContext + + +class AuthenticationError(Exception): + """Raised when authentication fails.""" + + def __init__(self, reason: str): + self.reason = reason + super().__init__(f"Authentication failed: {reason}") + + +@dataclass +class TenantContext: + """ + Tenant context returned by authentication. + + Contains the PostgreSQL schema name for tenant isolation. + All database queries will use fully-qualified table names + with this schema (e.g., schema_name.memory_units). + """ + + schema_name: str + + +class TenantExtension(Extension, ABC): + """ + Extension for multi-tenancy and API key authentication. + + This extension validates incoming requests and returns the tenant context + including the PostgreSQL schema to use for database operations. + + Built-in implementation: + hindsight_api.extensions.builtin.tenant.ApiKeyTenantExtension + + Enable via environment variable: + HINDSIGHT_API_TENANT_EXTENSION=hindsight_api.extensions.builtin.tenant:ApiKeyTenantExtension + HINDSIGHT_API_TENANT_API_KEY=your-secret-key + + The returned schema_name is used for fully-qualified table names in queries, + enabling tenant isolation at the database level. + """ + + @abstractmethod + async def authenticate(self, context: RequestContext) -> TenantContext: + """ + Authenticate the action context and return tenant context. + + Args: + context: The action context containing API key and other auth data. + + Returns: + TenantContext with the schema_name for database operations. + + Raises: + AuthenticationError: If authentication fails. + """ + ... diff --git a/hindsight-api/hindsight_api/main.py b/hindsight-api/hindsight_api/main.py index 4aaeda74..8d29d12b 100644 --- a/hindsight-api/hindsight_api/main.py +++ b/hindsight-api/hindsight_api/main.py @@ -185,7 +185,7 @@ def main(): mcp_enabled=config.mcp_enabled, ) - uvicorn.run(**uvicorn_config) + uvicorn.run(**uvicorn_config) # type: ignore[invalid-argument-type] - dict kwargs if __name__ == "__main__": diff --git a/hindsight-api/hindsight_api/mcp_local.py b/hindsight-api/hindsight_api/mcp_local.py index 431efb54..7205a5e5 100644 --- a/hindsight-api/hindsight_api/mcp_local.py +++ b/hindsight-api/hindsight_api/mcp_local.py @@ -87,6 +87,7 @@ def create_local_mcp_server(bank_id: str, memory=None) -> FastMCP: from hindsight_api import MemoryEngine from hindsight_api.engine.memory_engine import Budget from hindsight_api.engine.response_models import VALID_RECALL_FACT_TYPES + from hindsight_api.models import RequestContext # Create memory engine with pg0 embedded database if not provided if memory is None: @@ -115,7 +116,11 @@ def create_local_mcp_server(bank_id: str, memory=None) -> FastMCP: async def _retain(): try: - await memory.retain_batch_async(bank_id=bank_id, contents=[{"content": content, "context": context}]) + await memory.retain_batch_async( + bank_id=bank_id, + contents=[{"content": content, "context": context}], + request_context=RequestContext(), + ) except Exception as e: logger.error(f"Error storing memory: {e}", exc_info=True) @@ -142,6 +147,7 @@ def create_local_mcp_server(bank_id: str, memory=None) -> FastMCP: fact_type=list(VALID_RECALL_FACT_TYPES), budget=budget_enum, max_tokens=max_tokens, + request_context=RequestContext(), ) return search_result.model_dump() diff --git a/hindsight-api/hindsight_api/migrations.py b/hindsight-api/hindsight_api/migrations.py index 8d0e1cbc..91022980 100644 --- a/hindsight-api/hindsight_api/migrations.py +++ b/hindsight-api/hindsight_api/migrations.py @@ -6,12 +6,16 @@ on application startup. It is designed to be safe for concurrent execution using PostgreSQL advisory locks to coordinate between distributed workers. +Supports multi-tenant schema isolation: migrations can target a specific +PostgreSQL schema, allowing each tenant to have isolated tables. + Important: All migrations must be backward-compatible to allow safe rolling deployments. No alembic.ini required - all configuration is done programmatically. """ +import hashlib import logging import os from pathlib import Path @@ -26,11 +30,29 @@ logger = logging.getLogger(__name__) MIGRATION_LOCK_ID = 123456789 -def _run_migrations_internal(database_url: str, script_location: str) -> None: +def _get_schema_lock_id(schema: str) -> int: + """ + Generate a unique advisory lock ID for a schema. + + Uses hash of schema name to create a deterministic lock ID. + """ + # Use hash to create a unique lock ID per schema + # Keep within PostgreSQL's bigint range + hash_bytes = hashlib.sha256(schema.encode()).digest()[:8] + return int.from_bytes(hash_bytes, byteorder="big") % (2**31) + + +def _run_migrations_internal(database_url: str, script_location: str, schema: str | None = None) -> None: """ Internal function to run migrations without locking. + + Args: + database_url: SQLAlchemy database URL + script_location: Path to alembic scripts + schema: Target schema (None for default/public) """ - logger.info("Running database migrations to head...") + schema_name = schema or "public" + logger.info(f"Running database migrations to head for schema '{schema_name}'...") logger.info(f"Database URL: {database_url}") logger.info(f"Script location: {script_location}") @@ -50,13 +72,22 @@ def _run_migrations_internal(database_url: str, script_location: str) -> None: # Set path_separator to avoid deprecation warning alembic_cfg.set_main_option("path_separator", "os") - # Run migrations to head (latest version) + # If targeting a specific schema, pass it to env.py via config + # env.py will handle setting search_path and version_table_schema + if schema: + alembic_cfg.set_main_option("target_schema", schema) + + # Run migrations command.upgrade(alembic_cfg, "head") - logger.info("Database migrations completed successfully") + logger.info(f"Database migrations completed successfully for schema '{schema_name}'") -def run_migrations(database_url: str, script_location: str | None = None) -> None: +def run_migrations( + database_url: str, + script_location: str | None = None, + schema: str | None = None, +) -> None: """ Run database migrations to the latest version using programmatic Alembic configuration. @@ -65,19 +96,28 @@ def run_migrations(database_url: str, script_location: str | None = None) -> Non - Other workers wait for the lock, then verify migrations are complete - If schema is already up-to-date, this is a fast no-op + Supports multi-tenant schema isolation: when a schema is specified, migrations + run in that schema instead of public. This allows tenant extensions to provision + new tenant schemas with their own isolated tables. + Args: database_url: SQLAlchemy database URL (e.g., "postgresql://user:pass@host/db") script_location: Path to alembic migrations directory (e.g., "/path/to/alembic"). If None, defaults to hindsight-api/alembic directory. + schema: Target PostgreSQL schema name. If None, uses default (public). + When specified, creates the schema if needed and runs migrations there. Raises: RuntimeError: If migrations fail to complete FileNotFoundError: If script_location doesn't exist Example: - # Using default location (hindsight_api package) + # Using default location and public schema run_migrations("postgresql://user:pass@host/db") + # Run migrations for a specific tenant schema + run_migrations("postgresql://user:pass@host/db", schema="tenant_acme") + # Using custom location (when importing from another project) run_migrations( "postgresql://user:pass@host/db", @@ -99,21 +139,25 @@ def run_migrations(database_url: str, script_location: str | None = None) -> Non f"Alembic script location not found at {script_location}. Database migrations cannot be run." ) + # Use schema-specific lock ID for multi-tenant isolation + lock_id = _get_schema_lock_id(schema) if schema else MIGRATION_LOCK_ID + schema_name = schema or "public" + # Use PostgreSQL advisory lock to coordinate between distributed workers engine = create_engine(database_url) with engine.connect() as conn: # pg_advisory_lock blocks until the lock is acquired # The lock is automatically released when the connection closes - logger.debug(f"Acquiring migration advisory lock (id={MIGRATION_LOCK_ID})...") - conn.execute(text(f"SELECT pg_advisory_lock({MIGRATION_LOCK_ID})")) + logger.debug(f"Acquiring migration advisory lock for schema '{schema_name}' (id={lock_id})...") + conn.execute(text(f"SELECT pg_advisory_lock({lock_id})")) logger.debug("Migration advisory lock acquired") try: # Run migrations while holding the lock - _run_migrations_internal(database_url, script_location) + _run_migrations_internal(database_url, script_location, schema=schema) finally: # Explicitly release the lock (also released on connection close) - conn.execute(text(f"SELECT pg_advisory_unlock({MIGRATION_LOCK_ID})")) + conn.execute(text(f"SELECT pg_advisory_unlock({lock_id})")) logger.debug("Migration advisory lock released") except FileNotFoundError: diff --git a/hindsight-api/hindsight_api/models.py b/hindsight-api/hindsight_api/models.py index 023a1628..de5eddc4 100644 --- a/hindsight-api/hindsight_api/models.py +++ b/hindsight-api/hindsight_api/models.py @@ -2,9 +2,24 @@ SQLAlchemy models for the memory system. """ +from dataclasses import dataclass from datetime import datetime from uuid import UUID as PyUUID + +@dataclass +class RequestContext: + """ + Context for request authentication and authorization. + + This dataclass carries authentication data from HTTP requests to the + memory engine operations. It can be extended to include additional + context like headers, tokens, user info, etc. + """ + + api_key: str | None = None + + from pgvector.sqlalchemy import Vector from sqlalchemy import ( CheckConstraint, diff --git a/hindsight-api/hindsight_api/pg0.py b/hindsight-api/hindsight_api/pg0.py index ef40e046..797d9465 100644 --- a/hindsight-api/hindsight_api/pg0.py +++ b/hindsight-api/hindsight_api/pg0.py @@ -40,7 +40,7 @@ class EmbeddedPostgres: # Only set port if explicitly specified if self.port is not None: kwargs["port"] = self.port - self._pg0 = Pg0(**kwargs) + self._pg0 = Pg0(**kwargs) # type: ignore[invalid-argument-type] - dict kwargs return self._pg0 async def start(self, max_retries: int = 5, retry_delay: float = 4.0) -> str: diff --git a/hindsight-api/pyproject.toml b/hindsight-api/pyproject.toml index 4a77fd28..1d7619a9 100644 --- a/hindsight-api/pyproject.toml +++ b/hindsight-api/pyproject.toml @@ -92,6 +92,7 @@ dev = [ "python-dotenv>=1.2.1", "filelock>=3.0.0", "ruff>=0.8.0", + "ty>=0.0.1", ] [tool.ruff] @@ -121,3 +122,28 @@ ignore = [ [tool.ruff.format] quote-style = "double" indent-style = "space" + +[tool.ty] +# Type checking configuration +# ty is an extremely fast Python type checker from Astral (same team as ruff/uv) + +[tool.ty.environment] +python-version = "3.11" + +[tool.ty.src] +exclude = [ + "tests/", + "hindsight_api/alembic/", +] + +[tool.ty.rules] +# Disable noisy rules while keeping important ones +invalid-argument-type = "ignore" # False positives with **kwargs patterns +invalid-return-type = "ignore" # Often intentional in async code +invalid-parameter-default = "ignore" # Optional params with None default +possibly-missing-attribute = "ignore" # Common with Optional types +invalid-raise = "ignore" # False positives with exception tracking +call-non-callable = "ignore" # False positives with Optional types +invalid-key = "ignore" # Pydantic ConfigDict not understood +invalid-method-override = "ignore" # Intentional signature differences +unresolved-reference = "ignore" # Forward references not always resolved diff --git a/hindsight-api/tests/conftest.py b/hindsight-api/tests/conftest.py index 79cfbc3e..d2db8dde 100644 --- a/hindsight-api/tests/conftest.py +++ b/hindsight-api/tests/conftest.py @@ -8,7 +8,7 @@ import os import filelock from pathlib import Path from dotenv import load_dotenv -from hindsight_api import MemoryEngine, LLMConfig, LocalSTEmbeddings +from hindsight_api import MemoryEngine, LLMConfig, LocalSTEmbeddings, RequestContext from hindsight_api.engine.cross_encoder import LocalSTCrossEncoder from hindsight_api.engine.query_analyzer import DateparserQueryAnalyzer @@ -99,6 +99,12 @@ def pg0_db_url(db_url, tmp_path_factory, worker_id): return url +@pytest.fixture(scope="function") +def request_context(): + """Provide a default RequestContext for tests.""" + return RequestContext() + + @pytest.fixture(scope="session") def llm_config(): """ diff --git a/hindsight-api/tests/test_agents_api.py b/hindsight-api/tests/test_agents_api.py index 6bab3dd3..ca66a734 100644 --- a/hindsight-api/tests/test_agents_api.py +++ b/hindsight-api/tests/test_agents_api.py @@ -3,7 +3,7 @@ Tests for agent management API (profile, disposition, background). """ import pytest import uuid -from hindsight_api import MemoryEngine +from hindsight_api import MemoryEngine, RequestContext from hindsight_api.api import CreateBankRequest, DispositionTraits from hindsight_api.engine.memory_engine import Budget @@ -17,11 +17,11 @@ class TestAgentProfile: """Tests for agent profile management.""" @pytest.mark.asyncio - async def test_get_agent_profile_creates_default(self, memory: MemoryEngine): + async def test_get_agent_profile_creates_default(self, memory: MemoryEngine, request_context): """Test that getting a profile for a new agent creates default disposition.""" bank_id = unique_agent_id("test_profile_default") - profile = await memory.get_bank_profile(bank_id) + profile = await memory.get_bank_profile(bank_id, request_context=request_context) assert profile is not None assert "disposition" in profile @@ -35,11 +35,11 @@ class TestAgentProfile: assert profile["background"] == "" @pytest.mark.asyncio - async def test_update_agent_disposition(self, memory: MemoryEngine): + async def test_update_agent_disposition(self, memory: MemoryEngine, request_context): """Test updating agent disposition traits.""" bank_id = unique_agent_id("test_profile_update") - profile = await memory.get_bank_profile(bank_id) + profile = await memory.get_bank_profile(bank_id, request_context=request_context) assert profile["disposition"].skepticism == 3 new_disposition = { @@ -47,26 +47,26 @@ class TestAgentProfile: "literalism": 4, "empathy": 2, } - await memory.update_bank_disposition(bank_id, new_disposition) + await memory.update_bank_disposition(bank_id, new_disposition, request_context=request_context) - updated_profile = await memory.get_bank_profile(bank_id) + updated_profile = await memory.get_bank_profile(bank_id, request_context=request_context) disposition = updated_profile["disposition"] assert disposition.skepticism == new_disposition["skepticism"] assert disposition.literalism == new_disposition["literalism"] assert disposition.empathy == new_disposition["empathy"] @pytest.mark.asyncio - async def test_list_agents(self, memory: MemoryEngine): + async def test_list_agents(self, memory: MemoryEngine, request_context): """Test listing all agents.""" agent_id_1 = unique_agent_id("test_list") agent_id_2 = unique_agent_id("test_list") agent_id_3 = unique_agent_id("test_list") - await memory.get_bank_profile(agent_id_1) - await memory.get_bank_profile(agent_id_2) - await memory.get_bank_profile(agent_id_3) + await memory.get_bank_profile(agent_id_1, request_context=request_context) + await memory.get_bank_profile(agent_id_2, request_context=request_context) + await memory.get_bank_profile(agent_id_3, request_context=request_context) - agents = await memory.list_banks() + agents = await memory.list_banks(request_context=request_context) agent_ids = [a["bank_id"] for a in agents] assert agent_id_1 in agent_ids @@ -85,46 +85,50 @@ class TestAgentBackground: """Tests for agent background management.""" @pytest.mark.asyncio - async def test_merge_agent_background(self, memory: MemoryEngine): + async def test_merge_agent_background(self, memory: MemoryEngine, request_context): """Test merging agent background information.""" bank_id = unique_agent_id("test_profile_merge") - profile = await memory.get_bank_profile(bank_id) + profile = await memory.get_bank_profile(bank_id, request_context=request_context) assert profile["background"] == "" result1 = await memory.merge_bank_background( bank_id, "I was born in Texas", - update_disposition=False + update_disposition=False, + request_context=request_context, ) assert "Texas" in result1["background"] result2 = await memory.merge_bank_background( bank_id, "I have 10 years of startup experience", - update_disposition=False + update_disposition=False, + request_context=request_context, ) assert "Texas" in result2["background"] or "startup" in result2["background"] - final_profile = await memory.get_bank_profile(bank_id) + final_profile = await memory.get_bank_profile(bank_id, request_context=request_context) assert final_profile["background"] != "" @pytest.mark.asyncio - async def test_merge_background_handles_conflicts(self, memory: MemoryEngine): + async def test_merge_background_handles_conflicts(self, memory: MemoryEngine, request_context): """Test that merging background handles conflicts (new overwrites old).""" bank_id = unique_agent_id("test_profile_conflict") result1 = await memory.merge_bank_background( bank_id, "I was born in Colorado", - update_disposition=False + update_disposition=False, + request_context=request_context, ) assert "Colorado" in result1["background"] result2 = await memory.merge_bank_background( bank_id, "You were born in Texas", - update_disposition=False + update_disposition=False, + request_context=request_context, ) assert "Texas" in result2["background"] @@ -133,7 +137,7 @@ class TestAgentEndpoint: """Tests for agent PUT endpoint logic.""" @pytest.mark.asyncio - async def test_put_agent_create(self, memory: MemoryEngine): + async def test_put_agent_create(self, memory: MemoryEngine, request_context): """Test creating an agent via PUT endpoint.""" bank_id = unique_agent_id("test_put_create") @@ -146,12 +150,13 @@ class TestAgentEndpoint: background="I am a creative software engineer" ) - profile = await memory.get_bank_profile(bank_id) + profile = await memory.get_bank_profile(bank_id, request_context=request_context) if request.disposition is not None: await memory.update_bank_disposition( bank_id, - request.disposition.model_dump() + request.disposition.model_dump(), + request_context=request_context, ) if request.background is not None: @@ -168,14 +173,14 @@ class TestAgentEndpoint: request.background ) - final_profile = await memory.get_bank_profile(bank_id) + final_profile = await memory.get_bank_profile(bank_id, request_context=request_context) assert final_profile["disposition"].skepticism == 4 assert final_profile["disposition"].literalism == 5 assert final_profile["background"] == "I am a creative software engineer" @pytest.mark.asyncio - async def test_put_agent_partial_update(self, memory: MemoryEngine): + async def test_put_agent_partial_update(self, memory: MemoryEngine, request_context): """Test updating only background.""" bank_id = unique_agent_id("test_put_partial") @@ -183,7 +188,7 @@ class TestAgentEndpoint: background="I am a data scientist" ) - profile = await memory.get_bank_profile(bank_id) + profile = await memory.get_bank_profile(bank_id, request_context=request_context) if request.background is not None: pool = await memory._get_pool() @@ -199,7 +204,7 @@ class TestAgentEndpoint: request.background ) - final_profile = await memory.get_bank_profile(bank_id) + final_profile = await memory.get_bank_profile(bank_id, request_context=request_context) assert final_profile["disposition"].skepticism == 3 # Default assert final_profile["background"] == "I am a data scientist" @@ -209,7 +214,7 @@ class TestAgentDispositionIntegration: """Tests for disposition integration with other features.""" @pytest.mark.asyncio - async def test_think_uses_disposition(self, memory: MemoryEngine): + async def test_think_uses_disposition(self, memory: MemoryEngine, request_context): """Test that THINK operation uses agent disposition.""" bank_id = unique_agent_id("test_think") @@ -218,12 +223,13 @@ class TestAgentDispositionIntegration: "literalism": 4, # High literalism "empathy": 2, # Low empathy } - await memory.update_bank_disposition(bank_id, disposition) + await memory.update_bank_disposition(bank_id, disposition, request_context=request_context) await memory.merge_bank_background( bank_id, "I am a creative artist who values innovation over tradition", - update_disposition=False + update_disposition=False, + request_context=request_context, ) await memory.retain_batch_async( @@ -232,13 +238,14 @@ class TestAgentDispositionIntegration: {"content": "Traditional painting techniques have been used for centuries"}, {"content": "Modern digital art is changing the art world"} ], - document_id="art_facts" + request_context=request_context, ) result = await memory.reflect_async( bank_id=bank_id, query="What do you think about traditional vs modern art?", - budget=Budget.LOW + budget=Budget.LOW, + request_context=request_context, ) assert result.text is not None diff --git a/hindsight-api/tests/test_batch_chunking.py b/hindsight-api/tests/test_batch_chunking.py index d7968d87..e1329875 100644 --- a/hindsight-api/tests/test_batch_chunking.py +++ b/hindsight-api/tests/test_batch_chunking.py @@ -6,7 +6,7 @@ import os @pytest.mark.asyncio -async def test_large_batch_auto_chunks(memory): +async def test_large_batch_auto_chunks(memory, request_context): bank_id = "test_chunking_agent" # Create a large batch that should trigger chunking # Each item is ~2000 chars, so 30 items = 60k chars (exceeds 50k threshold) @@ -24,7 +24,8 @@ async def test_large_batch_auto_chunks(memory): # Ingest the large batch (should auto-chunk) result = await memory.retain_batch_async( bank_id=bank_id, - contents=contents + contents=contents, + request_context=request_context, ) # Verify we got results back @@ -33,7 +34,7 @@ async def test_large_batch_auto_chunks(memory): @pytest.mark.asyncio -async def test_small_batch_no_chunking(memory): +async def test_small_batch_no_chunking(memory, request_context): bank_id = "test_no_chunking_agent" # Create a small batch that should NOT trigger chunking @@ -50,7 +51,8 @@ async def test_small_batch_no_chunking(memory): # Ingest the small batch (should NOT auto-chunk) result = await memory.retain_batch_async( bank_id=bank_id, - contents=contents + contents=contents, + request_context=request_context, ) # Verify we got results back diff --git a/hindsight-api/tests/test_combined_scoring.py b/hindsight-api/tests/test_combined_scoring.py index 82f22c9e..4a12e135 100644 --- a/hindsight-api/tests/test_combined_scoring.py +++ b/hindsight-api/tests/test_combined_scoring.py @@ -10,6 +10,7 @@ import pytest from datetime import datetime, timezone from hindsight_api.engine.search.types import RetrievalResult, MergedCandidate, ScoredResult from hindsight_api.engine.memory_engine import Budget +from hindsight_api import RequestContext class TestRRFNormalization: @@ -125,7 +126,7 @@ class TestCombinedScoringFormula: @pytest.mark.asyncio -async def test_trace_has_normalized_rrf(memory): +async def test_trace_has_normalized_rrf(memory, request_context): """Integration test: verify trace contains normalized RRF values, not raw.""" bank_id = f"test_scoring_{datetime.now(timezone.utc).timestamp()}" @@ -135,21 +136,25 @@ async def test_trace_has_normalized_rrf(memory): bank_id=bank_id, content="Python is a programming language created by Guido van Rossum", context="tech facts", + request_context=request_context, ) await memory.retain_async( bank_id=bank_id, content="JavaScript was created by Brendan Eich at Netscape", context="tech facts", + request_context=request_context, ) await memory.retain_async( bank_id=bank_id, content="The Eiffel Tower is located in Paris, France", context="geography facts", + request_context=request_context, ) await memory.retain_async( bank_id=bank_id, content="Mount Everest is the tallest mountain on Earth", context="geography facts", + request_context=request_context, ) # Search with tracing @@ -160,6 +165,7 @@ async def test_trace_has_normalized_rrf(memory): budget=Budget.LOW, max_tokens=1024, enable_trace=True, + request_context=request_context, ) assert result.trace is not None, "Trace should be present" @@ -210,11 +216,11 @@ async def test_trace_has_normalized_rrf(memory): print(f" - First result score components: {sc}") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) @pytest.mark.asyncio -async def test_rrf_normalized_not_raw_in_trace(memory): +async def test_rrf_normalized_not_raw_in_trace(memory, request_context): """Verify that raw RRF scores (0.04-0.06 range) don't appear as normalized values.""" bank_id = f"test_rrf_raw_{datetime.now(timezone.utc).timestamp()}" @@ -225,6 +231,7 @@ async def test_rrf_normalized_not_raw_in_trace(memory): bank_id=bank_id, content=f"Test fact number {i} about various topics", context="test context", + request_context=request_context, ) result = await memory.recall_async( @@ -234,6 +241,7 @@ async def test_rrf_normalized_not_raw_in_trace(memory): budget=Budget.LOW, max_tokens=512, enable_trace=True, + request_context=request_context, ) trace = result.trace @@ -268,11 +276,11 @@ async def test_rrf_normalized_not_raw_in_trace(memory): print("\n✓ RRF raw vs normalized test passed!") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) @pytest.mark.asyncio -async def test_combined_score_matches_components(memory): +async def test_combined_score_matches_components(memory, request_context): """Verify the final score actually equals the weighted sum of components.""" bank_id = f"test_combined_{datetime.now(timezone.utc).timestamp()}" @@ -281,11 +289,13 @@ async def test_combined_score_matches_components(memory): bank_id=bank_id, content="The quick brown fox jumps over the lazy dog", context="test", + request_context=request_context, ) await memory.retain_async( bank_id=bank_id, content="A quick test of the emergency broadcast system", context="test", + request_context=request_context, ) result = await memory.recall_async( @@ -295,6 +305,7 @@ async def test_combined_score_matches_components(memory): budget=Budget.LOW, max_tokens=512, enable_trace=True, + request_context=request_context, ) trace = result.trace @@ -320,4 +331,4 @@ async def test_combined_score_matches_components(memory): print("\n✓ Combined score verification test passed!") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) diff --git a/hindsight-api/tests/test_document_tracking.py b/hindsight-api/tests/test_document_tracking.py index 8ec23759..521c3c4b 100644 --- a/hindsight-api/tests/test_document_tracking.py +++ b/hindsight-api/tests/test_document_tracking.py @@ -4,10 +4,11 @@ Tests for document tracking and upsert functionality. import logging import pytest from datetime import datetime, timezone +from hindsight_api import RequestContext @pytest.mark.asyncio -async def test_document_creation_and_retrieval(memory): +async def test_document_creation_and_retrieval(memory, request_context): """Test that documents are created and can be retrieved.""" bank_id = f"test_doc_{datetime.now(timezone.utc).timestamp()}" @@ -19,11 +20,12 @@ async def test_document_creation_and_retrieval(memory): bank_id=bank_id, content="Alice works at Google. Bob works at Microsoft.", context="Team meeting", - document_id=document_id + document_id=document_id, + request_context=request_context, ) # Retrieve document - doc = await memory.get_document(document_id, bank_id) + doc = await memory.get_document(document_id, bank_id, request_context=request_context) assert doc is not None assert doc["id"] == document_id @@ -32,11 +34,11 @@ async def test_document_creation_and_retrieval(memory): assert doc["memory_unit_count"] > 0 finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) @pytest.mark.asyncio -async def test_document_upsert(memory): +async def test_document_upsert(memory, request_context): """Test that providing the same document_id automatically upserts (deletes old units and creates new ones).""" bank_id = f"test_upsert_{datetime.now(timezone.utc).timestamp()}" @@ -48,11 +50,12 @@ async def test_document_upsert(memory): bank_id=bank_id, content="Alice works at Google.", context="Initial", - document_id=document_id + document_id=document_id, + request_context=request_context, ) # Get document stats - doc_v1 = await memory.get_document(document_id, bank_id) + doc_v1 = await memory.get_document(document_id, bank_id, request_context=request_context) count_v1 = doc_v1["memory_unit_count"] # Update with different content (automatic upsert when same document_id is provided) @@ -60,11 +63,12 @@ async def test_document_upsert(memory): bank_id=bank_id, content="Alice works at Microsoft. Bob works at Apple.", context="Updated", - document_id=document_id + document_id=document_id, + request_context=request_context, ) # Get updated document stats - doc_v2 = await memory.get_document(document_id, bank_id) + doc_v2 = await memory.get_document(document_id, bank_id, request_context=request_context) count_v2 = doc_v2["memory_unit_count"] # Verify old units were replaced @@ -75,11 +79,11 @@ async def test_document_upsert(memory): assert set(units_v1).isdisjoint(set(units_v2)) finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) @pytest.mark.asyncio -async def test_document_deletion(memory): +async def test_document_deletion(memory, request_context): """Test that deleting a document cascades to memory units.""" bank_id = f"test_delete_{datetime.now(timezone.utc).timestamp()}" @@ -91,29 +95,30 @@ async def test_document_deletion(memory): bank_id=bank_id, content="Alice works at Google.", context="Test", - document_id=document_id + document_id=document_id, + request_context=request_context, ) # Verify it exists - doc = await memory.get_document(document_id, bank_id) + doc = await memory.get_document(document_id, bank_id, request_context=request_context) assert doc is not None assert doc["memory_unit_count"] > 0 # Delete document - result = await memory.delete_document(document_id, bank_id) + result = await memory.delete_document(document_id, bank_id, request_context=request_context) assert result["document_deleted"] == 1 assert result["memory_units_deleted"] > 0 # Verify it's gone - doc_after = await memory.get_document(document_id, bank_id) + doc_after = await memory.get_document(document_id, bank_id, request_context=request_context) assert doc_after is None finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) @pytest.mark.asyncio -async def test_memory_without_document(memory): +async def test_memory_without_document(memory, request_context): """Test that memories can still be created without document tracking.""" bank_id = f"test_no_doc_{datetime.now(timezone.utc).timestamp()}" @@ -122,10 +127,11 @@ async def test_memory_without_document(memory): units = await memory.retain_async( bank_id=bank_id, content="Alice works at Google.", - context="Test" + context="Test", + request_context=request_context, ) assert len(units) > 0 finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) diff --git a/hindsight-api/tests/test_extensions.py b/hindsight-api/tests/test_extensions.py new file mode 100644 index 00000000..88a2f5d3 --- /dev/null +++ b/hindsight-api/tests/test_extensions.py @@ -0,0 +1,796 @@ +"""Tests for the Hindsight extensions system.""" + +from collections import defaultdict + +import pytest +from fastapi import APIRouter +from fastapi.testclient import TestClient + +from hindsight_api.extensions import ( + ApiKeyTenantExtension, + AuthenticationError, + Extension, + HttpExtension, + OperationValidationError, + OperationValidatorExtension, + RecallContext, + RecallResult, + ReflectContext, + ReflectResultContext, + RequestContext, + RetainContext, + RetainResult, + TenantContext, + TenantExtension, + ValidationResult, + load_extension, +) + + +class TestExtensionLoader: + """Tests for extension loading and lifecycle.""" + + def test_load_extension_with_config(self, monkeypatch): + """Extension receives config from prefixed env vars and supports lifecycle.""" + monkeypatch.setenv( + "HINDSIGHT_API_TEST_EXTENSION", + "tests.test_extensions:LifecycleTestExtension", + ) + monkeypatch.setenv("HINDSIGHT_API_TEST_API_URL", "https://example.com") + monkeypatch.setenv("HINDSIGHT_API_TEST_MAX_RETRIES", "5") + + ext = load_extension("TEST", Extension) + + assert ext is not None + assert ext.config["api_url"] == "https://example.com" + assert ext.config["max_retries"] == "5" + + @pytest.mark.asyncio + async def test_extension_lifecycle(self, monkeypatch): + """Extension on_startup and on_shutdown are called.""" + monkeypatch.setenv( + "HINDSIGHT_API_TEST_EXTENSION", + "tests.test_extensions:LifecycleTestExtension", + ) + + ext = load_extension("TEST", Extension) + + assert not ext.started + assert not ext.stopped + + await ext.on_startup() + assert ext.started + + await ext.on_shutdown() + assert ext.stopped + + +class LifecycleTestExtension(Extension): + """Test extension for config and lifecycle tests.""" + + def __init__(self, config): + super().__init__(config) + self.started = False + self.stopped = False + + async def on_startup(self): + self.started = True + + async def on_shutdown(self): + self.stopped = True + + +class RateLimitingValidator(OperationValidatorExtension): + """ + Mock validator that blocks after N attempts per bank_id. + + Used for testing the extension integration with MemoryEngine. + """ + + def __init__(self, config: dict): + super().__init__(config) + self.max_attempts = int(config.get("max_attempts", "2")) + self.retain_counts: dict[str, int] = defaultdict(int) + self.recall_counts: dict[str, int] = defaultdict(int) + self.reflect_counts: dict[str, int] = defaultdict(int) + + async def validate_retain(self, ctx: RetainContext) -> ValidationResult: + self.retain_counts[ctx.bank_id] += 1 + if self.retain_counts[ctx.bank_id] > self.max_attempts: + return ValidationResult.reject( + f"Retain limit exceeded for bank {ctx.bank_id}" + ) + return ValidationResult.accept() + + async def validate_recall(self, ctx: RecallContext) -> ValidationResult: + self.recall_counts[ctx.bank_id] += 1 + if self.recall_counts[ctx.bank_id] > self.max_attempts: + return ValidationResult.reject( + f"Recall limit exceeded for bank {ctx.bank_id}" + ) + return ValidationResult.accept() + + async def validate_reflect(self, ctx: ReflectContext) -> ValidationResult: + self.reflect_counts[ctx.bank_id] += 1 + if self.reflect_counts[ctx.bank_id] > self.max_attempts: + return ValidationResult.reject( + f"Reflect limit exceeded for bank {ctx.bank_id}" + ) + return ValidationResult.accept() + + +class TrackingValidator(OperationValidatorExtension): + """ + Mock validator that tracks all pre and post hook calls with full parameters. + + Used for testing that hooks receive all user-provided parameters. + """ + + def __init__(self, config: dict): + super().__init__(config) + # Pre-hook tracking + self.pre_retain_calls: list[RetainContext] = [] + self.pre_recall_calls: list[RecallContext] = [] + self.pre_reflect_calls: list[ReflectContext] = [] + # Post-hook tracking + self.post_retain_calls: list[RetainResult] = [] + self.post_recall_calls: list[RecallResult] = [] + self.post_reflect_calls: list[ReflectResultContext] = [] + + async def validate_retain(self, ctx: RetainContext) -> ValidationResult: + self.pre_retain_calls.append(ctx) + return ValidationResult.accept() + + async def validate_recall(self, ctx: RecallContext) -> ValidationResult: + self.pre_recall_calls.append(ctx) + return ValidationResult.accept() + + async def validate_reflect(self, ctx: ReflectContext) -> ValidationResult: + self.pre_reflect_calls.append(ctx) + return ValidationResult.accept() + + async def on_retain_complete(self, result: RetainResult) -> None: + self.post_retain_calls.append(result) + + async def on_recall_complete(self, result: RecallResult) -> None: + self.post_recall_calls.append(result) + + async def on_reflect_complete(self, result: ReflectResultContext) -> None: + self.post_reflect_calls.append(result) + + +class TestMemoryEngineValidation: + """Tests for validation integration with MemoryEngine. + + The OperationValidatorExtension is integrated at the MemoryEngine level, + so all interfaces (HTTP API, MCP, SDK) get the same validation behavior. + + For retain, the batch is validated as a whole (all or nothing) using + retain_batch_async which is the public method used by the HTTP API. + """ + + @pytest.mark.asyncio + async def test_retain_batch_validation(self, memory_with_validator): + """Retain batch is validated as a whole - accepts or rejects entire batch.""" + memory = memory_with_validator + bank_id = "test-retain-batch" + ctx = RequestContext() + + # First batch should succeed + await memory.retain_batch_async( + bank_id=bank_id, + contents=[ + {"content": "First item"}, + {"content": "Second item"}, + ], + request_context=ctx, + ) + + # Second batch should succeed (2nd attempt) + await memory.retain_batch_async( + bank_id=bank_id, + contents=[{"content": "Third item"}], + request_context=ctx, + ) + + # Third batch should be blocked entirely (exceeds limit) + with pytest.raises(OperationValidationError) as exc_info: + await memory.retain_batch_async( + bank_id=bank_id, + contents=[ + {"content": "Should not be stored"}, + {"content": "Neither should this"}, + ], + request_context=ctx, + ) + + assert "limit exceeded" in str(exc_info.value).lower() + + @pytest.mark.asyncio + async def test_recall_validation(self, memory_with_validator): + """Recall is validated before execution.""" + memory = memory_with_validator + bank_id = "test-recall-validation" + ctx = RequestContext() + + # First recall should pass validation + await memory.recall_async(bank_id, "test query", fact_type=["world"], request_context=ctx) + + # Second recall should pass validation + await memory.recall_async(bank_id, "another query", fact_type=["world"], request_context=ctx) + + # Third recall should be blocked by validator + with pytest.raises(OperationValidationError) as exc_info: + await memory.recall_async(bank_id, "blocked query", fact_type=["world"], request_context=ctx) + + assert "limit exceeded" in str(exc_info.value).lower() + + @pytest.mark.asyncio + async def test_reflect_validation(self, memory_with_validator): + """Reflect is validated before execution.""" + memory = memory_with_validator + bank_id = "test-reflect-validation" + ctx = RequestContext() + + # First reflect should pass validation (may fail internally but validation passes) + try: + await memory.reflect_async(bank_id, "test question", request_context=ctx) + except OperationValidationError: + raise # Re-raise validation errors + except Exception: + pass # Other errors are fine (e.g., no data) + + # Second reflect should pass validation + try: + await memory.reflect_async(bank_id, "another question", request_context=ctx) + except OperationValidationError: + raise + except Exception: + pass + + # Third reflect should be blocked by validator + with pytest.raises(OperationValidationError) as exc_info: + await memory.reflect_async(bank_id, "blocked question", request_context=ctx) + + assert "limit exceeded" in str(exc_info.value).lower() + + +@pytest.fixture +def memory_with_validator(memory): + """Memory engine with a rate-limiting validator (max 2 attempts per bank).""" + validator = RateLimitingValidator({"max_attempts": "2"}) + memory._operation_validator = validator + return memory + + +@pytest.fixture +def memory_with_tracking_validator(memory): + """Memory engine with a tracking validator that records all hook calls.""" + validator = TrackingValidator({}) + memory._operation_validator = validator + return memory, validator + + +class TestOperationHooksParameters: + """Tests for pre and post operation hooks receiving all user-provided parameters.""" + + @pytest.mark.asyncio + async def test_retain_pre_hook_receives_all_parameters(self, memory_with_tracking_validator): + """Pre-retain hook receives all user-provided parameters.""" + memory, validator = memory_with_tracking_validator + bank_id = "test-retain-params" + ctx = RequestContext(api_key="test-key") + contents = [{"content": "Test content", "context": "test context"}] + document_id = "doc-123" + + await memory.retain_batch_async( + bank_id=bank_id, + contents=contents, + document_id=document_id, + fact_type_override="world", + confidence_score=0.9, + request_context=ctx, + ) + + assert len(validator.pre_retain_calls) == 1 + pre_ctx = validator.pre_retain_calls[0] + + # Verify all parameters are present + assert pre_ctx.bank_id == bank_id + # Note: contents is copied before document_id is applied to individual items + assert len(pre_ctx.contents) == len(contents) + assert pre_ctx.contents[0]["content"] == contents[0]["content"] + assert pre_ctx.document_id == document_id + assert pre_ctx.fact_type_override == "world" + assert pre_ctx.confidence_score == 0.9 + assert pre_ctx.request_context == ctx + + @pytest.mark.asyncio + async def test_retain_post_hook_receives_all_parameters_and_result(self, memory_with_tracking_validator): + """Post-retain hook receives all parameters plus the result.""" + memory, validator = memory_with_tracking_validator + bank_id = "test-retain-post" + ctx = RequestContext(api_key="test-key") + contents = [{"content": "Test content for post hook"}] + document_id = "doc-456" + + result = await memory.retain_batch_async( + bank_id=bank_id, + contents=contents, + document_id=document_id, + fact_type_override="experience", + confidence_score=0.8, + request_context=ctx, + ) + + assert len(validator.post_retain_calls) == 1 + post_result = validator.post_retain_calls[0] + + # Verify all parameters are present + assert post_result.bank_id == bank_id + assert post_result.document_id == document_id + assert post_result.fact_type_override == "experience" + assert post_result.confidence_score == 0.8 + assert post_result.request_context == ctx + + # Verify result data + assert post_result.success is True + assert post_result.error is None + assert post_result.unit_ids == result # Should match the return value + + @pytest.mark.asyncio + async def test_recall_pre_hook_receives_all_parameters(self, memory_with_tracking_validator): + """Pre-recall hook receives all user-provided parameters.""" + from datetime import datetime, timezone + from hindsight_api.engine.memory_engine import Budget + + memory, validator = memory_with_tracking_validator + bank_id = "test-recall-params" + ctx = RequestContext(api_key="test-key") + query = "test query" + question_date = datetime(2024, 1, 15, tzinfo=timezone.utc) + + await memory.recall_async( + bank_id=bank_id, + query=query, + budget=Budget.HIGH, + max_tokens=2048, + enable_trace=True, + fact_type=["world", "experience"], + question_date=question_date, + include_entities=True, + max_entity_tokens=300, + include_chunks=True, + max_chunk_tokens=4096, + request_context=ctx, + ) + + assert len(validator.pre_recall_calls) == 1 + pre_ctx = validator.pre_recall_calls[0] + + # Verify all parameters are present + assert pre_ctx.bank_id == bank_id + assert pre_ctx.query == query + assert pre_ctx.budget == Budget.HIGH + assert pre_ctx.max_tokens == 2048 + assert pre_ctx.enable_trace is True + assert pre_ctx.fact_types == ["world", "experience"] + assert pre_ctx.question_date == question_date + assert pre_ctx.include_entities is True + assert pre_ctx.max_entity_tokens == 300 + assert pre_ctx.include_chunks is True + assert pre_ctx.max_chunk_tokens == 4096 + assert pre_ctx.request_context == ctx + + @pytest.mark.asyncio + async def test_recall_post_hook_receives_all_parameters_and_result(self, memory_with_tracking_validator): + """Post-recall hook receives all parameters plus the result.""" + from hindsight_api.engine.memory_engine import Budget + + memory, validator = memory_with_tracking_validator + bank_id = "test-recall-post" + ctx = RequestContext(api_key="test-key") + + result = await memory.recall_async( + bank_id=bank_id, + query="test query for post", + budget=Budget.LOW, + max_tokens=1024, + fact_type=["world"], + request_context=ctx, + ) + + assert len(validator.post_recall_calls) == 1 + post_result = validator.post_recall_calls[0] + + # Verify all parameters are present + assert post_result.bank_id == bank_id + assert post_result.query == "test query for post" + assert post_result.budget == Budget.LOW + assert post_result.max_tokens == 1024 + assert post_result.fact_types == ["world"] + assert post_result.request_context == ctx + + # Verify result data + assert post_result.success is True + assert post_result.error is None + assert post_result.result == result # Should match the return value + + @pytest.mark.asyncio + async def test_reflect_pre_hook_receives_all_parameters(self, memory_with_tracking_validator): + """Pre-reflect hook receives all user-provided parameters.""" + from hindsight_api.engine.memory_engine import Budget + + memory, validator = memory_with_tracking_validator + bank_id = "test-reflect-params" + ctx = RequestContext(api_key="test-key") + + try: + await memory.reflect_async( + bank_id=bank_id, + query="test question", + budget=Budget.MID, + context="additional context", + request_context=ctx, + ) + except Exception: + pass # May fail if no data, but pre-hook should still be called + + assert len(validator.pre_reflect_calls) == 1 + pre_ctx = validator.pre_reflect_calls[0] + + # Verify all parameters are present + assert pre_ctx.bank_id == bank_id + assert pre_ctx.query == "test question" + assert pre_ctx.budget == Budget.MID + assert pre_ctx.context == "additional context" + assert pre_ctx.request_context == ctx + + @pytest.mark.asyncio + async def test_reflect_post_hook_receives_all_parameters_and_result(self, memory_with_tracking_validator): + """Post-reflect hook receives all parameters plus the result on success.""" + from hindsight_api.engine.memory_engine import Budget + + memory, validator = memory_with_tracking_validator + bank_id = "test-reflect-post" + ctx = RequestContext(api_key="test-key") + + # Store some content first so reflect has something to work with + await memory.retain_batch_async( + bank_id=bank_id, + contents=[{"content": "Alice is a software engineer at Google."}], + request_context=ctx, + ) + + result = await memory.reflect_async( + bank_id=bank_id, + query="What does Alice do?", + budget=Budget.LOW, + context="work context", + request_context=ctx, + ) + + assert len(validator.post_reflect_calls) == 1 + post_result = validator.post_reflect_calls[0] + + # Verify all parameters are present + assert post_result.bank_id == bank_id + assert post_result.query == "What does Alice do?" + assert post_result.budget == Budget.LOW + assert post_result.context == "work context" + assert post_result.request_context == ctx + + # Verify result data + assert post_result.success is True + assert post_result.error is None + assert post_result.result == result # Should match the return value + assert post_result.result.text is not None + + @pytest.mark.asyncio + async def test_post_hooks_called_in_order_after_pre_hooks(self, memory_with_tracking_validator): + """Post hooks are called after pre hooks and after operation completes.""" + memory, validator = memory_with_tracking_validator + bank_id = "test-hook-order" + ctx = RequestContext() + + # Retain operation + await memory.retain_batch_async( + bank_id=bank_id, + contents=[{"content": "Test content"}], + request_context=ctx, + ) + + # Pre-hook should be called before post-hook + assert len(validator.pre_retain_calls) == 1 + assert len(validator.post_retain_calls) == 1 + + # Recall operation + await memory.recall_async( + bank_id=bank_id, + query="test", + fact_type=["world"], + request_context=ctx, + ) + + assert len(validator.pre_recall_calls) == 1 + assert len(validator.post_recall_calls) == 1 + + +class TestTenantExtension: + """Tests for TenantExtension and ApiKeyTenantExtension.""" + + @pytest.mark.asyncio + async def test_api_key_tenant_extension_valid_key(self): + """ApiKeyTenantExtension accepts valid API key.""" + ext = ApiKeyTenantExtension({"api_key": "secret-key-123"}) + + result = await ext.authenticate(RequestContext(api_key="secret-key-123")) + + assert result.schema_name == "public" + + @pytest.mark.asyncio + async def test_api_key_tenant_extension_invalid_key(self): + """ApiKeyTenantExtension rejects invalid API key.""" + ext = ApiKeyTenantExtension({"api_key": "secret-key-123"}) + + with pytest.raises(AuthenticationError) as exc_info: + await ext.authenticate(RequestContext(api_key="wrong-key")) + + assert "Invalid API key" in str(exc_info.value) + + @pytest.mark.asyncio + async def test_api_key_tenant_extension_missing_key(self): + """ApiKeyTenantExtension rejects missing API key.""" + ext = ApiKeyTenantExtension({"api_key": "secret-key-123"}) + + with pytest.raises(AuthenticationError): + await ext.authenticate(RequestContext(api_key=None)) + + def test_api_key_tenant_extension_requires_config(self): + """ApiKeyTenantExtension requires api_key in config.""" + with pytest.raises(ValueError) as exc_info: + ApiKeyTenantExtension({}) + + assert "HINDSIGHT_API_TENANT_API_KEY is required" in str(exc_info.value) + + +class TestMemoryEngineTenantAuth: + """Tests for tenant authentication in MemoryEngine.""" + + @pytest.mark.asyncio + async def test_retain_requires_tenant_request_when_extension_configured( + self, memory_with_tenant + ): + """Retain fails without RequestContext when tenant extension is configured.""" + memory = memory_with_tenant + + with pytest.raises(AuthenticationError) as exc_info: + await memory.retain_batch_async( + bank_id="test-bank", + contents=[{"content": "test"}], + request_context=None, # Missing! + ) + + assert "RequestContext is required" in str(exc_info.value) + + @pytest.mark.asyncio + async def test_retain_succeeds_with_valid_tenant_request(self, memory_with_tenant): + """Retain succeeds with valid RequestContext.""" + memory = memory_with_tenant + + # Should not raise + await memory.retain_batch_async( + bank_id="test-bank-tenant", + contents=[{"content": "test content"}], + request_context=RequestContext(api_key="test-api-key"), + ) + + @pytest.mark.asyncio + async def test_retain_fails_with_invalid_api_key(self, memory_with_tenant): + """Retain fails with invalid API key.""" + memory = memory_with_tenant + + with pytest.raises(AuthenticationError) as exc_info: + await memory.retain_batch_async( + bank_id="test-bank", + contents=[{"content": "test"}], + request_context=RequestContext(api_key="wrong-key"), + ) + + assert "Invalid API key" in str(exc_info.value) + + @pytest.mark.asyncio + async def test_recall_requires_tenant_request_when_extension_configured( + self, memory_with_tenant + ): + """Recall fails without RequestContext when tenant extension is configured.""" + memory = memory_with_tenant + + with pytest.raises(AuthenticationError): + await memory.recall_async( + bank_id="test-bank", + query="test query", + fact_type=["world"], + request_context=None, + ) + + @pytest.mark.asyncio + async def test_no_tenant_request_needed_without_extension(self, memory): + """Operations work with empty RequestContext when no tenant extension configured.""" + # Should not raise - no tenant extension configured, just pass empty RequestContext + await memory.retain_batch_async( + bank_id="test-bank-no-tenant", + contents=[{"content": "test content"}], + request_context=RequestContext(), + ) + + +@pytest.fixture +def memory_with_tenant(memory): + """Memory engine with a tenant extension (API key auth).""" + tenant_ext = ApiKeyTenantExtension({"api_key": "test-api-key"}) + memory._tenant_extension = tenant_ext + return memory + + +class SampleHttpExtension(HttpExtension): + """Sample HTTP extension for testing that provides custom endpoints.""" + + def __init__(self, config: dict): + super().__init__(config) + self.started = False + self.stopped = False + self.request_count = 0 + + async def on_startup(self): + self.started = True + + async def on_shutdown(self): + self.stopped = True + + def get_router(self, memory) -> APIRouter: + router = APIRouter() + + @router.get("/hello") + async def hello(): + self.request_count += 1 + return {"message": "Hello from extension!"} + + @router.get("/config") + async def get_config(): + return {"config": self.config} + + @router.get("/health-check") + async def extension_health(): + health = await memory.health_check() + return {"extension": "healthy", "memory": health} + + @router.post("/echo") + async def echo(data: dict): + return {"echoed": data} + + return router + + +class TestHttpExtensionIntegration: + """Tests for HTTP extension integration.""" + + def test_load_http_extension(self, monkeypatch): + """HttpExtension can be loaded from environment variable.""" + monkeypatch.setenv( + "HINDSIGHT_API_HTTP_EXTENSION", + "tests.test_extensions:SampleHttpExtension", + ) + monkeypatch.setenv("HINDSIGHT_API_HTTP_CUSTOM_PARAM", "custom_value") + + ext = load_extension("HTTP", HttpExtension) + + assert ext is not None + assert isinstance(ext, SampleHttpExtension) + assert ext.config["custom_param"] == "custom_value" + + def test_http_extension_router_mounted_at_ext(self, memory): + """HTTP extension router is mounted at /ext/.""" + from hindsight_api.api.http import create_app + + ext = SampleHttpExtension({"test_key": "test_value"}) + app = create_app(memory, initialize_memory=False, http_extension=ext) + + client = TestClient(app) + + # Extension endpoint should be accessible at /ext/ + response = client.get("/ext/hello") + assert response.status_code == 200 + assert response.json() == {"message": "Hello from extension!"} + + # Should track request count + assert ext.request_count == 1 + + # Old path should NOT work + response = client.get("/extension/hello") + assert response.status_code == 404 + + def test_http_extension_config_endpoint(self, memory): + """Extension can expose its config via custom endpoint.""" + from hindsight_api.api.http import create_app + + ext = SampleHttpExtension({"api_key": "secret", "limit": "100"}) + app = create_app(memory, initialize_memory=False, http_extension=ext) + + client = TestClient(app) + + response = client.get("/ext/config") + assert response.status_code == 200 + assert response.json()["config"]["api_key"] == "secret" + assert response.json()["config"]["limit"] == "100" + + def test_http_extension_can_access_memory(self, memory): + """Extension endpoints can access memory engine.""" + from hindsight_api.api.http import create_app + + ext = SampleHttpExtension({}) + app = create_app(memory, initialize_memory=False, http_extension=ext) + + client = TestClient(app) + + response = client.get("/ext/health-check") + assert response.status_code == 200 + data = response.json() + assert data["extension"] == "healthy" + assert "memory" in data + + def test_http_extension_post_endpoint(self, memory): + """Extension can handle POST requests with JSON body.""" + from hindsight_api.api.http import create_app + + ext = SampleHttpExtension({}) + app = create_app(memory, initialize_memory=False, http_extension=ext) + + client = TestClient(app) + + response = client.post("/ext/echo", json={"key": "value", "number": 42}) + assert response.status_code == 200 + assert response.json() == {"echoed": {"key": "value", "number": 42}} + + def test_http_extension_not_mounted_when_none(self, memory): + """No extension routes when http_extension is None.""" + from hindsight_api.api.http import create_app + + app = create_app(memory, initialize_memory=False, http_extension=None) + + client = TestClient(app) + + # Extension endpoint should not exist + response = client.get("/ext/hello") + assert response.status_code == 404 + + @pytest.mark.asyncio + async def test_http_extension_lifecycle(self): + """HTTP extension on_startup and on_shutdown are called.""" + ext = SampleHttpExtension({}) + + assert not ext.started + assert not ext.stopped + + await ext.on_startup() + assert ext.started + + await ext.on_shutdown() + assert ext.stopped + + def test_core_routes_still_work_with_extension(self, memory): + """Core API routes still work when extension is mounted.""" + from hindsight_api.api.http import create_app + + ext = SampleHttpExtension({}) + app = create_app(memory, initialize_memory=False, http_extension=ext) + + client = TestClient(app) + + # Health endpoint should work + response = client.get("/health") + assert response.status_code in (200, 503) # May be unhealthy if DB not connected + + # Banks list endpoint should work + response = client.get("/v1/default/banks") + assert response.status_code in (200, 500) # May fail if DB not ready diff --git a/hindsight-api/tests/test_fact_extraction_quality.py b/hindsight-api/tests/test_fact_extraction_quality.py index 5e852a46..7d67900e 100644 --- a/hindsight-api/tests/test_fact_extraction_quality.py +++ b/hindsight-api/tests/test_fact_extraction_quality.py @@ -897,7 +897,7 @@ class TestDispositionInference: """Tests for LLM-based disposition trait inference from background.""" @pytest.mark.asyncio - async def test_background_merge_with_disposition_inference(self, memory): + async def test_background_merge_with_disposition_inference(self, memory, request_context): """Test that background merge infers disposition traits by default.""" import uuid bank_id = f"test_infer_{uuid.uuid4().hex[:8]}" @@ -905,7 +905,8 @@ class TestDispositionInference: result = await memory.merge_bank_background( bank_id, "I am a creative software engineer who loves innovation and trying new technologies", - update_disposition=True + update_disposition=True, + request_context=request_context, ) assert "background" in result @@ -923,30 +924,31 @@ class TestDispositionInference: assert 1 <= disposition[trait] <= 5 @pytest.mark.asyncio - async def test_background_merge_without_disposition_inference(self, memory): + async def test_background_merge_without_disposition_inference(self, memory, request_context): """Test that background merge skips disposition inference when disabled.""" import uuid bank_id = f"test_no_infer_{uuid.uuid4().hex[:8]}" - initial_profile = await memory.get_bank_profile(bank_id) + initial_profile = await memory.get_bank_profile(bank_id, request_context=request_context) initial_disposition = initial_profile["disposition"] result = await memory.merge_bank_background( bank_id, "I am a data scientist", - update_disposition=False + update_disposition=False, + request_context=request_context, ) assert "background" in result assert "disposition" not in result - final_profile = await memory.get_bank_profile(bank_id) + final_profile = await memory.get_bank_profile(bank_id, request_context=request_context) final_disposition = final_profile["disposition"] assert initial_disposition == final_disposition @pytest.mark.asyncio - async def test_disposition_inference_for_lawyer(self, memory): + async def test_disposition_inference_for_lawyer(self, memory, request_context): """Test disposition inference for lawyer profile (high skepticism, high literalism).""" import uuid bank_id = f"test_lawyer_{uuid.uuid4().hex[:8]}" @@ -954,7 +956,8 @@ class TestDispositionInference: result = await memory.merge_bank_background( bank_id, "I am a lawyer who focuses on contract details and never takes claims at face value", - update_disposition=True + update_disposition=True, + request_context=request_context, ) disposition = result["disposition"] @@ -964,7 +967,7 @@ class TestDispositionInference: assert disposition["literalism"] >= 3 @pytest.mark.asyncio - async def test_disposition_inference_for_therapist(self, memory): + async def test_disposition_inference_for_therapist(self, memory, request_context): """Test disposition inference for therapist profile (high empathy).""" import uuid bank_id = f"test_therapist_{uuid.uuid4().hex[:8]}" @@ -972,7 +975,8 @@ class TestDispositionInference: result = await memory.merge_bank_background( bank_id, "I am a therapist who deeply understands and connects with people's emotional struggles", - update_disposition=True + update_disposition=True, + request_context=request_context, ) disposition = result["disposition"] @@ -981,7 +985,7 @@ class TestDispositionInference: assert disposition["empathy"] >= 3 @pytest.mark.asyncio - async def test_disposition_updates_in_database(self, memory): + async def test_disposition_updates_in_database(self, memory, request_context): """Test that inferred disposition is actually stored in database.""" import uuid bank_id = f"test_db_update_{uuid.uuid4().hex[:8]}" @@ -989,12 +993,13 @@ class TestDispositionInference: result = await memory.merge_bank_background( bank_id, "I am an innovative designer", - update_disposition=True + update_disposition=True, + request_context=request_context, ) inferred_disposition = result["disposition"] - profile = await memory.get_bank_profile(bank_id) + profile = await memory.get_bank_profile(bank_id, request_context=request_context) db_disposition = profile["disposition"] # Compare values (db_disposition is a Pydantic model) @@ -1003,7 +1008,7 @@ class TestDispositionInference: assert db_disposition.empathy == inferred_disposition["empathy"] @pytest.mark.asyncio - async def test_multiple_background_merges_update_disposition(self, memory): + async def test_multiple_background_merges_update_disposition(self, memory, request_context): """Test that each background merge can update disposition.""" import uuid bank_id = f"test_multi_merge_{uuid.uuid4().hex[:8]}" @@ -1011,14 +1016,16 @@ class TestDispositionInference: result1 = await memory.merge_bank_background( bank_id, "I am a software engineer", - update_disposition=True + update_disposition=True, + request_context=request_context, ) disposition1 = result1["disposition"] result2 = await memory.merge_bank_background( bank_id, "I love creative problem solving and innovation", - update_disposition=True + update_disposition=True, + request_context=request_context, ) disposition2 = result2["disposition"] @@ -1026,7 +1033,7 @@ class TestDispositionInference: assert "creative" in result2["background"].lower() or "innovation" in result2["background"].lower() @pytest.mark.asyncio - async def test_background_merge_conflict_resolution_with_disposition(self, memory): + async def test_background_merge_conflict_resolution_with_disposition(self, memory, request_context): """Test that conflicts are resolved and disposition reflects final background.""" import uuid bank_id = f"test_conflict_{uuid.uuid4().hex[:8]}" @@ -1034,13 +1041,15 @@ class TestDispositionInference: await memory.merge_bank_background( bank_id, "I was born in Colorado and prefer stability", - update_disposition=True + update_disposition=True, + request_context=request_context, ) result = await memory.merge_bank_background( bank_id, "You were born in Texas and are very skeptical of people", - update_disposition=True + update_disposition=True, + request_context=request_context, ) background = result["background"] diff --git a/hindsight-api/tests/test_fact_ordering.py b/hindsight-api/tests/test_fact_ordering.py index f16c4a0c..84fdbf65 100644 --- a/hindsight-api/tests/test_fact_ordering.py +++ b/hindsight-api/tests/test_fact_ordering.py @@ -7,24 +7,24 @@ distinguish between things said earlier vs later. """ import pytest from datetime import datetime, timezone -from hindsight_api import MemoryEngine +from hindsight_api import MemoryEngine, RequestContext from hindsight_api.engine.memory_engine import Budget import os @pytest.mark.asyncio -async def test_fact_ordering_within_conversation(memory): +async def test_fact_ordering_within_conversation(memory, request_context): bank_id = "test_ordering_agent" # Get/create agent (auto-creates with defaults) - await memory.get_bank_profile(bank_id) + await memory.get_bank_profile(bank_id, request_context=request_context) # Update disposition to match Marcus await memory.update_bank_disposition(bank_id, { "skepticism": 3, "literalism": 3, "empathy": 3 - }) + }, request_context=request_context) # A conversation where Marcus changes his position conversation = """ @@ -43,7 +43,8 @@ Marcus: Yeah, I realized I was being too optimistic about their defense. content=conversation, context="podcast discussion about NFL game", event_date=base_event_date, - document_id="test_conv_1" + document_id="test_conv_1", + request_context=request_context, ) # Search for all facts about Marcus's predictions @@ -52,7 +53,8 @@ Marcus: Yeah, I realized I was being too optimistic about their defense. query="Marcus prediction Rams", fact_type=['opinion', 'experience', 'world'], budget=Budget.LOW, - max_tokens=8192 + max_tokens=8192, + request_context=request_context, ) print(f"\n=== Retrieved {len(results.results)} facts ===") @@ -113,17 +115,17 @@ Marcus: Yeah, I realized I was being too optimistic about their defense. print(f"\n✅ Temporal ordering preserved: First prediction came before changed prediction") # Cleanup - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) print(f"\n✅ Test passed: Fact ordering within conversation is preserved") @pytest.mark.asyncio -async def test_multiple_documents_ordering(memory): +async def test_multiple_documents_ordering(memory, request_context): bank_id = "test_multi_doc_agent" - await memory.get_bank_profile(bank_id) # Auto-creates with defaults + await memory.get_bank_profile(bank_id, request_context=request_context) # Auto-creates with defaults # Two separate conversations with same base time base_time = datetime(2024, 11, 14, 10, 0, 0, tzinfo=timezone.utc) @@ -146,7 +148,8 @@ Alice: I reconsidered the team's experience level. contents=[ {"content": conv1, "context": "project discussion 1", "event_date": base_time}, {"content": conv2, "context": "project discussion 2", "event_date": base_time} - ] + ], + request_context=request_context, ) # Search for Alice's preferences @@ -155,7 +158,8 @@ Alice: I reconsidered the team's experience level. query="Alice preference React Vue", fact_type=['opinion', 'experience'], budget=Budget.LOW, - max_tokens=8192 + max_tokens=8192, + request_context=request_context, ) print(f"\n=== Retrieved {len(results.results)} agent facts ===") @@ -175,6 +179,6 @@ Alice: I reconsidered the team's experience level. print(f"\n✅ Facts from {len(agent_facts)} statements have {len(unique_timestamps)} unique timestamps") # Cleanup - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) print(f"\n✅ Test passed: Multiple documents maintain separate ordering") diff --git a/hindsight-api/tests/test_observations.py b/hindsight-api/tests/test_observations.py index 1085d036..f66f16cf 100644 --- a/hindsight-api/tests/test_observations.py +++ b/hindsight-api/tests/test_observations.py @@ -3,11 +3,12 @@ Test observation generation and entity state functionality. """ import pytest from hindsight_api.engine.memory_engine import Budget +from hindsight_api import RequestContext from datetime import datetime, timezone @pytest.mark.asyncio -async def test_observation_generation_on_put(memory): +async def test_observation_generation_on_put(memory, request_context): """ Test that observations are generated SYNCHRONOUSLY when new facts are added. @@ -36,7 +37,8 @@ async def test_observation_generation_on_put(memory): bank_id=bank_id, content=content, context="work info", - event_date=datetime(2024, 1, 15 + i, tzinfo=timezone.utc) + event_date=datetime(2024, 1, 15 + i, tzinfo=timezone.utc), + request_context=request_context, ) # Observations are generated SYNCHRONOUSLY during retain, @@ -75,7 +77,7 @@ async def test_observation_generation_on_put(memory): print(f"Entity: {entity_name} (id: {entity_id})") # Get observations for the entity - should be available immediately - observations = await memory.get_entity_observations(bank_id, entity_id, limit=10) + observations = await memory.get_entity_observations(bank_id, entity_id, limit=10, request_context=request_context) print(f"\n=== Observations for {entity_name} ===") print(f"Total observations: {len(observations)}") @@ -102,7 +104,7 @@ async def test_observation_generation_on_put(memory): @pytest.mark.asyncio -async def test_regenerate_entity_observations(memory): +async def test_regenerate_entity_observations(memory, request_context): """ Test explicit regeneration of observations for an entity. """ @@ -114,7 +116,8 @@ async def test_regenerate_entity_observations(memory): bank_id=bank_id, content="Sarah is a product manager who loves user research and data analysis.", context="work info", - event_date=datetime(2024, 1, 15, tzinfo=timezone.utc) + event_date=datetime(2024, 1, 15, tzinfo=timezone.utc), + request_context=request_context, ) await memory.wait_for_background_tasks() @@ -140,14 +143,15 @@ async def test_regenerate_entity_observations(memory): created_ids = await memory.regenerate_entity_observations( bank_id=bank_id, entity_id=entity_id, - entity_name=entity_name + entity_name=entity_name, + request_context=request_context, ) print(f"\n=== Regenerated Observations ===") print(f"Created {len(created_ids)} observations for {entity_name}") # Get the observations - observations = await memory.get_entity_observations(bank_id, entity_id, limit=10) + observations = await memory.get_entity_observations(bank_id, entity_id, limit=10, request_context=request_context) for obs in observations: print(f" - {obs.text}") @@ -170,7 +174,7 @@ async def test_regenerate_entity_observations(memory): @pytest.mark.asyncio -async def test_search_with_include_entities(memory): +async def test_search_with_include_entities(memory, request_context): """ Test that search with include_entities=True returns entity observations. @@ -196,7 +200,8 @@ async def test_search_with_include_entities(memory): bank_id=bank_id, content=content, context="work info", - event_date=datetime(2024, 1, 15 + i, tzinfo=timezone.utc) + event_date=datetime(2024, 1, 15 + i, tzinfo=timezone.utc), + request_context=request_context, ) # Observations are generated synchronously during retain, no need to wait @@ -209,7 +214,8 @@ async def test_search_with_include_entities(memory): budget=Budget.LOW, max_tokens=2000, include_entities=True, - max_entity_tokens=500 + max_entity_tokens=500, + request_context=request_context, ) print(f"\n=== Search Results ===") @@ -263,7 +269,7 @@ async def test_search_with_include_entities(memory): @pytest.mark.asyncio -async def test_get_entity_state(memory): +async def test_get_entity_state(memory, request_context): """ Test getting the full state of an entity. """ @@ -275,7 +281,8 @@ async def test_get_entity_state(memory): bank_id=bank_id, content="Bob is a frontend developer who specializes in React and TypeScript.", context="work info", - event_date=datetime(2024, 1, 15, tzinfo=timezone.utc) + event_date=datetime(2024, 1, 15, tzinfo=timezone.utc), + request_context=request_context, ) await memory.wait_for_background_tasks() @@ -302,7 +309,8 @@ async def test_get_entity_state(memory): bank_id=bank_id, entity_id=entity_id, entity_name=entity_name, - limit=10 + limit=10, + request_context=request_context, ) print(f"\n=== Entity State for {entity_name} ===") @@ -324,7 +332,7 @@ async def test_get_entity_state(memory): @pytest.mark.asyncio -async def test_observation_fact_type_in_database(memory): +async def test_observation_fact_type_in_database(memory, request_context): """ Test that observations are stored with correct fact_type in database. """ @@ -336,7 +344,8 @@ async def test_observation_fact_type_in_database(memory): bank_id=bank_id, content="Charlie is a DevOps engineer who manages the Kubernetes infrastructure.", context="work info", - event_date=datetime(2024, 1, 15, tzinfo=timezone.utc) + event_date=datetime(2024, 1, 15, tzinfo=timezone.utc), + request_context=request_context, ) await memory.wait_for_background_tasks() @@ -374,7 +383,7 @@ async def test_observation_fact_type_in_database(memory): @pytest.mark.asyncio -async def test_user_entity_prioritized_for_observations(memory): +async def test_user_entity_prioritized_for_observations(memory, request_context): """ Test that the 'user' entity gets observations even when many other entities exist. @@ -410,7 +419,8 @@ async def test_user_entity_prioritized_for_observations(memory): bank_id=bank_id, content=content, context="personal info", - event_date=datetime(2024, 1, 15 + i, tzinfo=timezone.utc) + event_date=datetime(2024, 1, 15 + i, tzinfo=timezone.utc), + request_context=request_context, ) # Observations are generated synchronously during retain @@ -466,7 +476,7 @@ async def test_user_entity_prioritized_for_observations(memory): f"User entity should have at least 5 facts, but has {user_fact_count}" # Get observations for user entity - observations = await memory.get_entity_observations(bank_id, user_entity_id, limit=10) + observations = await memory.get_entity_observations(bank_id, user_entity_id, limit=10, request_context=request_context) print(f"\n=== User Entity Observations ===") print(f"Total observations: {len(observations)}") diff --git a/hindsight-api/tests/test_retain.py b/hindsight-api/tests/test_retain.py index cbbc570a..82999024 100644 --- a/hindsight-api/tests/test_retain.py +++ b/hindsight-api/tests/test_retain.py @@ -5,12 +5,13 @@ import pytest import logging from datetime import datetime, timezone, timedelta from hindsight_api.engine.memory_engine import Budget +from hindsight_api import RequestContext logger = logging.getLogger(__name__) @pytest.mark.asyncio -async def test_retain_with_chunks(memory): +async def test_retain_with_chunks(memory, request_context): """ Test that retain function: 1. Stores facts with associated chunks @@ -41,7 +42,8 @@ async def test_retain_with_chunks(memory): content=long_content, context="team overview", event_date=datetime(2024, 1, 15, tzinfo=timezone.utc), - document_id=document_id + document_id=document_id, + request_context=request_context, ) print(f"\n=== Retained {len(unit_ids)} facts ===") @@ -56,7 +58,8 @@ async def test_retain_with_chunks(memory): fact_type=["world"], # Search for world facts include_entities=False, # Disable entities for simpler test include_chunks=True, # Enable chunks - max_chunk_tokens=8192 + max_chunk_tokens=8192, + request_context=request_context, ) print(f"\n=== Recall Results (with chunks) ===") @@ -88,12 +91,12 @@ async def test_retain_with_chunks(memory): finally: # Cleanup - delete the test bank - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) print(f"\n=== Cleaned up bank: {bank_id} ===") @pytest.mark.asyncio -async def test_chunks_and_entities_follow_fact_order(memory): +async def test_chunks_and_entities_follow_fact_order(memory, request_context): """ Test that chunks and entities in recall results follow the same order as facts. This is critical because token limits may truncate later items. @@ -130,7 +133,8 @@ async def test_chunks_and_entities_follow_fact_order(memory): content=item["content"], context=item["context"], event_date=datetime(2024, 1, 15, tzinfo=timezone.utc), - document_id=item["document_id"] + document_id=item["document_id"], + request_context=request_context, ) print("\n=== Stored 3 separate documents ===") @@ -144,7 +148,8 @@ async def test_chunks_and_entities_follow_fact_order(memory): fact_type=["world"], include_entities=True, include_chunks=True, - max_chunk_tokens=8192 + max_chunk_tokens=8192, + request_context=request_context, ) print(f"\n=== Recall Results ===") @@ -214,12 +219,12 @@ async def test_chunks_and_entities_follow_fact_order(memory): finally: # Cleanup - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) print(f"\n=== Cleaned up bank: {bank_id} ===") @pytest.mark.asyncio -async def test_event_date_storage(memory): +async def test_event_date_storage(memory, request_context): """ Test that event_date is correctly stored as occurred_start. Verifies that we can track when events actually happened vs when they were stored. @@ -235,7 +240,8 @@ async def test_event_date_storage(memory): bank_id=bank_id, content="Alice completed the Q2 product launch on June 15th, 2023.", context="project history", - event_date=past_event_date + event_date=past_event_date, + request_context=request_context, ) assert len(unit_ids) > 0, "Should have created at least one memory unit" @@ -246,7 +252,8 @@ async def test_event_date_storage(memory): query="When did Alice complete the product launch?", budget=Budget.LOW, max_tokens=500, - fact_type=["world"] + fact_type=["world"], + request_context=request_context, ) assert len(result.results) > 0, "Should recall the stored fact" @@ -268,11 +275,11 @@ async def test_event_date_storage(memory): print(f"\n✓ Event date correctly stored: {occurred_dt}") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) @pytest.mark.asyncio -async def test_temporal_ordering(memory): +async def test_temporal_ordering(memory, request_context): """ Test that facts can be stored and retrieved with correct temporal ordering. Stores facts with different event_dates and verifies temporal relationships. @@ -305,7 +312,8 @@ async def test_temporal_ordering(memory): bank_id=bank_id, content=event["content"], context=event["context"], - event_date=event["event_date"] + event_date=event["event_date"], + request_context=request_context, ) print("\n=== Stored 3 events with different temporal dates ===") @@ -316,7 +324,8 @@ async def test_temporal_ordering(memory): query="Tell me about Alice's career progression", budget=Budget.MID, max_tokens=1000, - fact_type=["world"] + fact_type=["world"], + request_context=request_context, ) assert len(result.results) >= 3, f"Should recall all 3 events, got {len(result.results)}" @@ -345,11 +354,11 @@ async def test_temporal_ordering(memory): print(f"\n✓ Temporal ordering preserved: {min_date.date()} to {max_date.date()}") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) @pytest.mark.asyncio -async def test_mentioned_at_vs_occurred(memory): +async def test_mentioned_at_vs_occurred(memory, request_context): """ Test distinction between when fact occurred vs when it was mentioned. @@ -369,7 +378,8 @@ async def test_mentioned_at_vs_occurred(memory): bank_id=bank_id, content="Alice graduated from MIT in March 2020.", context="education history", - event_date=conversation_date # When this conversation happened + event_date=conversation_date, # When this conversation happened + request_context=request_context, ) assert len(unit_ids) > 0, "Should create memory unit" @@ -380,7 +390,8 @@ async def test_mentioned_at_vs_occurred(memory): query="Where did Alice go to school?", budget=Budget.LOW, max_tokens=500, - fact_type=["world"] + fact_type=["world"], + request_context=request_context, ) assert len(result.results) > 0, "Should recall the fact" @@ -415,11 +426,11 @@ async def test_mentioned_at_vs_occurred(memory): print(f"✓ Test passed: Historical conversation correctly ingested with event_date=2020") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) @pytest.mark.asyncio -async def test_occurred_dates_not_defaulted(memory): +async def test_occurred_dates_not_defaulted(memory, request_context): """ Test that occurred_start and occurred_end are NOT defaulted to mentioned_at. @@ -441,7 +452,8 @@ async def test_occurred_dates_not_defaulted(memory): bank_id=bank_id, content="Alice likes coffee. The weather is sunny today.", context="current observations", - event_date=event_date + event_date=event_date, + request_context=request_context, ) assert len(unit_ids) > 0, "Should create memory unit" @@ -452,7 +464,8 @@ async def test_occurred_dates_not_defaulted(memory): query="What does Alice like?", budget=Budget.LOW, max_tokens=500, - fact_type=["world", "opinion"] + fact_type=["world", "opinion"], + request_context=request_context, ) assert len(result.results) > 0, "Should recall the fact" @@ -504,11 +517,11 @@ async def test_occurred_dates_not_defaulted(memory): print(f"✓ Test passed: occurred dates are not incorrectly defaulted to mentioned_at") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) @pytest.mark.asyncio -async def test_mentioned_at_from_context_string(memory): +async def test_mentioned_at_from_context_string(memory, request_context): """ Test that mentioned_at is extracted from context string by LLM. @@ -527,7 +540,8 @@ async def test_mentioned_at_from_context_string(memory): bank_id=bank_id, content="Alice mentioned she loves hiking in the mountains.", context=f"Session ABC123 - you are the assistant in this conversation - happened on {session_date.strftime('%Y-%m-%d %H:%M:%S')} UTC.", - event_date=None # Not providing event_date - should default to now() if LLM doesn't extract + event_date=None, # Not providing event_date - should default to now() if LLM doesn't extract + request_context=request_context, ) assert len(unit_ids) > 0, "Should create memory unit" @@ -538,7 +552,8 @@ async def test_mentioned_at_from_context_string(memory): query="What does Alice like?", budget=Budget.LOW, max_tokens=500, - fact_type=["world"] + fact_type=["world"], + request_context=request_context, ) assert len(result.results) > 0, "Should recall the fact" @@ -574,7 +589,7 @@ async def test_mentioned_at_from_context_string(memory): print(f"✓ mentioned_at is always set (never None)") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) # ============================================================ @@ -582,7 +597,7 @@ async def test_mentioned_at_from_context_string(memory): # ============================================================ @pytest.mark.asyncio -async def test_context_preservation(memory): +async def test_context_preservation(memory, request_context): """ Test that context is preserved and retrievable. Context helps understand why/how memory was formed. @@ -597,7 +612,8 @@ async def test_context_preservation(memory): bank_id=bank_id, content="The team decided to prioritize mobile development for next quarter.", context=specific_context, - event_date=datetime(2024, 1, 15, tzinfo=timezone.utc) + event_date=datetime(2024, 1, 15, tzinfo=timezone.utc), + request_context=request_context, ) assert len(unit_ids) > 0, "Should create at least one memory unit" @@ -608,7 +624,8 @@ async def test_context_preservation(memory): query="What did the team decide?", budget=Budget.LOW, max_tokens=500, - fact_type=["world"] + fact_type=["world"], + request_context=request_context, ) assert len(result.results) > 0, "Should recall the stored fact" @@ -620,11 +637,11 @@ async def test_context_preservation(memory): print(f" Retrieved {len(result.results)} facts") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) @pytest.mark.asyncio -async def test_context_with_batch(memory): +async def test_context_with_batch(memory, request_context): """ Test that each item in a batch can have different contexts. """ @@ -650,7 +667,8 @@ async def test_context_with_batch(memory): "context": "incident response", "event_date": datetime(2024, 1, 12, tzinfo=timezone.utc) } - ] + ], + request_context=request_context, ) # Should have created facts from all items @@ -661,7 +679,7 @@ async def test_context_with_batch(memory): print(f" Created {total_units} total memory units") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) # ============================================================ @@ -669,7 +687,7 @@ async def test_context_with_batch(memory): # ============================================================ @pytest.mark.asyncio -async def test_metadata_storage_and_retrieval(memory): +async def test_metadata_storage_and_retrieval(memory, request_context): """ Test that user-defined metadata is preserved. Metadata allows arbitrary key-value data to be stored with facts. @@ -692,7 +710,8 @@ async def test_metadata_storage_and_retrieval(memory): bank_id=bank_id, content="The product launch is scheduled for March 1st.", context="planning meeting", - event_date=datetime(2024, 1, 15, tzinfo=timezone.utc) + event_date=datetime(2024, 1, 15, tzinfo=timezone.utc), + request_context=request_context, ) assert len(unit_ids) > 0, "Should create memory units" @@ -703,7 +722,8 @@ async def test_metadata_storage_and_retrieval(memory): query="When is the product launch?", budget=Budget.LOW, max_tokens=500, - fact_type=["world"] + fact_type=["world"], + request_context=request_context, ) assert len(result.results) > 0, "Should recall stored facts" @@ -712,7 +732,7 @@ async def test_metadata_storage_and_retrieval(memory): print(f" (Note: Metadata support depends on API implementation)") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) # ============================================================ @@ -720,7 +740,7 @@ async def test_metadata_storage_and_retrieval(memory): # ============================================================ @pytest.mark.asyncio -async def test_empty_batch(memory): +async def test_empty_batch(memory, request_context): """ Test that empty batch is handled gracefully without errors. """ @@ -730,7 +750,8 @@ async def test_empty_batch(memory): # Attempt to store empty batch unit_ids = await memory.retain_batch_async( bank_id=bank_id, - contents=[] + contents=[], + request_context=request_context, ) # Should return empty list or handle gracefully @@ -741,11 +762,11 @@ async def test_empty_batch(memory): finally: # Clean up (though nothing should be stored) - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) @pytest.mark.asyncio -async def test_single_item_batch(memory): +async def test_single_item_batch(memory, request_context): """ Test that batch with one item works correctly. """ @@ -761,7 +782,8 @@ async def test_single_item_batch(memory): "context": "deployment log", "event_date": datetime(2024, 1, 15, tzinfo=timezone.utc) } - ] + ], + request_context=request_context, ) assert len(unit_ids) == 1, "Should return one list of unit IDs" @@ -770,11 +792,11 @@ async def test_single_item_batch(memory): print(f"✓ Single-item batch created {len(unit_ids[0])} units") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) @pytest.mark.asyncio -async def test_mixed_content_batch(memory): +async def test_mixed_content_batch(memory, request_context): """ Test batch with varying content sizes (short and long). """ @@ -798,7 +820,8 @@ async def test_mixed_content_batch(memory): {"content": short_content, "context": "onboarding"}, {"content": long_content, "context": "performance review"}, {"content": "Charlie is on vacation this week.", "context": "team status"} - ] + ], + request_context=request_context, ) # All items should be processed @@ -813,11 +836,11 @@ async def test_mixed_content_batch(memory): print(f" Long content: {long_units} units") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) @pytest.mark.asyncio -async def test_batch_with_missing_optional_fields(memory): +async def test_batch_with_missing_optional_fields(memory, request_context): """ Test that batch handles items with missing optional fields. """ @@ -842,7 +865,8 @@ async def test_batch_with_missing_optional_fields(memory): "context": "code review", # No event_date } - ] + ], + request_context=request_context, ) # All items should be processed successfully @@ -852,7 +876,7 @@ async def test_batch_with_missing_optional_fields(memory): print(f"✓ Batch with mixed optional fields created {total_units} total units") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) # ============================================================ @@ -860,7 +884,7 @@ async def test_batch_with_missing_optional_fields(memory): # ============================================================ @pytest.mark.asyncio -async def test_single_batch_multiple_documents(memory): +async def test_single_batch_multiple_documents(memory, request_context): """ Test storing multiple distinct documents in a single batch call. Each should be tracked separately. @@ -876,21 +900,24 @@ async def test_single_batch_multiple_documents(memory): bank_id=bank_id, content="Alice's resume: 10 years Python experience, worked at Google.", context="resume review", - document_id="resume_alice" + document_id="resume_alice", + request_context=request_context, ) doc2_units = await memory.retain_async( bank_id=bank_id, content="Bob's resume: 5 years JavaScript experience, worked at Meta.", context="resume review", - document_id="resume_bob" + document_id="resume_bob", + request_context=request_context, ) doc3_units = await memory.retain_async( bank_id=bank_id, content="Charlie's resume: 8 years Go experience, worked at Amazon.", context="resume review", - document_id="resume_charlie" + document_id="resume_charlie", + request_context=request_context, ) # All documents should be stored @@ -907,17 +934,18 @@ async def test_single_batch_multiple_documents(memory): query="Who worked at Google?", budget=Budget.MID, max_tokens=1000, - fact_type=["world"] + fact_type=["world"], + request_context=request_context, ) assert len(result.results) > 0, "Should find facts about Alice" finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) @pytest.mark.asyncio -async def test_document_upsert_behavior(memory): +async def test_document_upsert_behavior(memory, request_context): """ Test that upserting a document replaces the old content. """ @@ -930,7 +958,8 @@ async def test_document_upsert_behavior(memory): bank_id=bank_id, content="Project is in planning phase. Alice is the lead.", context="status update v1", - document_id=document_id + document_id=document_id, + request_context=request_context, ) assert len(v1_units) > 0, "Should create units for v1" @@ -940,7 +969,8 @@ async def test_document_upsert_behavior(memory): bank_id=bank_id, content="Project is in development phase. Bob has joined as co-lead.", context="status update v2", - document_id=document_id + document_id=document_id, + request_context=request_context, ) assert len(v2_units) > 0, "Should create units for v2" @@ -951,7 +981,8 @@ async def test_document_upsert_behavior(memory): query="What is the project status?", budget=Budget.MID, max_tokens=1000, - fact_type=["world"] + fact_type=["world"], + request_context=request_context, ) assert len(result.results) > 0, "Should recall facts" @@ -959,7 +990,7 @@ async def test_document_upsert_behavior(memory): print(f"✓ Document upsert created v1: {len(v1_units)} units, v2: {len(v2_units)} units") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) # ============================================================ @@ -967,7 +998,7 @@ async def test_document_upsert_behavior(memory): # ============================================================ @pytest.mark.asyncio -async def test_chunk_fact_mapping(memory): +async def test_chunk_fact_mapping(memory, request_context): """ Test that facts correctly reference their source chunks via chunk_id. """ @@ -990,7 +1021,8 @@ async def test_chunk_fact_mapping(memory): bank_id=bank_id, content=content, context="technical documentation", - document_id=document_id + document_id=document_id, + request_context=request_context, ) assert len(unit_ids) > 0, "Should create memory units" @@ -1003,7 +1035,8 @@ async def test_chunk_fact_mapping(memory): max_tokens=1000, fact_type=["world"], include_chunks=True, - max_chunk_tokens=8192 + max_chunk_tokens=8192, + request_context=request_context, ) assert len(result.results) > 0, "Should recall facts" @@ -1026,11 +1059,11 @@ async def test_chunk_fact_mapping(memory): print(f" Returned {len(result.chunks)} chunks matching fact references") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) @pytest.mark.asyncio -async def test_chunk_ordering_preservation(memory): +async def test_chunk_ordering_preservation(memory, request_context): """ Test that chunk_index reflects the correct order within a document. """ @@ -1070,7 +1103,8 @@ async def test_chunk_ordering_preservation(memory): bank_id=bank_id, content=content, context="multi-section document", - document_id=document_id + document_id=document_id, + request_context=request_context, ) assert len(unit_ids) > 0, "Should create units" @@ -1083,7 +1117,8 @@ async def test_chunk_ordering_preservation(memory): max_tokens=2000, fact_type=["world"], include_chunks=True, - max_chunk_tokens=8192 + max_chunk_tokens=8192, + request_context=request_context, ) if result.chunks: @@ -1103,11 +1138,11 @@ async def test_chunk_ordering_preservation(memory): print("✓ Content stored (may have created single chunk or no chunks returned)") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) @pytest.mark.asyncio -async def test_chunks_truncation_behavior(memory): +async def test_chunks_truncation_behavior(memory, request_context): """ Test that when chunks exceed max_chunk_tokens, truncation is indicated. """ @@ -1165,7 +1200,8 @@ async def test_chunks_truncation_behavior(memory): bank_id=bank_id, content=large_content, context="large document test", - document_id=document_id + document_id=document_id, + request_context=request_context, ) assert len(unit_ids) > 0, "Should create units" @@ -1178,7 +1214,8 @@ async def test_chunks_truncation_behavior(memory): max_tokens=1000, fact_type=["world"], include_chunks=True, - max_chunk_tokens=500 # Small limit to test truncation + max_chunk_tokens=500, # Small limit to test truncation + request_context=request_context, ) if result.chunks: @@ -1198,7 +1235,7 @@ async def test_chunks_truncation_behavior(memory): print("✓ No chunks returned (may be under token limit)") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) # ============================================================ @@ -1206,7 +1243,7 @@ async def test_chunks_truncation_behavior(memory): # ============================================================ @pytest.mark.asyncio -async def test_temporal_links_creation(memory): +async def test_temporal_links_creation(memory, request_context): """ Test that temporal links are created between facts with nearby event dates. @@ -1223,7 +1260,8 @@ async def test_temporal_links_creation(memory): bank_id=bank_id, content="Alice started working on the authentication module.", context="daily standup", - event_date=base_date + event_date=base_date, + request_context=request_context, ) # Fact 2 at 2:00 PM same day (4 hours later) @@ -1231,7 +1269,8 @@ async def test_temporal_links_creation(memory): bank_id=bank_id, content="Bob reviewed the API design document.", context="daily standup", - event_date=base_date.replace(hour=14) + event_date=base_date.replace(hour=14), + request_context=request_context, ) # Fact 3 at 9:00 AM next day (23 hours later) @@ -1239,7 +1278,8 @@ async def test_temporal_links_creation(memory): bank_id=bank_id, content="Charlie deployed the new database schema.", context="daily standup", - event_date=base_date.replace(day=16, hour=9) + event_date=base_date.replace(day=16, hour=9), + request_context=request_context, ) assert len(unit_ids_1) > 0 and len(unit_ids_2) > 0 and len(unit_ids_3) > 0 @@ -1278,11 +1318,11 @@ async def test_temporal_links_creation(memory): logger.info("Temporal links created successfully with proper weights") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) @pytest.mark.asyncio -async def test_semantic_links_creation(memory): +async def test_semantic_links_creation(memory, request_context): """ Test that semantic links are created between facts with similar content. @@ -1295,21 +1335,24 @@ async def test_semantic_links_creation(memory): unit_ids_1 = await memory.retain_async( bank_id=bank_id, content="Alice is an expert in Python programming and has built many web applications.", - context="team skills" + context="team skills", + request_context=request_context, ) # Similar content - should create semantic link unit_ids_2 = await memory.retain_async( bank_id=bank_id, content="Bob is proficient in Python development and specializes in building APIs.", - context="team skills" + context="team skills", + request_context=request_context, ) # Different content - less likely to create strong semantic link unit_ids_3 = await memory.retain_async( bank_id=bank_id, content="The quarterly sales meeting is scheduled for next Tuesday at 3 PM.", - context="calendar events" + context="calendar events", + request_context=request_context, ) assert len(unit_ids_1) > 0 and len(unit_ids_2) > 0 and len(unit_ids_3) > 0 @@ -1349,11 +1392,11 @@ async def test_semantic_links_creation(memory): logger.info("Semantic links created successfully between similar content") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) @pytest.mark.asyncio -async def test_entity_links_creation(memory): +async def test_entity_links_creation(memory, request_context): """ Test that entity links are created between facts that mention the same entities. @@ -1367,28 +1410,32 @@ async def test_entity_links_creation(memory): unit_ids_1 = await memory.retain_async( bank_id=bank_id, content="Alice joined Google as a software engineer in 2020.", - context="career history" + context="career history", + request_context=request_context, ) # Mentions same entity (Alice) - should create entity link unit_ids_2 = await memory.retain_async( bank_id=bank_id, content="Alice led the development of the new authentication system.", - context="project updates" + context="project updates", + request_context=request_context, ) # Mentions same entity (Google) - should create entity link unit_ids_3 = await memory.retain_async( bank_id=bank_id, content="Google announced new cloud services at their annual conference.", - context="tech news" + context="tech news", + request_context=request_context, ) # Different entities - no entity link expected unit_ids_4 = await memory.retain_async( bank_id=bank_id, content="Bob works at Meta on machine learning infrastructure.", - context="career history" + context="career history", + request_context=request_context, ) assert len(unit_ids_1) > 0 and len(unit_ids_2) > 0 and len(unit_ids_3) > 0 and len(unit_ids_4) > 0 @@ -1445,11 +1492,11 @@ async def test_entity_links_creation(memory): logger.info("Entity links are properly bidirectional") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) @pytest.mark.asyncio -async def test_causal_links_creation(memory): +async def test_causal_links_creation(memory, request_context): """ Test that causal links are created between facts with causal relationships. @@ -1471,7 +1518,8 @@ async def test_causal_links_creation(memory): unit_ids = await memory.retain_async( bank_id=bank_id, content=content, - context="project timeline" + context="project timeline", + request_context=request_context, ) assert len(unit_ids) > 0, "Should have created facts" @@ -1517,11 +1565,11 @@ async def test_causal_links_creation(memory): logger.info("Test completed (causal link extraction is LLM-dependent)") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) @pytest.mark.asyncio -async def test_all_link_types_together(memory): +async def test_all_link_types_together(memory, request_context): """ Integration test: Verify all link types can be created in a single retain operation. @@ -1539,7 +1587,8 @@ async def test_all_link_types_together(memory): bank_id=bank_id, content="Alice completed the Python backend service for the authentication system.", context="sprint review", - event_date=base_date + event_date=base_date, + request_context=request_context, ) # Fact 2: Related to Alice, similar topic (Python), close in time @@ -1547,7 +1596,8 @@ async def test_all_link_types_together(memory): bank_id=bank_id, content="Alice optimized the Python code and improved the authentication performance by 40%.", context="sprint review", - event_date=base_date.replace(hour=14) # Same day, 4 hours later + event_date=base_date.replace(hour=14), # Same day, 4 hours later + request_context=request_context, ) # Fact 3: Related to Alice, different topic but same entity @@ -1555,7 +1605,8 @@ async def test_all_link_types_together(memory): bank_id=bank_id, content="Alice presented the security architecture at the team meeting.", context="team meeting", - event_date=base_date.replace(day=16) # Next day + event_date=base_date.replace(day=16), # Next day + request_context=request_context, ) assert len(unit_ids_1) > 0 and len(unit_ids_2) > 0 and len(unit_ids_3) > 0 @@ -1594,11 +1645,11 @@ async def test_all_link_types_together(memory): logger.info("All major link types (temporal, semantic, entity) are working correctly") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) @pytest.mark.asyncio -async def test_semantic_links_within_same_batch(memory): +async def test_semantic_links_within_same_batch(memory, request_context): """ Test that semantic links are created between facts retained in the SAME batch. @@ -1617,7 +1668,8 @@ async def test_semantic_links_within_same_batch(memory): result = await memory.retain_batch_async( bank_id=bank_id, - contents=contents + contents=contents, + request_context=request_context, ) # Flatten the list of lists @@ -1652,11 +1704,11 @@ async def test_semantic_links_within_same_batch(memory): logger.info(f" Semantic link: {str(link['from_unit_id'])[:8]}... -> {str(link['to_unit_id'])[:8]}... (weight: {link['weight']:.3f})") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) @pytest.mark.asyncio -async def test_temporal_links_within_same_batch(memory): +async def test_temporal_links_within_same_batch(memory, request_context): """ Test that temporal links are created between facts retained in the SAME batch. @@ -1689,7 +1741,8 @@ async def test_temporal_links_within_same_batch(memory): result = await memory.retain_batch_async( bank_id=bank_id, - contents=contents + contents=contents, + request_context=request_context, ) # Flatten the list of lists @@ -1724,4 +1777,4 @@ async def test_temporal_links_within_same_batch(memory): logger.info(f" Temporal link: {str(link['from_unit_id'])[:8]}... -> {str(link['to_unit_id'])[:8]}... (weight: {link['weight']:.3f})") finally: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) diff --git a/hindsight-api/tests/test_schema_isolation.py b/hindsight-api/tests/test_schema_isolation.py new file mode 100644 index 00000000..cf7e767c --- /dev/null +++ b/hindsight-api/tests/test_schema_isolation.py @@ -0,0 +1,406 @@ +""" +Tests for multi-tenant schema isolation. + +Verifies that concurrent retain operations from different tenants +are properly isolated in their respective PostgreSQL schemas. +""" + +import asyncio +import uuid + +import pytest +import pytest_asyncio + +from hindsight_api.extensions import RequestContext, TenantContext, TenantExtension +from hindsight_api.engine.memory_engine import _current_schema, fq_table +from hindsight_api.migrations import run_migrations + + +class MultiSchemaTestTenantExtension(TenantExtension): + """ + Test tenant extension that maps API keys to schema names. + + API keys are in format: "key-{schema_name}" + Provisions schemas on first access using run_migrations(schema=name). + """ + + def __init__(self, config: dict): + super().__init__(config) + self.db_url = config.get("db_url") + # Pre-configured valid schemas for test + self.valid_schemas = config.get("valid_schemas", set()) + # Track provisioned schemas + self._provisioned: set[str] = set() + + async def authenticate(self, context: RequestContext) -> TenantContext: + if not context.api_key: + from hindsight_api.extensions import AuthenticationError + + raise AuthenticationError("API key required") + + # Parse schema from API key (format: "key-{schema}") + if context.api_key.startswith("key-"): + schema = context.api_key[4:] # Remove "key-" prefix + if schema in self.valid_schemas: + # Provision schema on first access + if schema not in self._provisioned and self.db_url: + run_migrations(self.db_url, schema=schema) + self._provisioned.add(schema) + return TenantContext(schema_name=schema) + + from hindsight_api.extensions import AuthenticationError + + raise AuthenticationError(f"Unknown API key: {context.api_key}") + + +async def drop_schema(conn, schema_name: str) -> None: + """Drop a schema and all its contents.""" + await conn.execute(f'DROP SCHEMA IF EXISTS "{schema_name}" CASCADE') + + +async def count_memories_in_schema(conn, schema_name: str, bank_id: str) -> int: + """Count memory units in a specific schema for a bank.""" + result = await conn.fetchval( + f'SELECT COUNT(*) FROM "{schema_name}".memory_units WHERE bank_id = $1', + bank_id, + ) + return result or 0 + + +async def get_memory_texts_in_schema(conn, schema_name: str, bank_id: str) -> list[str]: + """Get all memory texts in a specific schema for a bank.""" + rows = await conn.fetch( + f'SELECT text FROM "{schema_name}".memory_units WHERE bank_id = $1 ORDER BY text', + bank_id, + ) + return [row["text"] for row in rows] + + +class TestSchemaIsolation: + """Tests for multi-tenant schema isolation.""" + + @pytest.mark.asyncio + async def test_concurrent_inserts_isolated_by_schema(self, memory, pg0_db_url): + """ + Multiple concurrent database operations from different tenants + should store data in their respective schemas without cross-contamination. + + Uses run_migrations(schema=x) to provision schemas like a real extension. + """ + import asyncpg + + # Test schemas + schemas = ["tenant_alpha", "tenant_beta", "tenant_gamma"] + bank_id = f"test-isolation-{uuid.uuid4().hex[:8]}" + + # Clean up any existing schemas + conn = await asyncpg.connect(pg0_db_url) + try: + for schema in schemas: + await drop_schema(conn, schema) + finally: + await conn.close() + + # Configure tenant extension that provisions schemas via run_migrations + tenant_ext = MultiSchemaTestTenantExtension({ + "db_url": pg0_db_url, + "valid_schemas": set(schemas), + }) + memory._tenant_extension = tenant_ext + + # Define concurrent insert tasks for each tenant + async def insert_for_tenant(schema_name: str, content_prefix: str): + """Insert memories for a specific tenant using schema context.""" + # Authenticate to set the schema context + tenant_request = RequestContext(api_key=f"key-{schema_name}") + await memory._authenticate_tenant(tenant_request) + + # Now fq_table will use the correct schema + pool = await memory._get_pool() + from hindsight_api.engine.db_utils import acquire_with_retry + + async with acquire_with_retry(pool) as conn: + # Insert 3 memories for this tenant + for i in range(3): + await conn.execute( + f""" + INSERT INTO {fq_table('memory_units')} (bank_id, text, event_date, fact_type) + VALUES ($1, $2, now(), 'world') + """, + bank_id, + f"MARKER_{content_prefix}_DOC{i}: Memory for {schema_name}", + ) + + # Run concurrent inserts for all tenants + await asyncio.gather( + insert_for_tenant("tenant_alpha", "ALPHA"), + insert_for_tenant("tenant_beta", "BETA"), + insert_for_tenant("tenant_gamma", "GAMMA"), + ) + + # Verify isolation - each schema should only have its own data + conn = await asyncpg.connect(pg0_db_url) + try: + for schema in schemas: + texts = await get_memory_texts_in_schema(conn, schema, bank_id) + prefix = schema.replace("tenant_", "").upper() + + # Should have exactly 3 memories + assert len(texts) == 3, f"Schema {schema} should have 3 memories, got {len(texts)}" + + # All texts should contain the schema's marker + for text in texts: + assert f"MARKER_{prefix}" in text, ( + f"Memory in {schema} missing its marker: {text}" + ) + + # Should NOT contain other tenants' markers + other_prefixes = ["ALPHA", "BETA", "GAMMA"] + other_prefixes.remove(prefix) + for other in other_prefixes: + for text in texts: + assert f"MARKER_{other}" not in text, ( + f"Cross-contamination! Schema {schema} has {other}'s marker: {text}" + ) + + finally: + # Cleanup + for schema in schemas: + await drop_schema(conn, schema) + await conn.close() + + # Reset tenant extension + memory._tenant_extension = None + _current_schema.set("public") + + @pytest.mark.asyncio + async def test_schema_context_isolation_in_concurrent_tasks(self, pg0_db_url): + """ + Verify that _current_schema contextvar is properly isolated + between concurrent async tasks. + """ + results = {} + errors = [] + + async def check_schema_context(schema_name: str, delay: float): + """Set schema context, wait, then verify it's still correct.""" + try: + # Set the schema + _current_schema.set(schema_name) + + # Small delay to allow interleaving + await asyncio.sleep(delay) + + # Verify schema is still correct + current = _current_schema.get() + if current != schema_name: + errors.append(f"Expected {schema_name}, got {current}") + + # Verify fq_table uses correct schema + table = fq_table("memory_units") + expected = f"{schema_name}.memory_units" + if table != expected: + errors.append(f"Expected {expected}, got {table}") + + results[schema_name] = current + + except Exception as e: + errors.append(f"Error in {schema_name}: {e}") + + # Run many concurrent tasks with different schemas + tasks = [] + for i in range(10): + for schema in ["schema_a", "schema_b", "schema_c"]: + # Vary delays to create interleaving + delay = 0.01 * (i % 3) + tasks.append(check_schema_context(f"{schema}_{i}", delay)) + + await asyncio.gather(*tasks) + + # No errors should have occurred + assert not errors, f"Schema context isolation errors: {errors}" + + @pytest.mark.asyncio + async def test_list_memories_respects_schema(self, memory, pg0_db_url): + """ + list_memory_units should only return memories from the current schema. + + Uses run_migrations(schema=x) to provision schemas. + """ + import asyncpg + + schemas = ["tenant_list_a", "tenant_list_b"] + bank_id = f"test-list-{uuid.uuid4().hex[:8]}" + + # Clean up any existing schemas and provision via migrations + conn = await asyncpg.connect(pg0_db_url) + try: + for schema in schemas: + await drop_schema(conn, schema) + finally: + await conn.close() + + # Provision schemas using run_migrations + for schema in schemas: + run_migrations(pg0_db_url, schema=schema) + + # Insert test data directly into each schema + conn = await asyncpg.connect(pg0_db_url) + try: + for schema in schemas: + await conn.execute( + f""" + INSERT INTO "{schema}".memory_units (bank_id, text, event_date, fact_type) + VALUES ($1, $2, now(), 'world') + """, + bank_id, + f"Direct insert for {schema}", + ) + finally: + await conn.close() + + # Configure tenant extension + tenant_ext = MultiSchemaTestTenantExtension({ + "db_url": pg0_db_url, + "valid_schemas": set(schemas), + }) + memory._tenant_extension = tenant_ext + + try: + # Query as tenant_list_a - should only see tenant_list_a's data + tenant_a_request = RequestContext(api_key="key-tenant_list_a") + await memory._authenticate_tenant(tenant_a_request) + + result_a = await memory.list_memory_units(bank_id=bank_id, request_context=tenant_a_request) + texts_a = [item["text"] for item in result_a.get("items", [])] + + assert len(texts_a) == 1, f"Expected 1 memory for tenant_list_a, got {len(texts_a)}" + assert "tenant_list_a" in texts_a[0], f"Wrong content: {texts_a[0]}" + + # Query as tenant_list_b - should only see tenant_list_b's data + tenant_b_request = RequestContext(api_key="key-tenant_list_b") + await memory._authenticate_tenant(tenant_b_request) + + result_b = await memory.list_memory_units(bank_id=bank_id, request_context=tenant_b_request) + texts_b = [item["text"] for item in result_b.get("items", [])] + + assert len(texts_b) == 1, f"Expected 1 memory for tenant_list_b, got {len(texts_b)}" + assert "tenant_list_b" in texts_b[0], f"Wrong content: {texts_b[0]}" + + finally: + # Cleanup + conn = await asyncpg.connect(pg0_db_url) + try: + for schema in schemas: + await drop_schema(conn, schema) + finally: + await conn.close() + + memory._tenant_extension = None + _current_schema.set("public") + + @pytest.mark.asyncio + async def test_high_concurrency_schema_isolation(self, memory, pg0_db_url): + """ + Stress test: Many concurrent operations across multiple schemas + should maintain perfect isolation. + + Uses run_migrations(schema=x) to provision schemas like a real extension. + """ + import asyncpg + + # Create more schemas for stress test + num_schemas = 5 + ops_per_schema = 10 + schemas = [f"stress_tenant_{i}" for i in range(num_schemas)] + bank_id = f"test-stress-{uuid.uuid4().hex[:8]}" + + # Clean up any existing schemas first + conn = await asyncpg.connect(pg0_db_url) + try: + for schema in schemas: + await drop_schema(conn, schema) + finally: + await conn.close() + + # Provision schemas using run_migrations + for schema in schemas: + run_migrations(pg0_db_url, schema=schema) + + # Configure tenant extension (schemas already provisioned) + tenant_ext = MultiSchemaTestTenantExtension({ + "db_url": pg0_db_url, + "valid_schemas": set(schemas), + }) + # Mark schemas as already provisioned so extension doesn't re-run migrations + tenant_ext._provisioned = set(schemas) + memory._tenant_extension = tenant_ext + + errors = [] + + async def insert_one(schema: str, item_id: int): + """Single insert operation for tracking.""" + try: + # Authenticate to set the schema context + tenant_request = RequestContext(api_key=f"key-{schema}") + await memory._authenticate_tenant(tenant_request) + + # Insert using fq_table + pool = await memory._get_pool() + from hindsight_api.engine.db_utils import acquire_with_retry + + async with acquire_with_retry(pool) as conn: + await conn.execute( + f""" + INSERT INTO {fq_table('memory_units')} (bank_id, text, event_date, fact_type) + VALUES ($1, $2, now(), 'world') + """, + bank_id, + f"STRESS_MARKER_{schema}_ITEM{item_id}: Memory for {schema}", + ) + except Exception as e: + errors.append(f"Insert error for {schema}: {e}") + + # Run many concurrent operations + tasks = [] + for i in range(ops_per_schema): + for schema in schemas: + tasks.append(insert_one(schema, i)) + + await asyncio.gather(*tasks) + + # Check for errors during insert + assert not errors, f"Errors during insert: {errors}" + + # Verify no cross-contamination + conn = await asyncpg.connect(pg0_db_url) + try: + for schema in schemas: + texts = await get_memory_texts_in_schema(conn, schema, bank_id) + + # Should have exactly ops_per_schema memories + assert len(texts) == ops_per_schema, ( + f"Schema {schema} should have {ops_per_schema} memories, got {len(texts)}" + ) + + # All memories should reference this schema only + for text in texts: + # Check it contains our schema marker + assert f"STRESS_MARKER_{schema}" in text, ( + f"Memory in {schema} doesn't contain schema marker: {text}" + ) + + # Check it doesn't contain other schema markers + for other_schema in schemas: + if other_schema != schema: + assert f"STRESS_MARKER_{other_schema}" not in text, ( + f"Cross-contamination! {schema} has {other_schema}'s data: {text}" + ) + finally: + # Cleanup + for schema in schemas: + await drop_schema(conn, schema) + await conn.close() + + memory._tenant_extension = None + _current_schema.set("public") diff --git a/hindsight-api/tests/test_search_trace.py b/hindsight-api/tests/test_search_trace.py index 78dfca24..8fc4adbe 100644 --- a/hindsight-api/tests/test_search_trace.py +++ b/hindsight-api/tests/test_search_trace.py @@ -3,12 +3,12 @@ Test search tracing functionality. """ import pytest from hindsight_api.engine.memory_engine import Budget -from hindsight_api import SearchTrace +from hindsight_api import SearchTrace, RequestContext from datetime import datetime, timezone @pytest.mark.asyncio -async def test_search_with_trace(memory): +async def test_search_with_trace(memory, request_context): """Test that search with enable_trace=True returns a valid SearchTrace.""" # Generate a unique agent ID for this test bank_id = f"test_trace_{datetime.now(timezone.utc).timestamp()}" @@ -20,16 +20,19 @@ async def test_search_with_trace(memory): bank_id=bank_id, content="Alice works at Google in Mountain View", context="test context", + request_context=request_context, ) await memory.retain_async( bank_id=bank_id, content="Bob also works at Google but in New York", context="test context", + request_context=request_context, ) await memory.retain_async( bank_id=bank_id, content="Charlie founded a startup called TechCorp", context="test context", + request_context=request_context, ) # Search with tracing enabled @@ -40,6 +43,7 @@ async def test_search_with_trace(memory): budget=Budget.LOW, # 20, max_tokens=512, enable_trace=True, + request_context=request_context, ) # Verify results @@ -102,11 +106,11 @@ async def test_search_with_trace(memory): finally: # Cleanup - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) @pytest.mark.asyncio -async def test_search_without_trace(memory): +async def test_search_without_trace(memory, request_context): """Test that search with enable_trace=False returns None for trace.""" bank_id = f"test_no_trace_{datetime.now(timezone.utc).timestamp()}" @@ -117,6 +121,7 @@ async def test_search_without_trace(memory): bank_id=bank_id, content="Test memory without trace", context="test", + request_context=request_context, ) # Search without tracing @@ -127,6 +132,7 @@ async def test_search_without_trace(memory): budget=Budget.LOW, # 10, max_tokens=512, enable_trace=False, + request_context=request_context, ) # Verify trace is None @@ -137,4 +143,4 @@ async def test_search_without_trace(memory): finally: # Cleanup - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) diff --git a/hindsight-api/tests/test_sql_schema_safety.py b/hindsight-api/tests/test_sql_schema_safety.py new file mode 100644 index 00000000..b7ddd436 --- /dev/null +++ b/hindsight-api/tests/test_sql_schema_safety.py @@ -0,0 +1,136 @@ +""" +Safety tests to ensure all SQL queries use fully-qualified table names. + +This prevents cross-tenant data access by ensuring every table reference +includes the schema prefix (e.g., public.memory_units instead of just memory_units). +""" + +import re +from pathlib import Path + +import pytest + +# All tables that MUST be schema-qualified in SQL queries +TABLES = [ + "memory_units", + "memory_links", + "unit_entities", + "entities", + "entity_cooccurrences", + "banks", + "documents", + "chunks", + "async_operations", +] + +# Files to scan for SQL queries +SCAN_PATHS = [ + "hindsight_api/engine", + "hindsight_api/api", +] + +# Files to exclude (e.g., migrations, tests) +EXCLUDE_PATTERNS = [ + "alembic", + "__pycache__", + "test_", +] + + +def get_python_files() -> list[Path]: + """Get all Python files to scan.""" + root = Path(__file__).parent.parent + files = [] + for scan_path in SCAN_PATHS: + path = root / scan_path + if path.exists(): + for py_file in path.rglob("*.py"): + # Check exclusions + if any(excl in str(py_file) for excl in EXCLUDE_PATTERNS): + continue + files.append(py_file) + return files + + +def find_unqualified_table_refs(content: str, filename: str) -> list[tuple[int, str, str]]: + """ + Find SQL statements with unqualified table references. + + Returns list of (line_number, table_name, line_content). + """ + violations = [] + + # Patterns that indicate SQL context + sql_keywords = r"(?:FROM|JOIN|INTO|UPDATE|DELETE\s+FROM)\s+" + + # Additional SQL indicators to confirm this is actually SQL, not prose + sql_indicators = re.compile( + r"(SELECT|INSERT|DELETE|UPDATE|CREATE|ALTER|DROP|WHERE|SET|VALUES|" + r'f"""|f\'\'\'|""".*SELECT|\'\'\'.*SELECT)', + re.IGNORECASE, + ) + + lines = content.split("\n") + for line_num, line in enumerate(lines, 1): + # Skip comments and strings that are clearly not SQL + stripped = line.strip() + if stripped.startswith("#"): + continue + + for table in TABLES: + # Pattern: SQL keyword followed by unqualified table name + # Should match: FROM memory_units, JOIN memory_units, INTO memory_units + # Should NOT match: FROM public.memory_units, FROM {schema}.memory_units + # Should NOT match: fq_table("memory_units") + + # Check for unqualified table after SQL keyword + pattern = rf"{sql_keywords}{table}(?:\s|$|,|\))" + + if re.search(pattern, line, re.IGNORECASE): + # Check if it's actually qualified (has schema prefix) + qualified_pattern = rf"\.\s*{table}(?:\s|$|,|\))" + fq_table_pattern = rf'fq_table\s*\(\s*["\']?{table}' + + if not re.search(qualified_pattern, line) and not re.search( + fq_table_pattern, line + ): + # Additional check: line must have SQL indicators + # This avoids false positives in docstrings like "split into chunks" + if sql_indicators.search(line): + violations.append((line_num, table, stripped)) + + return violations + + +class TestSQLSchemaSafety: + """Ensure all SQL uses schema-qualified table names.""" + + def test_no_unqualified_table_references(self): + """All SQL queries must use fq_table() or schema.table format.""" + all_violations = [] + + for py_file in get_python_files(): + content = py_file.read_text() + violations = find_unqualified_table_refs(content, py_file.name) + + for line_num, table, line in violations: + all_violations.append( + f"{py_file.relative_to(py_file.parent.parent)}:{line_num} - " + f"unqualified '{table}': {line[:80]}..." + ) + + if all_violations: + msg = ( + f"Found {len(all_violations)} unqualified table references!\n" + "These could cause cross-tenant data access.\n" + "Use fq_table('table_name') for all table references.\n\n" + + "\n".join(all_violations[:20]) # Show first 20 + ) + if len(all_violations) > 20: + msg += f"\n... and {len(all_violations) - 20} more" + pytest.fail(msg) + + def test_tables_list_is_complete(self): + """Verify we're checking for all tables (sanity check).""" + # This is a sanity check - if you add a new table, add it to TABLES + assert len(TABLES) >= 9, "Update TABLES list if you added new tables" diff --git a/hindsight-api/tests/test_temporal_ranges.py b/hindsight-api/tests/test_temporal_ranges.py index 05c20807..168ccf62 100644 --- a/hindsight-api/tests/test_temporal_ranges.py +++ b/hindsight-api/tests/test_temporal_ranges.py @@ -3,16 +3,17 @@ import asyncio from datetime import datetime, timezone, timedelta import pytest from hindsight_api.engine.memory_engine import Budget +from hindsight_api import RequestContext @pytest.mark.asyncio -async def test_temporal_ranges_are_written(memory): +async def test_temporal_ranges_are_written(memory, request_context): """Test that occurred_start, occurred_end, and mentioned_at are actually written to database.""" bank_id = "test_temporal_ranges" # Clean up any existing data try: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) except Exception: pass @@ -23,7 +24,8 @@ async def test_temporal_ranges_are_written(memory): await memory.retain_async( bank_id=bank_id, content=text1, - event_date=conversation_date + event_date=conversation_date, + request_context=request_context, ) # Test 2: Period event (month range) @@ -32,7 +34,8 @@ async def test_temporal_ranges_are_written(memory): await memory.retain_async( bank_id=bank_id, content=text2, - event_date=conversation_date + event_date=conversation_date, + request_context=request_context, ) # Give it a moment for async processing @@ -114,7 +117,8 @@ async def test_temporal_ranges_are_written(memory): query="pottery workshop", fact_type=["world", "experience"], budget=Budget.LOW, - max_tokens=4096 + max_tokens=4096, + request_context=request_context, ) print(f"Found {len(search_result.results)} search results") @@ -132,4 +136,4 @@ async def test_temporal_ranges_are_written(memory): print("⚠ Temporal fields not yet populated in search results (known issue)") # Clean up - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) diff --git a/hindsight-api/tests/test_think.py b/hindsight-api/tests/test_think.py index 643c3888..f50b972a 100644 --- a/hindsight-api/tests/test_think.py +++ b/hindsight-api/tests/test_think.py @@ -4,10 +4,11 @@ Test think function for opinion generation and consistency. import pytest from datetime import datetime, timezone from hindsight_api.engine.memory_engine import Budget +from hindsight_api import RequestContext @pytest.mark.asyncio -async def test_think_opinion_consistency(memory): +async def test_think_opinion_consistency(memory, request_context): """ Test that think function: 1. Generates an opinion @@ -23,14 +24,16 @@ async def test_think_opinion_consistency(memory): bank_id=bank_id, content="Alice is a software engineer who has worked on 5 major projects. She always delivers on time and writes clean, well-documented code.", context="performance review", - event_date=datetime(2024, 1, 15, tzinfo=timezone.utc) + event_date=datetime(2024, 1, 15, tzinfo=timezone.utc), + request_context=request_context, ) await memory.retain_async( bank_id=bank_id, content="Bob recently joined the team. He missed his first deadline and his code had many bugs.", context="performance review", - event_date=datetime(2024, 2, 1, tzinfo=timezone.utc) + event_date=datetime(2024, 2, 1, tzinfo=timezone.utc), + request_context=request_context, ) # First think call - should generate opinions @@ -39,6 +42,7 @@ async def test_think_opinion_consistency(memory): bank_id=bank_id, query=query, budget=Budget.LOW, + request_context=request_context, ) print(f"\n=== First Think Call ===") @@ -82,6 +86,7 @@ async def test_think_opinion_consistency(memory): bank_id=bank_id, query=query, budget=Budget.LOW, + request_context=request_context, ) print(f"\n=== Second Think Call ===") @@ -122,13 +127,13 @@ async def test_think_opinion_consistency(memory): finally: # Clean up agent data try: - await memory.delete_bank(bank_id) + await memory.delete_bank(bank_id, request_context=request_context) except Exception as e: print(f"Warning: Error during cleanup: {e}") @pytest.mark.asyncio -async def test_think_without_prior_context(memory): +async def test_think_without_prior_context(memory, request_context): """ Test that think function handles queries when there's no relevant context. """ @@ -139,6 +144,7 @@ async def test_think_without_prior_context(memory): bank_id=bank_id, query="What is the capital of France?", budget=Budget.LOW, + request_context=request_context, ) print(f"\n=== Think Without Context ===") diff --git a/hindsight-cli/src/api.rs b/hindsight-cli/src/api.rs index 0aa5ed45..21753666 100644 --- a/hindsight-cli/src/api.rs +++ b/hindsight-cli/src/api.rs @@ -64,13 +64,24 @@ pub struct ApiClient { } impl ApiClient { - pub fn new(base_url: String) -> Result { + pub fn new(base_url: String, api_key: Option) -> Result { let runtime = std::sync::Arc::new(tokio::runtime::Runtime::new()?); - // Create HTTP client with 2-minute timeout - let http_client = reqwest::Client::builder() - .timeout(std::time::Duration::from_secs(120)) - .build()?; + // Create HTTP client with 2-minute timeout and optional auth header + let mut client_builder = reqwest::Client::builder() + .timeout(std::time::Duration::from_secs(120)); + + if let Some(key) = api_key { + let mut headers = reqwest::header::HeaderMap::new(); + let auth_value = format!("Bearer {}", key); + headers.insert( + reqwest::header::AUTHORIZATION, + reqwest::header::HeaderValue::from_str(&auth_value)?, + ); + client_builder = client_builder.default_headers(headers); + } + + let http_client = client_builder.build()?; let client = AsyncClient::new_with_client(&base_url, http_client); Ok(ApiClient { client, runtime }) diff --git a/hindsight-cli/src/config.rs b/hindsight-cli/src/config.rs index 0288c581..2cf4e5ae 100644 --- a/hindsight-cli/src/config.rs +++ b/hindsight-cli/src/config.rs @@ -10,6 +10,7 @@ const CONFIG_DIR_NAME: &str = ".hindsight"; pub struct Config { pub api_url: String, + pub api_key: Option, pub source: ConfigSource, } @@ -32,22 +33,27 @@ impl std::fmt::Display for ConfigSource { impl Config { /// Load configuration with the following priority: - /// 1. Environment variable (HINDSIGHT_API_URL) - highest priority, for overrides + /// 1. Environment variable (HINDSIGHT_API_URL, HINDSIGHT_API_KEY) - highest priority, for overrides /// 2. Local config file (~/.hindsight/config.toml) /// 3. Default (http://localhost:8888) pub fn load() -> Result { + // Load API key from environment (highest priority) + let env_api_key = env::var("HINDSIGHT_API_KEY").ok(); + // 1. Environment variable takes highest priority (for overrides) if let Ok(api_url) = env::var("HINDSIGHT_API_URL") { - return Self::validate_and_create(api_url, ConfigSource::Environment); + return Self::validate_and_create(api_url, env_api_key, ConfigSource::Environment); } // 2. Try local config file - if let Some(api_url) = Self::load_from_file()? { - return Self::validate_and_create(api_url, ConfigSource::LocalFile); + if let Some((api_url, file_api_key)) = Self::load_from_file()? { + // Environment api_key takes precedence over file api_key + let api_key = env_api_key.or(file_api_key); + return Self::validate_and_create(api_url, api_key, ConfigSource::LocalFile); } // 3. Fall back to default - Self::validate_and_create(DEFAULT_API_URL.to_string(), ConfigSource::Default) + Self::validate_and_create(DEFAULT_API_URL.to_string(), env_api_key, ConfigSource::Default) } /// Legacy method for backwards compatibility @@ -55,14 +61,14 @@ impl Config { Self::load() } - fn validate_and_create(api_url: String, source: ConfigSource) -> Result { + fn validate_and_create(api_url: String, api_key: Option, source: ConfigSource) -> Result { if !api_url.starts_with("http://") && !api_url.starts_with("https://") { anyhow::bail!( "Invalid API URL: {}. Must start with http:// or https://", api_url ); } - Ok(Config { api_url, source }) + Ok(Config { api_url, api_key, source }) } fn config_dir() -> Option { @@ -73,7 +79,7 @@ impl Config { Self::config_dir().map(|dir| dir.join(CONFIG_FILE_NAME)) } - fn load_from_file() -> Result> { + fn load_from_file() -> Result)>> { let config_path = match Self::config_file_path() { Some(path) => path, None => return Ok(None), @@ -86,23 +92,40 @@ impl Config { let content = fs::read_to_string(&config_path) .with_context(|| format!("Failed to read config file: {}", config_path.display()))?; - // Simple TOML parsing for api_url + let mut api_url: Option = None; + let mut api_key: Option = None; + + // Simple TOML parsing for api_url and api_key for line in content.lines() { let line = line.trim(); if line.starts_with("api_url") { if let Some(value) = line.split('=').nth(1) { let value = value.trim().trim_matches('"').trim_matches('\''); if !value.is_empty() { - return Ok(Some(value.to_string())); + api_url = Some(value.to_string()); + } + } + } else if line.starts_with("api_key") { + if let Some(value) = line.split('=').nth(1) { + let value = value.trim().trim_matches('"').trim_matches('\''); + if !value.is_empty() { + api_key = Some(value.to_string()); } } } } - Ok(None) + match api_url { + Some(url) => Ok(Some((url, api_key))), + None => Ok(None), + } } pub fn save_api_url(api_url: &str) -> Result { + Self::save_config(api_url, None) + } + + pub fn save_config(api_url: &str, api_key: Option<&str>) -> Result { let config_dir = Self::config_dir() .ok_or_else(|| anyhow::anyhow!("Could not determine home directory"))?; @@ -113,7 +136,10 @@ impl Config { } let config_path = config_dir.join(CONFIG_FILE_NAME); - let content = format!("api_url = \"{}\"\n", api_url); + let mut content = format!("api_url = \"{}\"\n", api_url); + if let Some(key) = api_key { + content.push_str(&format!("api_key = \"{}\"\n", key)); + } fs::write(&config_path, content) .with_context(|| format!("Failed to write config file: {}", config_path.display()))?; diff --git a/hindsight-cli/src/main.rs b/hindsight-cli/src/main.rs index 5b623372..1eba251a 100644 --- a/hindsight-cli/src/main.rs +++ b/hindsight-cli/src/main.rs @@ -94,12 +94,15 @@ enum Commands { /// Launch the web-based control plane UI Ui, - /// Configure the CLI (API URL, etc.) - #[command(after_help = "Configuration priority:\n 1. Environment variable (HINDSIGHT_API_URL) - highest priority\n 2. Config file (~/.hindsight/config)\n 3. Default (http://localhost:8888)")] + /// Configure the CLI (API URL, API key, etc.) + #[command(after_help = "Configuration priority:\n 1. Environment variables (HINDSIGHT_API_URL, HINDSIGHT_API_KEY) - highest priority\n 2. Config file (~/.hindsight/config)\n 3. Default (http://localhost:8888)")] Configure { /// API URL to connect to (interactive prompt if not provided) #[arg(long)] api_url: Option, + /// API key for authentication (sent as Bearer token) + #[arg(long)] + api_key: Option, }, } @@ -372,8 +375,8 @@ fn run() -> Result<()> { let verbose = cli.verbose; // Handle configure command before loading full config (it doesn't need API client) - if let Commands::Configure { api_url } = cli.command { - return handle_configure(api_url, output_format); + if let Commands::Configure { api_url, api_key } = cli.command { + return handle_configure(api_url, api_key, output_format); } // Handle ui command - needs config but not API client @@ -389,9 +392,10 @@ fn run() -> Result<()> { }); let api_url = config.api_url().to_string(); + let api_key = config.api_key.clone(); // Create API client - let client = ApiClient::new(api_url.clone()).unwrap_or_else(|e| { + let client = ApiClient::new(api_url.clone(), api_key).unwrap_or_else(|e| { errors::handle_api_error(e, &api_url); }); @@ -476,7 +480,7 @@ fn run() -> Result<()> { Ok(()) } -fn handle_configure(api_url: Option, output_format: OutputFormat) -> Result<()> { +fn handle_configure(api_url: Option, api_key: Option, output_format: OutputFormat) -> Result<()> { // Load current config to show current state let current_config = Config::load().ok(); @@ -487,6 +491,15 @@ fn handle_configure(api_url: Option, output_format: OutputFormat) -> Res // Show current configuration if let Some(ref config) = current_config { println!(" Current API URL: {}", config.api_url); + if let Some(ref key) = config.api_key { + // Mask the API key for display + let masked = if key.len() > 8 { + format!("{}...{}", &key[..4], &key[key.len()-4..]) + } else { + "****".to_string() + }; + println!(" Current API Key: {}", masked); + } println!(" Source: {}", config.source); println!(); } @@ -511,18 +524,30 @@ fn handle_configure(api_url: Option, output_format: OutputFormat) -> Res return Ok(()); } + // Use provided api_key, or keep existing one if not provided + let new_api_key = api_key.or_else(|| current_config.as_ref().and_then(|c| c.api_key.clone())); + // Save to config file - let config_path = Config::save_api_url(&new_api_url)?; + let config_path = Config::save_config(&new_api_url, new_api_key.as_deref())?; if output_format == OutputFormat::Pretty { ui::print_success(&format!("Configuration saved to {}", config_path.display())); println!(); println!(" API URL: {}", new_api_url); + if let Some(ref key) = new_api_key { + let masked = if key.len() > 8 { + format!("{}...{}", &key[..4], &key[key.len()-4..]) + } else { + "****".to_string() + }; + println!(" API Key: {}", masked); + } println!(); - println!("Note: Environment variable HINDSIGHT_API_URL will override this setting."); + println!("Note: Environment variables HINDSIGHT_API_URL and HINDSIGHT_API_KEY will override these settings."); } else { let result = serde_json::json!({ "api_url": new_api_url, + "api_key_set": new_api_key.is_some(), "config_path": config_path.display().to_string(), }); output::print_output(&result, output_format)?; diff --git a/hindsight-cli/src/utils.rs b/hindsight-cli/src/utils.rs index e8b0b428..c1b8e5a4 100644 --- a/hindsight-cli/src/utils.rs +++ b/hindsight-cli/src/utils.rs @@ -5,7 +5,7 @@ use crate::output::OutputFormat; /// Get API client from config pub fn get_client(config: &Config) -> Result { - ApiClient::new(config.api_url.clone()) + ApiClient::new(config.api_url.clone(), config.api_key.clone()) .context("Failed to create API client") } diff --git a/hindsight-clients/python/hindsight_client/hindsight_client.py b/hindsight-clients/python/hindsight_client/hindsight_client.py index 87f7c7fa..90b63afc 100644 --- a/hindsight-clients/python/hindsight_client/hindsight_client.py +++ b/hindsight-clients/python/hindsight_client/hindsight_client.py @@ -44,8 +44,12 @@ class Hindsight: ```python from hindsight_client import Hindsight + # Without authentication client = Hindsight(base_url="http://localhost:8888") + # With API key authentication + client = Hindsight(base_url="http://localhost:8888", api_key="your-api-key") + # Store a memory client.retain(bank_id="alice", content="Alice loves AI") @@ -59,15 +63,16 @@ class Hindsight: ``` """ - def __init__(self, base_url: str, timeout: float = 30.0): + def __init__(self, base_url: str, api_key: Optional[str] = None, timeout: float = 30.0): """ Initialize the Hindsight client. Args: base_url: The base URL of the Hindsight API server + api_key: Optional API key for authentication (sent as Bearer token) timeout: Request timeout in seconds (default: 30.0) """ - config = hindsight_client_api.Configuration(host=base_url) + config = hindsight_client_api.Configuration(host=base_url, access_token=api_key) self._api_client = hindsight_client_api.ApiClient(config) self._api = default_api.DefaultApi(self._api_client) diff --git a/hindsight-clients/typescript/src/index.ts b/hindsight-clients/typescript/src/index.ts index db08c7be..4c4cf061 100644 --- a/hindsight-clients/typescript/src/index.ts +++ b/hindsight-clients/typescript/src/index.ts @@ -5,8 +5,15 @@ * ```typescript * import { HindsightClient } from '@vectorize-io/hindsight-client'; * + * // Without authentication * const client = new HindsightClient({ baseUrl: 'http://localhost:8888' }); * + * // With API key authentication + * const client = new HindsightClient({ + * baseUrl: 'http://localhost:8888', + * apiKey: 'your-api-key' + * }); + * * // Retain a memory * await client.retain('alice', 'Alice loves AI'); * @@ -37,6 +44,10 @@ import type { export interface HindsightClientOptions { baseUrl: string; + /** + * Optional API key for authentication (sent as Bearer token in Authorization header) + */ + apiKey?: string; } export interface MemoryItemInput { @@ -54,6 +65,9 @@ export class HindsightClient { this.client = createClient( createConfig({ baseUrl: options.baseUrl, + headers: options.apiKey + ? { Authorization: `Bearer ${options.apiKey}` } + : undefined, }) ); } diff --git a/hindsight-dev/benchmarks/common/benchmark_runner.py b/hindsight-dev/benchmarks/common/benchmark_runner.py index 9fe47a3a..b3f6f57d 100644 --- a/hindsight-dev/benchmarks/common/benchmark_runner.py +++ b/hindsight-dev/benchmarks/common/benchmark_runner.py @@ -17,23 +17,24 @@ The framework supports two answer generation patterns: - Skips the search step for efficiency """ -import json import asyncio +import json import logging +import os from abc import ABC, abstractmethod from datetime import datetime, timezone -from typing import List, Dict, Any, Optional, Tuple from pathlib import Path -from rich.console import Console -from rich.progress import Progress, SpinnerColumn, TextColumn, BarColumn -from rich.table import Table -from rich import box -import pydantic +from typing import Any, Dict, List, Optional, Tuple +import pydantic from hindsight_api import MemoryEngine from hindsight_api.engine.memory_engine import Budget +from hindsight_api.models import RequestContext from openai import AsyncOpenAI -import os +from rich import box +from rich.console import Console +from rich.progress import BarColumn, Progress, SpinnerColumn, TextColumn +from rich.table import Table console = Console() @@ -61,18 +62,18 @@ def get_model_config() -> Dict[str, Dict[str, str]]: judge_model = os.getenv("HINDSIGHT_API_JUDGE_LLM_MODEL", memory_model) return { - 'hindsight': { - 'provider': memory_provider, - 'model': memory_model, + "hindsight": { + "provider": memory_provider, + "model": memory_model, }, - 'answer_generation': { - 'provider': answer_provider, - 'model': answer_model, + "answer_generation": { + "provider": answer_provider, + "model": answer_model, + }, + "judge": { + "provider": judge_provider, + "model": judge_model, }, - 'judge': { - 'provider': judge_provider, - 'model': judge_model, - } } @@ -82,7 +83,9 @@ def print_model_config(): console.print("\n[bold cyan]Model Configuration:[/bold cyan]") console.print(f" Hindsight: {config['hindsight']['provider']}/{config['hindsight']['model']}") - console.print(f" Answer Generation: {config['answer_generation']['provider']}/{config['answer_generation']['model']}") + console.print( + f" Answer Generation: {config['answer_generation']['provider']}/{config['answer_generation']['model']}" + ) console.print(f" LLM Judge: {config['judge']['provider']}/{config['judge']['model']}") console.print() @@ -170,7 +173,7 @@ class LLMAnswerGenerator(ABC): question: str, recall_result: Dict[str, Any], question_date: Optional[datetime] = None, - question_type: Optional[str] = None + question_type: Optional[str] = None, ) -> Tuple[str, str, Optional[List[Dict[str, Any]]]]: """ Generate answer from retrieved memories. @@ -194,6 +197,7 @@ class LLMAnswerGenerator(ABC): class JudgeResponse(pydantic.BaseModel): """Judge response format.""" + correct: bool reasoning: str @@ -204,6 +208,7 @@ class LLMAnswerEvaluator: def __init__(self): """Initialize with LLM configuration for judge/evaluator.""" from hindsight_api.engine.llm_wrapper import LLMConfig + self.llm_config = LLMConfig.for_judge() self.client = self.llm_config._client self.model = self.llm_config.model @@ -215,7 +220,7 @@ class LLMAnswerEvaluator: predicted_answer: str, semaphore: asyncio.Semaphore, category: Optional[str] = None, - max_retries: int = 3 + max_retries: int = 3, ) -> Tuple[bool, str]: """ Evaluate predicted answer using LLM-as-judge with category-specific prompts. @@ -235,7 +240,7 @@ class LLMAnswerEvaluator: for attempt in range(max_retries): try: # LongMemEval-specific evaluation prompts - if category in ['single-session-user', 'single-session-assistant', 'multi-session']: + if category in ["single-session-user", "single-session-assistant", "multi-session"]: prompt_content = f"""Evaluate if the model response contains the correct answer to the question. I will give you a question, a correct answer, and a response from a model. @@ -258,8 +263,8 @@ Provide your evaluation as JSON with: - reasoning: One sentence explanation - correct: true or false""" - elif category == 'temporal-reasoning': - prompt_content = f""" + elif category == "temporal-reasoning": + prompt_content = """ I will give you a question, a correct answer, and a response from a model. Please set correct=true if the response contains the correct answer. Otherwise, set correct=false. If the response is equivalent to the correct answer or contains all the intermediate steps to get the correct answer, you should also set correct=true. @@ -267,15 +272,15 @@ If the response only contains a subset of the information required by the answer In addition, do not penalize off-by-one errors for the number of days. If the question asks for the number of days/weeks/months, etc., and the model makes off-by-one errors (e.g., predicting 19 days when the answer is 18), the model's response is still correct. """ - elif category == 'knowledge-update': - prompt_content = f""" + elif category == "knowledge-update": + prompt_content = """ I will give you a question, a correct answer, and a response from a model. Please set correct=true if the response contains the correct answer. Otherwise, set correct=false. If the response contains some previous information along with an updated answer, the response should be considered as correct as long as the updated answer is the required answer. """ - elif category == 'single-session-preference': - prompt_content = f""" + elif category == "single-session-preference": + prompt_content = """ I will give you a question, a answer for desired personalized response, and a response from a model. Please set correct=true if the response satisfies the desired response. Otherwise, set correct=false. The model does not need to reflect all the points in the desired response. The response is correct as long as it recalls and utilizes the user's personal information correctly. @@ -283,7 +288,7 @@ The model does not need to reflect all the points in the desired response. The r else: # Default LoComo-style evaluation - prompt_content = f"""Your task is to label an answer to a question as 'CORRECT' or 'WRONG'. You will be given the following data: + prompt_content = """Your task is to label an answer to a question as 'CORRECT' or 'WRONG'. You will be given the following data: (1) a question (posed by one user to another user), (2) a 'gold' (ground truth) answer, (3) a generated answer @@ -311,13 +316,13 @@ Gold answer: {correct_answer} Generated answer: {predicted_answer} First, provide a short (one sentence) explanation of your reasoning. Short reasoning is preferred. If it's correct, set correct=true. -""" +""", } ], response_format=JudgeResponse, scope="judge", temperature=0, - max_completion_tokens=4096 + max_completion_tokens=4096, ) return judgement.correct, judgement.reasoning @@ -354,7 +359,7 @@ class BenchmarkRunner: dataset: BenchmarkDataset, answer_generator: LLMAnswerGenerator, answer_evaluator: LLMAnswerEvaluator, - memory: Optional[MemoryEngine] = None + memory: Optional[MemoryEngine] = None, ): """ Initialize benchmark runner. @@ -366,6 +371,7 @@ class BenchmarkRunner: memory: Memory system instance (creates new if None) """ import os + self.dataset = dataset self.answer_generator = answer_generator self.answer_evaluator = answer_evaluator @@ -393,26 +399,22 @@ class BenchmarkRunner: total_sessions += len(batch_contents) for session in batch_contents: - content_len = len(session['content']) + content_len = len(session["content"]) total_chars += content_len session_lengths.append(content_len) avg_length = total_chars / total_sessions if total_sessions > 0 else 0 return { - 'total_sessions': total_sessions, - 'total_chars': total_chars, - 'total_items': len(items), - 'avg_session_length': avg_length, - 'min_session_length': min(session_lengths) if session_lengths else 0, - 'max_session_length': max(session_lengths) if session_lengths else 0 + "total_sessions": total_sessions, + "total_chars": total_chars, + "total_items": len(items), + "avg_session_length": avg_length, + "min_session_length": min(session_lengths) if session_lengths else 0, + "max_session_length": max(session_lengths) if session_lengths else 0, } - async def ingest_conversation( - self, - item: Dict[str, Any], - agent_id: str - ) -> int: + async def ingest_conversation(self, item: Dict[str, Any], agent_id: str) -> int: """ Ingest conversation into memory using batch ingestion. @@ -426,7 +428,8 @@ class BenchmarkRunner: if batch_contents: await self.memory.retain_batch_async( bank_id=agent_id, - contents=batch_contents + contents=batch_contents, + request_context=RequestContext(), ) return len(batch_contents) @@ -462,6 +465,7 @@ class BenchmarkRunner: budget = Budget.LOW if thinking_budget <= 30 else Budget.MID if thinking_budget <= 70 else Budget.HIGH import time + recall_start_time = time.time() search_result = await self.memory.recall_async( bank_id=agent_id, @@ -473,7 +477,7 @@ class BenchmarkRunner: include_entities=True, max_entity_tokens=2048, include_chunks=True, - + request_context=RequestContext(), ) recall_time = time.time() - recall_start_time @@ -496,16 +500,24 @@ class BenchmarkRunner: return "I don't have enough information to answer that question.", "No relevant memories found.", [], {} # Generate answer using LLM - pass entire recall result - answer, reasoning, memories_override = await self.answer_generator.generate_answer(question, recall_result_dict, question_date, question_type) + answer, reasoning, memories_override = await self.answer_generator.generate_answer( + question, recall_result_dict, question_date, question_type + ) # Use override if provided, otherwise use the results from recall - final_memories = memories_override if memories_override is not None else [fact.model_dump() for fact in search_result.results] + final_memories = ( + memories_override + if memories_override is not None + else [fact.model_dump() for fact in search_result.results] + ) return answer, reasoning, final_memories, chunks else: # Integrated flow: generator does its own search (e.g., think API) # Pass empty recall result since generator doesn't need them - answer, reasoning, memories_override = await self.answer_generator.generate_answer(question, {"results": []}, question_date, question_type) + answer, reasoning, memories_override = await self.answer_generator.generate_answer( + question, {"results": []}, question_date, question_type + ) # Use memories from generator (should not be None for integrated mode) final_memories = memories_override if memories_override is not None else [] @@ -533,14 +545,14 @@ class BenchmarkRunner: """ # Filter out questions without answers (category 5) # First, identify and log category 5 questions that will be skipped - category_5_questions = [pair for pair in qa_pairs if pair.get('category') == 5] + category_5_questions = [pair for pair in qa_pairs if pair.get("category") == 5] if category_5_questions: logging.info(f"Skipping {len(category_5_questions)} category=5 questions for {item_id}") for q in category_5_questions: logging.debug(f" Skipped category=5 question: {q.get('question', 'N/A')[:100]}") # Filter out category 5 and questions without answers - qa_pairs = [pair for pair in qa_pairs if pair.get('category') != 5 and pair.get('answer')] + qa_pairs = [pair for pair in qa_pairs if pair.get("category") != 5 and pair.get("answer")] questions_to_eval = qa_pairs[:max_questions] if max_questions else qa_pairs with Progress( @@ -548,20 +560,19 @@ class BenchmarkRunner: TextColumn("[progress.description]{task.description}"), BarColumn(), TextColumn("[progress.percentage]{task.percentage:>3.0f}%"), - console=console + console=console, ) as progress: task = progress.add_task( - f"[cyan]Evaluating QA for {item_id} - {len(questions_to_eval)} questions", - total=len(questions_to_eval) + f"[cyan]Evaluating QA for {item_id} - {len(questions_to_eval)} questions", total=len(questions_to_eval) ) # Create tasks for all questions async def process_question(qa): async with semaphore: - question = qa['question'] - correct_answer = qa['answer'] - category = qa.get('category', 0) - question_date = qa.get('question_date') + question = qa["question"] + correct_answer = qa["answer"] + category = qa.get("category", 0) + question_date = qa.get("question_date") try: # Get predicted answer, reasoning, retrieved memories, and chunks @@ -571,33 +582,34 @@ class BenchmarkRunner: # Remove embeddings from retrieved memories to reduce file size memories_without_embeddings = [ - {k: v for k, v in mem.items() if k != 'embedding'} - for mem in retrieved_memories + {k: v for k, v in mem.items() if k != "embedding"} for mem in retrieved_memories ] return { - 'question': question, - 'correct_answer': correct_answer, - 'predicted_answer': predicted_answer, - 'reasoning': reasoning, - 'category': category, - 'retrieved_memories': memories_without_embeddings, - 'is_invalid': False, - 'error': None + "question": question, + "correct_answer": correct_answer, + "predicted_answer": predicted_answer, + "reasoning": reasoning, + "category": category, + "retrieved_memories": memories_without_embeddings, + "is_invalid": False, + "error": None, } except Exception as e: logging.exception(f"Failed to answer question: {question[:100]}") # Mark as invalid if answer generation failed - console.print(f" [red]✗[/red] Failed to answer question: {question[:50]}... Error: {str(e)[:100]}") + console.print( + f" [red]✗[/red] Failed to answer question: {question[:50]}... Error: {str(e)[:100]}" + ) return { - 'question': question, - 'correct_answer': correct_answer, - 'predicted_answer': 'ERROR: Failed to generate answer', - 'reasoning': f'Error: {str(e)}', - 'category': category, - 'retrieved_memories': [], - 'is_invalid': True, - 'error': str(e) + "question": question, + "correct_answer": correct_answer, + "predicted_answer": "ERROR: Failed to generate answer", + "reasoning": f"Error: {str(e)}", + "category": category, + "retrieved_memories": [], + "is_invalid": True, + "error": str(e), } question_tasks = [process_question(qa) for qa in questions_to_eval] @@ -632,40 +644,43 @@ class BenchmarkRunner: TextColumn("[progress.description]{task.description}"), BarColumn(), TextColumn("[progress.percentage]{task.percentage:>3.0f}%"), - console=console + console=console, ) as progress: task = progress.add_task( - f"[yellow]Judging answers with LLM (parallel, max {eval_semaphore_size})...", - total=total + f"[yellow]Judging answers with LLM (parallel, max {eval_semaphore_size})...", total=total ) # Create all judgment tasks async def judge_single(result): # Skip judging if already marked as invalid - if result.get('is_invalid', False): - result['is_correct'] = None - result['correctness_reasoning'] = f"Question invalid due to error: {result.get('error', 'Unknown error')}" + if result.get("is_invalid", False): + result["is_correct"] = None + result["correctness_reasoning"] = ( + f"Question invalid due to error: {result.get('error', 'Unknown error')}" + ) return result try: is_correct, eval_reasoning = await self.answer_evaluator.judge_answer( - result['question'], - result['correct_answer'], - result['predicted_answer'], + result["question"], + result["correct_answer"], + result["predicted_answer"], semaphore, - category=result.get('category') + category=result.get("category"), ) - result['is_correct'] = is_correct - result['correctness_reasoning'] = eval_reasoning + result["is_correct"] = is_correct + result["correctness_reasoning"] = eval_reasoning return result except Exception as e: # Mark as invalid if judging failed logging.exception(f"Failed to judge answer for question: {result.get('question', 'unknown')[:100]}") - console.print(f" [red]✗[/red] Failed to judge answer: {result.get('question', '')[:50]}... Error: {str(e)[:100]}") - result['is_invalid'] = True - result['is_correct'] = None - result['correctness_reasoning'] = f"Judge error: {str(e)}" - result['error'] = str(e) + console.print( + f" [red]✗[/red] Failed to judge answer: {result.get('question', '')[:50]}... Error: {str(e)[:100]}" + ) + result["is_invalid"] = True + result["is_correct"] = None + result["correctness_reasoning"] = f"Judge error: {str(e)}" + result["error"] = str(e) return result judgment_tasks = [judge_single(result) for result in results] @@ -678,32 +693,32 @@ class BenchmarkRunner: progress.update(task, advance=1) # Calculate stats - correct = sum(1 for r in judged_results if r.get('is_correct', False)) - invalid = sum(1 for r in judged_results if r.get('is_invalid', False)) + correct = sum(1 for r in judged_results if r.get("is_correct", False)) + invalid = sum(1 for r in judged_results if r.get("is_invalid", False)) valid_total = total - invalid category_stats = {} for result in judged_results: - category = result.get('category', 'unknown') + category = result.get("category", "unknown") if category not in category_stats: - category_stats[category] = {'correct': 0, 'total': 0, 'invalid': 0} - category_stats[category]['total'] += 1 - if result.get('is_invalid', False): - category_stats[category]['invalid'] += 1 - elif result.get('is_correct', False): - category_stats[category]['correct'] += 1 + category_stats[category] = {"correct": 0, "total": 0, "invalid": 0} + category_stats[category]["total"] += 1 + if result.get("is_invalid", False): + category_stats[category]["invalid"] += 1 + elif result.get("is_correct", False): + category_stats[category]["correct"] += 1 # Calculate accuracy excluding invalid questions accuracy = (correct / valid_total * 100) if valid_total > 0 else 0 return { - 'accuracy': accuracy, - 'correct': correct, - 'total': total, - 'invalid': invalid, - 'valid_total': valid_total, - 'category_stats': category_stats, - 'detailed_results': judged_results + "accuracy": accuracy, + "correct": correct, + "total": total, + "invalid": invalid, + "valid_total": valid_total, + "category_stats": category_stats, + "detailed_results": judged_results, } async def _agent_has_data(self, agent_id: str) -> bool: @@ -721,10 +736,9 @@ class BenchmarkRunner: pool = await self.memory._get_pool() async with pool.acquire() as conn: result = await conn.fetchrow( - "SELECT COUNT(*) as count FROM memory_units WHERE bank_id = $1 LIMIT 1", - agent_id + "SELECT COUNT(*) as count FROM memory_units WHERE bank_id = $1 LIMIT 1", agent_id ) - return result['count'] > 0 + return result["count"] > 0 except Exception as e: console.print(f" [red]Warning: Error checking agent data: {e}[/red]") return False @@ -761,7 +775,7 @@ class BenchmarkRunner: # Clear agent data before ingesting if clear_this_agent: console.print(" [1] Clearing previous agent data...") - await self.memory.delete_bank(agent_id) + await self.memory.delete_bank(agent_id, request_context=RequestContext()) console.print(f" [green]✓[/green] Cleared '{agent_id}' agent data") # Ingest conversation @@ -788,13 +802,11 @@ class BenchmarkRunner: console.print(" [4] Calculating metrics...") metrics = await self.calculate_metrics(qa_results, eval_semaphore_size) - console.print(f" [green]✓[/green] Accuracy: {metrics['accuracy']:.2f}% ({metrics['correct']}/{metrics['total']})") + console.print( + f" [green]✓[/green] Accuracy: {metrics['accuracy']:.2f}% ({metrics['correct']}/{metrics['total']})" + ) - return { - 'item_id': item_id, - 'metrics': metrics, - 'num_sessions': num_sessions - } + return {"item_id": item_id, "metrics": metrics, "num_sessions": num_sessions} async def run( self, @@ -837,7 +849,7 @@ class BenchmarkRunner: Returns: Dict with complete benchmark results """ - console.print(f"\n[bold cyan]Benchmark Evaluation[/bold cyan]") + console.print("\n[bold cyan]Benchmark Evaluation[/bold cyan]") console.print("=" * 80) # Print model configuration @@ -858,25 +870,39 @@ class BenchmarkRunner: console.print(f" [green]✓[/green] Loaded {len(items)} items") # Initialize memory system - console.print(f"\n[2] Initializing memory system...") - console.print(f" [green]✓[/green] Memory system initialized") + console.print("\n[2] Initializing memory system...") + console.print(" [green]✓[/green] Memory system initialized") if separate_ingestion_phase: # New two-phase approach: ingest all, then evaluate all return await self._run_two_phase( - items, agent_id, thinking_budget, max_tokens, - skip_ingestion, max_questions_per_item, - max_concurrent_questions, eval_semaphore_size, - output_path, merge_with_existing + items, + agent_id, + thinking_budget, + max_tokens, + skip_ingestion, + max_questions_per_item, + max_concurrent_questions, + eval_semaphore_size, + output_path, + merge_with_existing, ) else: # Original approach: process each item independently return await self._run_single_phase( - items, agent_id, thinking_budget, max_tokens, - skip_ingestion, max_questions_per_item, - max_concurrent_questions, eval_semaphore_size, - clear_agent_per_item, filln, max_concurrent_items, - output_path, merge_with_existing + items, + agent_id, + thinking_budget, + max_tokens, + skip_ingestion, + max_questions_per_item, + max_concurrent_questions, + eval_semaphore_size, + clear_agent_per_item, + filln, + max_concurrent_items, + output_path, + merge_with_existing, ) async def _run_single_phase( @@ -903,37 +929,53 @@ class BenchmarkRunner: if max_concurrent_items > 1 and clear_agent_per_item: # Parallel item processing (requires unique agent IDs) all_results = await self._process_items_parallel( - items, agent_id, thinking_budget, max_tokens, - skip_ingestion, max_questions_per_item, question_semaphore, - eval_semaphore_size, filln, max_concurrent_items, - output_path, merge_with_existing + items, + agent_id, + thinking_budget, + max_tokens, + skip_ingestion, + max_questions_per_item, + question_semaphore, + eval_semaphore_size, + filln, + max_concurrent_items, + output_path, + merge_with_existing, ) else: # Sequential item processing (original behavior) all_results = await self._process_items_sequential( - items, agent_id, thinking_budget, max_tokens, - skip_ingestion, max_questions_per_item, question_semaphore, - eval_semaphore_size, clear_agent_per_item, filln, - output_path, merge_with_existing + items, + agent_id, + thinking_budget, + max_tokens, + skip_ingestion, + max_questions_per_item, + question_semaphore, + eval_semaphore_size, + clear_agent_per_item, + filln, + output_path, + merge_with_existing, ) # Calculate overall metrics - total_correct = sum(r['metrics']['correct'] for r in all_results) - total_questions = sum(r['metrics']['total'] for r in all_results) - total_invalid = sum(r['metrics'].get('invalid', 0) for r in all_results) + total_correct = sum(r["metrics"]["correct"] for r in all_results) + total_questions = sum(r["metrics"]["total"] for r in all_results) + total_invalid = sum(r["metrics"].get("invalid", 0) for r in all_results) total_valid = total_questions - total_invalid # Calculate accuracy excluding invalid questions overall_accuracy = (total_correct / total_valid * 100) if total_valid > 0 else 0 return { - 'overall_accuracy': overall_accuracy, - 'total_correct': total_correct, - 'total_questions': total_questions, - 'total_invalid': total_invalid, - 'total_valid': total_valid, - 'num_items': len(items), - 'model_config': get_model_config(), - 'item_results': all_results + "overall_accuracy": overall_accuracy, + "total_correct": total_correct, + "total_questions": total_questions, + "total_invalid": total_invalid, + "total_valid": total_valid, + "num_items": len(items), + "model_config": get_model_config(), + "item_results": all_results, } async def _process_items_sequential( @@ -957,11 +999,11 @@ class BenchmarkRunner: # Load existing results if merge_with_existing is True if merge_with_existing and output_path and output_path.exists(): - with open(output_path, 'r') as f: + with open(output_path, "r") as f: existing_data = json.load(f) - if 'item_results' in existing_data: - all_results = existing_data['item_results'] - existing_item_ids = {r['item_id'] for r in all_results} + if "item_results" in existing_data: + all_results = existing_data["item_results"] + existing_item_ids = {r["item_id"] for r in all_results} console.print(f"[cyan]Loaded {len(all_results)} existing results from {output_path}[/cyan]") for i, item in enumerate(items, 1): @@ -975,28 +1017,35 @@ class BenchmarkRunner: else: item_agent_id = agent_id # Only clear on first item for shared agent_id - clear_this_agent = (i == 1) + clear_this_agent = i == 1 # Check if we should skip this item (fill mode - skip if already in results file) item_id = self.dataset.get_item_id(item) if filln: if item_id in existing_item_ids: console.print(f"\n[bold blue]Item {i}/{len(items)}[/bold blue] (ID: {item_id})") - console.print(f" [yellow]⊘[/yellow] Skipping - already has results in output file") + console.print(" [yellow]⊘[/yellow] Skipping - already has results in output file") continue result = await self.process_single_item( - item, item_agent_id, i, len(items), - thinking_budget, max_tokens, max_questions_per_item, - skip_ingestion, question_semaphore, eval_semaphore_size, + item, + item_agent_id, + i, + len(items), + thinking_budget, + max_tokens, + max_questions_per_item, + skip_ingestion, + question_semaphore, + eval_semaphore_size, clear_this_agent, ) # Replace existing result or append new one - result_item_id = result['item_id'] + result_item_id = result["item_id"] if result_item_id in existing_item_ids: # Replace existing result - all_results = [r for r in all_results if r['item_id'] != result_item_id] + all_results = [r for r in all_results if r["item_id"] != result_item_id] console.print(f" [cyan]↻[/cyan] Updating existing result for {result_item_id}") all_results.append(result) existing_item_ids.add(result_item_id) @@ -1029,11 +1078,11 @@ class BenchmarkRunner: result_lock = asyncio.Lock() # Lock for thread-safe updates to all_results if merge_with_existing and output_path and output_path.exists(): - with open(output_path, 'r') as f: + with open(output_path, "r") as f: existing_data = json.load(f) - if 'item_results' in existing_data: - all_results = existing_data['item_results'] - existing_item_ids = {r['item_id'] for r in all_results} + if "item_results" in existing_data: + all_results = existing_data["item_results"] + existing_item_ids = {r["item_id"] for r in all_results} console.print(f"[cyan]Loaded {len(all_results)} existing results from {output_path}[/cyan]") # Create semaphore for item-level parallelism @@ -1049,14 +1098,21 @@ class BenchmarkRunner: if filln: if item_id in existing_item_ids: console.print(f"\n[bold blue]Item {i}/{len(items)}[/bold blue] (ID: {item_id})") - console.print(f" [yellow]⊘[/yellow] Skipping - already has results in output file") + console.print(" [yellow]⊘[/yellow] Skipping - already has results in output file") return None # Process the item result = await self.process_single_item( - item, item_agent_id, i, len(items), - thinking_budget, max_tokens, max_questions_per_item, - skip_ingestion, question_semaphore, eval_semaphore_size, + item, + item_agent_id, + i, + len(items), + thinking_budget, + max_tokens, + max_questions_per_item, + skip_ingestion, + question_semaphore, + eval_semaphore_size, clear_this_agent=True, # Always clear for parallel processing ) return result @@ -1070,10 +1126,10 @@ class BenchmarkRunner: if result is not None: async with result_lock: # Replace existing result or append new one - result_item_id = result['item_id'] + result_item_id = result["item_id"] if result_item_id in existing_item_ids: # Replace existing result - all_results = [r for r in all_results if r['item_id'] != result_item_id] + all_results = [r for r in all_results if r["item_id"] != result_item_id] console.print(f" [cyan]↻[/cyan] Updating existing result for {result_item_id}") all_results.append(result) existing_item_ids.add(result_item_id) @@ -1105,41 +1161,42 @@ class BenchmarkRunner: # Phase 1: Ingestion if not skip_ingestion: # Calculate and display data statistics - console.print(f"\n[3] Analyzing data to be ingested...") + console.print("\n[3] Analyzing data to be ingested...") stats = self.calculate_data_stats(items) console.print(f" [cyan]Total items:[/cyan] {stats['total_items']}") console.print(f" [cyan]Total sessions:[/cyan] {stats['total_sessions']}") console.print(f" [cyan]Total characters:[/cyan] {stats['total_chars']:,}") console.print(f" [cyan]Avg session length:[/cyan] {stats['avg_session_length']:.0f} chars") - console.print(f" [cyan]Session length range:[/cyan] {stats['min_session_length']}-{stats['max_session_length']} chars") + console.print( + f" [cyan]Session length range:[/cyan] {stats['min_session_length']}-{stats['max_session_length']} chars" + ) console.print(f"\n[4] Phase 1: Ingesting all data into agent '{agent_id}'...") - console.print(f" [yellow]Clearing previous agent data...[/yellow]") - await self.memory.delete_bank(agent_id) - console.print(f" [green]✓[/green] Cleared agent data") + console.print(" [yellow]Clearing previous agent data...[/yellow]") + await self.memory.delete_bank(agent_id, request_context=RequestContext()) + console.print(" [green]✓[/green] Cleared agent data") # Collect all sessions and send in one batch (with auto-chunking) - console.print(f" [yellow]Collecting sessions from all items...[/yellow]") + console.print(" [yellow]Collecting sessions from all items...[/yellow]") all_sessions = [] for item in items: item_sessions = self.dataset.prepare_sessions_for_ingestion(item) all_sessions.extend(item_sessions) console.print(f" [cyan]Collected {len(all_sessions)} sessions from {len(items)} items[/cyan]") - console.print(f" [yellow]Ingesting in one batch (auto-chunks if needed)...[/yellow]") + console.print(" [yellow]Ingesting in one batch (auto-chunks if needed)...[/yellow]") # Ingest all sessions in one batch call (will auto-chunk if too large) await self.memory.retain_batch_async( - bank_id=agent_id, - contents=all_sessions + bank_id=agent_id, contents=all_sessions, request_context=RequestContext() ) console.print(f" [green]✓[/green] Ingested {len(all_sessions)} sessions from {len(items)} items") else: - console.print(f"\n[3] Skipping ingestion (using existing data)") + console.print("\n[3] Skipping ingestion (using existing data)") # Phase 2: Evaluation - console.print(f"\n[5] Phase 2: Evaluating all questions...") + console.print("\n[5] Phase 2: Evaluating all questions...") # Create semaphore for question processing question_semaphore = asyncio.Semaphore(max_concurrent_questions) @@ -1165,29 +1222,33 @@ class BenchmarkRunner: # Calculate metrics metrics = await self.calculate_metrics(qa_results, eval_semaphore_size) - console.print(f" [green]✓[/green] Accuracy: {metrics['accuracy']:.2f}% ({metrics['correct']}/{metrics['total']})") + console.print( + f" [green]✓[/green] Accuracy: {metrics['accuracy']:.2f}% ({metrics['correct']}/{metrics['total']})" + ) - all_results.append({ - 'item_id': item_id, - 'metrics': metrics, - 'num_sessions': -1 # Not tracked in two-phase mode - }) + all_results.append( + { + "item_id": item_id, + "metrics": metrics, + "num_sessions": -1, # Not tracked in two-phase mode + } + ) # Calculate overall metrics - total_correct = sum(r['metrics']['correct'] for r in all_results) - total_questions = sum(r['metrics']['total'] for r in all_results) - total_invalid = sum(r['metrics'].get('invalid', 0) for r in all_results) + total_correct = sum(r["metrics"]["correct"] for r in all_results) + total_questions = sum(r["metrics"]["total"] for r in all_results) + total_invalid = sum(r["metrics"].get("invalid", 0) for r in all_results) total_valid = total_questions - total_invalid overall_accuracy = (total_correct / total_valid * 100) if total_valid > 0 else 0 return { - 'overall_accuracy': overall_accuracy, - 'total_correct': total_correct, - 'total_questions': total_questions, - 'total_invalid': total_invalid, - 'total_valid': total_valid, - 'num_items': len(items), - 'item_results': all_results + "overall_accuracy": overall_accuracy, + "total_correct": total_correct, + "total_questions": total_questions, + "total_invalid": total_invalid, + "total_valid": total_valid, + "num_items": len(items), + "item_results": all_results, } def display_results(self, results: Dict[str, Any]): @@ -1195,11 +1256,13 @@ class BenchmarkRunner: console.print("\n[bold green]✓ Benchmark Complete![/bold green]\n") # Display model configuration - if 'model_config' in results: - config = results['model_config'] + if "model_config" in results: + config = results["model_config"] console.print("[bold cyan]Model Configuration:[/bold cyan]") console.print(f" Hindsight: {config['hindsight']['provider']}/{config['hindsight']['model']}") - console.print(f" Answer Generation: {config['answer_generation']['provider']}/{config['answer_generation']['model']}") + console.print( + f" Answer Generation: {config['answer_generation']['provider']}/{config['answer_generation']['model']}" + ) console.print(f" LLM Judge: {config['judge']['provider']}/{config['judge']['model']}") console.print() @@ -1212,20 +1275,20 @@ class BenchmarkRunner: table.add_column("Invalid", justify="right", style="red") table.add_column("Accuracy", justify="right", style="magenta") - for result in results['item_results']: - metrics = result['metrics'] - invalid_count = metrics.get('invalid', 0) + for result in results["item_results"]: + metrics = result["metrics"] + invalid_count = metrics.get("invalid", 0) invalid_str = str(invalid_count) if invalid_count > 0 else "-" table.add_row( - result['item_id'], - str(result['num_sessions']), - str(metrics['total']), - str(metrics['correct']), + result["item_id"], + str(result["num_sessions"]), + str(metrics["total"]), + str(metrics["correct"]), invalid_str, - f"{metrics['accuracy']:.1f}%" + f"{metrics['accuracy']:.1f}%", ) - overall_invalid = results.get('total_invalid', 0) + overall_invalid = results.get("total_invalid", 0) invalid_str = str(overall_invalid) if overall_invalid > 0 else "-" table.add_row( "[bold]OVERALL[/bold]", @@ -1233,14 +1296,16 @@ class BenchmarkRunner: f"[bold]{results['total_questions']}[/bold]", f"[bold]{results['total_correct']}[/bold]", f"[bold]{invalid_str}[/bold]", - f"[bold]{results['overall_accuracy']:.1f}%[/bold]" + f"[bold]{results['overall_accuracy']:.1f}%[/bold]", ) console.print(table) # Display note about invalid questions if any if overall_invalid > 0: - console.print(f"\n[yellow]Note: {overall_invalid} question(s) marked as invalid due to errors (excluded from accuracy calculation)[/yellow]") + console.print( + f"\n[yellow]Note: {overall_invalid} question(s) marked as invalid due to errors (excluded from accuracy calculation)[/yellow]" + ) def merge_results(self, new_results: Dict[str, Any], existing_results: Dict[str, Any]) -> Dict[str, Any]: """ @@ -1256,16 +1321,16 @@ class BenchmarkRunner: Merged results with updated overall metrics """ # Start with existing item results - merged_item_results = existing_results.get('item_results', []) + merged_item_results = existing_results.get("item_results", []) # Update or add new item results - for new_item in new_results['item_results']: - item_id = new_item['item_id'] + for new_item in new_results["item_results"]: + item_id = new_item["item_id"] # Find if item already exists found = False for i, existing_item in enumerate(merged_item_results): - if existing_item['item_id'] == item_id: + if existing_item["item_id"] == item_id: # Replace existing item result merged_item_results[i] = new_item found = True @@ -1278,21 +1343,21 @@ class BenchmarkRunner: console.print(f" [green]+[/green] Added results for item: {item_id}") # Recalculate overall metrics from all item results - total_correct = sum(r['metrics']['correct'] for r in merged_item_results) - total_questions = sum(r['metrics']['total'] for r in merged_item_results) - total_invalid = sum(r['metrics'].get('invalid', 0) for r in merged_item_results) + total_correct = sum(r["metrics"]["correct"] for r in merged_item_results) + total_questions = sum(r["metrics"]["total"] for r in merged_item_results) + total_invalid = sum(r["metrics"].get("invalid", 0) for r in merged_item_results) total_valid = total_questions - total_invalid # Calculate accuracy excluding invalid questions overall_accuracy = (total_correct / total_valid * 100) if total_valid > 0 else 0 return { - 'overall_accuracy': overall_accuracy, - 'total_correct': total_correct, - 'total_questions': total_questions, - 'total_invalid': total_invalid, - 'total_valid': total_valid, - 'num_items': len(merged_item_results), - 'item_results': merged_item_results + "overall_accuracy": overall_accuracy, + "total_correct": total_correct, + "total_questions": total_questions, + "total_invalid": total_invalid, + "total_valid": total_valid, + "num_items": len(merged_item_results), + "item_results": merged_item_results, } def _save_incremental_results(self, all_results: List[Dict], output_path: Path): @@ -1304,24 +1369,24 @@ class BenchmarkRunner: output_path: Path to save results to """ # Calculate metrics from current results - total_correct = sum(r['metrics']['correct'] for r in all_results) - total_questions = sum(r['metrics']['total'] for r in all_results) - total_invalid = sum(r['metrics'].get('invalid', 0) for r in all_results) + total_correct = sum(r["metrics"]["correct"] for r in all_results) + total_questions = sum(r["metrics"]["total"] for r in all_results) + total_invalid = sum(r["metrics"].get("invalid", 0) for r in all_results) total_valid = total_questions - total_invalid overall_accuracy = (total_correct / total_valid * 100) if total_valid > 0 else 0 results_dict = { - 'overall_accuracy': overall_accuracy, - 'total_correct': total_correct, - 'total_questions': total_questions, - 'total_invalid': total_invalid, - 'total_valid': total_valid, - 'num_items': len(all_results), - 'model_config': get_model_config(), - 'item_results': all_results + "overall_accuracy": overall_accuracy, + "total_correct": total_correct, + "total_questions": total_questions, + "total_invalid": total_invalid, + "total_valid": total_valid, + "num_items": len(all_results), + "model_config": get_model_config(), + "item_results": all_results, } - with open(output_path, 'w') as f: + with open(output_path, "w") as f: json.dump(results_dict, f, indent=2, default=str) def save_results(self, results: Dict[str, Any], output_path: Path, merge_with_existing: bool = False): @@ -1335,12 +1400,12 @@ class BenchmarkRunner: """ if merge_with_existing and output_path.exists(): # Load existing results - with open(output_path, 'r') as f: + with open(output_path, "r") as f: existing_results = json.load(f) console.print(f"\n[cyan]Merging with existing results from {output_path}...[/cyan]") results = self.merge_results(results, existing_results) - with open(output_path, 'w') as f: + with open(output_path, "w") as f: json.dump(results, f, indent=2, default=str) console.print(f"\n[green]✓[/green] Results saved to {output_path}") diff --git a/hindsight-dev/benchmarks/locomo/locomo_benchmark.py b/hindsight-dev/benchmarks/locomo/locomo_benchmark.py index 42d57169..e58999d4 100644 --- a/hindsight-dev/benchmarks/locomo/locomo_benchmark.py +++ b/hindsight-dev/benchmarks/locomo/locomo_benchmark.py @@ -3,28 +3,28 @@ LoComo-specific benchmark implementations. Provides dataset, answer generator, and evaluator for the LoComo benchmark. """ -import sys -from pathlib import Path -from benchmarks.common.benchmark_runner import BenchmarkRunner - -import json -from datetime import datetime, timezone -from typing import List, Dict, Any, Tuple, Optional import asyncio -import pydantic -from openai import AsyncOpenAI +import json import os +import sys +from datetime import datetime, timezone +from pathlib import Path +from typing import Any, Dict, List, Optional, Tuple -from benchmarks.common.benchmark_runner import BenchmarkDataset, LLMAnswerGenerator, LLMAnswerEvaluator +import pydantic from hindsight_api.engine.llm_wrapper import LLMConfig +from openai import AsyncOpenAI + +from benchmarks.common.benchmark_runner import BenchmarkDataset, BenchmarkRunner, LLMAnswerEvaluator, LLMAnswerGenerator + class LoComoDataset(BenchmarkDataset): """LoComo dataset implementation.""" def load(self, path: Path, max_items: Optional[int] = None) -> List[Dict[str, Any]]: """Load LoComo dataset from JSON file.""" - with open(path, 'r') as f: + with open(path, "r") as f: dataset = json.load(f) if max_items: @@ -34,7 +34,7 @@ class LoComoDataset(BenchmarkDataset): def get_item_id(self, item: Dict) -> str: """Get sample ID from LoComo item.""" - return item['sample_id'] + return item["sample_id"] def prepare_sessions_for_ingestion(self, item: Dict) -> List[Dict[str, Any]]: """ @@ -45,12 +45,12 @@ class LoComoDataset(BenchmarkDataset): Returns: List of session dicts, each containing 'content', 'context', 'event_date', 'document_id' """ - conv = item['conversation'] - speaker_a = conv['speaker_a'] - speaker_b = conv['speaker_b'] + conv = item["conversation"] + speaker_a = conv["speaker_a"] + speaker_b = conv["speaker_b"] # Get all session keys sorted - session_keys = sorted([k for k in conv.keys() if k.startswith('session_') and not k.endswith('_date_time')]) + session_keys = sorted([k for k in conv.keys() if k.startswith("session_") and not k.endswith("_date_time")]) session_items = [] @@ -65,12 +65,14 @@ class LoComoDataset(BenchmarkDataset): session_date = self._parse_date(conv.get(date_key)) session_content = json.dumps(session_data) document_id = f"{item['sample_id']}_{session_key}" - session_items.append({ - "content": session_content, - "context": f"Conversation between {speaker_a} and {speaker_b} ({session_key} of {item['sample_id']})", - "event_date": session_date, - "document_id": document_id - }) + session_items.append( + { + "content": session_content, + "context": f"Conversation between {speaker_a} and {speaker_b} ({session_key} of {item['sample_id']})", + "event_date": session_date, + "document_id": document_id, + } + ) return session_items @@ -81,7 +83,7 @@ class LoComoDataset(BenchmarkDataset): Returns: List of QA dicts with 'question', 'answer', 'category' """ - return item['qa'] + return item["qa"] def _parse_date(self, date_string: str) -> datetime: """Parse LoComo date format to datetime.""" @@ -95,6 +97,7 @@ class LoComoDataset(BenchmarkDataset): class QuestionAnswer(pydantic.BaseModel): """Answer format for LoComo questions.""" + answer: str reasoning: str @@ -113,7 +116,7 @@ class LoComoAnswerGenerator(LLMAnswerGenerator): question: str, recall_result: Dict[str, Any], question_date: Optional[datetime] = None, - question_type: Optional[str] = None + question_type: Optional[str] = None, ) -> Tuple[str, str, Optional[List[Dict[str, Any]]]]: """ Generate answer from retrieved memories using Groq. @@ -141,7 +144,7 @@ class LoComoAnswerGenerator(LLMAnswerGenerator): messages=[ { "role": "system", - "content": "You are a helpful expert assistant answering questions from lme_experiment users based on the provided context." + "content": "You are a helpful expert assistant answering questions from lme_experiment users based on the provided context.", }, { "role": "user", @@ -165,11 +168,11 @@ Context: Question: {question} Answer: -""" - } +""", + }, ], response_format=QuestionAnswer, - scope="memory" + scope="memory", ) return answer_obj.answer, answer_obj.reasoning, None except Exception as e: @@ -183,7 +186,7 @@ class LoComoThinkAnswerGenerator(LLMAnswerGenerator): so it doesn't need external search to be performed by the benchmark runner. """ - def __init__(self, memory: 'MemoryEngine', agent_id: str, thinking_budget: int = 500): + def __init__(self, memory: "MemoryEngine", agent_id: str, thinking_budget: int = 500): """Initialize with memory instance and agent_id. Args: @@ -204,7 +207,7 @@ class LoComoThinkAnswerGenerator(LLMAnswerGenerator): question: str, recall_result: Dict[str, Any], question_date: Optional[datetime] = None, - question_type: Optional[str] = None + question_type: Optional[str] = None, ) -> Tuple[str, str, Optional[List[Dict[str, Any]]]]: """ Generate answer using the integrated think API. @@ -235,9 +238,9 @@ class LoComoThinkAnswerGenerator(LLMAnswerGenerator): # Extract memories from based_on based_on = result.based_on - world_facts = based_on.get('world', []) - agent_facts = based_on.get('agent', []) - opinion_facts = based_on.get('opinion', []) + world_facts = based_on.get("world", []) + agent_facts = based_on.get("agent", []) + opinion_facts = based_on.get("opinion", []) # Combine all facts into retrieved_memories retrieved_memories = [] @@ -271,7 +274,7 @@ async def run_benchmark( api_url: str = None, max_concurrent_questions_override: int = None, only_failed: bool = False, - only_invalid: bool = False + only_invalid: bool = False, ): """ Run the LoComo benchmark. @@ -287,6 +290,7 @@ async def run_benchmark( only_invalid: If True, only run conversations that have invalid questions (is_invalid=True) """ from rich.console import Console + console = Console() # Load previous results if filtering for failed/invalid conversations @@ -294,35 +298,41 @@ async def run_benchmark( invalid_conversation_ids = set() if only_failed or only_invalid: suffix = "_think" if use_think else "" - results_filename = f'benchmark_results{suffix}.json' - results_path = Path(__file__).parent / 'results' / results_filename + results_filename = f"benchmark_results{suffix}.json" + results_path = Path(__file__).parent / "results" / results_filename if not results_path.exists(): - console.print(f"[red]Error: Cannot use --only-failed or --only-invalid without existing results file[/red]") + console.print("[red]Error: Cannot use --only-failed or --only-invalid without existing results file[/red]") console.print(f"[yellow]Results file not found: {results_path}[/yellow]") return - with open(results_path, 'r') as f: + with open(results_path, "r") as f: previous_results = json.load(f) # Extract conversation IDs that have failed or invalid questions - for item_result in previous_results.get('item_results', []): - item_id = item_result['item_id'] - for detail in item_result['metrics'].get('detailed_results', []): - if only_failed and detail.get('is_correct') == False and not detail.get('is_invalid', False): + for item_result in previous_results.get("item_results", []): + item_id = item_result["item_id"] + for detail in item_result["metrics"].get("detailed_results", []): + if only_failed and detail.get("is_correct") == False and not detail.get("is_invalid", False): failed_conversation_ids.add(item_id) - if only_invalid and detail.get('is_invalid', False): + if only_invalid and detail.get("is_invalid", False): invalid_conversation_ids.add(item_id) if only_failed: - console.print(f"[cyan]Filtering to {len(failed_conversation_ids)} conversations with failed questions (is_correct=False)[/cyan]") + console.print( + f"[cyan]Filtering to {len(failed_conversation_ids)} conversations with failed questions (is_correct=False)[/cyan]" + ) if only_invalid: - console.print(f"[cyan]Filtering to {len(invalid_conversation_ids)} conversations with invalid questions (is_invalid=True)[/cyan]") + console.print( + f"[cyan]Filtering to {len(invalid_conversation_ids)} conversations with invalid questions (is_invalid=True)[/cyan]" + ) target_ids = failed_conversation_ids if only_failed else invalid_conversation_ids if not target_ids: filter_type = "failed" if only_failed else "invalid" - console.print(f"[yellow]No conversations with {filter_type} questions found in previous results. Nothing to run.[/yellow]") + console.print( + f"[yellow]No conversations with {filter_type} questions found in previous results. Nothing to run.[/yellow]" + ) return # Initialize components @@ -331,18 +341,16 @@ async def run_benchmark( # Use remote API client if api_url is provided, otherwise use local memory if api_url: from benchmarks.common.benchmark_runner import HindsightClientAdapter + memory = HindsightClientAdapter(base_url=api_url) await memory.initialize() else: from benchmarks.common.benchmark_runner import create_memory_engine + memory = await create_memory_engine() if use_think: - answer_generator = LoComoThinkAnswerGenerator( - memory=memory, - agent_id="locomo", - thinking_budget=500 - ) + answer_generator = LoComoThinkAnswerGenerator(memory=memory, agent_id="locomo", thinking_budget=500) max_concurrent_questions = max_concurrent_questions_override or 4 eval_semaphore_size = 4 else: @@ -356,14 +364,11 @@ async def run_benchmark( # Create benchmark runner runner = BenchmarkRunner( - dataset=dataset, - answer_generator=answer_generator, - answer_evaluator=answer_evaluator, - memory=memory + dataset=dataset, answer_generator=answer_generator, answer_evaluator=answer_evaluator, memory=memory ) # Filter dataset if using --only-failed or --only-invalid - dataset_path = Path(__file__).parent / 'datasets' / 'locomo10.json' + dataset_path = Path(__file__).parent / "datasets" / "locomo10.json" if only_failed or only_invalid: # Load and filter dataset @@ -374,14 +379,16 @@ async def run_benchmark( # Temporarily replace dataset's load method original_load = dataset.load + def filtered_load(path: Path, max_items: Optional[int] = None): return filtered_items[:max_items] if max_items else filtered_items + dataset.load = filtered_load # Determine output filename based on mode suffix = "_think" if use_think else "" - results_filename = f'benchmark_results{suffix}.json' - output_path = Path(__file__).parent / 'results' / results_filename + results_filename = f"benchmark_results{suffix}.json" + output_path = Path(__file__).parent / "results" / results_filename # Create results directory if it doesn't exist output_path.parent.mkdir(parents=True, exist_ok=True) @@ -406,7 +413,7 @@ async def run_benchmark( clear_agent_per_item=True, # Use unique agent ID per conversation max_concurrent_items=3, # Process up to 3 conversations in parallel output_path=output_path, # Save results incrementally - merge_with_existing=merge_with_existing + merge_with_existing=merge_with_existing, ) # Display results (final save already happened incrementally) @@ -430,14 +437,10 @@ def generate_markdown_table(results: dict, use_think: bool = False): 4 = Open-domain """ from rich.console import Console + console = Console() - category_names = { - '1': 'Multi-hop', - '2': 'Single-hop', - '3': 'Temporal', - '4': 'Open-domain' - } + category_names = {"1": "Multi-hop", "2": "Single-hop", "3": "Temporal", "4": "Open-domain"} # Build markdown content lines = [] @@ -446,33 +449,41 @@ def generate_markdown_table(results: dict, use_think: bool = False): lines.append("") # Add model configuration - if 'model_config' in results: - config = results['model_config'] + if "model_config" in results: + config = results["model_config"] lines.append("## Model Configuration") lines.append("") lines.append(f"- **Hindsight**: {config['hindsight']['provider']}/{config['hindsight']['model']}") - lines.append(f"- **Answer Generation**: {config['answer_generation']['provider']}/{config['answer_generation']['model']}") + lines.append( + f"- **Answer Generation**: {config['answer_generation']['provider']}/{config['answer_generation']['model']}" + ) lines.append(f"- **LLM Judge**: {config['judge']['provider']}/{config['judge']['model']}") lines.append("") - lines.append(f"**Overall Accuracy**: {results['overall_accuracy']:.2f}% ({results['total_correct']}/{results['total_questions']})") + lines.append( + f"**Overall Accuracy**: {results['overall_accuracy']:.2f}% ({results['total_correct']}/{results['total_questions']})" + ) lines.append("") - lines.append("| Sample ID | Sessions | Questions | Correct | Accuracy | Multi-hop | Single-hop | Temporal | Open-domain |") - lines.append("|-----------|----------|-----------|---------|----------|-----------|------------|----------|-------------|") + lines.append( + "| Sample ID | Sessions | Questions | Correct | Accuracy | Multi-hop | Single-hop | Temporal | Open-domain |" + ) + lines.append( + "|-----------|----------|-----------|---------|----------|-----------|------------|----------|-------------|" + ) - for item_result in results['item_results']: - item_id = item_result['item_id'] - num_sessions = item_result['num_sessions'] - metrics = item_result['metrics'] + for item_result in results["item_results"]: + item_id = item_result["item_id"] + num_sessions = item_result["num_sessions"] + metrics = item_result["metrics"] # Calculate category accuracies - cat_stats = metrics.get('category_stats', {}) + cat_stats = metrics.get("category_stats", {}) cat_accuracies = {} - for cat_id in ['1', '2', '3', '4']: + for cat_id in ["1", "2", "3", "4"]: if cat_id in cat_stats: stats = cat_stats[cat_id] - acc = (stats['correct'] / stats['total'] * 100) if stats['total'] > 0 else 0 + acc = (stats["correct"] / stats["total"] * 100) if stats["total"] > 0 else 0 cat_accuracies[cat_id] = f"{acc:.1f}% ({stats['correct']}/{stats['total']})" else: cat_accuracies[cat_id] = "N/A" @@ -485,28 +496,48 @@ def generate_markdown_table(results: dict, use_think: bool = False): # Write to file with suffix suffix = "_think" if use_think else "" - output_file = Path(__file__).parent / 'results' / f'results_table{suffix}.md' + output_file = Path(__file__).parent / "results" / f"results_table{suffix}.md" output_file.parent.mkdir(parents=True, exist_ok=True) - output_file.write_text('\n'.join(lines)) + output_file.write_text("\n".join(lines)) console.print(f"\n[green]✓[/green] Results table saved to {output_file}") if __name__ == "__main__": - import logging import argparse + import logging - logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s') + logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s") - parser = argparse.ArgumentParser(description='Run LoComo benchmark') - parser.add_argument('--max-conversations', type=int, default=None, help='Maximum conversations to evaluate') - parser.add_argument('--max-questions', type=int, default=None, help='Maximum questions per conversation') - parser.add_argument('--skip-ingestion', action='store_true', help='Skip ingestion and use existing data') - parser.add_argument('--use-think', action='store_true', help='Use think API instead of search + LLM') - parser.add_argument('--conversation', type=str, default=None, help='Run only specific conversation (e.g., "conv-26")') - parser.add_argument('--api-url', type=str, default=None, help='Hindsight API URL (default: use local memory, example: http://localhost:8888)') - parser.add_argument('--max-concurrent-questions', type=int, default=None, help='Max concurrent questions per conversation (default: 4 for think, 10 for search)') - parser.add_argument('--only-failed', action='store_true', help='Only run conversations that have failed questions (is_correct=False). Requires existing results file.') - parser.add_argument('--only-invalid', action='store_true', help='Only run conversations that have invalid questions (is_invalid=True). Requires existing results file.') + parser = argparse.ArgumentParser(description="Run LoComo benchmark") + parser.add_argument("--max-conversations", type=int, default=None, help="Maximum conversations to evaluate") + parser.add_argument("--max-questions", type=int, default=None, help="Maximum questions per conversation") + parser.add_argument("--skip-ingestion", action="store_true", help="Skip ingestion and use existing data") + parser.add_argument("--use-think", action="store_true", help="Use think API instead of search + LLM") + parser.add_argument( + "--conversation", type=str, default=None, help='Run only specific conversation (e.g., "conv-26")' + ) + parser.add_argument( + "--api-url", + type=str, + default=None, + help="Hindsight API URL (default: use local memory, example: http://localhost:8888)", + ) + parser.add_argument( + "--max-concurrent-questions", + type=int, + default=None, + help="Max concurrent questions per conversation (default: 4 for think, 10 for search)", + ) + parser.add_argument( + "--only-failed", + action="store_true", + help="Only run conversations that have failed questions (is_correct=False). Requires existing results file.", + ) + parser.add_argument( + "--only-invalid", + action="store_true", + help="Only run conversations that have invalid questions (is_invalid=True). Requires existing results file.", + ) args = parser.parse_args() @@ -514,14 +545,16 @@ if __name__ == "__main__": if args.only_failed and args.only_invalid: parser.error("Cannot use both --only-failed and --only-invalid at the same time") - results = asyncio.run(run_benchmark( - max_conversations=args.max_conversations, - max_questions_per_conv=args.max_questions, - skip_ingestion=args.skip_ingestion, - use_think=args.use_think, - conversation=args.conversation, - api_url=args.api_url, - max_concurrent_questions_override=args.max_concurrent_questions, - only_failed=args.only_failed, - only_invalid=args.only_invalid - )) + results = asyncio.run( + run_benchmark( + max_conversations=args.max_conversations, + max_questions_per_conv=args.max_questions, + skip_ingestion=args.skip_ingestion, + use_think=args.use_think, + conversation=args.conversation, + api_url=args.api_url, + max_concurrent_questions_override=args.max_concurrent_questions, + only_failed=args.only_failed, + only_invalid=args.only_invalid, + ) + ) diff --git a/hindsight-dev/benchmarks/longmemeval/longmemeval_benchmark.py b/hindsight-dev/benchmarks/longmemeval/longmemeval_benchmark.py index 735084d9..549b49e0 100644 --- a/hindsight-dev/benchmarks/longmemeval/longmemeval_benchmark.py +++ b/hindsight-dev/benchmarks/longmemeval/longmemeval_benchmark.py @@ -3,21 +3,20 @@ LongMemEval-specific benchmark implementations. Provides dataset, answer generator, and evaluator for the LongMemEval benchmark. """ -import sys -from pathlib import Path -from benchmarks.common.benchmark_runner import BenchmarkRunner - -import json -from datetime import datetime, timezone -from typing import List, Dict, Any, Tuple, Optional import asyncio -import pydantic -from openai import AsyncOpenAI +import json import os +import sys +from datetime import datetime, timezone +from pathlib import Path +from typing import Any, Dict, List, Optional, Tuple -from benchmarks.common.benchmark_runner import BenchmarkDataset, LLMAnswerGenerator, LLMAnswerEvaluator +import pydantic from hindsight_api.engine.llm_wrapper import LLMConfig +from openai import AsyncOpenAI + +from benchmarks.common.benchmark_runner import BenchmarkDataset, BenchmarkRunner, LLMAnswerEvaluator, LLMAnswerGenerator class LongMemEvalDataset(BenchmarkDataset): @@ -25,7 +24,7 @@ class LongMemEvalDataset(BenchmarkDataset): def load(self, path: Path, max_items: Optional[int] = None) -> List[Dict[str, Any]]: """Load LongMemEval dataset from JSON file.""" - with open(path, 'r') as f: + with open(path, "r") as f: dataset = json.load(f) if max_items: @@ -67,7 +66,7 @@ class LongMemEvalDataset(BenchmarkDataset): for turn in session_turns: if isinstance(turn, dict): # Create a copy without has_answer - cleaned_turn = {k: v for k, v in turn.items() if k != 'has_answer'} + cleaned_turn = {k: v for k, v in turn.items() if k != "has_answer"} cleaned_turns.append(cleaned_turn) else: cleaned_turns.append(turn) @@ -75,12 +74,14 @@ class LongMemEvalDataset(BenchmarkDataset): session_content = json.dumps(cleaned_turns) question_id = item.get("question_id", "unknown") document_id = f"{question_id}_{session_id}" - batch_contents.append({ - "content": session_content, - "context": f"Session {document_id} - you are the assistant in this conversation - happened on {session_date.strftime('%Y-%m-%d %H:%M:%S')} UTC.", - "event_date": session_date, - "document_id": document_id - }) + batch_contents.append( + { + "content": session_content, + "context": f"Session {document_id} - you are the assistant in this conversation - happened on {session_date.strftime('%Y-%m-%d %H:%M:%S')} UTC.", + "event_date": session_date, + "document_id": document_id, + } + ) return batch_contents @@ -95,22 +96,24 @@ class LongMemEvalDataset(BenchmarkDataset): """ # Parse question_date if available question_date = None - if 'question_date' in item: - question_date = self._parse_date(item['question_date']) + if "question_date" in item: + question_date = self._parse_date(item["question_date"]) - return [{ - 'question': item.get("question", ""), - 'answer': item.get("answer", ""), - 'category': item.get("question_type", "unknown"), - 'question_date': question_date - }] + return [ + { + "question": item.get("question", ""), + "answer": item.get("answer", ""), + "category": item.get("question_type", "unknown"), + "question_date": question_date, + } + ] def _parse_date(self, date_str: str) -> datetime: """Parse date string to datetime object.""" try: # LongMemEval format: "2023/05/20 (Sat) 02:21" # Try to parse the main part before the day name - date_str_cleaned = date_str.split('(')[0].strip() if '(' in date_str else date_str + date_str_cleaned = date_str.split("(")[0].strip() if "(" in date_str else date_str # Try multiple formats for fmt in ["%Y/%m/%d %H:%M", "%Y-%m-%d %H:%M:%S", "%Y-%m-%d", "%Y/%m/%d"]: @@ -121,7 +124,7 @@ class LongMemEvalDataset(BenchmarkDataset): continue # Fallback: try ISO format - return datetime.fromisoformat(date_str.replace('Z', '+00:00')) + return datetime.fromisoformat(date_str.replace("Z", "+00:00")) except Exception: raise ValueError(f"Failed to parse date string: {date_str}") @@ -130,6 +133,7 @@ class QuestionAnswer(pydantic.BaseModel): answer: str reasoning: Optional[str] = None + class LongMemEvalAnswerGenerator(LLMAnswerGenerator): """LongMemEval-specific answer generator using configurable LLM provider.""" @@ -202,10 +206,7 @@ class LongMemEvalAnswerGenerator(LLMAnswerGenerator): chunk_text = chunk_info.get("chunk_text", "") # Build the formatted fact entry - entry_parts = [ - f"Fact {i} ({fact_type}): {fact_text}", - f"When: {when_str}" - ] + entry_parts = [f"Fact {i} ({fact_type}): {fact_text}", f"When: {when_str}"] # Add context field if present context = fact.get("context") @@ -217,7 +218,7 @@ class LongMemEvalAnswerGenerator(LLMAnswerGenerator): # Truncate very long chunks if len(chunk_text) > 1000: chunk_text = chunk_text[:1000] + "..." - entry_parts.append(f"Source chunk:\n \"{chunk_text}\"") + entry_parts.append(f'Source chunk:\n "{chunk_text}"') formatted_parts.append("\n".join(entry_parts)) @@ -326,43 +327,43 @@ The context contains memory facts extracted from previous conversations, each wi return "" async def generate_answer( - self, - question: str, - recall_result: Dict[str, Any], - question_date: Optional[datetime] = None, - question_type: Optional[str] = None - ) -> Tuple[str, str, Optional[List[Dict[str, Any]]]]: - """ - Generate answer from retrieved memories using Groq. + self, + question: str, + recall_result: Dict[str, Any], + question_date: Optional[datetime] = None, + question_type: Optional[str] = None, + ) -> Tuple[str, str, Optional[List[Dict[str, Any]]]]: + """ + Generate answer from retrieved memories using Groq. - Args: - question: The question text - recall_result: Full RecallResult dict containing results, entities, chunks, and trace - question_date: Date when the question was asked (for temporal context) - question_type: Question category (e.g., 'single-session-user', 'multi-session-assistant') + Args: + question: The question text + recall_result: Full RecallResult dict containing results, entities, chunks, and trace + question_date: Date when the question was asked (for temporal context) + question_type: Question category (e.g., 'single-session-user', 'multi-session-assistant') - Returns: - Tuple of (answer, reasoning, None) - - None indicates to use the memories from recall_result - """ - # Format context based on selected mode - if self.context_format == "structured": - context = self._format_context_structured(recall_result) - else: - context = self._format_context_json(recall_result) + Returns: + Tuple of (answer, reasoning, None) + - None indicates to use the memories from recall_result + """ + # Format context based on selected mode + if self.context_format == "structured": + context = self._format_context_structured(recall_result) + else: + context = self._format_context_json(recall_result) - context_instructions = self._get_context_instructions() + context_instructions = self._get_context_instructions() - # Format question date if provided - formatted_question_date = question_date.strftime('%Y-%m-%d %H:%M:%S UTC') if question_date else "Not specified" + # Format question date if provided + formatted_question_date = question_date.strftime("%Y-%m-%d %H:%M:%S UTC") if question_date else "Not specified" - # Use LLM to generate answer - try: - answer_obj = await self.llm_config.call( - messages=[ - { - "role": "user", - "content": f"""You are a helpful assistant that must answer user questions based on the previous conversations. + # Use LLM to generate answer + try: + answer_obj = await self.llm_config.call( + messages=[ + { + "role": "user", + "content": f"""You are a helpful assistant that must answer user questions based on the previous conversations. {context_instructions}**Answer Guidelines:** 1. Start by scanning retrieved context to understand the facts and events that happened and the timeline. @@ -393,20 +394,20 @@ Retrieved Context: Answer: -""" - } - ], - response_format=QuestionAnswer, - scope="memory", - max_completion_tokens=32768, - ) - reasoning_text = answer_obj.reasoning or "" - if reasoning_text: - reasoning_text = reasoning_text + " " - reasoning_text += f"(question date: {formatted_question_date})" - return answer_obj.answer, reasoning_text, None - except Exception as e: - return f"Error generating answer: {str(e)}", "Error occurred during answer generation.", None +""", + } + ], + response_format=QuestionAnswer, + scope="memory", + max_completion_tokens=32768, + ) + reasoning_text = answer_obj.reasoning or "" + if reasoning_text: + reasoning_text = reasoning_text + " " + reasoning_text += f"(question date: {formatted_question_date})" + return answer_obj.answer, reasoning_text, None + except Exception as e: + return f"Error generating answer: {str(e)}", "Error occurred during answer generation.", None async def run_benchmark( @@ -425,7 +426,7 @@ async def run_benchmark( max_concurrent_items: int = 1, results_filename: str = "benchmark_results.json", context_format: str = "json", - source_results: str = None + source_results: str = None, ): """ Run the LongMemEval benchmark. @@ -449,13 +450,16 @@ async def run_benchmark( source_results: Source results file to read failed/invalid questions from (for --only-failed/--only-invalid). Defaults to benchmark_results.json. """ from rich.console import Console + console = Console() # Validate mutually exclusive arguments # --max-instances-per-category can't be combined with --max-instances or --category # But --category CAN be combined with --max-instances (to limit questions within a category) if max_instances_per_category is not None and (max_instances is not None or category is not None): - console.print("[red]Error: --max-questions-per-category cannot be combined with --max-instances or --category[/red]") + console.print( + "[red]Error: --max-questions-per-category cannot be combined with --max-instances or --category[/red]" + ) return # Validate --only-ingested can't be combined with other dataset filters @@ -480,8 +484,10 @@ async def run_benchmark( dataset_path = Path(__file__).parent / "datasets" / "longmemeval_s_cleaned.json" if not dataset_path.exists(): if not download_dataset(dataset_path): - console.print(f"[red]Failed to download dataset. Please download manually:[/red]") - console.print("[yellow]curl -L 'https://huggingface.co/datasets/xiaowu0162/longmemeval-cleaned/resolve/main/longmemeval_s_cleaned.json' -o benchmarks/longmemeval/datasets/longmemeval_s_cleaned.json[/yellow]") + console.print("[red]Failed to download dataset. Please download manually:[/red]") + console.print( + "[yellow]curl -L 'https://huggingface.co/datasets/xiaowu0162/longmemeval-cleaned/resolve/main/longmemeval_s_cleaned.json' -o benchmarks/longmemeval/datasets/longmemeval_s_cleaned.json[/yellow]" + ) return # Initialize components @@ -499,9 +505,10 @@ async def run_benchmark( # Group by category and take max_instances_per_category from each from collections import defaultdict + category_items = defaultdict(list) for item in original_dataset_items: - cat = item.get('question_type', 'unknown') + cat = item.get("question_type", "unknown") category_items[cat].append(item) # Take up to max_instances_per_category from each category @@ -518,30 +525,34 @@ async def run_benchmark( invalid_question_ids = set() if only_failed or only_invalid: # Use source_results if specified, otherwise default to benchmark_results.json - source_file = source_results if source_results else 'benchmark_results.json' - results_path = Path(__file__).parent / 'results' / source_file + source_file = source_results if source_results else "benchmark_results.json" + results_path = Path(__file__).parent / "results" / source_file if not results_path.exists(): - console.print(f"[red]Error: Cannot use --only-failed or --only-invalid without existing results file[/red]") + console.print("[red]Error: Cannot use --only-failed or --only-invalid without existing results file[/red]") console.print(f"[yellow]Results file not found: {results_path}[/yellow]") return console.print(f"[cyan]Reading failed/invalid questions from: {source_file}[/cyan]") - with open(results_path, 'r') as f: + with open(results_path, "r") as f: previous_results = json.load(f) # Extract question IDs that failed or are invalid - for item_result in previous_results.get('item_results', []): - item_id = item_result['item_id'] - for detail in item_result['metrics'].get('detailed_results', []): - if only_failed and detail.get('is_correct') == False and not detail.get('is_invalid', False): + for item_result in previous_results.get("item_results", []): + item_id = item_result["item_id"] + for detail in item_result["metrics"].get("detailed_results", []): + if only_failed and detail.get("is_correct") == False and not detail.get("is_invalid", False): failed_question_ids.add(item_id) - if only_invalid and detail.get('is_invalid', False): + if only_invalid and detail.get("is_invalid", False): invalid_question_ids.add(item_id) if only_failed: - console.print(f"[cyan]Filtering to {len(failed_question_ids)} questions that failed (is_correct=False)[/cyan]") + console.print( + f"[cyan]Filtering to {len(failed_question_ids)} questions that failed (is_correct=False)[/cyan]" + ) if only_invalid: - console.print(f"[cyan]Filtering to {len(invalid_question_ids)} questions that were invalid (is_invalid=True)[/cyan]") + console.print( + f"[cyan]Filtering to {len(invalid_question_ids)} questions that were invalid (is_invalid=True)[/cyan]" + ) # Filter dataset by category if specified if category: @@ -550,11 +561,11 @@ async def run_benchmark( # Load full dataset without max_instances limit for filtering original_dataset_items = dataset.load(dataset_path, max_items=None) - filtered_items = [item for item in original_dataset_items if item.get('question_type') == category] + filtered_items = [item for item in original_dataset_items if item.get("question_type") == category] if not filtered_items: console.print(f"[yellow]No questions found for category '{category}'. Available categories:[/yellow]") - available_categories = set(item.get('question_type', 'unknown') for item in original_dataset_items) + available_categories = set(item.get("question_type", "unknown") for item in original_dataset_items) for cat in sorted(available_categories): console.print(f" - {cat}") return @@ -562,7 +573,9 @@ async def run_benchmark( total_found = len(filtered_items) will_run = min(total_found, max_instances) if max_instances else total_found if max_instances and total_found > max_instances: - console.print(f"[green]Found {total_found} questions for category '{category}' (will run {will_run} due to --max-instances)[/green]") + console.print( + f"[green]Found {total_found} questions for category '{category}' (will run {will_run} due to --max-instances)[/green]" + ) else: console.print(f"[green]Found {total_found} questions for category '{category}'[/green]") @@ -588,7 +601,9 @@ async def run_benchmark( total_found = len(filtered_items) will_run = min(total_found, max_instances) if max_instances else total_found if max_instances and total_found > max_instances: - console.print(f"[green]Found {total_found} {filter_type} items to re-evaluate (will run {will_run} due to --max-instances)[/green]") + console.print( + f"[green]Found {total_found} {filter_type} items to re-evaluate (will run {will_run} due to --max-instances)[/green]" + ) else: console.print(f"[green]Found {total_found} {filter_type} items to re-evaluate[/green]") @@ -600,6 +615,7 @@ async def run_benchmark( # Create local memory engine from benchmarks.common.benchmark_runner import create_memory_engine + memory = await create_memory_engine() # Filter by only_ingested: only run items whose memory bank already exists @@ -623,10 +639,9 @@ async def run_benchmark( # Check if bank has any memory units async with pool.acquire() as conn: result = await conn.fetchrow( - "SELECT COUNT(*) as count FROM memory_units WHERE bank_id = $1 LIMIT 1", - agent_id + "SELECT COUNT(*) as count FROM memory_units WHERE bank_id = $1 LIMIT 1", agent_id ) - if result['count'] > 0: + if result["count"] > 0: ingested_items.append(item) filtered_items = ingested_items @@ -638,34 +653,43 @@ async def run_benchmark( # Create benchmark runner runner = BenchmarkRunner( - dataset=dataset, - answer_generator=answer_generator, - answer_evaluator=answer_evaluator, - memory=memory + dataset=dataset, answer_generator=answer_generator, answer_evaluator=answer_evaluator, memory=memory ) # If filtering by category, failed, invalid, only_ingested, or max_instances_per_category, we need to use a custom dataset that only returns those items # We'll temporarily replace the dataset's load method if filtered_items is not None: original_load = dataset.load + def filtered_load(path: Path, max_items: Optional[int] = None): return filtered_items[:max_items] if max_items else filtered_items + dataset.load = filtered_load # Run benchmark # Single-phase approach: each question gets its own isolated agent_id # This ensures each question only has access to its own context - output_path = Path(__file__).parent / 'results' / results_filename + output_path = Path(__file__).parent / "results" / results_filename # Create results directory if it doesn't exist output_path.parent.mkdir(parents=True, exist_ok=True) - merge_with_existing = (filln or question_id is not None or only_failed or only_invalid or only_ingested or category is not None or max_instances_per_category is not None) + merge_with_existing = ( + filln + or question_id is not None + or only_failed + or only_invalid + or only_ingested + or category is not None + or max_instances_per_category is not None + ) results = await runner.run( dataset_path=dataset_path, agent_id="longmemeval", # Will be suffixed with question_id per item - max_items=max_instances if not max_instances_per_category else None, # Don't apply max_items when using per-category limit + max_items=max_instances + if not max_instances_per_category + else None, # Don't apply max_items when using per-category limit max_questions_per_item=max_questions_per_instance, thinking_budget=thinking_budget, max_tokens=max_tokens, @@ -678,7 +702,7 @@ async def run_benchmark( specific_item=question_id, # Optional filter for specific question ID max_concurrent_items=max_concurrent_items, # Parallel instance processing output_path=output_path, # Save results incrementally - merge_with_existing=merge_with_existing # Merge when using --fill, --category, --only-failed, --only-invalid flags or specific question + merge_with_existing=merge_with_existing, # Merge when using --fill, --category, --only-failed, --only-invalid flags or specific question ) # Display results (final save already happened incrementally) @@ -702,12 +726,14 @@ def download_dataset(dataset_path: Path) -> bool: True if successful, False otherwise """ import subprocess + from rich.console import Console + console = Console() url = "https://huggingface.co/datasets/xiaowu0162/longmemeval-cleaned/resolve/main/longmemeval_s_cleaned.json" - console.print(f"[yellow]Dataset not found. Downloading from HuggingFace...[/yellow]") + console.print("[yellow]Dataset not found. Downloading from HuggingFace...[/yellow]") console.print(f"[dim]URL: {url}[/dim]") console.print(f"[dim]Destination: {dataset_path}[/dim]") @@ -720,18 +746,18 @@ def download_dataset(dataset_path: Path) -> bool: ["curl", "-L", "-o", str(dataset_path), url], capture_output=True, text=True, - timeout=300 # 5 minute timeout + timeout=300, # 5 minute timeout ) if result.returncode == 0 and dataset_path.exists(): - console.print(f"[green]✓ Dataset downloaded successfully[/green]") + console.print("[green]✓ Dataset downloaded successfully[/green]") return True else: console.print(f"[red]✗ Download failed: {result.stderr}[/red]") return False except subprocess.TimeoutExpired: - console.print(f"[red]✗ Download timed out after 5 minutes[/red]") + console.print("[red]✗ Download timed out after 5 minutes[/red]") return False except Exception as e: console.print(f"[red]✗ Download error: {e}[/red]") @@ -740,22 +766,23 @@ def download_dataset(dataset_path: Path) -> bool: def generate_type_report(results: dict): """Generate a detailed report by question type.""" - from rich.table import Table from rich.console import Console + from rich.table import Table + console = Console() # Aggregate stats by question type type_stats = {} - for item_result in results['item_results']: - metrics = item_result['metrics'] - by_category = metrics.get('category_stats', {}) + for item_result in results["item_results"]: + metrics = item_result["metrics"] + by_category = metrics.get("category_stats", {}) for qtype, stats in by_category.items(): if qtype not in type_stats: - type_stats[qtype] = {'total': 0, 'correct': 0} - type_stats[qtype]['total'] += stats['total'] - type_stats[qtype]['correct'] += stats['correct'] + type_stats[qtype] = {"total": 0, "correct": 0} + type_stats[qtype]["total"] += stats["total"] + type_stats[qtype]["correct"] += stats["correct"] # Display table table = Table(title="Performance by Question Type") @@ -765,13 +792,8 @@ def generate_type_report(results: dict): table.add_column("Accuracy", justify="right", style="magenta") for qtype, stats in sorted(type_stats.items()): - acc = (stats['correct'] / stats['total'] * 100) if stats['total'] > 0 else 0 - table.add_row( - qtype, - str(stats['total']), - str(stats['correct']), - f"{acc:.1f}%" - ) + acc = (stats["correct"] / stats["total"] * 100) if stats["total"] > 0 else 0 + table.add_row(qtype, str(stats["total"]), str(stats["correct"]), f"{acc:.1f}%") console.print("\n") console.print(table) @@ -780,21 +802,22 @@ def generate_type_report(results: dict): def generate_markdown_table(results: dict, json_output_path: Path): """Generate a markdown results table with model configuration.""" from rich.console import Console + console = Console() # Aggregate stats by question type type_stats = {} - for item_result in results['item_results']: - metrics = item_result['metrics'] - by_category = metrics.get('category_stats', {}) + for item_result in results["item_results"]: + metrics = item_result["metrics"] + by_category = metrics.get("category_stats", {}) for qtype, stats in by_category.items(): if qtype not in type_stats: - type_stats[qtype] = {'total': 0, 'correct': 0, 'invalid': 0} - type_stats[qtype]['total'] += stats['total'] - type_stats[qtype]['correct'] += stats['correct'] - type_stats[qtype]['invalid'] += stats.get('invalid', 0) + type_stats[qtype] = {"total": 0, "correct": 0, "invalid": 0} + type_stats[qtype]["total"] += stats["total"] + type_stats[qtype]["correct"] += stats["correct"] + type_stats[qtype]["invalid"] += stats.get("invalid", 0) # Build markdown content lines = [] @@ -802,16 +825,20 @@ def generate_markdown_table(results: dict, json_output_path: Path): lines.append("") # Add model configuration - if 'model_config' in results: - config = results['model_config'] + if "model_config" in results: + config = results["model_config"] lines.append("## Model Configuration") lines.append("") lines.append(f"- **Hindsight**: {config['hindsight']['provider']}/{config['hindsight']['model']}") - lines.append(f"- **Answer Generation**: {config['answer_generation']['provider']}/{config['answer_generation']['model']}") + lines.append( + f"- **Answer Generation**: {config['answer_generation']['provider']}/{config['answer_generation']['model']}" + ) lines.append(f"- **LLM Judge**: {config['judge']['provider']}/{config['judge']['model']}") lines.append("") - lines.append(f"**Overall Accuracy**: {results['overall_accuracy']:.2f}% ({results['total_correct']}/{results['total_questions']})") + lines.append( + f"**Overall Accuracy**: {results['overall_accuracy']:.2f}% ({results['total_correct']}/{results['total_questions']})" + ) lines.append("") # Results by question type @@ -822,34 +849,36 @@ def generate_markdown_table(results: dict, json_output_path: Path): for qtype in sorted(type_stats.keys()): stats = type_stats[qtype] - valid_total = stats['total'] - stats['invalid'] - acc = (stats['correct'] / valid_total * 100) if valid_total > 0 else 0 - invalid_str = str(stats['invalid']) if stats['invalid'] > 0 else "-" + valid_total = stats["total"] - stats["invalid"] + acc = (stats["correct"] / valid_total * 100) if valid_total > 0 else 0 + invalid_str = str(stats["invalid"]) if stats["invalid"] > 0 else "-" lines.append(f"| {qtype} | {stats['total']} | {stats['correct']} | {invalid_str} | {acc:.1f}% |") # Add overall row - total_invalid = results.get('total_invalid', 0) + total_invalid = results.get("total_invalid", 0) invalid_str = str(total_invalid) if total_invalid > 0 else "-" - lines.append(f"| **OVERALL** | **{results['total_questions']}** | **{results['total_correct']}** | **{invalid_str}** | **{results['overall_accuracy']:.1f}%** |") + lines.append( + f"| **OVERALL** | **{results['total_questions']}** | **{results['total_correct']}** | **{invalid_str}** | **{results['overall_accuracy']:.1f}%** |" + ) # Write to file (same directory as JSON, but .md extension) - md_output_path = json_output_path.with_suffix('.md') - md_output_path.write_text('\n'.join(lines)) + md_output_path = json_output_path.with_suffix(".md") + md_output_path.write_text("\n".join(lines)) console.print(f"\n[green]✓[/green] Results table saved to {md_output_path}") if __name__ == "__main__": - import logging import argparse + import logging - logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s') + logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s") parser = argparse.ArgumentParser(description="Run LongMemEval benchmark") parser.add_argument( "--max-instances", type=int, default=None, - help="Limit TOTAL number of questions to evaluate (default: all 500). For per-category limits, use --max-questions-per-category instead." + help="Limit TOTAL number of questions to evaluate (default: all 500). For per-category limits, use --max-questions-per-category instead.", ) parser.add_argument( "--max-instances-per-category", @@ -857,87 +886,72 @@ if __name__ == "__main__": type=int, default=None, dest="max_instances_per_category", - help="Limit number of questions per category (e.g., 20 = 20 questions from each of the 6 categories = 120 total). Cannot be combined with --max-instances or --category." + help="Limit number of questions per category (e.g., 20 = 20 questions from each of the 6 categories = 120 total). Cannot be combined with --max-instances or --category.", ) parser.add_argument( - "--max-questions", - type=int, - default=None, - help="Limit number of questions per instance (for quick testing)" + "--max-questions", type=int, default=None, help="Limit number of questions per instance (for quick testing)" ) parser.add_argument( - "--thinking-budget", - type=int, - default=500, - help="Thinking budget for spreading activation search" - ) - parser.add_argument( - "--max-tokens", - type=int, - default=8192, - help="Maximum tokens to retrieve from memories" - ) - parser.add_argument( - "--skip-ingestion", - action="store_true", - help="Skip ingestion and use existing data" + "--thinking-budget", type=int, default=500, help="Thinking budget for spreading activation search" ) + parser.add_argument("--max-tokens", type=int, default=8192, help="Maximum tokens to retrieve from memories") + parser.add_argument("--skip-ingestion", action="store_true", help="Skip ingestion and use existing data") parser.add_argument( "--fill", action="store_true", - help="Only process questions not already in results file (for resuming interrupted runs)" + help="Only process questions not already in results file (for resuming interrupted runs)", ) parser.add_argument( "--question-id", type=str, default=None, - help="Filter to specific question ID (e.g., 'e47becba'). Useful with --skip-ingestion to test a single question." + help="Filter to specific question ID (e.g., 'e47becba'). Useful with --skip-ingestion to test a single question.", ) parser.add_argument( "--only-failed", action="store_true", - help="Only run questions that were previously marked as incorrect (is_correct=False). Requires existing results file." + help="Only run questions that were previously marked as incorrect (is_correct=False). Requires existing results file.", ) parser.add_argument( "--only-invalid", action="store_true", - help="Only run questions that were previously marked as invalid (is_invalid=True). Requires existing results file." + help="Only run questions that were previously marked as invalid (is_invalid=True). Requires existing results file.", ) parser.add_argument( "--only-ingested", action="store_true", - help="Only run questions whose memory bank already exists (has been ingested). Automatically skips ingestion. Cannot be combined with --only-failed, --only-invalid, --category, --question-id, or --max-instances-per-category." + help="Only run questions whose memory bank already exists (has been ingested). Automatically skips ingestion. Cannot be combined with --only-failed, --only-invalid, --category, --question-id, or --max-instances-per-category.", ) parser.add_argument( "--category", type=str, default=None, - help="Filter questions by category/question_type. Available categories: 'single-session-user', 'multi-session', 'single-session-preference', 'temporal-reasoning', 'knowledge-update', 'single-session-assistant'. Can be combined with --max-instances to limit questions within the category." + help="Filter questions by category/question_type. Available categories: 'single-session-user', 'multi-session', 'single-session-preference', 'temporal-reasoning', 'knowledge-update', 'single-session-assistant'. Can be combined with --max-instances to limit questions within the category.", ) parser.add_argument( "--parallel", type=int, default=1, - help="Number of instances to process in parallel (default: 1 for sequential). Higher values speed up evaluation but use more memory." + help="Number of instances to process in parallel (default: 1 for sequential). Higher values speed up evaluation but use more memory.", ) parser.add_argument( "--results-filename", type=str, default="benchmark_results.json", - help="Filename for results output (default: benchmark_results.json). Saved in results/ directory." + help="Filename for results output (default: benchmark_results.json). Saved in results/ directory.", ) parser.add_argument( "--context-format", type=str, choices=["json", "structured"], default="json", - help="How to format context for answer generation. 'json' (raw JSON dump, original behavior) or 'structured' (human-readable format with facts grouped with source chunks). Default: json." + help="How to format context for answer generation. 'json' (raw JSON dump, original behavior) or 'structured' (human-readable format with facts grouped with source chunks). Default: json.", ) parser.add_argument( "--source-results", type=str, default=None, - help="Source results file to read failed/invalid questions from (for --only-failed/--only-invalid). Defaults to benchmark_results.json if not specified." + help="Source results file to read failed/invalid questions from (for --only-failed/--only-invalid). Defaults to benchmark_results.json if not specified.", ) args = parser.parse_args() @@ -951,21 +965,23 @@ if __name__ == "__main__": if args.max_instances_per_category is not None and (args.max_instances is not None or args.category is not None): parser.error("--max-questions-per-category cannot be combined with --max-instances or --category") - results = asyncio.run(run_benchmark( - max_instances=args.max_instances, - max_instances_per_category=args.max_instances_per_category, - max_questions_per_instance=args.max_questions, - thinking_budget=args.thinking_budget, - max_tokens=args.max_tokens, - skip_ingestion=args.skip_ingestion, - filln=args.fill, - question_id=args.question_id, - only_failed=args.only_failed, - only_invalid=args.only_invalid, - only_ingested=args.only_ingested, - category=args.category, - max_concurrent_items=args.parallel, - results_filename=args.results_filename, - context_format=args.context_format, - source_results=args.source_results - )) + results = asyncio.run( + run_benchmark( + max_instances=args.max_instances, + max_instances_per_category=args.max_instances_per_category, + max_questions_per_instance=args.max_questions, + thinking_budget=args.thinking_budget, + max_tokens=args.max_tokens, + skip_ingestion=args.skip_ingestion, + filln=args.fill, + question_id=args.question_id, + only_failed=args.only_failed, + only_invalid=args.only_invalid, + only_ingested=args.only_ingested, + category=args.category, + max_concurrent_items=args.parallel, + results_filename=args.results_filename, + context_format=args.context_format, + source_results=args.source_results, + ) + ) diff --git a/hindsight-dev/benchmarks/visualizer/main.py b/hindsight-dev/benchmarks/visualizer/main.py index dc955a92..184a7bb2 100644 --- a/hindsight-dev/benchmarks/visualizer/main.py +++ b/hindsight-dev/benchmarks/visualizer/main.py @@ -16,6 +16,7 @@ from fasthtml.common import * # Get the benchmarks directory BENCHMARKS_DIR = Path(__file__).resolve().parent.parent + # Tailwind + shadcn/ui theme def get_head(): return ( @@ -72,9 +73,10 @@ def get_head(): color: hsl(222.2 84% 4.9%); } } - """) + """), ) + # Create FastHTML app app, rt = fast_app() @@ -113,12 +115,7 @@ def get_category_name(category: int | str) -> str: if isinstance(category, str): return category - categories = { - 1: "Multi-hop", - 2: "Single-hop", - 3: "Temporal", - 4: "Open-domain" - } + categories = {1: "Multi-hop", 2: "Single-hop", 3: "Temporal", 4: "Open-domain"} return categories.get(category, "Unknown") @@ -132,7 +129,7 @@ def get(): Div( H1("📊 Benchmark Visualizer", cls="text-4xl font-bold text-foreground"), P("Analyze and visualize benchmark results", cls="text-muted-foreground mt-2"), - cls="text-center py-12" + cls="text-center py-12", ), Div( Label("Select a benchmark to view:", cls="block text-sm font-medium text-foreground mb-2"), @@ -142,12 +139,12 @@ def get(): Option("LoComo (think mode)", value="/locomo/think"), Option("LongMemEval", value="/longmemeval"), onchange="if(this.value) window.location.href = this.value;", - cls="w-full px-3 py-2 border border-input rounded-md bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-ring" + cls="w-full px-3 py-2 border border-input rounded-md bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-ring", ), - cls="max-w-md mx-auto bg-white border border-border rounded-lg p-6 shadow-sm" + cls="max-w-md mx-auto bg-white border border-border rounded-lg p-6 shadow-sm", ), - cls="container mx-auto max-w-7xl px-4 py-8" - ) + cls="container mx-auto max-w-7xl px-4 py-8", + ), ) @@ -166,10 +163,17 @@ def get_locomo(mode: str, filter_type: str = "all", category_filter: str = "all" H1("⚠️ Benchmark Results Not Found", cls="text-3xl font-bold text-foreground mb-4"), P(f"The {mode_label} mode results are not available.", cls="text-muted-foreground mb-6"), H4("To generate results:", cls="text-lg font-semibold text-foreground mb-2"), - Pre(f"./scripts/benchmarks/run-locomo.sh --env local{extra_args}", cls="bg-slate-900 text-slate-100 p-4 rounded-md overflow-x-auto text-sm"), - A("← Back", href="/", cls="inline-flex items-center mt-6 px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90 text-sm font-medium"), - cls="container mx-auto max-w-7xl px-4 py-8" - ) + Pre( + f"./scripts/benchmarks/run-locomo.sh --env local{extra_args}", + cls="bg-slate-900 text-slate-100 p-4 rounded-md overflow-x-auto text-sm", + ), + A( + "← Back", + href="/", + cls="inline-flex items-center mt-6 px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90 text-sm font-medium", + ), + cls="container mx-auto max-w-7xl px-4 py-8", + ), ) all_results = data.get("item_results", data.get("conversation_results", [])) @@ -185,10 +189,14 @@ def get_locomo(mode: str, filter_type: str = "all", category_filter: str = "all" passes_correctness_filter = True elif filter_type == "correct": # Show items where all questions are correct (and not invalid) - passes_correctness_filter = detailed_results and all(r.get("is_correct") and not r.get("is_invalid") for r in detailed_results) + passes_correctness_filter = detailed_results and all( + r.get("is_correct") and not r.get("is_invalid") for r in detailed_results + ) elif filter_type == "incorrect": # Show items that have at least one incorrect question - passes_correctness_filter = any(not r.get("is_correct") and not r.get("is_invalid") for r in detailed_results) + passes_correctness_filter = any( + not r.get("is_correct") and not r.get("is_invalid") for r in detailed_results + ) elif filter_type == "invalid": # Show items that have at least one invalid question passes_correctness_filter = any(r.get("is_invalid") for r in detailed_results) @@ -210,7 +218,7 @@ def get_locomo(mode: str, filter_type: str = "all", category_filter: str = "all" 1: {"name": "Multi-hop", "correct": 0, "total": 0, "invalid": 0}, 2: {"name": "Single-hop", "correct": 0, "total": 0, "invalid": 0}, 3: {"name": "Temporal", "correct": 0, "total": 0, "invalid": 0}, - 4: {"name": "Open-domain", "correct": 0, "total": 0, "invalid": 0} + 4: {"name": "Open-domain", "correct": 0, "total": 0, "invalid": 0}, } total_invalid = 0 @@ -235,38 +243,43 @@ def get_locomo(mode: str, filter_type: str = "all", category_filter: str = "all" Div( P("Overall Accuracy", cls="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2"), P(f"{data['overall_accuracy']:.2f}%", cls="text-3xl font-bold text-foreground"), - cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm" + cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm", ), Div( P("Correct Answers", cls="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2"), P(f"{data['total_correct']} / {data['total_questions']}", cls="text-3xl font-bold text-foreground"), - cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm" + cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm", ), Div( P("Invalid Questions", cls="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2"), P(str(total_invalid), cls="text-3xl font-bold text-foreground"), - cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm" - ) if total_invalid > 0 else None, + cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm", + ) + if total_invalid > 0 + else None, Div( P("Items", cls="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2"), P(str(len(all_results)), cls="text-3xl font-bold text-foreground"), - cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm" + cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm", ), - cls="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-8" + cls="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-8", ), H4("Accuracy by Category", cls="text-xl font-semibold text-foreground mb-4"), Div( *[ Div( P(cat["name"], cls="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2"), - P(f"{(cat['correct'] / (cat['total'] - cat['invalid']) * 100) if (cat['total'] - cat['invalid']) > 0 else 0:.1f}%", cls="text-2xl font-bold text-foreground"), + P( + f"{(cat['correct'] / (cat['total'] - cat['invalid']) * 100) if (cat['total'] - cat['invalid']) > 0 else 0:.1f}%", + cls="text-2xl font-bold text-foreground", + ), P(f"{cat['correct']} / {cat['total']}", cls="text-sm text-muted-foreground mt-1"), - cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm" + cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm", ) for cat in category_stats.values() ], - cls="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4" - ) + cls="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4", + ), ) # Filter controls @@ -275,37 +288,111 @@ def get_locomo(mode: str, filter_type: str = "all", category_filter: str = "all" Div( P("Filter by correctness:", cls="text-sm font-medium text-foreground mb-2"), Div( - A("All", href=f"/locomo/{mode}?filter_type=all&category_filter={category_filter}", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if filter_type == 'all' else "bg-white text-foreground border border-border hover:bg-accent")), - A("✅ All Correct", href=f"/locomo/{mode}?filter_type=correct&category_filter={category_filter}", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if filter_type == 'correct' else "bg-white text-foreground border border-border hover:bg-accent")), - A("❌ Has Incorrect", href=f"/locomo/{mode}?filter_type=incorrect&category_filter={category_filter}", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if filter_type == 'incorrect' else "bg-white text-foreground border border-border hover:bg-accent")), - A("⚠️ Has Invalid", href=f"/locomo/{mode}?filter_type=invalid&category_filter={category_filter}", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if filter_type == 'invalid' else "bg-white text-foreground border border-border hover:bg-accent")) if total_invalid > 0 else None, - cls="flex flex-wrap gap-2" + A( + "All", + href=f"/locomo/{mode}?filter_type=all&category_filter={category_filter}", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if filter_type == "all" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + A( + "✅ All Correct", + href=f"/locomo/{mode}?filter_type=correct&category_filter={category_filter}", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if filter_type == "correct" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + A( + "❌ Has Incorrect", + href=f"/locomo/{mode}?filter_type=incorrect&category_filter={category_filter}", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if filter_type == "incorrect" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + A( + "⚠️ Has Invalid", + href=f"/locomo/{mode}?filter_type=invalid&category_filter={category_filter}", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if filter_type == "invalid" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ) + if total_invalid > 0 + else None, + cls="flex flex-wrap gap-2", ), - cls="mb-4" + cls="mb-4", ), # Category filter Div( P("Filter by question category:", cls="text-sm font-medium text-foreground mb-2"), Div( - A("All Categories", href=f"/locomo/{mode}?filter_type={filter_type}&category_filter=all", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if category_filter == 'all' else "bg-white text-foreground border border-border hover:bg-accent")), - A("Multi-hop", href=f"/locomo/{mode}?filter_type={filter_type}&category_filter=1", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if category_filter == '1' else "bg-white text-foreground border border-border hover:bg-accent")), - A("Single-hop", href=f"/locomo/{mode}?filter_type={filter_type}&category_filter=2", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if category_filter == '2' else "bg-white text-foreground border border-border hover:bg-accent")), - A("Temporal", href=f"/locomo/{mode}?filter_type={filter_type}&category_filter=3", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if category_filter == '3' else "bg-white text-foreground border border-border hover:bg-accent")), - A("Open-domain", href=f"/locomo/{mode}?filter_type={filter_type}&category_filter=4", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if category_filter == '4' else "bg-white text-foreground border border-border hover:bg-accent")), - cls="flex flex-wrap gap-2" + A( + "All Categories", + href=f"/locomo/{mode}?filter_type={filter_type}&category_filter=all", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if category_filter == "all" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + A( + "Multi-hop", + href=f"/locomo/{mode}?filter_type={filter_type}&category_filter=1", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if category_filter == "1" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + A( + "Single-hop", + href=f"/locomo/{mode}?filter_type={filter_type}&category_filter=2", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if category_filter == "2" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + A( + "Temporal", + href=f"/locomo/{mode}?filter_type={filter_type}&category_filter=3", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if category_filter == "3" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + A( + "Open-domain", + href=f"/locomo/{mode}?filter_type={filter_type}&category_filter=4", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if category_filter == "4" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + cls="flex flex-wrap gap-2", ), - cls="mb-4" + cls="mb-4", ), - cls="mb-6" + cls="mb-6", ) # Render items @@ -320,8 +407,14 @@ def get_locomo(mode: str, filter_type: str = "all", category_filter: str = "all" if category_filter != "all": detailed_results = metrics.get("detailed_results", []) category_id = int(category_filter) - filtered_correct = sum(1 for r in detailed_results if r.get("category") == category_id and r.get("is_correct") and not r.get("is_invalid")) - filtered_total = sum(1 for r in detailed_results if r.get("category") == category_id and not r.get("is_invalid")) + filtered_correct = sum( + 1 + for r in detailed_results + if r.get("category") == category_id and r.get("is_correct") and not r.get("is_invalid") + ) + filtered_total = sum( + 1 for r in detailed_results if r.get("category") == category_id and not r.get("is_invalid") + ) accuracy = (filtered_correct / filtered_total * 100) if filtered_total > 0 else 0 correct = filtered_correct total = filtered_total @@ -353,21 +446,21 @@ def get_locomo(mode: str, filter_type: str = "all", category_filter: str = "all" Div( P("Accuracy", cls="text-xs font-medium text-muted-foreground uppercase tracking-wide"), P(f"{accuracy:.1f}%", cls="text-2xl font-bold text-foreground"), - cls="text-center" + cls="text-center", ), Div( P("Correct", cls="text-xs font-medium text-muted-foreground uppercase tracking-wide"), P(f"{correct}/{total}", cls="text-xl font-semibold text-foreground"), - cls="text-center" + cls="text-center", ), - cls="flex gap-6 items-center" + cls="flex gap-6 items-center", ), - cls="p-6" + cls="p-6", ), - cls=f"bg-white border border-border rounded-lg shadow-sm transition-all {border_class} {bg_class}" + cls=f"bg-white border border-border rounded-lg shadow-sm transition-all {border_class} {bg_class}", ), href=f"/locomo/{mode}/item/{original_idx}?filter_type={filter_type}&category_filter={category_filter}", - cls="block no-underline" + cls="block no-underline", ) ) @@ -376,18 +469,19 @@ def get_locomo(mode: str, filter_type: str = "all", category_filter: str = "all" get_head(), Main( Div( - A("← Back to benchmarks", href="/", cls="inline-flex items-center px-4 py-2 bg-white border border-border rounded-md text-sm font-medium text-foreground hover:bg-accent mb-6"), + A( + "← Back to benchmarks", + href="/", + cls="inline-flex items-center px-4 py-2 bg-white border border-border rounded-md text-sm font-medium text-foreground hover:bg-accent mb-6", + ), stats_html, Hr(cls="my-6 border-border"), filters, P(f"Showing {len(results)} of {len(all_results)} items", cls="text-sm text-muted-foreground mb-6"), - Div( - *items_html, - cls="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4" - ), - cls="container mx-auto max-w-7xl px-4 py-8" + Div(*items_html, cls="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"), + cls="container mx-auto max-w-7xl px-4 py-8", ) - ) + ), ) @@ -445,7 +539,7 @@ def get_locomo_item(mode: str, item_idx: int, filter_type: str = "all", category 1: {"name": "Multi-hop", "correct": 0, "total": 0, "invalid": 0}, 2: {"name": "Single-hop", "correct": 0, "total": 0, "invalid": 0}, 3: {"name": "Temporal", "correct": 0, "total": 0, "invalid": 0}, - 4: {"name": "Open-domain", "correct": 0, "total": 0, "invalid": 0} + 4: {"name": "Open-domain", "correct": 0, "total": 0, "invalid": 0}, } for cat_id_str, stats in category_stats_raw.items(): @@ -463,51 +557,61 @@ def get_locomo_item(mode: str, item_idx: int, filter_type: str = "all", category Div( P("Overall Accuracy", cls="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2"), P(f"{accuracy:.2f}%", cls="text-3xl font-bold text-foreground"), - cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm" + cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm", ), Div( P("Correct Answers", cls="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2"), P(f"{correct} / {total}", cls="text-3xl font-bold text-foreground"), - cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm" + cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm", ), Div( P("Invalid Questions", cls="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2"), P(str(invalid), cls="text-3xl font-bold text-foreground"), - cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm" - ) if invalid > 0 else None, + cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm", + ) + if invalid > 0 + else None, Div( P("Total Questions", cls="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2"), P(str(total), cls="text-3xl font-bold text-foreground"), - cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm" + cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm", ), - cls="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-8" + cls="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-8", ), H4("Accuracy by Category", cls="text-xl font-semibold text-foreground mb-4"), Div( *[ Div( P(cat["name"], cls="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2"), - P(f"{(cat['correct'] / (cat['total'] - cat['invalid']) * 100) if (cat['total'] - cat['invalid']) > 0 else 0:.1f}%", cls="text-2xl font-bold text-foreground"), + P( + f"{(cat['correct'] / (cat['total'] - cat['invalid']) * 100) if (cat['total'] - cat['invalid']) > 0 else 0:.1f}%", + cls="text-2xl font-bold text-foreground", + ), P(f"{cat['correct']} / {cat['total']}", cls="text-sm text-muted-foreground mt-1"), - cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm" + cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm", ) - for cat in category_stats.values() if cat['total'] > 0 + for cat in category_stats.values() + if cat["total"] > 0 ], - cls="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4" - ) if any(cat['total'] > 0 for cat in category_stats.values()) else None, - cls="mb-6" + cls="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4", + ) + if any(cat["total"] > 0 for cat in category_stats.values()) + else None, + cls="mb-6", ) # Generate markdown table for copying markdown_rows = [f"| {item_id} | {accuracy:.1f}% |"] for cat in category_stats.values(): - if cat['total'] > 0: - cat_accuracy = (cat['correct'] / (cat['total'] - cat['invalid']) * 100) if (cat['total'] - cat['invalid']) > 0 else 0 + if cat["total"] > 0: + cat_accuracy = ( + (cat["correct"] / (cat["total"] - cat["invalid"]) * 100) if (cat["total"] - cat["invalid"]) > 0 else 0 + ) markdown_rows.append(f" {cat_accuracy:.1f}% |") - markdown_table = f"""| Conversation | Overall |{' | '.join([cat['name'] for cat in category_stats.values() if cat['total'] > 0])} | -|---|---|{' | '.join(['---' for cat in category_stats.values() if cat['total'] > 0])} | -{''.join(markdown_rows)}""" + markdown_table = f"""| Conversation | Overall |{" | ".join([cat["name"] for cat in category_stats.values() if cat["total"] > 0])} | +|---|---|{" | ".join(["---" for cat in category_stats.values() if cat["total"] > 0])} | +{"".join(markdown_rows)}""" # Copy button copy_button = Div( @@ -519,9 +623,9 @@ def get_locomo_item(mode: str, item_idx: int, filter_type: str = "all", category setTimeout(() => {{ this.textContent = '📋 Copy Stats Table'; }}, 2000); }}); """, - cls="px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90 text-sm font-medium cursor-pointer" + cls="px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90 text-sm font-medium cursor-pointer", ), - cls="mb-6" + cls="mb-6", ) # Filters for questions @@ -531,37 +635,119 @@ def get_locomo_item(mode: str, item_idx: int, filter_type: str = "all", category Div( P("Filter by correctness:", cls="text-sm font-medium text-foreground mb-2"), Div( - A("All", href=f"/locomo/{mode}/item/{item_idx}?filter_type=all&category_filter={category_filter}", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if filter_type == 'all' else "bg-white text-foreground border border-border hover:bg-accent")), - A("✅ Correct", href=f"/locomo/{mode}/item/{item_idx}?filter_type=correct&category_filter={category_filter}", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if filter_type == 'correct' else "bg-white text-foreground border border-border hover:bg-accent")), - A("❌ Incorrect", href=f"/locomo/{mode}/item/{item_idx}?filter_type=incorrect&category_filter={category_filter}", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if filter_type == 'incorrect' else "bg-white text-foreground border border-border hover:bg-accent")), - A("⚠️ Invalid", href=f"/locomo/{mode}/item/{item_idx}?filter_type=invalid&category_filter={category_filter}", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if filter_type == 'invalid' else "bg-white text-foreground border border-border hover:bg-accent")) if has_invalid else None, - cls="flex flex-wrap gap-2" + A( + "All", + href=f"/locomo/{mode}/item/{item_idx}?filter_type=all&category_filter={category_filter}", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if filter_type == "all" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + A( + "✅ Correct", + href=f"/locomo/{mode}/item/{item_idx}?filter_type=correct&category_filter={category_filter}", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if filter_type == "correct" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + A( + "❌ Incorrect", + href=f"/locomo/{mode}/item/{item_idx}?filter_type=incorrect&category_filter={category_filter}", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if filter_type == "incorrect" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + A( + "⚠️ Invalid", + href=f"/locomo/{mode}/item/{item_idx}?filter_type=invalid&category_filter={category_filter}", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if filter_type == "invalid" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ) + if has_invalid + else None, + cls="flex flex-wrap gap-2", ), - cls="mb-4" + cls="mb-4", ), # Category filter Div( P("Filter by category:", cls="text-sm font-medium text-foreground mb-2"), Div( - A("All Categories", href=f"/locomo/{mode}/item/{item_idx}?filter_type={filter_type}&category_filter=all", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if category_filter == 'all' else "bg-white text-foreground border border-border hover:bg-accent")), - A("Multi-hop", href=f"/locomo/{mode}/item/{item_idx}?filter_type={filter_type}&category_filter=1", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if category_filter == '1' else "bg-white text-foreground border border-border hover:bg-accent")) if any(cat_id == 1 for cat_id in category_stats.keys() if category_stats[cat_id]['total'] > 0) else None, - A("Single-hop", href=f"/locomo/{mode}/item/{item_idx}?filter_type={filter_type}&category_filter=2", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if category_filter == '2' else "bg-white text-foreground border border-border hover:bg-accent")) if any(cat_id == 2 for cat_id in category_stats.keys() if category_stats[cat_id]['total'] > 0) else None, - A("Temporal", href=f"/locomo/{mode}/item/{item_idx}?filter_type={filter_type}&category_filter=3", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if category_filter == '3' else "bg-white text-foreground border border-border hover:bg-accent")) if any(cat_id == 3 for cat_id in category_stats.keys() if category_stats[cat_id]['total'] > 0) else None, - A("Open-domain", href=f"/locomo/{mode}/item/{item_idx}?filter_type={filter_type}&category_filter=4", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if category_filter == '4' else "bg-white text-foreground border border-border hover:bg-accent")) if any(cat_id == 4 for cat_id in category_stats.keys() if category_stats[cat_id]['total'] > 0) else None, - cls="flex flex-wrap gap-2" + A( + "All Categories", + href=f"/locomo/{mode}/item/{item_idx}?filter_type={filter_type}&category_filter=all", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if category_filter == "all" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + A( + "Multi-hop", + href=f"/locomo/{mode}/item/{item_idx}?filter_type={filter_type}&category_filter=1", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if category_filter == "1" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ) + if any(cat_id == 1 for cat_id in category_stats.keys() if category_stats[cat_id]["total"] > 0) + else None, + A( + "Single-hop", + href=f"/locomo/{mode}/item/{item_idx}?filter_type={filter_type}&category_filter=2", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if category_filter == "2" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ) + if any(cat_id == 2 for cat_id in category_stats.keys() if category_stats[cat_id]["total"] > 0) + else None, + A( + "Temporal", + href=f"/locomo/{mode}/item/{item_idx}?filter_type={filter_type}&category_filter=3", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if category_filter == "3" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ) + if any(cat_id == 3 for cat_id in category_stats.keys() if category_stats[cat_id]["total"] > 0) + else None, + A( + "Open-domain", + href=f"/locomo/{mode}/item/{item_idx}?filter_type={filter_type}&category_filter=4", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if category_filter == "4" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ) + if any(cat_id == 4 for cat_id in category_stats.keys() if category_stats[cat_id]["total"] > 0) + else None, + cls="flex flex-wrap gap-2", ), - cls="mb-4" + cls="mb-4", ), - cls="mb-6" + cls="mb-6", ) # Render questions @@ -575,7 +761,11 @@ def get_locomo_item(mode: str, item_idx: int, filter_type: str = "all", category category = get_category_name(result.get("category", "Unknown")) icon = "⚠️" if is_invalid else ("✅" if is_correct else "❌") - border_class = "border-l-4 border-yellow-500" if is_invalid else ("border-l-4 border-green-600" if is_correct else "border-l-4 border-red-600") + border_class = ( + "border-l-4 border-yellow-500" + if is_invalid + else ("border-l-4 border-green-600" if is_correct else "border-l-4 border-red-600") + ) questions_html.append( Div( @@ -583,75 +773,106 @@ def get_locomo_item(mode: str, item_idx: int, filter_type: str = "all", category Div( P(f"{icon} Question {q_idx + 1}", cls="text-lg font-semibold text-foreground"), P(f"Category: {category}", cls="text-sm text-muted-foreground"), - cls="mb-4" + cls="mb-4", ), - # Question Div( P("Question:", cls="text-sm font-medium text-foreground mb-1"), P(question, cls="text-foreground"), - cls="mb-4" + cls="mb-4", ), - # Answers side by side Div( Div( P("✓ Correct Answer", cls="text-sm font-medium text-foreground mb-2"), Div(correct_answer, cls="bg-green-50 border border-green-200 rounded-md p-3 text-foreground"), - cls="flex-1" + cls="flex-1", ), Div( - P(f"{'✓' if is_correct else '✗'} Predicted Answer", cls="text-sm font-medium text-foreground mb-2"), - Div(predicted_answer, cls=f"border rounded-md p-3 text-foreground " + ("bg-green-50 border-green-200" if is_correct else "bg-red-50 border-red-200")), - cls="flex-1" + P( + f"{'✓' if is_correct else '✗'} Predicted Answer", + cls="text-sm font-medium text-foreground mb-2", + ), + Div( + predicted_answer, + cls="border rounded-md p-3 text-foreground " + + ("bg-green-50 border-green-200" if is_correct else "bg-red-50 border-red-200"), + ), + cls="flex-1", ), - cls="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4" + cls="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4", ), - # Details Details( - Summary("📝 Show Reasoning & Retrieved Memories", cls="cursor-pointer font-medium text-foreground hover:text-primary py-2"), + Summary( + "📝 Show Reasoning & Retrieved Memories", + cls="cursor-pointer font-medium text-foreground hover:text-primary py-2", + ), Div( # System Reasoning Div( P("System Reasoning:", cls="text-sm font-medium text-foreground mb-2"), - Pre(result.get("reasoning", "N/A"), cls="bg-slate-900 text-slate-100 p-3 rounded-md overflow-x-auto text-sm"), - cls="mb-4" + Pre( + result.get("reasoning", "N/A"), + cls="bg-slate-900 text-slate-100 p-3 rounded-md overflow-x-auto text-sm", + ), + cls="mb-4", ), # Judge Reasoning Div( P("Judge Reasoning:", cls="text-sm font-medium text-foreground mb-2"), - Pre(result.get("correctness_reasoning", "N/A"), cls="bg-slate-900 text-slate-100 p-3 rounded-md overflow-x-auto text-sm"), - cls="mb-4" + Pre( + result.get("correctness_reasoning", "N/A"), + cls="bg-slate-900 text-slate-100 p-3 rounded-md overflow-x-auto text-sm", + ), + cls="mb-4", ), # Retrieved Memories Div( - P(f"Retrieved Memories ({len(result.get('retrieved_memories', []))}):", cls="text-sm font-medium text-foreground mb-2"), + P( + f"Retrieved Memories ({len(result.get('retrieved_memories', []))}):", + cls="text-sm font-medium text-foreground mb-2", + ), *[ Div( P( - f"#{i+1} • " + - " • ".join(filter(None, [ - f"Occurred: {mem.get('occurred_start', '')[:10]}" + - (f" to {mem.get('occurred_end', '')[:10]}" if mem.get('occurred_end') and mem.get('occurred_start', '')[:10] != mem.get('occurred_end', '')[:10] else "") - if mem.get('occurred_start') else None, - f"Mentioned: {mem.get('mentioned_at', '')[:10]}" if mem.get('mentioned_at') else None, - f"Type: {mem.get('fact_type', 'unknown').upper()}" - ])), - cls="text-xs text-muted-foreground mb-1" + f"#{i + 1} • " + + " • ".join( + filter( + None, + [ + f"Occurred: {mem.get('occurred_start', '')[:10]}" + + ( + f" to {mem.get('occurred_end', '')[:10]}" + if mem.get("occurred_end") + and mem.get("occurred_start", "")[:10] + != mem.get("occurred_end", "")[:10] + else "" + ) + if mem.get("occurred_start") + else None, + f"Mentioned: {mem.get('mentioned_at', '')[:10]}" + if mem.get("mentioned_at") + else None, + f"Type: {mem.get('fact_type', 'unknown').upper()}", + ], + ) + ), + cls="text-xs text-muted-foreground mb-1", ), - P(mem.get('text', ''), cls="text-sm text-foreground"), - cls="bg-muted/50 border border-border rounded-md p-3 mb-2" + P(mem.get("text", ""), cls="text-sm text-foreground"), + cls="bg-muted/50 border border-border rounded-md p-3 mb-2", ) for i, mem in enumerate(result.get("retrieved_memories", [])) - ] if result.get("retrieved_memories") else [P("No memories retrieved", cls="text-sm text-muted-foreground")], + ] + if result.get("retrieved_memories") + else [P("No memories retrieved", cls="text-sm text-muted-foreground")], ), - cls="mt-3 space-y-2" + cls="mt-3 space-y-2", ), - cls="border border-border rounded-md p-4 bg-muted/30" + cls="border border-border rounded-md p-4 bg-muted/30", ), - - cls=f"bg-white border border-border rounded-lg p-6 mb-4 shadow-sm {border_class}" + cls=f"bg-white border border-border rounded-lg p-6 mb-4 shadow-sm {border_class}", ) ) @@ -660,19 +881,20 @@ def get_locomo_item(mode: str, item_idx: int, filter_type: str = "all", category get_head(), Main( Div( - A(f"← Back to LoComo ({mode})", href=f"/locomo/{mode}", cls="inline-flex items-center px-4 py-2 bg-white border border-border rounded-md text-sm font-medium text-foreground hover:bg-accent mb-6"), + A( + f"← Back to LoComo ({mode})", + href=f"/locomo/{mode}", + cls="inline-flex items-center px-4 py-2 bg-white border border-border rounded-md text-sm font-medium text-foreground hover:bg-accent mb-6", + ), stats_html, copy_button, Hr(cls="my-6 border-border"), q_filters, P(f"Showing {len(filtered_questions)} questions", cls="text-sm text-muted-foreground mb-6"), - Div( - *questions_html, - cls="space-y-4" - ), - cls="container mx-auto max-w-7xl px-4 py-8" + Div(*questions_html, cls="space-y-4"), + cls="container mx-auto max-w-7xl px-4 py-8", ) - ) + ), ) @@ -691,8 +913,8 @@ def get_longmemeval(filter_type: str = "all", category_filter: str = "all"): H4("To generate results:"), Pre("./scripts/benchmarks/run-longmemeval.sh --env local"), A("← Back", href="/", cls="btn mt-3"), - cls="container" - ) + cls="container", + ), ) all_results = data.get("item_results", []) @@ -708,10 +930,14 @@ def get_longmemeval(filter_type: str = "all", category_filter: str = "all"): passes_correctness_filter = True elif filter_type == "correct": # Show items where all questions are correct (and not invalid) - passes_correctness_filter = detailed_results and all(r.get("is_correct") and not r.get("is_invalid") for r in detailed_results) + passes_correctness_filter = detailed_results and all( + r.get("is_correct") and not r.get("is_invalid") for r in detailed_results + ) elif filter_type == "incorrect": # Show items that have at least one incorrect question - passes_correctness_filter = any(not r.get("is_correct") and not r.get("is_invalid") for r in detailed_results) + passes_correctness_filter = any( + not r.get("is_correct") and not r.get("is_invalid") for r in detailed_results + ) elif filter_type == "invalid": # Show items that have at least one invalid question passes_correctness_filter = any(r.get("is_invalid") for r in detailed_results) @@ -752,38 +978,45 @@ def get_longmemeval(filter_type: str = "all", category_filter: str = "all"): Div( P("Overall Accuracy", cls="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2"), P(f"{data['overall_accuracy']:.2f}%", cls="text-3xl font-bold text-foreground"), - cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm" + cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm", ), Div( P("Correct Answers", cls="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2"), P(f"{data['total_correct']} / {data['total_questions']}", cls="text-3xl font-bold text-foreground"), - cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm" + cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm", ), Div( P("Invalid Questions", cls="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2"), P(str(total_invalid), cls="text-3xl font-bold text-foreground"), - cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm" - ) if total_invalid > 0 else None, + cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm", + ) + if total_invalid > 0 + else None, Div( P("Items", cls="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2"), P(str(len(all_results)), cls="text-3xl font-bold text-foreground"), - cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm" + cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm", ), - cls="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-8" + cls="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-8", ), H4("Accuracy by Category", cls="text-xl font-semibold text-foreground mb-4"), Div( *[ Div( P(cat["name"], cls="text-xs font-medium text-muted-foreground uppercase tracking-wide mb-2"), - P(f"{(cat['correct'] / (cat['total'] - cat['invalid']) * 100) if (cat['total'] - cat['invalid']) > 0 else 0:.1f}%", cls="text-2xl font-bold text-foreground"), + P( + f"{(cat['correct'] / (cat['total'] - cat['invalid']) * 100) if (cat['total'] - cat['invalid']) > 0 else 0:.1f}%", + cls="text-2xl font-bold text-foreground", + ), P(f"{cat['correct']} / {cat['total']}", cls="text-sm text-muted-foreground mt-1"), - cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm" + cls="bg-white border border-border rounded-lg p-6 text-center shadow-sm", ) for cat in category_stats.values() ], - cls="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4" - ) if category_stats else None + cls="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4", + ) + if category_stats + else None, ) # Filter controls @@ -792,41 +1025,131 @@ def get_longmemeval(filter_type: str = "all", category_filter: str = "all"): Div( P("Filter by correctness:", cls="text-sm font-medium text-foreground mb-2"), Div( - A("All", href=f"/longmemeval?filter_type=all&category_filter={category_filter}", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if filter_type == 'all' else "bg-white text-foreground border border-border hover:bg-accent")), - A("✅ All Correct", href=f"/longmemeval?filter_type=correct&category_filter={category_filter}", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if filter_type == 'correct' else "bg-white text-foreground border border-border hover:bg-accent")), - A("❌ Has Incorrect", href=f"/longmemeval?filter_type=incorrect&category_filter={category_filter}", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if filter_type == 'incorrect' else "bg-white text-foreground border border-border hover:bg-accent")), - A("⚠️ Has Invalid", href=f"/longmemeval?filter_type=invalid&category_filter={category_filter}", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if filter_type == 'invalid' else "bg-white text-foreground border border-border hover:bg-accent")) if total_invalid > 0 else None, - cls="flex flex-wrap gap-2" + A( + "All", + href=f"/longmemeval?filter_type=all&category_filter={category_filter}", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if filter_type == "all" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + A( + "✅ All Correct", + href=f"/longmemeval?filter_type=correct&category_filter={category_filter}", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if filter_type == "correct" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + A( + "❌ Has Incorrect", + href=f"/longmemeval?filter_type=incorrect&category_filter={category_filter}", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if filter_type == "incorrect" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + A( + "⚠️ Has Invalid", + href=f"/longmemeval?filter_type=invalid&category_filter={category_filter}", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if filter_type == "invalid" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ) + if total_invalid > 0 + else None, + cls="flex flex-wrap gap-2", ), - cls="mb-4" + cls="mb-4", ), # Category filter Div( P("Filter by question category:", cls="text-sm font-medium text-foreground mb-2"), Div( - A("All Categories", href=f"/longmemeval?filter_type={filter_type}&category_filter=all", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if category_filter == 'all' else "bg-white text-foreground border border-border hover:bg-accent")), - A("Multi-session", href=f"/longmemeval?filter_type={filter_type}&category_filter=multi-session", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if category_filter == 'multi-session' else "bg-white text-foreground border border-border hover:bg-accent")), - A("Single-session User", href=f"/longmemeval?filter_type={filter_type}&category_filter=single-session-user", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if category_filter == 'single-session-user' else "bg-white text-foreground border border-border hover:bg-accent")), - A("Single-session Assistant", href=f"/longmemeval?filter_type={filter_type}&category_filter=single-session-assistant", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if category_filter == 'single-session-assistant' else "bg-white text-foreground border border-border hover:bg-accent")), - A("Single-session Preference", href=f"/longmemeval?filter_type={filter_type}&category_filter=single-session-preference", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if category_filter == 'single-session-preference' else "bg-white text-foreground border border-border hover:bg-accent")), - A("Temporal Reasoning", href=f"/longmemeval?filter_type={filter_type}&category_filter=temporal-reasoning", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if category_filter == 'temporal-reasoning' else "bg-white text-foreground border border-border hover:bg-accent")), - A("Knowledge Update", href=f"/longmemeval?filter_type={filter_type}&category_filter=knowledge-update", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if category_filter == 'knowledge-update' else "bg-white text-foreground border border-border hover:bg-accent")), - cls="flex flex-wrap gap-2" + A( + "All Categories", + href=f"/longmemeval?filter_type={filter_type}&category_filter=all", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if category_filter == "all" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + A( + "Multi-session", + href=f"/longmemeval?filter_type={filter_type}&category_filter=multi-session", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if category_filter == "multi-session" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + A( + "Single-session User", + href=f"/longmemeval?filter_type={filter_type}&category_filter=single-session-user", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if category_filter == "single-session-user" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + A( + "Single-session Assistant", + href=f"/longmemeval?filter_type={filter_type}&category_filter=single-session-assistant", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if category_filter == "single-session-assistant" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + A( + "Single-session Preference", + href=f"/longmemeval?filter_type={filter_type}&category_filter=single-session-preference", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if category_filter == "single-session-preference" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + A( + "Temporal Reasoning", + href=f"/longmemeval?filter_type={filter_type}&category_filter=temporal-reasoning", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if category_filter == "temporal-reasoning" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + A( + "Knowledge Update", + href=f"/longmemeval?filter_type={filter_type}&category_filter=knowledge-update", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if category_filter == "knowledge-update" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + cls="flex flex-wrap gap-2", ), - cls="mb-4" + cls="mb-4", ), - cls="mb-6" + cls="mb-6", ) # Render items @@ -862,21 +1185,21 @@ def get_longmemeval(filter_type: str = "all", category_filter: str = "all"): Div( P("Accuracy", cls="text-xs font-medium text-muted-foreground uppercase tracking-wide"), P(f"{accuracy:.1f}%", cls="text-2xl font-bold text-foreground"), - cls="text-center" + cls="text-center", ), Div( P("Correct", cls="text-xs font-medium text-muted-foreground uppercase tracking-wide"), P(f"{correct}/{total}", cls="text-xl font-semibold text-foreground"), - cls="text-center" + cls="text-center", ), - cls="flex gap-6 items-center" + cls="flex gap-6 items-center", ), - cls="p-6" + cls="p-6", ), - cls=f"bg-white border border-border rounded-lg shadow-sm transition-all {border_class} {bg_class}" + cls=f"bg-white border border-border rounded-lg shadow-sm transition-all {border_class} {bg_class}", ), href=f"/longmemeval/item/{original_idx}?filter_type={filter_type}&category_filter={category_filter}", - cls="block no-underline" + cls="block no-underline", ) ) @@ -885,18 +1208,19 @@ def get_longmemeval(filter_type: str = "all", category_filter: str = "all"): get_head(), Main( Div( - A("← Back to benchmarks", href="/", cls="inline-flex items-center px-4 py-2 bg-white border border-border rounded-md text-sm font-medium text-foreground hover:bg-accent mb-6"), + A( + "← Back to benchmarks", + href="/", + cls="inline-flex items-center px-4 py-2 bg-white border border-border rounded-md text-sm font-medium text-foreground hover:bg-accent mb-6", + ), stats_html, Hr(cls="my-6 border-border"), filters, P(f"Showing {len(results)} of {len(all_results)} items", cls="text-sm text-muted-foreground mb-6"), - Div( - *items_html, - cls="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4" - ), - cls="container mx-auto max-w-7xl px-4 py-8" + Div(*items_html, cls="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"), + cls="container mx-auto max-w-7xl px-4 py-8", ) - ) + ), ) @@ -937,17 +1261,51 @@ def get_longmemeval_item(item_idx: int, filter_type: str = "all"): q_filters = Div( P("Filter:", cls="text-sm font-medium text-foreground mb-2"), Div( - A("All", href=f"/longmemeval/item/{item_idx}?filter_type=all", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if filter_type == 'all' else "bg-white text-foreground border border-border hover:bg-accent")), - A("✅ Correct", href=f"/longmemeval/item/{item_idx}?filter_type=correct", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if filter_type == 'correct' else "bg-white text-foreground border border-border hover:bg-accent")), - A("❌ Incorrect", href=f"/longmemeval/item/{item_idx}?filter_type=incorrect", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if filter_type == 'incorrect' else "bg-white text-foreground border border-border hover:bg-accent")), - A("⚠️ Invalid", href=f"/longmemeval/item/{item_idx}?filter_type=invalid", - cls="px-3 py-1.5 rounded-md text-sm font-medium " + ("bg-primary text-primary-foreground" if filter_type == 'invalid' else "bg-white text-foreground border border-border hover:bg-accent")) if has_invalid else None, - cls="flex flex-wrap gap-2" + A( + "All", + href=f"/longmemeval/item/{item_idx}?filter_type=all", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if filter_type == "all" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + A( + "✅ Correct", + href=f"/longmemeval/item/{item_idx}?filter_type=correct", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if filter_type == "correct" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + A( + "❌ Incorrect", + href=f"/longmemeval/item/{item_idx}?filter_type=incorrect", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if filter_type == "incorrect" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ), + A( + "⚠️ Invalid", + href=f"/longmemeval/item/{item_idx}?filter_type=invalid", + cls="px-3 py-1.5 rounded-md text-sm font-medium " + + ( + "bg-primary text-primary-foreground" + if filter_type == "invalid" + else "bg-white text-foreground border border-border hover:bg-accent" + ), + ) + if has_invalid + else None, + cls="flex flex-wrap gap-2", ), - cls="mb-6" + cls="mb-6", ) # Render questions @@ -961,7 +1319,11 @@ def get_longmemeval_item(item_idx: int, filter_type: str = "all"): category = result.get("category", "Unknown") icon = "⚠️" if is_invalid else ("✅" if is_correct else "❌") - border_class = "border-l-4 border-yellow-500" if is_invalid else ("border-l-4 border-green-600" if is_correct else "border-l-4 border-red-600") + border_class = ( + "border-l-4 border-yellow-500" + if is_invalid + else ("border-l-4 border-green-600" if is_correct else "border-l-4 border-red-600") + ) questions_html.append( Div( @@ -969,75 +1331,106 @@ def get_longmemeval_item(item_idx: int, filter_type: str = "all"): Div( P(f"{icon} Question {q_idx + 1}", cls="text-lg font-semibold text-foreground"), P(f"Category: {category}", cls="text-sm text-muted-foreground"), - cls="mb-4" + cls="mb-4", ), - # Question Div( P("Question:", cls="text-sm font-medium text-foreground mb-1"), P(question, cls="text-foreground"), - cls="mb-4" + cls="mb-4", ), - # Answers side by side Div( Div( P("✓ Correct Answer", cls="text-sm font-medium text-foreground mb-2"), Div(correct_answer, cls="bg-green-50 border border-green-200 rounded-md p-3 text-foreground"), - cls="flex-1" + cls="flex-1", ), Div( - P(f"{'✓' if is_correct else '✗'} Predicted Answer", cls="text-sm font-medium text-foreground mb-2"), - Div(predicted_answer, cls=f"border rounded-md p-3 text-foreground " + ("bg-green-50 border-green-200" if is_correct else "bg-red-50 border-red-200")), - cls="flex-1" + P( + f"{'✓' if is_correct else '✗'} Predicted Answer", + cls="text-sm font-medium text-foreground mb-2", + ), + Div( + predicted_answer, + cls="border rounded-md p-3 text-foreground " + + ("bg-green-50 border-green-200" if is_correct else "bg-red-50 border-red-200"), + ), + cls="flex-1", ), - cls="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4" + cls="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4", ), - # Details Details( - Summary("📝 Show Reasoning & Retrieved Memories", cls="cursor-pointer font-medium text-foreground hover:text-primary py-2"), + Summary( + "📝 Show Reasoning & Retrieved Memories", + cls="cursor-pointer font-medium text-foreground hover:text-primary py-2", + ), Div( # System Reasoning Div( P("System Reasoning:", cls="text-sm font-medium text-foreground mb-2"), - Pre(result.get("reasoning", "N/A"), cls="bg-slate-900 text-slate-100 p-3 rounded-md overflow-x-auto text-sm"), - cls="mb-4" + Pre( + result.get("reasoning", "N/A"), + cls="bg-slate-900 text-slate-100 p-3 rounded-md overflow-x-auto text-sm", + ), + cls="mb-4", ), # Judge Reasoning Div( P("Judge Reasoning:", cls="text-sm font-medium text-foreground mb-2"), - Pre(result.get("correctness_reasoning", "N/A"), cls="bg-slate-900 text-slate-100 p-3 rounded-md overflow-x-auto text-sm"), - cls="mb-4" + Pre( + result.get("correctness_reasoning", "N/A"), + cls="bg-slate-900 text-slate-100 p-3 rounded-md overflow-x-auto text-sm", + ), + cls="mb-4", ), # Retrieved Memories Div( - P(f"Retrieved Memories ({len(result.get('retrieved_memories', []))}):", cls="text-sm font-medium text-foreground mb-2"), + P( + f"Retrieved Memories ({len(result.get('retrieved_memories', []))}):", + cls="text-sm font-medium text-foreground mb-2", + ), *[ Div( P( - f"#{i+1} • " + - " • ".join(filter(None, [ - f"Occurred: {mem.get('occurred_start', '')[:10]}" + - (f" to {mem.get('occurred_end', '')[:10]}" if mem.get('occurred_end') and mem.get('occurred_start', '')[:10] != mem.get('occurred_end', '')[:10] else "") - if mem.get('occurred_start') else None, - f"Mentioned: {mem.get('mentioned_at', '')[:10]}" if mem.get('mentioned_at') else None, - f"Type: {mem.get('fact_type', 'unknown').upper()}" - ])), - cls="text-xs text-muted-foreground mb-1" + f"#{i + 1} • " + + " • ".join( + filter( + None, + [ + f"Occurred: {mem.get('occurred_start', '')[:10]}" + + ( + f" to {mem.get('occurred_end', '')[:10]}" + if mem.get("occurred_end") + and mem.get("occurred_start", "")[:10] + != mem.get("occurred_end", "")[:10] + else "" + ) + if mem.get("occurred_start") + else None, + f"Mentioned: {mem.get('mentioned_at', '')[:10]}" + if mem.get("mentioned_at") + else None, + f"Type: {mem.get('fact_type', 'unknown').upper()}", + ], + ) + ), + cls="text-xs text-muted-foreground mb-1", ), - P(mem.get('text', ''), cls="text-sm text-foreground"), - cls="bg-muted/50 border border-border rounded-md p-3 mb-2" + P(mem.get("text", ""), cls="text-sm text-foreground"), + cls="bg-muted/50 border border-border rounded-md p-3 mb-2", ) for i, mem in enumerate(result.get("retrieved_memories", [])) - ] if result.get("retrieved_memories") else [P("No memories retrieved", cls="text-sm text-muted-foreground")], + ] + if result.get("retrieved_memories") + else [P("No memories retrieved", cls="text-sm text-muted-foreground")], ), - cls="mt-3 space-y-2" + cls="mt-3 space-y-2", ), - cls="border border-border rounded-md p-4 bg-muted/30" + cls="border border-border rounded-md p-4 bg-muted/30", ), - - cls=f"bg-white border border-border rounded-lg p-6 mb-4 shadow-sm {border_class}" + cls=f"bg-white border border-border rounded-lg p-6 mb-4 shadow-sm {border_class}", ) ) @@ -1046,23 +1439,25 @@ def get_longmemeval_item(item_idx: int, filter_type: str = "all"): get_head(), Main( Div( - A("← Back to LongMemEval", href="/longmemeval", cls="inline-flex items-center px-4 py-2 bg-white border border-border rounded-md text-sm font-medium text-foreground hover:bg-accent mb-6"), + A( + "← Back to LongMemEval", + href="/longmemeval", + cls="inline-flex items-center px-4 py-2 bg-white border border-border rounded-md text-sm font-medium text-foreground hover:bg-accent mb-6", + ), H3(f"📊 {item_id} - {accuracy:.2f}%", cls="text-2xl font-bold text-foreground mb-4"), Hr(cls="my-6 border-border"), q_filters, P(f"Showing {len(filtered_questions)} questions", cls="text-sm text-muted-foreground mb-6"), - Div( - *questions_html, - cls="space-y-4" - ), - cls="container mx-auto max-w-7xl px-4 py-8" + Div(*questions_html, cls="space-y-4"), + cls="container mx-auto max-w-7xl px-4 py-8", ) - ) + ), ) if __name__ == "__main__": import uvicorn + print("🚀 Starting Benchmark Visualizer...") print("📊 Server running at: http://localhost:8001") uvicorn.run("main:app", host="127.0.0.1", port=8001, reload=True) diff --git a/hindsight-dev/hindsight_dev/generate_changelog.py b/hindsight-dev/hindsight_dev/generate_changelog.py index d498cc95..2752384a 100644 --- a/hindsight-dev/hindsight_dev/generate_changelog.py +++ b/hindsight-dev/hindsight_dev/generate_changelog.py @@ -5,6 +5,7 @@ Generate changelog entry for a new release. This script fetches the commit diff between releases, uses an LLM to summarize, and prepends the entry to the changelog page. """ + import argparse import json import os @@ -29,6 +30,7 @@ CHANGELOG_PATH = REPO_PATH / "hindsight-docs" / "docs" / "changelog" / "index.md class ChangelogEntry(BaseModel): """A single changelog entry.""" + category: str # "feature", "improvement", "bugfix", "breaking", "other" summary: str # Brief description of the change commit_id: str # Short commit hash @@ -36,12 +38,14 @@ class ChangelogEntry(BaseModel): class ChangelogResponse(BaseModel): """Structured response from LLM.""" + entries: list[ChangelogEntry] @dataclass class Commit: """Parsed commit from git log.""" + hash: str message: str @@ -151,10 +155,7 @@ def analyze_commits_with_llm( file_diff: str, ) -> list[ChangelogEntry]: """Use LLM to analyze commits and return structured changelog entries.""" - commits_json = json.dumps( - [{"commit_id": c.hash, "message": c.message} for c in commits], - indent=2 - ) + commits_json = json.dumps([{"commit_id": c.hash, "message": c.message} for c in commits], indent=2) prompt = f"""Analyze the following git commits for release {version} of Hindsight (an AI memory system). @@ -252,8 +253,8 @@ For full release details, see [GitHub Releases](https://github.com/vectorize-io/ match = re.search(r"^## ", content, re.MULTILINE) if match: - header = content[:match.start()].rstrip() + "\n\n" - releases = content[match.start():] + header = content[: match.start()].rstrip() + "\n\n" + releases = content[match.start() :] else: header = content.rstrip() + "\n\n" releases = "" @@ -283,7 +284,7 @@ def generate_changelog_entry( tag = version if version.startswith("v") else f"v{version}" display_version = version.lstrip("v") - console.print(f"[blue]Fetching tags from repository...[/blue]") + console.print("[blue]Fetching tags from repository...[/blue]") existing_tags = get_git_tags() if tag not in existing_tags and display_version not in existing_tags: @@ -300,7 +301,7 @@ def generate_changelog_entry( else: console.print("[yellow]No previous version found, will include all commits[/yellow]") - console.print(f"[blue]Getting commits...[/blue]") + console.print("[blue]Getting commits...[/blue]") commits = get_commits(previous_tag, actual_tag) file_diff = get_detailed_diff(previous_tag, actual_tag) diff --git a/hindsight-dev/hindsight_dev/generate_openapi.py b/hindsight-dev/hindsight_dev/generate_openapi.py index 0730bb8f..62f7c216 100644 --- a/hindsight-dev/hindsight_dev/generate_openapi.py +++ b/hindsight-dev/hindsight_dev/generate_openapi.py @@ -4,13 +4,15 @@ Generate OpenAPI specification from FastAPI app. This script imports the FastAPI app and exports its OpenAPI schema to a JSON file. """ + import json -import sys import os +import sys from pathlib import Path -from hindsight_api.api import create_app from hindsight_api import MemoryEngine +from hindsight_api.api import create_app + def generate_openapi_spec(output_path: str = None): """Generate OpenAPI spec and save to file.""" @@ -34,7 +36,7 @@ def generate_openapi_spec(output_path: str = None): # Write to file output_file = Path(output_path) - with open(output_file, 'w') as f: + with open(output_file, "w") as f: json.dump(openapi_schema, f, indent=2) print(f"✓ OpenAPI specification generated: {output_file.absolute()}") @@ -44,14 +46,15 @@ def generate_openapi_spec(output_path: str = None): # List endpoints print("\n Endpoints:") - for path, methods in openapi_schema['paths'].items(): + for path, methods in openapi_schema["paths"].items(): for method in methods.keys(): - if method.upper() in ['GET', 'POST', 'PUT', 'DELETE', 'PATCH']: + if method.upper() in ["GET", "POST", "PUT", "DELETE", "PATCH"]: endpoint_info = methods[method] - summary = endpoint_info.get('summary', 'No summary') - tags = ', '.join(endpoint_info.get('tags', ['untagged'])) + summary = endpoint_info.get("summary", "No summary") + tags = ", ".join(endpoint_info.get("tags", ["untagged"])) print(f" {method.upper():6} {path:30} [{tags}] - {summary}") + if __name__ == "__main__": output = sys.argv[1] if len(sys.argv) > 1 else "openapi.json" generate_openapi_spec(output) diff --git a/hindsight-dev/hindsight_dev/sync_cookbook.py b/hindsight-dev/hindsight_dev/sync_cookbook.py index 8821bf03..3458df6c 100644 --- a/hindsight-dev/hindsight_dev/sync_cookbook.py +++ b/hindsight-dev/hindsight_dev/sync_cookbook.py @@ -212,9 +212,7 @@ This recipe is available as an interactive Jupyter notebook. # Insert callout after first heading first_heading_match = re.search(r"^(#\s+.+\n)", md_content, re.MULTILINE) if first_heading_match: - idx = md_content.index(first_heading_match.group(0)) + len( - first_heading_match.group(0) - ) + idx = md_content.index(first_heading_match.group(0)) + len(first_heading_match.group(0)) final_content = md_content[:idx] + "\n" + callout + "\n" + md_content[idx:] else: final_content = callout + "\n" + md_content @@ -247,9 +245,7 @@ def process_applications(cookbook_dir: Path, apps_dir: Path) -> list[dict]: continue slug = entry.name - title = extract_title_from_readme(readme_path) or " ".join( - word.capitalize() for word in slug.split("-") - ) + title = extract_title_from_readme(readme_path) or " ".join(word.capitalize() for word in slug.split("-")) print(f" Processing app: {entry.name} → {slug}.md") @@ -275,12 +271,8 @@ This is a complete, runnable application demonstrating Hindsight integration. # Insert callout after first heading first_heading_match = re.search(r"^(#\s+.+\n)", readme_content, re.MULTILINE) if first_heading_match: - idx = readme_content.index(first_heading_match.group(0)) + len( - first_heading_match.group(0) - ) - final_content = ( - readme_content[:idx] + "\n" + callout + "\n" + readme_content[idx:] - ) + idx = readme_content.index(first_heading_match.group(0)) + len(first_heading_match.group(0)) + final_content = readme_content[:idx] + "\n" + callout + "\n" + readme_content[idx:] else: final_content = callout + "\n" + readme_content @@ -407,26 +399,20 @@ def clean_description(desc: str) -> str: return desc -def update_cookbook_index( - recipes: list[dict], apps: list[dict], docs_dir: Path -): +def update_cookbook_index(recipes: list[dict], apps: list[dict], docs_dir: Path): """Update cookbook/index.mdx with recipe and app carousels.""" # Build recipe items for the carousel recipe_items = [] for r in recipes: title = r["title"].replace('"', '\\"') - recipe_items.append( - f' {{ title: "{title}", href: "/cookbook/recipes/{r["slug"]}" }}' - ) + recipe_items.append(f' {{ title: "{title}", href: "/cookbook/recipes/{r["slug"]}" }}') recipes_json = ",\n".join(recipe_items) # Build app items for the carousel app_items = [] for a in apps: title = a["title"].replace('"', '\\"') - app_items.append( - f' {{ title: "{title}", href: "/cookbook/applications/{a["slug"]}" }}' - ) + app_items.append(f' {{ title: "{title}", href: "/cookbook/applications/{a["slug"]}" }}') apps_json = ",\n".join(app_items) content = f"""--- diff --git a/hindsight-dev/pyproject.toml b/hindsight-dev/pyproject.toml index 74ec93fb..a87e4ac7 100644 --- a/hindsight-dev/pyproject.toml +++ b/hindsight-dev/pyproject.toml @@ -27,3 +27,58 @@ generate-openapi = "hindsight_dev.generate_openapi:generate_openapi_spec" generate-changelog = "hindsight_dev.generate_changelog:main" sync-cookbook = "hindsight_dev.sync_cookbook:main" generate-llms-full = "hindsight_dev.generate_llms_full:main" + +[dependency-groups] +dev = [ + "ruff>=0.8.0", + "ty>=0.0.1", +] + +[tool.ruff] +line-length = 120 +target-version = "py311" + +[tool.ruff.lint] +select = [ + "E", # pycodestyle errors + "W", # pycodestyle warnings + "F", # Pyflakes + "I", # isort +] +ignore = [ + "E501", # line too long (handled by formatter) + "E402", # module import not at top of file + "E712", # avoid equality comparisons to False (intentional for optional bools) + "F401", # unused import (too noisy during development) + "F403", # star imports (fasthtml uses this pattern) + "F405", # may be undefined from star imports (fasthtml uses this pattern) + "F841", # unused variable (too noisy during development) + "F811", # redefined while unused + "F821", # undefined name (forward references in type hints) + "W291", # trailing whitespace (in multiline strings) + "W293", # blank line contains whitespace (in multiline strings) +] + +[tool.ruff.format] +quote-style = "double" +indent-style = "space" + +[tool.ty] +# Type checking configuration +# ty is an extremely fast Python type checker from Astral (same team as ruff/uv) + +[tool.ty.environment] +python-version = "3.11" + +[tool.ty.rules] +# Disable noisy rules +invalid-argument-type = "ignore" # Too many false positives +invalid-return-type = "ignore" # Often intentional +# missing-argument and unknown-argument are enabled (default) +invalid-parameter-default = "ignore" # Optional params with None default +possibly-missing-attribute = "ignore" # Common with Optional types +unsupported-operator = "ignore" # Pandas DataFrame operations +unresolved-reference = "ignore" # Forward references +unresolved-import = "ignore" # Dynamic imports +invalid-assignment = "ignore" # Intentional monkey-patching +no-matching-overload = "ignore" # Complex generic issues diff --git a/hindsight-docs/docusaurus.config.ts b/hindsight-docs/docusaurus.config.ts index cd735a64..5fdac2f7 100644 --- a/hindsight-docs/docusaurus.config.ts +++ b/hindsight-docs/docusaurus.config.ts @@ -116,7 +116,18 @@ const config: Config = { ], ], - themes: ['@docusaurus/theme-mermaid'], + themes: [ + '@docusaurus/theme-mermaid', + [ + '@easyops-cn/docusaurus-search-local', + { + hashed: true, + docsRouteBasePath: '/', + indexBlog: false, + highlightSearchTermsOnTargetPage: false, + }, + ], + ], themeConfig: { ...(ANNOUNCEMENT_BAR && { diff --git a/hindsight-docs/package.json b/hindsight-docs/package.json index 2747dc07..73252453 100644 --- a/hindsight-docs/package.json +++ b/hindsight-docs/package.json @@ -19,6 +19,7 @@ "@docusaurus/preset-classic": "3.9.2", "@docusaurus/theme-common": "^3.9.2", "@docusaurus/theme-mermaid": "^3.9.2", + "@easyops-cn/docusaurus-search-local": "^0.52.2", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0", diff --git a/hindsight-docs/src/css/custom.css b/hindsight-docs/src/css/custom.css index eb4e4567..2e2321e9 100644 --- a/hindsight-docs/src/css/custom.css +++ b/hindsight-docs/src/css/custom.css @@ -890,3 +890,309 @@ div[class*="announcementBar"] a:hover { background: rgba(255, 255, 255, 0.3); } +/* ===== Local Search Plugin Styling ===== */ + +/* Search bar in navbar */ +.navbar__search { + margin-left: auto; +} + + +/* Hide keyboard shortcut hints */ +[class*="searchHint"], +[class*="searchHintContainer"] { + display: none !important; +} + +/* Minimal search button */ +[class*="searchBarContainer"] button, +[class*="searchBar_"] { + font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important; + font-size: 0.75rem !important; + font-weight: 500 !important; + background: transparent !important; + border: none !important; + border-bottom: 1px solid transparent !important; + border-image: linear-gradient(90deg, #0074d9, #009296) 1 !important; + border-radius: 0 !important; + padding: 0.25rem 0 !important; + color: var(--ifm-color-emphasis-600) !important; + transition: all 0.2s ease !important; + height: auto !important; + min-height: unset !important; +} + +[class*="searchBarContainer"] button:hover, +[class*="searchBar_"]:hover { + color: var(--ifm-font-color-base) !important; +} + +[data-theme='dark'] [class*="searchBarContainer"] button, +[data-theme='dark'] [class*="searchBar_"] { + color: var(--ifm-color-emphasis-500) !important; +} + +[data-theme='dark'] [class*="searchBarContainer"] button:hover, +[data-theme='dark'] [class*="searchBar_"]:hover { + color: #e2e8f0 !important; +} + +/* Search input field - remove ALL borders */ +[class*="searchInput"], +[class*="searchQueryInput"], +[class*="searchInput"] *, +[class*="searchQueryInput"] *, +[class*="searchBarContainer"] input, +[class*="searchBarContainer"] input * { + font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important; + font-size: 0.875rem !important; + font-weight: 500 !important; + background: transparent !important; + border: 0 !important; + border-top: 0 !important; + border-right: 0 !important; + border-bottom: 0 !important; + border-left: 0 !important; + border-radius: 0 !important; + color: var(--ifm-font-color-base) !important; + padding: 0.5rem 0 !important; + box-shadow: none !important; + outline: none !important; +} + +/* Add single underline via pseudo or direct */ +[class*="searchQueryInput"], +[class*="searchBarContainer"] input[type="search"] { + border-bottom: 1px solid var(--ifm-toc-border-color) !important; +} + +[data-theme='dark'] [class*="searchQueryInput"], +[data-theme='dark'] [class*="searchBarContainer"] input[type="search"] { + border-bottom: 1px solid #27272a !important; +} + +[class*="searchQueryInput"]:focus, +[class*="searchBarContainer"] input[type="search"]:focus { + border-bottom: 1px solid #0074d9 !important; +} + +[class*="searchInput"]::placeholder, +[class*="searchQueryInput"]::placeholder, +[class*="searchBarContainer"] input::placeholder { + font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important; + font-weight: 500 !important; + color: var(--ifm-color-emphasis-400) !important; +} + +/* Minimal dropdown */ +[class*="dropdownMenu"], +[class*="suggestionsContainer"], +[class*="searchResultsContainer"], +[class*="suggestions"], +ul[class*="suggestion"] { + font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important; + background: #ffffff !important; + background-color: #ffffff !important; + border: none !important; + border-radius: 0.25rem !important; + box-shadow: 0 4px 20px -4px rgba(0, 0, 0, 0.15) !important; + padding: 0.25rem !important; +} + +[data-theme='dark'] [class*="dropdownMenu"], +[data-theme='dark'] [class*="suggestionsContainer"], +[data-theme='dark'] [class*="searchResultsContainer"], +[data-theme='dark'] [class*="suggestions"], +[data-theme='dark'] ul[class*="suggestion"] { + background: #0f0f11 !important; + background-color: #0f0f11 !important; + box-shadow: 0 4px 20px -4px rgba(0, 0, 0, 0.5) !important; +} + +/* Minimal result items */ +[class*="searchResultItem"], +[class*="suggestion"] { + font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important; + background: transparent !important; + border-radius: 0.25rem !important; + padding: 0.5rem 0.75rem !important; + margin: 0 !important; + transition: background-color 0.1s ease !important; + cursor: pointer !important; + border-left: 2px solid transparent !important; +} + +/* No background hover - keep transparent */ +[class*="searchResultItem"]:hover, +[class*="searchResultItem"][class*="cursor"], +[class*="suggestion"]:hover, +[class*="suggestion"][class*="cursor"] { + background: transparent !important; + border-left-color: transparent !important; +} + +/* Icons - default color */ +[class*="hitIcon"], +[class*="hitTree"] { + color: #71717a !important; + transition: all 0.15s ease !important; +} + +[class*="hitIcon"] svg path, +[class*="hitIcon"] svg, +[class*="hitTree"] svg path, +[class*="hitTree"] svg { + stroke: #71717a !important; + color: #71717a !important; + transition: all 0.15s ease !important; +} + +/* Icons - hover gradient effect */ +[class*="suggestion"]:hover [class*="hitIcon"] svg path, +[class*="suggestion"]:hover [class*="hitIcon"] svg, +[class*="suggestion"]:hover [class*="hitTree"] svg path, +[class*="suggestion"]:hover [class*="hitTree"] svg { + stroke: #0074d9 !important; + color: #0074d9 !important; +} + +[data-theme='dark'] [class*="hitIcon"] svg path, +[data-theme='dark'] [class*="hitIcon"] svg, +[data-theme='dark'] [class*="hitTree"] svg path, +[data-theme='dark'] [class*="hitTree"] svg { + stroke: #71717a !important; + color: #71717a !important; +} + +[data-theme='dark'] [class*="suggestion"]:hover [class*="hitIcon"] svg path, +[data-theme='dark'] [class*="suggestion"]:hover [class*="hitIcon"] svg, +[data-theme='dark'] [class*="suggestion"]:hover [class*="hitTree"] svg path, +[data-theme='dark'] [class*="suggestion"]:hover [class*="hitTree"] svg { + stroke: #3396e8 !important; + color: #3396e8 !important; +} + +/* === PAGE-LEVEL RESULTS (doc icon, no tree) === */ +/* Title is the page name - GRADIENT */ +[class*="suggestion"]:not(:has([class*="hitTree"])) [class*="hitTitle"] { + font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important; + font-weight: 600 !important; + font-size: 0.9375rem !important; + background: linear-gradient(90deg, #0074d9, #009296) !important; + -webkit-background-clip: text !important; + background-clip: text !important; + -webkit-text-fill-color: transparent !important; + margin: 0 !important; +} + +/* === SECTION-LEVEL RESULTS (hashtag icon, has tree) === */ +/* Title is the section name - regular gray text */ +[class*="suggestion"]:has([class*="hitTree"]) [class*="hitTitle"] { + font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important; + font-weight: 500 !important; + font-size: 0.8125rem !important; + background: none !important; + -webkit-background-clip: unset !important; + background-clip: unset !important; + color: #3f3f46 !important; + -webkit-text-fill-color: #3f3f46 !important; + margin: 0 !important; +} + +[data-theme='dark'] [class*="suggestion"]:has([class*="hitTree"]) [class*="hitTitle"] { + color: #d4d4d8 !important; + -webkit-text-fill-color: #d4d4d8 !important; +} + +/* Path is the page name - GRADIENT */ +[class*="suggestion"]:has([class*="hitTree"]) [class*="hitPath"] { + font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important; + font-weight: 600 !important; + font-size: 0.75rem !important; + background: linear-gradient(90deg, #0074d9, #009296) !important; + -webkit-background-clip: text !important; + background-clip: text !important; + -webkit-text-fill-color: transparent !important; + text-transform: none !important; + letter-spacing: 0 !important; + margin-top: 0.125rem !important; + display: block !important; +} + +/* === FALLBACK for browsers without :has() === */ +[class*="hitPath"] { + font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important; + font-size: 0.625rem !important; + font-weight: 400 !important; + color: #71717a !important; + -webkit-text-fill-color: #71717a !important; + text-transform: none !important; + letter-spacing: 0 !important; +} + +[class*="hitTitle"] { + font-family: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important; + font-weight: 600 !important; + font-size: 0.9375rem !important; + background: linear-gradient(90deg, #0074d9, #009296) !important; + -webkit-background-clip: text !important; + background-clip: text !important; + -webkit-text-fill-color: transparent !important; + margin: 0 !important; +} + +/* Highlight matched text - must override color rules */ +[class*="searchResultItem"] mark, +[class*="suggestion"] mark, +.search-result-match mark, +[class*="searchResultItem"]:hover mark, +[class*="suggestion"]:hover mark, +[class*="searchResultItem"][class*="cursor"] mark, +[class*="suggestion"][class*="cursor"] mark { + background: transparent !important; + color: #0074d9 !important; + padding: 0 !important; + border-radius: 0 !important; + font-weight: 600 !important; + text-decoration: none !important; +} + +[data-theme='dark'] [class*="searchResultItem"] mark, +[data-theme='dark'] [class*="suggestion"] mark, +[data-theme='dark'] .search-result-match mark, +[data-theme='dark'] [class*="searchResultItem"]:hover mark, +[data-theme='dark'] [class*="suggestion"]:hover mark, +[data-theme='dark'] [class*="searchResultItem"][class*="cursor"] mark, +[data-theme='dark'] [class*="suggestion"][class*="cursor"] mark { + color: #66b3f0 !important; +} + +/* No results */ +[class*="noResults"], +[class*="searchNoResult"] { + font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important; + font-size: 0.75rem !important; + color: var(--ifm-color-emphasis-500) !important; + padding: 1rem !important; + text-align: center !important; +} + +/* Loading */ +[class*="searchIndexLoading"], +[class*="loadingRing"] { + font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif !important; + font-size: 0.75rem !important; + color: var(--ifm-color-emphasis-400) !important; +} + +/* Hide footer */ +[class*="hitFooter"], +[class*="searchFooter"] { + display: none !important; +} + +/* Hide action icons */ +[class*="hitAction"] { + display: none !important; +} + diff --git a/package-lock.json b/package-lock.json index ad9be7d1..bd0be49d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -77,6 +77,17 @@ "typescript-eslint": "^8.50.0" } }, + "hindsight-control-plane/node_modules/@eslint/js": { + "version": "9.39.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, "hindsight-control-plane/node_modules/@types/node": { "version": "24.10.1", "license": "MIT", @@ -84,12 +95,6 @@ "undici-types": "~7.16.0" } }, - "hindsight-control-plane/node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", - "license": "MIT" - }, "hindsight-docs": { "version": "0.0.0", "dependencies": { @@ -97,6 +102,7 @@ "@docusaurus/preset-classic": "3.9.2", "@docusaurus/theme-common": "^3.9.2", "@docusaurus/theme-mermaid": "^3.9.2", + "@easyops-cn/docusaurus-search-local": "^0.52.2", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", "prism-react-renderer": "^2.3.0", @@ -128,13 +134,11 @@ } }, "node_modules/@ai-sdk/gateway": { - "version": "2.0.23", - "resolved": "https://registry.npmjs.org/@ai-sdk/gateway/-/gateway-2.0.23.tgz", - "integrity": "sha512-qmX7afPRszUqG5hryHF3UN8ITPIRSGmDW6VYCmByzjoUkgm3MekzSx2hMV1wr0P+llDeuXb378SjqUfpvWJulg==", + "version": "2.0.18", "license": "Apache-2.0", "dependencies": { "@ai-sdk/provider": "2.0.0", - "@ai-sdk/provider-utils": "3.0.19", + "@ai-sdk/provider-utils": "3.0.18", "@vercel/oidc": "3.0.5" }, "engines": { @@ -146,8 +150,6 @@ }, "node_modules/@ai-sdk/provider": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@ai-sdk/provider/-/provider-2.0.0.tgz", - "integrity": "sha512-6o7Y2SeO9vFKB8lArHXehNuusnpddKPk7xqL7T2/b+OvXMRIXUO1rR4wcv1hAFUAT9avGZshty3Wlua/XA7TvA==", "license": "Apache-2.0", "dependencies": { "json-schema": "^0.4.0" @@ -157,9 +159,7 @@ } }, "node_modules/@ai-sdk/provider-utils": { - "version": "3.0.19", - "resolved": "https://registry.npmjs.org/@ai-sdk/provider-utils/-/provider-utils-3.0.19.tgz", - "integrity": "sha512-W41Wc9/jbUVXVwCN/7bWa4IKe8MtxO3EyA0Hfhx6grnmiYlCvpI8neSYWFE0zScXJkgA/YK3BRybzgyiXuu6JA==", + "version": "3.0.18", "license": "Apache-2.0", "dependencies": { "@ai-sdk/provider": "2.0.0", @@ -174,13 +174,11 @@ } }, "node_modules/@ai-sdk/react": { - "version": "2.0.118", - "resolved": "https://registry.npmjs.org/@ai-sdk/react/-/react-2.0.118.tgz", - "integrity": "sha512-K/5VVEGTIu9SWrdQ0s/11OldFU8IjprDzeE6TaC2fOcQWhG7dGVGl9H8Z32QBHzdfJyMhFUxEyFKSOgA2j9+VQ==", + "version": "2.0.106", "license": "Apache-2.0", "dependencies": { - "@ai-sdk/provider-utils": "3.0.19", - "ai": "5.0.116", + "@ai-sdk/provider-utils": "3.0.18", + "ai": "5.0.106", "swr": "^2.2.5", "throttleit": "2.1.0" }, @@ -188,7 +186,7 @@ "node": ">=18" }, "peerDependencies": { - "react": "^18 || ~19.0.1 || ~19.1.2 || ^19.2.1", + "react": "^18 || ^19 || ^19.0.0-rc", "zod": "^3.25.76 || ^4.1.8" }, "peerDependenciesMeta": { @@ -198,15 +196,13 @@ } }, "node_modules/@algolia/abtesting": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.12.1.tgz", - "integrity": "sha512-Y+7e2uPe376OH5O73OB1+vR40ZhbV2kzGh/AR/dPCWguoBOp1IK0o+uZQLX+7i32RMMBEKl3pj6KVEav100Kvg==", + "version": "1.12.0", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.46.1", - "@algolia/requester-browser-xhr": "5.46.1", - "@algolia/requester-fetch": "5.46.1", - "@algolia/requester-node-http": "5.46.1" + "@algolia/client-common": "5.46.0", + "@algolia/requester-browser-xhr": "5.46.0", + "@algolia/requester-fetch": "5.46.0", + "@algolia/requester-node-http": "5.46.0" }, "engines": { "node": ">= 14.0.0" @@ -214,8 +210,6 @@ }, "node_modules/@algolia/autocomplete-core": { "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.19.2.tgz", - "integrity": "sha512-mKv7RyuAzXvwmq+0XRK8HqZXt9iZ5Kkm2huLjgn5JoCPtDy+oh9yxUMfDDaVCw0oyzZ1isdJBc7l9nuCyyR7Nw==", "license": "MIT", "dependencies": { "@algolia/autocomplete-plugin-algolia-insights": "1.19.2", @@ -224,8 +218,6 @@ }, "node_modules/@algolia/autocomplete-plugin-algolia-insights": { "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.19.2.tgz", - "integrity": "sha512-TjxbcC/r4vwmnZaPwrHtkXNeqvlpdyR+oR9Wi2XyfORkiGkLTVhX2j+O9SaCCINbKoDfc+c2PB8NjfOnz7+oKg==", "license": "MIT", "dependencies": { "@algolia/autocomplete-shared": "1.19.2" @@ -236,8 +228,6 @@ }, "node_modules/@algolia/autocomplete-shared": { "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.19.2.tgz", - "integrity": "sha512-jEazxZTVD2nLrC+wYlVHQgpBoBB5KPStrJxLzsIFl6Kqd1AlG9sIAGl39V5tECLpIQzB3Qa2T6ZPJ1ChkwMK/w==", "license": "MIT", "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", @@ -245,100 +235,85 @@ } }, "node_modules/@algolia/client-abtesting": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.46.1.tgz", - "integrity": "sha512-5SWfl0UGuKxMBYlU2Y9BnlIKKEyhFU5jHE9F9jAd8nbhxZNLk0y7fXE+AZeFtyK1lkVw6O4B/e6c3XIVVCkmqw==", + "version": "5.46.0", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.46.1", - "@algolia/requester-browser-xhr": "5.46.1", - "@algolia/requester-fetch": "5.46.1", - "@algolia/requester-node-http": "5.46.1" + "@algolia/client-common": "5.46.0", + "@algolia/requester-browser-xhr": "5.46.0", + "@algolia/requester-fetch": "5.46.0", + "@algolia/requester-node-http": "5.46.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-analytics": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.46.1.tgz", - "integrity": "sha512-496K6B1l/0Jvyp3MbW/YIgmm1a6nkTrKXBM7DoEy9YAOJ8GywGpa2UYjNCW1UrOTt+em1ECzDjRx7PIzTR9YvA==", + "version": "5.46.0", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.46.1", - "@algolia/requester-browser-xhr": "5.46.1", - "@algolia/requester-fetch": "5.46.1", - "@algolia/requester-node-http": "5.46.1" + "@algolia/client-common": "5.46.0", + "@algolia/requester-browser-xhr": "5.46.0", + "@algolia/requester-fetch": "5.46.0", + "@algolia/requester-node-http": "5.46.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-common": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.46.1.tgz", - "integrity": "sha512-3u6AuZ1Kiss6V5JPuZfVIUYfPi8im06QBCgKqLg82GUBJ3SwhiTdSZFIEgz2mzFuitFdW1PQi3c/65zE/3FgIw==", + "version": "5.46.0", "license": "MIT", "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-insights": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.46.1.tgz", - "integrity": "sha512-LwuWjdO35HHl1rxtdn48t920Xl26Dl0SMxjxjFeAK/OwK/pIVfYjOZl/f3Pnm7Kixze+6HjpByVxEaqhTuAFaw==", + "version": "5.46.0", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.46.1", - "@algolia/requester-browser-xhr": "5.46.1", - "@algolia/requester-fetch": "5.46.1", - "@algolia/requester-node-http": "5.46.1" + "@algolia/client-common": "5.46.0", + "@algolia/requester-browser-xhr": "5.46.0", + "@algolia/requester-fetch": "5.46.0", + "@algolia/requester-node-http": "5.46.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-personalization": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.46.1.tgz", - "integrity": "sha512-6LvJAlfEsn9SVq63MYAFX2iUxztUK2Q7BVZtI1vN87lDiJ/tSVFKgKS/jBVO03A39ePxJQiFv6EKv7lmoGlWtQ==", + "version": "5.46.0", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.46.1", - "@algolia/requester-browser-xhr": "5.46.1", - "@algolia/requester-fetch": "5.46.1", - "@algolia/requester-node-http": "5.46.1" + "@algolia/client-common": "5.46.0", + "@algolia/requester-browser-xhr": "5.46.0", + "@algolia/requester-fetch": "5.46.0", + "@algolia/requester-node-http": "5.46.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-query-suggestions": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.46.1.tgz", - "integrity": "sha512-9GLUCyGGo7YOXHcNqbzca82XYHJTbuiI6iT0FTGc0BrnV2N4OcrznUuVKic/duiLSun5gcy/G2Bciw5Sav9f9w==", + "version": "5.46.0", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.46.1", - "@algolia/requester-browser-xhr": "5.46.1", - "@algolia/requester-fetch": "5.46.1", - "@algolia/requester-node-http": "5.46.1" + "@algolia/client-common": "5.46.0", + "@algolia/requester-browser-xhr": "5.46.0", + "@algolia/requester-fetch": "5.46.0", + "@algolia/requester-node-http": "5.46.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-search": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.46.1.tgz", - "integrity": "sha512-NL76o/BoEgU4ObY5oBEC3o6KSPpuXsnSta00tAxTm1iKUWOGR34DQEKhUt8xMHhMKleUNPM/rLPFiIVtfsGU8w==", + "version": "5.46.0", "license": "MIT", - "peer": true, "dependencies": { - "@algolia/client-common": "5.46.1", - "@algolia/requester-browser-xhr": "5.46.1", - "@algolia/requester-fetch": "5.46.1", - "@algolia/requester-node-http": "5.46.1" + "@algolia/client-common": "5.46.0", + "@algolia/requester-browser-xhr": "5.46.0", + "@algolia/requester-fetch": "5.46.0", + "@algolia/requester-node-http": "5.46.0" }, "engines": { "node": ">= 14.0.0" @@ -346,86 +321,72 @@ }, "node_modules/@algolia/events": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", - "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==", "license": "MIT" }, "node_modules/@algolia/ingestion": { - "version": "1.46.1", - "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.46.1.tgz", - "integrity": "sha512-52Nc8WKC1FFXsdlXlTMl1Re/pTAbd2DiJiNdYmgHiikZcfF96G+Opx4qKiLUG1q7zp9e+ahNwXF6ED0XChMywg==", + "version": "1.46.0", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.46.1", - "@algolia/requester-browser-xhr": "5.46.1", - "@algolia/requester-fetch": "5.46.1", - "@algolia/requester-node-http": "5.46.1" + "@algolia/client-common": "5.46.0", + "@algolia/requester-browser-xhr": "5.46.0", + "@algolia/requester-fetch": "5.46.0", + "@algolia/requester-node-http": "5.46.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/monitoring": { - "version": "1.46.1", - "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.46.1.tgz", - "integrity": "sha512-1x2/2Y/eqz6l3QcEZ8u/zMhSCpjlhePyizJd3sXrmg031HjayYT5+IxikjpqkdF7TU/deCTd/TFUcxLJ2ZHXiQ==", + "version": "1.46.0", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.46.1", - "@algolia/requester-browser-xhr": "5.46.1", - "@algolia/requester-fetch": "5.46.1", - "@algolia/requester-node-http": "5.46.1" + "@algolia/client-common": "5.46.0", + "@algolia/requester-browser-xhr": "5.46.0", + "@algolia/requester-fetch": "5.46.0", + "@algolia/requester-node-http": "5.46.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/recommend": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.46.1.tgz", - "integrity": "sha512-SSd3KlQuplxV3aRs5+Z09XilFesgpPjtCG7BGRxLTVje5hn9BLmhjO4W3gKw01INUt44Z1r0Fwx5uqnhAouunA==", + "version": "5.46.0", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.46.1", - "@algolia/requester-browser-xhr": "5.46.1", - "@algolia/requester-fetch": "5.46.1", - "@algolia/requester-node-http": "5.46.1" + "@algolia/client-common": "5.46.0", + "@algolia/requester-browser-xhr": "5.46.0", + "@algolia/requester-fetch": "5.46.0", + "@algolia/requester-node-http": "5.46.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/requester-browser-xhr": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.46.1.tgz", - "integrity": "sha512-3GfCwudeW6/3caKSdmOP6RXZEL4F3GiemCaXEStkTt2Re8f7NcGYAAZnGlHsCzvhlNEuDzPYdYxh4UweY8l/2w==", + "version": "5.46.0", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.46.1" + "@algolia/client-common": "5.46.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/requester-fetch": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.46.1.tgz", - "integrity": "sha512-JUAxYfmnLYTVtAOFxVvXJ4GDHIhMuaP7JGyZXa/nCk3P8RrN5FCNTdRyftSnxyzwSIAd8qH3CjdBS9WwxxqcHQ==", + "version": "5.46.0", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.46.1" + "@algolia/client-common": "5.46.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/requester-node-http": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.46.1.tgz", - "integrity": "sha512-VwbhV1xvTGiek3d2pOS6vNBC4dtbNadyRT+i1niZpGhOJWz1XnfhxNboVbXPGAyMJYz7kDrolbDvEzIDT93uUA==", + "version": "5.46.0", "license": "MIT", "dependencies": { - "@algolia/client-common": "5.46.1" + "@algolia/client-common": "5.46.0" }, "engines": { "node": ">= 14.0.0" @@ -433,8 +394,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">=10" @@ -445,8 +404,6 @@ }, "node_modules/@antfu/install-pkg": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.1.0.tgz", - "integrity": "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==", "license": "MIT", "dependencies": { "package-manager-detector": "^1.3.0", @@ -458,8 +415,6 @@ }, "node_modules/@babel/code-frame": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", @@ -472,8 +427,6 @@ }, "node_modules/@babel/compat-data": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", - "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -481,8 +434,6 @@ }, "node_modules/@babel/core": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", - "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", @@ -511,8 +462,6 @@ }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -520,8 +469,6 @@ }, "node_modules/@babel/generator": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", - "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", "license": "MIT", "dependencies": { "@babel/parser": "^7.28.5", @@ -536,8 +483,6 @@ }, "node_modules/@babel/helper-annotate-as-pure": { "version": "7.27.3", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", - "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", "license": "MIT", "dependencies": { "@babel/types": "^7.27.3" @@ -548,8 +493,6 @@ }, "node_modules/@babel/helper-compilation-targets": { "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", "license": "MIT", "dependencies": { "@babel/compat-data": "^7.27.2", @@ -564,8 +507,6 @@ }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -573,8 +514,6 @@ }, "node_modules/@babel/helper-create-class-features-plugin": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz", - "integrity": "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==", "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", @@ -594,8 +533,6 @@ }, "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -603,8 +540,6 @@ }, "node_modules/@babel/helper-create-regexp-features-plugin": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz", - "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==", "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", @@ -620,8 +555,6 @@ }, "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -629,8 +562,6 @@ }, "node_modules/@babel/helper-define-polyfill-provider": { "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", - "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", @@ -645,8 +576,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -654,8 +583,6 @@ }, "node_modules/@babel/helper-member-expression-to-functions": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", - "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", "license": "MIT", "dependencies": { "@babel/traverse": "^7.28.5", @@ -667,8 +594,6 @@ }, "node_modules/@babel/helper-module-imports": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", "license": "MIT", "dependencies": { "@babel/traverse": "^7.27.1", @@ -680,8 +605,6 @@ }, "node_modules/@babel/helper-module-transforms": { "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", - "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.27.1", @@ -697,8 +620,6 @@ }, "node_modules/@babel/helper-optimise-call-expression": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", - "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", "license": "MIT", "dependencies": { "@babel/types": "^7.27.1" @@ -709,8 +630,6 @@ }, "node_modules/@babel/helper-plugin-utils": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -718,8 +637,6 @@ }, "node_modules/@babel/helper-remap-async-to-generator": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", - "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", @@ -735,8 +652,6 @@ }, "node_modules/@babel/helper-replace-supers": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", - "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", "license": "MIT", "dependencies": { "@babel/helper-member-expression-to-functions": "^7.27.1", @@ -752,8 +667,6 @@ }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", - "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", "license": "MIT", "dependencies": { "@babel/traverse": "^7.27.1", @@ -765,8 +678,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -774,8 +685,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -783,8 +692,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -792,8 +699,6 @@ }, "node_modules/@babel/helper-wrap-function": { "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz", - "integrity": "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==", "license": "MIT", "dependencies": { "@babel/template": "^7.27.2", @@ -806,8 +711,6 @@ }, "node_modules/@babel/helpers": { "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", - "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", "license": "MIT", "dependencies": { "@babel/template": "^7.27.2", @@ -819,8 +722,6 @@ }, "node_modules/@babel/parser": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", - "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", "license": "MIT", "dependencies": { "@babel/types": "^7.28.5" @@ -834,8 +735,6 @@ }, "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz", - "integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", @@ -850,8 +749,6 @@ }, "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", - "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -865,8 +762,6 @@ }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", - "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -880,8 +775,6 @@ }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", - "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", @@ -897,8 +790,6 @@ }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz", - "integrity": "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", @@ -913,8 +804,6 @@ }, "node_modules/@babel/plugin-proposal-private-property-in-object": { "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -925,8 +814,6 @@ }, "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": { @@ -938,8 +825,6 @@ }, "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": { @@ -951,8 +836,6 @@ }, "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": { @@ -964,8 +847,6 @@ }, "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": { @@ -980,8 +861,6 @@ }, "node_modules/@babel/plugin-syntax-dynamic-import": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" @@ -992,8 +871,6 @@ }, "node_modules/@babel/plugin-syntax-import-assertions": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz", - "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1007,8 +884,6 @@ }, "node_modules/@babel/plugin-syntax-import-attributes": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", - "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1022,8 +897,6 @@ }, "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": { @@ -1035,8 +908,6 @@ }, "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": { @@ -1048,8 +919,6 @@ }, "node_modules/@babel/plugin-syntax-jsx": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", - "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1063,8 +932,6 @@ }, "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": { @@ -1076,8 +943,6 @@ }, "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": { @@ -1089,8 +954,6 @@ }, "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": { @@ -1102,8 +965,6 @@ }, "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": { @@ -1115,8 +976,6 @@ }, "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": { @@ -1128,8 +987,6 @@ }, "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": { @@ -1141,8 +998,6 @@ }, "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": { @@ -1157,8 +1012,6 @@ }, "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": { @@ -1173,8 +1026,6 @@ }, "node_modules/@babel/plugin-syntax-typescript": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", - "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1188,8 +1039,6 @@ }, "node_modules/@babel/plugin-syntax-unicode-sets-regex": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", @@ -1204,8 +1053,6 @@ }, "node_modules/@babel/plugin-transform-arrow-functions": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", - "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1219,8 +1066,6 @@ }, "node_modules/@babel/plugin-transform-async-generator-functions": { "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz", - "integrity": "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", @@ -1236,8 +1081,6 @@ }, "node_modules/@babel/plugin-transform-async-to-generator": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz", - "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.27.1", @@ -1253,8 +1096,6 @@ }, "node_modules/@babel/plugin-transform-block-scoped-functions": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", - "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1268,8 +1109,6 @@ }, "node_modules/@babel/plugin-transform-block-scoping": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz", - "integrity": "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1283,8 +1122,6 @@ }, "node_modules/@babel/plugin-transform-class-properties": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", - "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", @@ -1299,8 +1136,6 @@ }, "node_modules/@babel/plugin-transform-class-static-block": { "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz", - "integrity": "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==", "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.28.3", @@ -1315,8 +1150,6 @@ }, "node_modules/@babel/plugin-transform-classes": { "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz", - "integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==", "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", @@ -1335,8 +1168,6 @@ }, "node_modules/@babel/plugin-transform-computed-properties": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", - "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", @@ -1351,8 +1182,6 @@ }, "node_modules/@babel/plugin-transform-destructuring": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz", - "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", @@ -1367,8 +1196,6 @@ }, "node_modules/@babel/plugin-transform-dotall-regex": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz", - "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==", "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", @@ -1383,8 +1210,6 @@ }, "node_modules/@babel/plugin-transform-duplicate-keys": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", - "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1398,8 +1223,6 @@ }, "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz", - "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==", "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", @@ -1414,8 +1237,6 @@ }, "node_modules/@babel/plugin-transform-dynamic-import": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", - "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1429,8 +1250,6 @@ }, "node_modules/@babel/plugin-transform-explicit-resource-management": { "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz", - "integrity": "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", @@ -1445,8 +1264,6 @@ }, "node_modules/@babel/plugin-transform-exponentiation-operator": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.5.tgz", - "integrity": "sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1460,8 +1277,6 @@ }, "node_modules/@babel/plugin-transform-export-namespace-from": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", - "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1475,8 +1290,6 @@ }, "node_modules/@babel/plugin-transform-for-of": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", - "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", @@ -1491,8 +1304,6 @@ }, "node_modules/@babel/plugin-transform-function-name": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", - "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.27.1", @@ -1508,8 +1319,6 @@ }, "node_modules/@babel/plugin-transform-json-strings": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz", - "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1523,8 +1332,6 @@ }, "node_modules/@babel/plugin-transform-literals": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", - "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1538,8 +1345,6 @@ }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz", - "integrity": "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1553,8 +1358,6 @@ }, "node_modules/@babel/plugin-transform-member-expression-literals": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", - "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1568,8 +1371,6 @@ }, "node_modules/@babel/plugin-transform-modules-amd": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", - "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.27.1", @@ -1584,8 +1385,6 @@ }, "node_modules/@babel/plugin-transform-modules-commonjs": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", - "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.27.1", @@ -1600,8 +1399,6 @@ }, "node_modules/@babel/plugin-transform-modules-systemjs": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz", - "integrity": "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==", "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.28.3", @@ -1618,8 +1415,6 @@ }, "node_modules/@babel/plugin-transform-modules-umd": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", - "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.27.1", @@ -1634,8 +1429,6 @@ }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", - "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", @@ -1650,8 +1443,6 @@ }, "node_modules/@babel/plugin-transform-new-target": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", - "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1665,8 +1456,6 @@ }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", - "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1680,8 +1469,6 @@ }, "node_modules/@babel/plugin-transform-numeric-separator": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz", - "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1695,8 +1482,6 @@ }, "node_modules/@babel/plugin-transform-object-rest-spread": { "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz", - "integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==", "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.27.2", @@ -1714,8 +1499,6 @@ }, "node_modules/@babel/plugin-transform-object-super": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", - "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", @@ -1730,8 +1513,6 @@ }, "node_modules/@babel/plugin-transform-optional-catch-binding": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz", - "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1745,8 +1526,6 @@ }, "node_modules/@babel/plugin-transform-optional-chaining": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz", - "integrity": "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", @@ -1761,8 +1540,6 @@ }, "node_modules/@babel/plugin-transform-parameters": { "version": "7.27.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", - "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1776,8 +1553,6 @@ }, "node_modules/@babel/plugin-transform-private-methods": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", - "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.27.1", @@ -1792,8 +1567,6 @@ }, "node_modules/@babel/plugin-transform-private-property-in-object": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz", - "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==", "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", @@ -1809,8 +1582,6 @@ }, "node_modules/@babel/plugin-transform-property-literals": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", - "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1824,8 +1595,6 @@ }, "node_modules/@babel/plugin-transform-react-constant-elements": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.27.1.tgz", - "integrity": "sha512-edoidOjl/ZxvYo4lSBOQGDSyToYVkTAwyVoa2tkuYTSmjrB1+uAedoL5iROVLXkxH+vRgA7uP4tMg2pUJpZ3Ug==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1839,8 +1608,6 @@ }, "node_modules/@babel/plugin-transform-react-display-name": { "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.28.0.tgz", - "integrity": "sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1854,8 +1621,6 @@ }, "node_modules/@babel/plugin-transform-react-jsx": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz", - "integrity": "sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw==", "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", @@ -1873,8 +1638,6 @@ }, "node_modules/@babel/plugin-transform-react-jsx-development": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.27.1.tgz", - "integrity": "sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==", "license": "MIT", "dependencies": { "@babel/plugin-transform-react-jsx": "^7.27.1" @@ -1888,8 +1651,6 @@ }, "node_modules/@babel/plugin-transform-react-pure-annotations": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz", - "integrity": "sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==", "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.1", @@ -1904,8 +1665,6 @@ }, "node_modules/@babel/plugin-transform-regenerator": { "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz", - "integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1919,8 +1678,6 @@ }, "node_modules/@babel/plugin-transform-regexp-modifiers": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz", - "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==", "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", @@ -1935,8 +1692,6 @@ }, "node_modules/@babel/plugin-transform-reserved-words": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", - "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1950,8 +1705,6 @@ }, "node_modules/@babel/plugin-transform-runtime": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.5.tgz", - "integrity": "sha512-20NUVgOrinudkIBzQ2bNxP08YpKprUkRTiRSd2/Z5GOdPImJGkoN4Z7IQe1T5AdyKI1i5L6RBmluqdSzvaq9/w==", "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.27.1", @@ -1970,8 +1723,6 @@ }, "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -1979,8 +1730,6 @@ }, "node_modules/@babel/plugin-transform-shorthand-properties": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", - "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -1994,8 +1743,6 @@ }, "node_modules/@babel/plugin-transform-spread": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz", - "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", @@ -2010,8 +1757,6 @@ }, "node_modules/@babel/plugin-transform-sticky-regex": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", - "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -2025,8 +1770,6 @@ }, "node_modules/@babel/plugin-transform-template-literals": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", - "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -2040,8 +1783,6 @@ }, "node_modules/@babel/plugin-transform-typeof-symbol": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", - "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -2055,8 +1796,6 @@ }, "node_modules/@babel/plugin-transform-typescript": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.5.tgz", - "integrity": "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA==", "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", @@ -2074,8 +1813,6 @@ }, "node_modules/@babel/plugin-transform-unicode-escapes": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", - "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" @@ -2089,8 +1826,6 @@ }, "node_modules/@babel/plugin-transform-unicode-property-regex": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz", - "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==", "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", @@ -2105,8 +1840,6 @@ }, "node_modules/@babel/plugin-transform-unicode-regex": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", - "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", @@ -2121,8 +1854,6 @@ }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz", - "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==", "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.27.1", @@ -2137,8 +1868,6 @@ }, "node_modules/@babel/preset-env": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.5.tgz", - "integrity": "sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg==", "license": "MIT", "dependencies": { "@babel/compat-data": "^7.28.5", @@ -2221,8 +1950,6 @@ }, "node_modules/@babel/preset-env/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -2230,8 +1957,6 @@ }, "node_modules/@babel/preset-modules": { "version": "0.1.6-no-external-plugins", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", - "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", @@ -2244,8 +1969,6 @@ }, "node_modules/@babel/preset-react": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.28.5.tgz", - "integrity": "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", @@ -2264,8 +1987,6 @@ }, "node_modules/@babel/preset-typescript": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz", - "integrity": "sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==", "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", @@ -2283,8 +2004,6 @@ }, "node_modules/@babel/runtime": { "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", - "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -2292,8 +2011,6 @@ }, "node_modules/@babel/runtime-corejs3": { "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.28.4.tgz", - "integrity": "sha512-h7iEYiW4HebClDEhtvFObtPmIvrd1SSfpI9EhOeKk4CtIK/ngBWFpuhCzhdmRKtg71ylcue+9I6dv54XYO1epQ==", "license": "MIT", "dependencies": { "core-js-pure": "^3.43.0" @@ -2304,8 +2021,6 @@ }, "node_modules/@babel/template": { "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", @@ -2318,8 +2033,6 @@ }, "node_modules/@babel/traverse": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", - "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.27.1", @@ -2336,8 +2049,6 @@ }, "node_modules/@babel/types": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", - "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -2349,21 +2060,15 @@ }, "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/@braintree/sanitize-url": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.1.tgz", - "integrity": "sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw==", "license": "MIT" }, "node_modules/@chevrotain/cst-dts-gen": { "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz", - "integrity": "sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==", "license": "Apache-2.0", "dependencies": { "@chevrotain/gast": "11.0.3", @@ -2371,50 +2076,28 @@ "lodash-es": "4.17.21" } }, - "node_modules/@chevrotain/cst-dts-gen/node_modules/lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", - "license": "MIT" - }, "node_modules/@chevrotain/gast": { "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.0.3.tgz", - "integrity": "sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==", "license": "Apache-2.0", "dependencies": { "@chevrotain/types": "11.0.3", "lodash-es": "4.17.21" } }, - "node_modules/@chevrotain/gast/node_modules/lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", - "license": "MIT" - }, "node_modules/@chevrotain/regexp-to-ast": { "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz", - "integrity": "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==", "license": "Apache-2.0" }, "node_modules/@chevrotain/types": { "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.0.3.tgz", - "integrity": "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==", "license": "Apache-2.0" }, "node_modules/@chevrotain/utils": { "version": "11.0.3", - "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.0.3.tgz", - "integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==", "license": "Apache-2.0" }, "node_modules/@colors/colors": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", "license": "MIT", "optional": true, "engines": { @@ -2423,8 +2106,6 @@ }, "node_modules/@csstools/cascade-layer-name-parser": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@csstools/cascade-layer-name-parser/-/cascade-layer-name-parser-2.0.5.tgz", - "integrity": "sha512-p1ko5eHgV+MgXFVa4STPKpvPxr6ReS8oS2jzTukjR74i5zJNyWO1ZM1m8YKBXnzDKWfBN1ztLYlHxbVemDD88A==", "funding": [ { "type": "github", @@ -2446,8 +2127,6 @@ }, "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==", "funding": [ { "type": "github", @@ -2465,8 +2144,6 @@ }, "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==", "funding": [ { "type": "github", @@ -2488,8 +2165,6 @@ }, "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==", "funding": [ { "type": "github", @@ -2515,8 +2190,6 @@ }, "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==", "funding": [ { "type": "github", @@ -2528,7 +2201,6 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -2538,8 +2210,6 @@ }, "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==", "funding": [ { "type": "github", @@ -2551,15 +2221,12 @@ } ], "license": "MIT", - "peer": true, "engines": { "node": ">=18" } }, "node_modules/@csstools/media-query-list-parser": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.3.tgz", - "integrity": "sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==", "funding": [ { "type": "github", @@ -2581,8 +2248,6 @@ }, "node_modules/@csstools/postcss-alpha-function": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-alpha-function/-/postcss-alpha-function-1.0.1.tgz", - "integrity": "sha512-isfLLwksH3yHkFXfCI2Gcaqg7wGGHZZwunoJzEZk0yKYIokgre6hYVFibKL3SYAoR1kBXova8LB+JoO5vZzi9w==", "funding": [ { "type": "github", @@ -2610,8 +2275,6 @@ }, "node_modules/@csstools/postcss-cascade-layers": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@csstools/postcss-cascade-layers/-/postcss-cascade-layers-5.0.2.tgz", - "integrity": "sha512-nWBE08nhO8uWl6kSAeCx4im7QfVko3zLrtgWZY4/bP87zrSPpSyN/3W3TDqz1jJuH+kbKOHXg5rJnK+ZVYcFFg==", "funding": [ { "type": "github", @@ -2636,8 +2299,6 @@ }, "node_modules/@csstools/postcss-cascade-layers/node_modules/@csstools/selector-specificity": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", - "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", "funding": [ { "type": "github", @@ -2658,10 +2319,7 @@ }, "node_modules/@csstools/postcss-cascade-layers/node_modules/postcss-selector-parser": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", - "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -2672,8 +2330,6 @@ }, "node_modules/@csstools/postcss-color-function": { "version": "4.0.12", - "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function/-/postcss-color-function-4.0.12.tgz", - "integrity": "sha512-yx3cljQKRaSBc2hfh8rMZFZzChaFgwmO2JfFgFr1vMcF3C/uyy5I4RFIBOIWGq1D+XbKCG789CGkG6zzkLpagA==", "funding": [ { "type": "github", @@ -2701,8 +2357,6 @@ }, "node_modules/@csstools/postcss-color-function-display-p3-linear": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-color-function-display-p3-linear/-/postcss-color-function-display-p3-linear-1.0.1.tgz", - "integrity": "sha512-E5qusdzhlmO1TztYzDIi8XPdPoYOjoTY6HBYBCYSj+Gn4gQRBlvjgPQXzfzuPQqt8EhkC/SzPKObg4Mbn8/xMg==", "funding": [ { "type": "github", @@ -2730,8 +2384,6 @@ }, "node_modules/@csstools/postcss-color-mix-function": { "version": "3.0.12", - "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-function/-/postcss-color-mix-function-3.0.12.tgz", - "integrity": "sha512-4STERZfCP5Jcs13P1U5pTvI9SkgLgfMUMhdXW8IlJWkzOOOqhZIjcNhWtNJZes2nkBDsIKJ0CJtFtuaZ00moag==", "funding": [ { "type": "github", @@ -2759,8 +2411,6 @@ }, "node_modules/@csstools/postcss-color-mix-variadic-function-arguments": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@csstools/postcss-color-mix-variadic-function-arguments/-/postcss-color-mix-variadic-function-arguments-1.0.2.tgz", - "integrity": "sha512-rM67Gp9lRAkTo+X31DUqMEq+iK+EFqsidfecmhrteErxJZb6tUoJBVQca1Vn1GpDql1s1rD1pKcuYzMsg7Z1KQ==", "funding": [ { "type": "github", @@ -2788,8 +2438,6 @@ }, "node_modules/@csstools/postcss-content-alt-text": { "version": "2.0.8", - "resolved": "https://registry.npmjs.org/@csstools/postcss-content-alt-text/-/postcss-content-alt-text-2.0.8.tgz", - "integrity": "sha512-9SfEW9QCxEpTlNMnpSqFaHyzsiRpZ5J5+KqCu1u5/eEJAWsMhzT40qf0FIbeeglEvrGRMdDzAxMIz3wqoGSb+Q==", "funding": [ { "type": "github", @@ -2816,8 +2464,6 @@ }, "node_modules/@csstools/postcss-contrast-color-function": { "version": "2.0.12", - "resolved": "https://registry.npmjs.org/@csstools/postcss-contrast-color-function/-/postcss-contrast-color-function-2.0.12.tgz", - "integrity": "sha512-YbwWckjK3qwKjeYz/CijgcS7WDUCtKTd8ShLztm3/i5dhh4NaqzsbYnhm4bjrpFpnLZ31jVcbK8YL77z3GBPzA==", "funding": [ { "type": "github", @@ -2845,8 +2491,6 @@ }, "node_modules/@csstools/postcss-exponential-functions": { "version": "2.0.9", - "resolved": "https://registry.npmjs.org/@csstools/postcss-exponential-functions/-/postcss-exponential-functions-2.0.9.tgz", - "integrity": "sha512-abg2W/PI3HXwS/CZshSa79kNWNZHdJPMBXeZNyPQFbbj8sKO3jXxOt/wF7juJVjyDTc6JrvaUZYFcSBZBhaxjw==", "funding": [ { "type": "github", @@ -2872,8 +2516,6 @@ }, "node_modules/@csstools/postcss-font-format-keywords": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-4.0.0.tgz", - "integrity": "sha512-usBzw9aCRDvchpok6C+4TXC57btc4bJtmKQWOHQxOVKen1ZfVqBUuCZ/wuqdX5GHsD0NRSr9XTP+5ID1ZZQBXw==", "funding": [ { "type": "github", @@ -2898,8 +2540,6 @@ }, "node_modules/@csstools/postcss-gamut-mapping": { "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@csstools/postcss-gamut-mapping/-/postcss-gamut-mapping-2.0.11.tgz", - "integrity": "sha512-fCpCUgZNE2piVJKC76zFsgVW1apF6dpYsqGyH8SIeCcM4pTEsRTWTLCaJIMKFEundsCKwY1rwfhtrio04RJ4Dw==", "funding": [ { "type": "github", @@ -2925,8 +2565,6 @@ }, "node_modules/@csstools/postcss-gradients-interpolation-method": { "version": "5.0.12", - "resolved": "https://registry.npmjs.org/@csstools/postcss-gradients-interpolation-method/-/postcss-gradients-interpolation-method-5.0.12.tgz", - "integrity": "sha512-jugzjwkUY0wtNrZlFeyXzimUL3hN4xMvoPnIXxoZqxDvjZRiSh+itgHcVUWzJ2VwD/VAMEgCLvtaJHX+4Vj3Ow==", "funding": [ { "type": "github", @@ -2954,8 +2592,6 @@ }, "node_modules/@csstools/postcss-hwb-function": { "version": "4.0.12", - "resolved": "https://registry.npmjs.org/@csstools/postcss-hwb-function/-/postcss-hwb-function-4.0.12.tgz", - "integrity": "sha512-mL/+88Z53KrE4JdePYFJAQWFrcADEqsLprExCM04GDNgHIztwFzj0Mbhd/yxMBngq0NIlz58VVxjt5abNs1VhA==", "funding": [ { "type": "github", @@ -2983,8 +2619,6 @@ }, "node_modules/@csstools/postcss-ic-unit": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@csstools/postcss-ic-unit/-/postcss-ic-unit-4.0.4.tgz", - "integrity": "sha512-yQ4VmossuOAql65sCPppVO1yfb7hDscf4GseF0VCA/DTDaBc0Wtf8MTqVPfjGYlT5+2buokG0Gp7y0atYZpwjg==", "funding": [ { "type": "github", @@ -3010,8 +2644,6 @@ }, "node_modules/@csstools/postcss-initial": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-initial/-/postcss-initial-2.0.1.tgz", - "integrity": "sha512-L1wLVMSAZ4wovznquK0xmC7QSctzO4D0Is590bxpGqhqjboLXYA16dWZpfwImkdOgACdQ9PqXsuRroW6qPlEsg==", "funding": [ { "type": "github", @@ -3032,8 +2664,6 @@ }, "node_modules/@csstools/postcss-is-pseudo-class": { "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-5.0.3.tgz", - "integrity": "sha512-jS/TY4SpG4gszAtIg7Qnf3AS2pjcUM5SzxpApOrlndMeGhIbaTzWBzzP/IApXoNWEW7OhcjkRT48jnAUIFXhAQ==", "funding": [ { "type": "github", @@ -3058,8 +2688,6 @@ }, "node_modules/@csstools/postcss-is-pseudo-class/node_modules/@csstools/selector-specificity": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", - "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", "funding": [ { "type": "github", @@ -3080,10 +2708,7 @@ }, "node_modules/@csstools/postcss-is-pseudo-class/node_modules/postcss-selector-parser": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", - "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -3094,8 +2719,6 @@ }, "node_modules/@csstools/postcss-light-dark-function": { "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@csstools/postcss-light-dark-function/-/postcss-light-dark-function-2.0.11.tgz", - "integrity": "sha512-fNJcKXJdPM3Lyrbmgw2OBbaioU7yuKZtiXClf4sGdQttitijYlZMD5K7HrC/eF83VRWRrYq6OZ0Lx92leV2LFA==", "funding": [ { "type": "github", @@ -3122,8 +2745,6 @@ }, "node_modules/@csstools/postcss-logical-float-and-clear": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-float-and-clear/-/postcss-logical-float-and-clear-3.0.0.tgz", - "integrity": "sha512-SEmaHMszwakI2rqKRJgE+8rpotFfne1ZS6bZqBoQIicFyV+xT1UF42eORPxJkVJVrH9C0ctUgwMSn3BLOIZldQ==", "funding": [ { "type": "github", @@ -3144,8 +2765,6 @@ }, "node_modules/@csstools/postcss-logical-overflow": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-overflow/-/postcss-logical-overflow-2.0.0.tgz", - "integrity": "sha512-spzR1MInxPuXKEX2csMamshR4LRaSZ3UXVaRGjeQxl70ySxOhMpP2252RAFsg8QyyBXBzuVOOdx1+bVO5bPIzA==", "funding": [ { "type": "github", @@ -3166,8 +2785,6 @@ }, "node_modules/@csstools/postcss-logical-overscroll-behavior": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-overscroll-behavior/-/postcss-logical-overscroll-behavior-2.0.0.tgz", - "integrity": "sha512-e/webMjoGOSYfqLunyzByZj5KKe5oyVg/YSbie99VEaSDE2kimFm0q1f6t/6Jo+VVCQ/jbe2Xy+uX+C4xzWs4w==", "funding": [ { "type": "github", @@ -3188,8 +2805,6 @@ }, "node_modules/@csstools/postcss-logical-resize": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-resize/-/postcss-logical-resize-3.0.0.tgz", - "integrity": "sha512-DFbHQOFW/+I+MY4Ycd/QN6Dg4Hcbb50elIJCfnwkRTCX05G11SwViI5BbBlg9iHRl4ytB7pmY5ieAFk3ws7yyg==", "funding": [ { "type": "github", @@ -3213,8 +2828,6 @@ }, "node_modules/@csstools/postcss-logical-viewport-units": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@csstools/postcss-logical-viewport-units/-/postcss-logical-viewport-units-3.0.4.tgz", - "integrity": "sha512-q+eHV1haXA4w9xBwZLKjVKAWn3W2CMqmpNpZUk5kRprvSiBEGMgrNH3/sJZ8UA3JgyHaOt3jwT9uFa4wLX4EqQ==", "funding": [ { "type": "github", @@ -3239,8 +2852,6 @@ }, "node_modules/@csstools/postcss-media-minmax": { "version": "2.0.9", - "resolved": "https://registry.npmjs.org/@csstools/postcss-media-minmax/-/postcss-media-minmax-2.0.9.tgz", - "integrity": "sha512-af9Qw3uS3JhYLnCbqtZ9crTvvkR+0Se+bBqSr7ykAnl9yKhk6895z9rf+2F4dClIDJWxgn0iZZ1PSdkhrbs2ig==", "funding": [ { "type": "github", @@ -3267,8 +2878,6 @@ }, "node_modules/@csstools/postcss-media-queries-aspect-ratio-number-values": { "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@csstools/postcss-media-queries-aspect-ratio-number-values/-/postcss-media-queries-aspect-ratio-number-values-3.0.5.tgz", - "integrity": "sha512-zhAe31xaaXOY2Px8IYfoVTB3wglbJUVigGphFLj6exb7cjZRH9A6adyE22XfFK3P2PzwRk0VDeTJmaxpluyrDg==", "funding": [ { "type": "github", @@ -3294,8 +2903,6 @@ }, "node_modules/@csstools/postcss-nested-calc": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-nested-calc/-/postcss-nested-calc-4.0.0.tgz", - "integrity": "sha512-jMYDdqrQQxE7k9+KjstC3NbsmC063n1FTPLCgCRS2/qHUbHM0mNy9pIn4QIiQGs9I/Bg98vMqw7mJXBxa0N88A==", "funding": [ { "type": "github", @@ -3320,8 +2927,6 @@ }, "node_modules/@csstools/postcss-normalize-display-values": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.0.tgz", - "integrity": "sha512-HlEoG0IDRoHXzXnkV4in47dzsxdsjdz6+j7MLjaACABX2NfvjFS6XVAnpaDyGesz9gK2SC7MbNwdCHusObKJ9Q==", "funding": [ { "type": "github", @@ -3345,8 +2950,6 @@ }, "node_modules/@csstools/postcss-oklab-function": { "version": "4.0.12", - "resolved": "https://registry.npmjs.org/@csstools/postcss-oklab-function/-/postcss-oklab-function-4.0.12.tgz", - "integrity": "sha512-HhlSmnE1NKBhXsTnNGjxvhryKtO7tJd1w42DKOGFD6jSHtYOrsJTQDKPMwvOfrzUAk8t7GcpIfRyM7ssqHpFjg==", "funding": [ { "type": "github", @@ -3374,8 +2977,6 @@ }, "node_modules/@csstools/postcss-position-area-property": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-position-area-property/-/postcss-position-area-property-1.0.0.tgz", - "integrity": "sha512-fUP6KR8qV2NuUZV3Cw8itx0Ep90aRjAZxAEzC3vrl6yjFv+pFsQbR18UuQctEKmA72K9O27CoYiKEgXxkqjg8Q==", "funding": [ { "type": "github", @@ -3396,8 +2997,6 @@ }, "node_modules/@csstools/postcss-progressive-custom-properties": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-4.2.1.tgz", - "integrity": "sha512-uPiiXf7IEKtUQXsxu6uWtOlRMXd2QWWy5fhxHDnPdXKCQckPP3E34ZgDoZ62r2iT+UOgWsSbM4NvHE5m3mAEdw==", "funding": [ { "type": "github", @@ -3421,8 +3020,6 @@ }, "node_modules/@csstools/postcss-random-function": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-random-function/-/postcss-random-function-2.0.1.tgz", - "integrity": "sha512-q+FQaNiRBhnoSNo+GzqGOIBKoHQ43lYz0ICrV+UudfWnEF6ksS6DsBIJSISKQT2Bvu3g4k6r7t0zYrk5pDlo8w==", "funding": [ { "type": "github", @@ -3448,8 +3045,6 @@ }, "node_modules/@csstools/postcss-relative-color-syntax": { "version": "3.0.12", - "resolved": "https://registry.npmjs.org/@csstools/postcss-relative-color-syntax/-/postcss-relative-color-syntax-3.0.12.tgz", - "integrity": "sha512-0RLIeONxu/mtxRtf3o41Lq2ghLimw0w9ByLWnnEVuy89exmEEq8bynveBxNW3nyHqLAFEeNtVEmC1QK9MZ8Huw==", "funding": [ { "type": "github", @@ -3477,8 +3072,6 @@ }, "node_modules/@csstools/postcss-scope-pseudo-class": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@csstools/postcss-scope-pseudo-class/-/postcss-scope-pseudo-class-4.0.1.tgz", - "integrity": "sha512-IMi9FwtH6LMNuLea1bjVMQAsUhFxJnyLSgOp/cpv5hrzWmrUYU5fm0EguNDIIOHUqzXode8F/1qkC/tEo/qN8Q==", "funding": [ { "type": "github", @@ -3502,8 +3095,6 @@ }, "node_modules/@csstools/postcss-scope-pseudo-class/node_modules/postcss-selector-parser": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", - "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -3515,8 +3106,6 @@ }, "node_modules/@csstools/postcss-sign-functions": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@csstools/postcss-sign-functions/-/postcss-sign-functions-1.1.4.tgz", - "integrity": "sha512-P97h1XqRPcfcJndFdG95Gv/6ZzxUBBISem0IDqPZ7WMvc/wlO+yU0c5D/OCpZ5TJoTt63Ok3knGk64N+o6L2Pg==", "funding": [ { "type": "github", @@ -3542,8 +3131,6 @@ }, "node_modules/@csstools/postcss-stepped-value-functions": { "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-4.0.9.tgz", - "integrity": "sha512-h9btycWrsex4dNLeQfyU3y3w40LMQooJWFMm/SK9lrKguHDcFl4VMkncKKoXi2z5rM9YGWbUQABI8BT2UydIcA==", "funding": [ { "type": "github", @@ -3569,8 +3156,6 @@ }, "node_modules/@csstools/postcss-system-ui-font-family": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-system-ui-font-family/-/postcss-system-ui-font-family-1.0.0.tgz", - "integrity": "sha512-s3xdBvfWYfoPSBsikDXbuorcMG1nN1M6GdU0qBsGfcmNR0A/qhloQZpTxjA3Xsyrk1VJvwb2pOfiOT3at/DuIQ==", "funding": [ { "type": "github", @@ -3595,8 +3180,6 @@ }, "node_modules/@csstools/postcss-text-decoration-shorthand": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@csstools/postcss-text-decoration-shorthand/-/postcss-text-decoration-shorthand-4.0.3.tgz", - "integrity": "sha512-KSkGgZfx0kQjRIYnpsD7X2Om9BUXX/Kii77VBifQW9Ih929hK0KNjVngHDH0bFB9GmfWcR9vJYJJRvw/NQjkrA==", "funding": [ { "type": "github", @@ -3621,8 +3204,6 @@ }, "node_modules/@csstools/postcss-trigonometric-functions": { "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@csstools/postcss-trigonometric-functions/-/postcss-trigonometric-functions-4.0.9.tgz", - "integrity": "sha512-Hnh5zJUdpNrJqK9v1/E3BbrQhaDTj5YiX7P61TOvUhoDHnUmsNNxcDAgkQ32RrcWx9GVUvfUNPcUkn8R3vIX6A==", "funding": [ { "type": "github", @@ -3648,8 +3229,6 @@ }, "node_modules/@csstools/postcss-unset-value": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/postcss-unset-value/-/postcss-unset-value-4.0.0.tgz", - "integrity": "sha512-cBz3tOCI5Fw6NIFEwU3RiwK6mn3nKegjpJuzCndoGq3BZPkUjnsq7uQmIeMNeMbMk7YD2MfKcgCpZwX5jyXqCA==", "funding": [ { "type": "github", @@ -3670,8 +3249,6 @@ }, "node_modules/@csstools/utilities": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@csstools/utilities/-/utilities-2.0.0.tgz", - "integrity": "sha512-5VdOr0Z71u+Yp3ozOx8T11N703wIFGVRgOWbOZMKgglPJsWA54MRIoMNVMa7shUToIhx5J8vX4sOZgD2XiihiQ==", "funding": [ { "type": "github", @@ -3692,8 +3269,6 @@ }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -3701,8 +3276,6 @@ }, "node_modules/@docsearch/core": { "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@docsearch/core/-/core-4.3.1.tgz", - "integrity": "sha512-ktVbkePE+2h9RwqCUMbWXOoebFyDOxHqImAqfs+lC8yOU+XwEW4jgvHGJK079deTeHtdhUNj0PXHSnhJINvHzQ==", "license": "MIT", "peerDependencies": { "@types/react": ">= 16.8.0 < 20.0.0", @@ -3723,14 +3296,10 @@ }, "node_modules/@docsearch/css": { "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-4.3.2.tgz", - "integrity": "sha512-K3Yhay9MgkBjJJ0WEL5MxnACModX9xuNt3UlQQkDEDZJZ0+aeWKtOkxHNndMRkMBnHdYvQjxkm6mdlneOtU1IQ==", "license": "MIT" }, "node_modules/@docsearch/react": { "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-4.3.2.tgz", - "integrity": "sha512-74SFD6WluwvgsOPqifYOviEEVwDxslxfhakTlra+JviaNcs7KK/rjsPj89kVEoQc9FUxRkAofaJnHIR7pb4TSQ==", "license": "MIT", "dependencies": { "@ai-sdk/react": "^2.0.30", @@ -3765,8 +3334,6 @@ }, "node_modules/@docusaurus/babel": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/babel/-/babel-3.9.2.tgz", - "integrity": "sha512-GEANdi/SgER+L7Japs25YiGil/AUDnFFHaCGPBbundxoWtCkA2lmy7/tFmgED4y1htAy6Oi4wkJEQdGssnw9MA==", "license": "MIT", "dependencies": { "@babel/core": "^7.25.9", @@ -3791,8 +3358,6 @@ }, "node_modules/@docusaurus/bundler": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/bundler/-/bundler-3.9.2.tgz", - "integrity": "sha512-ZOVi6GYgTcsZcUzjblpzk3wH1Fya2VNpd5jtHoCCFcJlMQ1EYXZetfAnRHLcyiFeBABaI1ltTYbOBtH/gahGVA==", "license": "MIT", "dependencies": { "@babel/core": "^7.25.9", @@ -3834,8 +3399,6 @@ }, "node_modules/@docusaurus/core": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.9.2.tgz", - "integrity": "sha512-HbjwKeC+pHUFBfLMNzuSjqFE/58+rLVKmOU3lxQrpsxLBOGosYco/Q0GduBb0/jEMRiyEqjNT/01rRdOMWq5pw==", "license": "MIT", "dependencies": { "@docusaurus/babel": "3.9.2", @@ -3895,8 +3458,6 @@ }, "node_modules/@docusaurus/cssnano-preset": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.9.2.tgz", - "integrity": "sha512-8gBKup94aGttRduABsj7bpPFTX7kbwu+xh3K9NMCF5K4bWBqTFYW+REKHF6iBVDHRJ4grZdIPbvkiHd/XNKRMQ==", "license": "MIT", "dependencies": { "cssnano-preset-advanced": "^6.1.2", @@ -3910,8 +3471,6 @@ }, "node_modules/@docusaurus/logger": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.9.2.tgz", - "integrity": "sha512-/SVCc57ByARzGSU60c50rMyQlBuMIJCjcsJlkphxY6B0GV4UH3tcA1994N8fFfbJ9kX3jIBe/xg3XP5qBtGDbA==", "license": "MIT", "dependencies": { "chalk": "^4.1.2", @@ -3923,8 +3482,6 @@ }, "node_modules/@docusaurus/mdx-loader": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.9.2.tgz", - "integrity": "sha512-wiYoGwF9gdd6rev62xDU8AAM8JuLI/hlwOtCzMmYcspEkzecKrP8J8X+KpYnTlACBUUtXNJpSoCwFWJhLRevzQ==", "license": "MIT", "dependencies": { "@docusaurus/logger": "3.9.2", @@ -3962,8 +3519,6 @@ }, "node_modules/@docusaurus/module-type-aliases": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.9.2.tgz", - "integrity": "sha512-8qVe2QA9hVLzvnxP46ysuofJUIc/yYQ82tvA/rBTrnpXtCjNSFLxEZfd5U8cYZuJIVlkPxamsIgwd5tGZXfvew==", "license": "MIT", "dependencies": { "@docusaurus/types": "3.9.2", @@ -3981,8 +3536,6 @@ }, "node_modules/@docusaurus/plugin-content-blog": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.9.2.tgz", - "integrity": "sha512-3I2HXy3L1QcjLJLGAoTvoBnpOwa6DPUa3Q0dMK19UTY9mhPkKQg/DYhAGTiBUKcTR0f08iw7kLPqOhIgdV3eVQ==", "license": "MIT", "dependencies": { "@docusaurus/core": "3.9.2", @@ -4015,10 +3568,7 @@ }, "node_modules/@docusaurus/plugin-content-docs": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.9.2.tgz", - "integrity": "sha512-C5wZsGuKTY8jEYsqdxhhFOe1ZDjH0uIYJ9T/jebHwkyxqnr4wW0jTkB72OMqNjsoQRcb0JN3PcSeTwFlVgzCZg==", "license": "MIT", - "peer": true, "dependencies": { "@docusaurus/core": "3.9.2", "@docusaurus/logger": "3.9.2", @@ -4049,8 +3599,6 @@ }, "node_modules/@docusaurus/plugin-content-pages": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.9.2.tgz", - "integrity": "sha512-s4849w/p4noXUrGpPUF0BPqIAfdAe76BLaRGAGKZ1gTDNiGxGcpsLcwJ9OTi1/V8A+AzvsmI9pkjie2zjIQZKA==", "license": "MIT", "dependencies": { "@docusaurus/core": "3.9.2", @@ -4072,8 +3620,6 @@ }, "node_modules/@docusaurus/plugin-css-cascade-layers": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-css-cascade-layers/-/plugin-css-cascade-layers-3.9.2.tgz", - "integrity": "sha512-w1s3+Ss+eOQbscGM4cfIFBlVg/QKxyYgj26k5AnakuHkKxH6004ZtuLe5awMBotIYF2bbGDoDhpgQ4r/kcj4rQ==", "license": "MIT", "dependencies": { "@docusaurus/core": "3.9.2", @@ -4088,8 +3634,6 @@ }, "node_modules/@docusaurus/plugin-debug": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.9.2.tgz", - "integrity": "sha512-j7a5hWuAFxyQAkilZwhsQ/b3T7FfHZ+0dub6j/GxKNFJp2h9qk/P1Bp7vrGASnvA9KNQBBL1ZXTe7jlh4VdPdA==", "license": "MIT", "dependencies": { "@docusaurus/core": "3.9.2", @@ -4109,8 +3653,6 @@ }, "node_modules/@docusaurus/plugin-google-analytics": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.9.2.tgz", - "integrity": "sha512-mAwwQJ1Us9jL/lVjXtErXto4p4/iaLlweC54yDUK1a97WfkC6Z2k5/769JsFgwOwOP+n5mUQGACXOEQ0XDuVUw==", "license": "MIT", "dependencies": { "@docusaurus/core": "3.9.2", @@ -4128,8 +3670,6 @@ }, "node_modules/@docusaurus/plugin-google-gtag": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.9.2.tgz", - "integrity": "sha512-YJ4lDCphabBtw19ooSlc1MnxtYGpjFV9rEdzjLsUnBCeis2djUyCozZaFhCg6NGEwOn7HDDyMh0yzcdRpnuIvA==", "license": "MIT", "dependencies": { "@docusaurus/core": "3.9.2", @@ -4148,8 +3688,6 @@ }, "node_modules/@docusaurus/plugin-google-tag-manager": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.9.2.tgz", - "integrity": "sha512-LJtIrkZN/tuHD8NqDAW1Tnw0ekOwRTfobWPsdO15YxcicBo2ykKF0/D6n0vVBfd3srwr9Z6rzrIWYrMzBGrvNw==", "license": "MIT", "dependencies": { "@docusaurus/core": "3.9.2", @@ -4167,8 +3705,6 @@ }, "node_modules/@docusaurus/plugin-sitemap": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.9.2.tgz", - "integrity": "sha512-WLh7ymgDXjG8oPoM/T4/zUP7KcSuFYRZAUTl8vR6VzYkfc18GBM4xLhcT+AKOwun6kBivYKUJf+vlqYJkm+RHw==", "license": "MIT", "dependencies": { "@docusaurus/core": "3.9.2", @@ -4191,8 +3727,6 @@ }, "node_modules/@docusaurus/plugin-svgr": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-svgr/-/plugin-svgr-3.9.2.tgz", - "integrity": "sha512-n+1DE+5b3Lnf27TgVU5jM1d4x5tUh2oW5LTsBxJX4PsAPV0JGcmI6p3yLYtEY0LRVEIJh+8RsdQmRE66wSV8mw==", "license": "MIT", "dependencies": { "@docusaurus/core": "3.9.2", @@ -4214,8 +3748,6 @@ }, "node_modules/@docusaurus/preset-classic": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.9.2.tgz", - "integrity": "sha512-IgyYO2Gvaigi21LuDIe+nvmN/dfGXAiMcV/murFqcpjnZc7jxFAxW+9LEjdPt61uZLxG4ByW/oUmX/DDK9t/8w==", "license": "MIT", "dependencies": { "@docusaurus/core": "3.9.2", @@ -4244,8 +3776,6 @@ }, "node_modules/@docusaurus/theme-classic": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.9.2.tgz", - "integrity": "sha512-IGUsArG5hhekXd7RDb11v94ycpJpFdJPkLnt10fFQWOVxAtq5/D7hT6lzc2fhyQKaaCE62qVajOMKL7OiAFAIA==", "license": "MIT", "dependencies": { "@docusaurus/core": "3.9.2", @@ -4284,10 +3814,7 @@ }, "node_modules/@docusaurus/theme-common": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.9.2.tgz", - "integrity": "sha512-6c4DAbR6n6nPbnZhY2V3tzpnKnGL+6aOsLvFL26VRqhlczli9eWG0VDUNoCQEPnGwDMhPS42UhSAnz5pThm5Ag==", "license": "MIT", - "peer": true, "dependencies": { "@docusaurus/mdx-loader": "3.9.2", "@docusaurus/module-type-aliases": "3.9.2", @@ -4313,8 +3840,6 @@ }, "node_modules/@docusaurus/theme-mermaid": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-mermaid/-/theme-mermaid-3.9.2.tgz", - "integrity": "sha512-5vhShRDq/ntLzdInsQkTdoKWSzw8d1jB17sNPYhA/KvYYFXfuVEGHLM6nrf8MFbV8TruAHDG21Fn3W4lO8GaDw==", "license": "MIT", "dependencies": { "@docusaurus/core": "3.9.2", @@ -4341,8 +3866,6 @@ }, "node_modules/@docusaurus/theme-search-algolia": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.9.2.tgz", - "integrity": "sha512-GBDSFNwjnh5/LdkxCKQHkgO2pIMX1447BxYUBG2wBiajS21uj64a+gH/qlbQjDLxmGrbrllBrtJkUHxIsiwRnw==", "license": "MIT", "dependencies": { "@docsearch/react": "^3.9.0 || ^4.1.0", @@ -4372,8 +3895,6 @@ }, "node_modules/@docusaurus/theme-translations": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.9.2.tgz", - "integrity": "sha512-vIryvpP18ON9T9rjgMRFLr2xJVDpw1rtagEGf8Ccce4CkTrvM/fRB8N2nyWYOW5u3DdjkwKw5fBa+3tbn9P4PA==", "license": "MIT", "dependencies": { "fs-extra": "^11.1.1", @@ -4385,15 +3906,11 @@ }, "node_modules/@docusaurus/tsconfig": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.9.2.tgz", - "integrity": "sha512-j6/Fp4Rlpxsc632cnRnl5HpOWeb6ZKssDj6/XzzAzVGXXfm9Eptx3rxCC+fDzySn9fHTS+CWJjPineCR1bB5WQ==", "dev": true, "license": "MIT" }, "node_modules/@docusaurus/types": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.9.2.tgz", - "integrity": "sha512-Ux1JUNswg+EfUEmajJjyhIohKceitY/yzjRUpu04WXgvVz+fbhVC0p+R0JhvEu4ytw8zIAys2hrdpQPBHRIa8Q==", "license": "MIT", "dependencies": { "@mdx-js/mdx": "^3.0.0", @@ -4414,8 +3931,6 @@ }, "node_modules/@docusaurus/types/node_modules/webpack-merge": { "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", "license": "MIT", "dependencies": { "clone-deep": "^4.0.1", @@ -4428,10 +3943,7 @@ }, "node_modules/@docusaurus/utils": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.9.2.tgz", - "integrity": "sha512-lBSBiRruFurFKXr5Hbsl2thmGweAPmddhF3jb99U4EMDA5L+e5Y1rAkOS07Nvrup7HUMBDrCV45meaxZnt28nQ==", "license": "MIT", - "peer": true, "dependencies": { "@docusaurus/logger": "3.9.2", "@docusaurus/types": "3.9.2", @@ -4461,8 +3973,6 @@ }, "node_modules/@docusaurus/utils-common": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.9.2.tgz", - "integrity": "sha512-I53UC1QctruA6SWLvbjbhCpAw7+X7PePoe5pYcwTOEXD/PxeP8LnECAhTHHwWCblyUX5bMi4QLRkxvyZ+IT8Aw==", "license": "MIT", "dependencies": { "@docusaurus/types": "3.9.2", @@ -4474,8 +3984,6 @@ }, "node_modules/@docusaurus/utils-validation": { "version": "3.9.2", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.9.2.tgz", - "integrity": "sha512-l7yk3X5VnNmATbwijJkexdhulNsQaNDwoagiwujXoxFbWLcxHQqNQ+c/IAlzrfMMOfa/8xSBZ7KEKDesE/2J7A==", "license": "MIT", "dependencies": { "@docusaurus/logger": "3.9.2", @@ -4491,41 +3999,109 @@ "node": ">=20.0" } }, - "node_modules/@emnapi/core": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.7.1.tgz", - "integrity": "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==", + "node_modules/@easyops-cn/autocomplete.js": { + "version": "0.38.1", "license": "MIT", - "optional": true, "dependencies": { - "@emnapi/wasi-threads": "1.1.0", - "tslib": "^2.4.0" + "cssesc": "^3.0.0", + "immediate": "^3.2.3" } }, - "node_modules/@emnapi/runtime": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.1.tgz", - "integrity": "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==", + "node_modules/@easyops-cn/docusaurus-search-local": { + "version": "0.52.2", "license": "MIT", - "optional": true, "dependencies": { + "@docusaurus/plugin-content-docs": "^2 || ^3", + "@docusaurus/theme-translations": "^2 || ^3", + "@docusaurus/utils": "^2 || ^3", + "@docusaurus/utils-common": "^2 || ^3", + "@docusaurus/utils-validation": "^2 || ^3", + "@easyops-cn/autocomplete.js": "^0.38.1", + "@node-rs/jieba": "^1.6.0", + "cheerio": "^1.0.0", + "clsx": "^2.1.1", + "comlink": "^4.4.2", + "debug": "^4.2.0", + "fs-extra": "^10.0.0", + "klaw-sync": "^6.0.0", + "lunr": "^2.3.9", + "lunr-languages": "^1.4.0", + "mark.js": "^8.11.1", "tslib": "^2.4.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "@docusaurus/theme-common": "^2 || ^3", + "react": "^16.14.0 || ^17 || ^18 || ^19", + "react-dom": "^16.14.0 || 17 || ^18 || ^19" } }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", - "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", + "node_modules/@easyops-cn/docusaurus-search-local/node_modules/cheerio": { + "version": "1.1.2", "license": "MIT", - "optional": true, "dependencies": { - "tslib": "^2.4.0" + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "encoding-sniffer": "^0.2.1", + "htmlparser2": "^10.0.0", + "parse5": "^7.3.0", + "parse5-htmlparser2-tree-adapter": "^7.1.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^7.12.0", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=20.18.1" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/@easyops-cn/docusaurus-search-local/node_modules/entities": { + "version": "6.0.1", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/@easyops-cn/docusaurus-search-local/node_modules/fs-extra": { + "version": "10.1.0", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@easyops-cn/docusaurus-search-local/node_modules/htmlparser2": { + "version": "10.0.0", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.1", + "entities": "^6.0.0" } }, "node_modules/@emotion/is-prop-valid": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz", - "integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==", "license": "MIT", "dependencies": { "@emotion/memoize": "^0.8.1" @@ -4533,20 +4109,14 @@ }, "node_modules/@emotion/memoize": { "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz", - "integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==", "license": "MIT" }, "node_modules/@emotion/unitless": { "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz", - "integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==", "license": "MIT" }, "node_modules/@eslint-community/eslint-utils": { "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", - "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.4.3" @@ -4563,8 +4133,6 @@ }, "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==", "license": "Apache-2.0", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -4575,8 +4143,6 @@ }, "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==", "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" @@ -4584,8 +4150,6 @@ }, "node_modules/@eslint/config-array": { "version": "0.21.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", - "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", "license": "Apache-2.0", "dependencies": { "@eslint/object-schema": "^2.1.7", @@ -4596,10 +4160,26 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "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==", "license": "Apache-2.0", "dependencies": { "@eslint/core": "^0.17.0" @@ -4610,8 +4190,6 @@ }, "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==", "license": "Apache-2.0", "dependencies": { "@types/json-schema": "^7.0.15" @@ -4622,8 +4200,6 @@ }, "node_modules/@eslint/eslintrc": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", - "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", "license": "MIT", "dependencies": { "ajv": "^6.12.4", @@ -4643,10 +4219,26 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@eslint/js": { - "version": "9.39.2", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", - "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", + "version": "9.39.1", "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4657,8 +4249,6 @@ }, "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==", "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -4666,8 +4256,6 @@ }, "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==", "license": "Apache-2.0", "dependencies": { "@eslint/core": "^0.17.0", @@ -4679,14 +4267,10 @@ }, "node_modules/@exodus/schemasafe": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@exodus/schemasafe/-/schemasafe-1.3.0.tgz", - "integrity": "sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==", "license": "MIT" }, "node_modules/@floating-ui/core": { "version": "1.7.3", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz", - "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==", "license": "MIT", "dependencies": { "@floating-ui/utils": "^0.2.10" @@ -4694,8 +4278,6 @@ }, "node_modules/@floating-ui/dom": { "version": "1.7.4", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz", - "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==", "license": "MIT", "dependencies": { "@floating-ui/core": "^1.7.3", @@ -4704,8 +4286,6 @@ }, "node_modules/@floating-ui/react-dom": { "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.6.tgz", - "integrity": "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==", "license": "MIT", "dependencies": { "@floating-ui/dom": "^1.7.4" @@ -4717,20 +4297,14 @@ }, "node_modules/@floating-ui/utils": { "version": "0.2.10", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", - "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", "license": "MIT" }, "node_modules/@hapi/hoek": { "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", "license": "BSD-3-Clause" }, "node_modules/@hapi/topo": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", - "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", "license": "BSD-3-Clause", "dependencies": { "@hapi/hoek": "^9.0.0" @@ -4738,8 +4312,6 @@ }, "node_modules/@hey-api/codegen-core": { "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@hey-api/codegen-core/-/codegen-core-0.3.3.tgz", - "integrity": "sha512-vArVDtrvdzFewu1hnjUm4jX1NBITlSCeO81EdWq676MxQbyxsGcDPAgohaSA+Wvr4HjPSvsg2/1s2zYxUtXebg==", "dev": true, "license": "MIT", "engines": { @@ -4753,15 +4325,13 @@ } }, "node_modules/@hey-api/json-schema-ref-parser": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@hey-api/json-schema-ref-parser/-/json-schema-ref-parser-1.2.2.tgz", - "integrity": "sha512-oS+5yAdwnK20lSeFO1d53Ku+yaGCsY8PcrmSq2GtSs3bsBfRnHAbpPKSVzQcaxAOrzj5NB+f34WhZglVrNayBA==", + "version": "1.2.1", "dev": true, "license": "MIT", "dependencies": { "@jsdevtools/ono": "^7.1.3", "@types/json-schema": "^7.0.15", - "js-yaml": "^4.1.1", + "js-yaml": "^4.1.0", "lodash": "^4.17.21" }, "engines": { @@ -4772,14 +4342,12 @@ } }, "node_modules/@hey-api/openapi-ts": { - "version": "0.88.2", - "resolved": "https://registry.npmjs.org/@hey-api/openapi-ts/-/openapi-ts-0.88.2.tgz", - "integrity": "sha512-JMae1RJ8S8D8lVCFQnsrWaKY0CxrR4TUmZIoU1SuvaeZ+pkMPYuQoj8fO37R5d8juUfFVzCGYV5/Ro0vbDqBbA==", + "version": "0.88.0", "dev": true, "license": "MIT", "dependencies": { "@hey-api/codegen-core": "^0.3.3", - "@hey-api/json-schema-ref-parser": "1.2.2", + "@hey-api/json-schema-ref-parser": "1.2.1", "ansi-colors": "4.1.3", "c12": "3.3.2", "color-support": "1.1.3", @@ -4802,8 +4370,6 @@ }, "node_modules/@hey-api/openapi-ts/node_modules/commander": { "version": "14.0.2", - "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz", - "integrity": "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==", "dev": true, "license": "MIT", "engines": { @@ -4812,8 +4378,6 @@ }, "node_modules/@hey-api/openapi-ts/node_modules/define-lazy-prop": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", "dev": true, "license": "MIT", "engines": { @@ -4825,8 +4389,6 @@ }, "node_modules/@hey-api/openapi-ts/node_modules/open": { "version": "11.0.0", - "resolved": "https://registry.npmjs.org/open/-/open-11.0.0.tgz", - "integrity": "sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw==", "dev": true, "license": "MIT", "dependencies": { @@ -4846,8 +4408,6 @@ }, "node_modules/@hey-api/openapi-ts/node_modules/semver": { "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", "dev": true, "license": "ISC", "bin": { @@ -4859,8 +4419,6 @@ }, "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==", "license": "Apache-2.0", "engines": { "node": ">=18.18.0" @@ -4868,8 +4426,6 @@ }, "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==", "license": "Apache-2.0", "dependencies": { "@humanfs/core": "^0.19.1", @@ -4881,8 +4437,6 @@ }, "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==", "license": "Apache-2.0", "engines": { "node": ">=12.22" @@ -4894,8 +4448,6 @@ }, "node_modules/@humanwhocodes/retry": { "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", "license": "Apache-2.0", "engines": { "node": ">=18.18" @@ -4907,14 +4459,10 @@ }, "node_modules/@iconify/types": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", - "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", "license": "MIT" }, "node_modules/@iconify/utils": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-3.1.0.tgz", - "integrity": "sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==", "license": "MIT", "dependencies": { "@antfu/install-pkg": "^1.1.0", @@ -4924,8 +4472,6 @@ }, "node_modules/@img/colour": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz", - "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==", "license": "MIT", "optional": true, "engines": { @@ -4934,8 +4480,6 @@ }, "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" ], @@ -4954,32 +4498,8 @@ "@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" ], @@ -4992,406 +4512,8 @@ "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/@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": { @@ -5407,8 +4529,6 @@ }, "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": { @@ -5417,8 +4537,6 @@ }, "node_modules/@istanbuljs/load-nyc-config/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": { @@ -5427,8 +4545,6 @@ }, "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": { @@ -5441,8 +4557,6 @@ }, "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": { @@ -5455,8 +4569,6 @@ }, "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": { @@ -5468,8 +4580,6 @@ }, "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": { @@ -5484,8 +4594,6 @@ }, "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": { @@ -5497,8 +4605,6 @@ }, "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": { @@ -5507,8 +4613,6 @@ }, "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": { @@ -5517,8 +4621,6 @@ }, "node_modules/@jest/console": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", - "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", "dev": true, "license": "MIT", "dependencies": { @@ -5535,8 +4637,6 @@ }, "node_modules/@jest/core": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", - "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", "dev": true, "license": "MIT", "dependencies": { @@ -5583,8 +4683,6 @@ }, "node_modules/@jest/environment": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", - "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", "dev": true, "license": "MIT", "dependencies": { @@ -5599,8 +4697,6 @@ }, "node_modules/@jest/expect": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5613,8 +4709,6 @@ }, "node_modules/@jest/expect-utils": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", - "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", "dev": true, "license": "MIT", "dependencies": { @@ -5626,8 +4720,6 @@ }, "node_modules/@jest/fake-timers": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", - "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5644,8 +4736,6 @@ }, "node_modules/@jest/globals": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", - "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5660,8 +4750,6 @@ }, "node_modules/@jest/reporters": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", - "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", "dev": true, "license": "MIT", "dependencies": { @@ -5704,8 +4792,6 @@ }, "node_modules/@jest/schemas": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.27.8" @@ -5716,8 +4802,6 @@ }, "node_modules/@jest/source-map": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", - "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", "dev": true, "license": "MIT", "dependencies": { @@ -5731,8 +4815,6 @@ }, "node_modules/@jest/test-result": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", - "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", "dev": true, "license": "MIT", "dependencies": { @@ -5747,8 +4829,6 @@ }, "node_modules/@jest/test-sequencer": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", - "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", "dev": true, "license": "MIT", "dependencies": { @@ -5763,8 +4843,6 @@ }, "node_modules/@jest/transform": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", - "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", "dev": true, "license": "MIT", "dependencies": { @@ -5790,8 +4868,6 @@ }, "node_modules/@jest/types": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", @@ -5807,8 +4883,6 @@ }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", @@ -5817,8 +4891,6 @@ }, "node_modules/@jridgewell/remapping": { "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -5827,8 +4899,6 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "license": "MIT", "engines": { "node": ">=6.0.0" @@ -5836,8 +4906,6 @@ }, "node_modules/@jridgewell/source-map": { "version": "0.3.11", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", - "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -5846,14 +4914,10 @@ }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -5862,15 +4926,11 @@ }, "node_modules/@jsdevtools/ono": { "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", - "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", "dev": true, "license": "MIT" }, "node_modules/@jsonjoy.com/base64": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", "license": "Apache-2.0", "engines": { "node": ">=10.0" @@ -5885,8 +4945,6 @@ }, "node_modules/@jsonjoy.com/buffers": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", - "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", "license": "Apache-2.0", "engines": { "node": ">=10.0" @@ -5901,8 +4959,6 @@ }, "node_modules/@jsonjoy.com/codegen": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-1.0.0.tgz", - "integrity": "sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==", "license": "Apache-2.0", "engines": { "node": ">=10.0" @@ -5917,8 +4973,6 @@ }, "node_modules/@jsonjoy.com/json-pack": { "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.21.0.tgz", - "integrity": "sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==", "license": "Apache-2.0", "dependencies": { "@jsonjoy.com/base64": "^1.1.2", @@ -5943,8 +4997,6 @@ }, "node_modules/@jsonjoy.com/json-pointer": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz", - "integrity": "sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==", "license": "Apache-2.0", "dependencies": { "@jsonjoy.com/codegen": "^1.0.0", @@ -5963,8 +5015,6 @@ }, "node_modules/@jsonjoy.com/util": { "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.9.0.tgz", - "integrity": "sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==", "license": "Apache-2.0", "dependencies": { "@jsonjoy.com/buffers": "^1.0.0", @@ -5983,14 +5033,10 @@ }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", - "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", "license": "MIT" }, "node_modules/@mdx-js/mdx": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.1.tgz", - "integrity": "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==", "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", @@ -6026,10 +5072,7 @@ }, "node_modules/@mdx-js/react": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.1.1.tgz", - "integrity": "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==", "license": "MIT", - "peer": true, "dependencies": { "@types/mdx": "^2.0.0" }, @@ -6044,35 +5087,17 @@ }, "node_modules/@mermaid-js/parser": { "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.6.3.tgz", - "integrity": "sha512-lnjOhe7zyHjc+If7yT4zoedx2vo4sHaTmtkl1+or8BRTnCtDmcTpAjpzDSfCZrshM5bCoz0GyidzadJAH1xobA==", "license": "MIT", "dependencies": { "langium": "3.3.1" } }, - "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==", - "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.1.0", - "resolved": "https://registry.npmjs.org/@next/env/-/env-16.1.0.tgz", - "integrity": "sha512-Dd23XQeFHmhf3KBW76leYVkejHlCdB7erakC2At2apL1N08Bm+dLYNP+nNHh0tzUXfPQcNcXiQyacw0PG4Fcpw==", + "version": "16.0.10", "license": "MIT" }, "node_modules/@next/eslint-plugin-next": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.1.0.tgz", - "integrity": "sha512-sooC/k0LCF4/jLXYHpgfzJot04lZQqsttn8XJpTguP8N3GhqXN3wSkh68no2OcZzS/qeGwKDFTqhZ8WofdXmmQ==", + "version": "16.0.7", "license": "MIT", "dependencies": { "fast-glob": "3.3.1" @@ -6080,8 +5105,6 @@ }, "node_modules/@next/eslint-plugin-next/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==", "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -6095,9 +5118,7 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.1.0.tgz", - "integrity": "sha512-onHq8dl8KjDb8taANQdzs3XmIqQWV3fYdslkGENuvVInFQzZnuBYYOG2HGHqqtvgmEU7xWzhgndXXxnhk4Z3fQ==", + "version": "16.0.10", "cpu": [ "arm64" ], @@ -6110,12 +5131,37 @@ "node": ">= 10" } }, - "node_modules/@next/swc-darwin-x64": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.1.0.tgz", - "integrity": "sha512-Am6VJTp8KhLuAH13tPrAoVIXzuComlZlMwGr++o2KDjWiKPe3VwpxYhgV6I4gKls2EnsIMggL4y7GdXyDdJcFA==", + "node_modules/@node-rs/jieba": { + "version": "1.10.4", + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@node-rs/jieba-android-arm-eabi": "1.10.4", + "@node-rs/jieba-android-arm64": "1.10.4", + "@node-rs/jieba-darwin-arm64": "1.10.4", + "@node-rs/jieba-darwin-x64": "1.10.4", + "@node-rs/jieba-freebsd-x64": "1.10.4", + "@node-rs/jieba-linux-arm-gnueabihf": "1.10.4", + "@node-rs/jieba-linux-arm64-gnu": "1.10.4", + "@node-rs/jieba-linux-arm64-musl": "1.10.4", + "@node-rs/jieba-linux-x64-gnu": "1.10.4", + "@node-rs/jieba-linux-x64-musl": "1.10.4", + "@node-rs/jieba-wasm32-wasi": "1.10.4", + "@node-rs/jieba-win32-arm64-msvc": "1.10.4", + "@node-rs/jieba-win32-ia32-msvc": "1.10.4", + "@node-rs/jieba-win32-x64-msvc": "1.10.4" + } + }, + "node_modules/@node-rs/jieba-darwin-arm64": { + "version": "1.10.4", "cpu": [ - "x64" + "arm64" ], "license": "MIT", "optional": true, @@ -6126,106 +5172,8 @@ "node": ">= 10" } }, - "node_modules/@next/swc-linux-arm64-gnu": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.1.0.tgz", - "integrity": "sha512-fVicfaJT6QfghNyg8JErZ+EMNQ812IS0lmKfbmC01LF1nFBcKfcs4Q75Yy8IqnsCqH/hZwGhqzj3IGVfWV6vpA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-arm64-musl": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.1.0.tgz", - "integrity": "sha512-TojQnDRoX7wJWXEEwdfuJtakMDW64Q7NrxQPviUnfYJvAx5/5wcGE+1vZzQ9F17m+SdpFeeXuOr6v3jbyusYMQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-gnu": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.1.0.tgz", - "integrity": "sha512-quhNFVySW4QwXiZkZ34SbfzNBm27vLrxZ2HwTfFFO1BBP0OY1+pI0nbyewKeq1FriqU+LZrob/cm26lwsiAi8Q==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-linux-x64-musl": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.1.0.tgz", - "integrity": "sha512-6JW0z2FZUK5iOVhUIWqE4RblAhUj1EwhZ/MwteGb//SpFTOHydnhbp3868gxalwea+mbOLWO6xgxj9wA9wNvNw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-arm64-msvc": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.1.0.tgz", - "integrity": "sha512-+DK/akkAvvXn5RdYN84IOmLkSy87SCmpofJPdB8vbLmf01BzntPBSYXnMvnEEv/Vcf3HYJwt24QZ/s6sWAwOMQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@next/swc-win32-x64-msvc": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.1.0.tgz", - "integrity": "sha512-Tr0j94MphimCCks+1rtYPzQFK+faJuhHWCegU9S9gDlgyOk8Y3kPmO64UcjyzZAlligeBtYZ/2bEyrKq0d2wqQ==", - "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==", "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", @@ -6237,8 +5185,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">= 8" @@ -6246,8 +5192,6 @@ }, "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==", "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", @@ -6259,8 +5203,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">=12.4.0" @@ -6268,18 +5210,79 @@ }, "node_modules/@opentelemetry/api": { "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz", - "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==", "license": "Apache-2.0", - "peer": true, "engines": { "node": ">=8.0.0" } }, + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/detect-libc": { + "version": "1.0.3", + "license": "Apache-2.0", + "optional": true, + "peer": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/@pnpm/config.env-replace": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", - "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", "license": "MIT", "engines": { "node": ">=12.22.0" @@ -6287,8 +5290,6 @@ }, "node_modules/@pnpm/network.ca-file": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", - "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", "license": "MIT", "dependencies": { "graceful-fs": "4.2.10" @@ -6299,14 +5300,10 @@ }, "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", "license": "ISC" }, "node_modules/@pnpm/npm-conf": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz", - "integrity": "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==", "license": "MIT", "dependencies": { "@pnpm/config.env-replace": "^1.1.0", @@ -6319,26 +5316,18 @@ }, "node_modules/@polka/url": { "version": "1.0.0-next.29", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", - "integrity": "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==", "license": "MIT" }, "node_modules/@radix-ui/number": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz", - "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==", "license": "MIT" }, "node_modules/@radix-ui/primitive": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz", - "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==", "license": "MIT" }, "node_modules/@radix-ui/react-arrow": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz", - "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==", "license": "MIT", "dependencies": { "@radix-ui/react-primitive": "2.1.3" @@ -6360,8 +5349,6 @@ }, "node_modules/@radix-ui/react-checkbox": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz", - "integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.3", @@ -6390,8 +5377,6 @@ }, "node_modules/@radix-ui/react-collection": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz", - "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==", "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", @@ -6416,8 +5401,6 @@ }, "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" @@ -6434,8 +5417,6 @@ }, "node_modules/@radix-ui/react-compose-refs": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz", - "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -6449,8 +5430,6 @@ }, "node_modules/@radix-ui/react-context": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", - "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -6464,8 +5443,6 @@ }, "node_modules/@radix-ui/react-dialog": { "version": "1.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.15.tgz", - "integrity": "sha512-TCglVRtzlffRNxRMEyR36DGBLJpeusFcgMVD9PZEzAKnUs1lKCgX5u9BmC2Yg+LL9MgZDugFFs1Vl+Jp4t/PGw==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.3", @@ -6500,8 +5477,6 @@ }, "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-slot": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" @@ -6518,8 +5493,6 @@ }, "node_modules/@radix-ui/react-direction": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz", - "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -6533,8 +5506,6 @@ }, "node_modules/@radix-ui/react-dismissable-layer": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz", - "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.3", @@ -6560,8 +5531,6 @@ }, "node_modules/@radix-ui/react-focus-guards": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz", - "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -6575,8 +5544,6 @@ }, "node_modules/@radix-ui/react-focus-scope": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz", - "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==", "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", @@ -6600,8 +5567,6 @@ }, "node_modules/@radix-ui/react-id": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz", - "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==", "license": "MIT", "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" @@ -6618,8 +5583,6 @@ }, "node_modules/@radix-ui/react-label": { "version": "2.1.8", - "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.8.tgz", - "integrity": "sha512-FmXs37I6hSBVDlO4y764TNz1rLgKwjJMQ0EGte6F3Cb3f4bIuHB/iLa/8I9VKkmOy+gNHq8rql3j686ACVV21A==", "license": "MIT", "dependencies": { "@radix-ui/react-primitive": "2.1.4" @@ -6641,8 +5604,6 @@ }, "node_modules/@radix-ui/react-label/node_modules/@radix-ui/react-primitive": { "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz", - "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==", "license": "MIT", "dependencies": { "@radix-ui/react-slot": "1.2.4" @@ -6664,8 +5625,6 @@ }, "node_modules/@radix-ui/react-popover": { "version": "1.1.15", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.1.15.tgz", - "integrity": "sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.3", @@ -6701,8 +5660,6 @@ }, "node_modules/@radix-ui/react-popover/node_modules/@radix-ui/react-slot": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" @@ -6719,8 +5676,6 @@ }, "node_modules/@radix-ui/react-popper": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz", - "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==", "license": "MIT", "dependencies": { "@floating-ui/react-dom": "^2.0.0", @@ -6751,8 +5706,6 @@ }, "node_modules/@radix-ui/react-portal": { "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz", - "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==", "license": "MIT", "dependencies": { "@radix-ui/react-primitive": "2.1.3", @@ -6775,8 +5728,6 @@ }, "node_modules/@radix-ui/react-presence": { "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz", - "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==", "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.2", @@ -6799,8 +5750,6 @@ }, "node_modules/@radix-ui/react-primitive": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", - "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", "license": "MIT", "dependencies": { "@radix-ui/react-slot": "1.2.3" @@ -6822,8 +5771,6 @@ }, "node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" @@ -6840,8 +5787,6 @@ }, "node_modules/@radix-ui/react-radio-group": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.3.8.tgz", - "integrity": "sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.3", @@ -6872,8 +5817,6 @@ }, "node_modules/@radix-ui/react-roving-focus": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.11.tgz", - "integrity": "sha512-7A6S9jSgm/S+7MdtNDSb+IU859vQqJ/QAtcYQcfFC6W8RS4IxIZDldLR0xqCFZ6DCyrQLjLPsxtTNch5jVA4lA==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.3", @@ -6903,8 +5846,6 @@ }, "node_modules/@radix-ui/react-select": { "version": "2.2.6", - "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.6.tgz", - "integrity": "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==", "license": "MIT", "dependencies": { "@radix-ui/number": "1.1.1", @@ -6946,8 +5887,6 @@ }, "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-slot": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" @@ -6964,8 +5903,6 @@ }, "node_modules/@radix-ui/react-slider": { "version": "1.3.6", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.3.6.tgz", - "integrity": "sha512-JPYb1GuM1bxfjMRlNLE+BcmBC8onfCi60Blk7OBqi2MLTFdS+8401U4uFjnwkOr49BLmXxLC6JHkvAsx5OJvHw==", "license": "MIT", "dependencies": { "@radix-ui/number": "1.1.1", @@ -6997,8 +5934,6 @@ }, "node_modules/@radix-ui/react-slot": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz", - "integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==", "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.2" @@ -7015,8 +5950,6 @@ }, "node_modules/@radix-ui/react-switch": { "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.2.6.tgz", - "integrity": "sha512-bByzr1+ep1zk4VubeEVViV592vu2lHE2BZY5OnzehZqOOgogN80+mNtCqPkhn2gklJqOpxWgPoYTSnhBCqpOXQ==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.3", @@ -7044,8 +5977,6 @@ }, "node_modules/@radix-ui/react-use-callback-ref": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz", - "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -7059,8 +5990,6 @@ }, "node_modules/@radix-ui/react-use-controllable-state": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz", - "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==", "license": "MIT", "dependencies": { "@radix-ui/react-use-effect-event": "0.0.2", @@ -7078,8 +6007,6 @@ }, "node_modules/@radix-ui/react-use-effect-event": { "version": "0.0.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz", - "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==", "license": "MIT", "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" @@ -7096,8 +6023,6 @@ }, "node_modules/@radix-ui/react-use-escape-keydown": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz", - "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==", "license": "MIT", "dependencies": { "@radix-ui/react-use-callback-ref": "1.1.1" @@ -7114,8 +6039,6 @@ }, "node_modules/@radix-ui/react-use-layout-effect": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz", - "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -7129,8 +6052,6 @@ }, "node_modules/@radix-ui/react-use-previous": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz", - "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -7144,8 +6065,6 @@ }, "node_modules/@radix-ui/react-use-rect": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz", - "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==", "license": "MIT", "dependencies": { "@radix-ui/rect": "1.1.1" @@ -7162,8 +6081,6 @@ }, "node_modules/@radix-ui/react-use-size": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz", - "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==", "license": "MIT", "dependencies": { "@radix-ui/react-use-layout-effect": "1.1.1" @@ -7180,8 +6097,6 @@ }, "node_modules/@radix-ui/react-visually-hidden": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz", - "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==", "license": "MIT", "dependencies": { "@radix-ui/react-primitive": "2.1.3" @@ -7203,14 +6118,10 @@ }, "node_modules/@radix-ui/rect": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz", - "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", "license": "MIT" }, "node_modules/@redocly/ajv": { "version": "8.17.1", - "resolved": "https://registry.npmjs.org/@redocly/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-EDtsGZS964mf9zAUXAl9Ew16eYbeyAFWhsPr0fX6oaJxgd8rApYlPBf0joyhnUHz88WxrigyFtTaqqzXNzPgqw==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -7223,66 +6134,31 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@redocly/ajv/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, "node_modules/@redocly/config": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@redocly/config/-/config-0.6.3.tgz", - "integrity": "sha512-hGWJgCsXRw0Ow4rplqRlUQifZvoSwZipkYnt11e3SeH1Eb23VUIDBcRuaQOUqy1wn0eevXkU2GzzQ8fbKdQ7Mg==", + "version": "0.22.2", "license": "MIT" }, "node_modules/@redocly/openapi-core": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@redocly/openapi-core/-/openapi-core-1.16.0.tgz", - "integrity": "sha512-z06h+svyqbUcdAaePq8LPSwTPlm6Ig7j2VlL8skPBYnJvyaQ2IN7x/JkOvRL4ta+wcOCBdAex5JWnZbKaNktJg==", + "version": "1.34.5", "license": "MIT", "dependencies": { - "@redocly/ajv": "^8.11.0", - "@redocly/config": "^0.6.0", + "@redocly/ajv": "^8.11.2", + "@redocly/config": "^0.22.0", "colorette": "^1.2.0", - "https-proxy-agent": "^7.0.4", + "https-proxy-agent": "^7.0.5", "js-levenshtein": "^1.1.6", "js-yaml": "^4.1.0", - "lodash.isequal": "^4.5.0", "minimatch": "^5.0.1", - "node-fetch": "^2.6.1", "pluralize": "^8.0.0", "yaml-ast-parser": "0.0.43" }, "engines": { - "node": ">=14.19.0", - "npm": ">=7.0.0" - } - }, - "node_modules/@redocly/openapi-core/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==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@redocly/openapi-core/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" + "node": ">=18.17.0", + "npm": ">=9.5.0" } }, "node_modules/@reduxjs/toolkit": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.11.2.tgz", - "integrity": "sha512-Kd6kAHTA6/nUpp8mySPqj3en3dm0tdMIgbttnQ1xFMVpufoj+ADi8pXLBsd4xzTRHQa7t/Jv8W5UnCuW4kuWMQ==", + "version": "2.11.0", "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.0.0", @@ -7306,9 +6182,7 @@ } }, "node_modules/@reduxjs/toolkit/node_modules/immer": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/immer/-/immer-11.1.0.tgz", - "integrity": "sha512-dlzb07f5LDY+tzs+iLCSXV2yuhaYfezqyZQc+n6baLECWkOMEWxkECAOnXL0ba7lsA25fM9b2jtzpu/uxo1a7g==", + "version": "11.0.1", "license": "MIT", "funding": { "type": "opencollective", @@ -7317,14 +6191,10 @@ }, "node_modules/@rtsao/scc": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", - "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", "license": "MIT" }, "node_modules/@sideway/address": { "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", - "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", "license": "BSD-3-Clause", "dependencies": { "@hapi/hoek": "^9.0.0" @@ -7332,26 +6202,18 @@ }, "node_modules/@sideway/formula": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", - "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", "license": "BSD-3-Clause" }, "node_modules/@sideway/pinpoint": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", "license": "BSD-3-Clause" }, "node_modules/@sinclair/typebox": { "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", "license": "MIT" }, "node_modules/@sindresorhus/is": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", "license": "MIT", "engines": { "node": ">=10" @@ -7362,8 +6224,6 @@ }, "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": { @@ -7372,8 +6232,6 @@ }, "node_modules/@sinonjs/fake-timers": { "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -7382,8 +6240,6 @@ }, "node_modules/@slorber/remark-comment": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz", - "integrity": "sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==", "license": "MIT", "dependencies": { "micromark-factory-space": "^1.0.0", @@ -7392,21 +6248,15 @@ } }, "node_modules/@standard-schema/spec": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", - "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "version": "1.0.0", "license": "MIT" }, "node_modules/@standard-schema/utils": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", - "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", "license": "MIT" }, "node_modules/@svgr/babel-plugin-add-jsx-attribute": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-8.0.0.tgz", - "integrity": "sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==", "license": "MIT", "engines": { "node": ">=14" @@ -7421,8 +6271,6 @@ }, "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", - "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", "license": "MIT", "engines": { "node": ">=14" @@ -7437,8 +6285,6 @@ }, "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", - "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", "license": "MIT", "engines": { "node": ">=14" @@ -7453,8 +6299,6 @@ }, "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-8.0.0.tgz", - "integrity": "sha512-KVQ+PtIjb1BuYT3ht8M5KbzWBhdAjjUPdlMtpuw/VjT8coTrItWX6Qafl9+ji831JaJcu6PJNKCV0bp01lBNzQ==", "license": "MIT", "engines": { "node": ">=14" @@ -7469,8 +6313,6 @@ }, "node_modules/@svgr/babel-plugin-svg-dynamic-title": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-8.0.0.tgz", - "integrity": "sha512-omNiKqwjNmOQJ2v6ge4SErBbkooV2aAWwaPFs2vUY7p7GhVkzRkJ00kILXQvRhA6miHnNpXv7MRnnSjdRjK8og==", "license": "MIT", "engines": { "node": ">=14" @@ -7485,8 +6327,6 @@ }, "node_modules/@svgr/babel-plugin-svg-em-dimensions": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-8.0.0.tgz", - "integrity": "sha512-mURHYnu6Iw3UBTbhGwE/vsngtCIbHE43xCRK7kCw4t01xyGqb2Pd+WXekRRoFOBIY29ZoOhUCTEweDMdrjfi9g==", "license": "MIT", "engines": { "node": ">=14" @@ -7501,8 +6341,6 @@ }, "node_modules/@svgr/babel-plugin-transform-react-native-svg": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-8.1.0.tgz", - "integrity": "sha512-Tx8T58CHo+7nwJ+EhUwx3LfdNSG9R2OKfaIXXs5soiy5HtgoAEkDay9LIimLOcG8dJQH1wPZp/cnAv6S9CrR1Q==", "license": "MIT", "engines": { "node": ">=14" @@ -7517,8 +6355,6 @@ }, "node_modules/@svgr/babel-plugin-transform-svg-component": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-8.0.0.tgz", - "integrity": "sha512-DFx8xa3cZXTdb/k3kfPeaixecQLgKh5NVBMwD0AQxOzcZawK4oo1Jh9LbrcACUivsCA7TLG8eeWgrDXjTMhRmw==", "license": "MIT", "engines": { "node": ">=12" @@ -7533,8 +6369,6 @@ }, "node_modules/@svgr/babel-preset": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-8.1.0.tgz", - "integrity": "sha512-7EYDbHE7MxHpv4sxvnVPngw5fuR6pw79SkcrILHJ/iMpuKySNCl5W1qcwPEpU+LgyRXOaAFgH0KhwD18wwg6ug==", "license": "MIT", "dependencies": { "@svgr/babel-plugin-add-jsx-attribute": "8.0.0", @@ -7559,10 +6393,7 @@ }, "node_modules/@svgr/core": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-8.1.0.tgz", - "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "8.1.0", @@ -7580,8 +6411,6 @@ }, "node_modules/@svgr/hast-util-to-babel-ast": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-8.0.0.tgz", - "integrity": "sha512-EbDKwO9GpfWP4jN9sGdYwPBU0kdomaPIL2Eu4YwmgP+sJeXT+L7bMwJUBnhzfH8Q2qMBqZ4fJwpCyYsAN3mt2Q==", "license": "MIT", "dependencies": { "@babel/types": "^7.21.3", @@ -7597,8 +6426,6 @@ }, "node_modules/@svgr/plugin-jsx": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-8.1.0.tgz", - "integrity": "sha512-0xiIyBsLlr8quN+WyuxooNW9RJ0Dpr8uOnH/xrCVO8GLUcwHISwj1AG0k+LFzteTkAA0GbX0kj9q6Dk70PTiPA==", "license": "MIT", "dependencies": { "@babel/core": "^7.21.3", @@ -7619,8 +6446,6 @@ }, "node_modules/@svgr/plugin-svgo": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-8.1.0.tgz", - "integrity": "sha512-Ywtl837OGO9pTLIN/onoWLmDQ4zFUycI1g76vuKGEz6evR/ZTJlJuz3G/fIkb6OVBJ2g0o6CGJzaEjfmEo3AHA==", "license": "MIT", "dependencies": { "cosmiconfig": "^8.1.3", @@ -7640,8 +6465,6 @@ }, "node_modules/@svgr/webpack": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-8.1.0.tgz", - "integrity": "sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==", "license": "MIT", "dependencies": { "@babel/core": "^7.21.3", @@ -7663,8 +6486,6 @@ }, "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" @@ -7672,8 +6493,6 @@ }, "node_modules/@szmarczak/http-timer": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", "license": "MIT", "dependencies": { "defer-to-connect": "^2.0.1" @@ -7683,9 +6502,7 @@ } }, "node_modules/@tailwindcss/node": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.18.tgz", - "integrity": "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==", + "version": "4.1.17", "license": "MIT", "dependencies": { "@jridgewell/remapping": "^2.3.4", @@ -7694,61 +6511,39 @@ "lightningcss": "1.30.2", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", - "tailwindcss": "4.1.18" + "tailwindcss": "4.1.17" } }, "node_modules/@tailwindcss/node/node_modules/jiti": { "version": "2.6.1", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", - "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", "license": "MIT", "bin": { "jiti": "lib/jiti-cli.mjs" } }, "node_modules/@tailwindcss/oxide": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.18.tgz", - "integrity": "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==", + "version": "4.1.17", "license": "MIT", "engines": { "node": ">= 10" }, "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.1.18", - "@tailwindcss/oxide-darwin-arm64": "4.1.18", - "@tailwindcss/oxide-darwin-x64": "4.1.18", - "@tailwindcss/oxide-freebsd-x64": "4.1.18", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18", - "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18", - "@tailwindcss/oxide-linux-arm64-musl": "4.1.18", - "@tailwindcss/oxide-linux-x64-gnu": "4.1.18", - "@tailwindcss/oxide-linux-x64-musl": "4.1.18", - "@tailwindcss/oxide-wasm32-wasi": "4.1.18", - "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18", - "@tailwindcss/oxide-win32-x64-msvc": "4.1.18" - } - }, - "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.18.tgz", - "integrity": "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" + "@tailwindcss/oxide-android-arm64": "4.1.17", + "@tailwindcss/oxide-darwin-arm64": "4.1.17", + "@tailwindcss/oxide-darwin-x64": "4.1.17", + "@tailwindcss/oxide-freebsd-x64": "4.1.17", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.17", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.17", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.17", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.17", + "@tailwindcss/oxide-linux-x64-musl": "4.1.17", + "@tailwindcss/oxide-wasm32-wasi": "4.1.17", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.17", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.17" } }, "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.18.tgz", - "integrity": "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==", + "version": "4.1.17", "cpu": [ "arm64" ], @@ -7761,215 +6556,26 @@ "node": ">= 10" } }, - "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.18.tgz", - "integrity": "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.18.tgz", - "integrity": "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.18.tgz", - "integrity": "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.18.tgz", - "integrity": "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.18.tgz", - "integrity": "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.18.tgz", - "integrity": "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.18.tgz", - "integrity": "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.18.tgz", - "integrity": "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==", - "bundleDependencies": [ - "@napi-rs/wasm-runtime", - "@emnapi/core", - "@emnapi/runtime", - "@tybys/wasm-util", - "@emnapi/wasi-threads", - "tslib" - ], - "cpu": [ - "wasm32" - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1", - "@emnapi/wasi-threads": "^1.1.0", - "@napi-rs/wasm-runtime": "^1.1.0", - "@tybys/wasm-util": "^0.10.1", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.18.tgz", - "integrity": "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.18.tgz", - "integrity": "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, "node_modules/@tailwindcss/postcss": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.18.tgz", - "integrity": "sha512-Ce0GFnzAOuPyfV5SxjXGn0CubwGcuDB0zcdaPuCSzAa/2vII24JTkH+I6jcbXLb1ctjZMZZI6OjDaLPJQL1S0g==", + "version": "4.1.17", "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", - "@tailwindcss/node": "4.1.18", - "@tailwindcss/oxide": "4.1.18", + "@tailwindcss/node": "4.1.17", + "@tailwindcss/oxide": "4.1.17", "postcss": "^8.4.41", - "tailwindcss": "4.1.18" + "tailwindcss": "4.1.17" } }, "node_modules/@trysound/sax": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", "license": "ISC", "engines": { "node": ">=10.13.0" } }, - "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==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "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": { @@ -7982,8 +6588,6 @@ }, "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": { @@ -7992,8 +6596,6 @@ }, "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": { @@ -8003,8 +6605,6 @@ }, "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": { @@ -8013,8 +6613,6 @@ }, "node_modules/@types/body-parser": { "version": "1.19.6", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", - "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", "license": "MIT", "dependencies": { "@types/connect": "*", @@ -8023,8 +6621,6 @@ }, "node_modules/@types/bonjour": { "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -8032,8 +6628,6 @@ }, "node_modules/@types/connect": { "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -8041,8 +6635,6 @@ }, "node_modules/@types/connect-history-api-fallback": { "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", - "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", "license": "MIT", "dependencies": { "@types/express-serve-static-core": "*", @@ -8051,14 +6643,10 @@ }, "node_modules/@types/cytoscape": { "version": "3.21.9", - "resolved": "https://registry.npmjs.org/@types/cytoscape/-/cytoscape-3.21.9.tgz", - "integrity": "sha512-JyrG4tllI6jvuISPjHK9j2Xv/LTbnLekLke5otGStjFluIyA9JjgnvgZrSBsp8cEDpiTjwgZUZwpPv8TSBcoLw==", "license": "MIT" }, "node_modules/@types/d3": { "version": "7.4.3", - "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz", - "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==", "license": "MIT", "dependencies": { "@types/d3-array": "*", @@ -8095,14 +6683,10 @@ }, "node_modules/@types/d3-array": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz", - "integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==", "license": "MIT" }, "node_modules/@types/d3-axis": { "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz", - "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==", "license": "MIT", "dependencies": { "@types/d3-selection": "*" @@ -8110,8 +6694,6 @@ }, "node_modules/@types/d3-brush": { "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz", - "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==", "license": "MIT", "dependencies": { "@types/d3-selection": "*" @@ -8119,20 +6701,14 @@ }, "node_modules/@types/d3-chord": { "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz", - "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==", "license": "MIT" }, "node_modules/@types/d3-color": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", - "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", "license": "MIT" }, "node_modules/@types/d3-contour": { "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz", - "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==", "license": "MIT", "dependencies": { "@types/d3-array": "*", @@ -8141,20 +6717,14 @@ }, "node_modules/@types/d3-delaunay": { "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz", - "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==", "license": "MIT" }, "node_modules/@types/d3-dispatch": { "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz", - "integrity": "sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==", "license": "MIT" }, "node_modules/@types/d3-drag": { "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz", - "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==", "license": "MIT", "dependencies": { "@types/d3-selection": "*" @@ -8162,20 +6732,14 @@ }, "node_modules/@types/d3-dsv": { "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz", - "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==", "license": "MIT" }, "node_modules/@types/d3-ease": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", - "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", "license": "MIT" }, "node_modules/@types/d3-fetch": { "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz", - "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==", "license": "MIT", "dependencies": { "@types/d3-dsv": "*" @@ -8183,20 +6747,14 @@ }, "node_modules/@types/d3-force": { "version": "3.0.10", - "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz", - "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==", "license": "MIT" }, "node_modules/@types/d3-format": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz", - "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==", "license": "MIT" }, "node_modules/@types/d3-geo": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz", - "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==", "license": "MIT", "dependencies": { "@types/geojson": "*" @@ -8204,14 +6762,10 @@ }, "node_modules/@types/d3-hierarchy": { "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz", - "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==", "license": "MIT" }, "node_modules/@types/d3-interpolate": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", - "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", "license": "MIT", "dependencies": { "@types/d3-color": "*" @@ -8219,32 +6773,22 @@ }, "node_modules/@types/d3-path": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", - "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", "license": "MIT" }, "node_modules/@types/d3-polygon": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz", - "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==", "license": "MIT" }, "node_modules/@types/d3-quadtree": { "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz", - "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==", "license": "MIT" }, "node_modules/@types/d3-random": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz", - "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==", "license": "MIT" }, "node_modules/@types/d3-scale": { "version": "4.0.9", - "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", - "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", "license": "MIT", "dependencies": { "@types/d3-time": "*" @@ -8252,20 +6796,14 @@ }, "node_modules/@types/d3-scale-chromatic": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", - "integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==", "license": "MIT" }, "node_modules/@types/d3-selection": { "version": "3.0.11", - "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz", - "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==", "license": "MIT" }, "node_modules/@types/d3-shape": { "version": "3.1.7", - "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz", - "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==", "license": "MIT", "dependencies": { "@types/d3-path": "*" @@ -8273,26 +6811,18 @@ }, "node_modules/@types/d3-time": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", - "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", "license": "MIT" }, "node_modules/@types/d3-time-format": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz", - "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==", "license": "MIT" }, "node_modules/@types/d3-timer": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", - "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", "license": "MIT" }, "node_modules/@types/d3-transition": { "version": "3.0.9", - "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz", - "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==", "license": "MIT", "dependencies": { "@types/d3-selection": "*" @@ -8300,8 +6830,6 @@ }, "node_modules/@types/d3-zoom": { "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz", - "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==", "license": "MIT", "dependencies": { "@types/d3-interpolate": "*", @@ -8310,8 +6838,6 @@ }, "node_modules/@types/debug": { "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", "license": "MIT", "dependencies": { "@types/ms": "*" @@ -8319,8 +6845,6 @@ }, "node_modules/@types/eslint": { "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", - "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", "license": "MIT", "dependencies": { "@types/estree": "*", @@ -8329,8 +6853,6 @@ }, "node_modules/@types/eslint-scope": { "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", "license": "MIT", "dependencies": { "@types/eslint": "*", @@ -8339,14 +6861,10 @@ }, "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==", "license": "MIT" }, "node_modules/@types/estree-jsx": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", - "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", "license": "MIT", "dependencies": { "@types/estree": "*" @@ -8354,8 +6872,6 @@ }, "node_modules/@types/express": { "version": "4.17.25", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.25.tgz", - "integrity": "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==", "license": "MIT", "dependencies": { "@types/body-parser": "*", @@ -8366,8 +6882,6 @@ }, "node_modules/@types/express-serve-static-core": { "version": "4.19.7", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.7.tgz", - "integrity": "sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg==", "license": "MIT", "dependencies": { "@types/node": "*", @@ -8378,14 +6892,10 @@ }, "node_modules/@types/geojson": { "version": "7946.0.16", - "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz", - "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==", "license": "MIT" }, "node_modules/@types/graceful-fs": { "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8394,14 +6904,10 @@ }, "node_modules/@types/gtag.js": { "version": "0.0.12", - "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", - "integrity": "sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==", "license": "MIT" }, "node_modules/@types/hast": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", "license": "MIT", "dependencies": { "@types/unist": "*" @@ -8409,32 +6915,22 @@ }, "node_modules/@types/history": { "version": "4.7.11", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", - "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", "license": "MIT" }, "node_modules/@types/html-minifier-terser": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", "license": "MIT" }, "node_modules/@types/http-cache-semantics": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", "license": "MIT" }, "node_modules/@types/http-errors": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", - "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", "license": "MIT" }, "node_modules/@types/http-proxy": { "version": "1.17.17", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.17.tgz", - "integrity": "sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -8442,14 +6938,10 @@ }, "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==", "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==", "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "*" @@ -8457,8 +6949,6 @@ }, "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==", "license": "MIT", "dependencies": { "@types/istanbul-lib-report": "*" @@ -8466,8 +6956,6 @@ }, "node_modules/@types/jest": { "version": "29.5.14", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", - "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8477,20 +6965,14 @@ }, "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==", "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==", "license": "MIT" }, "node_modules/@types/mdast": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", - "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", "license": "MIT", "dependencies": { "@types/unist": "*" @@ -8498,26 +6980,18 @@ }, "node_modules/@types/mdx": { "version": "2.0.13", - "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", - "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", "license": "MIT" }, "node_modules/@types/mime": { "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", "license": "MIT" }, "node_modules/@types/ms": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", "license": "MIT" }, "node_modules/@types/node": { - "version": "20.19.27", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.27.tgz", - "integrity": "sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==", + "version": "20.19.25", "license": "MIT", "dependencies": { "undici-types": "~6.21.0" @@ -8525,55 +6999,43 @@ }, "node_modules/@types/node-forge": { "version": "1.3.14", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.14.tgz", - "integrity": "sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==", "license": "MIT", "dependencies": { "@types/node": "*" } }, + "node_modules/@types/node/node_modules/undici-types": { + "version": "6.21.0", + "license": "MIT" + }, "node_modules/@types/prismjs": { "version": "1.26.5", - "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.5.tgz", - "integrity": "sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==", "license": "MIT" }, "node_modules/@types/qs": { "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", "license": "MIT" }, "node_modules/@types/range-parser": { "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", "license": "MIT" }, "node_modules/@types/react": { "version": "19.2.7", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz", - "integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==", "license": "MIT", - "peer": true, "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==", "license": "MIT", - "peer": true, "peerDependencies": { "@types/react": "^19.2.0" } }, "node_modules/@types/react-router": { "version": "5.1.20", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", - "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", "license": "MIT", "dependencies": { "@types/history": "^4.7.11", @@ -8582,8 +7044,6 @@ }, "node_modules/@types/react-router-config": { "version": "5.0.11", - "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.11.tgz", - "integrity": "sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==", "license": "MIT", "dependencies": { "@types/history": "^4.7.11", @@ -8593,8 +7053,6 @@ }, "node_modules/@types/react-router-dom": { "version": "5.3.3", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", - "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", "license": "MIT", "dependencies": { "@types/history": "^4.7.11", @@ -8604,14 +7062,10 @@ }, "node_modules/@types/retry": { "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", - "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", "license": "MIT" }, "node_modules/@types/sax": { "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", - "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -8619,8 +7073,6 @@ }, "node_modules/@types/send": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", - "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -8628,8 +7080,6 @@ }, "node_modules/@types/serve-index": { "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", - "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", "license": "MIT", "dependencies": { "@types/express": "*" @@ -8637,8 +7087,6 @@ }, "node_modules/@types/serve-static": { "version": "1.15.10", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.10.tgz", - "integrity": "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==", "license": "MIT", "dependencies": { "@types/http-errors": "*", @@ -8648,8 +7096,6 @@ }, "node_modules/@types/serve-static/node_modules/@types/send": { "version": "0.17.6", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.6.tgz", - "integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==", "license": "MIT", "dependencies": { "@types/mime": "^1", @@ -8658,8 +7104,6 @@ }, "node_modules/@types/sockjs": { "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", - "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -8667,40 +7111,28 @@ }, "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/stylis": { "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz", - "integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==", "license": "MIT" }, "node_modules/@types/trusted-types": { "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", - "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", "license": "MIT", "optional": true }, "node_modules/@types/unist": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", - "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", "license": "MIT" }, "node_modules/@types/use-sync-external-store": { "version": "0.0.6", - "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", - "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", "license": "MIT" }, "node_modules/@types/ws": { "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", "license": "MIT", "dependencies": { "@types/node": "*" @@ -8708,8 +7140,6 @@ }, "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==", "license": "MIT", "dependencies": { "@types/yargs-parser": "*" @@ -8717,14 +7147,10 @@ }, "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==", "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.50.0.tgz", - "integrity": "sha512-O7QnmOXYKVtPrfYzMolrCTfkezCJS9+ljLdKW/+DCvRsc3UAz+sbH6Xcsv7p30+0OwUbeWfUDAQE0vpabZ3QLg==", "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", @@ -8751,8 +7177,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">= 4" @@ -8760,10 +7184,7 @@ }, "node_modules/@typescript-eslint/parser": { "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.50.0.tgz", - "integrity": "sha512-6/cmF2piao+f6wSxUsJLZjck7OQsYyRtcOZS02k7XINSNlz93v6emM8WutDQSXnroG2xwYlEVHJI+cPA7CPM3Q==", "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.50.0", "@typescript-eslint/types": "8.50.0", @@ -8785,8 +7206,6 @@ }, "node_modules/@typescript-eslint/project-service": { "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.50.0.tgz", - "integrity": "sha512-Cg/nQcL1BcoTijEWyx4mkVC56r8dj44bFDvBdygifuS20f3OZCHmFbjF34DPSi07kwlFvqfv/xOLnJ5DquxSGQ==", "license": "MIT", "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.50.0", @@ -8806,8 +7225,6 @@ }, "node_modules/@typescript-eslint/scope-manager": { "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.50.0.tgz", - "integrity": "sha512-xCwfuCZjhIqy7+HKxBLrDVT5q/iq7XBVBXLn57RTIIpelLtEIZHXAF/Upa3+gaCpeV1NNS5Z9A+ID6jn50VD4A==", "license": "MIT", "dependencies": { "@typescript-eslint/types": "8.50.0", @@ -8823,8 +7240,6 @@ }, "node_modules/@typescript-eslint/tsconfig-utils": { "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.50.0.tgz", - "integrity": "sha512-vxd3G/ybKTSlm31MOA96gqvrRGv9RJ7LGtZCn2Vrc5htA0zCDvcMqUkifcjrWNNKXHUU3WCkYOzzVSFBd0wa2w==", "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -8839,8 +7254,6 @@ }, "node_modules/@typescript-eslint/type-utils": { "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.50.0.tgz", - "integrity": "sha512-7OciHT2lKCewR0mFoBrvZJ4AXTMe/sYOe87289WAViOocEmDjjv8MvIOT2XESuKj9jp8u3SZYUSh89QA4S1kQw==", "license": "MIT", "dependencies": { "@typescript-eslint/types": "8.50.0", @@ -8863,8 +7276,6 @@ }, "node_modules/@typescript-eslint/types": { "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.50.0.tgz", - "integrity": "sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w==", "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -8876,8 +7287,6 @@ }, "node_modules/@typescript-eslint/typescript-estree": { "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.50.0.tgz", - "integrity": "sha512-W7SVAGBR/IX7zm1t70Yujpbk+zdPq/u4soeFSknWFdXIFuWsBGBOUu/Tn/I6KHSKvSh91OiMuaSnYp3mtPt5IQ==", "license": "MIT", "dependencies": { "@typescript-eslint/project-service": "8.50.0", @@ -8901,19 +7310,8 @@ "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/typescript-estree/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==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -8927,8 +7325,6 @@ }, "node_modules/@typescript-eslint/utils": { "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.50.0.tgz", - "integrity": "sha512-87KgUXET09CRjGCi2Ejxy3PULXna63/bMYv72tCAlDJC3Yqwln0HiFJ3VJMst2+mEtNtZu5oFvX4qJGjKsnAgg==", "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", @@ -8950,8 +7346,6 @@ }, "node_modules/@typescript-eslint/visitor-keys": { "version": "8.50.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.50.0.tgz", - "integrity": "sha512-Xzmnb58+Db78gT/CCj/PVCvK+zxbnsw6F+O1oheYszJbBSdEjVhQi3C/Xttzxgi/GLmpvOggRs1RFpiJ8+c34Q==", "license": "MIT", "dependencies": { "@typescript-eslint/types": "8.50.0", @@ -8967,40 +7361,10 @@ }, "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==", "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" - ], - "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" - ], - "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" ], @@ -9010,217 +7374,6 @@ "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" - ], - "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" - ], - "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" - ], - "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" - ], - "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" - ], - "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" - ], - "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" - ], - "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" - ], - "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" - ], - "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" - ], - "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" - ], - "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" - ], - "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" - ], - "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" - ], - "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" - ], - "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" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@vectorize-io/hindsight-client": { "resolved": "hindsight-clients/typescript", "link": true @@ -9231,8 +7384,6 @@ }, "node_modules/@vercel/oidc": { "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@vercel/oidc/-/oidc-3.0.5.tgz", - "integrity": "sha512-fnYhv671l+eTTp48gB4zEsTW/YtRgRPnkI2nT7x6qw5rkI1Lq2hTmQIpHPgyThI0znLK+vX2n9XxKdXZ7BUbbw==", "license": "Apache-2.0", "engines": { "node": ">= 20" @@ -9240,8 +7391,6 @@ }, "node_modules/@webassemblyjs/ast": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", - "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", "license": "MIT", "dependencies": { "@webassemblyjs/helper-numbers": "1.13.2", @@ -9250,26 +7399,18 @@ }, "node_modules/@webassemblyjs/floating-point-hex-parser": { "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", - "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", "license": "MIT" }, "node_modules/@webassemblyjs/helper-api-error": { "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", - "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", "license": "MIT" }, "node_modules/@webassemblyjs/helper-buffer": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", - "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", - "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", "license": "MIT", "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.13.2", @@ -9279,14 +7420,10 @@ }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", - "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", - "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", @@ -9297,8 +7434,6 @@ }, "node_modules/@webassemblyjs/ieee754": { "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", - "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" @@ -9306,8 +7441,6 @@ }, "node_modules/@webassemblyjs/leb128": { "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", - "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" @@ -9315,14 +7448,10 @@ }, "node_modules/@webassemblyjs/utf8": { "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", - "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", - "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", @@ -9337,8 +7466,6 @@ }, "node_modules/@webassemblyjs/wasm-gen": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", - "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", @@ -9350,8 +7477,6 @@ }, "node_modules/@webassemblyjs/wasm-opt": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", - "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", @@ -9362,8 +7487,6 @@ }, "node_modules/@webassemblyjs/wasm-parser": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", - "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", @@ -9376,8 +7499,6 @@ }, "node_modules/@webassemblyjs/wast-printer": { "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", - "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.14.1", @@ -9386,20 +7507,14 @@ }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", "license": "BSD-3-Clause" }, "node_modules/@xtuc/long": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", "license": "Apache-2.0" }, "node_modules/accepts": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "license": "MIT", "dependencies": { "mime-types": "~2.1.34", @@ -9409,31 +7524,8 @@ "node": ">= 0.6" } }, - "node_modules/accepts/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/accepts/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/accepts/node_modules/negotiator": { "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -9441,10 +7533,7 @@ }, "node_modules/acorn": { "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -9454,8 +7543,6 @@ }, "node_modules/acorn-import-phases": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", - "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", "license": "MIT", "engines": { "node": ">=10.13.0" @@ -9466,8 +7553,6 @@ }, "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==", "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" @@ -9475,8 +7560,6 @@ }, "node_modules/acorn-walk": { "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", "license": "MIT", "dependencies": { "acorn": "^8.11.0" @@ -9487,8 +7570,6 @@ }, "node_modules/address": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", - "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", "license": "MIT", "engines": { "node": ">= 10.0.0" @@ -9496,8 +7577,6 @@ }, "node_modules/agent-base": { "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "license": "MIT", "engines": { "node": ">= 14" @@ -9505,8 +7584,6 @@ }, "node_modules/aggregate-error": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", "license": "MIT", "dependencies": { "clean-stack": "^2.0.0", @@ -9517,14 +7594,12 @@ } }, "node_modules/ai": { - "version": "5.0.116", - "resolved": "https://registry.npmjs.org/ai/-/ai-5.0.116.tgz", - "integrity": "sha512-+2hYJ80/NcDWuv9K2/MLP3cTCFgwWHmHlS1tOpFUKKcmLbErAAlE/S2knsKboc3PNAu8pQkDr2N3K/Vle7ENgQ==", + "version": "5.0.106", "license": "Apache-2.0", "dependencies": { - "@ai-sdk/gateway": "2.0.23", + "@ai-sdk/gateway": "2.0.18", "@ai-sdk/provider": "2.0.0", - "@ai-sdk/provider-utils": "3.0.19", + "@ai-sdk/provider-utils": "3.0.18", "@opentelemetry/api": "1.9.0" }, "engines": { @@ -9536,10 +7611,7 @@ }, "node_modules/ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -9553,8 +7625,6 @@ }, "node_modules/ajv-formats": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", "license": "MIT", "dependencies": { "ajv": "^8.0.0" @@ -9570,8 +7640,6 @@ }, "node_modules/ajv-formats/node_modules/ajv": { "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -9584,42 +7652,35 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, "node_modules/ajv-keywords": { "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" } }, + "node_modules/ajv/node_modules/json-schema-traverse": { + "version": "0.4.1", + "license": "MIT" + }, "node_modules/algoliasearch": { - "version": "5.46.1", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.46.1.tgz", - "integrity": "sha512-39ol8Ulqb3MntofkXHlrcXKyU8BU0PXvQrXPBIX6eXj/EO4VT7651mhGVORI2oF8ydya9nFzT3fYDoqme/KL6w==", + "version": "5.46.0", "license": "MIT", - "peer": true, "dependencies": { - "@algolia/abtesting": "1.12.1", - "@algolia/client-abtesting": "5.46.1", - "@algolia/client-analytics": "5.46.1", - "@algolia/client-common": "5.46.1", - "@algolia/client-insights": "5.46.1", - "@algolia/client-personalization": "5.46.1", - "@algolia/client-query-suggestions": "5.46.1", - "@algolia/client-search": "5.46.1", - "@algolia/ingestion": "1.46.1", - "@algolia/monitoring": "1.46.1", - "@algolia/recommend": "5.46.1", - "@algolia/requester-browser-xhr": "5.46.1", - "@algolia/requester-fetch": "5.46.1", - "@algolia/requester-node-http": "5.46.1" + "@algolia/abtesting": "1.12.0", + "@algolia/client-abtesting": "5.46.0", + "@algolia/client-analytics": "5.46.0", + "@algolia/client-common": "5.46.0", + "@algolia/client-insights": "5.46.0", + "@algolia/client-personalization": "5.46.0", + "@algolia/client-query-suggestions": "5.46.0", + "@algolia/client-search": "5.46.0", + "@algolia/ingestion": "1.46.0", + "@algolia/monitoring": "1.46.0", + "@algolia/recommend": "5.46.0", + "@algolia/requester-browser-xhr": "5.46.0", + "@algolia/requester-fetch": "5.46.0", + "@algolia/requester-node-http": "5.46.0" }, "engines": { "node": ">= 14.0.0" @@ -9627,8 +7688,6 @@ }, "node_modules/algoliasearch-helper": { "version": "3.26.1", - "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.26.1.tgz", - "integrity": "sha512-CAlCxm4fYBXtvc5MamDzP6Svu8rW4z9me4DCBY1rQ2UDJ0u0flWmusQ8M3nOExZsLLRcUwUPoRAPMrhzOG3erw==", "license": "MIT", "dependencies": { "@algolia/events": "^4.0.1" @@ -9639,8 +7698,6 @@ }, "node_modules/ansi-align": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", "license": "ISC", "dependencies": { "string-width": "^4.1.0" @@ -9648,14 +7705,10 @@ }, "node_modules/ansi-align/node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "license": "MIT" }, "node_modules/ansi-align/node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -9668,8 +7721,6 @@ }, "node_modules/ansi-colors": { "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", "dev": true, "license": "MIT", "engines": { @@ -9678,8 +7729,6 @@ }, "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==", "license": "MIT", "dependencies": { "type-fest": "^0.21.3" @@ -9693,8 +7742,6 @@ }, "node_modules/ansi-escapes/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==", "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -9705,8 +7752,6 @@ }, "node_modules/ansi-html-community": { "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", "engines": [ "node >= 0.8.0" ], @@ -9717,8 +7762,6 @@ }, "node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "license": "MIT", "engines": { "node": ">=8" @@ -9726,8 +7769,6 @@ }, "node_modules/ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -9741,8 +7782,6 @@ }, "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==", "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", @@ -9754,20 +7793,14 @@ }, "node_modules/arg": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", "license": "MIT" }, "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==", "license": "Python-2.0" }, "node_modules/aria-hidden": { "version": "1.2.6", - "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz", - "integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==", "license": "MIT", "dependencies": { "tslib": "^2.0.0" @@ -9778,8 +7811,6 @@ }, "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==", "license": "Apache-2.0", "engines": { "node": ">= 0.4" @@ -9787,8 +7818,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -9803,14 +7832,10 @@ }, "node_modules/array-flatten": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "license": "MIT" }, "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==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -9831,8 +7856,6 @@ }, "node_modules/array-union": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "license": "MIT", "engines": { "node": ">=8" @@ -9840,8 +7863,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bind": "^1.0.7", @@ -9860,8 +7881,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -9881,8 +7900,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -9899,8 +7916,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -9917,8 +7932,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bind": "^1.0.7", @@ -9933,8 +7946,6 @@ }, "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==", "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.1", @@ -9954,14 +7965,10 @@ }, "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==", "license": "MIT" }, "node_modules/astring": { "version": "1.9.0", - "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", - "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", "license": "MIT", "bin": { "astring": "bin/astring" @@ -9969,17 +7976,13 @@ }, "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==", "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/autoprefixer": { - "version": "10.4.23", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.23.tgz", - "integrity": "sha512-YYTXSFulfwytnjAPlw8QHncHJmlvFKtczb8InXaAx9Q0LbfDnfEYDE55omerIJKihhmU61Ft+cAOSzQVaBUmeA==", + "version": "10.4.22", "funding": [ { "type": "opencollective", @@ -9996,9 +7999,10 @@ ], "license": "MIT", "dependencies": { - "browserslist": "^4.28.1", - "caniuse-lite": "^1.0.30001760", + "browserslist": "^4.27.0", + "caniuse-lite": "^1.0.30001754", "fraction.js": "^5.3.4", + "normalize-range": "^0.1.2", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, @@ -10014,8 +8018,6 @@ }, "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==", "license": "MIT", "dependencies": { "possible-typed-array-names": "^1.0.0" @@ -10029,8 +8031,6 @@ }, "node_modules/axe-core": { "version": "4.11.0", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.0.tgz", - "integrity": "sha512-ilYanEU8vxxBexpJd8cWM4ElSQq4QctCLKih0TSfjIfCQTeyH/6zVrmIJfLPrKTKJRbiG+cfnZbQIjAlJmF1jQ==", "license": "MPL-2.0", "engines": { "node": ">=4" @@ -10038,8 +8038,6 @@ }, "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==", "license": "Apache-2.0", "engines": { "node": ">= 0.4" @@ -10047,8 +8045,6 @@ }, "node_modules/babel-jest": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", - "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "dev": true, "license": "MIT", "dependencies": { @@ -10069,8 +8065,6 @@ }, "node_modules/babel-loader": { "version": "9.2.1", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz", - "integrity": "sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==", "license": "MIT", "dependencies": { "find-cache-dir": "^4.0.0", @@ -10086,8 +8080,6 @@ }, "node_modules/babel-plugin-dynamic-import-node": { "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", "license": "MIT", "dependencies": { "object.assign": "^4.1.0" @@ -10095,8 +8087,6 @@ }, "node_modules/babel-plugin-istanbul": { "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -10112,8 +8102,6 @@ }, "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -10129,8 +8117,6 @@ }, "node_modules/babel-plugin-istanbul/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": { @@ -10139,8 +8125,6 @@ }, "node_modules/babel-plugin-jest-hoist": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", - "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", "dev": true, "license": "MIT", "dependencies": { @@ -10155,8 +8139,6 @@ }, "node_modules/babel-plugin-polyfill-corejs2": { "version": "0.4.14", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", - "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", "license": "MIT", "dependencies": { "@babel/compat-data": "^7.27.7", @@ -10169,8 +8151,6 @@ }, "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -10178,8 +8158,6 @@ }, "node_modules/babel-plugin-polyfill-corejs3": { "version": "0.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", - "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", "license": "MIT", "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.5", @@ -10191,8 +8169,6 @@ }, "node_modules/babel-plugin-polyfill-regenerator": { "version": "0.6.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", - "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", "license": "MIT", "dependencies": { "@babel/helper-define-polyfill-provider": "^0.6.5" @@ -10203,8 +8179,6 @@ }, "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": { @@ -10230,8 +8204,6 @@ }, "node_modules/babel-preset-jest": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", - "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", "dev": true, "license": "MIT", "dependencies": { @@ -10247,8 +8219,6 @@ }, "node_modules/bail": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", "license": "MIT", "funding": { "type": "github", @@ -10257,14 +8227,10 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.9.11", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz", - "integrity": "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==", + "version": "2.9.2", "license": "Apache-2.0", "bin": { "baseline-browser-mapping": "dist/cli.js" @@ -10272,14 +8238,10 @@ }, "node_modules/batch": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", "license": "MIT" }, "node_modules/big.js": { "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", "license": "MIT", "engines": { "node": "*" @@ -10287,8 +8249,6 @@ }, "node_modules/binary-extensions": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", "license": "MIT", "engines": { "node": ">=8" @@ -10299,8 +8259,6 @@ }, "node_modules/body-parser": { "version": "1.20.4", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", - "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", "license": "MIT", "dependencies": { "bytes": "~3.1.2", @@ -10323,8 +8281,6 @@ }, "node_modules/body-parser/node_modules/bytes": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -10332,8 +8288,6 @@ }, "node_modules/body-parser/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -10341,8 +8295,6 @@ }, "node_modules/body-parser/node_modules/iconv-lite": { "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" @@ -10353,14 +8305,10 @@ }, "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/bonjour-service": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", - "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -10369,14 +8317,10 @@ }, "node_modules/boolbase": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", "license": "ISC" }, "node_modules/boxen": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-6.2.1.tgz", - "integrity": "sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==", "license": "MIT", "dependencies": { "ansi-align": "^3.0.1", @@ -10396,19 +8340,14 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "2.0.2", "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "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==", "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -10419,8 +8358,6 @@ }, "node_modules/browserslist": { "version": "4.28.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", - "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "funding": [ { "type": "opencollective", @@ -10436,7 +8373,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -10453,8 +8389,6 @@ }, "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": { @@ -10466,8 +8400,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": { @@ -10476,14 +8408,10 @@ }, "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==", "license": "MIT" }, "node_modules/bundle-name": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", - "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", "license": "MIT", "dependencies": { "run-applescript": "^7.0.0" @@ -10497,8 +8425,6 @@ }, "node_modules/bytes": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -10506,8 +8432,6 @@ }, "node_modules/c12": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/c12/-/c12-3.3.2.tgz", - "integrity": "sha512-QkikB2X5voO1okL3QsES0N690Sn/K9WokXqUsDQsWy5SnYb+psYQFGA10iy1bZHj3fjISKsI67Q90gruvWWM3A==", "dev": true, "license": "MIT", "dependencies": { @@ -10535,8 +8459,6 @@ }, "node_modules/c12/node_modules/chokidar": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, "license": "MIT", "dependencies": { @@ -10551,8 +8473,6 @@ }, "node_modules/c12/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": { @@ -10561,8 +8481,6 @@ }, "node_modules/c12/node_modules/readdirp": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "dev": true, "license": "MIT", "engines": { @@ -10575,8 +8493,6 @@ }, "node_modules/cacheable-lookup": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", - "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", "license": "MIT", "engines": { "node": ">=14.16" @@ -10584,8 +8500,6 @@ }, "node_modules/cacheable-request": { "version": "10.2.14", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", - "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", "license": "MIT", "dependencies": { "@types/http-cache-semantics": "^4.0.2", @@ -10602,8 +8516,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.0", @@ -10620,8 +8532,6 @@ }, "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==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -10633,8 +8543,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -10649,14 +8557,10 @@ }, "node_modules/call-me-maybe": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", - "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", "license": "MIT" }, "node_modules/callsites": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "license": "MIT", "engines": { "node": ">=6" @@ -10664,8 +8568,6 @@ }, "node_modules/camel-case": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", "license": "MIT", "dependencies": { "pascal-case": "^3.1.2", @@ -10674,8 +8576,6 @@ }, "node_modules/camelcase": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "license": "MIT", "engines": { "node": ">=10" @@ -10686,8 +8586,6 @@ }, "node_modules/camelize": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", - "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -10695,8 +8593,6 @@ }, "node_modules/caniuse-api": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", "license": "MIT", "dependencies": { "browserslist": "^4.0.0", @@ -10706,9 +8602,7 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001761", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001761.tgz", - "integrity": "sha512-JF9ptu1vP2coz98+5051jZ4PwQgd2ni8A+gYSN7EA7dPKIMf0pDlSUxhdmVOaV3/fYK5uWBkgSXJaRLr4+3A6g==", + "version": "1.0.30001759", "funding": [ { "type": "opencollective", @@ -10727,8 +8621,6 @@ }, "node_modules/ccount": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", "license": "MIT", "funding": { "type": "github", @@ -10737,8 +8629,6 @@ }, "node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -10753,8 +8643,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">=10" @@ -10762,8 +8650,6 @@ }, "node_modules/character-entities": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", "license": "MIT", "funding": { "type": "github", @@ -10772,8 +8658,6 @@ }, "node_modules/character-entities-html4": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", - "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", "license": "MIT", "funding": { "type": "github", @@ -10782,8 +8666,6 @@ }, "node_modules/character-entities-legacy": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", "license": "MIT", "funding": { "type": "github", @@ -10792,8 +8674,6 @@ }, "node_modules/character-reference-invalid": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", - "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", "license": "MIT", "funding": { "type": "github", @@ -10802,8 +8682,6 @@ }, "node_modules/cheerio": { "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", - "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", "license": "MIT", "dependencies": { "cheerio-select": "^2.1.0", @@ -10823,8 +8701,6 @@ }, "node_modules/cheerio-select": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", @@ -10840,8 +8716,6 @@ }, "node_modules/chevrotain": { "version": "11.0.3", - "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz", - "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==", "license": "Apache-2.0", "dependencies": { "@chevrotain/cst-dts-gen": "11.0.3", @@ -10854,8 +8728,6 @@ }, "node_modules/chevrotain-allstar": { "version": "0.3.1", - "resolved": "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz", - "integrity": "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==", "license": "MIT", "dependencies": { "lodash-es": "^4.17.21" @@ -10864,16 +8736,8 @@ "chevrotain": "^11.0.0" } }, - "node_modules/chevrotain/node_modules/lodash-es": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", - "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", - "license": "MIT" - }, "node_modules/chokidar": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "license": "MIT", "dependencies": { "anymatch": "~3.1.2", @@ -10896,8 +8760,6 @@ }, "node_modules/chrome-trace-event": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", "license": "MIT", "engines": { "node": ">=6.0" @@ -10905,8 +8767,6 @@ }, "node_modules/ci-info": { "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "funding": [ { "type": "github", @@ -10920,8 +8780,6 @@ }, "node_modules/citty": { "version": "0.1.6", - "resolved": "https://registry.npmjs.org/citty/-/citty-0.1.6.tgz", - "integrity": "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10930,15 +8788,11 @@ }, "node_modules/cjs-module-lexer": { "version": "1.4.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", - "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", "dev": true, "license": "MIT" }, "node_modules/class-variance-authority": { "version": "0.7.1", - "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", - "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", "license": "Apache-2.0", "dependencies": { "clsx": "^2.1.1" @@ -10949,14 +8803,10 @@ }, "node_modules/classnames": { "version": "2.5.1", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", - "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==", "license": "MIT" }, "node_modules/clean-css": { "version": "5.3.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", - "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", "license": "MIT", "dependencies": { "source-map": "~0.6.0" @@ -10967,8 +8817,6 @@ }, "node_modules/clean-css/node_modules/source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -10976,8 +8824,6 @@ }, "node_modules/clean-stack": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "license": "MIT", "engines": { "node": ">=6" @@ -10985,8 +8831,6 @@ }, "node_modules/cli-boxes": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", - "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", "license": "MIT", "engines": { "node": ">=10" @@ -10997,8 +8841,6 @@ }, "node_modules/cli-table3": { "version": "0.6.5", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", - "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", "license": "MIT", "dependencies": { "string-width": "^4.2.0" @@ -11012,14 +8854,10 @@ }, "node_modules/cli-table3/node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "license": "MIT" }, "node_modules/cli-table3/node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -11032,14 +8870,10 @@ }, "node_modules/client-only": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", - "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", "license": "MIT" }, "node_modules/cliui": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "license": "ISC", "dependencies": { "string-width": "^4.2.0", @@ -11052,14 +8886,10 @@ }, "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==", "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==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -11072,8 +8902,6 @@ }, "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==", "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -11089,8 +8917,6 @@ }, "node_modules/clone-deep": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", "license": "MIT", "dependencies": { "is-plain-object": "^2.0.4", @@ -11103,8 +8929,6 @@ }, "node_modules/clsx": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", - "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", "license": "MIT", "engines": { "node": ">=6" @@ -11112,8 +8936,6 @@ }, "node_modules/cmdk": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-1.1.1.tgz", - "integrity": "sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==", "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "^1.1.1", @@ -11128,8 +8950,6 @@ }, "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": { @@ -11139,8 +8959,6 @@ }, "node_modules/collapse-white-space": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", - "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", "license": "MIT", "funding": { "type": "github", @@ -11149,15 +8967,11 @@ }, "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==", "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -11168,14 +8982,10 @@ }, "node_modules/color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/color-support": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "dev": true, "license": "ISC", "bin": { @@ -11184,29 +8994,25 @@ }, "node_modules/colord": { "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", "license": "MIT" }, "node_modules/colorette": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", - "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", "license": "MIT" }, "node_modules/combine-promises": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/combine-promises/-/combine-promises-1.2.0.tgz", - "integrity": "sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==", "license": "MIT", "engines": { "node": ">=10" } }, + "node_modules/comlink": { + "version": "4.4.2", + "license": "Apache-2.0" + }, "node_modules/comma-separated-tokens": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", "license": "MIT", "funding": { "type": "github", @@ -11215,8 +9021,6 @@ }, "node_modules/commander": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", "license": "MIT", "engines": { "node": ">= 6" @@ -11224,14 +9028,10 @@ }, "node_modules/common-path-prefix": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", "license": "ISC" }, "node_modules/compressible": { "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", "license": "MIT", "dependencies": { "mime-db": ">= 1.43.0 < 2" @@ -11240,19 +9040,8 @@ "node": ">= 0.6" } }, - "node_modules/compressible/node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/compression": { "version": "1.8.1", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", - "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", "license": "MIT", "dependencies": { "bytes": "3.1.2", @@ -11269,8 +9058,6 @@ }, "node_modules/compression/node_modules/bytes": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -11278,8 +9065,6 @@ }, "node_modules/compression/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -11287,27 +9072,19 @@ }, "node_modules/compression/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "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==", "license": "MIT" }, "node_modules/confbox": { "version": "0.2.2", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", - "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", "dev": true, "license": "MIT" }, "node_modules/config-chain": { "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", "license": "MIT", "dependencies": { "ini": "^1.3.4", @@ -11316,14 +9093,10 @@ }, "node_modules/config-chain/node_modules/ini": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "license": "ISC" }, "node_modules/configstore": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", - "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", "license": "BSD-2-Clause", "dependencies": { "dot-prop": "^6.0.1", @@ -11341,8 +9114,6 @@ }, "node_modules/configstore/node_modules/write-file-atomic": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", @@ -11353,8 +9124,6 @@ }, "node_modules/connect-history-api-fallback": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", "license": "MIT", "engines": { "node": ">=0.8" @@ -11362,8 +9131,6 @@ }, "node_modules/consola": { "version": "3.4.2", - "resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz", - "integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==", "license": "MIT", "engines": { "node": "^14.18.0 || >=16.10.0" @@ -11371,8 +9138,6 @@ }, "node_modules/content-disposition": { "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -11380,8 +9145,6 @@ }, "node_modules/content-type": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -11389,14 +9152,10 @@ }, "node_modules/convert-source-map": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "license": "MIT" }, "node_modules/cookie": { "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -11404,14 +9163,10 @@ }, "node_modules/cookie-signature": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", - "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", "license": "MIT" }, "node_modules/copy-to-clipboard": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", - "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", "license": "MIT", "dependencies": { "toggle-selection": "^1.0.6" @@ -11419,8 +9174,6 @@ }, "node_modules/copy-webpack-plugin": { "version": "11.0.0", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", - "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", "license": "MIT", "dependencies": { "fast-glob": "^3.2.11", @@ -11443,8 +9196,6 @@ }, "node_modules/copy-webpack-plugin/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==", "license": "ISC", "dependencies": { "is-glob": "^4.0.3" @@ -11455,8 +9206,6 @@ }, "node_modules/copy-webpack-plugin/node_modules/globby": { "version": "13.2.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", - "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", "license": "MIT", "dependencies": { "dir-glob": "^3.0.1", @@ -11474,8 +9223,6 @@ }, "node_modules/copy-webpack-plugin/node_modules/slash": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", "license": "MIT", "engines": { "node": ">=12" @@ -11486,11 +9233,8 @@ }, "node_modules/core-js": { "version": "3.47.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.47.0.tgz", - "integrity": "sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg==", "hasInstallScript": true, "license": "MIT", - "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" @@ -11498,8 +9242,6 @@ }, "node_modules/core-js-compat": { "version": "3.47.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.47.0.tgz", - "integrity": "sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==", "license": "MIT", "dependencies": { "browserslist": "^4.28.0" @@ -11511,8 +9253,6 @@ }, "node_modules/core-js-pure": { "version": "3.47.0", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.47.0.tgz", - "integrity": "sha512-BcxeDbzUrRnXGYIVAGFtcGQVNpFcUhVjr6W7F8XktvQW2iJP9e66GP6xdKotCRFlrxBvNIBrhwKteRXqMV86Nw==", "hasInstallScript": true, "license": "MIT", "funding": { @@ -11522,14 +9262,10 @@ }, "node_modules/core-util-is": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "license": "MIT" }, "node_modules/cose-base": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz", - "integrity": "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==", "license": "MIT", "dependencies": { "layout-base": "^1.0.0" @@ -11537,8 +9273,6 @@ }, "node_modules/cosmiconfig": { "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", "license": "MIT", "dependencies": { "import-fresh": "^3.3.0", @@ -11563,8 +9297,6 @@ }, "node_modules/create-jest": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", - "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", "dev": true, "license": "MIT", "dependencies": { @@ -11585,8 +9317,6 @@ }, "node_modules/cross-spawn": { "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -11599,8 +9329,6 @@ }, "node_modules/crypto-random-string": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", - "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", "license": "MIT", "dependencies": { "type-fest": "^1.0.1" @@ -11614,8 +9342,6 @@ }, "node_modules/crypto-random-string/node_modules/type-fest": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" @@ -11626,8 +9352,6 @@ }, "node_modules/css-blank-pseudo": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/css-blank-pseudo/-/css-blank-pseudo-7.0.1.tgz", - "integrity": "sha512-jf+twWGDf6LDoXDUode+nc7ZlrqfaNphrBIBrcmeP3D8yw1uPaix1gCC8LUQUGQ6CycuK2opkbFFWFuq/a94ag==", "funding": [ { "type": "github", @@ -11651,8 +9375,6 @@ }, "node_modules/css-blank-pseudo/node_modules/postcss-selector-parser": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", - "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -11664,8 +9386,6 @@ }, "node_modules/css-color-keywords": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", - "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", "license": "ISC", "engines": { "node": ">=4" @@ -11673,8 +9393,6 @@ }, "node_modules/css-declaration-sorter": { "version": "7.3.0", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-7.3.0.tgz", - "integrity": "sha512-LQF6N/3vkAMYF4xoHLJfG718HRJh34Z8BnNhd6bosOMIVjMlhuZK5++oZa3uYAgrI5+7x2o27gUqTR2U/KjUOQ==", "license": "ISC", "engines": { "node": "^14 || ^16 || >=18" @@ -11685,8 +9403,6 @@ }, "node_modules/css-has-pseudo": { "version": "7.0.3", - "resolved": "https://registry.npmjs.org/css-has-pseudo/-/css-has-pseudo-7.0.3.tgz", - "integrity": "sha512-oG+vKuGyqe/xvEMoxAQrhi7uY16deJR3i7wwhBerVrGQKSqUC5GiOVxTpM9F9B9hw0J+eKeOWLH7E9gZ1Dr5rA==", "funding": [ { "type": "github", @@ -11712,8 +9428,6 @@ }, "node_modules/css-has-pseudo/node_modules/@csstools/selector-specificity": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", - "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", "funding": [ { "type": "github", @@ -11734,10 +9448,7 @@ }, "node_modules/css-has-pseudo/node_modules/postcss-selector-parser": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", - "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -11748,8 +9459,6 @@ }, "node_modules/css-loader": { "version": "6.11.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.11.0.tgz", - "integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==", "license": "MIT", "dependencies": { "icss-utils": "^5.1.0", @@ -11783,8 +9492,6 @@ }, "node_modules/css-minimizer-webpack-plugin": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz", - "integrity": "sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==", "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.18", @@ -11827,8 +9534,6 @@ }, "node_modules/css-prefers-color-scheme": { "version": "10.0.0", - "resolved": "https://registry.npmjs.org/css-prefers-color-scheme/-/css-prefers-color-scheme-10.0.0.tgz", - "integrity": "sha512-VCtXZAWivRglTZditUfB4StnsWr6YVZ2PRtuxQLKTNRdtAf8tpzaVPE9zXIF3VaSc7O70iK/j1+NXxyQCqdPjQ==", "funding": [ { "type": "github", @@ -11849,8 +9554,6 @@ }, "node_modules/css-select": { "version": "5.2.2", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", - "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", @@ -11865,8 +9568,6 @@ }, "node_modules/css-to-react-native": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", - "integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==", "license": "MIT", "dependencies": { "camelize": "^1.0.0", @@ -11876,8 +9577,6 @@ }, "node_modules/css-tree": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", "license": "MIT", "dependencies": { "mdn-data": "2.0.30", @@ -11889,8 +9588,6 @@ }, "node_modules/css-what": { "version": "6.2.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", - "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", "license": "BSD-2-Clause", "engines": { "node": ">= 6" @@ -11901,8 +9598,6 @@ }, "node_modules/cssdb": { "version": "8.5.2", - "resolved": "https://registry.npmjs.org/cssdb/-/cssdb-8.5.2.tgz", - "integrity": "sha512-Pmoj9RmD8RIoIzA2EQWO4D4RMeDts0tgAH0VXdlNdxjuBGI3a9wMOIcUwaPNmD4r2qtIa06gqkIf7sECl+cBCg==", "funding": [ { "type": "opencollective", @@ -11917,8 +9612,6 @@ }, "node_modules/cssesc": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "license": "MIT", "bin": { "cssesc": "bin/cssesc" @@ -11929,14 +9622,10 @@ }, "node_modules/cssfilter": { "version": "0.0.10", - "resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz", - "integrity": "sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==", "license": "MIT" }, "node_modules/cssnano": { "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-6.1.2.tgz", - "integrity": "sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==", "license": "MIT", "dependencies": { "cssnano-preset-default": "^6.1.2", @@ -11955,8 +9644,6 @@ }, "node_modules/cssnano-preset-advanced": { "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-6.1.2.tgz", - "integrity": "sha512-Nhao7eD8ph2DoHolEzQs5CfRpiEP0xa1HBdnFZ82kvqdmbwVBUr2r1QuQ4t1pi+D1ZpqpcO4T+wy/7RxzJ/WPQ==", "license": "MIT", "dependencies": { "autoprefixer": "^10.4.19", @@ -11976,8 +9663,6 @@ }, "node_modules/cssnano-preset-default": { "version": "6.1.2", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz", - "integrity": "sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==", "license": "MIT", "dependencies": { "browserslist": "^4.23.0", @@ -12020,8 +9705,6 @@ }, "node_modules/cssnano-utils": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-4.0.2.tgz", - "integrity": "sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==", "license": "MIT", "engines": { "node": "^14 || ^16 || >=18.0" @@ -12032,8 +9715,6 @@ }, "node_modules/csso": { "version": "5.0.5", - "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", - "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", "license": "MIT", "dependencies": { "css-tree": "~2.2.0" @@ -12045,8 +9726,6 @@ }, "node_modules/csso/node_modules/css-tree": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", - "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", "license": "MIT", "dependencies": { "mdn-data": "2.0.28", @@ -12059,30 +9738,21 @@ }, "node_modules/csso/node_modules/mdn-data": { "version": "2.0.28", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", "license": "CC0-1.0" }, "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==", "license": "MIT" }, "node_modules/cytoscape": { "version": "3.33.1", - "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.33.1.tgz", - "integrity": "sha512-iJc4TwyANnOGR1OmWhsS9ayRS3s+XQ185FmuHObThD+5AeJCakAAbWv8KimMTt08xCCLNgneQwFp+JRJOr9qGQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10" } }, "node_modules/cytoscape-cose-bilkent": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz", - "integrity": "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==", "license": "MIT", "dependencies": { "cose-base": "^1.0.0" @@ -12093,8 +9763,6 @@ }, "node_modules/cytoscape-fcose": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz", - "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==", "license": "MIT", "dependencies": { "cose-base": "^2.2.0" @@ -12105,8 +9773,6 @@ }, "node_modules/cytoscape-fcose/node_modules/cose-base": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz", - "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==", "license": "MIT", "dependencies": { "layout-base": "^2.0.0" @@ -12114,14 +9780,10 @@ }, "node_modules/cytoscape-fcose/node_modules/layout-base": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz", - "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==", "license": "MIT" }, "node_modules/d3": { "version": "7.9.0", - "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", - "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", "license": "ISC", "dependencies": { "d3-array": "3", @@ -12161,8 +9823,6 @@ }, "node_modules/d3-array": { "version": "3.2.4", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", - "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", "license": "ISC", "dependencies": { "internmap": "1 - 2" @@ -12173,8 +9833,6 @@ }, "node_modules/d3-axis": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", - "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", "license": "ISC", "engines": { "node": ">=12" @@ -12182,8 +9840,6 @@ }, "node_modules/d3-brush": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", - "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", "license": "ISC", "dependencies": { "d3-dispatch": "1 - 3", @@ -12198,8 +9854,6 @@ }, "node_modules/d3-chord": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", - "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", "license": "ISC", "dependencies": { "d3-path": "1 - 3" @@ -12210,8 +9864,6 @@ }, "node_modules/d3-color": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", - "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", "license": "ISC", "engines": { "node": ">=12" @@ -12219,8 +9871,6 @@ }, "node_modules/d3-contour": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", - "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", "license": "ISC", "dependencies": { "d3-array": "^3.2.0" @@ -12231,8 +9881,6 @@ }, "node_modules/d3-delaunay": { "version": "6.0.4", - "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", - "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", "license": "ISC", "dependencies": { "delaunator": "5" @@ -12243,8 +9891,6 @@ }, "node_modules/d3-dispatch": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", - "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", "license": "ISC", "engines": { "node": ">=12" @@ -12252,8 +9898,6 @@ }, "node_modules/d3-drag": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", - "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", "license": "ISC", "dependencies": { "d3-dispatch": "1 - 3", @@ -12265,8 +9909,6 @@ }, "node_modules/d3-dsv": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", - "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", "license": "ISC", "dependencies": { "commander": "7", @@ -12290,8 +9932,6 @@ }, "node_modules/d3-dsv/node_modules/commander": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "license": "MIT", "engines": { "node": ">= 10" @@ -12299,8 +9939,6 @@ }, "node_modules/d3-ease": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", - "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", "license": "BSD-3-Clause", "engines": { "node": ">=12" @@ -12308,8 +9946,6 @@ }, "node_modules/d3-fetch": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", - "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", "license": "ISC", "dependencies": { "d3-dsv": "1 - 3" @@ -12320,8 +9956,6 @@ }, "node_modules/d3-force": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", - "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", "license": "ISC", "dependencies": { "d3-dispatch": "1 - 3", @@ -12334,8 +9968,6 @@ }, "node_modules/d3-format": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", - "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", "license": "ISC", "engines": { "node": ">=12" @@ -12343,8 +9975,6 @@ }, "node_modules/d3-geo": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", - "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", "license": "ISC", "dependencies": { "d3-array": "2.5.0 - 3" @@ -12355,8 +9985,6 @@ }, "node_modules/d3-hierarchy": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", - "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", "license": "ISC", "engines": { "node": ">=12" @@ -12364,8 +9992,6 @@ }, "node_modules/d3-interpolate": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", - "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", "license": "ISC", "dependencies": { "d3-color": "1 - 3" @@ -12376,8 +10002,6 @@ }, "node_modules/d3-path": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", - "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", "license": "ISC", "engines": { "node": ">=12" @@ -12385,8 +10009,6 @@ }, "node_modules/d3-polygon": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", - "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", "license": "ISC", "engines": { "node": ">=12" @@ -12394,8 +10016,6 @@ }, "node_modules/d3-quadtree": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", - "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", "license": "ISC", "engines": { "node": ">=12" @@ -12403,8 +10023,6 @@ }, "node_modules/d3-random": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", - "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", "license": "ISC", "engines": { "node": ">=12" @@ -12412,8 +10030,6 @@ }, "node_modules/d3-sankey": { "version": "0.12.3", - "resolved": "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz", - "integrity": "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==", "license": "BSD-3-Clause", "dependencies": { "d3-array": "1 - 2", @@ -12422,8 +10038,6 @@ }, "node_modules/d3-sankey/node_modules/d3-array": { "version": "2.12.1", - "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz", - "integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==", "license": "BSD-3-Clause", "dependencies": { "internmap": "^1.0.0" @@ -12431,14 +10045,10 @@ }, "node_modules/d3-sankey/node_modules/d3-path": { "version": "1.0.9", - "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz", - "integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==", "license": "BSD-3-Clause" }, "node_modules/d3-sankey/node_modules/d3-shape": { "version": "1.3.7", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz", - "integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==", "license": "BSD-3-Clause", "dependencies": { "d3-path": "1" @@ -12446,14 +10056,10 @@ }, "node_modules/d3-sankey/node_modules/internmap": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz", - "integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==", "license": "ISC" }, "node_modules/d3-scale": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", - "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", "license": "ISC", "dependencies": { "d3-array": "2.10.0 - 3", @@ -12468,8 +10074,6 @@ }, "node_modules/d3-scale-chromatic": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", - "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", "license": "ISC", "dependencies": { "d3-color": "1 - 3", @@ -12481,18 +10085,13 @@ }, "node_modules/d3-selection": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", - "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", "license": "ISC", - "peer": true, "engines": { "node": ">=12" } }, "node_modules/d3-shape": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", - "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", "license": "ISC", "dependencies": { "d3-path": "^3.1.0" @@ -12503,8 +10102,6 @@ }, "node_modules/d3-time": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", - "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", "license": "ISC", "dependencies": { "d3-array": "2 - 3" @@ -12515,8 +10112,6 @@ }, "node_modules/d3-time-format": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", - "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", "license": "ISC", "dependencies": { "d3-time": "1 - 3" @@ -12527,8 +10122,6 @@ }, "node_modules/d3-timer": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", - "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", "license": "ISC", "engines": { "node": ">=12" @@ -12536,8 +10129,6 @@ }, "node_modules/d3-transition": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", - "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", "license": "ISC", "dependencies": { "d3-color": "1 - 3", @@ -12555,8 +10146,6 @@ }, "node_modules/d3-zoom": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", - "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", "license": "ISC", "dependencies": { "d3-dispatch": "1 - 3", @@ -12571,8 +10160,6 @@ }, "node_modules/dagre-d3-es": { "version": "7.0.13", - "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.13.tgz", - "integrity": "sha512-efEhnxpSuwpYOKRm/L5KbqoZmNNukHa/Flty4Wp62JRvgH2ojwVgPgdYyr4twpieZnyRDdIH7PY2mopX26+j2Q==", "license": "MIT", "dependencies": { "d3": "^7.9.0", @@ -12581,14 +10168,10 @@ }, "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==", "license": "BSD-2-Clause" }, "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==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -12604,8 +10187,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -12621,8 +10202,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -12638,20 +10217,14 @@ }, "node_modules/dayjs": { "version": "1.11.19", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz", - "integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==", "license": "MIT" }, "node_modules/debounce": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", - "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==", "license": "MIT" }, "node_modules/debug": { "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -12667,19 +10240,13 @@ }, "node_modules/decimal.js-light": { "version": "2.5.1", - "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", - "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==", "license": "MIT" }, "node_modules/decko": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decko/-/decko-1.2.0.tgz", - "integrity": "sha512-m8FnyHXV1QX+S1cl+KPFDIl6NMkxtKsy6+U/aYyjrOqWMuwAwYWu7ePqrsUHtDR5Y8Yk2pi/KIDSgF+vT4cPOQ==" + "version": "1.2.0" }, "node_modules/decode-named-character-reference": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz", - "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==", "license": "MIT", "dependencies": { "character-entities": "^2.0.0" @@ -12691,8 +10258,6 @@ }, "node_modules/decompress-response": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "license": "MIT", "dependencies": { "mimic-response": "^3.1.0" @@ -12706,8 +10271,6 @@ }, "node_modules/decompress-response/node_modules/mimic-response": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", "license": "MIT", "engines": { "node": ">=10" @@ -12717,9 +10280,7 @@ } }, "node_modules/dedent": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.1.tgz", - "integrity": "sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg==", + "version": "1.7.0", "dev": true, "license": "MIT", "peerDependencies": { @@ -12733,8 +10294,6 @@ }, "node_modules/deep-extend": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "license": "MIT", "engines": { "node": ">=4.0.0" @@ -12742,14 +10301,10 @@ }, "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==", "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==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -12757,8 +10312,6 @@ }, "node_modules/default-browser": { "version": "5.4.0", - "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.4.0.tgz", - "integrity": "sha512-XDuvSq38Hr1MdN47EDvYtx3U0MTqpCEn+F6ft8z2vYDzMrvQhVp0ui9oQdqW3MvK3vqUETglt1tVGgjLuJ5izg==", "license": "MIT", "dependencies": { "bundle-name": "^4.1.0", @@ -12773,8 +10326,6 @@ }, "node_modules/default-browser-id": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz", - "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", "license": "MIT", "engines": { "node": ">=18" @@ -12785,8 +10336,6 @@ }, "node_modules/defer-to-connect": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", "license": "MIT", "engines": { "node": ">=10" @@ -12794,8 +10343,6 @@ }, "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==", "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", @@ -12811,8 +10358,6 @@ }, "node_modules/define-lazy-prop": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", "license": "MIT", "engines": { "node": ">=8" @@ -12820,8 +10365,6 @@ }, "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==", "license": "MIT", "dependencies": { "define-data-property": "^1.0.1", @@ -12837,15 +10380,11 @@ }, "node_modules/defu": { "version": "6.1.4", - "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz", - "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==", "dev": true, "license": "MIT" }, "node_modules/delaunator": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", - "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", "license": "ISC", "dependencies": { "robust-predicates": "^3.0.2" @@ -12853,8 +10392,6 @@ }, "node_modules/depd": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -12862,8 +10399,6 @@ }, "node_modules/dequal": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "license": "MIT", "engines": { "node": ">=6" @@ -12871,15 +10406,11 @@ }, "node_modules/destr": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", - "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", "dev": true, "license": "MIT" }, "node_modules/destroy": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "license": "MIT", "engines": { "node": ">= 0.8", @@ -12888,8 +10419,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==", "license": "Apache-2.0", "engines": { "node": ">=8" @@ -12897,8 +10426,6 @@ }, "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": { @@ -12907,20 +10434,14 @@ }, "node_modules/detect-node": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", "license": "MIT" }, "node_modules/detect-node-es": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", - "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", "license": "MIT" }, "node_modules/detect-port": { "version": "1.6.1", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.6.1.tgz", - "integrity": "sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==", "license": "MIT", "dependencies": { "address": "^1.0.1", @@ -12936,8 +10457,6 @@ }, "node_modules/devlop": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", "license": "MIT", "dependencies": { "dequal": "^2.0.0" @@ -12949,8 +10468,6 @@ }, "node_modules/diff-sequences": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, "license": "MIT", "engines": { @@ -12959,8 +10476,6 @@ }, "node_modules/dir-glob": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "license": "MIT", "dependencies": { "path-type": "^4.0.0" @@ -12971,8 +10486,6 @@ }, "node_modules/dns-packet": { "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", "license": "MIT", "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" @@ -12983,8 +10496,6 @@ }, "node_modules/doctrine": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" @@ -12995,8 +10506,6 @@ }, "node_modules/docusaurus-plugin-redoc": { "version": "2.5.0", - "resolved": "https://registry.npmjs.org/docusaurus-plugin-redoc/-/docusaurus-plugin-redoc-2.5.0.tgz", - "integrity": "sha512-44sDhuXvItHnUuPdKswF3cRhiN5UW3YZxmMBsQLSfCYKcYr9tgWF2qvDfQoZO9i1DwpaYbIZ/RKMrSgny/iWYA==", "license": "MIT", "dependencies": { "@redocly/openapi-core": "1.16.0", @@ -13009,10 +10518,33 @@ "@docusaurus/utils": "^3.6.0" } }, + "node_modules/docusaurus-plugin-redoc/node_modules/@redocly/config": { + "version": "0.6.3", + "license": "MIT" + }, + "node_modules/docusaurus-plugin-redoc/node_modules/@redocly/openapi-core": { + "version": "1.16.0", + "license": "MIT", + "dependencies": { + "@redocly/ajv": "^8.11.0", + "@redocly/config": "^0.6.0", + "colorette": "^1.2.0", + "https-proxy-agent": "^7.0.4", + "js-levenshtein": "^1.1.6", + "js-yaml": "^4.1.0", + "lodash.isequal": "^4.5.0", + "minimatch": "^5.0.1", + "node-fetch": "^2.6.1", + "pluralize": "^8.0.0", + "yaml-ast-parser": "0.0.43" + }, + "engines": { + "node": ">=14.19.0", + "npm": ">=7.0.0" + } + }, "node_modules/docusaurus-theme-redoc": { "version": "2.5.0", - "resolved": "https://registry.npmjs.org/docusaurus-theme-redoc/-/docusaurus-theme-redoc-2.5.0.tgz", - "integrity": "sha512-ykLmnnvE20Im3eABlIpUnXnT2gSHVAjgyy2fU2G8yecu7zqIE+G/SiBpBg/hrWMUycL31a8VSG7Ehkf3pg1u+A==", "license": "MIT", "dependencies": { "@redocly/openapi-core": "1.16.0", @@ -13032,10 +10564,33 @@ "webpack": "^5.0.0" } }, + "node_modules/docusaurus-theme-redoc/node_modules/@redocly/config": { + "version": "0.6.3", + "license": "MIT" + }, + "node_modules/docusaurus-theme-redoc/node_modules/@redocly/openapi-core": { + "version": "1.16.0", + "license": "MIT", + "dependencies": { + "@redocly/ajv": "^8.11.0", + "@redocly/config": "^0.6.0", + "colorette": "^1.2.0", + "https-proxy-agent": "^7.0.4", + "js-levenshtein": "^1.1.6", + "js-yaml": "^4.1.0", + "lodash.isequal": "^4.5.0", + "minimatch": "^5.0.1", + "node-fetch": "^2.6.1", + "pluralize": "^8.0.0", + "yaml-ast-parser": "0.0.43" + }, + "engines": { + "node": ">=14.19.0", + "npm": ">=7.0.0" + } + }, "node_modules/docusaurus-theme-redoc/node_modules/clsx": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", - "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", "license": "MIT", "engines": { "node": ">=6" @@ -13043,8 +10598,6 @@ }, "node_modules/dom-converter": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", "license": "MIT", "dependencies": { "utila": "~0.4" @@ -13052,8 +10605,6 @@ }, "node_modules/dom-serializer": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", @@ -13066,8 +10617,6 @@ }, "node_modules/domelementtype": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", "funding": [ { "type": "github", @@ -13078,8 +10627,6 @@ }, "node_modules/domhandler": { "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.3.0" @@ -13092,9 +10639,7 @@ } }, "node_modules/dompurify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.3.1.tgz", - "integrity": "sha512-qkdCKzLNtrgPFP1Vo+98FRzJnBRGe4ffyCea9IwHB1fyxPOeNTHpLKYGd4Uk9xvNoH0ZoOjwZxNptyMwqrId1Q==", + "version": "3.3.0", "license": "(MPL-2.0 OR Apache-2.0)", "optionalDependencies": { "@types/trusted-types": "^2.0.7" @@ -13102,8 +10647,6 @@ }, "node_modules/domutils": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", - "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^2.0.0", @@ -13116,8 +10659,6 @@ }, "node_modules/dot-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", "license": "MIT", "dependencies": { "no-case": "^3.0.4", @@ -13126,8 +10667,6 @@ }, "node_modules/dot-prop": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", - "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", "license": "MIT", "dependencies": { "is-obj": "^2.0.0" @@ -13141,8 +10680,6 @@ }, "node_modules/dot-prop/node_modules/is-obj": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", "license": "MIT", "engines": { "node": ">=8" @@ -13150,8 +10687,6 @@ }, "node_modules/dotenv": { "version": "17.2.3", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz", - "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -13163,8 +10698,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -13177,32 +10710,22 @@ }, "node_modules/duplexer": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "license": "MIT" }, "node_modules/eastasianwidth": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "license": "MIT" }, "node_modules/ee-first": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.267", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", - "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", + "version": "1.5.265", "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": { @@ -13214,20 +10737,14 @@ }, "node_modules/emoji-regex": { "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "license": "MIT" }, "node_modules/emojilib": { "version": "2.4.0", - "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", - "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==", "license": "MIT" }, "node_modules/emojis-list": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", "license": "MIT", "engines": { "node": ">= 4" @@ -13235,8 +10752,6 @@ }, "node_modules/emoticon": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-4.1.0.tgz", - "integrity": "sha512-VWZfnxqwNcc51hIy/sbOdEem6D+cVtpPzEEtVAFdaas30+1dgkyaOQ4sQ6Bp0tOMqWO1v+HQfYaoodOkdhK6SQ==", "license": "MIT", "funding": { "type": "github", @@ -13245,17 +10760,24 @@ }, "node_modules/encodeurl": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "license": "MIT", "engines": { "node": ">= 0.8" } }, + "node_modules/encoding-sniffer": { + "version": "0.2.1", + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, "node_modules/enhanced-resolve": { - "version": "5.18.4", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz", - "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==", + "version": "5.18.3", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", @@ -13267,8 +10789,6 @@ }, "node_modules/entities": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -13279,17 +10799,13 @@ }, "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==", "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==", + "version": "1.24.0", "license": "MIT", "dependencies": { "array-buffer-byte-length": "^1.0.2", @@ -13356,8 +10872,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -13365,34 +10879,30 @@ }, "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==", "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/es-iterator-helpers": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.2.tgz", - "integrity": "sha512-BrUQ0cPTB/IwXj23HtwHjS9n7O4h9FX94b4xc5zlTHxeLgTAdzYUDyy6KdExAl9lbN5rtfe44xpjpmj9grxs5w==", + "version": "1.2.1", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", - "call-bound": "^1.0.4", + "call-bound": "^1.0.3", "define-properties": "^1.2.1", - "es-abstract": "^1.24.1", + "es-abstract": "^1.23.6", "es-errors": "^1.3.0", - "es-set-tostringtag": "^2.1.0", + "es-set-tostringtag": "^2.0.3", "function-bind": "^1.1.2", - "get-intrinsic": "^1.3.0", + "get-intrinsic": "^1.2.6", "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", + "iterator.prototype": "^1.1.4", "safe-array-concat": "^1.1.3" }, "engines": { @@ -13400,15 +10910,11 @@ } }, "node_modules/es-module-lexer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", - "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", + "version": "1.7.0", "license": "MIT" }, "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==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -13419,8 +10925,6 @@ }, "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==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -13434,8 +10938,6 @@ }, "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==", "license": "MIT", "dependencies": { "hasown": "^2.0.2" @@ -13446,8 +10948,6 @@ }, "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==", "license": "MIT", "dependencies": { "is-callable": "^1.2.7", @@ -13462,9 +10962,7 @@ } }, "node_modules/es-toolkit": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.43.0.tgz", - "integrity": "sha512-SKCT8AsWvYzBBuUqMk4NPwFlSdqLpJwmy6AP322ERn8W2YLIB6JBXnwMI2Qsh2gfphT3q7EKAxKb23cvFHFwKA==", + "version": "1.42.0", "license": "MIT", "workspaces": [ "docs", @@ -13473,14 +10971,10 @@ }, "node_modules/es6-promise": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz", - "integrity": "sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==", "license": "MIT" }, "node_modules/esast-util-from-estree": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz", - "integrity": "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==", "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", @@ -13495,8 +10989,6 @@ }, "node_modules/esast-util-from-js": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz", - "integrity": "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==", "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", @@ -13511,8 +11003,6 @@ }, "node_modules/escalade": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "license": "MIT", "engines": { "node": ">=6" @@ -13520,8 +11010,6 @@ }, "node_modules/escape-goat": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz", - "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==", "license": "MIT", "engines": { "node": ">=12" @@ -13532,14 +11020,10 @@ }, "node_modules/escape-html": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "license": "MIT" }, "node_modules/escape-string-regexp": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "license": "MIT", "engines": { "node": ">=10" @@ -13549,11 +11033,8 @@ } }, "node_modules/eslint": { - "version": "9.39.2", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", - "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", + "version": "9.39.1", "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -13561,7 +11042,7 @@ "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.39.2", + "@eslint/js": "9.39.1", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", @@ -13609,12 +11090,10 @@ } }, "node_modules/eslint-config-next": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.1.0.tgz", - "integrity": "sha512-RlPb8E2uO/Ix/w3kizxz6+6ogw99WqtNzTG0ArRZ5NEkIYcsfRb8U0j7aTG7NjRvcrsak5QtUSuxGNN2UcA58g==", + "version": "16.0.7", "license": "MIT", "dependencies": { - "@next/eslint-plugin-next": "16.1.0", + "@next/eslint-plugin-next": "16.0.7", "eslint-import-resolver-node": "^0.3.6", "eslint-import-resolver-typescript": "^3.5.2", "eslint-plugin-import": "^2.32.0", @@ -13636,8 +11115,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">=18" @@ -13648,8 +11125,6 @@ }, "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==", "license": "MIT", "dependencies": { "debug": "^3.2.7", @@ -13659,8 +11134,6 @@ }, "node_modules/eslint-import-resolver-node/node_modules/debug": { "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "license": "MIT", "dependencies": { "ms": "^2.1.1" @@ -13668,8 +11141,6 @@ }, "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==", "license": "ISC", "dependencies": { "@nolyfill/is-core-module": "1.0.39", @@ -13702,8 +11173,6 @@ }, "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==", "license": "MIT", "dependencies": { "debug": "^3.2.7" @@ -13719,8 +11188,6 @@ }, "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==", "license": "MIT", "dependencies": { "ms": "^2.1.1" @@ -13728,8 +11195,6 @@ }, "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==", "license": "MIT", "dependencies": { "@rtsao/scc": "^1.1.0", @@ -13759,19 +11224,33 @@ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.12", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "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==", "license": "MIT", "dependencies": { "ms": "^2.1.1" } }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/eslint-plugin-import/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -13779,8 +11258,6 @@ }, "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==", "license": "MIT", "dependencies": { "aria-query": "^5.3.2", @@ -13806,10 +11283,26 @@ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" } }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": { + "version": "1.1.12", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/minimatch": { + "version": "3.1.2", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "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==", "license": "MIT", "dependencies": { "array-includes": "^3.1.8", @@ -13840,8 +11333,6 @@ }, "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==", "license": "MIT", "dependencies": { "@babel/core": "^7.24.4", @@ -13857,10 +11348,26 @@ "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/brace-expansion": { + "version": "1.1.12", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-react/node_modules/minimatch": { + "version": "3.1.2", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/eslint-plugin-react/node_modules/resolve": { "version": "2.0.0-next.5", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", - "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", @@ -13876,8 +11383,6 @@ }, "node_modules/eslint-plugin-react/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -13885,8 +11390,6 @@ }, "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==", "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", @@ -13901,8 +11404,6 @@ }, "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==", "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -13911,10 +11412,16 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.12", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "node_modules/eslint/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==", "license": "ISC", "dependencies": { "is-glob": "^4.0.3" @@ -13923,10 +11430,18 @@ "node": ">=10.13.0" } }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/espree": { "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.15.0", @@ -13942,8 +11457,6 @@ }, "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==", "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", @@ -13955,8 +11468,6 @@ }, "node_modules/esquery": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" @@ -13967,8 +11478,6 @@ }, "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==", "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" @@ -13979,8 +11488,6 @@ }, "node_modules/estraverse": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "license": "BSD-2-Clause", "engines": { "node": ">=4.0" @@ -13988,8 +11495,6 @@ }, "node_modules/estree-util-attach-comments": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", - "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", "license": "MIT", "dependencies": { "@types/estree": "^1.0.0" @@ -14001,8 +11506,6 @@ }, "node_modules/estree-util-build-jsx": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", - "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", @@ -14017,8 +11520,6 @@ }, "node_modules/estree-util-is-identifier-name": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", - "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", "license": "MIT", "funding": { "type": "opencollective", @@ -14027,8 +11528,6 @@ }, "node_modules/estree-util-scope": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/estree-util-scope/-/estree-util-scope-1.0.0.tgz", - "integrity": "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==", "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", @@ -14041,8 +11540,6 @@ }, "node_modules/estree-util-to-js": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", - "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", @@ -14056,8 +11553,6 @@ }, "node_modules/estree-util-value-to-estree": { "version": "3.5.0", - "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.5.0.tgz", - "integrity": "sha512-aMV56R27Gv3QmfmF1MY12GWkGzzeAezAX+UplqHVASfjc9wNzI/X6hC0S9oxq61WT4aQesLGslWP9tKk6ghRZQ==", "license": "MIT", "dependencies": { "@types/estree": "^1.0.0" @@ -14068,8 +11563,6 @@ }, "node_modules/estree-util-visit": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", - "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", @@ -14082,8 +11575,6 @@ }, "node_modules/estree-walker": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "license": "MIT", "dependencies": { "@types/estree": "^1.0.0" @@ -14091,8 +11582,6 @@ }, "node_modules/esutils": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" @@ -14100,8 +11589,6 @@ }, "node_modules/eta": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/eta/-/eta-2.2.0.tgz", - "integrity": "sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==", "license": "MIT", "engines": { "node": ">=6.0.0" @@ -14112,8 +11599,6 @@ }, "node_modules/etag": { "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -14121,8 +11606,6 @@ }, "node_modules/eval": { "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz", - "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==", "dependencies": { "@types/node": "*", "require-like": ">= 0.1.1" @@ -14133,14 +11616,10 @@ }, "node_modules/eventemitter3": { "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "license": "MIT" }, "node_modules/events": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "license": "MIT", "engines": { "node": ">=0.8.x" @@ -14148,8 +11627,6 @@ }, "node_modules/eventsource-parser": { "version": "3.0.6", - "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", - "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", "license": "MIT", "engines": { "node": ">=18.0.0" @@ -14157,8 +11634,6 @@ }, "node_modules/execa": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", @@ -14180,8 +11655,6 @@ }, "node_modules/exit": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "dev": true, "engines": { "node": ">= 0.8.0" @@ -14189,8 +11662,6 @@ }, "node_modules/expect": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", "dev": true, "license": "MIT", "dependencies": { @@ -14206,8 +11677,6 @@ }, "node_modules/express": { "version": "4.22.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", - "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", "license": "MIT", "dependencies": { "accepts": "~1.3.8", @@ -14252,8 +11721,6 @@ }, "node_modules/express/node_modules/content-disposition": { "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" @@ -14264,8 +11731,6 @@ }, "node_modules/express/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -14273,20 +11738,14 @@ }, "node_modules/express/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/express/node_modules/path-to-regexp": { "version": "0.1.12", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", "license": "MIT" }, "node_modules/express/node_modules/range-parser": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -14294,21 +11753,15 @@ }, "node_modules/exsolve": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz", - "integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==", "dev": true, "license": "MIT" }, "node_modules/extend": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "license": "MIT" }, "node_modules/extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", "license": "MIT", "dependencies": { "is-extendable": "^0.1.0" @@ -14319,14 +11772,10 @@ }, "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==", "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -14341,26 +11790,18 @@ }, "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==", "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==", "license": "MIT" }, "node_modules/fast-safe-stringify": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", "license": "MIT" }, "node_modules/fast-uri": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", "funding": [ { "type": "github", @@ -14375,8 +11816,6 @@ }, "node_modules/fast-xml-parser": { "version": "4.5.3", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.3.tgz", - "integrity": "sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==", "funding": [ { "type": "github", @@ -14393,8 +11832,6 @@ }, "node_modules/fastq": { "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -14402,8 +11839,6 @@ }, "node_modules/fault": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", - "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", "license": "MIT", "dependencies": { "format": "^0.2.0" @@ -14415,8 +11850,6 @@ }, "node_modules/faye-websocket": { "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", "license": "Apache-2.0", "dependencies": { "websocket-driver": ">=0.5.1" @@ -14427,8 +11860,6 @@ }, "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": { @@ -14437,8 +11868,6 @@ }, "node_modules/feed": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", - "integrity": "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==", "license": "MIT", "dependencies": { "xml-js": "^1.6.11" @@ -14449,8 +11878,6 @@ }, "node_modules/figures": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "license": "MIT", "dependencies": { "escape-string-regexp": "^1.0.5" @@ -14464,8 +11891,6 @@ }, "node_modules/figures/node_modules/escape-string-regexp": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "license": "MIT", "engines": { "node": ">=0.8.0" @@ -14473,8 +11898,6 @@ }, "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==", "license": "MIT", "dependencies": { "flat-cache": "^4.0.0" @@ -14485,8 +11908,6 @@ }, "node_modules/file-loader": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", - "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", "license": "MIT", "dependencies": { "loader-utils": "^2.0.0", @@ -14505,8 +11926,6 @@ }, "node_modules/file-loader/node_modules/schema-utils": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.8", @@ -14523,8 +11942,6 @@ }, "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==", "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -14535,8 +11952,6 @@ }, "node_modules/finalhandler": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", - "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", "license": "MIT", "dependencies": { "debug": "2.6.9", @@ -14553,8 +11968,6 @@ }, "node_modules/finalhandler/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -14562,14 +11975,10 @@ }, "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/find-cache-dir": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", - "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", "license": "MIT", "dependencies": { "common-path-prefix": "^3.0.0", @@ -14584,8 +11993,6 @@ }, "node_modules/find-up": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "license": "MIT", "dependencies": { "locate-path": "^6.0.0", @@ -14600,8 +12007,6 @@ }, "node_modules/flat": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "license": "BSD-3-Clause", "bin": { "flat": "cli.js" @@ -14609,8 +12014,6 @@ }, "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==", "license": "MIT", "dependencies": { "flatted": "^3.2.9", @@ -14622,20 +12025,14 @@ }, "node_modules/flatted": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", "license": "ISC" }, "node_modules/focus-visible": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/focus-visible/-/focus-visible-5.2.1.tgz", - "integrity": "sha512-8Bx950VD1bWTQJEH/AM6SpEk+SU55aVnp4Ujhuuxy3eMEBCRwBnTBnVXr9YAPvZL3/CNjCa8u4IWfNmEO53whA==", "license": "W3C" }, "node_modules/follow-redirects": { "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "funding": [ { "type": "individual", @@ -14654,8 +12051,6 @@ }, "node_modules/for-each": { "version": "0.3.5", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", - "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "license": "MIT", "dependencies": { "is-callable": "^1.2.7" @@ -14669,14 +12064,10 @@ }, "node_modules/foreach": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.6.tgz", - "integrity": "sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg==", "license": "MIT" }, "node_modules/form-data-encoder": { "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", - "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", "license": "MIT", "engines": { "node": ">= 14.17" @@ -14684,16 +12075,12 @@ }, "node_modules/format": { "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", "engines": { "node": ">=0.4.x" } }, "node_modules/forwarded": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -14701,8 +12088,6 @@ }, "node_modules/fraction.js": { "version": "5.3.4", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", - "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", "license": "MIT", "engines": { "node": "*" @@ -14714,17 +12099,13 @@ }, "node_modules/fresh": { "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/fs-extra": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.3.tgz", - "integrity": "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==", + "version": "11.3.2", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", @@ -14737,16 +12118,11 @@ }, "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==", - "hasInstallScript": true, "license": "MIT", "optional": true, "os": [ @@ -14758,8 +12134,6 @@ }, "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==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -14767,8 +12141,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -14787,8 +12159,6 @@ }, "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==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -14796,8 +12166,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -14805,8 +12173,6 @@ }, "node_modules/gensync": { "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "license": "MIT", "engines": { "node": ">=6.9.0" @@ -14814,8 +12180,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==", "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" @@ -14823,8 +12187,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -14847,8 +12209,6 @@ }, "node_modules/get-nonce": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", - "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", "license": "MIT", "engines": { "node": ">=6" @@ -14856,14 +12216,10 @@ }, "node_modules/get-own-enumerable-property-symbols": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", "license": "ISC" }, "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": { @@ -14872,8 +12228,6 @@ }, "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==", "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -14885,8 +12239,6 @@ }, "node_modules/get-stream": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "license": "MIT", "engines": { "node": ">=10" @@ -14897,8 +12249,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -14914,8 +12264,6 @@ }, "node_modules/get-tsconfig": { "version": "4.13.0", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", - "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", "license": "MIT", "dependencies": { "resolve-pkg-maps": "^1.0.0" @@ -14926,8 +12274,6 @@ }, "node_modules/giget": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/giget/-/giget-2.0.0.tgz", - "integrity": "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==", "dev": true, "license": "MIT", "dependencies": { @@ -14944,15 +12290,10 @@ }, "node_modules/github-slugger": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", - "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==", "license": "ISC" }, "node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", "dependencies": { @@ -14972,8 +12313,6 @@ }, "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==", "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -14984,8 +12323,6 @@ }, "node_modules/glob-to-regex.js": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/glob-to-regex.js/-/glob-to-regex.js-1.2.0.tgz", - "integrity": "sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==", "license": "Apache-2.0", "engines": { "node": ">=10.0" @@ -15000,14 +12337,30 @@ }, "node_modules/glob-to-regexp": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "license": "BSD-2-Clause" }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.12", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/global-dirs": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", - "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", "license": "MIT", "dependencies": { "ini": "2.0.0" @@ -15021,8 +12374,6 @@ }, "node_modules/globals": { "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "license": "MIT", "engines": { "node": ">=18" @@ -15033,8 +12384,6 @@ }, "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==", "license": "MIT", "dependencies": { "define-properties": "^1.2.1", @@ -15049,8 +12398,6 @@ }, "node_modules/globby": { "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "license": "MIT", "dependencies": { "array-union": "^2.1.0", @@ -15069,8 +12416,6 @@ }, "node_modules/gopd": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -15081,8 +12426,6 @@ }, "node_modules/got": { "version": "12.6.1", - "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", - "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", "license": "MIT", "dependencies": { "@sindresorhus/is": "^5.2.0", @@ -15106,8 +12449,6 @@ }, "node_modules/got/node_modules/@sindresorhus/is": { "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", - "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", "license": "MIT", "engines": { "node": ">=14.16" @@ -15118,14 +12459,10 @@ }, "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==", "license": "ISC" }, "node_modules/gray-matter": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", - "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", "license": "MIT", "dependencies": { "js-yaml": "^3.13.1", @@ -15139,8 +12476,6 @@ }, "node_modules/gray-matter/node_modules/argparse": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" @@ -15148,8 +12483,6 @@ }, "node_modules/gray-matter/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==", "license": "MIT", "dependencies": { "argparse": "^1.0.7", @@ -15161,8 +12494,6 @@ }, "node_modules/gzip-size": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", "license": "MIT", "dependencies": { "duplexer": "^0.1.2" @@ -15176,20 +12507,14 @@ }, "node_modules/hachure-fill": { "version": "0.5.2", - "resolved": "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz", - "integrity": "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==", "license": "MIT" }, "node_modules/handle-thing": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", "license": "MIT" }, "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": { @@ -15210,8 +12535,6 @@ }, "node_modules/handlebars/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": { @@ -15220,8 +12543,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -15232,8 +12553,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">=8" @@ -15241,8 +12560,6 @@ }, "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==", "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" @@ -15253,8 +12570,6 @@ }, "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==", "license": "MIT", "dependencies": { "dunder-proto": "^1.0.0" @@ -15268,8 +12583,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -15280,8 +12593,6 @@ }, "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==", "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -15295,8 +12606,6 @@ }, "node_modules/has-yarn": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", - "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==", "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" @@ -15307,8 +12616,6 @@ }, "node_modules/hasown": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -15319,8 +12626,6 @@ }, "node_modules/hast-util-from-parse5": { "version": "8.0.3", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", - "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -15339,8 +12644,6 @@ }, "node_modules/hast-util-parse-selector": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", - "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0" @@ -15352,8 +12655,6 @@ }, "node_modules/hast-util-raw": { "version": "9.1.0", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", - "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -15377,8 +12678,6 @@ }, "node_modules/hast-util-to-estree": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.3.tgz", - "integrity": "sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==", "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", @@ -15405,8 +12704,6 @@ }, "node_modules/hast-util-to-jsx-runtime": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", - "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", @@ -15432,8 +12729,6 @@ }, "node_modules/hast-util-to-parse5": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.1.tgz", - "integrity": "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -15451,8 +12746,6 @@ }, "node_modules/hast-util-whitespace": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0" @@ -15464,8 +12757,6 @@ }, "node_modules/hastscript": { "version": "9.0.1", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", - "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -15481,8 +12772,6 @@ }, "node_modules/he": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "license": "MIT", "bin": { "he": "bin/he" @@ -15490,14 +12779,10 @@ }, "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==", "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==", "license": "MIT", "dependencies": { "hermes-estree": "0.25.1" @@ -15509,8 +12794,6 @@ }, "node_modules/history": { "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.1.2", @@ -15523,8 +12806,6 @@ }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", "license": "BSD-3-Clause", "dependencies": { "react-is": "^16.7.0" @@ -15532,14 +12813,10 @@ }, "node_modules/hoist-non-react-statics/node_modules/react-is": { "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "license": "MIT" }, "node_modules/hpack.js": { "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", "license": "MIT", "dependencies": { "inherits": "^2.0.1", @@ -15550,14 +12827,10 @@ }, "node_modules/hpack.js/node_modules/isarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "license": "MIT" }, "node_modules/hpack.js/node_modules/readable-stream": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", @@ -15571,14 +12844,10 @@ }, "node_modules/hpack.js/node_modules/safe-buffer": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "license": "MIT" }, "node_modules/hpack.js/node_modules/string_decoder": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" @@ -15586,14 +12855,10 @@ }, "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==", "license": "MIT" }, "node_modules/html-minifier-terser": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", - "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", "license": "MIT", "dependencies": { "camel-case": "^4.1.2", @@ -15613,8 +12878,6 @@ }, "node_modules/html-minifier-terser/node_modules/commander": { "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", "license": "MIT", "engines": { "node": ">=14" @@ -15622,8 +12885,6 @@ }, "node_modules/html-tags": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", - "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", "license": "MIT", "engines": { "node": ">=8" @@ -15634,8 +12895,6 @@ }, "node_modules/html-void-elements": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", - "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", "license": "MIT", "funding": { "type": "github", @@ -15644,8 +12903,6 @@ }, "node_modules/html-webpack-plugin": { "version": "5.6.5", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.5.tgz", - "integrity": "sha512-4xynFbKNNk+WlzXeQQ+6YYsH2g7mpfPszQZUi3ovKlj+pDmngQ7vRXjrrmGROabmKwyQkcgcX5hqfOwHbFmK5g==", "license": "MIT", "dependencies": { "@types/html-minifier-terser": "^6.0.0", @@ -15676,8 +12933,6 @@ }, "node_modules/html-webpack-plugin/node_modules/commander": { "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", "license": "MIT", "engines": { "node": ">= 12" @@ -15685,8 +12940,6 @@ }, "node_modules/html-webpack-plugin/node_modules/html-minifier-terser": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", "license": "MIT", "dependencies": { "camel-case": "^4.1.2", @@ -15706,8 +12959,6 @@ }, "node_modules/htmlparser2": { "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { @@ -15725,20 +12976,14 @@ }, "node_modules/http-cache-semantics": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", - "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", "license": "BSD-2-Clause" }, "node_modules/http-deceiver": { "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", "license": "MIT" }, "node_modules/http-errors": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", "license": "MIT", "dependencies": { "depd": "~2.0.0", @@ -15757,14 +13002,10 @@ }, "node_modules/http-parser-js": { "version": "0.5.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", - "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", "license": "MIT" }, "node_modules/http-proxy": { "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", "license": "MIT", "dependencies": { "eventemitter3": "^4.0.0", @@ -15777,8 +13018,6 @@ }, "node_modules/http-proxy-middleware": { "version": "2.0.9", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz", - "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==", "license": "MIT", "dependencies": { "@types/http-proxy": "^1.17.8", @@ -15801,8 +13040,6 @@ }, "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", "license": "MIT", "engines": { "node": ">=10" @@ -15813,14 +13050,10 @@ }, "node_modules/http2-client": { "version": "1.3.5", - "resolved": "https://registry.npmjs.org/http2-client/-/http2-client-1.3.5.tgz", - "integrity": "sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA==", "license": "MIT" }, "node_modules/http2-wrapper": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", - "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", "license": "MIT", "dependencies": { "quick-lru": "^5.1.1", @@ -15832,8 +13065,6 @@ }, "node_modules/https-proxy-agent": { "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "license": "MIT", "dependencies": { "agent-base": "^7.1.2", @@ -15845,8 +13076,6 @@ }, "node_modules/human-signals": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "license": "Apache-2.0", "engines": { "node": ">=10.17.0" @@ -15854,8 +13083,6 @@ }, "node_modules/hyperdyperid": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", - "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", "license": "MIT", "engines": { "node": ">=10.18" @@ -15863,8 +13090,6 @@ }, "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==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -15875,8 +13100,6 @@ }, "node_modules/icss-utils": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", "license": "ISC", "engines": { "node": "^10 || ^12 || >= 14" @@ -15887,8 +13110,6 @@ }, "node_modules/ignore": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "license": "MIT", "engines": { "node": ">= 4" @@ -15896,8 +13117,6 @@ }, "node_modules/image-size": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-2.0.2.tgz", - "integrity": "sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==", "license": "MIT", "bin": { "image-size": "bin/image-size.js" @@ -15906,20 +13125,26 @@ "node": ">=16.x" } }, + "node_modules/immediate": { + "version": "3.3.0", + "license": "MIT" + }, "node_modules/immer": { "version": "10.2.0", - "resolved": "https://registry.npmjs.org/immer/-/immer-10.2.0.tgz", - "integrity": "sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==", "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/immer" } }, + "node_modules/immutable": { + "version": "5.1.4", + "license": "MIT", + "optional": true, + "peer": true + }, "node_modules/import-fresh": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "license": "MIT", "dependencies": { "parent-module": "^1.0.0", @@ -15934,8 +13159,6 @@ }, "node_modules/import-lazy": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", - "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", "license": "MIT", "engines": { "node": ">=8" @@ -15943,8 +13166,6 @@ }, "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": { @@ -15963,8 +13184,6 @@ }, "node_modules/import-local/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": { @@ -15977,8 +13196,6 @@ }, "node_modules/import-local/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": { @@ -15990,8 +13207,6 @@ }, "node_modules/import-local/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": { @@ -16006,8 +13221,6 @@ }, "node_modules/import-local/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": { @@ -16019,8 +13232,6 @@ }, "node_modules/import-local/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": { @@ -16032,8 +13243,6 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "license": "MIT", "engines": { "node": ">=0.8.19" @@ -16041,8 +13250,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">=8" @@ -16050,8 +13257,6 @@ }, "node_modules/infima": { "version": "0.2.0-alpha.45", - "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.45.tgz", - "integrity": "sha512-uyH0zfr1erU1OohLk0fT4Rrb94AOhguWNOcD9uGrSpRvNB+6gZXUoJX5J0NtvzBO10YZ9PgvA4NFgt+fYg8ojw==", "license": "MIT", "engines": { "node": ">=12" @@ -16059,9 +13264,6 @@ }, "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": { @@ -16071,29 +13273,17 @@ }, "node_modules/inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, "node_modules/ini": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", "license": "ISC", "engines": { "node": ">=10" } }, - "node_modules/inline-style-parser": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz", - "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", - "license": "MIT" - }, "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==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -16106,8 +13296,6 @@ }, "node_modules/internmap": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", - "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", "license": "ISC", "engines": { "node": ">=12" @@ -16115,8 +13303,6 @@ }, "node_modules/invariant": { "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "license": "MIT", "dependencies": { "loose-envify": "^1.0.0" @@ -16124,8 +13310,6 @@ }, "node_modules/ipaddr.js": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.3.0.tgz", - "integrity": "sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==", "license": "MIT", "engines": { "node": ">= 10" @@ -16133,8 +13317,6 @@ }, "node_modules/is-alphabetical": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", - "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", "license": "MIT", "funding": { "type": "github", @@ -16143,8 +13325,6 @@ }, "node_modules/is-alphanumerical": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", - "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", "license": "MIT", "dependencies": { "is-alphabetical": "^2.0.0", @@ -16157,8 +13337,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -16174,14 +13352,10 @@ }, "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==", "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==", "license": "MIT", "dependencies": { "async-function": "^1.0.0", @@ -16199,8 +13373,6 @@ }, "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==", "license": "MIT", "dependencies": { "has-bigints": "^1.0.2" @@ -16214,8 +13386,6 @@ }, "node_modules/is-binary-path": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" @@ -16226,8 +13396,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -16242,8 +13410,6 @@ }, "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==", "license": "MIT", "dependencies": { "semver": "^7.7.1" @@ -16251,8 +13417,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -16263,8 +13427,6 @@ }, "node_modules/is-ci": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", "license": "MIT", "dependencies": { "ci-info": "^3.2.0" @@ -16275,8 +13437,6 @@ }, "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==", "license": "MIT", "dependencies": { "hasown": "^2.0.2" @@ -16290,8 +13450,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -16307,8 +13465,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -16323,8 +13479,6 @@ }, "node_modules/is-decimal": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", - "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", "license": "MIT", "funding": { "type": "github", @@ -16333,8 +13487,6 @@ }, "node_modules/is-docker": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "license": "MIT", "bin": { "is-docker": "cli.js" @@ -16348,8 +13500,6 @@ }, "node_modules/is-extendable": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -16357,8 +13507,6 @@ }, "node_modules/is-extglob": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -16366,8 +13514,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3" @@ -16381,8 +13527,6 @@ }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "license": "MIT", "engines": { "node": ">=8" @@ -16390,8 +13534,6 @@ }, "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": { @@ -16400,8 +13542,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==", "license": "MIT", "dependencies": { "call-bound": "^1.0.4", @@ -16419,8 +13559,6 @@ }, "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==", "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -16431,8 +13569,6 @@ }, "node_modules/is-hexadecimal": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", - "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", "license": "MIT", "funding": { "type": "github", @@ -16441,8 +13577,6 @@ }, "node_modules/is-in-ssh": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-in-ssh/-/is-in-ssh-1.0.0.tgz", - "integrity": "sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==", "dev": true, "license": "MIT", "engines": { @@ -16454,8 +13588,6 @@ }, "node_modules/is-inside-container": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", "license": "MIT", "dependencies": { "is-docker": "^3.0.0" @@ -16472,8 +13604,6 @@ }, "node_modules/is-inside-container/node_modules/is-docker": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", "license": "MIT", "bin": { "is-docker": "cli.js" @@ -16487,8 +13617,6 @@ }, "node_modules/is-installed-globally": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", "license": "MIT", "dependencies": { "global-dirs": "^3.0.0", @@ -16503,8 +13631,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -16515,8 +13641,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -16527,8 +13651,6 @@ }, "node_modules/is-network-error": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.0.tgz", - "integrity": "sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw==", "license": "MIT", "engines": { "node": ">=16" @@ -16539,8 +13661,6 @@ }, "node_modules/is-npm": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.1.0.tgz", - "integrity": "sha512-O2z4/kNgyjhQwVR1Wpkbfc19JIhggF97NZNCpWTnjH7kVcZMUrnut9XSN7txI7VdyIYk5ZatOq3zvSuWpU8hoA==", "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" @@ -16551,8 +13671,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">=0.12.0" @@ -16560,8 +13678,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -16576,8 +13692,6 @@ }, "node_modules/is-obj": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -16585,8 +13699,6 @@ }, "node_modules/is-path-inside": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "license": "MIT", "engines": { "node": ">=8" @@ -16594,8 +13706,6 @@ }, "node_modules/is-plain-obj": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", "license": "MIT", "engines": { "node": ">=12" @@ -16606,8 +13716,6 @@ }, "node_modules/is-plain-object": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "license": "MIT", "dependencies": { "isobject": "^3.0.1" @@ -16618,8 +13726,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -16636,8 +13742,6 @@ }, "node_modules/is-regexp": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -16645,8 +13749,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -16657,8 +13759,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3" @@ -16672,8 +13772,6 @@ }, "node_modules/is-stream": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "license": "MIT", "engines": { "node": ">=8" @@ -16684,8 +13782,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -16700,8 +13796,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -16717,8 +13811,6 @@ }, "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==", "license": "MIT", "dependencies": { "which-typed-array": "^1.1.16" @@ -16732,14 +13824,10 @@ }, "node_modules/is-typedarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", "license": "MIT" }, "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==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -16750,8 +13838,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3" @@ -16765,8 +13851,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -16781,8 +13865,6 @@ }, "node_modules/is-wsl": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "license": "MIT", "dependencies": { "is-docker": "^2.0.0" @@ -16793,8 +13875,6 @@ }, "node_modules/is-yarn-global": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", - "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==", "license": "MIT", "engines": { "node": ">=12" @@ -16802,20 +13882,14 @@ }, "node_modules/isarray": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "license": "ISC" }, "node_modules/isobject": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -16823,8 +13897,6 @@ }, "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": { @@ -16833,8 +13905,6 @@ }, "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": { @@ -16850,8 +13920,6 @@ }, "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": { @@ -16865,8 +13933,6 @@ }, "node_modules/istanbul-lib-source-maps": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -16880,8 +13946,6 @@ }, "node_modules/istanbul-lib-source-maps/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": { @@ -16890,8 +13954,6 @@ }, "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": { @@ -16904,8 +13966,6 @@ }, "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==", "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", @@ -16921,11 +13981,8 @@ }, "node_modules/jest": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", - "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -16949,8 +14006,6 @@ }, "node_modules/jest-changed-files": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", - "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", "dev": true, "license": "MIT", "dependencies": { @@ -16964,8 +14019,6 @@ }, "node_modules/jest-circus": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", - "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", "dev": true, "license": "MIT", "dependencies": { @@ -16996,8 +14049,6 @@ }, "node_modules/jest-cli": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", - "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", "dev": true, "license": "MIT", "dependencies": { @@ -17030,8 +14081,6 @@ }, "node_modules/jest-config": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", - "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", "dev": true, "license": "MIT", "dependencies": { @@ -17076,8 +14125,6 @@ }, "node_modules/jest-diff": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", - "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", "dev": true, "license": "MIT", "dependencies": { @@ -17092,8 +14139,6 @@ }, "node_modules/jest-docblock": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", - "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", "dev": true, "license": "MIT", "dependencies": { @@ -17105,8 +14150,6 @@ }, "node_modules/jest-each": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", - "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", "dev": true, "license": "MIT", "dependencies": { @@ -17122,8 +14165,6 @@ }, "node_modules/jest-environment-node": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", - "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", "dev": true, "license": "MIT", "dependencies": { @@ -17140,8 +14181,6 @@ }, "node_modules/jest-get-type": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", - "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", "dev": true, "license": "MIT", "engines": { @@ -17150,8 +14189,6 @@ }, "node_modules/jest-haste-map": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", - "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", "dev": true, "license": "MIT", "dependencies": { @@ -17176,8 +14213,6 @@ }, "node_modules/jest-leak-detector": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", - "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", "dev": true, "license": "MIT", "dependencies": { @@ -17190,8 +14225,6 @@ }, "node_modules/jest-matcher-utils": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", - "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", "dev": true, "license": "MIT", "dependencies": { @@ -17206,8 +14239,6 @@ }, "node_modules/jest-message-util": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", - "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", "dev": true, "license": "MIT", "dependencies": { @@ -17227,8 +14258,6 @@ }, "node_modules/jest-mock": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", - "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "dev": true, "license": "MIT", "dependencies": { @@ -17242,8 +14271,6 @@ }, "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": { @@ -17260,8 +14287,6 @@ }, "node_modules/jest-regex-util": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", - "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", "dev": true, "license": "MIT", "engines": { @@ -17270,8 +14295,6 @@ }, "node_modules/jest-resolve": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", - "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", "dev": true, "license": "MIT", "dependencies": { @@ -17291,8 +14314,6 @@ }, "node_modules/jest-resolve-dependencies": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", - "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", "dev": true, "license": "MIT", "dependencies": { @@ -17305,8 +14326,6 @@ }, "node_modules/jest-runner": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", - "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", "dev": true, "license": "MIT", "dependencies": { @@ -17338,8 +14357,6 @@ }, "node_modules/jest-runtime": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", - "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", "dev": true, "license": "MIT", "dependencies": { @@ -17372,8 +14389,6 @@ }, "node_modules/jest-snapshot": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", - "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", "dev": true, "license": "MIT", "dependencies": { @@ -17404,8 +14419,6 @@ }, "node_modules/jest-util": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", @@ -17421,8 +14434,6 @@ }, "node_modules/jest-validate": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", - "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", "dev": true, "license": "MIT", "dependencies": { @@ -17439,8 +14450,6 @@ }, "node_modules/jest-watcher": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", - "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", "dev": true, "license": "MIT", "dependencies": { @@ -17459,8 +14468,6 @@ }, "node_modules/jest-worker": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "license": "MIT", "dependencies": { "@types/node": "*", @@ -17474,8 +14481,6 @@ }, "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==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -17489,18 +14494,13 @@ }, "node_modules/jiti": { "version": "1.21.7", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", - "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "license": "MIT", - "peer": true, "bin": { "jiti": "bin/jiti.js" } }, "node_modules/joi": { "version": "17.13.3", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", - "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", "license": "BSD-3-Clause", "dependencies": { "@hapi/hoek": "^9.3.0", @@ -17512,8 +14512,6 @@ }, "node_modules/js-levenshtein": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", - "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -17521,14 +14519,10 @@ }, "node_modules/js-tokens": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -17539,8 +14533,6 @@ }, "node_modules/jsesc": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "license": "MIT", "bin": { "jsesc": "bin/jsesc" @@ -17551,20 +14543,14 @@ }, "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==", "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==", "license": "MIT" }, "node_modules/json-pointer": { "version": "0.6.2", - "resolved": "https://registry.npmjs.org/json-pointer/-/json-pointer-0.6.2.tgz", - "integrity": "sha512-vLWcKbOaXlO+jvRy4qNd+TI1QUPZzfJj1tpJ3vAXDych5XJf93ftpUKe5pKCrzyIIwgBJcOcCVRUfqQP25afBw==", "license": "MIT", "dependencies": { "foreach": "^2.0.4" @@ -17572,26 +14558,18 @@ }, "node_modules/json-schema": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", "license": "(AFL-2.1 OR BSD-3-Clause)" }, "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "version": "1.0.0", "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==", "license": "MIT" }, "node_modules/json5": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "license": "MIT", "bin": { "json5": "lib/cli.js" @@ -17602,8 +14580,6 @@ }, "node_modules/jsonfile": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", - "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", "license": "MIT", "dependencies": { "universalify": "^2.0.0" @@ -17614,8 +14590,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==", "license": "MIT", "dependencies": { "array-includes": "^3.1.6", @@ -17628,9 +14602,7 @@ } }, "node_modules/katex": { - "version": "0.16.27", - "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.27.tgz", - "integrity": "sha512-aeQoDkuRWSqQN6nSvVCEFvfXdqo1OQiCmmW1kc9xSdjutPv7BGO7pqY9sQRJpMOGrEdfDgF2TfRXe5eUAD2Waw==", + "version": "0.16.25", "funding": [ "https://opencollective.com/katex", "https://github.com/sponsors/katex" @@ -17645,8 +14617,6 @@ }, "node_modules/katex/node_modules/commander": { "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", "license": "MIT", "engines": { "node": ">= 12" @@ -17654,31 +14624,30 @@ }, "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==", "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } }, "node_modules/khroma": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/khroma/-/khroma-2.1.0.tgz", - "integrity": "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==" + "version": "2.1.0" }, "node_modules/kind-of": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "license": "MIT", "engines": { "node": ">=0.10.0" } }, + "node_modules/klaw-sync": { + "version": "6.0.0", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.11" + } + }, "node_modules/kleur": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "license": "MIT", "engines": { "node": ">=6" @@ -17686,8 +14655,6 @@ }, "node_modules/langium": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/langium/-/langium-3.3.1.tgz", - "integrity": "sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w==", "license": "MIT", "dependencies": { "chevrotain": "~11.0.3", @@ -17702,14 +14669,10 @@ }, "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==", "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==", "license": "MIT", "dependencies": { "language-subtag-registry": "^0.3.20" @@ -17720,8 +14683,6 @@ }, "node_modules/latest-version": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", - "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", "license": "MIT", "dependencies": { "package-json": "^8.1.0" @@ -17735,8 +14696,6 @@ }, "node_modules/launch-editor": { "version": "2.12.0", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.12.0.tgz", - "integrity": "sha512-giOHXoOtifjdHqUamwKq6c49GzBdLjvxrd2D+Q4V6uOHopJv7p9VJxikDsQ/CBXZbEITgUqSVHXLTG3VhPP1Dg==", "license": "MIT", "dependencies": { "picocolors": "^1.1.1", @@ -17745,14 +14704,10 @@ }, "node_modules/layout-base": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz", - "integrity": "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==", "license": "MIT" }, "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==", "license": "MIT", "engines": { "node": ">=6" @@ -17760,8 +14715,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==", "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", @@ -17773,8 +14726,6 @@ }, "node_modules/lightningcss": { "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", - "integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==", "license": "MPL-2.0", "dependencies": { "detect-libc": "^2.0.3" @@ -17800,30 +14751,8 @@ "lightningcss-win32-x64-msvc": "1.30.2" } }, - "node_modules/lightningcss-android-arm64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz", - "integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==", - "cpu": [ - "arm64" - ], - "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.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz", - "integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==", "cpu": [ "arm64" ], @@ -17840,190 +14769,8 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz", - "integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==", - "cpu": [ - "x64" - ], - "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.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz", - "integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==", - "cpu": [ - "x64" - ], - "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.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz", - "integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==", - "cpu": [ - "arm" - ], - "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.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz", - "integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==", - "cpu": [ - "arm64" - ], - "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.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz", - "integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==", - "cpu": [ - "arm64" - ], - "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.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz", - "integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==", - "cpu": [ - "x64" - ], - "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.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz", - "integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==", - "cpu": [ - "x64" - ], - "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.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz", - "integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==", - "cpu": [ - "arm64" - ], - "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.30.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz", - "integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/lilconfig": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", - "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", "license": "MIT", "engines": { "node": ">=14" @@ -18034,14 +14781,10 @@ }, "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==", "license": "MIT" }, "node_modules/loader-runner": { "version": "4.3.1", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", - "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", "license": "MIT", "engines": { "node": ">=6.11.5" @@ -18053,8 +14796,6 @@ }, "node_modules/loader-utils": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "license": "MIT", "dependencies": { "big.js": "^5.2.2", @@ -18067,8 +14808,6 @@ }, "node_modules/locate-path": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "license": "MIT", "dependencies": { "p-locate": "^5.0.0" @@ -18082,51 +14821,34 @@ }, "node_modules/lodash": { "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "license": "MIT" }, "node_modules/lodash-es": { - "version": "4.17.22", - "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.22.tgz", - "integrity": "sha512-XEawp1t0gxSi9x01glktRZ5HDy0HXqrM0x5pXQM98EaI0NxO6jVM7omDOxsuEo5UIASAnm2bRp1Jt/e0a2XU8Q==", + "version": "4.17.21", "license": "MIT" }, "node_modules/lodash.debounce": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "license": "MIT" }, "node_modules/lodash.isequal": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", - "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", "license": "MIT" }, "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==", "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==", "license": "MIT" }, "node_modules/lodash.uniq": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", "license": "MIT" }, "node_modules/longest-streak": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", - "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", "license": "MIT", "funding": { "type": "github", @@ -18135,8 +14857,6 @@ }, "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==", "license": "MIT", "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" @@ -18147,8 +14867,6 @@ }, "node_modules/lower-case": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", "license": "MIT", "dependencies": { "tslib": "^2.0.3" @@ -18156,8 +14874,6 @@ }, "node_modules/lowercase-keys": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" @@ -18168,8 +14884,6 @@ }, "node_modules/lru-cache": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "license": "ISC", "dependencies": { "yallist": "^3.0.2" @@ -18177,8 +14891,6 @@ }, "node_modules/lucide-react": { "version": "0.553.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.553.0.tgz", - "integrity": "sha512-BRgX5zrWmNy/lkVAe0dXBgd7XQdZ3HTf+Hwe3c9WK6dqgnj9h+hxV+MDncM88xDWlCq27+TKvHGE70ViODNILw==", "license": "ISC", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" @@ -18186,14 +14898,14 @@ }, "node_modules/lunr": { "version": "2.3.9", - "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", - "integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==", "license": "MIT" }, + "node_modules/lunr-languages": { + "version": "1.14.0", + "license": "MPL-1.1" + }, "node_modules/magic-string": { "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" @@ -18201,8 +14913,6 @@ }, "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": { @@ -18217,15 +14927,11 @@ }, "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": { @@ -18234,14 +14940,10 @@ }, "node_modules/mark.js": { "version": "8.11.1", - "resolved": "https://registry.npmjs.org/mark.js/-/mark.js-8.11.1.tgz", - "integrity": "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==", "license": "MIT" }, "node_modules/markdown-extensions": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", - "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", "license": "MIT", "engines": { "node": ">=16" @@ -18252,8 +14954,6 @@ }, "node_modules/markdown-table": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", - "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", "license": "MIT", "funding": { "type": "github", @@ -18262,8 +14962,6 @@ }, "node_modules/marked": { "version": "16.4.2", - "resolved": "https://registry.npmjs.org/marked/-/marked-16.4.2.tgz", - "integrity": "sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==", "license": "MIT", "bin": { "marked": "bin/marked.js" @@ -18274,8 +14972,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -18283,8 +14979,6 @@ }, "node_modules/mdast-util-directive": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.1.0.tgz", - "integrity": "sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -18304,8 +14998,6 @@ }, "node_modules/mdast-util-find-and-replace": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", - "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -18320,8 +15012,6 @@ }, "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "license": "MIT", "engines": { "node": ">=12" @@ -18332,8 +15022,6 @@ }, "node_modules/mdast-util-from-markdown": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", - "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -18356,8 +15044,6 @@ }, "node_modules/mdast-util-from-markdown/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -18372,8 +15058,6 @@ }, "node_modules/mdast-util-frontmatter": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", - "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -18390,8 +15074,6 @@ }, "node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "license": "MIT", "engines": { "node": ">=12" @@ -18402,8 +15084,6 @@ }, "node_modules/mdast-util-gfm": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", - "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", "license": "MIT", "dependencies": { "mdast-util-from-markdown": "^2.0.0", @@ -18421,8 +15101,6 @@ }, "node_modules/mdast-util-gfm-autolink-literal": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", - "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -18438,8 +15116,6 @@ }, "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-character": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -18458,8 +15134,6 @@ }, "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -18474,8 +15148,6 @@ }, "node_modules/mdast-util-gfm-footnote": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -18491,8 +15163,6 @@ }, "node_modules/mdast-util-gfm-strikethrough": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -18506,8 +15176,6 @@ }, "node_modules/mdast-util-gfm-table": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", - "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -18523,8 +15191,6 @@ }, "node_modules/mdast-util-gfm-task-list-item": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", - "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -18539,8 +15205,6 @@ }, "node_modules/mdast-util-mdx": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", - "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", "license": "MIT", "dependencies": { "mdast-util-from-markdown": "^2.0.0", @@ -18556,8 +15220,6 @@ }, "node_modules/mdast-util-mdx-expression": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", - "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", @@ -18574,8 +15236,6 @@ }, "node_modules/mdast-util-mdx-jsx": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", - "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", @@ -18598,8 +15258,6 @@ }, "node_modules/mdast-util-mdxjs-esm": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", - "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", @@ -18616,8 +15274,6 @@ }, "node_modules/mdast-util-phrasing": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", - "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -18630,8 +15286,6 @@ }, "node_modules/mdast-util-to-hast": { "version": "13.2.1", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", - "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -18651,8 +15305,6 @@ }, "node_modules/mdast-util-to-markdown": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", - "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -18672,8 +15324,6 @@ }, "node_modules/mdast-util-to-string": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0" @@ -18685,14 +15335,10 @@ }, "node_modules/mdn-data": { "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", "license": "CC0-1.0" }, "node_modules/media-typer": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -18700,8 +15346,6 @@ }, "node_modules/memfs": { "version": "4.51.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.51.1.tgz", - "integrity": "sha512-Eyt3XrufitN2ZL9c/uIRMyDwXanLI88h/L3MoWqNY747ha3dMR9dWqp8cRT5ntjZ0U1TNuq4U91ZXK0sMBjYOQ==", "license": "Apache-2.0", "dependencies": { "@jsonjoy.com/json-pack": "^1.11.0", @@ -18718,8 +15362,6 @@ }, "node_modules/merge-descriptors": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -18727,14 +15369,10 @@ }, "node_modules/merge-stream": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "license": "MIT", "engines": { "node": ">= 8" @@ -18742,8 +15380,6 @@ }, "node_modules/mermaid": { "version": "11.12.2", - "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.12.2.tgz", - "integrity": "sha512-n34QPDPEKmaeCG4WDMGy0OT6PSyxKCfy2pJgShP+Qow2KLrvWjclwbc3yXfSIf4BanqWEhQEpngWwNp/XhZt6w==", "license": "MIT", "dependencies": { "@braintree/sanitize-url": "^7.1.1", @@ -18770,8 +15406,6 @@ }, "node_modules/methods": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -18779,8 +15413,6 @@ }, "node_modules/micromark": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", - "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", "funding": [ { "type": "GitHub Sponsors", @@ -18814,8 +15446,6 @@ }, "node_modules/micromark-core-commonmark": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", - "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", "funding": [ { "type": "GitHub Sponsors", @@ -18848,8 +15478,6 @@ }, "node_modules/micromark-core-commonmark/node_modules/micromark-factory-space": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", "funding": [ { "type": "GitHub Sponsors", @@ -18868,8 +15496,6 @@ }, "node_modules/micromark-core-commonmark/node_modules/micromark-util-character": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -18888,8 +15514,6 @@ }, "node_modules/micromark-core-commonmark/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -18904,8 +15528,6 @@ }, "node_modules/micromark-extension-directive": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz", - "integrity": "sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==", "license": "MIT", "dependencies": { "devlop": "^1.0.0", @@ -18923,8 +15545,6 @@ }, "node_modules/micromark-extension-directive/node_modules/micromark-factory-space": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", "funding": [ { "type": "GitHub Sponsors", @@ -18943,8 +15563,6 @@ }, "node_modules/micromark-extension-directive/node_modules/micromark-util-character": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -18963,8 +15581,6 @@ }, "node_modules/micromark-extension-directive/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -18979,8 +15595,6 @@ }, "node_modules/micromark-extension-frontmatter": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", - "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", "license": "MIT", "dependencies": { "fault": "^2.0.0", @@ -18995,8 +15609,6 @@ }, "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-character": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19015,8 +15627,6 @@ }, "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19031,8 +15641,6 @@ }, "node_modules/micromark-extension-gfm": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", - "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", "license": "MIT", "dependencies": { "micromark-extension-gfm-autolink-literal": "^2.0.0", @@ -19051,8 +15659,6 @@ }, "node_modules/micromark-extension-gfm-autolink-literal": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", - "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", @@ -19067,8 +15673,6 @@ }, "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-character": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19087,8 +15691,6 @@ }, "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19103,8 +15705,6 @@ }, "node_modules/micromark-extension-gfm-footnote": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", - "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", "license": "MIT", "dependencies": { "devlop": "^1.0.0", @@ -19123,8 +15723,6 @@ }, "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-factory-space": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", "funding": [ { "type": "GitHub Sponsors", @@ -19143,8 +15741,6 @@ }, "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-character": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19163,8 +15759,6 @@ }, "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19179,8 +15773,6 @@ }, "node_modules/micromark-extension-gfm-strikethrough": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", - "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", "license": "MIT", "dependencies": { "devlop": "^1.0.0", @@ -19197,8 +15789,6 @@ }, "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19213,8 +15803,6 @@ }, "node_modules/micromark-extension-gfm-table": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", - "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", "license": "MIT", "dependencies": { "devlop": "^1.0.0", @@ -19230,8 +15818,6 @@ }, "node_modules/micromark-extension-gfm-table/node_modules/micromark-factory-space": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", "funding": [ { "type": "GitHub Sponsors", @@ -19250,8 +15836,6 @@ }, "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-character": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19270,8 +15854,6 @@ }, "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19286,8 +15868,6 @@ }, "node_modules/micromark-extension-gfm-tagfilter": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", - "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", "license": "MIT", "dependencies": { "micromark-util-types": "^2.0.0" @@ -19299,8 +15879,6 @@ }, "node_modules/micromark-extension-gfm-task-list-item": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", - "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", "license": "MIT", "dependencies": { "devlop": "^1.0.0", @@ -19316,8 +15894,6 @@ }, "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-factory-space": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", "funding": [ { "type": "GitHub Sponsors", @@ -19336,8 +15912,6 @@ }, "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-character": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19356,8 +15930,6 @@ }, "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19372,8 +15944,6 @@ }, "node_modules/micromark-extension-mdx-expression": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz", - "integrity": "sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19398,8 +15968,6 @@ }, "node_modules/micromark-extension-mdx-expression/node_modules/micromark-factory-space": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", "funding": [ { "type": "GitHub Sponsors", @@ -19418,8 +15986,6 @@ }, "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-character": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19438,8 +16004,6 @@ }, "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19454,8 +16018,6 @@ }, "node_modules/micromark-extension-mdx-jsx": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.2.tgz", - "integrity": "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==", "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", @@ -19476,8 +16038,6 @@ }, "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-factory-space": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", "funding": [ { "type": "GitHub Sponsors", @@ -19496,8 +16056,6 @@ }, "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-character": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19516,8 +16074,6 @@ }, "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19532,8 +16088,6 @@ }, "node_modules/micromark-extension-mdx-md": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", - "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", "license": "MIT", "dependencies": { "micromark-util-types": "^2.0.0" @@ -19545,8 +16099,6 @@ }, "node_modules/micromark-extension-mdxjs": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", - "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", "license": "MIT", "dependencies": { "acorn": "^8.0.0", @@ -19565,8 +16117,6 @@ }, "node_modules/micromark-extension-mdxjs-esm": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", - "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", @@ -19586,8 +16136,6 @@ }, "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-character": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19606,8 +16154,6 @@ }, "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19622,8 +16168,6 @@ }, "node_modules/micromark-factory-destination": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", - "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", "funding": [ { "type": "GitHub Sponsors", @@ -19643,8 +16187,6 @@ }, "node_modules/micromark-factory-destination/node_modules/micromark-util-character": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19663,8 +16205,6 @@ }, "node_modules/micromark-factory-destination/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19679,8 +16219,6 @@ }, "node_modules/micromark-factory-label": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", - "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", "funding": [ { "type": "GitHub Sponsors", @@ -19701,8 +16239,6 @@ }, "node_modules/micromark-factory-label/node_modules/micromark-util-character": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19721,8 +16257,6 @@ }, "node_modules/micromark-factory-label/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19737,8 +16271,6 @@ }, "node_modules/micromark-factory-mdx-expression": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.3.tgz", - "integrity": "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==", "funding": [ { "type": "GitHub Sponsors", @@ -19764,8 +16296,6 @@ }, "node_modules/micromark-factory-mdx-expression/node_modules/micromark-factory-space": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", "funding": [ { "type": "GitHub Sponsors", @@ -19784,8 +16314,6 @@ }, "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-character": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19804,8 +16332,6 @@ }, "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19820,8 +16346,6 @@ }, "node_modules/micromark-factory-space": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", - "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", "funding": [ { "type": "GitHub Sponsors", @@ -19840,8 +16364,6 @@ }, "node_modules/micromark-factory-space/node_modules/micromark-util-types": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", "funding": [ { "type": "GitHub Sponsors", @@ -19856,8 +16378,6 @@ }, "node_modules/micromark-factory-title": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", - "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", "funding": [ { "type": "GitHub Sponsors", @@ -19878,8 +16398,6 @@ }, "node_modules/micromark-factory-title/node_modules/micromark-factory-space": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", "funding": [ { "type": "GitHub Sponsors", @@ -19898,8 +16416,6 @@ }, "node_modules/micromark-factory-title/node_modules/micromark-util-character": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19918,8 +16434,6 @@ }, "node_modules/micromark-factory-title/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19934,8 +16448,6 @@ }, "node_modules/micromark-factory-whitespace": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", - "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", "funding": [ { "type": "GitHub Sponsors", @@ -19956,8 +16468,6 @@ }, "node_modules/micromark-factory-whitespace/node_modules/micromark-factory-space": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", "funding": [ { "type": "GitHub Sponsors", @@ -19976,8 +16486,6 @@ }, "node_modules/micromark-factory-whitespace/node_modules/micromark-util-character": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -19996,8 +16504,6 @@ }, "node_modules/micromark-factory-whitespace/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -20012,8 +16518,6 @@ }, "node_modules/micromark-util-character": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", - "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", "funding": [ { "type": "GitHub Sponsors", @@ -20032,8 +16536,6 @@ }, "node_modules/micromark-util-character/node_modules/micromark-util-types": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", "funding": [ { "type": "GitHub Sponsors", @@ -20048,8 +16550,6 @@ }, "node_modules/micromark-util-chunked": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", - "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", "funding": [ { "type": "GitHub Sponsors", @@ -20067,8 +16567,6 @@ }, "node_modules/micromark-util-chunked/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -20083,8 +16581,6 @@ }, "node_modules/micromark-util-classify-character": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", - "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", "funding": [ { "type": "GitHub Sponsors", @@ -20104,8 +16600,6 @@ }, "node_modules/micromark-util-classify-character/node_modules/micromark-util-character": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -20124,8 +16618,6 @@ }, "node_modules/micromark-util-classify-character/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -20140,8 +16632,6 @@ }, "node_modules/micromark-util-combine-extensions": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", - "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", "funding": [ { "type": "GitHub Sponsors", @@ -20160,8 +16650,6 @@ }, "node_modules/micromark-util-decode-numeric-character-reference": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", - "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", "funding": [ { "type": "GitHub Sponsors", @@ -20179,8 +16667,6 @@ }, "node_modules/micromark-util-decode-numeric-character-reference/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -20195,8 +16681,6 @@ }, "node_modules/micromark-util-decode-string": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", - "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", "funding": [ { "type": "GitHub Sponsors", @@ -20217,8 +16701,6 @@ }, "node_modules/micromark-util-decode-string/node_modules/micromark-util-character": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -20237,8 +16719,6 @@ }, "node_modules/micromark-util-decode-string/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -20253,8 +16733,6 @@ }, "node_modules/micromark-util-encode": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", - "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", "funding": [ { "type": "GitHub Sponsors", @@ -20269,8 +16747,6 @@ }, "node_modules/micromark-util-events-to-acorn": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.3.tgz", - "integrity": "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==", "funding": [ { "type": "GitHub Sponsors", @@ -20294,8 +16770,6 @@ }, "node_modules/micromark-util-events-to-acorn/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -20310,8 +16784,6 @@ }, "node_modules/micromark-util-html-tag-name": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", - "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", "funding": [ { "type": "GitHub Sponsors", @@ -20326,8 +16798,6 @@ }, "node_modules/micromark-util-normalize-identifier": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", - "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", "funding": [ { "type": "GitHub Sponsors", @@ -20345,8 +16815,6 @@ }, "node_modules/micromark-util-normalize-identifier/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -20361,8 +16829,6 @@ }, "node_modules/micromark-util-resolve-all": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", - "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", "funding": [ { "type": "GitHub Sponsors", @@ -20380,8 +16846,6 @@ }, "node_modules/micromark-util-sanitize-uri": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", - "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", "funding": [ { "type": "GitHub Sponsors", @@ -20401,8 +16865,6 @@ }, "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-character": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -20421,8 +16883,6 @@ }, "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -20437,8 +16897,6 @@ }, "node_modules/micromark-util-subtokenize": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", - "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", "funding": [ { "type": "GitHub Sponsors", @@ -20459,8 +16917,6 @@ }, "node_modules/micromark-util-subtokenize/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -20475,8 +16931,6 @@ }, "node_modules/micromark-util-symbol": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", - "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", "funding": [ { "type": "GitHub Sponsors", @@ -20491,8 +16945,6 @@ }, "node_modules/micromark-util-types": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", - "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", "funding": [ { "type": "GitHub Sponsors", @@ -20507,8 +16959,6 @@ }, "node_modules/micromark/node_modules/micromark-factory-space": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", - "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", "funding": [ { "type": "GitHub Sponsors", @@ -20527,8 +16977,6 @@ }, "node_modules/micromark/node_modules/micromark-util-character": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", - "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", "funding": [ { "type": "GitHub Sponsors", @@ -20547,8 +16995,6 @@ }, "node_modules/micromark/node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", - "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", "funding": [ { "type": "GitHub Sponsors", @@ -20563,8 +17009,6 @@ }, "node_modules/micromatch": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "license": "MIT", "dependencies": { "braces": "^3.0.3", @@ -20576,8 +17020,6 @@ }, "node_modules/mime": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", "license": "MIT", "bin": { "mime": "cli.js" @@ -20587,21 +17029,17 @@ } }, "node_modules/mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "version": "1.52.0", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "version": "2.1.35", "license": "MIT", "dependencies": { - "mime-db": "~1.33.0" + "mime-db": "1.52.0" }, "engines": { "node": ">= 0.6" @@ -20609,8 +17047,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==", "license": "MIT", "engines": { "node": ">=6" @@ -20618,8 +17054,6 @@ }, "node_modules/mimic-response": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", - "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" @@ -20630,8 +17064,6 @@ }, "node_modules/mini-css-extract-plugin": { "version": "2.9.4", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.4.tgz", - "integrity": "sha512-ZWYT7ln73Hptxqxk2DxPU9MmapXRhxkJD6tkSR04dnQxm8BGu2hzgKLugK5yySD97u/8yy7Ma7E76k9ZdvtjkQ==", "license": "MIT", "dependencies": { "schema-utils": "^4.0.0", @@ -20650,26 +17082,20 @@ }, "node_modules/minimalistic-assert": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", "license": "ISC" }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "5.1.6", "license": "ISC", "dependencies": { - "brace-expansion": "^1.1.7" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "*" + "node": ">=10" } }, "node_modules/minimist": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -20677,8 +17103,6 @@ }, "node_modules/mlly": { "version": "1.8.0", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz", - "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==", "license": "MIT", "dependencies": { "acorn": "^8.15.0", @@ -20689,14 +17113,10 @@ }, "node_modules/mlly/node_modules/confbox": { "version": "0.1.8", - "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz", - "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==", "license": "MIT" }, "node_modules/mlly/node_modules/pkg-types": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz", - "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==", "license": "MIT", "dependencies": { "confbox": "^0.1.8", @@ -20706,10 +17126,7 @@ }, "node_modules/mobx": { "version": "6.15.0", - "resolved": "https://registry.npmjs.org/mobx/-/mobx-6.15.0.tgz", - "integrity": "sha512-UczzB+0nnwGotYSgllfARAqWCJ5e/skuV2K/l+Zyck/H6pJIhLXuBnz+6vn2i211o7DtbE78HQtsYEKICHGI+g==", "license": "MIT", - "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/mobx" @@ -20717,8 +17134,6 @@ }, "node_modules/mobx-react": { "version": "9.2.1", - "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-9.2.1.tgz", - "integrity": "sha512-WJNNm0FB2n0Z0u+jS1QHmmWyV8l2WiAj8V8I/96kbUEN2YbYCoKW+hbbqKKRUBqElu0llxM7nWKehvRIkhBVJw==", "license": "MIT", "dependencies": { "mobx-react-lite": "^4.1.1" @@ -20742,8 +17157,6 @@ }, "node_modules/mobx-react-lite": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/mobx-react-lite/-/mobx-react-lite-4.1.1.tgz", - "integrity": "sha512-iUxiMpsvNraCKXU+yPotsOncNNmyeS2B5DKL+TL6Tar/xm+wwNJAubJmtRSeAoYawdZqwv8Z/+5nPRHeQxTiXg==", "license": "MIT", "dependencies": { "use-sync-external-store": "^1.4.0" @@ -20767,8 +17180,6 @@ }, "node_modules/mrmime": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", - "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", "license": "MIT", "engines": { "node": ">=10" @@ -20776,14 +17187,10 @@ }, "node_modules/ms": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, "node_modules/multicast-dns": { "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", "license": "MIT", "dependencies": { "dns-packet": "^5.2.2", @@ -20795,8 +17202,6 @@ }, "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", @@ -20813,8 +17218,6 @@ }, "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==", "license": "MIT", "bin": { "napi-postinstall": "lib/cli.js" @@ -20828,14 +17231,10 @@ }, "node_modules/natural-compare": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "license": "MIT" }, "node_modules/negotiator": { "version": "0.6.4", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", - "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -20843,19 +17242,14 @@ }, "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==", "license": "MIT" }, "node_modules/next": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/next/-/next-16.1.0.tgz", - "integrity": "sha512-Y+KbmDbefYtHDDQKLNrmzE/YYzG2msqo2VXhzh5yrJ54tx/6TmGdkR5+kP9ma7i7LwZpZMfoY3m/AoPPPKxtVw==", + "version": "16.0.10", "license": "MIT", "dependencies": { - "@next/env": "16.1.0", + "@next/env": "16.0.10", "@swc/helpers": "0.5.15", - "baseline-browser-mapping": "^2.8.3", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" @@ -20867,14 +17261,14 @@ "node": ">=20.9.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "16.1.0", - "@next/swc-darwin-x64": "16.1.0", - "@next/swc-linux-arm64-gnu": "16.1.0", - "@next/swc-linux-arm64-musl": "16.1.0", - "@next/swc-linux-x64-gnu": "16.1.0", - "@next/swc-linux-x64-musl": "16.1.0", - "@next/swc-win32-arm64-msvc": "16.1.0", - "@next/swc-win32-x64-msvc": "16.1.0", + "@next/swc-darwin-arm64": "16.0.10", + "@next/swc-darwin-x64": "16.0.10", + "@next/swc-linux-arm64-gnu": "16.0.10", + "@next/swc-linux-arm64-musl": "16.0.10", + "@next/swc-linux-x64-gnu": "16.0.10", + "@next/swc-linux-x64-musl": "16.0.10", + "@next/swc-win32-arm64-msvc": "16.0.10", + "@next/swc-win32-x64-msvc": "16.0.10", "sharp": "^0.34.4" }, "peerDependencies": { @@ -20902,8 +17296,6 @@ }, "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", @@ -20930,18 +17322,20 @@ }, "node_modules/no-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", "license": "MIT", "dependencies": { "lower-case": "^2.0.2", "tslib": "^2.0.3" } }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "license": "MIT", + "optional": true, + "peer": true + }, "node_modules/node-emoji": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.2.0.tgz", - "integrity": "sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==", "license": "MIT", "dependencies": { "@sindresorhus/is": "^4.6.0", @@ -20955,8 +17349,6 @@ }, "node_modules/node-fetch": { "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" @@ -20975,8 +17367,6 @@ }, "node_modules/node-fetch-h2": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/node-fetch-h2/-/node-fetch-h2-2.3.0.tgz", - "integrity": "sha512-ofRW94Ab0T4AOh5Fk8t0h8OBWrmjb0SSB20xh1H8YnPV9EJ+f5AMoYSUQ2zgJ4Iq2HAK0I2l5/Nequ8YzFS3Hg==", "license": "MIT", "dependencies": { "http2-client": "^1.2.5" @@ -20987,15 +17377,11 @@ }, "node_modules/node-fetch-native": { "version": "1.6.7", - "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", - "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", "dev": true, "license": "MIT" }, "node_modules/node-forge": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.3.tgz", - "integrity": "sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==", "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { "node": ">= 6.13.0" @@ -21003,15 +17389,11 @@ }, "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-readfiles": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/node-readfiles/-/node-readfiles-0.2.0.tgz", - "integrity": "sha512-SU00ZarexNlE4Rjdm83vglt5Y9yiQ+XI1XpflWlb7q7UTN1JUItm69xMeiQCTxtTfnzt+83T8Cx+vI2ED++VDA==", "license": "MIT", "dependencies": { "es6-promise": "^3.2.1" @@ -21019,14 +17401,17 @@ }, "node_modules/node-releases": { "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", "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==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -21034,8 +17419,6 @@ }, "node_modules/normalize-url": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.1.0.tgz", - "integrity": "sha512-X06Mfd/5aKsRHc0O0J5CUedwnPmnDtLF2+nq+KN9KSDlJHkPuh0JUviWjEWMe0SW/9TDdSLVPuk7L5gGTIA1/w==", "license": "MIT", "engines": { "node": ">=14.16" @@ -21046,8 +17429,6 @@ }, "node_modules/npm-run-path": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "license": "MIT", "dependencies": { "path-key": "^3.0.0" @@ -21058,14 +17439,10 @@ }, "node_modules/nprogress": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", - "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==", "license": "MIT" }, "node_modules/nth-check": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0" @@ -21076,8 +17453,6 @@ }, "node_modules/null-loader": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/null-loader/-/null-loader-4.0.1.tgz", - "integrity": "sha512-pxqVbi4U6N26lq+LmgIbB5XATP0VdZKOG25DhHi8btMmJJefGArFyDg1yc4U3hWCJbMqSrw0qyrz1UQX+qYXqg==", "license": "MIT", "dependencies": { "loader-utils": "^2.0.0", @@ -21096,8 +17471,6 @@ }, "node_modules/null-loader/node_modules/schema-utils": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.8", @@ -21114,8 +17487,6 @@ }, "node_modules/nypm": { "version": "0.6.2", - "resolved": "https://registry.npmjs.org/nypm/-/nypm-0.6.2.tgz", - "integrity": "sha512-7eM+hpOtrKrBDCh7Ypu2lJ9Z7PNZBdi/8AT3AX8xoCj43BBVHD0hPSTEvMtkMpfs8FCqBGhxB+uToIQimA111g==", "dev": true, "license": "MIT", "dependencies": { @@ -21134,8 +17505,6 @@ }, "node_modules/oas-kit-common": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/oas-kit-common/-/oas-kit-common-1.0.8.tgz", - "integrity": "sha512-pJTS2+T0oGIwgjGpw7sIRU8RQMcUoKCDWFLdBqKB2BNmGpbBMH2sdqAaOXUg8OzonZHU0L7vfJu1mJFEiYDWOQ==", "license": "BSD-3-Clause", "dependencies": { "fast-safe-stringify": "^2.0.7" @@ -21143,8 +17512,6 @@ }, "node_modules/oas-linter": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/oas-linter/-/oas-linter-3.2.2.tgz", - "integrity": "sha512-KEGjPDVoU5K6swgo9hJVA/qYGlwfbFx+Kg2QB/kd7rzV5N8N5Mg6PlsoCMohVnQmo+pzJap/F610qTodKzecGQ==", "license": "BSD-3-Clause", "dependencies": { "@exodus/schemasafe": "^1.0.0-rc.2", @@ -21157,8 +17524,6 @@ }, "node_modules/oas-resolver": { "version": "2.5.6", - "resolved": "https://registry.npmjs.org/oas-resolver/-/oas-resolver-2.5.6.tgz", - "integrity": "sha512-Yx5PWQNZomfEhPPOphFbZKi9W93CocQj18NlD2Pa4GWZzdZpSJvYwoiuurRI7m3SpcChrnO08hkuQDL3FGsVFQ==", "license": "BSD-3-Clause", "dependencies": { "node-fetch-h2": "^2.3.0", @@ -21176,8 +17541,6 @@ }, "node_modules/oas-schema-walker": { "version": "1.1.5", - "resolved": "https://registry.npmjs.org/oas-schema-walker/-/oas-schema-walker-1.1.5.tgz", - "integrity": "sha512-2yucenq1a9YPmeNExoUa9Qwrt9RFkjqaMAA1X+U7sbb0AqBeTIdMHky9SQQ6iN94bO5NW0W4TRYXerG+BdAvAQ==", "license": "BSD-3-Clause", "funding": { "url": "https://github.com/Mermade/oas-kit?sponsor=1" @@ -21185,8 +17548,6 @@ }, "node_modules/oas-validator": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/oas-validator/-/oas-validator-5.0.8.tgz", - "integrity": "sha512-cu20/HE5N5HKqVygs3dt94eYJfBi0TsZvPVXDhbXQHiEityDN+RROTleefoKRKKJ9dFAF2JBkDHgvWj0sjKGmw==", "license": "BSD-3-Clause", "dependencies": { "call-me-maybe": "^1.0.1", @@ -21204,8 +17565,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -21213,8 +17572,6 @@ }, "node_modules/object-inspect": { "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -21225,8 +17582,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -21234,8 +17589,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -21254,8 +17607,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -21269,8 +17620,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bind": "^1.0.7", @@ -21287,8 +17636,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bind": "^1.0.7", @@ -21301,8 +17648,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -21319,21 +17664,15 @@ }, "node_modules/obuf": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", "license": "MIT" }, "node_modules/ohash": { "version": "2.0.11", - "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.11.tgz", - "integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==", "dev": true, "license": "MIT" }, "node_modules/on-finished": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "license": "MIT", "dependencies": { "ee-first": "1.1.1" @@ -21344,8 +17683,6 @@ }, "node_modules/on-headers": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", - "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -21353,8 +17690,6 @@ }, "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": { @@ -21363,8 +17698,6 @@ }, "node_modules/onetime": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" @@ -21378,8 +17711,6 @@ }, "node_modules/open": { "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", "license": "MIT", "dependencies": { "define-lazy-prop": "^2.0.0", @@ -21395,8 +17726,6 @@ }, "node_modules/openapi-sampler": { "version": "1.6.2", - "resolved": "https://registry.npmjs.org/openapi-sampler/-/openapi-sampler-1.6.2.tgz", - "integrity": "sha512-NyKGiFKfSWAZr4srD/5WDhInOWDhfml32h/FKUqLpEwKJt0kG0LGUU0MdyNkKrVGuJnw6DuPWq/sHCwAMpiRxg==", "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.7", @@ -21406,8 +17735,6 @@ }, "node_modules/opener": { "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", "license": "(WTFPL OR MIT)", "bin": { "opener": "bin/opener-bin.js" @@ -21415,8 +17742,6 @@ }, "node_modules/optionator": { "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "license": "MIT", "dependencies": { "deep-is": "^0.1.3", @@ -21432,8 +17757,6 @@ }, "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==", "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.6", @@ -21449,8 +17772,6 @@ }, "node_modules/p-cancelable": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", "license": "MIT", "engines": { "node": ">=12.20" @@ -21458,8 +17779,6 @@ }, "node_modules/p-finally": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", "license": "MIT", "engines": { "node": ">=4" @@ -21467,8 +17786,6 @@ }, "node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" @@ -21482,8 +17799,6 @@ }, "node_modules/p-locate": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "license": "MIT", "dependencies": { "p-limit": "^3.0.2" @@ -21497,8 +17812,6 @@ }, "node_modules/p-map": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", "license": "MIT", "dependencies": { "aggregate-error": "^3.0.0" @@ -21512,8 +17825,6 @@ }, "node_modules/p-queue": { "version": "6.6.2", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", - "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", "license": "MIT", "dependencies": { "eventemitter3": "^4.0.4", @@ -21528,8 +17839,6 @@ }, "node_modules/p-retry": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", - "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", "license": "MIT", "dependencies": { "@types/retry": "0.12.2", @@ -21545,8 +17854,6 @@ }, "node_modules/p-timeout": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", "license": "MIT", "dependencies": { "p-finally": "^1.0.0" @@ -21557,8 +17864,6 @@ }, "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": { @@ -21567,8 +17872,6 @@ }, "node_modules/package-json": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", - "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", "license": "MIT", "dependencies": { "got": "^12.1.0", @@ -21585,14 +17888,10 @@ }, "node_modules/package-manager-detector": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz", - "integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==", "license": "MIT" }, "node_modules/param-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", "license": "MIT", "dependencies": { "dot-case": "^3.0.4", @@ -21601,8 +17900,6 @@ }, "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==", "license": "MIT", "dependencies": { "callsites": "^3.0.0" @@ -21613,8 +17910,6 @@ }, "node_modules/parse-entities": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", - "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", "license": "MIT", "dependencies": { "@types/unist": "^2.0.0", @@ -21632,14 +17927,10 @@ }, "node_modules/parse-entities/node_modules/@types/unist": { "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", - "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", "license": "MIT" }, "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==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", @@ -21656,14 +17947,10 @@ }, "node_modules/parse-numeric-range": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", - "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==", "license": "ISC" }, "node_modules/parse5": { "version": "7.3.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", - "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", "license": "MIT", "dependencies": { "entities": "^6.0.0" @@ -21674,8 +17961,6 @@ }, "node_modules/parse5-htmlparser2-tree-adapter": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", - "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", "license": "MIT", "dependencies": { "domhandler": "^5.0.3", @@ -21685,10 +17970,18 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/parse5/node_modules/entities": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -21699,8 +17992,6 @@ }, "node_modules/parseurl": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -21708,8 +17999,6 @@ }, "node_modules/pascal-case": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", "license": "MIT", "dependencies": { "no-case": "^3.0.4", @@ -21718,20 +18007,14 @@ }, "node_modules/path-browserify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", "license": "MIT" }, "node_modules/path-data-parser": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz", - "integrity": "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==", "license": "MIT" }, "node_modules/path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "license": "MIT", "engines": { "node": ">=8" @@ -21739,8 +18022,6 @@ }, "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": { @@ -21749,14 +18030,10 @@ }, "node_modules/path-is-inside": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", "license": "(WTFPL OR MIT)" }, "node_modules/path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "license": "MIT", "engines": { "node": ">=8" @@ -21764,14 +18041,10 @@ }, "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==", "license": "MIT" }, "node_modules/path-to-regexp": { "version": "1.9.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", - "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", "license": "MIT", "dependencies": { "isarray": "0.0.1" @@ -21779,8 +18052,6 @@ }, "node_modules/path-type": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "license": "MIT", "engines": { "node": ">=8" @@ -21788,33 +18059,23 @@ }, "node_modules/pathe": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "license": "MIT" }, "node_modules/perfect-debounce": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-2.0.0.tgz", - "integrity": "sha512-fkEH/OBiKrqqI/yIgjR92lMfs2K8105zt/VT6+7eTjNwisrsh47CeIED9z58zI7DfKdH3uHAn25ziRZn3kgAow==", "dev": true, "license": "MIT" }, "node_modules/perfect-scrollbar": { "version": "1.5.6", - "resolved": "https://registry.npmjs.org/perfect-scrollbar/-/perfect-scrollbar-1.5.6.tgz", - "integrity": "sha512-rixgxw3SxyJbCaSpo1n35A/fwI1r2rdwMKOTCg/AcG+xOEyZcE8UHVjpZMFCVImzsFoCZeJTT+M/rdEIQYO2nw==", "license": "MIT" }, "node_modules/picocolors": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "license": "MIT", "engines": { "node": ">=8.6" @@ -21825,8 +18086,6 @@ }, "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": { @@ -21835,8 +18094,6 @@ }, "node_modules/pkg-dir": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", - "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", "license": "MIT", "dependencies": { "find-up": "^6.3.0" @@ -21850,8 +18107,6 @@ }, "node_modules/pkg-dir/node_modules/find-up": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", "license": "MIT", "dependencies": { "locate-path": "^7.1.0", @@ -21866,8 +18121,6 @@ }, "node_modules/pkg-dir/node_modules/locate-path": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", "license": "MIT", "dependencies": { "p-locate": "^6.0.0" @@ -21881,8 +18134,6 @@ }, "node_modules/pkg-dir/node_modules/p-limit": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", "license": "MIT", "dependencies": { "yocto-queue": "^1.0.0" @@ -21896,8 +18147,6 @@ }, "node_modules/pkg-dir/node_modules/p-locate": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", "license": "MIT", "dependencies": { "p-limit": "^4.0.0" @@ -21911,8 +18160,6 @@ }, "node_modules/pkg-dir/node_modules/path-exists": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" @@ -21920,8 +18167,6 @@ }, "node_modules/pkg-dir/node_modules/yocto-queue": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", - "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", "license": "MIT", "engines": { "node": ">=12.20" @@ -21932,8 +18177,6 @@ }, "node_modules/pkg-types": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz", - "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==", "dev": true, "license": "MIT", "dependencies": { @@ -21944,8 +18187,6 @@ }, "node_modules/pluralize": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", "license": "MIT", "engines": { "node": ">=4" @@ -21953,14 +18194,10 @@ }, "node_modules/points-on-curve": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/points-on-curve/-/points-on-curve-0.2.0.tgz", - "integrity": "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==", "license": "MIT" }, "node_modules/points-on-path": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/points-on-path/-/points-on-path-0.2.1.tgz", - "integrity": "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==", "license": "MIT", "dependencies": { "path-data-parser": "0.1.0", @@ -21969,8 +18206,6 @@ }, "node_modules/polished": { "version": "4.3.1", - "resolved": "https://registry.npmjs.org/polished/-/polished-4.3.1.tgz", - "integrity": "sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.17.8" @@ -21981,8 +18216,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -21990,8 +18223,6 @@ }, "node_modules/postcss": { "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", "funding": [ { "type": "opencollective", @@ -22007,7 +18238,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -22019,8 +18249,6 @@ }, "node_modules/postcss-attribute-case-insensitive": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-7.0.1.tgz", - "integrity": "sha512-Uai+SupNSqzlschRyNx3kbCTWgY/2hcwtHEI/ej2LJWc9JJ77qKgGptd8DHwY1mXtZ7Aoh4z4yxfwMBue9eNgw==", "funding": [ { "type": "github", @@ -22044,8 +18272,6 @@ }, "node_modules/postcss-attribute-case-insensitive/node_modules/postcss-selector-parser": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", - "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -22057,8 +18283,6 @@ }, "node_modules/postcss-calc": { "version": "9.0.1", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-9.0.1.tgz", - "integrity": "sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==", "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.11", @@ -22073,8 +18297,6 @@ }, "node_modules/postcss-clamp": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-clamp/-/postcss-clamp-4.1.0.tgz", - "integrity": "sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -22088,8 +18310,6 @@ }, "node_modules/postcss-color-functional-notation": { "version": "7.0.12", - "resolved": "https://registry.npmjs.org/postcss-color-functional-notation/-/postcss-color-functional-notation-7.0.12.tgz", - "integrity": "sha512-TLCW9fN5kvO/u38/uesdpbx3e8AkTYhMvDZYa9JpmImWuTE99bDQ7GU7hdOADIZsiI9/zuxfAJxny/khknp1Zw==", "funding": [ { "type": "github", @@ -22117,8 +18337,6 @@ }, "node_modules/postcss-color-hex-alpha": { "version": "10.0.0", - "resolved": "https://registry.npmjs.org/postcss-color-hex-alpha/-/postcss-color-hex-alpha-10.0.0.tgz", - "integrity": "sha512-1kervM2cnlgPs2a8Vt/Qbe5cQ++N7rkYo/2rz2BkqJZIHQwaVuJgQH38REHrAi4uM0b1fqxMkWYmese94iMp3w==", "funding": [ { "type": "github", @@ -22143,8 +18361,6 @@ }, "node_modules/postcss-color-rebeccapurple": { "version": "10.0.0", - "resolved": "https://registry.npmjs.org/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-10.0.0.tgz", - "integrity": "sha512-JFta737jSP+hdAIEhk1Vs0q0YF5P8fFcj+09pweS8ktuGuZ8pPlykHsk6mPxZ8awDl4TrcxUqJo9l1IhVr/OjQ==", "funding": [ { "type": "github", @@ -22169,8 +18385,6 @@ }, "node_modules/postcss-colormin": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-6.1.0.tgz", - "integrity": "sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==", "license": "MIT", "dependencies": { "browserslist": "^4.23.0", @@ -22187,8 +18401,6 @@ }, "node_modules/postcss-convert-values": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz", - "integrity": "sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==", "license": "MIT", "dependencies": { "browserslist": "^4.23.0", @@ -22203,8 +18415,6 @@ }, "node_modules/postcss-custom-media": { "version": "11.0.6", - "resolved": "https://registry.npmjs.org/postcss-custom-media/-/postcss-custom-media-11.0.6.tgz", - "integrity": "sha512-C4lD4b7mUIw+RZhtY7qUbf4eADmb7Ey8BFA2px9jUbwg7pjTZDl4KY4bvlUV+/vXQvzQRfiGEVJyAbtOsCMInw==", "funding": [ { "type": "github", @@ -22231,8 +18441,6 @@ }, "node_modules/postcss-custom-properties": { "version": "14.0.6", - "resolved": "https://registry.npmjs.org/postcss-custom-properties/-/postcss-custom-properties-14.0.6.tgz", - "integrity": "sha512-fTYSp3xuk4BUeVhxCSJdIPhDLpJfNakZKoiTDx7yRGCdlZrSJR7mWKVOBS4sBF+5poPQFMj2YdXx1VHItBGihQ==", "funding": [ { "type": "github", @@ -22260,8 +18468,6 @@ }, "node_modules/postcss-custom-selectors": { "version": "8.0.5", - "resolved": "https://registry.npmjs.org/postcss-custom-selectors/-/postcss-custom-selectors-8.0.5.tgz", - "integrity": "sha512-9PGmckHQswiB2usSO6XMSswO2yFWVoCAuih1yl9FVcwkscLjRKjwsjM3t+NIWpSU2Jx3eOiK2+t4vVTQaoCHHg==", "funding": [ { "type": "github", @@ -22288,8 +18494,6 @@ }, "node_modules/postcss-custom-selectors/node_modules/postcss-selector-parser": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", - "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -22301,8 +18505,6 @@ }, "node_modules/postcss-dir-pseudo-class": { "version": "9.0.1", - "resolved": "https://registry.npmjs.org/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-9.0.1.tgz", - "integrity": "sha512-tRBEK0MHYvcMUrAuYMEOa0zg9APqirBcgzi6P21OhxtJyJADo/SWBwY1CAwEohQ/6HDaa9jCjLRG7K3PVQYHEA==", "funding": [ { "type": "github", @@ -22326,8 +18528,6 @@ }, "node_modules/postcss-dir-pseudo-class/node_modules/postcss-selector-parser": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", - "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -22339,8 +18539,6 @@ }, "node_modules/postcss-discard-comments": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz", - "integrity": "sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==", "license": "MIT", "engines": { "node": "^14 || ^16 || >=18.0" @@ -22351,8 +18549,6 @@ }, "node_modules/postcss-discard-duplicates": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz", - "integrity": "sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==", "license": "MIT", "engines": { "node": "^14 || ^16 || >=18.0" @@ -22363,8 +18559,6 @@ }, "node_modules/postcss-discard-empty": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz", - "integrity": "sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==", "license": "MIT", "engines": { "node": "^14 || ^16 || >=18.0" @@ -22375,8 +18569,6 @@ }, "node_modules/postcss-discard-overridden": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz", - "integrity": "sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==", "license": "MIT", "engines": { "node": "^14 || ^16 || >=18.0" @@ -22387,8 +18579,6 @@ }, "node_modules/postcss-discard-unused": { "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-6.0.5.tgz", - "integrity": "sha512-wHalBlRHkaNnNwfC8z+ppX57VhvS+HWgjW508esjdaEYr3Mx7Gnn2xA4R/CKf5+Z9S5qsqC+Uzh4ueENWwCVUA==", "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.16" @@ -22402,8 +18592,6 @@ }, "node_modules/postcss-double-position-gradients": { "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-double-position-gradients/-/postcss-double-position-gradients-6.0.4.tgz", - "integrity": "sha512-m6IKmxo7FxSP5nF2l63QbCC3r+bWpFUWmZXZf096WxG0m7Vl1Q1+ruFOhpdDRmKrRS+S3Jtk+TVk/7z0+BVK6g==", "funding": [ { "type": "github", @@ -22429,8 +18617,6 @@ }, "node_modules/postcss-focus-visible": { "version": "10.0.1", - "resolved": "https://registry.npmjs.org/postcss-focus-visible/-/postcss-focus-visible-10.0.1.tgz", - "integrity": "sha512-U58wyjS/I1GZgjRok33aE8juW9qQgQUNwTSdxQGuShHzwuYdcklnvK/+qOWX1Q9kr7ysbraQ6ht6r+udansalA==", "funding": [ { "type": "github", @@ -22454,8 +18640,6 @@ }, "node_modules/postcss-focus-visible/node_modules/postcss-selector-parser": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", - "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -22467,8 +18651,6 @@ }, "node_modules/postcss-focus-within": { "version": "9.0.1", - "resolved": "https://registry.npmjs.org/postcss-focus-within/-/postcss-focus-within-9.0.1.tgz", - "integrity": "sha512-fzNUyS1yOYa7mOjpci/bR+u+ESvdar6hk8XNK/TRR0fiGTp2QT5N+ducP0n3rfH/m9I7H/EQU6lsa2BrgxkEjw==", "funding": [ { "type": "github", @@ -22492,8 +18674,6 @@ }, "node_modules/postcss-focus-within/node_modules/postcss-selector-parser": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", - "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -22505,8 +18685,6 @@ }, "node_modules/postcss-font-variant": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz", - "integrity": "sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA==", "license": "MIT", "peerDependencies": { "postcss": "^8.1.0" @@ -22514,8 +18692,6 @@ }, "node_modules/postcss-gap-properties": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-gap-properties/-/postcss-gap-properties-6.0.0.tgz", - "integrity": "sha512-Om0WPjEwiM9Ru+VhfEDPZJAKWUd0mV1HmNXqp2C29z80aQ2uP9UVhLc7e3aYMIor/S5cVhoPgYQ7RtfeZpYTRw==", "funding": [ { "type": "github", @@ -22536,8 +18712,6 @@ }, "node_modules/postcss-image-set-function": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/postcss-image-set-function/-/postcss-image-set-function-7.0.0.tgz", - "integrity": "sha512-QL7W7QNlZuzOwBTeXEmbVckNt1FSmhQtbMRvGGqqU4Nf4xk6KUEQhAoWuMzwbSv5jxiRiSZ5Tv7eiDB9U87znA==", "funding": [ { "type": "github", @@ -22562,8 +18736,6 @@ }, "node_modules/postcss-lab-function": { "version": "7.0.12", - "resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-7.0.12.tgz", - "integrity": "sha512-tUcyRk1ZTPec3OuKFsqtRzW2Go5lehW29XA21lZ65XmzQkz43VY2tyWEC202F7W3mILOjw0voOiuxRGTsN+J9w==", "funding": [ { "type": "github", @@ -22591,8 +18763,6 @@ }, "node_modules/postcss-loader": { "version": "7.3.4", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.4.tgz", - "integrity": "sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A==", "license": "MIT", "dependencies": { "cosmiconfig": "^8.3.5", @@ -22613,8 +18783,6 @@ }, "node_modules/postcss-logical": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/postcss-logical/-/postcss-logical-8.1.0.tgz", - "integrity": "sha512-pL1hXFQ2fEXNKiNiAgtfA005T9FBxky5zkX6s4GZM2D8RkVgRqz3f4g1JUoq925zXv495qk8UNldDwh8uGEDoA==", "funding": [ { "type": "github", @@ -22638,8 +18806,6 @@ }, "node_modules/postcss-merge-idents": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-6.0.3.tgz", - "integrity": "sha512-1oIoAsODUs6IHQZkLQGO15uGEbK3EAl5wi9SS8hs45VgsxQfMnxvt+L+zIr7ifZFIH14cfAeVe2uCTa+SPRa3g==", "license": "MIT", "dependencies": { "cssnano-utils": "^4.0.2", @@ -22654,8 +18820,6 @@ }, "node_modules/postcss-merge-longhand": { "version": "6.0.5", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz", - "integrity": "sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0", @@ -22670,8 +18834,6 @@ }, "node_modules/postcss-merge-rules": { "version": "6.1.1", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz", - "integrity": "sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==", "license": "MIT", "dependencies": { "browserslist": "^4.23.0", @@ -22688,8 +18850,6 @@ }, "node_modules/postcss-minify-font-values": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz", - "integrity": "sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -22703,8 +18863,6 @@ }, "node_modules/postcss-minify-gradients": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz", - "integrity": "sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==", "license": "MIT", "dependencies": { "colord": "^2.9.3", @@ -22720,8 +18878,6 @@ }, "node_modules/postcss-minify-params": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz", - "integrity": "sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==", "license": "MIT", "dependencies": { "browserslist": "^4.23.0", @@ -22737,8 +18893,6 @@ }, "node_modules/postcss-minify-selectors": { "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz", - "integrity": "sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==", "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.16" @@ -22752,8 +18906,6 @@ }, "node_modules/postcss-modules-extract-imports": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", - "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", "license": "ISC", "engines": { "node": "^10 || ^12 || >= 14" @@ -22764,8 +18916,6 @@ }, "node_modules/postcss-modules-local-by-default": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", - "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", "license": "MIT", "dependencies": { "icss-utils": "^5.0.0", @@ -22781,8 +18931,6 @@ }, "node_modules/postcss-modules-local-by-default/node_modules/postcss-selector-parser": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", - "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -22794,8 +18942,6 @@ }, "node_modules/postcss-modules-scope": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", - "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", "license": "ISC", "dependencies": { "postcss-selector-parser": "^7.0.0" @@ -22809,8 +18955,6 @@ }, "node_modules/postcss-modules-scope/node_modules/postcss-selector-parser": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", - "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -22822,8 +18966,6 @@ }, "node_modules/postcss-modules-values": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", "license": "ISC", "dependencies": { "icss-utils": "^5.0.0" @@ -22837,8 +18979,6 @@ }, "node_modules/postcss-nesting": { "version": "13.0.2", - "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.2.tgz", - "integrity": "sha512-1YCI290TX+VP0U/K/aFxzHzQWHWURL+CtHMSbex1lCdpXD1SoR2sYuxDu5aNI9lPoXpKTCggFZiDJbwylU0LEQ==", "funding": [ { "type": "github", @@ -22864,8 +19004,6 @@ }, "node_modules/postcss-nesting/node_modules/@csstools/selector-resolve-nested": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.1.0.tgz", - "integrity": "sha512-mf1LEW0tJLKfWyvn5KdDrhpxHyuxpbNwTIwOYLIvsTffeyOf85j5oIzfG0yosxDgx/sswlqBnESYUcQH0vgZ0g==", "funding": [ { "type": "github", @@ -22886,8 +19024,6 @@ }, "node_modules/postcss-nesting/node_modules/@csstools/selector-specificity": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", - "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", "funding": [ { "type": "github", @@ -22908,10 +19044,7 @@ }, "node_modules/postcss-nesting/node_modules/postcss-selector-parser": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", - "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -22922,8 +19055,6 @@ }, "node_modules/postcss-normalize-charset": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz", - "integrity": "sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==", "license": "MIT", "engines": { "node": "^14 || ^16 || >=18.0" @@ -22934,8 +19065,6 @@ }, "node_modules/postcss-normalize-display-values": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz", - "integrity": "sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -22949,8 +19078,6 @@ }, "node_modules/postcss-normalize-positions": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz", - "integrity": "sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -22964,8 +19091,6 @@ }, "node_modules/postcss-normalize-repeat-style": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz", - "integrity": "sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -22979,8 +19104,6 @@ }, "node_modules/postcss-normalize-string": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz", - "integrity": "sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -22994,8 +19117,6 @@ }, "node_modules/postcss-normalize-timing-functions": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz", - "integrity": "sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -23009,8 +19130,6 @@ }, "node_modules/postcss-normalize-unicode": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz", - "integrity": "sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==", "license": "MIT", "dependencies": { "browserslist": "^4.23.0", @@ -23025,8 +19144,6 @@ }, "node_modules/postcss-normalize-url": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz", - "integrity": "sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -23040,8 +19157,6 @@ }, "node_modules/postcss-normalize-whitespace": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz", - "integrity": "sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -23055,8 +19170,6 @@ }, "node_modules/postcss-opacity-percentage": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-opacity-percentage/-/postcss-opacity-percentage-3.0.0.tgz", - "integrity": "sha512-K6HGVzyxUxd/VgZdX04DCtdwWJ4NGLG212US4/LA1TLAbHgmAsTWVR86o+gGIbFtnTkfOpb9sCRBx8K7HO66qQ==", "funding": [ { "type": "kofi", @@ -23077,8 +19190,6 @@ }, "node_modules/postcss-ordered-values": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz", - "integrity": "sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==", "license": "MIT", "dependencies": { "cssnano-utils": "^4.0.2", @@ -23093,8 +19204,6 @@ }, "node_modules/postcss-overflow-shorthand": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-overflow-shorthand/-/postcss-overflow-shorthand-6.0.0.tgz", - "integrity": "sha512-BdDl/AbVkDjoTofzDQnwDdm/Ym6oS9KgmO7Gr+LHYjNWJ6ExORe4+3pcLQsLA9gIROMkiGVjjwZNoL/mpXHd5Q==", "funding": [ { "type": "github", @@ -23118,8 +19227,6 @@ }, "node_modules/postcss-page-break": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/postcss-page-break/-/postcss-page-break-3.0.4.tgz", - "integrity": "sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ==", "license": "MIT", "peerDependencies": { "postcss": "^8" @@ -23127,8 +19234,6 @@ }, "node_modules/postcss-place": { "version": "10.0.0", - "resolved": "https://registry.npmjs.org/postcss-place/-/postcss-place-10.0.0.tgz", - "integrity": "sha512-5EBrMzat2pPAxQNWYavwAfoKfYcTADJ8AXGVPcUZ2UkNloUTWzJQExgrzrDkh3EKzmAx1evfTAzF9I8NGcc+qw==", "funding": [ { "type": "github", @@ -23152,8 +19257,6 @@ }, "node_modules/postcss-prefix-selector": { "version": "1.16.1", - "resolved": "https://registry.npmjs.org/postcss-prefix-selector/-/postcss-prefix-selector-1.16.1.tgz", - "integrity": "sha512-Umxu+FvKMwlY6TyDzGFoSUnzW+NOfMBLyC1tAkIjgX+Z/qGspJeRjVC903D7mx7TuBpJlwti2ibXtWuA7fKMeQ==", "license": "MIT", "peerDependencies": { "postcss": ">4 <9" @@ -23161,8 +19264,6 @@ }, "node_modules/postcss-preset-env": { "version": "10.5.0", - "resolved": "https://registry.npmjs.org/postcss-preset-env/-/postcss-preset-env-10.5.0.tgz", - "integrity": "sha512-xgxFQPAPxeWmsgy8cR7GM1PGAL/smA5E9qU7K//D4vucS01es3M0fDujhDJn3kY8Ip7/vVYcecbe1yY+vBo3qQ==", "funding": [ { "type": "github", @@ -23254,8 +19355,6 @@ }, "node_modules/postcss-pseudo-class-any-link": { "version": "10.0.1", - "resolved": "https://registry.npmjs.org/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-10.0.1.tgz", - "integrity": "sha512-3el9rXlBOqTFaMFkWDOkHUTQekFIYnaQY55Rsp8As8QQkpiSgIYEcF/6Ond93oHiDsGb4kad8zjt+NPlOC1H0Q==", "funding": [ { "type": "github", @@ -23279,8 +19378,6 @@ }, "node_modules/postcss-pseudo-class-any-link/node_modules/postcss-selector-parser": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", - "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -23292,8 +19389,6 @@ }, "node_modules/postcss-reduce-idents": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-6.0.3.tgz", - "integrity": "sha512-G3yCqZDpsNPoQgbDUy3T0E6hqOQ5xigUtBQyrmq3tn2GxlyiL0yyl7H+T8ulQR6kOcHJ9t7/9H4/R2tv8tJbMA==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -23307,8 +19402,6 @@ }, "node_modules/postcss-reduce-initial": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz", - "integrity": "sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==", "license": "MIT", "dependencies": { "browserslist": "^4.23.0", @@ -23323,8 +19416,6 @@ }, "node_modules/postcss-reduce-transforms": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz", - "integrity": "sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" @@ -23338,8 +19429,6 @@ }, "node_modules/postcss-replace-overflow-wrap": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz", - "integrity": "sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw==", "license": "MIT", "peerDependencies": { "postcss": "^8.0.3" @@ -23347,8 +19436,6 @@ }, "node_modules/postcss-selector-not": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/postcss-selector-not/-/postcss-selector-not-8.0.1.tgz", - "integrity": "sha512-kmVy/5PYVb2UOhy0+LqUYAhKj7DUGDpSWa5LZqlkWJaaAV+dxxsOG3+St0yNLu6vsKD7Dmqx+nWQt0iil89+WA==", "funding": [ { "type": "github", @@ -23372,8 +19459,6 @@ }, "node_modules/postcss-selector-not/node_modules/postcss-selector-parser": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz", - "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -23385,8 +19470,6 @@ }, "node_modules/postcss-selector-parser": { "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -23398,8 +19481,6 @@ }, "node_modules/postcss-sort-media-queries": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-5.2.0.tgz", - "integrity": "sha512-AZ5fDMLD8SldlAYlvi8NIqo0+Z8xnXU2ia0jxmuhxAU+Lqt9K+AlmLNJ/zWEnE9x+Zx3qL3+1K20ATgNOr3fAA==", "license": "MIT", "dependencies": { "sort-css-media-queries": "2.2.0" @@ -23413,8 +19494,6 @@ }, "node_modules/postcss-svgo": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-6.0.3.tgz", - "integrity": "sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==", "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0", @@ -23429,8 +19508,6 @@ }, "node_modules/postcss-unique-selectors": { "version": "6.0.4", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz", - "integrity": "sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==", "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.16" @@ -23444,14 +19521,10 @@ }, "node_modules/postcss-value-parser": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "license": "MIT" }, "node_modules/postcss-zindex": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-6.0.2.tgz", - "integrity": "sha512-5BxW9l1evPB/4ZIc+2GobEBoKC+h8gPGCMi+jxsYvd2x0mjq7wazk6DrP71pStqxE9Foxh5TVnonbWpFZzXaYg==", "license": "MIT", "engines": { "node": "^14 || ^16 || >=18.0" @@ -23462,8 +19535,6 @@ }, "node_modules/powershell-utils": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/powershell-utils/-/powershell-utils-0.1.0.tgz", - "integrity": "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==", "dev": true, "license": "MIT", "engines": { @@ -23475,8 +19546,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">= 0.8.0" @@ -23484,8 +19553,6 @@ }, "node_modules/prettier": { "version": "3.7.4", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.4.tgz", - "integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==", "dev": true, "license": "MIT", "bin": { @@ -23500,8 +19567,6 @@ }, "node_modules/pretty-error": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", "license": "MIT", "dependencies": { "lodash": "^4.17.20", @@ -23510,8 +19575,6 @@ }, "node_modules/pretty-format": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, "license": "MIT", "dependencies": { @@ -23525,8 +19588,6 @@ }, "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", "engines": { @@ -23538,15 +19599,11 @@ }, "node_modules/pretty-format/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/pretty-time": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", - "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", "license": "MIT", "engines": { "node": ">=4" @@ -23554,8 +19611,6 @@ }, "node_modules/prism-react-renderer": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.4.1.tgz", - "integrity": "sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig==", "license": "MIT", "dependencies": { "@types/prismjs": "^1.26.0", @@ -23567,8 +19622,6 @@ }, "node_modules/prismjs": { "version": "1.30.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", - "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", "license": "MIT", "engines": { "node": ">=6" @@ -23576,14 +19629,10 @@ }, "node_modules/process-nextick-args": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "license": "MIT" }, "node_modules/prompts": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "license": "MIT", "dependencies": { "kleur": "^3.0.3", @@ -23595,8 +19644,6 @@ }, "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==", "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", @@ -23606,14 +19653,10 @@ }, "node_modules/prop-types/node_modules/react-is": { "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "license": "MIT" }, "node_modules/property-information": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", - "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", "license": "MIT", "funding": { "type": "github", @@ -23622,14 +19665,10 @@ }, "node_modules/proto-list": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", "license": "ISC" }, "node_modules/proxy-addr": { "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "license": "MIT", "dependencies": { "forwarded": "0.2.0", @@ -23641,8 +19680,6 @@ }, "node_modules/proxy-addr/node_modules/ipaddr.js": { "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "license": "MIT", "engines": { "node": ">= 0.10" @@ -23650,8 +19687,6 @@ }, "node_modules/punycode": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "license": "MIT", "engines": { "node": ">=6" @@ -23659,8 +19694,6 @@ }, "node_modules/pupa": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.3.0.tgz", - "integrity": "sha512-LjgDO2zPtoXP2wJpDjZrGdojii1uqO0cnwKoIoUzkfS98HDmbeiGmYiXo3lXeFlq2xvne1QFQhwYXSUCLKtEuA==", "license": "MIT", "dependencies": { "escape-goat": "^4.0.0" @@ -23674,8 +19707,6 @@ }, "node_modules/pure-rand": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", - "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", "dev": true, "funding": [ { @@ -23691,8 +19722,6 @@ }, "node_modules/qs": { "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" @@ -23706,8 +19735,6 @@ }, "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==", "funding": [ { "type": "github", @@ -23726,8 +19753,6 @@ }, "node_modules/quick-lru": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", "license": "MIT", "engines": { "node": ">=10" @@ -23738,8 +19763,6 @@ }, "node_modules/randombytes": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" @@ -23747,8 +19770,6 @@ }, "node_modules/range-parser": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -23756,8 +19777,6 @@ }, "node_modules/raw-body": { "version": "2.5.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", - "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", "license": "MIT", "dependencies": { "bytes": "~3.1.2", @@ -23771,8 +19790,6 @@ }, "node_modules/raw-body/node_modules/bytes": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -23780,8 +19797,6 @@ }, "node_modules/raw-body/node_modules/iconv-lite": { "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" @@ -23792,8 +19807,6 @@ }, "node_modules/raw-loader": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-4.0.2.tgz", - "integrity": "sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==", "license": "MIT", "dependencies": { "loader-utils": "^2.0.0", @@ -23812,8 +19825,6 @@ }, "node_modules/raw-loader/node_modules/schema-utils": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.8", @@ -23830,8 +19841,6 @@ }, "node_modules/rc": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "dependencies": { "deep-extend": "^0.6.0", @@ -23845,14 +19854,10 @@ }, "node_modules/rc/node_modules/ini": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "license": "ISC" }, "node_modules/rc/node_modules/strip-json-comments": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -23860,8 +19865,6 @@ }, "node_modules/rc9": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/rc9/-/rc9-2.1.2.tgz", - "integrity": "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==", "dev": true, "license": "MIT", "dependencies": { @@ -23870,19 +19873,14 @@ } }, "node_modules/react": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz", - "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", + "version": "19.2.1", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } }, "node_modules/react-chrono": { "version": "2.9.1", - "resolved": "https://registry.npmjs.org/react-chrono/-/react-chrono-2.9.1.tgz", - "integrity": "sha512-/Qq6O7MQ3MYpq0A6IRAKS3mpx4y5B5Jl5os67Q/nt7iuvEnLJ08Yl6/7vlorH1NC2MiLzykOLO3vPnRAChb+HA==", "license": "MIT", "dependencies": { "classnames": "^2.5.1", @@ -23899,29 +19897,22 @@ } }, "node_modules/react-dom": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz", - "integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==", + "version": "19.2.1", "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^19.2.3" + "react": "^19.2.1" } }, "node_modules/react-fast-compare": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", - "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==", "license": "MIT" }, "node_modules/react-helmet-async": { "name": "@slorber/react-helmet-async", "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@slorber/react-helmet-async/-/react-helmet-async-1.3.0.tgz", - "integrity": "sha512-e9/OK8VhwUSc67diWI8Rb3I0YgI9/SBQtnhe9aEuK6MhZm7ntZZimXgwXnd8W96YTmSOb9M4d8LwhRZyhWr/1A==", "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.12.5", @@ -23936,16 +19927,12 @@ } }, "node_modules/react-is": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.3.tgz", - "integrity": "sha512-qJNJfu81ByyabuG7hPFEbXqNcWSU3+eVus+KJs+0ncpGfMyYdvSmxiJxbWR65lYi1I+/0HBcliO029gc4F+PnA==", + "version": "19.2.1", "license": "MIT", "peer": true }, "node_modules/react-json-view-lite": { "version": "2.5.0", - "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-2.5.0.tgz", - "integrity": "sha512-tk7o7QG9oYyELWHL8xiMQ8x4WzjCzbWNyig3uexmkLb54r8jO0yH3WCWx8UZS0c49eSA4QUmG5caiRJ8fAn58g==", "license": "MIT", "engines": { "node": ">=18" @@ -23957,10 +19944,7 @@ "node_modules/react-loadable": { "name": "@docusaurus/react-loadable", "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-6.0.0.tgz", - "integrity": "sha512-YMMxTUQV/QFSnbgrP3tjDzLHRg7vsbMn8e9HAa8o/1iXoiomo48b7sk/kkmWEuWNDPJVlKSJRB6Y2fHqdJk+SQ==", "license": "MIT", - "peer": true, "dependencies": { "@types/react": "*" }, @@ -23970,8 +19954,6 @@ }, "node_modules/react-loadable-ssr-addon-v5-slorber": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz", - "integrity": "sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.10.3" @@ -23986,10 +19968,7 @@ }, "node_modules/react-redux": { "version": "9.2.0", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz", - "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==", "license": "MIT", - "peer": true, "dependencies": { "@types/use-sync-external-store": "^0.0.6", "use-sync-external-store": "^1.4.0" @@ -24010,8 +19989,6 @@ }, "node_modules/react-remove-scroll": { "version": "2.7.2", - "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz", - "integrity": "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==", "license": "MIT", "dependencies": { "react-remove-scroll-bar": "^2.3.7", @@ -24035,8 +20012,6 @@ }, "node_modules/react-remove-scroll-bar": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz", - "integrity": "sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==", "license": "MIT", "dependencies": { "react-style-singleton": "^2.2.2", @@ -24057,8 +20032,6 @@ }, "node_modules/react-router": { "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", - "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.13", @@ -24077,8 +20050,6 @@ }, "node_modules/react-router-config": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/react-router-config/-/react-router-config-5.1.1.tgz", - "integrity": "sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.1.2" @@ -24090,8 +20061,6 @@ }, "node_modules/react-router-dom": { "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", - "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.13", @@ -24108,14 +20077,10 @@ }, "node_modules/react-router/node_modules/react-is": { "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "license": "MIT" }, "node_modules/react-style-singleton": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz", - "integrity": "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==", "license": "MIT", "dependencies": { "get-nonce": "^1.0.0", @@ -24136,8 +20101,6 @@ }, "node_modules/react-tabs": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/react-tabs/-/react-tabs-6.1.0.tgz", - "integrity": "sha512-6QtbTRDKM+jA/MZTTefvigNxo0zz+gnBTVFw2CFVvq+f2BuH0nF0vDLNClL045nuTAdOoK/IL1vTP0ZLX0DAyQ==", "license": "MIT", "dependencies": { "clsx": "^2.0.0", @@ -24149,8 +20112,6 @@ }, "node_modules/react18-json-view": { "version": "0.2.9", - "resolved": "https://registry.npmjs.org/react18-json-view/-/react18-json-view-0.2.9.tgz", - "integrity": "sha512-z3JQgCwZRKbmWh54U94loCU6vE0ZoDBK7C8ZpcMYQB8jYMi+mR/fcgMI9jKgATeF0I6+OAF025PD+UKkXIqueQ==", "license": "MIT", "dependencies": { "copy-to-clipboard": "^3.3.3" @@ -24161,8 +20122,6 @@ }, "node_modules/readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -24175,8 +20134,6 @@ }, "node_modules/readdirp": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "license": "MIT", "dependencies": { "picomatch": "^2.2.1" @@ -24186,9 +20143,7 @@ } }, "node_modules/recharts": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/recharts/-/recharts-3.6.0.tgz", - "integrity": "sha512-L5bjxvQRAe26RlToBAziKUB7whaGKEwD3znoM6fz3DrTowCIC/FnJYnuq1GEzB8Zv2kdTfaxQfi5GoH0tBinyg==", + "version": "3.5.1", "license": "MIT", "workspaces": [ "www" @@ -24217,14 +20172,10 @@ }, "node_modules/recharts/node_modules/eventemitter3": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", "license": "MIT" }, "node_modules/recma-build-jsx": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz", - "integrity": "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==", "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", @@ -24238,8 +20189,6 @@ }, "node_modules/recma-jsx": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/recma-jsx/-/recma-jsx-1.0.1.tgz", - "integrity": "sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==", "license": "MIT", "dependencies": { "acorn-jsx": "^5.0.0", @@ -24258,8 +20207,6 @@ }, "node_modules/recma-parse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/recma-parse/-/recma-parse-1.0.0.tgz", - "integrity": "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==", "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", @@ -24274,8 +20221,6 @@ }, "node_modules/recma-stringify": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/recma-stringify/-/recma-stringify-1.0.0.tgz", - "integrity": "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==", "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", @@ -24290,8 +20235,6 @@ }, "node_modules/redoc": { "version": "2.4.0", - "resolved": "https://registry.npmjs.org/redoc/-/redoc-2.4.0.tgz", - "integrity": "sha512-rFlfzFVWS9XJ6aYAs/bHnLhHP5FQEhwAHDBVgwb9L2FqDQ8Hu8rQ1G84iwaWXxZfPP9UWn7JdWkxI6MXr2ZDjw==", "license": "MIT", "dependencies": { "@redocly/openapi-core": "^1.4.0", @@ -24330,14 +20273,10 @@ }, "node_modules/redoc/node_modules/eventemitter3": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", "license": "MIT" }, "node_modules/redoc/node_modules/marked": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", - "integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==", "license": "MIT", "bin": { "marked": "bin/marked.js" @@ -24346,10 +20285,15 @@ "node": ">= 12" } }, + "node_modules/redoc/node_modules/slugify": { + "version": "1.4.7", + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/redocusaurus": { "version": "2.5.0", - "resolved": "https://registry.npmjs.org/redocusaurus/-/redocusaurus-2.5.0.tgz", - "integrity": "sha512-QWJX2hgnEfSDb7fZzS4iZe6aqdAvm/XLCsNv6RkgDw6Pl/lsTZKipP2n1r5QS1CC5hY8eAwsjVXeF7B03vkz2g==", "license": "MIT", "dependencies": { "docusaurus-plugin-redoc": "2.5.0", @@ -24365,15 +20309,10 @@ }, "node_modules/redux": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", - "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/redux-thunk": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", - "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", "license": "MIT", "peerDependencies": { "redux": "^5.0.0" @@ -24381,8 +20320,6 @@ }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", - "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -24403,8 +20340,6 @@ }, "node_modules/reftools": { "version": "1.1.9", - "resolved": "https://registry.npmjs.org/reftools/-/reftools-1.1.9.tgz", - "integrity": "sha512-OVede/NQE13xBQ+ob5CKd5KyeJYU2YInb1bmV4nRoOfquZPkAkxuOXicSe1PvqIuZZ4kD13sPKBbR7UFDmli6w==", "license": "BSD-3-Clause", "funding": { "url": "https://github.com/Mermade/oas-kit?sponsor=1" @@ -24412,14 +20347,10 @@ }, "node_modules/regenerate": { "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", "license": "MIT" }, "node_modules/regenerate-unicode-properties": { "version": "10.2.2", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", - "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", "license": "MIT", "dependencies": { "regenerate": "^1.4.2" @@ -24430,8 +20361,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -24450,8 +20379,6 @@ }, "node_modules/regexpu-core": { "version": "6.4.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", - "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", "license": "MIT", "dependencies": { "regenerate": "^1.4.2", @@ -24467,8 +20394,6 @@ }, "node_modules/registry-auth-token": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.1.0.tgz", - "integrity": "sha512-GdekYuwLXLxMuFTwAPg5UKGLW/UXzQrZvH/Zj791BQif5T05T0RsaLfHc9q3ZOKi7n+BoprPD9mJ0O0k4xzUlw==", "license": "MIT", "dependencies": { "@pnpm/npm-conf": "^2.1.0" @@ -24479,8 +20404,6 @@ }, "node_modules/registry-url": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", - "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", "license": "MIT", "dependencies": { "rc": "1.2.8" @@ -24494,14 +20417,10 @@ }, "node_modules/regjsgen": { "version": "0.8.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", "license": "MIT" }, "node_modules/regjsparser": { "version": "0.13.0", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz", - "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==", "license": "BSD-2-Clause", "dependencies": { "jsesc": "~3.1.0" @@ -24512,8 +20431,6 @@ }, "node_modules/rehype-raw": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", - "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -24527,8 +20444,6 @@ }, "node_modules/rehype-recma": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/rehype-recma/-/rehype-recma-1.0.0.tgz", - "integrity": "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==", "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", @@ -24542,8 +20457,6 @@ }, "node_modules/relateurl": { "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", "license": "MIT", "engines": { "node": ">= 0.10" @@ -24551,8 +20464,6 @@ }, "node_modules/remark-directive": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.1.tgz", - "integrity": "sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -24567,8 +20478,6 @@ }, "node_modules/remark-emoji": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-4.0.1.tgz", - "integrity": "sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.2", @@ -24583,8 +20492,6 @@ }, "node_modules/remark-frontmatter": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", - "integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -24599,8 +20506,6 @@ }, "node_modules/remark-gfm": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", - "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -24617,8 +20522,6 @@ }, "node_modules/remark-mdx": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.1.tgz", - "integrity": "sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==", "license": "MIT", "dependencies": { "mdast-util-mdx": "^3.0.0", @@ -24631,8 +20534,6 @@ }, "node_modules/remark-parse": { "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", - "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -24647,8 +20548,6 @@ }, "node_modules/remark-rehype": { "version": "11.1.2", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", - "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", @@ -24664,8 +20563,6 @@ }, "node_modules/remark-stringify": { "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", - "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", @@ -24679,8 +20576,6 @@ }, "node_modules/renderkid": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", - "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", "license": "MIT", "dependencies": { "css-select": "^4.1.3", @@ -24692,8 +20587,6 @@ }, "node_modules/renderkid/node_modules/css-select": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", @@ -24708,8 +20601,6 @@ }, "node_modules/renderkid/node_modules/dom-serializer": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", "license": "MIT", "dependencies": { "domelementtype": "^2.0.1", @@ -24722,8 +20613,6 @@ }, "node_modules/renderkid/node_modules/domhandler": { "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.2.0" @@ -24737,8 +20626,6 @@ }, "node_modules/renderkid/node_modules/domutils": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^1.0.1", @@ -24751,8 +20638,6 @@ }, "node_modules/renderkid/node_modules/entities": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", "license": "BSD-2-Clause", "funding": { "url": "https://github.com/fb55/entities?sponsor=1" @@ -24760,8 +20645,6 @@ }, "node_modules/renderkid/node_modules/htmlparser2": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { @@ -24779,8 +20662,6 @@ }, "node_modules/repeat-string": { "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", "license": "MIT", "engines": { "node": ">=0.10" @@ -24788,8 +20669,6 @@ }, "node_modules/require-directory": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -24797,8 +20676,6 @@ }, "node_modules/require-from-string": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -24806,28 +20683,20 @@ }, "node_modules/require-like": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", - "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", "engines": { "node": "*" } }, "node_modules/requires-port": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", "license": "MIT" }, "node_modules/reselect": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", - "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", "license": "MIT" }, "node_modules/resolve": { "version": "1.22.11", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", - "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", "license": "MIT", "dependencies": { "is-core-module": "^2.16.1", @@ -24846,14 +20715,10 @@ }, "node_modules/resolve-alpn": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", "license": "MIT" }, "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": { @@ -24865,8 +20730,6 @@ }, "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": { @@ -24875,8 +20738,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">=4" @@ -24884,14 +20745,10 @@ }, "node_modules/resolve-pathname": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", - "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==", "license": "MIT" }, "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==", "license": "MIT", "funding": { "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" @@ -24899,8 +20756,6 @@ }, "node_modules/resolve.exports": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", - "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", "dev": true, "license": "MIT", "engines": { @@ -24909,8 +20764,6 @@ }, "node_modules/responselike": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", - "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", "license": "MIT", "dependencies": { "lowercase-keys": "^3.0.0" @@ -24924,8 +20777,6 @@ }, "node_modules/retry": { "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", "license": "MIT", "engines": { "node": ">= 4" @@ -24933,8 +20784,6 @@ }, "node_modules/reusify": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "license": "MIT", "engines": { "iojs": ">=1.0.0", @@ -24943,14 +20792,10 @@ }, "node_modules/robust-predicates": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", - "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==", "license": "Unlicense" }, "node_modules/roughjs": { "version": "4.6.6", - "resolved": "https://registry.npmjs.org/roughjs/-/roughjs-4.6.6.tgz", - "integrity": "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==", "license": "MIT", "dependencies": { "hachure-fill": "^0.5.2", @@ -24961,8 +20806,6 @@ }, "node_modules/rtlcss": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.3.0.tgz", - "integrity": "sha512-FI+pHEn7Wc4NqKXMXFM+VAYKEj/mRIcW4h24YVwVtyjI+EqGrLc2Hx/Ny0lrZ21cBWU2goLy36eqMcNj3AQJig==", "license": "MIT", "dependencies": { "escalade": "^3.1.1", @@ -24979,8 +20822,6 @@ }, "node_modules/run-applescript": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", - "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", "license": "MIT", "engines": { "node": ">=18" @@ -24991,8 +20832,6 @@ }, "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==", "funding": [ { "type": "github", @@ -25014,14 +20853,10 @@ }, "node_modules/rw": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", - "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==", "license": "BSD-3-Clause" }, "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==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -25039,14 +20874,10 @@ }, "node_modules/safe-array-concat/node_modules/isarray": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "license": "MIT" }, "node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -25065,8 +20896,6 @@ }, "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==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -25081,14 +20910,10 @@ }, "node_modules/safe-push-apply/node_modules/isarray": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "license": "MIT" }, "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==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -25104,32 +20929,70 @@ }, "node_modules/safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT" }, + "node_modules/sass": { + "version": "1.94.2", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/sass/node_modules/chokidar": { + "version": "4.0.3", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/sass/node_modules/readdirp": { + "version": "4.1.2", + "license": "MIT", + "optional": true, + "peer": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/sax": { "version": "1.4.3", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.3.tgz", - "integrity": "sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==", "license": "BlueOak-1.0.0" }, "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/schema-dts": { "version": "1.1.5", - "resolved": "https://registry.npmjs.org/schema-dts/-/schema-dts-1.1.5.tgz", - "integrity": "sha512-RJr9EaCmsLzBX2NDiO5Z3ux2BVosNZN5jo0gWgsyKvxKIUL5R3swNvoorulAeL9kLB0iTSX7V6aokhla2m7xbg==", "license": "Apache-2.0" }, "node_modules/schema-utils": { "version": "4.3.3", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", - "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", @@ -25147,10 +21010,7 @@ }, "node_modules/schema-utils/node_modules/ajv": { "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -25164,8 +21024,6 @@ }, "node_modules/schema-utils/node_modules/ajv-keywords": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3" @@ -25174,23 +21032,13 @@ "ajv": "^8.8.2" } }, - "node_modules/schema-utils/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, "node_modules/search-insights": { "version": "2.17.3", - "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.17.3.tgz", - "integrity": "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ==", "license": "MIT", "peer": true }, "node_modules/section-matter": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", - "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", "license": "MIT", "dependencies": { "extend-shallow": "^2.0.1", @@ -25202,14 +21050,10 @@ }, "node_modules/select-hose": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", "license": "MIT" }, "node_modules/selfsigned": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", - "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", "license": "MIT", "dependencies": { "@types/node-forge": "^1.3.0", @@ -25221,8 +21065,6 @@ }, "node_modules/semver": { "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -25233,8 +21075,6 @@ }, "node_modules/semver-diff": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", - "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", "license": "MIT", "dependencies": { "semver": "^7.3.5" @@ -25247,9 +21087,7 @@ } }, "node_modules/send": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", - "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", + "version": "0.19.1", "license": "MIT", "dependencies": { "debug": "2.6.9", @@ -25258,13 +21096,13 @@ "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "fresh": "~0.5.2", - "http-errors": "~2.0.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", - "on-finished": "~2.4.1", + "on-finished": "2.4.1", "range-parser": "~1.2.1", - "statuses": "~2.0.2" + "statuses": "2.0.1" }, "engines": { "node": ">= 0.8.0" @@ -25272,8 +21110,6 @@ }, "node_modules/send/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -25281,23 +21117,38 @@ }, "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, + "node_modules/send/node_modules/http-errors": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/send/node_modules/range-parser": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "license": "MIT", "engines": { "node": ">= 0.6" } }, + "node_modules/send/node_modules/statuses": { + "version": "2.0.1", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/serialize-javascript": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" @@ -25305,8 +21156,6 @@ }, "node_modules/serve-handler": { "version": "6.1.6", - "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.6.tgz", - "integrity": "sha512-x5RL9Y2p5+Sh3D38Fh9i/iQ5ZK+e4xuXRd/pGbM4D13tgo/MGwbttUk8emytcr1YYzBYs+apnUngBDFYfpjPuQ==", "license": "MIT", "dependencies": { "bytes": "3.0.0", @@ -25318,16 +21167,47 @@ "range-parser": "1.2.0" } }, + "node_modules/serve-handler/node_modules/brace-expansion": { + "version": "1.1.12", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/serve-handler/node_modules/mime-db": { + "version": "1.33.0", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-handler/node_modules/mime-types": { + "version": "2.1.18", + "license": "MIT", + "dependencies": { + "mime-db": "~1.33.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-handler/node_modules/minimatch": { + "version": "3.1.2", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/serve-handler/node_modules/path-to-regexp": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", - "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==", "license": "MIT" }, "node_modules/serve-index": { "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", "license": "MIT", "dependencies": { "accepts": "~1.3.4", @@ -25344,8 +21224,6 @@ }, "node_modules/serve-index/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -25353,8 +21231,6 @@ }, "node_modules/serve-index/node_modules/depd": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -25362,8 +21238,6 @@ }, "node_modules/serve-index/node_modules/http-errors": { "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", "license": "MIT", "dependencies": { "depd": "~1.1.2", @@ -25377,50 +21251,106 @@ }, "node_modules/serve-index/node_modules/inherits": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", "license": "ISC" }, "node_modules/serve-index/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, "node_modules/serve-index/node_modules/setprototypeof": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", "license": "ISC" }, "node_modules/serve-index/node_modules/statuses": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/serve-static": { - "version": "1.16.3", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", - "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", + "version": "1.16.2", "license": "MIT", "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "~0.19.1" + "send": "0.19.0" }, "engines": { "node": ">= 0.8.0" } }, + "node_modules/serve-static/node_modules/debug": { + "version": "2.6.9", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-static/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/serve-static/node_modules/http-errors": { + "version": "2.0.0", + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serve-static/node_modules/range-parser": { + "version": "1.2.1", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-static/node_modules/send": { + "version": "0.19.0", + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-static/node_modules/send/node_modules/encodeurl": { + "version": "1.0.2", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serve-static/node_modules/statuses": { + "version": "2.0.1", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "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==", "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", @@ -25436,8 +21366,6 @@ }, "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==", "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", @@ -25451,8 +21379,6 @@ }, "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==", "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -25465,14 +21391,10 @@ }, "node_modules/setprototypeof": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "license": "ISC" }, "node_modules/shallow-clone": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", "license": "MIT", "dependencies": { "kind-of": "^6.0.2" @@ -25483,14 +21405,10 @@ }, "node_modules/shallowequal": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", "license": "MIT" }, "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, @@ -25534,8 +21452,6 @@ }, "node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -25546,8 +21462,6 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "license": "MIT", "engines": { "node": ">=8" @@ -25555,8 +21469,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -25567,8 +21479,6 @@ }, "node_modules/should": { "version": "13.2.3", - "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz", - "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==", "license": "MIT", "dependencies": { "should-equal": "^2.0.0", @@ -25580,8 +21490,6 @@ }, "node_modules/should-equal": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz", - "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==", "license": "MIT", "dependencies": { "should-type": "^1.4.0" @@ -25589,8 +21497,6 @@ }, "node_modules/should-format": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", - "integrity": "sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==", "license": "MIT", "dependencies": { "should-type": "^1.3.0", @@ -25599,14 +21505,10 @@ }, "node_modules/should-type": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", - "integrity": "sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==", "license": "MIT" }, "node_modules/should-type-adaptors": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", - "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", "license": "MIT", "dependencies": { "should-type": "^1.3.0", @@ -25615,14 +21517,10 @@ }, "node_modules/should-util": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz", - "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==", "license": "MIT" }, "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==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -25640,8 +21538,6 @@ }, "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==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -25656,8 +21552,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -25674,8 +21568,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -25693,14 +21585,10 @@ }, "node_modules/signal-exit": { "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "license": "ISC" }, "node_modules/sirv": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", - "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", "license": "MIT", "dependencies": { "@polka/url": "^1.0.0-next.24", @@ -25713,14 +21601,10 @@ }, "node_modules/sisteransi": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "license": "MIT" }, "node_modules/sitemap": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.2.tgz", - "integrity": "sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==", "license": "MIT", "dependencies": { "@types/node": "^17.0.5", @@ -25738,14 +21622,10 @@ }, "node_modules/sitemap/node_modules/@types/node": { "version": "17.0.45", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", - "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", "license": "MIT" }, "node_modules/skin-tone": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", - "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", "license": "MIT", "dependencies": { "unicode-emoji-modifier-base": "^1.0.0" @@ -25756,26 +21636,13 @@ }, "node_modules/slash": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/slugify": { - "version": "1.4.7", - "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.4.7.tgz", - "integrity": "sha512-tf+h5W1IrjNm/9rKKj0JU2MDMruiopx0jjVA5zCdBtcGjfp0+c5rHw/zADLC3IeKlGHtVbHtpfzvYA0OYT+HKg==", - "license": "MIT", - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/snake-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", - "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", "license": "MIT", "dependencies": { "dot-case": "^3.0.4", @@ -25784,8 +21651,6 @@ }, "node_modules/sockjs": { "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", "license": "MIT", "dependencies": { "faye-websocket": "^0.11.3", @@ -25795,8 +21660,6 @@ }, "node_modules/sockjs/node_modules/uuid": { "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "license": "MIT", "bin": { "uuid": "dist/bin/uuid" @@ -25804,8 +21667,6 @@ }, "node_modules/sort-css-media-queries": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.2.0.tgz", - "integrity": "sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==", "license": "MIT", "engines": { "node": ">= 6.3.0" @@ -25813,8 +21674,6 @@ }, "node_modules/source-map": { "version": "0.7.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", - "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", "license": "BSD-3-Clause", "engines": { "node": ">= 12" @@ -25822,8 +21681,6 @@ }, "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" @@ -25831,8 +21688,6 @@ }, "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": { @@ -25842,8 +21697,6 @@ }, "node_modules/source-map-support/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": { @@ -25852,8 +21705,6 @@ }, "node_modules/space-separated-tokens": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", "license": "MIT", "funding": { "type": "github", @@ -25862,8 +21713,6 @@ }, "node_modules/spdy": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", "license": "MIT", "dependencies": { "debug": "^4.1.0", @@ -25878,8 +21727,6 @@ }, "node_modules/spdy-transport": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", "license": "MIT", "dependencies": { "debug": "^4.1.0", @@ -25892,14 +21739,10 @@ }, "node_modules/sprintf-js": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "license": "BSD-3-Clause" }, "node_modules/srcset": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz", - "integrity": "sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==", "license": "MIT", "engines": { "node": ">=12" @@ -25910,14 +21753,10 @@ }, "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==", "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": { @@ -25929,8 +21768,6 @@ }, "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": { @@ -25939,8 +21776,6 @@ }, "node_modules/statuses": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", - "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -25948,19 +21783,13 @@ }, "node_modules/std-env": { "version": "3.10.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", - "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", "license": "MIT" }, "node_modules/stickyfill": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stickyfill/-/stickyfill-1.1.1.tgz", - "integrity": "sha512-GCp7vHAfpao+Qh/3Flh9DXEJ/qSi0KJwJw6zYlZOtRYXWUIpMM6mC2rIep/dK8RQqwW0KxGJIllmjPIBOGN8AA==" + "version": "1.1.1" }, "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==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -25972,8 +21801,6 @@ }, "node_modules/string_decoder": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" @@ -25981,8 +21808,6 @@ }, "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": { @@ -25995,8 +21820,6 @@ }, "node_modules/string-width": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", @@ -26012,8 +21835,6 @@ }, "node_modules/string-width/node_modules/ansi-regex": { "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "license": "MIT", "engines": { "node": ">=12" @@ -26024,8 +21845,6 @@ }, "node_modules/string-width/node_modules/strip-ansi": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -26039,8 +21858,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bind": "^1.0.7", @@ -26053,8 +21870,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -26080,8 +21895,6 @@ }, "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==", "license": "MIT", "dependencies": { "define-properties": "^1.1.3", @@ -26090,8 +21903,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -26111,8 +21922,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -26129,8 +21938,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bind": "^1.0.7", @@ -26146,8 +21953,6 @@ }, "node_modules/stringify-entities": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", - "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", "license": "MIT", "dependencies": { "character-entities-html4": "^2.0.0", @@ -26160,8 +21965,6 @@ }, "node_modules/stringify-object": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", "license": "BSD-2-Clause", "dependencies": { "get-own-enumerable-property-symbols": "^3.0.0", @@ -26174,8 +21977,6 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -26186,8 +21987,6 @@ }, "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": { @@ -26196,8 +21995,6 @@ }, "node_modules/strip-bom-string": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -26205,8 +22002,6 @@ }, "node_modules/strip-final-newline": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "license": "MIT", "engines": { "node": ">=6" @@ -26214,8 +22009,6 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "license": "MIT", "engines": { "node": ">=8" @@ -26226,8 +22019,6 @@ }, "node_modules/strnum": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", - "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", "funding": [ { "type": "github", @@ -26238,17 +22029,17 @@ }, "node_modules/style-to-js": { "version": "1.1.21", - "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz", - "integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==", "license": "MIT", "dependencies": { "style-to-object": "1.0.14" } }, - "node_modules/style-to-object": { + "node_modules/style-to-js/node_modules/inline-style-parser": { + "version": "0.2.7", + "license": "MIT" + }, + "node_modules/style-to-js/node_modules/style-to-object": { "version": "1.0.14", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz", - "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==", "license": "MIT", "dependencies": { "inline-style-parser": "0.2.7" @@ -26256,8 +22047,6 @@ }, "node_modules/styled-components": { "version": "6.1.19", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.19.tgz", - "integrity": "sha512-1v/e3Dl1BknC37cXMhwGomhO8AkYmN41CqyX9xhUDxry1ns3BFQy2lLDRQXJRdVVWB9OHemv/53xaStimvWyuA==", "license": "MIT", "dependencies": { "@emotion/is-prop-valid": "1.2.2", @@ -26284,14 +22073,10 @@ }, "node_modules/styled-components/node_modules/csstype": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "license": "MIT" }, "node_modules/styled-components/node_modules/postcss": { "version": "8.4.49", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", - "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", "funding": [ { "type": "opencollective", @@ -26318,20 +22103,14 @@ }, "node_modules/styled-components/node_modules/stylis": { "version": "4.3.2", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz", - "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==", "license": "MIT" }, "node_modules/styled-components/node_modules/tslib": { "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "license": "0BSD" }, "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" @@ -26353,8 +22132,6 @@ }, "node_modules/stylehacks": { "version": "6.1.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-6.1.1.tgz", - "integrity": "sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==", "license": "MIT", "dependencies": { "browserslist": "^4.23.0", @@ -26369,14 +22146,10 @@ }, "node_modules/stylis": { "version": "4.3.6", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz", - "integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==", "license": "MIT" }, "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==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -26387,8 +22160,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -26399,14 +22170,10 @@ }, "node_modules/svg-parser": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", - "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==", "license": "MIT" }, "node_modules/svgo": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", - "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", "license": "MIT", "dependencies": { "@trysound/sax": "0.2.0", @@ -26430,8 +22197,6 @@ }, "node_modules/svgo/node_modules/commander": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "license": "MIT", "engines": { "node": ">= 10" @@ -26439,8 +22204,6 @@ }, "node_modules/swagger2openapi": { "version": "7.0.8", - "resolved": "https://registry.npmjs.org/swagger2openapi/-/swagger2openapi-7.0.8.tgz", - "integrity": "sha512-upi/0ZGkYgEcLeGieoz8gT74oWHA0E7JivX7aN9mAf+Tc7BQoRBvnIGHoPDw+f9TXTW4s6kGYCZJtauP6OYp7g==", "license": "BSD-3-Clause", "dependencies": { "call-me-maybe": "^1.0.1", @@ -26465,13 +22228,11 @@ } }, "node_modules/swr": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/swr/-/swr-2.3.8.tgz", - "integrity": "sha512-gaCPRVoMq8WGDcWj9p4YWzCMPHzE0WNl6W8ADIx9c3JBEIdMkJGMzW+uzXvxHMltwcYACr9jP+32H8/hgwMR7w==", + "version": "2.3.7", "license": "MIT", "dependencies": { "dequal": "^2.0.3", - "use-sync-external-store": "^1.6.0" + "use-sync-external-store": "^1.4.0" }, "peerDependencies": { "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" @@ -26479,8 +22240,6 @@ }, "node_modules/tailwind-merge": { "version": "3.4.0", - "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.4.0.tgz", - "integrity": "sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==", "license": "MIT", "funding": { "type": "github", @@ -26488,16 +22247,11 @@ } }, "node_modules/tailwindcss": { - "version": "4.1.18", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz", - "integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==", - "license": "MIT", - "peer": true + "version": "4.1.17", + "license": "MIT" }, "node_modules/tailwindcss-animate": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz", - "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", "license": "MIT", "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders" @@ -26505,8 +22259,6 @@ }, "node_modules/tapable": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", - "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", "license": "MIT", "engines": { "node": ">=6" @@ -26518,8 +22270,6 @@ }, "node_modules/terser": { "version": "5.44.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.1.tgz", - "integrity": "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==", "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", @@ -26535,9 +22285,7 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.16", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz", - "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==", + "version": "5.3.14", "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", @@ -26570,8 +22318,6 @@ }, "node_modules/terser-webpack-plugin/node_modules/jest-worker": { "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", "license": "MIT", "dependencies": { "@types/node": "*", @@ -26584,8 +22330,6 @@ }, "node_modules/terser-webpack-plugin/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==", "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -26599,14 +22343,10 @@ }, "node_modules/terser/node_modules/commander": { "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "license": "MIT" }, "node_modules/terser/node_modules/source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -26614,8 +22354,6 @@ }, "node_modules/terser/node_modules/source-map-support": { "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", @@ -26624,8 +22362,6 @@ }, "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": { @@ -26637,10 +22373,28 @@ "node": ">=8" } }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.12", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/thingies": { "version": "2.5.0", - "resolved": "https://registry.npmjs.org/thingies/-/thingies-2.5.0.tgz", - "integrity": "sha512-s+2Bwztg6PhWUD7XMfeYm5qliDdSiZm7M7n8KjTkIsm3l/2lgVRc2/Gx/v+ZX8lT4FMA+i8aQvhcWylldc+ZNw==", "license": "MIT", "engines": { "node": ">=10.18" @@ -26655,14 +22409,10 @@ }, "node_modules/three": { "version": "0.182.0", - "resolved": "https://registry.npmjs.org/three/-/three-0.182.0.tgz", - "integrity": "sha512-GbHabT+Irv+ihI1/f5kIIsZ+Ef9Sl5A1Y7imvS5RQjWgtTPfPnZ43JmlYI7NtCRDK9zir20lQpfg8/9Yd02OvQ==", "license": "MIT" }, "node_modules/throttleit": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-2.1.0.tgz", - "integrity": "sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==", "license": "MIT", "engines": { "node": ">=18" @@ -26673,26 +22423,18 @@ }, "node_modules/thunky": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", "license": "MIT" }, "node_modules/tiny-invariant": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", - "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", "license": "MIT" }, "node_modules/tiny-warning": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", "license": "MIT" }, "node_modules/tinyexec": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", - "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", "license": "MIT", "engines": { "node": ">=18" @@ -26700,8 +22442,6 @@ }, "node_modules/tinyglobby": { "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", "license": "MIT", "dependencies": { "fdir": "^6.5.0", @@ -26716,8 +22456,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -26733,10 +22471,7 @@ }, "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==", "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -26746,8 +22481,6 @@ }, "node_modules/tinypool": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", - "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", "license": "MIT", "engines": { "node": "^18.0.0 || >=20.0.0" @@ -26755,15 +22488,11 @@ }, "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==", "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -26774,14 +22503,10 @@ }, "node_modules/toggle-selection": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", - "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==", "license": "MIT" }, "node_modules/toidentifier": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "license": "MIT", "engines": { "node": ">=0.6" @@ -26789,8 +22514,6 @@ }, "node_modules/totalist": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", "license": "MIT", "engines": { "node": ">=6" @@ -26798,14 +22521,10 @@ }, "node_modules/tr46": { "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "license": "MIT" }, "node_modules/tree-dump": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.1.0.tgz", - "integrity": "sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==", "license": "Apache-2.0", "engines": { "node": ">=10.0" @@ -26820,8 +22539,6 @@ }, "node_modules/trim-lines": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", - "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", "license": "MIT", "funding": { "type": "github", @@ -26830,8 +22547,6 @@ }, "node_modules/trough": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", - "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", "license": "MIT", "funding": { "type": "github", @@ -26840,8 +22555,6 @@ }, "node_modules/ts-api-utils": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", - "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", "license": "MIT", "engines": { "node": ">=18.12" @@ -26852,8 +22565,6 @@ }, "node_modules/ts-dedent": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", - "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", "license": "MIT", "engines": { "node": ">=6.10" @@ -26861,8 +22572,6 @@ }, "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": { @@ -26914,8 +22623,6 @@ }, "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": { @@ -26927,8 +22634,6 @@ }, "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==", "license": "MIT", "dependencies": { "@types/json5": "^0.0.29", @@ -26939,8 +22644,6 @@ }, "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==", "license": "MIT", "dependencies": { "minimist": "^1.2.0" @@ -26951,8 +22654,6 @@ }, "node_modules/tsconfig-paths/node_modules/strip-bom": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "license": "MIT", "engines": { "node": ">=4" @@ -26960,15 +22661,10 @@ }, "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", - "peer": true + "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==", "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" @@ -26979,8 +22675,6 @@ }, "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": { @@ -26989,8 +22683,6 @@ }, "node_modules/type-fest": { "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=12.20" @@ -27001,8 +22693,6 @@ }, "node_modules/type-is": { "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "license": "MIT", "dependencies": { "media-typer": "0.3.0", @@ -27012,31 +22702,8 @@ "node": ">= 0.6" } }, - "node_modules/type-is/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/type-is/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "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==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -27049,8 +22716,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -27068,8 +22733,6 @@ }, "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==", "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", @@ -27089,8 +22752,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bind": "^1.0.7", @@ -27109,8 +22770,6 @@ }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "license": "MIT", "dependencies": { "is-typedarray": "^1.0.0" @@ -27118,10 +22777,7 @@ }, "node_modules/typescript": { "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -27132,8 +22788,6 @@ }, "node_modules/typescript-eslint": { "version": "8.50.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.50.0.tgz", - "integrity": "sha512-Q1/6yNUmCpH94fbgMUMg2/BSAr/6U7GBk61kZTv1/asghQOWOjTlp9K8mixS5NcJmm2creY+UFfGeW/+OcA64A==", "license": "MIT", "dependencies": { "@typescript-eslint/eslint-plugin": "8.50.0", @@ -27155,14 +22809,10 @@ }, "node_modules/ufo": { "version": "1.6.1", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", - "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", "license": "MIT" }, "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, @@ -27175,8 +22825,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -27191,16 +22839,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici": { + "version": "7.16.0", + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "version": "7.16.0", "license": "MIT" }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", - "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", "license": "MIT", "engines": { "node": ">=4" @@ -27208,8 +22859,6 @@ }, "node_modules/unicode-emoji-modifier-base": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", - "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", "license": "MIT", "engines": { "node": ">=4" @@ -27217,8 +22866,6 @@ }, "node_modules/unicode-match-property-ecmascript": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", "license": "MIT", "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", @@ -27230,8 +22877,6 @@ }, "node_modules/unicode-match-property-value-ecmascript": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", - "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", "license": "MIT", "engines": { "node": ">=4" @@ -27239,8 +22884,6 @@ }, "node_modules/unicode-property-aliases-ecmascript": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", - "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", "license": "MIT", "engines": { "node": ">=4" @@ -27248,8 +22891,6 @@ }, "node_modules/unified": { "version": "11.0.5", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", - "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -27267,8 +22908,6 @@ }, "node_modules/unique-string": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", - "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", "license": "MIT", "dependencies": { "crypto-random-string": "^4.0.0" @@ -27282,8 +22921,6 @@ }, "node_modules/unist-util-is": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", - "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" @@ -27295,8 +22932,6 @@ }, "node_modules/unist-util-position": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" @@ -27308,8 +22943,6 @@ }, "node_modules/unist-util-position-from-estree": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", - "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" @@ -27321,8 +22954,6 @@ }, "node_modules/unist-util-stringify-position": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" @@ -27334,8 +22965,6 @@ }, "node_modules/unist-util-visit": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -27349,8 +22978,6 @@ }, "node_modules/unist-util-visit-parents": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", - "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -27363,8 +22990,6 @@ }, "node_modules/universalify": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "license": "MIT", "engines": { "node": ">= 10.0.0" @@ -27372,8 +22997,6 @@ }, "node_modules/unpipe": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -27381,8 +23004,6 @@ }, "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==", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -27414,9 +23035,7 @@ } }, "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==", + "version": "1.2.2", "funding": [ { "type": "opencollective", @@ -27445,8 +23064,6 @@ }, "node_modules/update-notifier": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz", - "integrity": "sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==", "license": "BSD-2-Clause", "dependencies": { "boxen": "^7.0.0", @@ -27473,8 +23090,6 @@ }, "node_modules/update-notifier/node_modules/boxen": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", - "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", "license": "MIT", "dependencies": { "ansi-align": "^3.0.1", @@ -27495,8 +23110,6 @@ }, "node_modules/update-notifier/node_modules/camelcase": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", - "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", "license": "MIT", "engines": { "node": ">=14.16" @@ -27507,8 +23120,6 @@ }, "node_modules/update-notifier/node_modules/chalk": { "version": "5.6.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", - "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" @@ -27519,8 +23130,6 @@ }, "node_modules/uri-js": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" @@ -27528,8 +23137,6 @@ }, "node_modules/url-loader": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", - "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", "license": "MIT", "dependencies": { "loader-utils": "^2.0.0", @@ -27553,31 +23160,8 @@ } } }, - "node_modules/url-loader/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/url-loader/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/url-loader/node_modules/schema-utils": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.8", @@ -27594,14 +23178,10 @@ }, "node_modules/url-template": { "version": "2.0.8", - "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", - "integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==", "license": "BSD" }, "node_modules/use-callback-ref": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", - "integrity": "sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==", "license": "MIT", "dependencies": { "tslib": "^2.0.0" @@ -27621,8 +23201,6 @@ }, "node_modules/use-debounce": { "version": "10.0.6", - "resolved": "https://registry.npmjs.org/use-debounce/-/use-debounce-10.0.6.tgz", - "integrity": "sha512-C5OtPyhAZgVoteO9heXMTdW7v/IbFI+8bSVKYCJrSmiWWCLsbUxiBSp4t9v0hNBTGY97bT72ydDIDyGSFWfwXg==", "license": "MIT", "engines": { "node": ">= 16.0.0" @@ -27633,8 +23211,6 @@ }, "node_modules/use-sidecar": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz", - "integrity": "sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==", "license": "MIT", "dependencies": { "detect-node-es": "^1.1.0", @@ -27655,8 +23231,6 @@ }, "node_modules/use-sync-external-store": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", - "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", "license": "MIT", "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" @@ -27664,20 +23238,14 @@ }, "node_modules/util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, "node_modules/utila": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==", "license": "MIT" }, "node_modules/utility-types": { "version": "3.11.0", - "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", - "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", "license": "MIT", "engines": { "node": ">= 4" @@ -27685,8 +23253,6 @@ }, "node_modules/utils-merge": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "license": "MIT", "engines": { "node": ">= 0.4.0" @@ -27694,8 +23260,6 @@ }, "node_modules/uuid": { "version": "11.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", - "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -27707,8 +23271,6 @@ }, "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": { @@ -27722,14 +23284,10 @@ }, "node_modules/value-equal": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", - "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==", "license": "MIT" }, "node_modules/vary": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -27737,8 +23295,6 @@ }, "node_modules/vfile": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", - "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -27751,8 +23307,6 @@ }, "node_modules/vfile-location": { "version": "5.0.3", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", - "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -27765,8 +23319,6 @@ }, "node_modules/vfile-message": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", - "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", @@ -27779,8 +23331,6 @@ }, "node_modules/victory-vendor": { "version": "37.3.6", - "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-37.3.6.tgz", - "integrity": "sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==", "license": "MIT AND ISC", "dependencies": { "@types/d3-array": "^3.0.3", @@ -27801,8 +23351,6 @@ }, "node_modules/vscode-jsonrpc": { "version": "8.2.0", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", - "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", "license": "MIT", "engines": { "node": ">=14.0.0" @@ -27810,8 +23358,6 @@ }, "node_modules/vscode-languageserver": { "version": "9.0.1", - "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", - "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", "license": "MIT", "dependencies": { "vscode-languageserver-protocol": "3.17.5" @@ -27822,8 +23368,6 @@ }, "node_modules/vscode-languageserver-protocol": { "version": "3.17.5", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", - "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", "license": "MIT", "dependencies": { "vscode-jsonrpc": "8.2.0", @@ -27832,26 +23376,18 @@ }, "node_modules/vscode-languageserver-textdocument": { "version": "1.0.12", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", - "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==", "license": "MIT" }, "node_modules/vscode-languageserver-types": { "version": "3.17.5", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", - "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", "license": "MIT" }, "node_modules/vscode-uri": { "version": "3.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", - "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==", "license": "MIT" }, "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": { @@ -27860,8 +23396,6 @@ }, "node_modules/watchpack": { "version": "2.4.4", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", - "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", @@ -27873,8 +23407,6 @@ }, "node_modules/wbuf": { "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", "license": "MIT", "dependencies": { "minimalistic-assert": "^1.0.0" @@ -27882,8 +23414,6 @@ }, "node_modules/web-namespaces": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", - "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", "license": "MIT", "funding": { "type": "github", @@ -27892,16 +23422,11 @@ }, "node_modules/webidl-conversions": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "license": "BSD-2-Clause" }, "node_modules/webpack": { - "version": "5.104.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.104.1.tgz", - "integrity": "sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==", + "version": "5.103.0", "license": "MIT", - "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -27911,10 +23436,10 @@ "@webassemblyjs/wasm-parser": "^1.14.1", "acorn": "^8.15.0", "acorn-import-phases": "^1.0.3", - "browserslist": "^4.28.1", + "browserslist": "^4.26.3", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.17.4", - "es-module-lexer": "^2.0.0", + "enhanced-resolve": "^5.17.3", + "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", @@ -27925,7 +23450,7 @@ "neo-async": "^2.6.2", "schema-utils": "^4.3.3", "tapable": "^2.3.0", - "terser-webpack-plugin": "^5.3.16", + "terser-webpack-plugin": "^5.3.11", "watchpack": "^2.4.4", "webpack-sources": "^3.3.3" }, @@ -27947,8 +23472,6 @@ }, "node_modules/webpack-bundle-analyzer": { "version": "4.10.2", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.2.tgz", - "integrity": "sha512-vJptkMm9pk5si4Bv922ZbKLV8UTT4zib4FPgXMhgzUny0bfDDkLXAVQs3ly3fS4/TN9ROFtb0NFrm04UXFE/Vw==", "license": "MIT", "dependencies": { "@discoveryjs/json-ext": "0.5.7", @@ -27973,8 +23496,6 @@ }, "node_modules/webpack-bundle-analyzer/node_modules/commander": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "license": "MIT", "engines": { "node": ">= 10" @@ -27982,8 +23503,6 @@ }, "node_modules/webpack-dev-middleware": { "version": "7.4.5", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.5.tgz", - "integrity": "sha512-uxQ6YqGdE4hgDKNf7hUiPXOdtkXvBJXrfEGYSx7P7LC8hnUYGK70X6xQXUvXeNyBDDcsiQXpG2m3G9vxowaEuA==", "license": "MIT", "dependencies": { "colorette": "^2.0.10", @@ -28011,14 +23530,10 @@ }, "node_modules/webpack-dev-middleware/node_modules/colorette": { "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "license": "MIT" }, "node_modules/webpack-dev-middleware/node_modules/mime-db": { "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -28026,8 +23541,6 @@ }, "node_modules/webpack-dev-middleware/node_modules/mime-types": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", - "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "license": "MIT", "dependencies": { "mime-db": "^1.54.0" @@ -28042,8 +23555,6 @@ }, "node_modules/webpack-dev-middleware/node_modules/range-parser": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -28051,8 +23562,6 @@ }, "node_modules/webpack-dev-server": { "version": "5.2.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.2.tgz", - "integrity": "sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==", "license": "MIT", "dependencies": { "@types/bonjour": "^3.5.13", @@ -28108,14 +23617,10 @@ }, "node_modules/webpack-dev-server/node_modules/colorette": { "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "license": "MIT" }, "node_modules/webpack-dev-server/node_modules/define-lazy-prop": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", "license": "MIT", "engines": { "node": ">=12" @@ -28126,8 +23631,6 @@ }, "node_modules/webpack-dev-server/node_modules/is-wsl": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", - "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", "license": "MIT", "dependencies": { "is-inside-container": "^1.0.0" @@ -28141,8 +23644,6 @@ }, "node_modules/webpack-dev-server/node_modules/open": { "version": "10.2.0", - "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", - "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", "license": "MIT", "dependencies": { "default-browser": "^5.2.1", @@ -28159,8 +23660,6 @@ }, "node_modules/webpack-dev-server/node_modules/ws": { "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -28180,8 +23679,6 @@ }, "node_modules/webpack-dev-server/node_modules/wsl-utils": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", - "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", "license": "MIT", "dependencies": { "is-wsl": "^3.1.0" @@ -28195,8 +23692,6 @@ }, "node_modules/webpack-merge": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", - "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", "license": "MIT", "dependencies": { "clone-deep": "^4.0.1", @@ -28209,8 +23704,6 @@ }, "node_modules/webpack-sources": { "version": "3.3.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", - "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", "license": "MIT", "engines": { "node": ">=10.13.0" @@ -28218,8 +23711,6 @@ }, "node_modules/webpack/node_modules/eslint-scope": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", @@ -28231,38 +23722,13 @@ }, "node_modules/webpack/node_modules/estraverse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, - "node_modules/webpack/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/webpack/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/webpackbar": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-6.0.1.tgz", - "integrity": "sha512-TnErZpmuKdwWBdMoexjio3KKX6ZtoKHRVvLIU0A47R0VVBDtx3ZyOJDktgYixhoJokZTYTt1Z37OkO9pnGJa9Q==", "license": "MIT", "dependencies": { "ansi-escapes": "^4.3.2", @@ -28283,14 +23749,10 @@ }, "node_modules/webpackbar/node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "license": "MIT" }, "node_modules/webpackbar/node_modules/markdown-table": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", - "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", "license": "MIT", "dependencies": { "repeat-string": "^1.0.0" @@ -28302,8 +23764,6 @@ }, "node_modules/webpackbar/node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -28316,8 +23776,6 @@ }, "node_modules/webpackbar/node_modules/wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -28333,8 +23791,6 @@ }, "node_modules/websocket-driver": { "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", "license": "Apache-2.0", "dependencies": { "http-parser-js": ">=0.5.1", @@ -28347,17 +23803,30 @@ }, "node_modules/websocket-extensions": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", "license": "Apache-2.0", "engines": { "node": ">=0.8.0" } }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/whatwg-url": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "license": "MIT", "dependencies": { "tr46": "~0.0.3", @@ -28366,8 +23835,6 @@ }, "node_modules/which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -28381,8 +23848,6 @@ }, "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==", "license": "MIT", "dependencies": { "is-bigint": "^1.1.0", @@ -28400,8 +23865,6 @@ }, "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==", "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -28427,14 +23890,10 @@ }, "node_modules/which-builtin-type/node_modules/isarray": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "license": "MIT" }, "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==", "license": "MIT", "dependencies": { "is-map": "^2.0.3", @@ -28451,8 +23910,6 @@ }, "node_modules/which-typed-array": { "version": "1.1.19", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", - "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", @@ -28472,8 +23929,6 @@ }, "node_modules/widest-line": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", - "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", "license": "MIT", "dependencies": { "string-width": "^5.0.1" @@ -28487,14 +23942,10 @@ }, "node_modules/wildcard": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", "license": "MIT" }, "node_modules/word-wrap": { "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -28502,15 +23953,11 @@ }, "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==", "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", @@ -28526,8 +23973,6 @@ }, "node_modules/wrap-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==", "license": "MIT", "engines": { "node": ">=12" @@ -28538,8 +23983,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">=12" @@ -28550,8 +23993,6 @@ }, "node_modules/wrap-ansi/node_modules/strip-ansi": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -28565,15 +24006,11 @@ }, "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": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, "license": "ISC", "dependencies": { @@ -28586,8 +24023,6 @@ }, "node_modules/ws": { "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "license": "MIT", "engines": { "node": ">=8.3.0" @@ -28607,8 +24042,6 @@ }, "node_modules/wsl-utils": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.3.0.tgz", - "integrity": "sha512-3sFIGLiaDP7rTO4xh3g+b3AzhYDIUGGywE/WsmqzJWDxus5aJXVnPTNC/6L+r2WzrwXqVOdD262OaO+cEyPMSQ==", "dev": true, "license": "MIT", "dependencies": { @@ -28624,8 +24057,6 @@ }, "node_modules/wsl-utils/node_modules/is-wsl": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", - "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", "dev": true, "license": "MIT", "dependencies": { @@ -28640,8 +24071,6 @@ }, "node_modules/xdg-basedir": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", - "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", "license": "MIT", "engines": { "node": ">=12" @@ -28652,8 +24081,6 @@ }, "node_modules/xml-js": { "version": "1.6.11", - "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", - "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", "license": "MIT", "dependencies": { "sax": "^1.2.4" @@ -28664,8 +24091,6 @@ }, "node_modules/xss": { "version": "1.0.15", - "resolved": "https://registry.npmjs.org/xss/-/xss-1.0.15.tgz", - "integrity": "sha512-FVdlVVC67WOIPvfOwhoMETV72f6GbW7aOabBC3WxN/oUdoEMDyLz4OgRv5/gck2ZeNqEQu+Tb0kloovXOfpYVg==", "license": "MIT", "dependencies": { "commander": "^2.20.3", @@ -28680,14 +24105,10 @@ }, "node_modules/xss/node_modules/commander": { "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "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==", "license": "ISC", "engines": { "node": ">=10" @@ -28695,14 +24116,10 @@ }, "node_modules/yallist": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "license": "ISC" }, "node_modules/yaml": { "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", "license": "ISC", "engines": { "node": ">= 6" @@ -28710,14 +24127,10 @@ }, "node_modules/yaml-ast-parser": { "version": "0.0.43", - "resolved": "https://registry.npmjs.org/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz", - "integrity": "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==", "license": "Apache-2.0" }, "node_modules/yargs": { "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "license": "MIT", "dependencies": { "cliui": "^8.0.1", @@ -28734,8 +24147,6 @@ }, "node_modules/yargs-parser": { "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "license": "ISC", "engines": { "node": ">=12" @@ -28743,14 +24154,10 @@ }, "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==", "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==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -28763,8 +24170,6 @@ }, "node_modules/yocto-queue": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "license": "MIT", "engines": { "node": ">=10" @@ -28774,19 +24179,14 @@ } }, "node_modules/zod": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.2.1.tgz", - "integrity": "sha512-0wZ1IRqGGhMP76gLqz8EyfBXKk0J2qo2+H3fi4mcUP/KtTocoX08nmIAHl1Z2kJIZbZee8KOpBCSNPRgauucjw==", + "version": "4.1.13", "license": "MIT", - "peer": true, "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==", "license": "MIT", "engines": { "node": ">=18.0.0" @@ -28797,8 +24197,6 @@ }, "node_modules/zwitch": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", "license": "MIT", "funding": { "type": "github", diff --git a/scripts/hooks/lint-node.sh b/scripts/hooks/lint-node.sh deleted file mode 100755 index 13c73682..00000000 --- a/scripts/hooks/lint-node.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -# Lint Node/TypeScript code with ESLint and Prettier - -REPO_ROOT="$(git rev-parse --show-toplevel)" -cd "$REPO_ROOT/hindsight-control-plane" - -echo " Linting Node/TS with ESLint and Prettier..." - -# Capture output and only show on failure -OUTPUT=$(npx eslint --fix "src/**/*.{ts,tsx}" 2>&1) -if [ $? -ne 0 ]; then - echo "$OUTPUT" - exit 1 -fi - -OUTPUT=$(npx prettier --write "src/**/*.{ts,tsx}" 2>&1) -if [ $? -ne 0 ]; then - echo "$OUTPUT" - exit 1 -fi - -echo " Node lint complete" diff --git a/scripts/hooks/lint-python.sh b/scripts/hooks/lint-python.sh deleted file mode 100755 index b42224ce..00000000 --- a/scripts/hooks/lint-python.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -# Lint Python code with Ruff - -REPO_ROOT="$(git rev-parse --show-toplevel)" -cd "$REPO_ROOT/hindsight-api" - -echo " Linting Python with Ruff..." - -# Capture output and only show on failure -OUTPUT=$(uv run ruff check --fix . 2>&1) -if [ $? -ne 0 ]; then - echo "$OUTPUT" - exit 1 -fi - -OUTPUT=$(uv run ruff format . 2>&1) -if [ $? -ne 0 ]; then - echo "$OUTPUT" - exit 1 -fi - -echo " Python lint complete" diff --git a/scripts/hooks/lint.sh b/scripts/hooks/lint.sh new file mode 100755 index 00000000..11b4566d --- /dev/null +++ b/scripts/hooks/lint.sh @@ -0,0 +1,76 @@ +#!/bin/bash +# Parallel linting for all code (Node, Python) +# Runs all linting tasks concurrently for faster execution + +set -e + +REPO_ROOT="$(git rev-parse --show-toplevel)" +TEMP_DIR=$(mktemp -d) +trap "rm -rf $TEMP_DIR" EXIT + +# Track all background jobs +declare -a PIDS +declare -a NAMES + +run_task() { + local name="$1" + local dir="$2" + shift 2 + local cmd="$@" + + ( + cd "$dir" + if OUTPUT=$($cmd 2>&1); then + echo "OK" > "$TEMP_DIR/$name.status" + else + echo "FAIL" > "$TEMP_DIR/$name.status" + echo "$OUTPUT" > "$TEMP_DIR/$name.output" + fi + ) & + PIDS+=($!) + NAMES+=("$name") +} + +echo " Running lints in parallel..." + +# Node/TypeScript tasks +run_task "eslint" "$REPO_ROOT/hindsight-control-plane" "npx eslint --fix src/**/*.{ts,tsx}" +run_task "prettier" "$REPO_ROOT/hindsight-control-plane" "npx prettier --write src/**/*.{ts,tsx}" + +# Python hindsight-api tasks +run_task "ruff-api-check" "$REPO_ROOT/hindsight-api" "uv run ruff check --fix ." +run_task "ruff-api-format" "$REPO_ROOT/hindsight-api" "uv run ruff format ." +run_task "ty-api" "$REPO_ROOT/hindsight-api" "uv run ty check hindsight_api" + +# Python hindsight-dev tasks +run_task "ruff-dev-check" "$REPO_ROOT/hindsight-dev" "uv run ruff check --fix ." +run_task "ruff-dev-format" "$REPO_ROOT/hindsight-dev" "uv run ruff format ." +run_task "ty-dev" "$REPO_ROOT/hindsight-dev" "uv run ty check hindsight_dev benchmarks" + +# Wait for all tasks to complete +for pid in "${PIDS[@]}"; do + wait "$pid" 2>/dev/null || true +done + +# Check results +FAILED=0 +for name in "${NAMES[@]}"; do + if [ -f "$TEMP_DIR/$name.status" ]; then + STATUS=$(cat "$TEMP_DIR/$name.status") + if [ "$STATUS" = "FAIL" ]; then + echo "" + echo " ❌ $name failed:" + cat "$TEMP_DIR/$name.output" + FAILED=1 + fi + else + echo " ❌ $name: no status (crashed?)" + FAILED=1 + fi +done + +if [ $FAILED -eq 1 ]; then + exit 1 +fi + +echo " All lints passed ✓" diff --git a/uv.lock b/uv.lock index 8f10908f..48bf0f54 100644 --- a/uv.lock +++ b/uv.lock @@ -1216,6 +1216,7 @@ dev = [ { name = "pytest-xdist" }, { name = "python-dotenv" }, { name = "ruff" }, + { name = "ty" }, ] [package.metadata] @@ -1265,6 +1266,7 @@ dev = [ { name = "pytest-xdist", specifier = ">=3.8.0" }, { name = "python-dotenv", specifier = ">=1.2.1" }, { name = "ruff", specifier = ">=0.8.0" }, + { name = "ty", specifier = ">=0.0.1" }, ] [[package]] @@ -1314,6 +1316,12 @@ dependencies = [ { name = "streamlit" }, ] +[package.dev-dependencies] +dev = [ + { name = "ruff" }, + { name = "ty" }, +] + [package.metadata] requires-dist = [ { name = "hindsight-api", editable = "hindsight-api" }, @@ -1324,6 +1332,12 @@ requires-dist = [ { name = "streamlit", specifier = ">=1.51.0" }, ] +[package.metadata.requires-dev] +dev = [ + { name = "ruff", specifier = ">=0.8.0" }, + { name = "ty", specifier = ">=0.0.1" }, +] + [[package]] name = "httpcore" version = "1.0.9" @@ -4266,6 +4280,31 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/78/eb/65f5ba83c2a123f6498a3097746607e5b2f16add29e36765305e4ac7fdd8/triton-3.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8182f42fd8080a7d39d666814fa36c5e30cc00ea7eeeb1a2983dbb4c99a0fdc", size = 209551444 }, ] +[[package]] +name = "ty" +version = "0.0.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9e/db/6299d478000f4f1c6f9bf2af749359381610ffc4cbe6713b66e436ecf6e7/ty-0.0.5.tar.gz", hash = "sha256:983da6330773ff71e2b249810a19c689f9a0372f6e21bbf7cde37839d05b4346", size = 4806218 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7c/98/c1f61ba378b4191e641bb36c07b7fcc70ff844d61be7a4bf2fea7472b4a9/ty-0.0.5-py3-none-linux_armv6l.whl", hash = "sha256:1594cd9bb68015eb2f5a3c68a040860f3c9306dc6667d7a0e5f4df9967b460e2", size = 9785554 }, + { url = "https://files.pythonhosted.org/packages/ab/f9/b37b77c03396bd779c1397dae4279b7ad79315e005b3412feed8812a4256/ty-0.0.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:7c0140ba980233d28699d9ddfe8f43d0b3535d6a3bbff9935df625a78332a3cf", size = 9603995 }, + { url = "https://files.pythonhosted.org/packages/7d/70/4e75c11903b0e986c0203040472627cb61d6a709e1797fb08cdf9d565743/ty-0.0.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:15de414712cde92048ae4b1a77c4dc22920bd23653fe42acaf73028bad88f6b9", size = 9145815 }, + { url = "https://files.pythonhosted.org/packages/89/05/93983dfcf871a41dfe58e5511d28e6aa332a1f826cc67333f77ae41a2f8a/ty-0.0.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:438aa51ad6c5fae64191f8d58876266e26f9250cf09f6624b6af47a22fa88618", size = 9619849 }, + { url = "https://files.pythonhosted.org/packages/82/b6/896ab3aad59f846823f202e94be6016fb3f72434d999d2ae9bd0f28b3af9/ty-0.0.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1b3d373fd96af1564380caf153600481c676f5002ee76ba8a7c3508cdff82ee0", size = 9606611 }, + { url = "https://files.pythonhosted.org/packages/ca/ae/098e33fc92330285ed843e2750127e896140c4ebd2d73df7732ea496f588/ty-0.0.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8453692503212ad316cf8b99efbe85a91e5f63769c43be5345e435a1b16cba5a", size = 10029523 }, + { url = "https://files.pythonhosted.org/packages/04/5a/f4b4c33758b9295e9aca0de9645deca0f4addd21d38847228723a6e780fc/ty-0.0.5-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:2e4c454139473abbd529767b0df7a795ed828f780aef8d0d4b144558c0dc4446", size = 10870892 }, + { url = "https://files.pythonhosted.org/packages/c3/c5/4e3e7e88389365aa1e631c99378711cf0c9d35a67478cb4720584314cf44/ty-0.0.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:426d4f3b82475b1ec75f3cc9ee5a667c8a4ae8441a09fcd8e823a53b706d00c7", size = 10599291 }, + { url = "https://files.pythonhosted.org/packages/c1/5d/138f859ea87bd95e17b9818e386ae25a910e46521c41d516bf230ed83ffc/ty-0.0.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5710817b67c6b2e4c0224e4f319b7decdff550886e9020f6d46aa1ce8f89a609", size = 10413515 }, + { url = "https://files.pythonhosted.org/packages/27/21/1cbcd0d3b1182172f099e88218137943e0970603492fb10c7c9342369d9a/ty-0.0.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e23c55ef08882c7c5ced1ccb90b4eeefa97f690aea254f58ac0987896c590f76", size = 10144992 }, + { url = "https://files.pythonhosted.org/packages/ad/30/fdac06a5470c09ad2659a0806497b71f338b395d59e92611f71b623d05a0/ty-0.0.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b9e4c1a28a23b14cf8f4f793f4da396939f16c30bfa7323477c8cc234e352ac4", size = 9606408 }, + { url = "https://files.pythonhosted.org/packages/09/93/e99dcd7f53295192d03efd9cbcec089a916f49cad4935c0160ea9adbd53d/ty-0.0.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:4e9ebb61529b9745af662e37c37a01ad743cdd2c95f0d1421705672874d806cd", size = 9630040 }, + { url = "https://files.pythonhosted.org/packages/d7/f8/6d1e87186e4c35eb64f28000c1df8fd5f73167ce126c5e3dd21fd1204a23/ty-0.0.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5eb191a8e332f50f56dfe45391bdd7d43dd4ef6e60884710fd7ce84c5d8c1eb5", size = 9754016 }, + { url = "https://files.pythonhosted.org/packages/28/e6/20f989342cb3115852dda404f1d89a10a3ce93f14f42b23f095a3d1a00c9/ty-0.0.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:92ed7451a1e82ee134a2c24ca43b74dd31e946dff2b08e5c34473e6b051de542", size = 10252877 }, + { url = "https://files.pythonhosted.org/packages/57/9d/fc66fa557443233dfad9ae197ff3deb70ae0efcfb71d11b30ef62f5cdcc3/ty-0.0.5-py3-none-win32.whl", hash = "sha256:71f6707e4c1c010c158029a688a498220f28bb22fdb6707e5c20e09f11a5e4f2", size = 9212640 }, + { url = "https://files.pythonhosted.org/packages/68/b6/05c35f6dea29122e54af0e9f8dfedd0a100c721affc8cc801ebe2bc2ed13/ty-0.0.5-py3-none-win_amd64.whl", hash = "sha256:2b8b754a0d7191e94acdf0c322747fec34371a4d0669f5b4e89549aef28814ae", size = 10034701 }, + { url = "https://files.pythonhosted.org/packages/df/ca/4201ed5cb2af73912663d0c6ded927c28c28b3c921c9348aa8d2cfef4853/ty-0.0.5-py3-none-win_arm64.whl", hash = "sha256:83bea5a5296caac20d52b790ded2b830a7ff91c4ed9f36730fe1f393ceed6654", size = 9566474 }, +] + [[package]] name = "typer" version = "0.20.0"