From 6bb918bad6832512c46dc51f56d0039635988067 Mon Sep 17 00:00:00 2001 From: alorig <220087330+alorig@users.noreply.github.com> Date: Fri, 21 Nov 2025 04:59:28 +0500 Subject: [PATCH] cleanup --- STAGE3_IMPLEMENTATION_SUMMARY.md | 120 - STAGE3_TEST_RESULTS.md | 115 - .../MIGRATION_RESET_PLAN.md | 0 .../SITE_BUILDER_WIZARD_REMOVAL_REFERENCE.md | 0 part2-dev/README.md | 35 - part2-dev/planning/01-strategy.md | 89 - part2-dev/planning/02-workflows.md | 127 - part2-dev/planning/03-phase-reports.md | 91 - part2-dev/planning/04-roadmap.md | 184 - .../PLANNING_DOCS_CONSOLIDATION_PLAN.md | 46 - .../DEPLOYMENT_GUIDE.md | 84 - .../SITE_BUILDER_AUDIT_REPORT.md | 240 - .../SITE_BUILDER_INTEGRATION_PLAN.md | 264 - .../SITE_BUILDER_URLS_AND_FILES.md | 139 - .../SITE_BUILDER_WORKFLOW_EXPLANATION.md | 65 - .../TEMPLATE_SYSTEM_EXPLANATION.md | 185 - refactor-plan/refactor-stage-2.md | 89 - refactor-plan/refactor-stage-3.md | 85 - refactor-plan/refactor-stage-4.md | 89 - site-builder/.gitignore | 24 - site-builder/Dockerfile.dev | 18 - site-builder/README.md | 73 - site-builder/eslint.config.js | 23 - site-builder/index.html | 13 - site-builder/package-lock.json | 6025 ----------------- site-builder/package.json | 42 - site-builder/public/vite.svg | 1 - site-builder/src/App.css | 330 - site-builder/src/App.tsx | 43 - site-builder/src/api/builder.api.ts | 86 - site-builder/src/api/system.api.ts | 27 - site-builder/src/assets/react.svg | 1 - site-builder/src/components/common/Card.css | 45 - site-builder/src/components/common/Card.tsx | 25 - .../src/components/common/ProgressModal.css | 118 - .../src/components/common/ProgressModal.tsx | 76 - .../components/shared/blocks/HeroBlock.tsx | 28 - .../components/shared/layouts/PageCanvas.css | 13 - .../components/shared/layouts/PageCanvas.tsx | 12 - .../src/components/shared/layouts/Section.css | 39 - .../src/components/shared/layouts/Section.tsx | 25 - site-builder/src/components/shared/theme.ts | 29 - site-builder/src/hooks/useTaskProgress.ts | 102 - site-builder/src/index.css | 28 - site-builder/src/main.tsx | 13 - .../src/pages/dashboard/SiteDashboard.tsx | 101 - .../src/pages/preview/PreviewCanvas.tsx | 353 - .../preview/__tests__/PreviewCanvas.test.tsx | 106 - site-builder/src/pages/wizard/WizardPage.tsx | 185 - .../wizard/__tests__/WizardPage.test.tsx | 187 - .../src/pages/wizard/steps/BriefStep.tsx | 28 - .../wizard/steps/BusinessDetailsStep.tsx | 94 - .../src/pages/wizard/steps/ObjectivesStep.tsx | 52 - .../src/pages/wizard/steps/StyleStep.tsx | 74 - site-builder/src/setupTests.ts | 9 - .../src/state/__tests__/builderStore.test.ts | 92 - .../__tests__/siteDefinitionStore.test.ts | 95 - site-builder/src/state/builderStore.ts | 227 - site-builder/src/state/siteDefinitionStore.ts | 28 - site-builder/src/types/siteBuilder.ts | 87 - site-builder/tsconfig.app.json | 31 - site-builder/tsconfig.json | 7 - site-builder/tsconfig.node.json | 26 - site-builder/vite.config.ts | 36 - 64 files changed, 11124 deletions(-) delete mode 100644 STAGE3_IMPLEMENTATION_SUMMARY.md delete mode 100644 STAGE3_TEST_RESULTS.md rename MIGRATION_RESET_PLAN.md => active-workflow-docs/MIGRATION_RESET_PLAN.md (100%) rename SITE_BUILDER_WIZARD_REMOVAL_REFERENCE.md => active-workflow-docs/SITE_BUILDER_WIZARD_REMOVAL_REFERENCE.md (100%) delete mode 100644 part2-dev/README.md delete mode 100644 part2-dev/planning/01-strategy.md delete mode 100644 part2-dev/planning/02-workflows.md delete mode 100644 part2-dev/planning/03-phase-reports.md delete mode 100644 part2-dev/planning/04-roadmap.md delete mode 100644 part2-dev/planning/PLANNING_DOCS_CONSOLIDATION_PLAN.md delete mode 100644 part2-dev/site-builder-docs-to-remove/DEPLOYMENT_GUIDE.md delete mode 100644 part2-dev/site-builder-docs-to-remove/SITE_BUILDER_AUDIT_REPORT.md delete mode 100644 part2-dev/site-builder-docs-to-remove/SITE_BUILDER_INTEGRATION_PLAN.md delete mode 100644 part2-dev/site-builder-docs-to-remove/SITE_BUILDER_URLS_AND_FILES.md delete mode 100644 part2-dev/site-builder-docs-to-remove/SITE_BUILDER_WORKFLOW_EXPLANATION.md delete mode 100644 part2-dev/site-builder-docs-to-remove/TEMPLATE_SYSTEM_EXPLANATION.md delete mode 100644 refactor-plan/refactor-stage-2.md delete mode 100644 refactor-plan/refactor-stage-3.md delete mode 100644 refactor-plan/refactor-stage-4.md delete mode 100644 site-builder/.gitignore delete mode 100644 site-builder/Dockerfile.dev delete mode 100644 site-builder/README.md delete mode 100644 site-builder/eslint.config.js delete mode 100644 site-builder/index.html delete mode 100644 site-builder/package-lock.json delete mode 100644 site-builder/package.json delete mode 100644 site-builder/public/vite.svg delete mode 100644 site-builder/src/App.css delete mode 100644 site-builder/src/App.tsx delete mode 100644 site-builder/src/api/builder.api.ts delete mode 100644 site-builder/src/api/system.api.ts delete mode 100644 site-builder/src/assets/react.svg delete mode 100644 site-builder/src/components/common/Card.css delete mode 100644 site-builder/src/components/common/Card.tsx delete mode 100644 site-builder/src/components/common/ProgressModal.css delete mode 100644 site-builder/src/components/common/ProgressModal.tsx delete mode 100644 site-builder/src/components/shared/blocks/HeroBlock.tsx delete mode 100644 site-builder/src/components/shared/layouts/PageCanvas.css delete mode 100644 site-builder/src/components/shared/layouts/PageCanvas.tsx delete mode 100644 site-builder/src/components/shared/layouts/Section.css delete mode 100644 site-builder/src/components/shared/layouts/Section.tsx delete mode 100644 site-builder/src/components/shared/theme.ts delete mode 100644 site-builder/src/hooks/useTaskProgress.ts delete mode 100644 site-builder/src/index.css delete mode 100644 site-builder/src/main.tsx delete mode 100644 site-builder/src/pages/dashboard/SiteDashboard.tsx delete mode 100644 site-builder/src/pages/preview/PreviewCanvas.tsx delete mode 100644 site-builder/src/pages/preview/__tests__/PreviewCanvas.test.tsx delete mode 100644 site-builder/src/pages/wizard/WizardPage.tsx delete mode 100644 site-builder/src/pages/wizard/__tests__/WizardPage.test.tsx delete mode 100644 site-builder/src/pages/wizard/steps/BriefStep.tsx delete mode 100644 site-builder/src/pages/wizard/steps/BusinessDetailsStep.tsx delete mode 100644 site-builder/src/pages/wizard/steps/ObjectivesStep.tsx delete mode 100644 site-builder/src/pages/wizard/steps/StyleStep.tsx delete mode 100644 site-builder/src/setupTests.ts delete mode 100644 site-builder/src/state/__tests__/builderStore.test.ts delete mode 100644 site-builder/src/state/__tests__/siteDefinitionStore.test.ts delete mode 100644 site-builder/src/state/builderStore.ts delete mode 100644 site-builder/src/state/siteDefinitionStore.ts delete mode 100644 site-builder/src/types/siteBuilder.ts delete mode 100644 site-builder/tsconfig.app.json delete mode 100644 site-builder/tsconfig.json delete mode 100644 site-builder/tsconfig.node.json delete mode 100644 site-builder/vite.config.ts diff --git a/STAGE3_IMPLEMENTATION_SUMMARY.md b/STAGE3_IMPLEMENTATION_SUMMARY.md deleted file mode 100644 index c5c0b674..00000000 --- a/STAGE3_IMPLEMENTATION_SUMMARY.md +++ /dev/null @@ -1,120 +0,0 @@ -# Stage 3 Implementation Summary - -## ✅ Completed Backend Features - -### 1. Database Schema & Migrations -- ✅ Added `entity_type`, `taxonomy`, `cluster_role` fields to Tasks model -- ✅ Created migration `0013_stage3_add_task_metadata.py` -- ✅ Updated backfill function in `0012_metadata_mapping_tables.py` to populate existing data - -### 2. Pipeline Updates -- ✅ **Ideas → Tasks**: Updated `ContentIdeasViewSet.bulk_queue_to_writer()` to inherit `entity_type`, `taxonomy`, `cluster_role` from Ideas -- ✅ **PageBlueprint → Tasks**: Updated `PageGenerationService._create_task_from_page()` to set metadata from blueprint -- ✅ **Tasks → Content**: Created `MetadataMappingService` to persist cluster/taxonomy mappings when Content is created - -### 3. Validation Services -- ✅ Created `ContentValidationService` with: - - `validate_task()` - Validates task metadata - - `validate_content()` - Validates content metadata - - `validate_for_publish()` - Comprehensive pre-publish validation - - `ensure_required_attributes()` - Checks required attributes per entity type - -### 4. Linker & Optimizer Enhancements -- ✅ **Linker**: Enhanced `CandidateEngine` to: - - Prioritize content from same clusters (50 points) - - Match by taxonomy (20 points) - - Match by entity type (15 points) - - Flag cluster/taxonomy matches in results - -- ✅ **Optimizer**: Enhanced `ContentAnalyzer` to: - - Calculate metadata completeness score (0-100) - - Check cluster/taxonomy mappings - - Include metadata score in overall optimization score (15% weight) - -### 5. API Endpoints -- ✅ `GET /api/v1/writer/content/{id}/validation/` - Get validation checklist -- ✅ `POST /api/v1/writer/content/{id}/validate/` - Re-run validators -- ✅ `GET /api/v1/site-builder/blueprints/{id}/progress/` - Cluster-level completion status - -### 6. Management Commands -- ✅ Created `audit_site_metadata` command: - - Usage: `python manage.py audit_site_metadata --site {id}` - - Shows metadata completeness per site - - Includes detailed breakdown with `--detailed` flag - -## ⚠️ Frontend Updates (Pending) - -### Writer UI Enhancements -- [ ] Add metadata columns to Content list (entity_type, cluster, taxonomy) -- [ ] Add validation panel to Content editor showing: - - Validation errors - - Metadata completeness indicators - - Publish button disabled until valid -- [ ] Display cluster/taxonomy chips in Content cards -- [ ] Add filters for entity_type and validation status - -### Linker UI Enhancements -- [ ] Group link suggestions by cluster role (hub → supporting, hub → attribute) -- [ ] Show cluster match indicators -- [ ] Display context snippets with cluster information - -### Optimizer UI Enhancements -- [ ] Add metadata scorecard to optimization dashboard -- [ ] Show cluster coverage indicators -- [ ] Display taxonomy alignment status -- [ ] Add "next action" cards for missing metadata - -## 📋 Next Steps - -1. **Run Migrations**: - ```bash - python manage.py migrate writer 0013_stage3_add_task_metadata - python manage.py migrate writer 0012_metadata_mapping_tables # Re-run to backfill - ``` - -2. **Test Backend**: - - Test Ideas → Tasks pipeline with metadata inheritance - - Test Content validation endpoints - - Test Linker/Optimizer with cluster mappings - - Run audit command: `python manage.py audit_site_metadata --site 5` - -3. **Frontend Implementation**: - - Update Writer Content list to show metadata - - Add validation panel to Content editor - - Enhance Linker/Optimizer UIs with cluster information - -## 🔧 Files Modified - -### Backend -- `backend/igny8_core/business/content/models.py` - Added metadata fields to Tasks -- `backend/igny8_core/modules/writer/migrations/0013_stage3_add_task_metadata.py` - New migration -- `backend/igny8_core/modules/writer/migrations/0012_metadata_mapping_tables.py` - Updated backfill -- `backend/igny8_core/modules/planner/views.py` - Updated Ideas→Tasks pipeline -- `backend/igny8_core/business/site_building/services/page_generation_service.py` - Updated PageBlueprint→Tasks -- `backend/igny8_core/business/content/services/metadata_mapping_service.py` - New service -- `backend/igny8_core/business/content/services/validation_service.py` - New service -- `backend/igny8_core/business/linking/services/candidate_engine.py` - Enhanced with cluster matching -- `backend/igny8_core/business/optimization/services/analyzer.py` - Enhanced with metadata scoring -- `backend/igny8_core/modules/writer/views.py` - Added validation endpoints -- `backend/igny8_core/modules/site_builder/views.py` - Added progress endpoint -- `backend/igny8_core/modules/writer/management/commands/audit_site_metadata.py` - New command - -## 🎯 Stage 3 Objectives Status - -| Objective | Status | -|-----------|--------| -| Metadata backfill | ✅ Complete | -| Ideas→Tasks pipeline | ✅ Complete | -| Tasks→Content pipeline | ✅ Complete | -| Validation services | ✅ Complete | -| Linker enhancements | ✅ Complete | -| Optimizer enhancements | ✅ Complete | -| API endpoints | ✅ Complete | -| Audit command | ✅ Complete | -| Frontend Writer UI | ⚠️ Pending | -| Frontend Linker UI | ⚠️ Pending | -| Frontend Optimizer UI | ⚠️ Pending | - -**Overall Stage 3 Backend: ~85% Complete** -**Overall Stage 3 Frontend: ~0% Complete** - diff --git a/STAGE3_TEST_RESULTS.md b/STAGE3_TEST_RESULTS.md deleted file mode 100644 index ffe8a110..00000000 --- a/STAGE3_TEST_RESULTS.md +++ /dev/null @@ -1,115 +0,0 @@ -# Stage 3 Test Results - -## ✅ Migration Tests - -### Migration Execution -```bash -✅ Migration 0012_metadata_mapping_tables: SUCCESS - - Backfill complete: - - Tasks entity_type updated: 0 - - Content entity_type updated: 0 - - Cluster mappings created: 10 - - Taxonomy mappings created: 0 - -✅ Migration 0013_stage3_add_task_metadata: SUCCESS - - Added entity_type, taxonomy, cluster_role fields to Tasks - - Added indexes for entity_type and cluster_role -``` - -## ✅ Backend API Tests - -### 1. Audit Command Test -```bash -$ python manage.py audit_site_metadata --site 5 - -✅ SUCCESS - Results: -📋 Tasks Summary: - Total Tasks: 11 - With Cluster: 11/11 (100%) - With Entity Type: 11/11 (100%) - With Taxonomy: 0/11 (0%) - With Cluster Role: 11/11 (100%) - -📄 Content Summary: - Total Content: 10 - With Entity Type: 10/10 (100%) - With Cluster Mapping: 10/10 (100%) - With Taxonomy Mapping: 0/10 (0%) - With Attributes: 0/10 (0%) - -⚠️ Gaps: - Tasks missing cluster: 0 - Tasks missing entity_type: 0 - Content missing cluster mapping: 0 -``` - -### 2. Validation Service Test -```python -✅ ContentValidationService.validate_content() - WORKING - - Correctly identifies missing cluster mapping - - Returns structured error: "Content must be mapped to at least one cluster" -``` - -### 3. API Endpoints (Ready for Testing) -- ✅ `GET /api/v1/writer/content/{id}/validation/` - Endpoint added -- ✅ `POST /api/v1/writer/content/{id}/validate/` - Endpoint added -- ✅ `GET /api/v1/site-builder/blueprints/{id}/progress/` - Endpoint added - -## ✅ Frontend Browser Tests - -### Pages Loaded Successfully -1. ✅ **Dashboard** (`/`) - Loaded successfully -2. ✅ **Writer Content** (`/writer/content`) - Loaded successfully - - API call: `GET /api/v1/writer/content/?site_id=9&page=1&page_size=10&ordering=-generated_at` - 200 OK -3. ✅ **Site Builder** (`/sites/builder`) - Loaded successfully -4. ✅ **Blueprints** (`/sites/blueprints`) - Loaded successfully - -### Console Status -- ✅ No JavaScript errors -- ✅ Vite connected successfully -- ✅ All API calls returning 200 status - -## 📊 Data Status - -### Current State -- **Tasks**: 11 total, all have clusters and entity_type -- **Content**: 10 total, all have entity_type and cluster mappings -- **Cluster Mappings**: 10 created successfully -- **Taxonomy Mappings**: 0 (expected - no taxonomies assigned yet) - -## 🎯 Stage 3 Backend Status: ✅ COMPLETE - -All backend features are implemented and tested: -- ✅ Database migrations applied -- ✅ Metadata fields added to Tasks -- ✅ Backfill completed (10 cluster mappings created) -- ✅ Validation service working -- ✅ API endpoints added -- ✅ Audit command working -- ✅ Linker/Optimizer enhancements complete - -## ⚠️ Frontend Status: Pending - -Frontend UI updates for Stage 3 are not yet implemented: -- ⚠️ Writer Content list - metadata columns not added -- ⚠️ Validation panel - not added to Content editor -- ⚠️ Linker UI - cluster-based suggestions not displayed -- ⚠️ Optimizer UI - metadata scorecards not displayed - -## 🔄 Next Steps - -1. **Test API Endpoints** (via browser/Postman): - - `GET /api/v1/writer/content/{id}/validation/` - - `POST /api/v1/writer/content/{id}/validate/` - - `GET /api/v1/site-builder/blueprints/{id}/progress/` - -2. **Create Test Blueprint** to test workflow wizard: - - Navigate to `/sites/builder` - - Create new blueprint - - Test workflow wizard at `/sites/builder/workflow/{blueprintId}` - -3. **Frontend Implementation** (when ready): - - Add metadata columns to Content list - - Add validation panel to Content editor - - Enhance Linker/Optimizer UIs - diff --git a/MIGRATION_RESET_PLAN.md b/active-workflow-docs/MIGRATION_RESET_PLAN.md similarity index 100% rename from MIGRATION_RESET_PLAN.md rename to active-workflow-docs/MIGRATION_RESET_PLAN.md diff --git a/SITE_BUILDER_WIZARD_REMOVAL_REFERENCE.md b/active-workflow-docs/SITE_BUILDER_WIZARD_REMOVAL_REFERENCE.md similarity index 100% rename from SITE_BUILDER_WIZARD_REMOVAL_REFERENCE.md rename to active-workflow-docs/SITE_BUILDER_WIZARD_REMOVAL_REFERENCE.md diff --git a/part2-dev/README.md b/part2-dev/README.md deleted file mode 100644 index 4a5364a4..00000000 --- a/part2-dev/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# Planning & Phase Documentation - -The Part 2 planning folder now uses four consolidated docs instead of many phase-specific files. Start here to understand where to look for strategy, workflows, history, and the active roadmap. - ---- - -## Consolidated Docs - -| Doc | Description | -| --- | --- | -| [`planning/01-strategy.md`](planning/01-strategy.md) | Platform context, architecture principles, module overview, security baseline. | -| [`planning/02-workflows.md`](planning/02-workflows.md) | End-to-end workflows for Planner, Site Builder, Ideas/Writer, Publishing, and credit usage. | -| [`planning/03-phase-reports.md`](planning/03-phase-reports.md) | Historical phase summaries, verification highlights, lessons learned. | -| [`planning/04-roadmap.md`](planning/04-roadmap.md) | Current execution roadmap, stages, milestones, dependencies, risks. | - -All former PHASE-*.md files, Igny8-part-2 plan, and implementation plans have been merged into these references (see git history if you need the raw originals). - ---- - -## How to Use -1. **Align on context** – read `01-strategy.md` to understand the architecture and goals. -2. **Review workflows** – `02-workflows.md` explains how Planner → Site Builder → Writer → Publishing connect. -3. **Learn from history** – `03-phase-reports.md` documents what’s been completed and verified. -4. **Plan execution** – `04-roadmap.md` lists active stages, milestones, and cross-team dependencies. - ---- - -## Status Tracking -- Keep this README and the four bundle docs updated as milestones shift. -- Any new planning artifact should extend one of the consolidated docs rather than creating a new standalone file. - ---- - -**Last Updated:** 2025-11-19 - diff --git a/part2-dev/planning/01-strategy.md b/part2-dev/planning/01-strategy.md deleted file mode 100644 index d8f10672..00000000 --- a/part2-dev/planning/01-strategy.md +++ /dev/null @@ -1,89 +0,0 @@ -# IGNY8 Phase 2 Strategy & Architecture - -## Purpose -Single reference for the “why” and “what” behind Phase 2, combining the original `ARCHITECTURE_CONTEXT.md` and the strategic sections of `IGNY8-HOLISTIC-ARCHITECTURE-PLAN.md`. Use this doc to align stakeholders before diving into workflows, phases, or roadmap specifics. - ---- - -## Executive Summary -- IGNY8 is a multi-tenant SaaS for SEO planning and AI content creation. Accounts own sites, sites contain sectors, and all planner/writer activity is scoped to that hierarchy. -- The refreshed strategy focuses on a **cluster-first planning engine**, **state-aware site builder**, and **shared metadata across Planner, Writer, Linker, Optimizer, and WordPress sync**. -- Platform foundations: Django 5.2 + DRF backend, React 19 frontend, PostgreSQL, Redis, Celery, Dockerized infra with Caddy reverse proxy. - -### Guiding Principles -1. **Multi-tenancy everywhere** – automatic account/site/sector scoping in models & viewsets. -2. **Configuration-driven UX** – shared templates, centralized API client, environment-configurable AI prompts. -3. **Unified AI engine** – all AI calls flow through `AIEngine` via Celery, with credit tracking and progress reporting. -4. **Stage-gated workflows** – users move through guided wizards (Planner → Site Builder → Writer → Publish) with clear prerequisites. - ---- - -## Architecture Overview -### Layers -| Layer | Responsibilities | -| --- | --- | -| **Client Apps** | Main SaaS app (`app.igny8`), marketing site, admin tooling. | -| **Reverse Proxy** | Caddy terminates TLS and routes traffic. | -| **Application Services** | React frontend (8021), Django backend (8011), Celery worker/beat. | -| **Data & Storage** | PostgreSQL, Redis, `/data/app/sites-data` for site deployments. | -| **External Integrations** | OpenAI/Runware for AI, WordPress for publishing, future Shopify. | - -### Module Snapshot -- **Planner**: Keywords, Clusters, Ideas, clustering AI. -- **Writer**: Tasks, Content, Images, AI generation, WordPress publishing. -- **Site Builder**: Blueprints, page scaffolding, deployment adapters. -- **System/Integration**: Settings, API keys, sync adapters. -- **Billing**: Credits, transactions, usage logs. - ---- - -## Data Hierarchy & Access -``` -Account → Site → Sector → (Keywords, Clusters, Ideas, Tasks, Content, Images) -``` -- Roles (`developer > owner > admin > editor > viewer > system_bot`) determine automatic access. -- Editors/Viewers require explicit `SiteUserAccess`. -- Middleware injects `request.account`; viewsets enforce scoping. - ---- - -## Key Workflows (High-Level) -1. **Account Setup** – create account/site/sector, configure integrations, assign roles. -2. **Planner** – import keywords, auto-cluster, attach clusters to site builder. -3. **Writer** – turn ideas into tasks, run AI content generation, manage reviews. -4. **Publishing** – deploy to IGNY8 renderer or sync to WordPress (future Shopify). - -Detailed mechanics live in `02-workflows.md`. - ---- - -## AI Framework Snapshot -- Entry point: `run_ai_task(function_name, payload, account_id)`. -- Six-phase pipeline (INIT → PREP → AI_CALL → PARSE → SAVE → DONE). -- Functions currently: `auto_cluster`, `generate_ideas`, `generate_content`, `generate_image_prompts`, `generate_images`. -- Credits deducted post-success; each function declares cost. - ---- - -## Security & Ops -- JWT auth with 15 min access / 7 day refresh, stored client-side. -- Role-based authorization on every request. -- Dockerized infra split between `igny8-infra` (Postgres, Redis, Caddy, etc.) and `igny8-app` (backend/frontend/worker). -- External services configured per account via Integration Settings. - ---- - -## Current Strategic Priorities -1. **Cluster-first planning** – enforce keyword clusters before site planning. -2. **Taxonomy-aware site builder** – blog/ecommerce/company flows with state-aware wizard. -3. **Unified content metadata** – propagate cluster/taxonomy data through writer, linker, optimizer, and publishing. -4. **WordPress parity** – treat synced WP sites as first-class citizens without duplicating site data. - ---- - -## References -- Detailed workflows: `02-workflows.md` -- Phase reports & learnings: `03-phase-reports.md` -- Execution roadmap: `04-roadmap.md` - - diff --git a/part2-dev/planning/02-workflows.md b/part2-dev/planning/02-workflows.md deleted file mode 100644 index 1745e071..00000000 --- a/part2-dev/planning/02-workflows.md +++ /dev/null @@ -1,127 +0,0 @@ -# IGNY8 Core Workflows & Systems - -Combines the previous `CONTENT-WORKFLOW-DIAGRAM.md`, sample credit usage notes, and scattered workflow descriptions into a single reference. - ---- - -## Table of Contents -1. Planner Workflows -2. Site Builder (State-Aware Wizard) -3. Ideas & Writer Pipeline -4. Publishing & Sync -5. Credit & Usage Examples - ---- - -## 1. Planner Workflows - -### Keyword Intake & Management -1. Import keywords via CSV/manual → validate intent, volume, difficulty. -2. Keywords inherit account/site/sector context; duplicates prevented via `seed_keyword` + site/sector constraint. -3. Filtering/searching available by status, intent, sector, cluster assignment. - -### Auto Clustering -``` -Keyword Selection → POST /planner/keywords/auto-cluster → -run_ai_task(auto_cluster) → AI groups keywords → -Clusters created + keywords linked → Credits deducted -``` -- Clusters now tagged with `context_type` (`topic`, `attribute`, `service_line`). -- Outputs recommendation metadata used by site builder taxonomy step. - -### Cluster Management -- Views show per-cluster metrics (keyword count, volume, gap warnings). -- Users can assign clusters to site blueprints; gating enforced before sitemap generation. - ---- - -## 2. Site Builder Workflow (Self-Guided Wizard) - -| Step | Requirements | Output | -| --- | --- | --- | -| 1. Business Details | Site + sector selected, site type (blog/ecom/company), hosting target (IGNY8 vs WP). | Draft `SiteBlueprint`, workflow state `business_details`. | -| 2. Cluster Assignment | ≥1 planner cluster linked; show coverage metrics. | `SiteBlueprintCluster` rows, state `clusters_ready`. | -| 3. Taxonomy Builder | Define/import categories, tags, product attributes, service groups; map to clusters. | `SiteBlueprintTaxonomy` records, state `taxonomies_ready`. | -| 4. AI Sitemap | Allowed only when clusters + taxonomies ready; AI generates pages w/ entity types + cluster refs. | `PageBlueprint` records, coverage matrix, state `sitemap_ready`. | -| 5. Coverage Validation | Confirm each cluster has hub/supporting pages; unresolved items block progress. | Approval flag, state `ideas_ready`. | -| 6. Ideas Hand-off | Selected pages pushed to Planner Ideas with optional guidance prompt. | Idea queue seeded, state `ideas_in_progress`. | - -Frontend enforcement: -- Zustand `builderWorkflowStore` tracks step state via `/site-builder/workflow/{id}`. -- Next buttons disabled until backend returns `step_status = complete`. -- Inline tooltips explain missing prerequisites, with links back to Planner. - ---- - -## 3. Ideas & Writer Pipeline - -### Ideas Creation -1. Wizard hand-off calls `POST /planner/content-ideas/bulk_from_blueprint`. -2. Each idea stores `cluster_id`, `taxonomy_id`, `site_entity_type`, `cluster_role`. -3. Ideas appear in Planner UI with badges showing target page type (blog post, product page, service page, taxonomy hub). - -### Task Generation -1. `PageGenerationService.generate_all_pages` turns ideas/pages into Writer tasks. -2. Tasks carry metadata: `entity_type`, `taxonomy_id`, `cluster_role`, `product_data` (JSON for specs), keywords. - -### AI Content Generation -``` -Task Selection → POST /writer/tasks/generate → -run_ai_task(generate_content) → AI produces html/json_blocks → -Content saved + linked to tasks → Linker/Optimizer receive metadata -``` -- Content also mapped to clusters/taxonomies via `ContentClusterMap` etc. -- Images workflow attaches prompts, usage context (featured, gallery, variant). - -### State Awareness -- Writer dashboards show per-site progress bars (e.g., “Cluster Alpha: 2/5 hubs published”). -- Editors cannot mark content ready unless required taxonomy/attribute data is filled. - ---- - -## 4. Publishing & Sync - -### IGNY8 Hosting -1. Deploy action triggers `SitesRendererAdapter`. -2. Adapter merges published `Content.json_blocks` into page definitions, writes to `/data/app/sites-data/clients/{site_id}/v{version}`. -3. Renderer serves `https://sites.igny8.com/{siteSlug}`; cluster/taxonomy metadata included for internal linking. - -### WordPress Sync -1. Integration settings tested via `WordPressAdapter.test_connection`. -2. Sync job (`ContentSyncService`) fetches WP taxonomies/posts/products, maps them to IGNY8 schemas via TaxonomyService. -3. Publishing back to WP reuses same metadata: categories/tags/attributes auto-created if missing, pages matched by external IDs. -4. Workflow enforces cluster assignment for imported content before allowing optimization tasks. - ---- - -## 5. Credit & Usage Examples - -| Operation | Trigger | Credit Cost | Notes | -| --- | --- | --- | --- | -| Auto Cluster | Planner keywords | 1 credit / 30 keywords | Minimum 1 credit per request. | -| Idea Generation | Cluster selection | 1 credit / idea | Charged when ideas created. | -| Content Generation | Writer tasks | 3 credits / content | Includes HTML + structured blocks. | -| Image Generation | Image tasks | 1 credit / image | Prompt extraction included in content gen. | -| Re-optimization | Optimizer rerun | 1 credit / rerun | Optional step for existing content. | - -Credits deducted post-success via `CreditService`. Usage logs available under Billing > Usage. - ---- - -## Credit-Only Operating Principles -- Subscription plans only define credit refills + support tier; every feature stays unlocked. -- No per-plan limits (keywords, clusters, tasks, images, sites, users, etc.); credits are the sole limiter. -- Actions check credit balance before running; insufficient credits show a blocking warning with CTA to top up. -- Frontend should always show remaining credits + estimated cost before execution. -- Credits must be purchasable on-demand, with logs + notifications when balances are low. - -These principles come from the former “sample usage limits & credit system” note and govern all future modules. - ---- - -## Cross-References -- Strategy & architecture context: `01-strategy.md` -- Phase-specific learnings & QA logs: `03-phase-reports.md` -- Execution roadmap & milestones: `04-roadmap.md` - - diff --git a/part2-dev/planning/03-phase-reports.md b/part2-dev/planning/03-phase-reports.md deleted file mode 100644 index 017aca15..00000000 --- a/part2-dev/planning/03-phase-reports.md +++ /dev/null @@ -1,91 +0,0 @@ -# Phase & Verification Reports (Consolidated) - -This document replaces the individual PHASE-*.md files and verification reports. Use it to review historical execution, QA findings, and lessons learned. - ---- - -## Table of Contents -1. Phase Timeline Overview -2. Phase Details - - Phases 0–4: Foundation to Linker/Optimizer - - Phases 5–7–9: Sites Renderer & UI Integration - - Phase 8: Universal Content Types -3. Verification & Migration Reports -4. Key Lessons & Follow-Ups - ---- - -## 1. Phase Timeline Overview - -| Phase | Focus | Status | Highlights | -| --- | --- | --- | --- | -| 0 | Environment & infra readiness | ✅ Complete | Docker stacks, CI hooks, base monitoring. | -| 1 | Core planner foundations | ✅ Complete | Keywords import, clustering MVP, credit accounting. | -| 2 | Writer baseline | ✅ Complete | Task pipeline, AI content generation, WordPress adapter stub. | -| 3 | Automation & Thinker modules | ✅ Complete | Prompt registry, author profiles, AI config UI. | -| 4 | Linker & Optimizer foundations | ✅ Complete | Internal linking prototype, optimization scoring. | -| 5 | Site builder migration + renderer sync | ✅ Complete | Blueprint models, renderer integration, deployment flow. | -| 6 | UI polish & dashboard alignment | ✅ Complete | Unified design system, navigation updates. | -| 7 | Sites preview & publisher UX | ✅ Complete | Blueprint preview, publish states, progress indicators. | -| 8 | Universal Content Types (UCT) | ✅ Complete | Entity types, structured blocks, taxonomy groundwork. | -| 9 | Final renderer alignment & QA | ✅ Complete | Deployment validation, edge-case fixing. | - ---- - -## 2. Phase Details - -### Phases 0–4: Foundation to Linker/Optimizer -- **Infra Setup:** Split `igny8-infra` vs `igny8-app`, network hardening, secrets management. -- **Planner Enhancements:** CSV import, dedupe logic, clustering UI, integration with billing. -- **Writer MVP:** Task creation from ideas, Celery-driven AI content, HTML editor baseline. -- **AI Framework:** `AIEngine`, function registry, standardized progress reporting. -- **Linker & Optimizer:** Early scoring model, automatic anchor suggestion pipeline, storage for link graphs. - -### Phases 5–7–9: Sites Renderer & UI Integration -- **Site Builder Migration:** Blueprint CRUD, page generation, deployment service writing to `/sites-data`. -- **Renderer Alignment:** Public site routes, navigation auto-generation, content fallback behavior. -- **UI Alignment:** Builder wizard moved into main frontend, state managed via new stores, progress modals. -- **Publishing Workflow:** Deploy button gating, deployment logs, error surfacing. - -### Phase 8: Universal Content Types -- Introduced `entity_type`, `json_blocks`, `structure_data` on `Content`. -- Added mapping tables for clusters/taxonomies (foundation for current architecture). -- Updated Writer UI to show entity context; prepared for ecommerce/service content. - ---- - -## 3. Verification & Migration Reports - -### Implementation Verification (condensed from `PHASE-IMPLEMENTATION-VERIFICATION-REPORT.md`) -- **Database**: Ensured migrations applied for planner, writer, site builder, UCT tables. -- **Async Stack**: Verified Redis/Celery worker/beat running; failover mode documented. -- **APIs**: Regression-tested planner/writer endpoints, new blueprint actions, publisher endpoints. -- **Front-End**: Smoke tests on navigation, wizard steps, planner → writer transitions. - -### Phase 5 Migration Reports -- Confirmed blueprint tables, metadata seeds, and renderer outputs after migration. -- Validated WordPress adapter still reachable; flagged missing taxonomy sync (addressed in new plan). - -### Final Verification -- Deployment smoke test across multiple site types. -- Cross-checked credit deductions vs usage logs. -- QA sign-off captured with issue follow-ups (see next section). - ---- - -## 4. Key Lessons & Follow-Ups -1. **State Awareness Needed** – Users struggled with knowing “what’s next”; resolved via new wizard gating plan. -2. **Taxonomy Gaps** – Ecommerce/service taxonomies were ad-hoc; led to current blueprint taxonomy initiative. -3. **WordPress Sync Depth** – Publishing worked but taxonomy/product sync missing; prioritized in new roadmap. -4. **Monitoring** – Need better visibility into AI task queues; future work: add metrics dashboards tied to Celery and credits. - -Outstanding actions now captured in `04-roadmap.md`. - ---- - -## References -- Strategy context: `01-strategy.md` -- Operational workflows: `02-workflows.md` -- Execution roadmap & milestones: `04-roadmap.md` - - diff --git a/part2-dev/planning/04-roadmap.md b/part2-dev/planning/04-roadmap.md deleted file mode 100644 index 8e7f0393..00000000 --- a/part2-dev/planning/04-roadmap.md +++ /dev/null @@ -1,184 +0,0 @@ -# IGNY8 Phase 2 Roadmap & Implementation Plan - -Consolidates `Igny8-part-2-plan.md` and `IGNY8-IMPLEMENTATION-PLAN.md` into a single execution roadmap. - ---- - -## 1. Roadmap Overview - -### Strategic Themes -1. **Planner Modernization** – richer clustering, taxonomy seeding, keyword governance. -2. **Site Builder Evolution** – guided wizard, taxonomy-aware sitemap generation, blueprint ↔ planner sync. -3. **Writer & Optimization Depth** – metadata propagation, product/service support, auto-linking improvements. -4. **Publishing & Sync** – IGNY8 deployments + full WordPress parity (taxonomies, products, attributes). - -### Stage Rollout -| Stage | Focus | Target Outcome | -| --- | --- | --- | -| Stage 1 | Data & services foundation | New schema, clustering upgrades, workflow state APIs. | -| Stage 2 | Planner + Wizard UX | State-aware wizard, taxonomy builder, planner UI refresh. | -| Stage 3 | Writer / Linker / Optimizer | Metadata-aware tasks/content, improved linking & scoring. | -| Stage 4 | Publishing & Sync | WordPress taxonomy sync, deployment polish, QA. | - ---- - -## 2. Detailed Workstream Breakdown - -### Workstream A – Data & Services -- Apply migrations for blueprint clusters/taxonomies, writer mapping tables. -- Implement `WorkflowStateService`, validation endpoints, TaxonomyService. -- Upgrade clustering prompt/service for multi-dimensional outputs. -- Update API serializers to expose entity metadata. - -### Workstream B – Planner & Wizard UX -- New planner views for clusters/taxonomies with matrix visualization. -- Wizard steps (business, clusters, taxonomy, sitemap, validation, hand-off) with gating logic. -- Toasts/tooltips/inline helpers to keep users oriented. -- Resume capability (persisted step state). - -### Workstream C – Writer, Linker, Optimizer -- Extend ideas/tasks/content editors with cluster/taxonomy context panels. -- Enforce validation (no publish without assigned taxonomy/attributes). -- Linker suggestions grouped by cluster role; optimizer scoring for coverage. -- Progress dashboards per site/cluster. - -### Workstream D – Publishing & Sync -- Finish WordPress taxonomy + product attribute sync (bi-directional). -- Update deployment adapters to honor new metadata; ensure renderer reads cluster/taxonomy info. -- Provide sync dashboards with health indicators, last sync timestamps. -- Final regression + staging sign-off. - ---- - -## 3. Milestones & Deliverables - -| Milestone | Key Deliverables | Dependencies | -| --- | --- | --- | -| M1 – Schema Ready | Migrations merged, services deployed, API docs updated. | None. | -| M2 – Guided Planner & Wizard | New UI flows live behind feature flag, analytics instrumented. | M1. | -| M3 – Metadata-Driven Writer | Writer/linker/optimizer using new relations, validation in place. | M2. | -| M4 – Publish & Sync Alpha | WordPress sync parity, deployment QA, release notes. | M3. | - -Each milestone includes QA checklist, documentation update (master-docs + in-app help), and telemetry validation. - ---- - -## 4. Dependencies & Risks -- **Redis/Celery availability** – AI flows block if infra not running; ensure monitoring. -- **Migration coordination** – new tables touched by multiple services; schedule maintenance window. -- **WordPress API variance** – taxonomy/product endpoints vary by site; need robust error handling + manual override UI. -- **User learning curve** – wizard adds structure; include onboarding tips and inline docs. - -Mitigations described in `02-workflows.md` (UX guardrails) and `03-phase-reports.md` (lessons learned). - ---- - -## 5. Communication & Tracking -- Maintain status in `part2-dev/README.md` with links to this roadmap. -- Sprint boards map tasks back to stage/milestone. -- Release notes reference doc IDs here for posterity. - ---- - -## References -- Strategy context: `01-strategy.md` -- Detailed workflows: `02-workflows.md` -- Historical reports: `03-phase-reports.md` - ---- - -## 6. Stage Implementation Details - -### Stage 1 – Data & Services Foundation -**Goal:** Ship all schema + backend building blocks so later stages can focus on UX. - -**Backend** -- Migrations for `SiteBlueprintCluster`, `SiteBlueprintTaxonomy`, `WorkflowState`, writer mapping tables. -- `WorkflowStateService` with REST endpoints for fetching/updating step status. -- `TaxonomyService` (CRUD/import/export) and `ClusteringService` prompt upgrade for multi-dimensional clusters. -- API validation hooks (`validate_clusters_attached`, `validate_taxonomies_ready`, etc.) consumed by wizard gating. -- Serializer updates exposing entity metadata to frontend. - -**Frontend** -- Minimal work (feature flags + API clients) to prepare for new endpoints; no user-facing change yet. - -**Testing/Acceptance** -- Migration dry run, rollback verified. -- Unit/integration tests for services and validators. -- API documentation updated; Postman suite green. - -### Stage 2 – Planner + Wizard UX -**Goal:** Deliver the guided, state-aware planning experience. - -**Backend** -- Ensure planner endpoints return cluster metrics, taxonomy suggestions, validation errors. -- Audit logging for workflow transitions. - -**Frontend** -- Implement `builderWorkflowStore` (Zustand) with resume capability, blocking logic, telemetry. -- Build wizard steps: - 1. Business details + hosting detection. - 2. Cluster assignment (coverage metrics, filters). - 3. Taxonomy builder (create/import/match clusters). - 4. AI sitemap review with checklist + edits. - 5. Coverage validation summary. - 6. Ideas hand-off with secondary prompt. -- Update planner cluster/taxonomy management screens (matrix view, inline warnings). - -**UX Guardrails** -- Progress indicator with completion badges. -- Disabled buttons explain “what’s missing”. -- CTAs back to Planner when prerequisites unmet. - -**Testing/Acceptance** -- Manual script for full wizard flow (new IGNY8 site + WP-linked site). -- Cypress/e2e coverage for gating + resume behavior. -- Telemetry events for step completion firing. - -### Stage 3 – Writer / Linker / Optimizer Enhancements -**Goal:** Propagate metadata end-to-end and enforce validation. - -**Backend** -- Ensure ideas/tasks/content writer pipeline populates `entity_type`, `taxonomy_id`, `cluster_role`, `product_data`. -- Linker/optimizer services consume mapping tables and expose coverage metrics via APIs. -- Progress dashboard endpoints (per site/cluster) for frontend widgets. - -**Frontend** -- Planner Ideas + Writer Tasks lists show entity/taxonomy chips and warnings. -- Writer editor sidebar summarizing target cluster, taxonomy, attribute requirements; validation prompts before publish. -- Linker UI grouped by cluster role; Optimizer dashboards show dimension scorecards and “next actions”. -- Sites module progress bars summarizing blueprint completion. - -**Testing/Acceptance** -- Regression on task/content creation flows. -- QA verifies publish blocked when metadata missing. -- Performance profiling on linker/optimizer queries with new joins. - -### Stage 4 – Publishing & Sync Integration -**Goal:** Achieve parity between IGNY8-hosted and WordPress-hosted sites. - -**Backend** -- Complete WordPress taxonomy/product attribute import/export in `ContentSyncService`. -- Enhance `SitesRendererAdapter` to include cluster/taxonomy metadata for navigation + internal linking. -- Sync health endpoints (last sync, mismatched taxonomies, errors) and deployment logs/rollback hooks. - -**Frontend** -- Sync dashboard showing taxonomy parity, cluster coverage, last sync status, manual retry/reconcile actions. -- Deployment panel summarizing readiness (clusters covered, content publish state) before enabling deploy. -- Notifications/toasts for sync success/failure and deployments. - -**Testing/Acceptance** -- End-to-end tests: IGNY8 deployment, WP publish for posts/products/services (blog/ecom/company templates). -- Fallback behavior validated (auto-creating missing taxonomies). -- Final QA checklist signed off; release notes + training updates distributed. - ---- - -## 7. Stage Exit Criteria - -| Stage | Exit Criteria | -| --- | --- | -| 1 | Migrations live, services stable, existing Planner/Writer flows unaffected, docs updated. | -| 2 | Wizard fully usable with telemetry + QA sign-off; planner UIs reflect new taxonomy data. | -| 3 | Writer/linker/optimizer using metadata, publishing blocked without required info, dashboards live. | -| 4 | WordPress parity achieved, deployments verified, sync dashboards green, release announced. | diff --git a/part2-dev/planning/PLANNING_DOCS_CONSOLIDATION_PLAN.md b/part2-dev/planning/PLANNING_DOCS_CONSOLIDATION_PLAN.md deleted file mode 100644 index f8659865..00000000 --- a/part2-dev/planning/PLANNING_DOCS_CONSOLIDATION_PLAN.md +++ /dev/null @@ -1,46 +0,0 @@ -# Planning Docs Consolidation Plan - -## 1. Inventory & Tags - -| File | Scope | Notes | -| --- | --- | --- | -| `planning/ARCHITECTURE_CONTEXT.md` | Contextual overview of Part 2 goals, stakeholders, constraints. | High-level reference. | -| `planning/CONTENT-WORKFLOW-DIAGRAM.md` | Detailed content lifecycle diagrams + descriptions. | Visual/text workflow. | -| `planning/sample-usage-limits-credit-system` | Legacy notes on credit usage examples. | Likely merge into workflows appendix. | -| `IGNY8-HOLISTIC-ARCHITECTURE-PLAN.md` | Comprehensive architecture narrative (cross-domain). | Overlaps with strategy sections. | -| `IGNY8-IMPLEMENTATION-PLAN.md` | Detailed step-by-step implementation roadmap. | Overlaps with roadmap bundle. | -| `Igny8-part-2-plan.md` | Program-level planning doc with milestones. | Should anchor roadmap bundle. | -| `PHASE-0-4-FOUNDATION-TO-LINKER-OPTIMIZER.md` | Phase-specific execution report for early phases. | Belongs in phase reports bundle. | -| `PHASE-5-7-9-SITES-RENDERER-INTEGRATION-UI.md` | Later phase report (sites renderer, UI). | Phase reports bundle. | -| `PHASE-8-UNIVERSAL-CONTENT-TYPES.md` | Focused phase doc on UCT. | Phase reports bundle. | -| `PHASE-IMPLEMENTATION-VERIFICATION-REPORT.md` | Consolidated verification results. | Phase reports bundle. | -| `PHASE-5-MIGRATION-VERIFICATION-REPORT.md` | Specific verification log. | Phase reports bundle (appendix). | -| `PHASE-5-MIGRATION-FINAL-VERIFICATION.md` | Final pass notes. | Combine with verification. | -| `README.md` | Folder guidance. | Needs update after consolidation. | - -## 2. Target Bundles - -| Bundle | New File | Contents | -| --- | --- | --- | -| Strategy & Architecture | `planning/01-strategy.md` | Merge `ARCHITECTURE_CONTEXT.md` + relevant sections from `IGNY8-HOLISTIC-ARCHITECTURE-PLAN.md`. | -| Workflows & Systems | `planning/02-workflows.md` | Combine `CONTENT-WORKFLOW-DIAGRAM.md`, sample credit usage appendix, excerpts describing planner/writer/site builder alignment (pull from holistic plan where needed). | -| Phase & Verification Reports | `planning/03-phase-reports.md` | Consolidate all PHASE* docs + implementation verification into chronological sections with TOC anchors. | -| Roadmap & Implementation | `planning/04-roadmap.md` | Merge `Igny8-part-2-plan.md` + `IGNY8-IMPLEMENTATION-PLAN.md`, highlight milestones/stage gates. | - -## 3. Merge & Cross-Link Plan -1. Create the four new bundle files with clear TOCs. -2. For each source doc, move content into appropriate section, preserving headings. -3. Add cross-links between bundles (e.g., roadmap references strategy section anchors). -4. Update `README.md` to describe new structure and point to bundle docs. - -## 4. Cleanup Tasks -- Archive or delete superseded source files once content is moved (keep git history). -- Update any references in other docs (`master-docs`, repo README, etc.) to point to the new bundle filenames. -- Verify diagrams/images still referenced correctly (adjust paths if needed). - -## Next Steps -1. Approve bundle structure (or adjust naming). -2. Execute merges in order: strategy → workflows → phase reports → roadmap. -3. Run lint/format checks on updated markdown. - - diff --git a/part2-dev/site-builder-docs-to-remove/DEPLOYMENT_GUIDE.md b/part2-dev/site-builder-docs-to-remove/DEPLOYMENT_GUIDE.md deleted file mode 100644 index c46af8b4..00000000 --- a/part2-dev/site-builder-docs-to-remove/DEPLOYMENT_GUIDE.md +++ /dev/null @@ -1,84 +0,0 @@ -# Site Deployment Guide - -## How Site Deployment Works - -### Overview -When you deploy a site blueprint, the system: -1. Builds a site definition (merging Content from Writer into PageBlueprint blocks) -2. Writes it to the filesystem at `/data/app/sites-data/clients/{site_id}/v{version}/` -3. The Sites Renderer reads from this filesystem to serve the public site - -### Deployment Process - -#### Step 1: Prepare Your Site -1. **Generate Structure**: Create site blueprint with pages (has placeholder blocks) -2. **Generate Content**: Pages → Tasks → Content (Writer generates real content) -3. **Publish Content**: In Content Manager, set Content status to `'publish'` for each page -4. **Publish Pages**: In Page Manager, set Page status to `'published'` (for navigation) - -#### Step 2: Deploy the Blueprint -**API Endpoint**: `POST /api/v1/publisher/deploy/{blueprint_id}/` - -**What Happens**: -- `SitesRendererAdapter.deploy()` is called -- For each page, it finds the associated Writer Task -- If Content exists and is published, it uses `Content.json_blocks` instead of blueprint placeholders -- Builds complete site definition with all pages -- Writes to filesystem: `/data/app/sites-data/clients/{site_id}/v{version}/site.json` -- Creates deployment record - -#### Step 3: Access Your Site -**Public URL**: `https://sites.igny8.com/{siteSlug}` - -**How It Works**: -- Sites Renderer loads site definition from filesystem (or API fallback) -- Shows navigation menu with all published pages -- Home route (`/siteSlug`) shows only home page content -- Page routes (`/siteSlug/pageSlug`) show specific page content - -### Navigation Menu - -The navigation menu automatically includes: -- **Home** link (always shown) -- All pages with status `'published'` or `'ready'` (excluding home) -- Pages are sorted by their `order` field - -### Page Routing - -- **Homepage**: `https://sites.igny8.com/{siteSlug}` → Shows home page only -- **Individual Pages**: `https://sites.igny8.com/{siteSlug}/{pageSlug}` → Shows that specific page - - Example: `https://sites.igny8.com/auto-g8/products` - - Example: `https://sites.igny8.com/auto-g8/blog` - -### Content Merging - -When deploying: -- **If Content is published**: Uses `Content.json_blocks` (actual written content) -- **If Content not published**: Uses `PageBlueprint.blocks_json` (placeholder blocks) -- **Content takes precedence**: Published Content always replaces blueprint placeholders - -### Important Notes - -1. **Two Statuses**: - - `PageBlueprint.status = 'published'` → Controls page visibility in navigation - - `Content.status = 'publish'` → Controls which content is used (real vs placeholder) - -2. **Redeploy Required**: After publishing Content, you must **redeploy** the site for changes to appear - -3. **All Pages Deployed**: The deployment includes ALL pages from the blueprint, but only published pages show in navigation - -4. **Navigation Auto-Generated**: If no explicit navigation is set in blueprint, it auto-generates from published pages - -### Troubleshooting - -**Problem**: Navigation only shows "Home" -- **Solution**: Make sure other pages have status `'published'` or `'ready'` in Page Manager - -**Problem**: Pages show placeholder content instead of real content -- **Solution**: - 1. Check Content status is `'publish'` in Content Manager - 2. Redeploy the site blueprint - -**Problem**: Pages not accessible via URL -- **Solution**: Make sure pages have status `'published'` or `'ready'` and the site is deployed - diff --git a/part2-dev/site-builder-docs-to-remove/SITE_BUILDER_AUDIT_REPORT.md b/part2-dev/site-builder-docs-to-remove/SITE_BUILDER_AUDIT_REPORT.md deleted file mode 100644 index a608dee2..00000000 --- a/part2-dev/site-builder-docs-to-remove/SITE_BUILDER_AUDIT_REPORT.md +++ /dev/null @@ -1,240 +0,0 @@ -# Site Builder & AI Functions - Comprehensive Audit Report - -## Executive Summary -This audit identifies all requirements, dependencies, and gaps for the Site Builder functionality and related AI generation features. The primary issues are: -1. **Database migrations not applied** - Site builder tables don't exist -2. **Redis/Celery not running** - AI tasks can't execute asynchronously -3. All code components are present and properly configured - ---- - -## Requirements Audit Table - -| Category | Component | Requirement | Status | Location/Notes | Action Required | -|----------|-----------|-------------|--------|----------------|-----------------| -| **Database** | Migrations | `0001_initial.py` - SiteBlueprint, PageBlueprint tables | ✅ EXISTS | `backend/igny8_core/business/site_building/migrations/0001_initial.py` | ❌ **NOT APPLIED** - Run migrations | -| **Database** | Migrations | `0002_sitebuilder_metadata.py` - BusinessType, AudienceProfile, BrandPersonality, HeroImageryDirection | ✅ EXISTS | `backend/igny8_core/business/site_building/migrations/0002_sitebuilder_metadata.py` | ❌ **NOT APPLIED** - Run migrations | -| **Database** | Table | `igny8_site_blueprints` | ❌ MISSING | Should be created by 0001_initial.py | Run `python manage.py migrate site_building` | -| **Database** | Table | `igny8_page_blueprints` | ❌ MISSING | Should be created by 0001_initial.py | Run `python manage.py migrate site_building` | -| **Database** | Table | `igny8_site_builder_business_types` | ❌ MISSING | Should be created by 0002_sitebuilder_metadata.py | Run `python manage.py migrate site_building` | -| **Database** | Table | `igny8_site_builder_audience_profiles` | ❌ MISSING | Should be created by 0002_sitebuilder_metadata.py | Run `python manage.py migrate site_building` | -| **Database** | Table | `igny8_site_builder_brand_personalities` | ❌ MISSING | Should be created by 0002_sitebuilder_metadata.py | Run `python manage.py migrate site_building` | -| **Database** | Table | `igny8_site_builder_hero_imagery` | ❌ MISSING | Should be created by 0002_sitebuilder_metadata.py | Run `python manage.py migrate site_building` | -| **Database** | Seed Data | Business types, audience profiles, brand personalities, hero imagery | ✅ DEFINED | Migration 0002 includes `seed_site_builder_metadata()` function | Will seed automatically when migration runs | -| **App Config** | Django App | `igny8_core.business.site_building.apps.SiteBuildingConfig` | ✅ REGISTERED | `backend/igny8_core/settings.py:55` | No action needed | -| **App Config** | Django App | `igny8_core.modules.site_builder.apps.SiteBuilderConfig` | ✅ REGISTERED | `backend/igny8_core/settings.py:59` | No action needed | -| **Models** | SiteBlueprint | Model with all fields (name, description, config_json, structure_json, status, hosting_type, version) | ✅ EXISTS | `backend/igny8_core/business/site_building/models.py:10-83` | No action needed | -| **Models** | PageBlueprint | Model with all fields (site_blueprint, slug, title, type, blocks_json, status, order) | ✅ EXISTS | `backend/igny8_core/business/site_building/models.py:85-166` | No action needed | -| **Models** | BusinessType | Model extending SiteBuilderOption | ✅ EXISTS | `backend/igny8_core/business/site_building/models.py:189-194` | No action needed | -| **Models** | AudienceProfile | Model extending SiteBuilderOption | ✅ EXISTS | `backend/igny8_core/business/site_building/models.py:197-202` | No action needed | -| **Models** | BrandPersonality | Model extending SiteBuilderOption | ✅ EXISTS | `backend/igny8_core/business/site_building/models.py:205-210` | No action needed | -| **Models** | HeroImageryDirection | Model extending SiteBuilderOption | ✅ EXISTS | `backend/igny8_core/business/site_building/models.py:213-218` | No action needed | -| **Services** | StructureGenerationService | Service to trigger AI structure generation | ✅ EXISTS | `backend/igny8_core/business/site_building/services/structure_generation_service.py` | No action needed | -| **Services** | PageGenerationService | Service to generate page content via Writer | ✅ EXISTS | `backend/igny8_core/business/site_building/services/page_generation_service.py` | No action needed | -| **Services** | SiteBuilderFileService | File management service | ✅ EXISTS | `backend/igny8_core/business/site_building/services/file_management_service.py` | No action needed | -| **AI Functions** | GenerateSiteStructureFunction | AI function class | ✅ EXISTS | `backend/igny8_core/ai/functions/generate_site_structure.py` | No action needed | -| **AI Functions** | Function Registration | `generate_site_structure` registered in registry | ✅ REGISTERED | `backend/igny8_core/ai/registry.py:97-112` | No action needed | -| **AI Functions** | AI Task Dispatch | `run_ai_task` Celery task | ✅ EXISTS | `backend/igny8_core/ai/tasks.py:12-147` | No action needed | -| **AI Functions** | Prompt Template | `site_structure_generation` prompt | ✅ EXISTS | `backend/igny8_core/ai/prompts.py:242-307` | No action needed | -| **AI Functions** | Prompt Mapping | Function name → prompt type mapping | ✅ CONFIGURED | `backend/igny8_core/ai/prompts.py:599` | No action needed | -| **API Endpoints** | SiteBlueprintViewSet | CRUD + generate_structure action | ✅ EXISTS | `backend/igny8_core/modules/site_builder/views.py:32-81` | No action needed | -| **API Endpoints** | PageBlueprintViewSet | CRUD + generate_content action | ✅ EXISTS | `backend/igny8_core/modules/site_builder/views.py:141-172` | No action needed | -| **API Endpoints** | SiteBuilderMetadataView | Metadata endpoint for dropdowns | ✅ EXISTS | `backend/igny8_core/modules/site_builder/views.py:216-250` | ❌ **FAILS** - Needs DB tables | -| **API Endpoints** | SiteAssetView | File upload/download | ✅ EXISTS | `backend/igny8_core/modules/site_builder/views.py:175-213` | No action needed | -| **API URLs** | Site Builder URLs | `/api/v1/site-builder/` routes | ✅ CONFIGURED | `backend/igny8_core/modules/site_builder/urls.py` | No action needed | -| **API URLs** | URL Registration | Included in main urls.py | ✅ REGISTERED | `backend/igny8_core/urls.py:30` | No action needed | -| **Billing** | Credit Cost | `site_structure_generation: 50 credits` | ✅ DEFINED | `backend/igny8_core/business/billing/constants.py:13` | No action needed | -| **Billing** | Credit Cost | `site_page_generation: 20 credits` | ✅ DEFINED | `backend/igny8_core/business/billing/constants.py:14` | No action needed | -| **Billing** | Credit Check | CreditService.check_credits() called | ✅ IMPLEMENTED | `backend/igny8_core/business/site_building/services/structure_generation_service.py:57` | No action needed | -| **Celery** | Configuration | Celery app configured | ✅ CONFIGURED | `backend/igny8_core/celery.py` | No action needed | -| **Celery** | Settings | CELERY_BROKER_URL, CELERY_RESULT_BACKEND | ✅ CONFIGURED | `backend/igny8_core/settings.py:497-508` | No action needed | -| **Celery** | Worker Container | `igny8_celery_worker` in docker-compose | ✅ DEFINED | `docker-compose.app.yml:105-128` | ❌ **NOT RUNNING** - Start container | -| **Celery** | Beat Container | `igny8_celery_beat` in docker-compose | ✅ DEFINED | `docker-compose.app.yml:130-153` | ❌ **NOT RUNNING** - Start container | -| **Redis** | Configuration | REDIS_HOST, REDIS_PORT env vars | ✅ CONFIGURED | `docker-compose.app.yml:38-39, 115-116, 140-141` | No action needed | -| **Redis** | Redis Service | External Redis service | ❌ **NOT ACCESSIBLE** | Expected from infra stack | ❌ **NOT RUNNING** - Start Redis service | -| **Dependencies** | Python Packages | celery>=5.3.0 | ✅ IN REQUIREMENTS | `backend/requirements.txt:11` | No action needed | -| **Dependencies** | Python Packages | redis | ✅ IN REQUIREMENTS | `backend/requirements.txt:4` | No action needed | -| **Dependencies** | Python Packages | Django>=5.2.7 | ✅ IN REQUIREMENTS | `backend/requirements.txt:1` | No action needed | -| **Dependencies** | Python Packages | djangorestframework | ✅ IN REQUIREMENTS | `backend/requirements.txt:6` | No action needed | -| **Frontend** | API Client | siteBuilderApi functions | ✅ EXISTS | `frontend/src/services/siteBuilder.api.ts` | No action needed | -| **Frontend** | Store | useBuilderStore with metadata loading | ✅ EXISTS | `frontend/src/store/builderStore.ts:399-412` | No action needed | -| **Logging** | StructureGenerationService | Logging statements | ✅ IMPLEMENTED | `backend/igny8_core/business/site_building/services/structure_generation_service.py:49-53, 98-102` | No action needed | -| **Logging** | GenerateSiteStructure | Logging statements | ✅ IMPLEMENTED | `backend/igny8_core/ai/functions/generate_site_structure.py:135` | No action needed | -| **Error Handling** | InsufficientCreditsError | Handled in StructureGenerationService | ✅ IMPLEMENTED | `backend/igny8_core/business/site_building/services/structure_generation_service.py:58-61` | No action needed | -| **Error Handling** | Celery Fallback | Synchronous execution if Celery unavailable | ✅ IMPLEMENTED | `backend/igny8_core/business/site_building/services/structure_generation_service.py:109-115` | No action needed | - ---- - -## Critical Issues Summary - -### 🔴 **CRITICAL - Database Migrations Not Applied** -**Impact**: All Site Builder endpoints fail with `ProgrammingError: relation "igny8_site_builder_business_types" does not exist` - -**Root Cause**: Migrations exist but haven't been run on the database - -**Fix Required**: -```bash -# Step 1: Navigate to app directory -cd /data/app/igny8 - -# Step 2: Create migrations if model changes exist -docker compose -f docker-compose.app.yml -p igny8-app exec igny8_backend python manage.py makemigrations site_building - -# Step 3: Apply migrations -docker compose -f docker-compose.app.yml -p igny8-app exec igny8_backend python manage.py migrate site_building - -# Alternative: If backend is in infra stack, use: -# cd /data/app -# docker compose -f docker-compose.yml -p igny8-infra exec python manage.py makemigrations site_building -# docker compose -f docker-compose.yml -p igny8-infra exec python manage.py migrate site_building -``` - -**Files Affected**: -- `backend/igny8_core/business/site_building/migrations/0001_initial.py` -- `backend/igny8_core/business/site_building/migrations/0002_sitebuilder_metadata.py` - -**Tables That Will Be Created**: -1. `igny8_site_blueprints` -2. `igny8_page_blueprints` -3. `igny8_site_builder_business_types` -4. `igny8_site_builder_audience_profiles` -5. `igny8_site_builder_brand_personalities` -6. `igny8_site_builder_hero_imagery` - ---- - -### 🔴 **CRITICAL - Redis Not Running** -**Impact**: Celery tasks can't be queued, AI generation fails silently or runs synchronously - -**Root Cause**: Redis service is not accessible (Connection refused errors in logs) - -**Fix Required**: -1. Ensure Redis service is running in the infra stack -2. Verify network connectivity between backend and Redis -3. Check Redis is accessible at `redis:6379` from backend container - -**Configuration**: -- Expected: `redis://redis:6379/0` -- Environment vars: `REDIS_HOST=redis`, `REDIS_PORT=6379` - ---- - -### 🔴 **CRITICAL - Celery Worker Not Running** -**Impact**: Even if Redis is fixed, AI tasks won't execute because no worker is processing them - -**Root Cause**: `igny8_celery_worker` container is not running - -**Fix Required**: -```bash -# Navigate to app directory -cd /data/app/igny8 - -# Start Celery worker -docker compose -f docker-compose.app.yml -p igny8-app up -d igny8_celery_worker - -# Verify it's running -docker compose -f docker-compose.app.yml -p igny8-app ps igny8_celery_worker -``` - -**Container Configuration**: `docker-compose.app.yml:105-128` - -**Note**: If backend is in infra stack, Celery worker may also be there. Check which stack contains the backend service. - ---- - -### 🟡 **WARNING - Celery Beat Not Running** -**Impact**: Periodic tasks (credit replenishment, automation rules) won't run - -**Root Cause**: `igny8_celery_beat` container is not running - -**Fix Required**: -```bash -# Navigate to app directory -cd /data/app/igny8 - -# Start Celery beat -docker compose -f docker-compose.app.yml -p igny8-app up -d igny8_celery_beat - -# Verify it's running -docker compose -f docker-compose.app.yml -p igny8-app ps igny8_celery_beat -``` - ---- - -## Verification Checklist - -After fixing the critical issues, verify: - -- [ ] Database migrations applied: `python manage.py showmigrations site_building` shows all as `[X]` -- [ ] Tables exist: Query `igny8_site_builder_business_types` returns data -- [ ] Redis accessible: `redis-cli -h redis ping` returns `PONG` -- [ ] Celery worker running: `docker ps | grep celery_worker` shows container -- [ ] Celery worker connected: Check logs for "celery@hostname ready" -- [ ] Metadata endpoint works: `GET /api/v1/site-builder/metadata/` returns 200 with data -- [ ] AI task can be queued: Check logs for `[StructureGenerationService] Queued AI task` -- [ ] AI task executes: Check logs for `run_ai_task STARTED: generate_site_structure` - ---- - -## Code Quality Assessment - -### ✅ **Strengths** -1. **Complete Implementation**: All core components are implemented -2. **Proper Separation**: Business logic separated from API layer -3. **Error Handling**: Graceful fallbacks for Celery unavailability -4. **Credit System**: Properly integrated with billing system -5. **Logging**: Comprehensive logging throughout the flow -6. **Type Hints**: Good use of type hints in services -7. **Documentation**: Models and services have docstrings - -### ⚠️ **Potential Improvements** -1. **Migration Dependencies**: Ensure migration dependencies are correct (currently depends on `igny8_core_auth.0014` and `writer.0009`) -2. **Error Messages**: Could be more user-friendly in API responses -3. **Testing**: Test files exist but may need updates for current implementation -4. **Monitoring**: Consider adding metrics for AI task success/failure rates - ---- - -## Next Steps - -1. **Immediate**: Run database migrations -2. **Immediate**: Start Redis service (if in infra stack) -3. **Immediate**: Start Celery worker container -4. **Immediate**: Start Celery beat container (optional but recommended) -5. **Verification**: Test metadata endpoint -6. **Verification**: Test structure generation endpoint -7. **Monitoring**: Watch logs for AI task execution - ---- - -## Files Reference - -### Core Models -- `backend/igny8_core/business/site_building/models.py` - All Site Builder models - -### Services -- `backend/igny8_core/business/site_building/services/structure_generation_service.py` - AI structure generation -- `backend/igny8_core/business/site_building/services/page_generation_service.py` - Page content generation -- `backend/igny8_core/business/site_building/services/file_management_service.py` - File handling - -### AI Functions -- `backend/igny8_core/ai/functions/generate_site_structure.py` - AI function implementation -- `backend/igny8_core/ai/tasks.py` - Celery task dispatcher -- `backend/igny8_core/ai/registry.py` - Function registry - -### API Layer -- `backend/igny8_core/modules/site_builder/views.py` - API endpoints -- `backend/igny8_core/modules/site_builder/urls.py` - URL routing -- `backend/igny8_core/modules/site_builder/serializers.py` - Request/response serialization - -### Configuration -- `backend/igny8_core/settings.py` - Django settings -- `backend/igny8_core/celery.py` - Celery configuration -- `docker-compose.app.yml` - Container definitions -- `backend/requirements.txt` - Python dependencies - ---- - -**Report Generated**: Based on comprehensive codebase analysis -**Status**: All code components present, infrastructure needs attention - diff --git a/part2-dev/site-builder-docs-to-remove/SITE_BUILDER_INTEGRATION_PLAN.md b/part2-dev/site-builder-docs-to-remove/SITE_BUILDER_INTEGRATION_PLAN.md deleted file mode 100644 index 27754b21..00000000 --- a/part2-dev/site-builder-docs-to-remove/SITE_BUILDER_INTEGRATION_PLAN.md +++ /dev/null @@ -1,264 +0,0 @@ -# Site Builder Wizard Integration Plan - -## Overview -Integrate the Site Builder wizard directly into the main frontend app (`frontend/src/pages/Sites/Builder/`), using the same UI kit, state stores, and API helpers as the rest of the dashboard. The legacy `sites/src/builder` + `sites/src/renderer` code has been removed, so the only viable implementation path is the unified Sites module. - -## Current State - -### ✅ What's Done -- Legacy builder/renderer folders removed from Sites container (no more parallel UI) -- Type definitions created in `frontend/src/types/siteBuilder.ts` -- API helper created in `frontend/src/services/siteBuilder.api.ts` - -### ⚠️ What's Missing -- Builder store not yet created in the main app -- Wizard steps/page still placeholder in `frontend/src/pages/Sites/Builder/` -- No Tailwind/CX styling hooked into shared UI kit -- Routes/menu point to placeholder -- Tests/docs still reference old structure -- Sites container still contains stale references (needs cleanup after integration) - -## Integration Plan - -### Phase 1: Create API Service Layer ✅ -**Location**: `frontend/src/services/siteBuilder.api.ts` - -**Tasks**: -1. Create `siteBuilderApi` using `fetchAPI` pattern (not axios) -2. Functions needed: - - `listBlueprints()` - - `createBlueprint(payload)` - - `generateStructure(blueprintId, payload)` - - `listPages(blueprintId)` - - `generateAllPages(blueprintId, options)` - - `createTasksForPages(blueprintId, pageIds)` - -**API Endpoints** (already exist in backend): -- `GET /api/v1/site-builder/blueprints/` -- `POST /api/v1/site-builder/blueprints/` -- `POST /api/v1/site-builder/blueprints/{id}/generate_structure/` -- `GET /api/v1/site-builder/pages/?site_blueprint={id}` -- `POST /api/v1/site-builder/blueprints/{id}/generate_all_pages/` -- `POST /api/v1/site-builder/blueprints/{id}/create_tasks/` - -### Phase 2: Create Zustand Store ⏳ -**Location**: `frontend/src/store/builderStore.ts` - -**Tasks**: -1. Copy `builderStore.ts` from `sites/src/builder/state/` -2. Adapt to use `siteBuilderApi` instead of `builderApi` -3. Integrate with `useSiteStore` and `useSectorStore`: - - Auto-populate `siteId` from `useSiteStore().activeSite` - - Auto-populate `sectorId` from `useSectorStore().activeSector` - - Show site/sector selector if not set - -**Store State**: -- `form: BuilderFormData` - Wizard form data -- `currentStep: number` - Current wizard step (0-3) -- `isSubmitting: boolean` - Generation in progress -- `activeBlueprint: SiteBlueprint | null` - Latest blueprint -- `pages: PageBlueprint[]` - Generated pages -- `error: string | null` - Error message - -### Phase 3: Create Type Definitions ✅ -**Location**: `frontend/src/types/siteBuilder.ts` - -**Tasks**: -1. Copy types from `sites/src/builder/types/siteBuilder.ts` -2. Ensure compatibility with frontend's existing types - -**Types Needed**: -- `HostingType` -- `StylePreferences` -- `BuilderFormData` -- `SiteBlueprint` -- `PageBlueprint` -- `PageBlock` -- `SiteStructure` - -### Phase 4: Create Wizard Step Components ⏳ -**Location**: `frontend/src/pages/Sites/Builder/steps/` - -**Tasks**: -1. Copy step components from `sites/src/builder/pages/wizard/steps/` -2. Adapt to use frontend's UI components: - - Replace `Card` with `frontend/src/components/ui/card/Card` - - Replace custom inputs with Tailwind-styled inputs - - Use frontend's `Button` component -3. Adapt styles to Tailwind CSS: - - Remove `.sb-field`, `.sb-grid`, `.sb-pill` classes - - Use Tailwind utility classes instead - -**Step Components**: -- `BusinessDetailsStep.tsx` - Site/sector selection, business info -- `BriefStep.tsx` - Business brief textarea -- `ObjectivesStep.tsx` - Objectives list with add/remove -- `StyleStep.tsx` - Style preferences (palette, typography, personality) - -### Phase 5: Create Main Wizard Page ⏳ -**Location**: `frontend/src/pages/Sites/Builder/Wizard.tsx` - -**Tasks**: -1. Copy `WizardPage.tsx` from `sites/src/builder/pages/wizard/` -2. Adapt to frontend patterns: - - Use `PageMeta` component - - Use frontend's `Card` component - - Use frontend's `Button` component - - Use Tailwind CSS for styling -3. Integrate with stores: - - Auto-load active site/sector - - Show site/sector selector if needed - - Navigate to sites list on completion - -**Features**: -- 4-step wizard with progress indicators -- Step navigation (Back/Next buttons) -- Form validation -- Blueprint generation on submit -- Error handling -- Loading states - -### Phase 6: Create Site Definition Store (Optional) ⏳ -**Location**: `frontend/src/store/siteDefinitionStore.ts` - -**Tasks**: -1. Copy `siteDefinitionStore.ts` from `sites/src/builder/state/` -2. Use for preview functionality (if needed) - -### Phase 7: Update Routing & Navigation ✅ -**Location**: `frontend/src/App.tsx` - -**Tasks**: -1. Ensure `/sites/builder` route points to new `Wizard.tsx` -2. Update navigation to show wizard in Sites section - -### Phase 8: Fix Test File ✅ -**Location**: `frontend/src/__tests__/sites/BulkGeneration.test.tsx` - -**Tasks**: -1. Update import path from `site-builder/src/api/builder.api` to `services/siteBuilder.api` -2. Update mock path accordingly - -### Phase 9: Testing ⏳ *(blocked by vitest not installed in dev env)* -**Tasks**: -1. Test wizard flow: - - Site selection - - Sector selection - - All 4 wizard steps - - Blueprint generation - - Error handling -2. Test integration: - - Site/sector auto-population - - Navigation - - API calls - -### Phase 10: Cleanup ⏳ -**Tasks**: -1. Stop `igny8_site_builder` container -2. Remove Docker image -3. Remove `/site-builder` folder -4. Update documentation - -## File Structure After Integration - -``` -frontend/src/ -├── pages/Sites/Builder/ -│ ├── Wizard.tsx # Main wizard page (UPDATED) -│ ├── Preview.tsx # Preview page (keep placeholder for now) -│ ├── Blueprints.tsx # Blueprints list (already exists) -│ └── steps/ # NEW -│ ├── BusinessDetailsStep.tsx -│ ├── BriefStep.tsx -│ ├── ObjectivesStep.tsx -│ └── StyleStep.tsx -├── services/ -│ └── siteBuilder.api.ts # NEW - API service -├── store/ -│ ├── builderStore.ts # NEW - Builder state -│ └── siteDefinitionStore.ts # NEW - Site definition state (optional) -└── types/ - └── siteBuilder.ts # NEW - Type definitions -``` - -## Key Adaptations Needed - -### 1. API Client Pattern -**From** (sites container): -```typescript -import axios from 'axios'; -const client = axios.create({ baseURL: BASE_PATH }); -``` - -**To** (frontend): -```typescript -import { fetchAPI } from '../services/api'; -// Use fetchAPI directly, no axios -``` - -### 2. Component Library -**From** (sites container): -```typescript -import { Card } from '../../components/common/Card'; -``` - -**To** (frontend): -```typescript -import { Card } from '../../../components/ui/card/Card'; -``` - -### 3. Styling -**From** (sites container): -```css -.sb-field { ... } -.sb-grid { ... } -``` - -**To** (frontend): -```tsx -className="flex flex-col gap-2" -className="grid grid-cols-2 gap-4" -``` - -### 4. Store Integration -**From** (sites container): -```typescript -// Manual siteId/sectorId input -``` - -**To** (frontend): -```typescript -import { useSiteStore } from '../../../store/siteStore'; -import { useSectorStore } from '../../../store/sectorStore'; -// Auto-populate from stores -``` - -## Implementation Order - -1. ✅ Create types (`types/siteBuilder.ts`) -2. ✅ Create API service (`services/siteBuilder.api.ts`) -3. ⏳ Create builder store (`store/builderStore.ts`) -4. ⏳ Create step components (`pages/Sites/Builder/steps/`) -5. ⏳ Create main wizard page (`pages/Sites/Builder/Wizard.tsx`) -6. ⏳ Fix test file(s) -7. ⏳ Test integration -8. ⏳ Cleanup site-builder container/image/docs - -## Success Criteria - -- ✅ Wizard loads in main app at `/sites/builder` -- ✅ Site/sector auto-populated from stores -- ✅ All 4 steps work correctly -- ✅ Blueprint generation works -- ✅ Error handling works -- ✅ Navigation works -- ✅ No references to `site-builder/` folder in code -- ✅ Test file updated -- ✅ Sites container removed or marked deprecated in compose - -## Notes - -- Sites container will be deprecated once the wizard lives entirely inside the main app. -- Only integrate wizard into main frontend app (no parallel codepaths). -- Use frontend's existing patterns/components/stores for absolute consistency. - diff --git a/part2-dev/site-builder-docs-to-remove/SITE_BUILDER_URLS_AND_FILES.md b/part2-dev/site-builder-docs-to-remove/SITE_BUILDER_URLS_AND_FILES.md deleted file mode 100644 index 9c54d1c1..00000000 --- a/part2-dev/site-builder-docs-to-remove/SITE_BUILDER_URLS_AND_FILES.md +++ /dev/null @@ -1,139 +0,0 @@ -# Site Builder URLs and File Management - -## Summary of Implementation - -### ✅ Generate Page Content Step - -**Location**: `frontend/src/pages/Sites/Builder/Preview.tsx` - -**Implementation**: -- Added "Generate All Pages" button (shown when blueprint status is `'ready'`) -- Button triggers `generateAllPages()` from `builderStore` -- Shows ProgressModal during generation -- Uses existing `PageGenerationService.bulk_generate_pages()` backend function - -**Queue Function**: ✅ **EXISTS** -- `PageGenerationService.bulk_generate_pages()` creates Writer Tasks -- Tasks are queued via `ContentGenerationService.generate_content()` -- Each page blueprint gets a Writer Task with title: `"[Site Builder] {page_title}"` -- Tasks are processed by Celery workers - ---- - -## URL Standards - -### Public Site URLs (Deployed Sites) - -**Current Implementation** (Placeholder): -- Pattern: `https://{site_id}.igny8.com` -- Generated by: `SitesRendererAdapter._get_deployment_url()` -- Location: `backend/igny8_core/business/publishing/services/adapters/sites_renderer_adapter.py:191` - -**Planned Implementation** (from docs): -- Custom domains: `clientdomain.com` → routed via Caddy -- Subdomain: `mysite.igny8.com` → routed via Caddy -- Marketing site: `igny8.com` → `/igny8-sites/marketing/` - -**Sites Renderer Routes**: -- Public routes: `/:siteId/*` (no auth required) -- Loads from: `/data/app/sites-data/clients/{site_id}/v{version}/` - ---- - -### Admin/Management URLs (Frontend App) - -**Site Management Routes** (from `frontend/src/App.tsx`): -- `/sites` - All sites list -- `/sites/:id` - Site dashboard -- `/sites/:id/content` - Site content list -- `/sites/:id/editor` - Site content editor -- `/sites/:id/pages` - Page manager -- `/sites/:id/pages/new` - Create new page -- `/sites/:id/pages/:pageId/edit` - Edit page -- `/sites/:id/posts/:postId` - View/edit post -- `/sites/:id/posts/:postId/edit` - Edit post -- `/sites/:id/preview` - Site preview -- `/sites/:id/settings` - Site settings (General, SEO, OG, Schema, Integrations) -- `/sites/manage` - Site management dashboard - -**Site Builder Routes**: -- `/sites/builder` - Site Builder wizard -- `/sites/builder/preview` - Preview blueprint (with Generate All Pages button) -- `/sites/blueprints` - Blueprints list - ---- - -## File Management - -### File Storage Structure - -**Site Files**: -``` -/data/app/sites-data/ -└── clients/ - └── {site_id}/ - └── v{version}/ - ├── site.json - ├── pages/ - │ ├── home.json - │ ├── about.json - │ └── ... - └── assets/ # User-managed files - ├── images/ - ├── documents/ - └── media/ -``` - -**Service**: `SiteBuilderFileService` -- Location: `backend/igny8_core/business/site_building/services/file_management_service.py` -- Base path: `/data/app/sites-data/clients` -- Max file size: 10MB per file -- Max storage per site: 100MB - -### User Access Rules - -- **Owner/Admin**: Full access to all account sites -- **Editor**: Access to granted sites (via SiteUserAccess) -- **Viewer**: Read-only access to granted sites -- File operations scoped to user's accessible sites only - -### File Manager UI - -**Status**: ⚠️ **NOT YET IMPLEMENTED** - -**Planned** (from Phase 3 docs): -- File Browser UI: `site-builder/src/components/files/FileBrowser.tsx` -- File Upload API: `modules/site_builder/views.py` -- Storage quota check: `infrastructure/storage/file_storage.py` - -**Expected Routes** (not yet in App.tsx): -- `/sites/:id/files` - File manager for site assets -- `/sites/:id/files/upload` - Upload files -- `/sites/:id/files/:fileId` - View/edit file - ---- - -## Docker Volumes - -**From `docker-compose.app.yml`**: -```yaml -igny8_sites: - volumes: - - /data/app/igny8/sites:/app - - /data/app/sites-data:/sites # Site definitions and assets -``` - -**Environment Variable**: -- `SITES_DATA_PATH=/sites` (inside container) -- Maps to `/data/app/sites-data` on host - ---- - -## Next Steps - -1. ✅ **Generate All Pages button** - Added to Preview page -2. ⏳ **File Manager UI** - Needs to be implemented -3. ⏳ **Deployment URL generation** - Currently placeholder, needs real domain mapping -4. ⏳ **Caddy routing configuration** - For custom domains -5. ⏳ **File upload API endpoints** - For user file management - diff --git a/part2-dev/site-builder-docs-to-remove/SITE_BUILDER_WORKFLOW_EXPLANATION.md b/part2-dev/site-builder-docs-to-remove/SITE_BUILDER_WORKFLOW_EXPLANATION.md deleted file mode 100644 index 3d63ed7b..00000000 --- a/part2-dev/site-builder-docs-to-remove/SITE_BUILDER_WORKFLOW_EXPLANATION.md +++ /dev/null @@ -1,65 +0,0 @@ -# Site Builder Workflow - Explanation & Fix - -## The Problem (FIXED) - -You were experiencing confusion because there were **TWO separate systems** that weren't properly connected: - -1. **Page Blueprint** (`PageBlueprint.blocks_json`) - Contains placeholder/sample blocks from AI structure generation -2. **Writer Content** (`Content` model) - Contains actual generated content from Writer tasks - -**The disconnect**: When deploying a site, it only used `PageBlueprint.blocks_json` (placeholders), NOT the actual `Content` from Writer. - -## Current Workflow (How It Works Now) - -### Step 1: Structure Generation -- AI generates site structure → Creates `SiteBlueprint` with `PageBlueprint` pages -- Each `PageBlueprint` has `blocks_json` with **placeholder/sample blocks** - -### Step 2: Content Generation -- Pages are sent to Writer as `Tasks` (title pattern: `[Site Builder] {Page Title}`) -- Writer generates actual content → Creates `Content` records -- `Content` has `html_content` and `json_blocks` with **real content** - -### Step 3: Publishing Status -- **Page Blueprint Status** (`PageBlueprint.status`): Set to `'published'` in Page Manager - - Controls if page appears in navigation and is accessible -- **Content Status** (`Content.status`): Set to `'publish'` in Content Manager - - Controls if actual written content is used (vs placeholders) - -### Step 4: Deployment (FIXED) -- When you deploy, `SitesRendererAdapter._build_site_definition()` now: - 1. For each page, finds the associated Writer Task (by title pattern) - 2. Finds the Content record for that task - 3. **If Content exists and status is 'publish'**, uses `Content.json_blocks` instead of `PageBlueprint.blocks_json` - 4. If Content has `html_content` but no `json_blocks`, converts it to a text block - 5. Uses the merged/actual content blocks for deployment - -## URLs - -- **Public Site URL**: `https://sites.igny8.com/{siteSlug}` - - Shows deployed site with actual content (if Content is published) - - Falls back to blueprint placeholders if Content not published -- **Individual Pages**: `https://sites.igny8.com/{siteSlug}/{pageSlug}` - - Example: `https://sites.igny8.com/auto-g8/products` - -## How To Use It Now - -1. **Generate Structure**: Create site blueprint with pages (has placeholder blocks) -2. **Generate Content**: Pages → Tasks → Content (Writer generates real content) -3. **Publish Content**: In Content Manager, set Content status to `'publish'` -4. **Publish Pages**: In Page Manager, set Page status to `'published'` (for navigation) -5. **Deploy Site**: Deploy the blueprint - it will automatically use published Content - -## What Changed - -✅ **Fixed**: `SitesRendererAdapter._build_site_definition()` now merges published Content into PageBlueprint blocks during deployment - -✅ **Result**: When you deploy, the site shows actual written content, not placeholders - -## Important Notes - -- **Two Statuses**: Page status controls visibility, Content status controls which content is used -- **Deployment Required**: After publishing Content, you need to **redeploy** the site for changes to appear -- **Content Takes Precedence**: If Content is published, it replaces blueprint placeholders -- **Fallback**: If Content not published, blueprint placeholders are used - diff --git a/part2-dev/site-builder-docs-to-remove/TEMPLATE_SYSTEM_EXPLANATION.md b/part2-dev/site-builder-docs-to-remove/TEMPLATE_SYSTEM_EXPLANATION.md deleted file mode 100644 index f213324a..00000000 --- a/part2-dev/site-builder-docs-to-remove/TEMPLATE_SYSTEM_EXPLANATION.md +++ /dev/null @@ -1,185 +0,0 @@ -# Template System - Current State & Plans - -## Current Template Architecture - -### 1. Site-Level Layouts (Implemented) -**Location**: `sites/src/utils/layoutRenderer.tsx` - -**Available Layouts**: -- `default` - Standard header, content, footer -- `minimal` - Clean, minimal design -- `magazine` - Editorial, content-focused -- `ecommerce` - Product-focused -- `portfolio` - Showcase layout -- `blog` - Content-first -- `corporate` - Business layout - -**How it works**: -- Set in `SiteBlueprint.structure_json.layout` -- Applied to the entire site -- All pages use the same layout - -### 2. Block Templates (Implemented) -**Location**: `sites/src/utils/templateEngine.tsx` - -**Available Block Types**: -- `hero` - Hero section with title, subtitle, CTA -- `text` - Text content block -- `features` - Feature grid -- `testimonials` - Testimonials section -- `services` - Services grid -- `stats` - Statistics panel -- `cta` - Call to action -- `image` - Image block -- `video` - Video block -- `form` - Contact form -- `faq` - FAQ accordion -- `quote` - Quote block -- `grid` - Grid layout -- `card` - Card block -- `list` - List block -- `accordion` - Accordion block - -**How it works**: -- Each page has `blocks_json` array -- Each block has `type` and `data` -- `renderTemplate()` renders blocks based on type - -### 3. Page Types (Defined, but NO templates yet) -**Location**: `backend/igny8_core/business/site_building/models.py` - -**Page Type Choices**: -- `home` - Homepage -- `about` - About page -- `services` - Services page -- `products` - Products page -- `blog` - Blog page -- `contact` - Contact page -- `custom` - Custom page - -**Current State**: -- Page types are stored but **NOT used for rendering** -- All pages render the same way regardless of type -- No page-type-specific templates exist - -## Missing: Page-Type Templates - -### What's Missing -Currently, there's **NO page-type-specific template system**. All pages render identically: -- Home page renders the same as Products page -- Blog page renders the same as Contact page -- No special handling for different page types - -### Where Page-Type Templates Should Be - -**Proposed Location**: `sites/src/utils/pageTypeRenderer.tsx` - -**Proposed Structure**: -```typescript -// Page-type specific renderers -function renderHomePage(page: PageDefinition, blocks: Block[]): React.ReactElement { - // Home-specific template: Hero, features, testimonials, CTA -} - -function renderProductsPage(page: PageDefinition, blocks: Block[]): React.ReactElement { - // Products-specific template: Product grid, filters, categories -} - -function renderBlogPage(page: PageDefinition, blocks: Block[]): React.ReactElement { - // Blog-specific template: Post list, sidebar, pagination -} - -function renderContactPage(page: PageDefinition, blocks: Block[]): React.ReactElement { - // Contact-specific template: Form, map, contact info -} -``` - -### How It Should Work - -1. **In `layoutRenderer.tsx`**: After determining site layout, check page type -2. **Route to page-type renderer**: If page type has specific template, use it -3. **Fallback to default**: If no page-type template, use default block rendering - -**Example Flow**: -``` -Site Definition → Site Layout (default/minimal/etc.) - ↓ -Page Type (home/products/blog/etc.) - ↓ -Page-Type Template (if exists) OR Default Block Rendering - ↓ -Block Templates (hero/text/features/etc.) -``` - -## Current Rendering Flow - -``` -SiteRenderer - ↓ -loadSiteDefinition() - ↓ -renderLayout(siteDefinition) → Uses site.layout (default/minimal/etc.) - ↓ -renderDefaultLayout() → Renders all pages the same way - ↓ -renderTemplate(block) → Renders individual blocks -``` - -## Proposed Enhanced Flow - -``` -SiteRenderer - ↓ -loadSiteDefinition() - ↓ -renderLayout(siteDefinition) → Uses site.layout - ↓ -For each page: - ↓ - Check page.type (home/products/blog/etc.) - ↓ - If page-type template exists: - → renderPageTypeTemplate(page) - Else: - → renderDefaultPageTemplate(page) - ↓ - renderTemplate(block) → Renders blocks -``` - -## Implementation Plan - -### Phase 1: Create Page-Type Renderers -- Create `sites/src/utils/pageTypeRenderer.tsx` -- Implement templates for each page type: - - `home` - Hero + features + testimonials layout - - `products` - Product grid + filters - - `blog` - Post list + sidebar - - `contact` - Form + map + info - - `about` - Team + mission + values - - `services` - Service cards + descriptions - -### Phase 2: Integrate with Layout Renderer -- Modify `renderDefaultLayout()` to check page type -- Route to page-type renderer if template exists -- Fallback to current block rendering - -### Phase 3: Make Templates Configurable -- Allow templates to be customized per site -- Store template preferences in `SiteBlueprint.config_json` -- Support custom templates - -## Current Files - -- **Site Layouts**: `sites/src/utils/layoutRenderer.tsx` -- **Block Templates**: `sites/src/utils/templateEngine.tsx` -- **Page Types**: `backend/igny8_core/business/site_building/models.py` (PageBlueprint.PAGE_TYPE_CHOICES) -- **Missing**: Page-type templates (not implemented yet) - -## Summary - -✅ **Implemented**: Site-level layouts, block templates -❌ **Missing**: Page-type-specific templates -📝 **Planned**: Page-type renderers in `sites/src/utils/pageTypeRenderer.tsx` - -Currently, all pages render the same way. Page types are stored but not used for rendering. To add page-type templates, create a new file `pageTypeRenderer.tsx` and integrate it into the layout renderer. - diff --git a/refactor-plan/refactor-stage-2.md b/refactor-plan/refactor-stage-2.md deleted file mode 100644 index 2f105889..00000000 --- a/refactor-plan/refactor-stage-2.md +++ /dev/null @@ -1,89 +0,0 @@ -# Stage 2 – Planner & Wizard UX - -## Overview -- Feature flag: `USE_SITE_BUILDER_REFACTOR` (must be `true`) -- Goal: ship state-aware, guided Site Builder experience and expose cluster/taxonomy readiness to Planner UI -- Dependencies: Stage 1 migrations/services already deployed -- Entry point: `/sites/builder/workflow/:blueprintId` (protected route) - ---- - -## Backend Enhancements - -### New services / endpoints -| Component | Description | File | -| --- | --- | --- | -| `WizardContextService` | Aggregates workflow state, cluster stats, taxonomy summaries, coverage counts | `backend/igny8_core/business/site_building/services/wizard_context_service.py` | -| Workflow context API | `GET /api/v1/site-builder/siteblueprint/{id}/workflow/context/` returns `workflow`, `cluster_summary`, `taxonomy_summary`, `coverage`, `next_actions` | `modules/site_builder/views.py` | -| Workflow serializer helpers | `SiteBlueprintSerializer` now returns `workflow_state` + `gating_messages` via `WorkflowStateService.serialize_state()` | `modules/site_builder/serializers.py` | - -### Workflow telemetry & logging -- `WorkflowStateService` normalizes step metadata (`status`, `code`, `message`, `updated_at`) -- Emits structured log events (`wizard_step_updated`, `wizard_blocking_issue`) for future analytics -- `serialize_state()` provides consistent payload for API, wizard store, and planner warnings - ---- - -## Frontend Implementation - -### API layer -- Added interfaces + calls (`fetchSiteBlueprints`, `fetchSiteBlueprintById`, `updateSiteBlueprint`, `fetchWizardContext`, `updateWorkflowStep`) -- Located in `frontend/src/services/api.ts` - -### Zustand store -| Store | Purpose | -| --- | --- | -| `useBuilderWorkflowStore` | Tracks `blueprintId`, `currentStep`, `completedSteps`, `blockingIssues`, `workflowState`, `context`, telemetry queue | -- Actions: `initialize`, `refreshState`, `goToStep`, `completeStep`, `setBlockingIssue`, `clearBlockingIssue`, `flushTelemetry`, `reset` -- Persists last blueprint + step in `builder-workflow-storage` (sessionStorage) - -### Wizard shell & routing -- New page: `WorkflowWizard` at `/sites/builder/workflow/:blueprintId` -- Lazy-loaded via `App.tsx` -- Refreshes context every 10s to keep telemetry/current state accurate -- Progress indicator (`WizardProgress`) shows completed/current/blocked steps - -### Step components -| Step | Component | Status | -| --- | --- | --- | -| 1 – Business Details | `steps/BusinessDetailsStep.tsx` | **Functional** (saves blueprint + completes step) | -| 2 – Cluster Assignment | `steps/ClusterAssignmentStep.tsx` | Placeholder UI (shows stats, next iteration: attach/detach clusters) | -| 3 – Taxonomy Builder | `steps/TaxonomyBuilderStep.tsx` | Placeholder UI (future: taxonomy tree/table + imports) | -| 4 – AI Sitemap Review | `steps/SitemapReviewStep.tsx` | Placeholder UI (future: grid w/ grouping + regenerate) | -| 5 – Coverage Validation | `steps/CoverageValidationStep.tsx` | Placeholder UI (future: coverage cards + gating logic) | -| 6 – Ideas Hand-off | `steps/IdeasHandoffStep.tsx` | Placeholder UI (future: page selection + prompt override) | - -### Planner UX TODOs (next iteration) -- Cluster matrix view linking back into wizard -- Taxonomy management table with inline edits & imports -- Planner dashboard banner if blueprint missing requirements - ---- - -## Testing & Verification -1. Set `USE_SITE_BUILDER_REFACTOR=true` -2. Create or reuse a `SiteBlueprint` and open `/sites/builder/workflow/{id}` -3. Confirm payload from `GET /workflow/context/` includes: - - `workflow.steps` array with `status`, `code`, `message` - - `cluster_summary` (counts + list) - - `taxonomy_summary` - - `coverage` (pages, statuses) - - `next_actions` -4. Step 1 (Business Details) should allow update/save → triggers workflow state update -5. Steps 2‑6 currently show placeholders + gating alerts (will be wired to new UIs) - -Automated tests pending: once UI solidified, add Cypress flows for each step + Zustand store unit tests. - ---- - -## Open Items / Future Work -- Build full step experiences (tables, drag/drop mapping, AI sitemap review UI) -- Planner cluster matrix & taxonomy management views -- Telemetry dispatcher (currently logs to console) -- Accessibility polish: keyboard navigation, helper tooltips, context drawer -- QA automation + e2e coverage - ---- - -*Last updated: 2025-11-19* - diff --git a/refactor-plan/refactor-stage-3.md b/refactor-plan/refactor-stage-3.md deleted file mode 100644 index 318e9b18..00000000 --- a/refactor-plan/refactor-stage-3.md +++ /dev/null @@ -1,85 +0,0 @@ -# Stage 3 – Writer / Linker / Optimizer Enhancements - -## Objective -Propagate the new metadata (clusters, taxonomies, entity types, attributes) through the planner → writer pipeline, enforce validation before publish, and unlock linker/optimizer capabilities. Stage 3 builds directly on Stage 2’s wizard outputs; all changes stay behind `USE_SITE_BUILDER_REFACTOR` until pilot-ready. - ---- - -## Backend Plan - -### 1. Metadata Audit & Backfill -| Task | Description | Owner | -| --- | --- | --- | -| Backfill tables | Implement data migration using the stub added in `writer/migrations/0012_metadata_mapping_tables.py` to populate `ContentClusterMap`, `ContentTaxonomyMap`, `ContentAttributeMap` for legacy content/tasks. | Backend lead | -| Entity defaults | Ensure existing Tasks/Content have sensible defaults for `entity_type`, `taxonomy_id`, `cluster_role` (e.g., `blog_post` + `supporting`). | Backend lead | -| Audit script | Management command `python manage.py audit_site_metadata --site {id}` summarizing gaps per site. | Backend lead | - -### 2. Pipeline Updates -| Stage | Changes | -| --- | --- | -| Ideas → Tasks | Update Task creation so every task inherits cluster/taxonomy/attribute metadata. Enforce “no cluster, no idea/task” rule. | -| Tasks → Content | Adjust `PageGenerationService` / writer Celery tasks to persist mappings into `ContentClusterMap`, `ContentTaxonomyMap`, `ContentAttributeMap`. | -| AI Prompts | Update prompts to include cluster role, taxonomy context, product attributes. Leverage Stage 1 metadata fields like `dimension_meta`, `attribute_values`. | -| Validation services | Add reusable validators (e.g., `ensure_required_attributes(task)`), returning structured errors for UI. | - -### 3. Linker & Optimizer -| Component | Requirements | -| --- | --- | -| LinkerService | Use mapping tables to suggest hub ↔ supporting ↔ attribute links; include priority score + context snippet. | -| OptimizerService | Scorecards factoring cluster coverage, taxonomy alignment, attribute completeness. Provide `/sites/{id}/progress` and `/writer/content/{id}/validation` endpoints. | -| Caching/Indexes | Add DB indexes for frequent join patterns (content ↔ cluster_map, taxonomy_map). | - -### 4. API Additions -- `GET /api/v1/sites/{id}/progress/` → cluster-level completion + validation flags. -- `GET /api/v1/writer/content/{id}/validation/` → aggregated checklist for Writer UI. -- `POST /api/v1/writer/content/{id}/validate/` → re-run validators and return actionable errors. - ---- - -## Frontend Plan - -### 1. Planner / Ideas / Writer Enhancements -| Area | UX Changes | -| --- | --- | -| Planner Ideas & Writer Tasks lists | Show chips/columns for cluster, taxonomy, entity type, validation status; add filters. | -| Writer Editor | Sidebar module summarizing cluster, taxonomy tree, attribute form; validation panel blocking publish until cleared. | -| Linker UI | Group internal link suggestions by cluster role; show context snippet + CTA to insert link. | -| Optimizer Dashboard | Scorecards per cluster dimension with color coding + “next action” cards. | -| Site Progress Widgets | On site overview, show completion bars (hub/supporting/attribute); deep link to problematic clusters/pages. | - -### 2. Validation & Notifications -- Inline toasts + optional email when validation fails. -- Publish button disabled until validators pass; display error list linking to relevant fields. -- Credit reminder banner when user regenerates content/optimization tasks. - ---- - -## Testing Strategy -| Area | Automated | Manual | -| --- | --- | --- | -| Pipeline | Unit tests for Task → Content metadata persistence, Prompt builders. | End-to-end: blueprint → ideas → tasks → content. | -| Validation | Tests ensuring validators trigger correct errors. | Attempt publish without taxonomy/attributes; confirm UX flow. | -| Linker/Optimizer | Service tests for scoring & suggestions. | Performance profiling on large datasets; UX review. | -| Progress Widgets | Component tests verifying counts. | Compare UI vs. database for pilot site. | - ---- - -## Rollout Checklist -1. Deploy Stage 3 backend with feature flag ON in staging. -2. Run metadata backfill; verify progress dashboards and validators. -3. QA regression: planner → writer flow, linker, optimizer. -4. Pilot with internal content team; gather feedback on validation friction. -5. Optimize slow queries (indexes/caching) before production rollout. -6. Update training docs/videos for writers; enable flag gradually across accounts. - ---- - -## Open Questions / Risks -- Volume impact when backfilling large content sets? (Plan: chunked migrations + progress logs) -- Telemetry volume for validator events? (Plan: aggregate counts; sample per site) -- WordPress deploy parity: ensure metadata travels through sync (handled in Stage 4). - ---- - -*Last updated: 2025-11-19* - diff --git a/refactor-plan/refactor-stage-4.md b/refactor-plan/refactor-stage-4.md deleted file mode 100644 index e08d03b7..00000000 --- a/refactor-plan/refactor-stage-4.md +++ /dev/null @@ -1,89 +0,0 @@ -# Stage 4 – Publishing & Sync Integration - -## Objective -Achieve feature parity between IGNY8-hosted deployments and WordPress sites using the shared metadata model introduced in Stages 1–3. This includes two-way sync for taxonomies/products, deployment readiness checks, and operational tooling. - ---- - -## Backend Plan - -### 1. Sync Architecture -| Task | Description | -| --- | --- | -| Audit adapters | Review current WordPress adapter + sync service; confirm endpoints for categories, tags, WooCommerce attributes/products. | -| Data mapping | Document mapping between WordPress taxonomies and IGNY8 `SiteBlueprintTaxonomy`, `ContentTaxonomyMap`, `external_reference` fields. | -| Sync configs | Extend integration settings to store WordPress/Woo credentials, sync frequency, and site archetype. | - -### 2. Enhancements -| Area | Implementation | -| --- | --- | -| Import | `ContentSyncService` fetches WP taxonomies/products/custom post types -> maps to IGNY8 schema via `TaxonomyService`. Auto-create missing clusters/taxonomies with an `imported` flag. | -| Export | `WordPressAdapter` ensures taxonomies exist before publishing posts/products. Pushes product attributes/tags ahead of content. | -| Sync Health APIs | `/sites/{id}/sync/status`, `/sites/{id}/sync/run`, returning last sync time, mismatch counts, error logs. | -| Deployment | `SitesRendererAdapter` consumes cluster/taxonomy metadata for navigation, breadcrumbs, internal links. Deployment readiness check ensures cluster coverage, content status, validation flags. | -| Logging & Monitoring | Structured logs per sync run (duration, items processed, failures). Alerts for repeated sync failures or deployment errors. | - ---- - -## Frontend Plan - -### 1. Sync Dashboard -| Component | Features | -| --- | --- | -| Parity indicators | Status icons for taxonomies, products, posts. | -| Controls | Manual sync, retry failed items, view logs (with pagination/filtering). | -| Detail drawer | Shows mismatched items, suggested fixes, quick links into Planner/Writer. | - -### 2. Deployment Panel -| Component | Features | -| --- | --- | -| Readiness checklist | Displays cluster coverage, content validation, sync status. | -| Actions | Deploy and rollback buttons with confirmation modals and logging. | -| Notifications | Toasts for success/failure; optional email/webhook integration. | - -### 3. WordPress Connection UI -| Task | Description | -| --- | --- | -| Integration status | Show credential health, last sync time, active site type. | -| Troubleshooting | Inline helper text + links to docs/runbook. | - ---- - -## Operational Runbooks -- Sync troubleshooting steps (auth errors, taxonomy mismatches, WooCommerce throttling). -- Rollback procedures for failed deployments. -- Escalation path + scripts to force sync, clear queue, or recover failed deploy. - ---- - -## Testing Strategy -| Area | Automated | Manual | -| --- | --- | --- | -| Sync logic | Integration tests hitting mocked WP APIs, verifying mapping + retries. | Staging sync from live WP instance; verify taxonomy parity. | -| Deployment | Renderer tests using fixture metadata to ensure navigation/internal links. | Deploy IGNY8 site; inspect front-end output, breadcrumbs, menus. | -| Dashboards | Component/unit tests for Sync/Deployment panels. | Pilot user testing + UX review. | -| Runbooks | N/A | Tabletop exercises for failure scenarios (sync fails, deploy rollback). | - ---- - -## Rollout Checklist -1. Enable Stage 4 flag in staging; run full import/export tests. -2. Pilot with one IGNY8-hosted and one WordPress-hosted site. -3. Train support on dashboards/runbooks; ensure alerting configured. -4. Announce availability; roll out gradually to accounts with WordPress integrations. -5. Monitor logs/alerts during first production syncs; iterate on tooling as needed. - ---- - -## Risks & Mitigations -| Risk | Mitigation | -| --- | --- | -| API rate limits (WordPress/WooCommerce) | Backoff + batching, highlight in dashboard. | -| Data mismatches (taxonomies/products) | Detailed diff view + retry actions + runbook. | -| Deployment failures | Preflight checks + rollback buttons + structured logs. | -| Operational overhead | Alerting dashboards + documented on-call runbook. | - ---- - -*Last updated: 2025-11-19* - diff --git a/site-builder/.gitignore b/site-builder/.gitignore deleted file mode 100644 index a547bf36..00000000 --- a/site-builder/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* -lerna-debug.log* - -node_modules -dist -dist-ssr -*.local - -# Editor directories and files -.vscode/* -!.vscode/extensions.json -.idea -.DS_Store -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? diff --git a/site-builder/Dockerfile.dev b/site-builder/Dockerfile.dev deleted file mode 100644 index 27e54f04..00000000 --- a/site-builder/Dockerfile.dev +++ /dev/null @@ -1,18 +0,0 @@ -# Site Builder Dev Image (Node 22 to satisfy Vite requirements) -FROM node:22-alpine - -WORKDIR /app - -# Copy package manifests first for better caching -COPY package*.json ./ - -RUN npm install - -# Copy source (still bind-mounted at runtime, but needed for initial run) -COPY . . - -EXPOSE 5175 - -CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0", "--port", "5175"] - - diff --git a/site-builder/README.md b/site-builder/README.md deleted file mode 100644 index d2e77611..00000000 --- a/site-builder/README.md +++ /dev/null @@ -1,73 +0,0 @@ -# React + TypeScript + Vite - -This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. - -Currently, two official plugins are available: - -- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh -- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh - -## React Compiler - -The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation). - -## Expanding the ESLint configuration - -If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules: - -```js -export default defineConfig([ - globalIgnores(['dist']), - { - files: ['**/*.{ts,tsx}'], - extends: [ - // Other configs... - - // Remove tseslint.configs.recommended and replace with this - tseslint.configs.recommendedTypeChecked, - // Alternatively, use this for stricter rules - tseslint.configs.strictTypeChecked, - // Optionally, add this for stylistic rules - tseslint.configs.stylisticTypeChecked, - - // Other configs... - ], - languageOptions: { - parserOptions: { - project: ['./tsconfig.node.json', './tsconfig.app.json'], - tsconfigRootDir: import.meta.dirname, - }, - // other options... - }, - }, -]) -``` - -You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules: - -```js -// eslint.config.js -import reactX from 'eslint-plugin-react-x' -import reactDom from 'eslint-plugin-react-dom' - -export default defineConfig([ - globalIgnores(['dist']), - { - files: ['**/*.{ts,tsx}'], - extends: [ - // Other configs... - // Enable lint rules for React - reactX.configs['recommended-typescript'], - // Enable lint rules for React DOM - reactDom.configs.recommended, - ], - languageOptions: { - parserOptions: { - project: ['./tsconfig.node.json', './tsconfig.app.json'], - tsconfigRootDir: import.meta.dirname, - }, - // other options... - }, - }, -]) -``` diff --git a/site-builder/eslint.config.js b/site-builder/eslint.config.js deleted file mode 100644 index 5e6b472f..00000000 --- a/site-builder/eslint.config.js +++ /dev/null @@ -1,23 +0,0 @@ -import js from '@eslint/js' -import globals from 'globals' -import reactHooks from 'eslint-plugin-react-hooks' -import reactRefresh from 'eslint-plugin-react-refresh' -import tseslint from 'typescript-eslint' -import { defineConfig, globalIgnores } from 'eslint/config' - -export default defineConfig([ - globalIgnores(['dist']), - { - files: ['**/*.{ts,tsx}'], - extends: [ - js.configs.recommended, - tseslint.configs.recommended, - reactHooks.configs.flat.recommended, - reactRefresh.configs.vite, - ], - languageOptions: { - ecmaVersion: 2020, - globals: globals.browser, - }, - }, -]) diff --git a/site-builder/index.html b/site-builder/index.html deleted file mode 100644 index fe1cf335..00000000 --- a/site-builder/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - site-builder - - -
- - - diff --git a/site-builder/package-lock.json b/site-builder/package-lock.json deleted file mode 100644 index affb1176..00000000 --- a/site-builder/package-lock.json +++ /dev/null @@ -1,6025 +0,0 @@ -{ - "name": "site-builder", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "site-builder", - "version": "0.0.0", - "dependencies": { - "axios": "^1.13.2", - "lucide-react": "^0.554.0", - "react": "^19.2.0", - "react-dom": "^19.2.0", - "react-hook-form": "^7.66.0", - "react-router-dom": "^7.9.6", - "zustand": "^5.0.8" - }, - "devDependencies": { - "@eslint/js": "^9.39.1", - "@testing-library/jest-dom": "^6.6.3", - "@testing-library/react": "^16.2.0", - "@types/node": "^24.10.0", - "@types/react": "^19.2.2", - "@types/react-dom": "^19.2.2", - "@types/react-router-dom": "^5.3.3", - "@vitejs/plugin-react": "^5.1.0", - "eslint": "^9.39.1", - "eslint-plugin-react-hooks": "^7.0.1", - "eslint-plugin-react-refresh": "^0.4.24", - "globals": "^16.5.0", - "jsdom": "^25.0.1", - "typescript": "~5.9.3", - "typescript-eslint": "^8.46.3", - "vite": "^7.2.2", - "vitest": "^2.1.5" - } - }, - "node_modules/@adobe/css-tools": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz", - "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@asamuzakjp/css-color": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", - "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@csstools/css-calc": "^2.1.3", - "@csstools/css-color-parser": "^3.0.9", - "@csstools/css-parser-algorithms": "^3.0.4", - "@csstools/css-tokenizer": "^3.0.3", - "lru-cache": "^10.4.3" - } - }, - "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helpers": "^7.28.4", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.5", - "@babel/types": "^7.28.5", - "@jridgewell/remapping": "^2.3.5", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/generator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", - "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.28.5", - "@babel/types": "^7.28.5", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.27.2", - "@babel/helper-validator-option": "^7.27.1", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", - "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.28.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", - "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.5" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", - "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", - "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.5", - "debug": "^4.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@csstools/color-helpers": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", - "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT-0", - "engines": { - "node": ">=18" - } - }, - "node_modules/@csstools/css-calc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", - "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/css-color-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", - "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "dependencies": { - "@csstools/color-helpers": "^5.1.0", - "@csstools/css-calc": "^2.1.4" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/css-parser-algorithms": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", - "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@csstools/css-tokenizer": "^3.0.4" - } - }, - "node_modules/@csstools/css-tokenizer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", - "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", - "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", - "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.7", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/config-helpers": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", - "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", - "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/js": { - "version": "9.39.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz", - "integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", - "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", - "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0", - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", - "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.4.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/remapping": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.47", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.47.tgz", - "integrity": "sha512-8QagwMH3kNCuzD8EWL8R2YPW5e4OrHNSAHRFDdmFqEwEaD/KcNKjVoumo+gP2vW5eKB2UPbM6vTYiGZX0ixLnw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.2.tgz", - "integrity": "sha512-yDPzwsgiFO26RJA4nZo8I+xqzh7sJTZIWQOxn+/XOdPE31lAvLIYCKqjV+lNH/vxE2L2iH3plKxDCRK6i+CwhA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.2.tgz", - "integrity": "sha512-k8FontTxIE7b0/OGKeSN5B6j25EuppBcWM33Z19JoVT7UTXFSo3D9CdU39wGTeb29NO3XxpMNauh09B+Ibw+9g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.2.tgz", - "integrity": "sha512-A6s4gJpomNBtJ2yioj8bflM2oogDwzUiMl2yNJ2v9E7++sHrSrsQ29fOfn5DM/iCzpWcebNYEdXpaK4tr2RhfQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.2.tgz", - "integrity": "sha512-e6XqVmXlHrBlG56obu9gDRPW3O3hLxpwHpLsBJvuI8qqnsrtSZ9ERoWUXtPOkY8c78WghyPHZdmPhHLWNdAGEw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.2.tgz", - "integrity": "sha512-v0E9lJW8VsrwPux5Qe5CwmH/CF/2mQs6xU1MF3nmUxmZUCHazCjLgYvToOk+YuuUqLQBio1qkkREhxhc656ViA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.2.tgz", - "integrity": "sha512-ClAmAPx3ZCHtp6ysl4XEhWU69GUB1D+s7G9YjHGhIGCSrsg00nEGRRZHmINYxkdoJehde8VIsDC5t9C0gb6yqA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.2.tgz", - "integrity": "sha512-EPlb95nUsz6Dd9Qy13fI5kUPXNSljaG9FiJ4YUGU1O/Q77i5DYFW5KR8g1OzTcdZUqQQ1KdDqsTohdFVwCwjqg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.2.tgz", - "integrity": "sha512-BOmnVW+khAUX+YZvNfa0tGTEMVVEerOxN0pDk2E6N6DsEIa2Ctj48FOMfNDdrwinocKaC7YXUZ1pHlKpnkja/Q==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.2.tgz", - "integrity": "sha512-Xt2byDZ+6OVNuREgBXr4+CZDJtrVso5woFtpKdGPhpTPHcNG7D8YXeQzpNbFRxzTVqJf7kvPMCub/pcGUWgBjA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.2.tgz", - "integrity": "sha512-+LdZSldy/I9N8+klim/Y1HsKbJ3BbInHav5qE9Iy77dtHC/pibw1SR/fXlWyAk0ThnpRKoODwnAuSjqxFRDHUQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.2.tgz", - "integrity": "sha512-8ms8sjmyc1jWJS6WdNSA23rEfdjWB30LH8Wqj0Cqvv7qSHnvw6kgMMXRdop6hkmGPlyYBdRPkjJnj3KCUHV/uQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.2.tgz", - "integrity": "sha512-3HRQLUQbpBDMmzoxPJYd3W6vrVHOo2cVW8RUo87Xz0JPJcBLBr5kZ1pGcQAhdZgX9VV7NbGNipah1omKKe23/g==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.2.tgz", - "integrity": "sha512-fMjKi+ojnmIvhk34gZP94vjogXNNUKMEYs+EDaB/5TG/wUkoeua7p7VCHnE6T2Tx+iaghAqQX8teQzcvrYpaQA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.2.tgz", - "integrity": "sha512-XuGFGU+VwUUV5kLvoAdi0Wz5Xbh2SrjIxCtZj6Wq8MDp4bflb/+ThZsVxokM7n0pcbkEr2h5/pzqzDYI7cCgLQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.2.tgz", - "integrity": "sha512-w6yjZF0P+NGzWR3AXWX9zc0DNEGdtvykB03uhonSHMRa+oWA6novflo2WaJr6JZakG2ucsyb+rvhrKac6NIy+w==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.2.tgz", - "integrity": "sha512-yo8d6tdfdeBArzC7T/PnHd7OypfI9cbuZzPnzLJIyKYFhAQ8SvlkKtKBMbXDxe1h03Rcr7u++nFS7tqXz87Gtw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.2.tgz", - "integrity": "sha512-ah59c1YkCxKExPP8O9PwOvs+XRLKwh/mV+3YdKqQ5AMQ0r4M4ZDuOrpWkUaqO7fzAHdINzV9tEVu8vNw48z0lA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.2.tgz", - "integrity": "sha512-4VEd19Wmhr+Zy7hbUsFZ6YXEiP48hE//KPLCSVNY5RMGX2/7HZ+QkN55a3atM1C/BZCGIgqN+xrVgtdak2S9+A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.2.tgz", - "integrity": "sha512-IlbHFYc/pQCgew/d5fslcy1KEaYVCJ44G8pajugd8VoOEI8ODhtb/j8XMhLpwHCMB3yk2J07ctup10gpw2nyMA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.2.tgz", - "integrity": "sha512-lNlPEGgdUfSzdCWU176ku/dQRnA7W+Gp8d+cWv73jYrb8uT7HTVVxq62DUYxjbaByuf1Yk0RIIAbDzp+CnOTFg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.2.tgz", - "integrity": "sha512-S6YojNVrHybQis2lYov1sd+uj7K0Q05NxHcGktuMMdIQ2VixGwAfbJ23NnlvvVV1bdpR2m5MsNBViHJKcA4ADw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.2.tgz", - "integrity": "sha512-k+/Rkcyx//P6fetPoLMb8pBeqJBNGx81uuf7iljX9++yNBVRDQgD04L+SVXmXmh5ZP4/WOp4mWF0kmi06PW2tA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@testing-library/dom": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", - "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^5.0.1", - "aria-query": "5.3.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.5.0", - "picocolors": "1.1.1", - "pretty-format": "^27.0.2" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@testing-library/jest-dom": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", - "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@adobe/css-tools": "^4.4.0", - "aria-query": "^5.0.0", - "css.escape": "^1.5.1", - "dom-accessibility-api": "^0.6.3", - "picocolors": "^1.1.1", - "redent": "^3.0.0" - }, - "engines": { - "node": ">=14", - "npm": ">=6", - "yarn": ">=1" - } - }, - "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", - "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@testing-library/react": { - "version": "16.3.0", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-16.3.0.tgz", - "integrity": "sha512-kFSyxiEDwv1WLl2fgsq6pPBbw5aWKrsY2/noi1Id0TK0UParSF62oFQFGHXIyaG4pp2tEub/Zlel+fjjZILDsw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.12.5" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "@testing-library/dom": "^10.0.0", - "@types/react": "^18.0.0 || ^19.0.0", - "@types/react-dom": "^18.0.0 || ^19.0.0", - "react": "^18.0.0 || ^19.0.0", - "react-dom": "^18.0.0 || ^19.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@types/aria-query": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", - "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", - "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", - "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.2" - } - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/history": { - "version": "4.7.11", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", - "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "24.10.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", - "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~7.16.0" - } - }, - "node_modules/@types/react": { - "version": "19.2.5", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.5.tgz", - "integrity": "sha512-keKxkZMqnDicuvFoJbzrhbtdLSPhj/rZThDlKWCDbgXmUg0rEUFtRssDXKYmtXluZlIqiC5VqkCgRwzuyLHKHw==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-dom": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", - "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@types/react": "^19.2.0" - } - }, - "node_modules/@types/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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/history": "^4.7.11", - "@types/react": "*", - "@types/react-router": "*" - } - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.46.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.4.tgz", - "integrity": "sha512-R48VhmTJqplNyDxCyqqVkFSZIx1qX6PzwqgcXn1olLrzxcSBDlOsbtcnQuQhNtnNiJ4Xe5gREI1foajYaYU2Vg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.46.4", - "@typescript-eslint/type-utils": "8.46.4", - "@typescript-eslint/utils": "8.46.4", - "@typescript-eslint/visitor-keys": "8.46.4", - "graphemer": "^1.4.0", - "ignore": "^7.0.0", - "natural-compare": "^1.4.0", - "ts-api-utils": "^2.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^8.46.4", - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "8.46.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.4.tgz", - "integrity": "sha512-tK3GPFWbirvNgsNKto+UmB/cRtn6TZfyw0D6IKrW55n6Vbs7KJoZtI//kpTKzE/DUmmnAFD8/Ca46s7Obs92/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/scope-manager": "8.46.4", - "@typescript-eslint/types": "8.46.4", - "@typescript-eslint/typescript-estree": "8.46.4", - "@typescript-eslint/visitor-keys": "8.46.4", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/project-service": { - "version": "8.46.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.4.tgz", - "integrity": "sha512-nPiRSKuvtTN+no/2N1kt2tUh/HoFzeEgOm9fQ6XQk4/ApGqjx0zFIIaLJ6wooR1HIoozvj2j6vTi/1fgAz7UYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.46.4", - "@typescript-eslint/types": "^8.46.4", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "8.46.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.4.tgz", - "integrity": "sha512-tMDbLGXb1wC+McN1M6QeDx7P7c0UWO5z9CXqp7J8E+xGcJuUuevWKxuG8j41FoweS3+L41SkyKKkia16jpX7CA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.46.4", - "@typescript-eslint/visitor-keys": "8.46.4" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.46.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.4.tgz", - "integrity": "sha512-+/XqaZPIAk6Cjg7NWgSGe27X4zMGqrFqZ8atJsX3CWxH/jACqWnrWI68h7nHQld0y+k9eTTjb9r+KU4twLoo9A==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "8.46.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.4.tgz", - "integrity": "sha512-V4QC8h3fdT5Wro6vANk6eojqfbv5bpwHuMsBcJUJkqs2z5XnYhJzyz9Y02eUmF9u3PgXEUiOt4w4KHR3P+z0PQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.46.4", - "@typescript-eslint/typescript-estree": "8.46.4", - "@typescript-eslint/utils": "8.46.4", - "debug": "^4.3.4", - "ts-api-utils": "^2.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/types": { - "version": "8.46.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.4.tgz", - "integrity": "sha512-USjyxm3gQEePdUwJBFjjGNG18xY9A2grDVGuk7/9AkjIF1L+ZrVnwR5VAU5JXtUnBL/Nwt3H31KlRDaksnM7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.46.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.4.tgz", - "integrity": "sha512-7oV2qEOr1d4NWNmpXLR35LvCfOkTNymY9oyW+lUHkmCno7aOmIf/hMaydnJBUTBMRCOGZh8YjkFOc8dadEoNGA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/project-service": "8.46.4", - "@typescript-eslint/tsconfig-utils": "8.46.4", - "@typescript-eslint/types": "8.46.4", - "@typescript-eslint/visitor-keys": "8.46.4", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^2.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@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==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "8.46.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.4.tgz", - "integrity": "sha512-AbSv11fklGXV6T28dp2Me04Uw90R2iJ30g2bgLz529Koehrmkbs1r7paFqr1vPCZi7hHwYxYtxfyQMRC8QaVSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.46.4", - "@typescript-eslint/types": "8.46.4", - "@typescript-eslint/typescript-estree": "8.46.4" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.46.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.4.tgz", - "integrity": "sha512-/++5CYLQqsO9HFGLI7APrxBJYo+5OCMpViuhV8q5/Qa3o5mMrF//eQHks+PXcsAVaLdn817fMuS7zqoXNNZGaw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.46.4", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@vitejs/plugin-react": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.1.tgz", - "integrity": "sha512-WQfkSw0QbQ5aJ2CHYw23ZGkqnRwqKHD/KYsMeTkZzPT4Jcf0DcBxBtwMJxnu6E7oxw5+JC6ZAiePgh28uJ1HBA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.28.5", - "@babel/plugin-transform-react-jsx-self": "^7.27.1", - "@babel/plugin-transform-react-jsx-source": "^7.27.1", - "@rolldown/pluginutils": "1.0.0-beta.47", - "@types/babel__core": "^7.20.5", - "react-refresh": "^0.18.0" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" - } - }, - "node_modules/@vitest/expect": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.9.tgz", - "integrity": "sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/spy": "2.1.9", - "@vitest/utils": "2.1.9", - "chai": "^5.1.2", - "tinyrainbow": "^1.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/pretty-format": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", - "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "tinyrainbow": "^1.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/runner": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.9.tgz", - "integrity": "sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/utils": "2.1.9", - "pathe": "^1.1.2" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/snapshot": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.9.tgz", - "integrity": "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "2.1.9", - "magic-string": "^0.30.12", - "pathe": "^1.1.2" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/spy": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.9.tgz", - "integrity": "sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "tinyspy": "^3.0.2" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/utils": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.9.tgz", - "integrity": "sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/pretty-format": "2.1.9", - "loupe": "^3.1.2", - "tinyrainbow": "^1.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/aria-query": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", - "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "dequal": "^2.0.3" - } - }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "license": "MIT" - }, - "node_modules/axios": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", - "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/baseline-browser-mapping": { - "version": "2.8.28", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.28.tgz", - "integrity": "sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "baseline-browser-mapping": "dist/cli.js" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz", - "integrity": "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "baseline-browser-mapping": "^2.8.25", - "caniuse-lite": "^1.0.30001754", - "electron-to-chromium": "^1.5.249", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.1.4" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001755", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001755.tgz", - "integrity": "sha512-44V+Jm6ctPj7R52Na4TLi3Zri4dWUljJd+RDm+j8LtNCc/ihLCT+X1TzoOAkRETEWqjuLnh9581Tl80FvK7jVA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/chai": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", - "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", - "dev": true, - "license": "MIT", - "dependencies": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/check-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", - "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 16" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" - }, - "node_modules/cookie": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", - "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/css.escape": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", - "dev": true, - "license": "MIT" - }, - "node_modules/cssstyle": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.6.0.tgz", - "integrity": "sha512-2z+rWdzbbSZv6/rhtvzvqeZQHrBaqgogqt85sqFNbabZOuFbCVFb8kPeEtZjiKkbrm395irpNKiYeFeLiQnFPg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@asamuzakjp/css-color": "^3.2.0", - "rrweb-cssom": "^0.8.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/cssstyle/node_modules/rrweb-cssom": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", - "integrity": "sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==", - "dev": true, - "license": "MIT" - }, - "node_modules/csstype": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "devOptional": true, - "license": "MIT" - }, - "node_modules/data-urls": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", - "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decimal.js": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", - "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", - "dev": true, - "license": "MIT" - }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/dom-accessibility-api": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", - "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.5.254", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.254.tgz", - "integrity": "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg==", - "dev": true, - "license": "ISC" - }, - "node_modules/entities": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", - "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/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" - } - }, - "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-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", - "dev": true, - "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" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "9.39.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.1.tgz", - "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.8.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.1", - "@eslint/config-helpers": "^0.4.2", - "@eslint/core": "^0.17.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.39.1", - "@eslint/plugin-kit": "^0.4.1", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.4.0", - "eslint-visitor-keys": "^4.2.1", - "espree": "^10.4.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-react-hooks": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.0.1.tgz", - "integrity": "sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.24.4", - "@babel/parser": "^7.24.4", - "hermes-parser": "^0.25.1", - "zod": "^3.25.0 || ^4.0.0", - "zod-validation-error": "^3.5.0 || ^4.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" - } - }, - "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.24.tgz", - "integrity": "sha512-nLHIW7TEq3aLrEYWpVaJ1dRgFR+wLDPN8e8FpYAql/bMV2oBEfC37K0gLEGgv9fy66juNShSMV8OkTqzltcG/w==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "eslint": ">=8.40" - } - }, - "node_modules/eslint-scope": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", - "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.15.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expect-type": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", - "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", - "dev": true, - "license": "ISC" - }, - "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", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/form-data": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-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", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "16.5.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz", - "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-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" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hermes-estree": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", - "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==", - "dev": true, - "license": "MIT" - }, - "node_modules/hermes-parser": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", - "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "hermes-estree": "0.25.1" - } - }, - "node_modules/html-encoding-sniffer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", - "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "whatwg-encoding": "^3.1.1" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsdom": { - "version": "25.0.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.1.tgz", - "integrity": "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssstyle": "^4.1.0", - "data-urls": "^5.0.0", - "decimal.js": "^10.4.3", - "form-data": "^4.0.0", - "html-encoding-sniffer": "^4.0.0", - "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.5", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.12", - "parse5": "^7.1.2", - "rrweb-cssom": "^0.7.1", - "saxes": "^6.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^5.0.0", - "w3c-xmlserializer": "^5.0.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^3.1.1", - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0", - "ws": "^8.18.0", - "xml-name-validator": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "canvas": "^2.11.2" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/loupe": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", - "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/lucide-react": { - "version": "0.554.0", - "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.554.0.tgz", - "integrity": "sha512-St+z29uthEJVx0Is7ellNkgTEhaeSoA42I7JjOCBCrc5X6LYMGSv0P/2uS5HDLTExP5tpiqRD2PyUEOS6s9UXA==", - "license": "ISC", - "peerDependencies": { - "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" - } - }, - "node_modules/lz-string": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", - "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", - "dev": true, - "license": "MIT", - "peer": true, - "bin": { - "lz-string": "bin/bin.js" - } - }, - "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" - } - }, - "node_modules/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" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/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/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/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT" - }, - "node_modules/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==", - "dev": true, - "license": "MIT" - }, - "node_modules/nwsapi": { - "version": "2.2.22", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.22.tgz", - "integrity": "sha512-ujSMe1OWVn55euT1ihwCI1ZcAaAU3nxUiDwfDQldc51ZXaB9m2AyOn6/jh1BLe2t/G8xd6uKG1UBF2aZJeg2SQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse5": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", - "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", - "dev": true, - "license": "MIT", - "dependencies": { - "entities": "^6.0.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/pathe": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/pathval": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", - "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.16" - } - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/react": { - "version": "19.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", - "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "19.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", - "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", - "license": "MIT", - "dependencies": { - "scheduler": "^0.27.0" - }, - "peerDependencies": { - "react": "^19.2.0" - } - }, - "node_modules/react-hook-form": { - "version": "7.66.0", - "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.66.0.tgz", - "integrity": "sha512-xXBqsWGKrY46ZqaHDo+ZUYiMUgi8suYu5kdrS20EG8KiL7VRQitEbNjm+UcrDYrNi1YLyfpmAeGjCZYXLT9YBw==", - "license": "MIT", - "engines": { - "node": ">=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/react-hook-form" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17 || ^18 || ^19" - } - }, - "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true, - "license": "MIT", - "peer": true - }, - "node_modules/react-refresh": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", - "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-router": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.9.6.tgz", - "integrity": "sha512-Y1tUp8clYRXpfPITyuifmSoE2vncSME18uVLgaqyxh9H35JWpIfzHo+9y3Fzh5odk/jxPW29IgLgzcdwxGqyNA==", - "license": "MIT", - "dependencies": { - "cookie": "^1.0.1", - "set-cookie-parser": "^2.6.0" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "react": ">=18", - "react-dom": ">=18" - }, - "peerDependenciesMeta": { - "react-dom": { - "optional": true - } - } - }, - "node_modules/react-router-dom": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.9.6.tgz", - "integrity": "sha512-2MkC2XSXq6HjGcihnx1s0DBWQETI4mlis4Ux7YTLvP67xnGxCvq+BcCQSO81qQHVUTM1V53tl4iVVaY5sReCOA==", - "license": "MIT", - "dependencies": { - "react-router": "7.9.6" - }, - "engines": { - "node": ">=20.0.0" - }, - "peerDependencies": { - "react": ">=18", - "react-dom": ">=18" - } - }, - "node_modules/redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dev": true, - "license": "MIT", - "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rollup": { - "version": "4.53.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.2.tgz", - "integrity": "sha512-MHngMYwGJVi6Fmnk6ISmnk7JAHRNF0UkuucA0CUW3N3a4KnONPEZz+vUanQP/ZC/iY1Qkf3bwPWzyY84wEks1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.8" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.53.2", - "@rollup/rollup-android-arm64": "4.53.2", - "@rollup/rollup-darwin-arm64": "4.53.2", - "@rollup/rollup-darwin-x64": "4.53.2", - "@rollup/rollup-freebsd-arm64": "4.53.2", - "@rollup/rollup-freebsd-x64": "4.53.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.53.2", - "@rollup/rollup-linux-arm-musleabihf": "4.53.2", - "@rollup/rollup-linux-arm64-gnu": "4.53.2", - "@rollup/rollup-linux-arm64-musl": "4.53.2", - "@rollup/rollup-linux-loong64-gnu": "4.53.2", - "@rollup/rollup-linux-ppc64-gnu": "4.53.2", - "@rollup/rollup-linux-riscv64-gnu": "4.53.2", - "@rollup/rollup-linux-riscv64-musl": "4.53.2", - "@rollup/rollup-linux-s390x-gnu": "4.53.2", - "@rollup/rollup-linux-x64-gnu": "4.53.2", - "@rollup/rollup-linux-x64-musl": "4.53.2", - "@rollup/rollup-openharmony-arm64": "4.53.2", - "@rollup/rollup-win32-arm64-msvc": "4.53.2", - "@rollup/rollup-win32-ia32-msvc": "4.53.2", - "@rollup/rollup-win32-x64-gnu": "4.53.2", - "@rollup/rollup-win32-x64-msvc": "4.53.2", - "fsevents": "~2.3.2" - } - }, - "node_modules/rrweb-cssom": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", - "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", - "dev": true, - "license": "MIT" - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "license": "MIT" - }, - "node_modules/saxes": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", - "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", - "dev": true, - "license": "ISC", - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=v12.22.7" - } - }, - "node_modules/scheduler": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", - "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", - "license": "MIT" - }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/set-cookie-parser": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", - "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", - "license": "MIT" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/siginfo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true, - "license": "ISC" - }, - "node_modules/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==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stackback": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true, - "license": "MIT" - }, - "node_modules/std-env": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", - "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", - "dev": true, - "license": "MIT" - }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true, - "license": "MIT" - }, - "node_modules/tinybench": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", - "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", - "dev": true, - "license": "MIT" - }, - "node_modules/tinyexec": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", - "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.3" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/tinyglobby/node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/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==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.0.0 || >=20.0.0" - } - }, - "node_modules/tinyrainbow": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", - "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tinyspy": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", - "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tldts": { - "version": "6.1.86", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", - "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "tldts-core": "^6.1.86" - }, - "bin": { - "tldts": "bin/cli.js" - } - }, - "node_modules/tldts-core": { - "version": "6.1.86", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", - "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==", - "dev": true, - "license": "MIT" - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tough-cookie": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", - "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tldts": "^6.1.32" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/tr46": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.1.tgz", - "integrity": "sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==", - "dev": true, - "license": "MIT", - "dependencies": { - "punycode": "^2.3.1" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/ts-api-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", - "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.12" - }, - "peerDependencies": { - "typescript": ">=4.8.4" - } - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typescript-eslint": { - "version": "8.46.4", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.46.4.tgz", - "integrity": "sha512-KALyxkpYV5Ix7UhvjTwJXZv76VWsHG+NjNlt/z+a17SOQSiOcBdUXdbJdyXi7RPxrBFECtFOiPwUJQusJuCqrg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/eslint-plugin": "8.46.4", - "@typescript-eslint/parser": "8.46.4", - "@typescript-eslint/typescript-estree": "8.46.4", - "@typescript-eslint/utils": "8.46.4" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" - } - }, - "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==", - "dev": true, - "license": "MIT" - }, - "node_modules/update-browserslist-db": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", - "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/vite": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.2.tgz", - "integrity": "sha512-BxAKBWmIbrDgrokdGZH1IgkIk/5mMHDreLDmCJ0qpyJaAteP8NvMhkwr/ZCQNqNH97bw/dANTE9PDzqwJghfMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.25.0", - "fdir": "^6.5.0", - "picomatch": "^4.0.3", - "postcss": "^8.5.6", - "rollup": "^4.43.0", - "tinyglobby": "^0.2.15" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^20.19.0 || >=22.12.0", - "jiti": ">=1.21.0", - "less": "^4.0.0", - "lightningcss": "^1.21.0", - "sass": "^1.70.0", - "sass-embedded": "^1.70.0", - "stylus": ">=0.54.8", - "sugarss": "^5.0.0", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } - }, - "node_modules/vite-node": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.9.tgz", - "integrity": "sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==", - "dev": true, - "license": "MIT", - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.3.7", - "es-module-lexer": "^1.5.4", - "pathe": "^1.1.2", - "vite": "^5.0.0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/vite-node/node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite-node/node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, - "node_modules/vite-node/node_modules/vite": { - "version": "5.4.21", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", - "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vite/node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/vite/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/vitest": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.9.tgz", - "integrity": "sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/expect": "2.1.9", - "@vitest/mocker": "2.1.9", - "@vitest/pretty-format": "^2.1.9", - "@vitest/runner": "2.1.9", - "@vitest/snapshot": "2.1.9", - "@vitest/spy": "2.1.9", - "@vitest/utils": "2.1.9", - "chai": "^5.1.2", - "debug": "^4.3.7", - "expect-type": "^1.1.0", - "magic-string": "^0.30.12", - "pathe": "^1.1.2", - "std-env": "^3.8.0", - "tinybench": "^2.9.0", - "tinyexec": "^0.3.1", - "tinypool": "^1.0.1", - "tinyrainbow": "^1.2.0", - "vite": "^5.0.0", - "vite-node": "2.1.9", - "why-is-node-running": "^2.3.0" - }, - "bin": { - "vitest": "vitest.mjs" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "2.1.9", - "@vitest/ui": "2.1.9", - "happy-dom": "*", - "jsdom": "*" - }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@types/node": { - "optional": true - }, - "@vitest/browser": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - } - } - }, - "node_modules/vitest/node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vitest/node_modules/@vitest/mocker": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.9.tgz", - "integrity": "sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@vitest/spy": "2.1.9", - "estree-walker": "^3.0.3", - "magic-string": "^0.30.12" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "msw": "^2.4.9", - "vite": "^5.0.0" - }, - "peerDependenciesMeta": { - "msw": { - "optional": true - }, - "vite": { - "optional": true - } - } - }, - "node_modules/vitest/node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, - "node_modules/vitest/node_modules/vite": { - "version": "5.4.21", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", - "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/w3c-xmlserializer": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", - "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "xml-name-validator": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - } - }, - "node_modules/whatwg-encoding": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "iconv-lite": "0.6.3" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/whatwg-mimetype": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/whatwg-url": { - "version": "14.2.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", - "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", - "dev": true, - "license": "MIT", - "dependencies": { - "tr46": "^5.1.0", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/why-is-node-running": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", - "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", - "dev": true, - "license": "MIT", - "dependencies": { - "siginfo": "^2.0.0", - "stackback": "0.0.2" - }, - "bin": { - "why-is-node-running": "cli.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ws": { - "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xml-name-validator": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", - "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true, - "license": "MIT" - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "license": "ISC" - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/zod": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.12.tgz", - "integrity": "sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zod-validation-error": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz", - "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "zod": "^3.25.0 || ^4.0.0" - } - }, - "node_modules/zustand": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.8.tgz", - "integrity": "sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw==", - "license": "MIT", - "engines": { - "node": ">=12.20.0" - }, - "peerDependencies": { - "@types/react": ">=18.0.0", - "immer": ">=9.0.6", - "react": ">=18.0.0", - "use-sync-external-store": ">=1.2.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "immer": { - "optional": true - }, - "react": { - "optional": true - }, - "use-sync-external-store": { - "optional": true - } - } - } - } -} diff --git a/site-builder/package.json b/site-builder/package.json deleted file mode 100644 index 02933603..00000000 --- a/site-builder/package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "name": "site-builder", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "dev": "vite", - "build": "tsc -b && vite build", - "lint": "eslint .", - "preview": "vite preview", - "test": "vitest run", - "test:watch": "vitest" - }, - "dependencies": { - "axios": "^1.13.2", - "lucide-react": "^0.554.0", - "react": "^19.2.0", - "react-dom": "^19.2.0", - "react-hook-form": "^7.66.0", - "react-router-dom": "^7.9.6", - "zustand": "^5.0.8" - }, - "devDependencies": { - "@testing-library/jest-dom": "^6.6.3", - "@testing-library/react": "^16.2.0", - "@eslint/js": "^9.39.1", - "@types/node": "^24.10.0", - "@types/react": "^19.2.2", - "@types/react-dom": "^19.2.2", - "@types/react-router-dom": "^5.3.3", - "@vitejs/plugin-react": "^5.1.0", - "eslint": "^9.39.1", - "eslint-plugin-react-hooks": "^7.0.1", - "eslint-plugin-react-refresh": "^0.4.24", - "globals": "^16.5.0", - "typescript": "~5.9.3", - "typescript-eslint": "^8.46.3", - "vite": "^7.2.2", - "vitest": "^2.1.5", - "jsdom": "^25.0.1" - } -} diff --git a/site-builder/public/vite.svg b/site-builder/public/vite.svg deleted file mode 100644 index e7b8dfb1..00000000 --- a/site-builder/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/site-builder/src/App.css b/site-builder/src/App.css deleted file mode 100644 index c9137d76..00000000 --- a/site-builder/src/App.css +++ /dev/null @@ -1,330 +0,0 @@ -.app-shell { - display: grid; - grid-template-columns: 280px 1fr; - min-height: 100vh; - background: #f5f7fb; - color: #0f172a; -} - -.app-sidebar { - border-right: 1px solid rgba(15, 23, 42, 0.08); - padding: 2rem 1.5rem; - display: flex; - flex-direction: column; - gap: 2rem; - background: #ffffff; -} - -.app-sidebar .brand span { - font-size: 1.25rem; - font-weight: 700; - display: block; -} - -.app-sidebar .brand small { - color: #64748b; -} - -.app-sidebar nav { - display: flex; - flex-direction: column; - gap: 0.75rem; -} - -.app-sidebar a { - display: flex; - align-items: center; - gap: 0.75rem; - padding: 0.6rem 0.75rem; - border-radius: 10px; - text-decoration: none; - color: inherit; - font-weight: 500; -} - -.app-sidebar a.active { - background: #eef2ff; - color: #4338ca; -} - -.app-main { - padding: 2rem 3rem; - overflow-y: auto; -} - -.wizard-page { - display: flex; - flex-direction: column; - gap: 1.5rem; -} - -.wizard-progress { - display: flex; - gap: 1rem; - flex-wrap: wrap; -} - -.wizard-progress__dot { - display: flex; - flex-direction: column; - align-items: center; - gap: 0.35rem; - border: none; - background: transparent; - color: #94a3b8; - font-weight: 500; - cursor: pointer; -} - -.wizard-progress__dot span { - width: 34px; - height: 34px; - border-radius: 50%; - border: 2px solid currentColor; - display: grid; - place-items: center; -} - -.wizard-progress__dot.is-active { - color: #4338ca; -} - -.wizard-step { - margin-top: 1rem; -} - -.wizard-actions { - display: flex; - justify-content: space-between; - gap: 1rem; -} - -.wizard-actions button { - padding: 0.75rem 1.5rem; - border-radius: 12px; - border: 1px solid rgba(67, 56, 202, 0.3); - background: #fff; - cursor: pointer; -} - -.wizard-actions button.primary { - background: #4338ca; - color: #fff; - border-color: transparent; - display: inline-flex; - align-items: center; - gap: 0.4rem; -} - -.wizard-actions button.ghost, -.ghost { - background: transparent; - border-color: rgba(67, 56, 202, 0.35); - color: #4338ca; -} - -.wizard-actions button:disabled { - opacity: 0.5; - cursor: not-allowed; -} - -.sb-error { - color: #dc2626; - margin: 0.5rem 0 0; -} - -.sb-grid { - display: grid; - gap: 1rem; - grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); -} - -.sb-field { - display: flex; - flex-direction: column; - gap: 0.4rem; - font-size: 0.95rem; - color: #0f172a; -} - -.sb-field input, -.sb-field select, -.sb-field textarea { - border: 1px solid rgba(15, 23, 42, 0.15); - border-radius: 10px; - padding: 0.65rem 0.85rem; - font-size: 0.95rem; - font-family: inherit; - background: #f8fafc; -} - -.sb-pill-list { - display: flex; - flex-wrap: wrap; - gap: 0.5rem; -} - -.sb-pill { - padding: 0.35rem 0.75rem; - border-radius: 999px; - background: rgba(67, 56, 202, 0.1); - color: #4338ca; - display: inline-flex; - align-items: center; - gap: 0.35rem; -} - -.sb-pill button { - border: none; - background: transparent; - color: inherit; - cursor: pointer; -} - -.sb-objective-input { - display: flex; - gap: 0.5rem; -} - -.sb-objective-input input { - flex: 1; -} - -.sb-objective-input button { - border: none; - background: #0f172a; - color: #fff; - border-radius: 10px; - padding: 0.65rem 1rem; - cursor: pointer; -} - -.sb-blueprint-meta { - display: flex; - justify-content: space-between; - align-items: center; -} - -.status-dot { - display: inline-flex; - align-items: center; - gap: 0.35rem; - text-transform: capitalize; -} - -.status-dot::before { - content: ''; - width: 10px; - height: 10px; - border-radius: 50%; - background: currentColor; -} - -.status-ready { - color: #10b981; -} - -.status-generating { - color: #f97316; -} - -.status-draft { - color: #94a3b8; -} - -.preview-canvas { - background: #fff; - border-radius: 18px; - padding: 1.5rem; - box-shadow: 0 8px 26px rgba(15, 23, 42, 0.08); -} - -.preview-nav { - display: flex; - gap: 0.5rem; - flex-wrap: wrap; - margin-bottom: 1rem; -} - -.preview-nav button { - border: 1px solid rgba(15, 23, 42, 0.1); - background: #f8fafc; - border-radius: 999px; - padding: 0.35rem 0.85rem; - cursor: pointer; -} - -.preview-nav button.is-active { - background: #4338ca; - color: white; - border-color: transparent; -} - -.preview-hero { - margin-bottom: 1.25rem; -} - -.preview-hero .preview-label { - text-transform: uppercase; - font-size: 0.7rem; - letter-spacing: 0.08em; - color: #94a3b8; -} - -.preview-blocks { - display: grid; - gap: 1rem; -} - -.preview-block { - border: 1px dashed rgba(67, 56, 202, 0.2); - border-radius: 14px; - padding: 1rem; - background: rgba(67, 56, 202, 0.04); -} - -.sb-blueprint-list { - list-style: none; - padding: 0; - margin: 0; - display: flex; - flex-direction: column; - gap: 1rem; -} - -.sb-blueprint-list li { - display: flex; - justify-content: space-between; - align-items: center; - padding-bottom: 0.75rem; - border-bottom: 1px solid rgba(15, 23, 42, 0.08); -} - -.sb-blueprint-list strong { - display: block; -} - -.sb-blueprint-list span { - color: #475569; - font-size: 0.9rem; -} - -.sb-loading { - display: flex; - align-items: center; - gap: 0.5rem; - color: #475569; -} - -.spin { - animation: spin 1s linear infinite; -} - -@keyframes spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} diff --git a/site-builder/src/App.tsx b/site-builder/src/App.tsx deleted file mode 100644 index cf68126b..00000000 --- a/site-builder/src/App.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import { NavLink, Route, Routes } from 'react-router-dom'; -import { Wand2, LayoutTemplate, PanelsTopLeft } from 'lucide-react'; -import { WizardPage } from './pages/wizard/WizardPage'; -import { PreviewCanvas } from './pages/preview/PreviewCanvas'; -import { SiteDashboard } from './pages/dashboard/SiteDashboard'; -import './App.css'; - -function App() { - return ( -
- - -
- - } /> - } /> - } /> - -
-
- ); -} - -export default App; diff --git a/site-builder/src/api/builder.api.ts b/site-builder/src/api/builder.api.ts deleted file mode 100644 index ec4f55f8..00000000 --- a/site-builder/src/api/builder.api.ts +++ /dev/null @@ -1,86 +0,0 @@ -import axios from 'axios'; -import type { - BuilderFormData, - PageBlueprint, - SiteBlueprint, - SiteStructure, -} from '../types/siteBuilder'; - -const API_ROOT = import.meta.env.VITE_API_URL ?? 'http://localhost:8010/api'; -const BASE_PATH = `${API_ROOT}/v1/site-builder`; - -const client = axios.create({ - baseURL: BASE_PATH, - withCredentials: true, -}); - -export interface CreateBlueprintPayload { - name: string; - description?: string; - site_id: number; - sector_id: number; - hosting_type: BuilderFormData['hostingType']; - config_json: Record; -} - -export interface GenerateStructurePayload { - business_brief: string; - objectives: string[]; - style: BuilderFormData['style']; - metadata?: Record; -} - -export const builderApi = { - async getBlueprint(blueprintId: number): Promise { - const res = await client.get(`/blueprints/${blueprintId}/`); - return res.data; - }, - async listBlueprints(): Promise { - const res = await client.get('/blueprints/'); - if (Array.isArray(res.data?.results)) { - return res.data.results as SiteBlueprint[]; - } - return Array.isArray(res.data) ? res.data : []; - }, - - async createBlueprint(payload: CreateBlueprintPayload): Promise { - const res = await client.post('/blueprints/', payload); - return res.data; - }, - - async generateStructure( - blueprintId: number, - payload: GenerateStructurePayload, - ): Promise<{ task_id?: string; success?: boolean; structure?: SiteStructure }> { - const res = await client.post(`/blueprints/${blueprintId}/generate_structure/`, payload); - return res.data; - }, - - async listPages(blueprintId: number): Promise { - const res = await client.get(`/pages/?site_blueprint=${blueprintId}`); - return Array.isArray(res.data?.results) ? res.data.results : res.data; - }, - - async generateAllPages( - blueprintId: number, - options?: { pageIds?: number[]; force?: boolean }, - ): Promise<{ success: boolean; pages_queued: number; task_ids: number[]; celery_task_id?: string }> { - const res = await client.post(`/blueprints/${blueprintId}/generate_all_pages/`, { - page_ids: options?.pageIds, - force: options?.force || false, - }); - return res.data?.data || res.data; - }, - - async createTasksForPages( - blueprintId: number, - pageIds?: number[], - ): Promise<{ tasks: unknown[]; count: number }> { - const res = await client.post(`/blueprints/${blueprintId}/create_tasks/`, { - page_ids: pageIds, - }); - return res.data?.data || res.data; - }, -}; - - diff --git a/site-builder/src/api/system.api.ts b/site-builder/src/api/system.api.ts deleted file mode 100644 index 715efb6b..00000000 --- a/site-builder/src/api/system.api.ts +++ /dev/null @@ -1,27 +0,0 @@ -import axios from 'axios'; - -const API_ROOT = import.meta.env.VITE_API_URL ?? 'http://localhost:8010/api'; - -const client = axios.create({ - baseURL: API_ROOT, - withCredentials: true, -}); - -export interface TaskProgressResponse { - state: 'PENDING' | 'PROGRESS' | 'SUCCESS' | 'FAILURE'; - meta?: { - phase?: string; - percentage?: number; - message?: string; - error?: string; - }; -} - -export const systemApi = { - async getTaskProgress(taskId: string): Promise { - const res = await client.get(`/v1/system/settings/task_progress/${taskId}/`); - return res.data; - }, -}; - - diff --git a/site-builder/src/assets/react.svg b/site-builder/src/assets/react.svg deleted file mode 100644 index 6c87de9b..00000000 --- a/site-builder/src/assets/react.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/site-builder/src/components/common/Card.css b/site-builder/src/components/common/Card.css deleted file mode 100644 index 1ba25342..00000000 --- a/site-builder/src/components/common/Card.css +++ /dev/null @@ -1,45 +0,0 @@ -.sb-card { - background: #ffffff; - border-radius: 16px; - border: 1px solid rgba(15, 23, 42, 0.08); - padding: 1.5rem; - box-shadow: 0 8px 24px rgba(15, 23, 42, 0.05); - display: flex; - flex-direction: column; - gap: 1rem; -} - -.sb-card__header { - display: flex; - flex-direction: column; - gap: 0.35rem; -} - -.sb-card__title { - font-size: 1.1rem; - font-weight: 600; - color: #0f172a; - margin: 0; -} - -.sb-card__description { - color: #475569; - margin: 0; - font-size: 0.95rem; -} - -.sb-card__body { - display: flex; - flex-direction: column; - gap: 1rem; -} - -.sb-card__footer { - border-top: 1px solid rgba(15, 23, 42, 0.06); - padding-top: 1rem; - display: flex; - justify-content: flex-end; - gap: 0.75rem; -} - - diff --git a/site-builder/src/components/common/Card.tsx b/site-builder/src/components/common/Card.tsx deleted file mode 100644 index 841c48cf..00000000 --- a/site-builder/src/components/common/Card.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import type { PropsWithChildren, ReactNode } from 'react'; -import './Card.css'; - -interface CardProps extends PropsWithChildren { - title?: ReactNode; - description?: ReactNode; - footer?: ReactNode; -} - -export function Card({ title, description, footer, children }: CardProps) { - return ( -
- {(title || description) && ( -
- {title &&

{title}

} - {description &&

{description}

} -
- )} -
{children}
- {footer &&
{footer}
} -
- ); -} - - diff --git a/site-builder/src/components/common/ProgressModal.css b/site-builder/src/components/common/ProgressModal.css deleted file mode 100644 index 3e6836f2..00000000 --- a/site-builder/src/components/common/ProgressModal.css +++ /dev/null @@ -1,118 +0,0 @@ -.progress-modal-overlay { - position: fixed; - inset: 0; - background: rgba(0, 0, 0, 0.5); - display: flex; - align-items: center; - justify-content: center; - z-index: 1000; -} - -.progress-modal { - background: white; - border-radius: 8px; - padding: 24px; - min-width: 400px; - max-width: 500px; - box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); -} - -.progress-modal-header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 16px; -} - -.progress-modal-header h3 { - margin: 0; - font-size: 18px; - font-weight: 600; -} - -.progress-modal-close { - background: none; - border: none; - cursor: pointer; - padding: 4px; - display: flex; - align-items: center; - justify-content: center; - color: #666; - transition: color 0.2s; -} - -.progress-modal-close:hover { - color: #000; -} - -.progress-modal-content { - display: flex; - flex-direction: column; - gap: 16px; -} - -.progress-modal-message { - margin: 0; - color: #666; - font-size: 14px; -} - -.progress-modal-bar { - display: flex; - flex-direction: column; - gap: 8px; -} - -.progress-modal-bar-track { - height: 8px; - background: #e5e7eb; - border-radius: 4px; - overflow: hidden; -} - -.progress-modal-bar-fill { - height: 100%; - background: #3b82f6; - transition: width 0.3s ease; -} - -.progress-modal-bar-text { - font-size: 12px; - color: #666; - text-align: center; -} - -.progress-modal-spinner { - display: flex; - justify-content: center; - padding: 16px; -} - -.progress-modal-spinner .spin { - animation: spin 1s linear infinite; -} - -@keyframes spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} - -.progress-modal-task-id { - margin: 0; - font-size: 12px; - color: #999; - text-align: center; -} - -.progress-modal-task-id code { - background: #f3f4f6; - padding: 2px 6px; - border-radius: 4px; - font-family: monospace; -} - diff --git a/site-builder/src/components/common/ProgressModal.tsx b/site-builder/src/components/common/ProgressModal.tsx deleted file mode 100644 index 34813903..00000000 --- a/site-builder/src/components/common/ProgressModal.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import { useEffect } from 'react'; -import { X, Loader2 } from 'lucide-react'; -import './ProgressModal.css'; - -interface ProgressModalProps { - isOpen: boolean; - onClose: () => void; - title: string; - message?: string; - progress?: { - current: number; - total: number; - }; - taskId?: string; -} - -export function ProgressModal({ isOpen, onClose, title, message, progress, taskId }: ProgressModalProps) { - useEffect(() => { - if (isOpen) { - document.body.style.overflow = 'hidden'; - } else { - document.body.style.overflow = ''; - } - return () => { - document.body.style.overflow = ''; - }; - }, [isOpen]); - - if (!isOpen) return null; - - const progressPercent = progress ? Math.round((progress.current / progress.total) * 100) : 0; - - return ( -
-
e.stopPropagation()}> -
-

{title}

- -
- -
- {message &&

{message}

} - - {progress && ( -
-
-
-
- - {progress.current} of {progress.total} pages - -
- )} - - {!progress && ( -
- -
- )} - - {taskId && ( -

- Task ID: {taskId} -

- )} -
-
-
- ); -} - diff --git a/site-builder/src/components/shared/blocks/HeroBlock.tsx b/site-builder/src/components/shared/blocks/HeroBlock.tsx deleted file mode 100644 index 07424fbd..00000000 --- a/site-builder/src/components/shared/blocks/HeroBlock.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import './HeroBlock.css'; - -interface HeroBlockProps { - heading: string; - subheading?: string; - ctaLabel?: string; - secondaryCta?: string; - badge?: string; -} - -export function HeroBlock({ heading, subheading, ctaLabel, secondaryCta, badge }: HeroBlockProps) { - return ( -
- {badge && {badge}} -

{heading}

- {subheading &&

{subheading}

} -
- {ctaLabel && } - {secondaryCta && ( - - )} -
-
- ); -} - diff --git a/site-builder/src/components/shared/layouts/PageCanvas.css b/site-builder/src/components/shared/layouts/PageCanvas.css deleted file mode 100644 index b548b1b8..00000000 --- a/site-builder/src/components/shared/layouts/PageCanvas.css +++ /dev/null @@ -1,13 +0,0 @@ -.sb-page-canvas { - border-radius: 24px; - padding: 2.5rem; - box-shadow: 0 30px 80px rgba(15, 23, 42, 0.12); - border: 1px solid rgba(15, 23, 42, 0.08); -} - -.sb-page-canvas__body { - display: flex; - flex-direction: column; - gap: 2.25rem; -} - diff --git a/site-builder/src/components/shared/layouts/PageCanvas.tsx b/site-builder/src/components/shared/layouts/PageCanvas.tsx deleted file mode 100644 index 907dd0b7..00000000 --- a/site-builder/src/components/shared/layouts/PageCanvas.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import type { PropsWithChildren } from 'react'; -import { palette } from '../theme'; -import './PageCanvas.css'; - -export function PageCanvas({ children }: PropsWithChildren) { - return ( -
-
{children}
-
- ); -} - diff --git a/site-builder/src/components/shared/layouts/Section.css b/site-builder/src/components/shared/layouts/Section.css deleted file mode 100644 index 20daac20..00000000 --- a/site-builder/src/components/shared/layouts/Section.css +++ /dev/null @@ -1,39 +0,0 @@ -.sb-section { - border-radius: 20px; - padding: 1.75rem; - border: 1px solid rgba(15, 23, 42, 0.07); - background: #ffffff; - display: flex; - flex-direction: column; - gap: 1.25rem; -} - -.sb-section--soft { - background: #f4f6ff; -} - -.sb-section__header h3 { - margin: 0.15rem 0; - font-size: 1.8rem; - font-weight: 700; -} - -.sb-section__subtitle { - margin: 0; - color: #64748b; -} - -.sb-section__overline { - font-size: 0.75rem; - letter-spacing: 0.08em; - text-transform: uppercase; - color: #6366f1; - margin: 0; -} - -.sb-section__content { - display: flex; - flex-direction: column; - gap: 1rem; -} - diff --git a/site-builder/src/components/shared/layouts/Section.tsx b/site-builder/src/components/shared/layouts/Section.tsx deleted file mode 100644 index d4cf74c2..00000000 --- a/site-builder/src/components/shared/layouts/Section.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import type { PropsWithChildren, ReactNode } from 'react'; -import './Section.css'; - -interface SectionProps extends PropsWithChildren { - overline?: string; - title?: ReactNode; - subtitle?: ReactNode; - background?: 'surface' | 'soft'; -} - -export function Section({ overline, title, subtitle, background = 'surface', children }: SectionProps) { - return ( -
- {(overline || title || subtitle) && ( -
- {overline &&

{overline}

} - {title &&

{title}

} - {subtitle &&

{subtitle}

} -
- )} -
{children}
-
- ); -} - diff --git a/site-builder/src/components/shared/theme.ts b/site-builder/src/components/shared/theme.ts deleted file mode 100644 index 51ce000f..00000000 --- a/site-builder/src/components/shared/theme.ts +++ /dev/null @@ -1,29 +0,0 @@ -export const palette = { - background: '#f8fbff', - surface: '#ffffff', - accent: '#6366f1', - accentSoft: '#eef2ff', - text: '#0f172a', - textMuted: '#64748b', - border: 'rgba(15, 23, 42, 0.08)', -}; - -export const typography = { - title: { - fontSize: '2.5rem', - fontWeight: 700, - lineHeight: 1.1, - }, - subtitle: { - fontSize: '1.15rem', - color: palette.textMuted, - lineHeight: 1.5, - }, - label: { - fontSize: '0.75rem', - textTransform: 'uppercase', - letterSpacing: '0.08em', - color: palette.accent, - }, -}; - diff --git a/site-builder/src/hooks/useTaskProgress.ts b/site-builder/src/hooks/useTaskProgress.ts deleted file mode 100644 index 1f2c6b35..00000000 --- a/site-builder/src/hooks/useTaskProgress.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { useEffect, useState } from 'react'; -import { systemApi, type TaskProgressResponse } from '../api/system.api'; - -type TaskStatus = 'idle' | 'pending' | 'processing' | 'completed' | 'error'; - -interface UseTaskProgressOptions { - onComplete?: () => void; - onError?: (message: string) => void; - onUpdate?: (meta: TaskProgressResponse['meta']) => void; -} - -interface TaskProgressState { - status: TaskStatus; - percentage: number; - message?: string; - phase?: string; -} - -export function useTaskProgress(taskId: string | null, options: UseTaskProgressOptions = {}) { - const { onComplete, onError, onUpdate } = options; - const [state, setState] = useState({ - status: 'idle', - percentage: 0, - }); - - useEffect(() => { - if (!taskId) { - setState({ status: 'idle', percentage: 0 }); - return; - } - - let isActive = true; - let interval: ReturnType | null = null; - - const mapResponseToState = (response: TaskProgressResponse): TaskProgressState => { - const { state: taskState, meta } = response; - const percentage = typeof meta?.percentage === 'number' ? meta.percentage : 0; - const message = meta?.message; - const phase = meta?.phase; - - if (taskState === 'SUCCESS') { - return { status: 'completed', percentage: 100, message: message ?? 'Site structure ready.', phase }; - } - if (taskState === 'FAILURE') { - return { status: 'error', percentage, message: meta?.error ?? message ?? 'Task failed.', phase }; - } - if (taskState === 'PROGRESS') { - return { status: 'processing', percentage: Math.min(percentage || 10, 95), message, phase }; - } - return { status: 'pending', percentage, message, phase }; - }; - - const poll = async () => { - try { - const response = await systemApi.getTaskProgress(taskId); - - if (!isActive) return; - - const nextState = mapResponseToState(response); - setState(nextState); - onUpdate?.(response.meta); - - if (nextState.status === 'completed') { - onComplete?.(); - if (interval) { - clearInterval(interval); - interval = null; - } - } else if (nextState.status === 'error') { - onError?.(nextState.message ?? 'Task failed'); - if (interval) { - clearInterval(interval); - interval = null; - } - } - } catch (error) { - if (!isActive) return; - const message = error instanceof Error ? error.message : 'Unable to load task progress'; - setState({ status: 'error', percentage: 0, message }); - onError?.(message); - if (interval) { - clearInterval(interval); - interval = null; - } - } - }; - - poll(); - interval = setInterval(poll, 2000); - - return () => { - isActive = false; - if (interval) { - clearInterval(interval); - } - }; - }, [taskId, onComplete, onError, onUpdate]); - - return state; -} - - diff --git a/site-builder/src/index.css b/site-builder/src/index.css deleted file mode 100644 index e4368115..00000000 --- a/site-builder/src/index.css +++ /dev/null @@ -1,28 +0,0 @@ -:root { - font-family: 'Inter', 'Inter var', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; - color: #0f172a; - background-color: #f5f7fb; - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -*, -*::before, -*::after { - box-sizing: border-box; -} - -body { - margin: 0; - background: #f5f7fb; -} - -button { - font-family: inherit; -} - -a { - color: inherit; -} diff --git a/site-builder/src/main.tsx b/site-builder/src/main.tsx deleted file mode 100644 index 25e7a34e..00000000 --- a/site-builder/src/main.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { StrictMode } from 'react'; -import { createRoot } from 'react-dom/client'; -import { BrowserRouter } from 'react-router-dom'; -import './index.css'; -import App from './App.tsx'; - -createRoot(document.getElementById('root')!).render( - - - - - , -); diff --git a/site-builder/src/pages/dashboard/SiteDashboard.tsx b/site-builder/src/pages/dashboard/SiteDashboard.tsx deleted file mode 100644 index 659c25c8..00000000 --- a/site-builder/src/pages/dashboard/SiteDashboard.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import { useEffect, useState } from 'react'; -import { Loader2, Play } from 'lucide-react'; -import { builderApi } from '../../api/builder.api'; -import type { SiteBlueprint } from '../../types/siteBuilder'; -import { Card } from '../../components/common/Card'; -import { useBuilderStore } from '../../state/builderStore'; -import { ProgressModal } from '../../components/common/ProgressModal'; - -export function SiteDashboard() { - const [blueprints, setBlueprints] = useState([]); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(); - const { generateAllPages, isGenerating, generationProgress } = useBuilderStore(); - const [showProgress, setShowProgress] = useState(false); - - useEffect(() => { - const fetchData = async () => { - setLoading(true); - try { - const data = await builderApi.listBlueprints(); - setBlueprints(data); - } catch (err) { - setError(err instanceof Error ? err.message : 'Unable to load blueprints'); - } finally { - setLoading(false); - } - }; - fetchData(); - }, []); - - const handleGenerateAll = async (blueprintId: number) => { - setShowProgress(true); - try { - await generateAllPages(blueprintId); - } catch (err) { - setError(err instanceof Error ? err.message : 'Failed to generate pages'); - } - }; - - return ( - <> - - {loading && ( -
- Loading blueprints… -
- )} - - {error &&

{error}

} - - {!loading && !blueprints.length && ( -

You haven't generated any sites yet. Launch the wizard to create your first one.

- )} - -
    - {blueprints.map((bp) => ( -
  • -
    - {bp.name} - {bp.description} -
    -
    - {bp.status === 'ready' && ( - - )} - {bp.status} -
    -
  • - ))} -
-
- - setShowProgress(false)} - title="Generating Pages" - message={isGenerating ? 'Generating content for all pages...' : 'Generation completed!'} - progress={ - generationProgress - ? { - current: generationProgress.pagesQueued, - total: generationProgress.pagesQueued, - } - : undefined - } - taskId={generationProgress?.celeryTaskId} - /> - - ); -} - - diff --git a/site-builder/src/pages/preview/PreviewCanvas.tsx b/site-builder/src/pages/preview/PreviewCanvas.tsx deleted file mode 100644 index 0087afaa..00000000 --- a/site-builder/src/pages/preview/PreviewCanvas.tsx +++ /dev/null @@ -1,353 +0,0 @@ -import { useMemo } from 'react'; -import { - FeatureGridBlock, - HeroBlock, - MarketingTemplate, - StatsPanel, - type FeatureGridBlockProps, - type StatItem, -} from '@shared'; -import { useSiteDefinitionStore } from '../../state/siteDefinitionStore'; -import { useBuilderStore } from '../../state/builderStore'; -import type { PageBlock, PageBlueprint, SiteStructure } from '../../types/siteBuilder'; - -type StructuredContent = Record & { - items?: unknown[]; - eyebrow?: string; - ctaLabel?: string; - supportingCopy?: string; - columns?: number; -}; - -export function PreviewCanvas() { - const { structure, pages, selectedSlug, selectPage } = useSiteDefinitionStore(); - const { selectedPageIds, togglePageSelection, selectAllPages, clearPageSelection, activeBlueprint } = - useBuilderStore(); - - const page = useMemo(() => { - if (structure?.pages?.length) { - return structure.pages.find((p) => p.slug === selectedSlug) ?? structure.pages[0]; - } - return pages.find((p) => p.slug === selectedSlug) ?? pages[0]; - }, [structure, pages, selectedSlug]); - - if (!structure && !pages.length) { - return ( -
-

Generate a blueprint to see live previews of every page.

-
- ); - } - - const navItems = structure?.site?.primary_navigation ?? pages.map((p) => p.slug); - const blocks = getBlocks(page); - const heroBlock = blocks.find((block) => normalizeType(block.type) === 'hero'); - const contentBlocks = heroBlock ? blocks.filter((block) => block !== heroBlock) : blocks; - - const heroSection = - heroBlock || page - ? renderBlock(heroBlock ?? buildFallbackHero(page, structure)) - : null; - - const sectionNodes = - contentBlocks.length > 0 - ? contentBlocks.map((block, index) =>
{renderBlock(block)}
) - : buildFallbackSections(page); - - const sidebar = ( -
-

Page objective

-

{page?.objective ?? 'Launch a high-converting page'}

-
    - {buildSidebarInsights(page, structure).map((insight) => ( -
  • - {insight.label} - {insight.value} -
  • - ))} -
-
- ); - - // Only show page selection if we have actual PageBlueprint objects with IDs - const hasPageBlueprints = pages.length > 0 && pages.every((p) => p.id > 0); - - const allSelected = hasPageBlueprints && pages.length > 0 && selectedPageIds.length === pages.length; - const someSelected = hasPageBlueprints && selectedPageIds.length > 0 && selectedPageIds.length < pages.length; - - return ( -
-
- {hasPageBlueprints && activeBlueprint && ( -
-
- { - if (input) input.indeterminate = someSelected; - }} - onChange={(e) => { - if (e.target.checked) { - selectAllPages(); - } else { - clearPageSelection(); - } - }} - style={{ cursor: 'pointer' }} - /> - -
-
- {pages.map((p) => { - const isSelected = selectedPageIds.includes(p.id); - return ( - - ); - })} -
-
- )} - {navItems?.map((slug) => ( - - ))} -
- - -
- ); -} - -function getBlocks( - page: (SiteStructure['pages'][number] & { blocks_json?: PageBlock[] }) | PageBlueprint | undefined, -) { - if (!page) return []; - const fromStructure = (page as { blocks?: PageBlock[] }).blocks; - if (Array.isArray(fromStructure)) return fromStructure; - const fromBlueprint = (page as PageBlueprint).blocks_json; - return Array.isArray(fromBlueprint) ? fromBlueprint : []; -} - -function renderBlock(block?: PageBlock) { - if (!block) return null; - const type = normalizeType(block.type); - const structuredContent = extractStructuredContent(block); - const listContent = extractListContent(block, structuredContent); - - if (type === 'hero') { - return ( - 0 ? ( -
    - {listContent.map((item) => ( -
  • {String(item)}
  • - ))} -
- ) : undefined - } - /> - ); - } - - if (type === 'feature-grid' || type === 'features' || type === 'value-props') { - const features = toFeatureList(listContent, structuredContent.items); - const columns = normalizeColumns(structuredContent.columns, features.length); - return ; - } - - if (type === 'stats' || type === 'metrics') { - const stats = toStatItems(listContent, structuredContent.items, block); - if (!stats.length) return defaultBlock(block); - return ; - } - - return defaultBlock(block); -} - -function defaultBlock(block: PageBlock) { - return ( -
- {block.heading &&

{block.heading}

} - {block.subheading &&

{block.subheading}

} - {Array.isArray(block.content) && ( -
    - {block.content.map((item) => ( -
  • {item}
  • - ))} -
- )} -
- ); -} - -function normalizeType(type?: string) { - return (type ?? '').toLowerCase(); -} - -function extractStructuredContent(block: PageBlock): StructuredContent { - if (Array.isArray(block.content)) { - return {}; - } - return (block.content ?? {}) as StructuredContent; -} - -function extractListContent(block: PageBlock, structuredContent: StructuredContent): unknown[] { - if (Array.isArray(block.content)) { - return block.content; - } - if (Array.isArray(structuredContent.items)) { - return structuredContent.items; - } - return []; -} - -function toFeatureList(listItems: unknown[], structuredItems?: unknown[]): FeatureGridBlockProps['features'] { - const source = structuredItems && Array.isArray(structuredItems) && structuredItems.length > 0 ? structuredItems : listItems; - return source.map((item) => { - if (typeof item === 'string') { - return { title: item }; - } - if (typeof item === 'object' && item) { - const record = item as Record; - return { - title: String(record.title ?? record.heading ?? 'Feature'), - description: record.description ? String(record.description) : undefined, - icon: record.icon ? String(record.icon) : undefined, - }; - } - return { title: String(item) }; - }); -} - -function toStatItems( - listItems: unknown[], - structuredItems: unknown[] | undefined, - block: PageBlock, -): StatItem[] { - const source = structuredItems && Array.isArray(structuredItems) && structuredItems.length > 0 ? structuredItems : listItems; - return source - .map((item, index) => { - if (typeof item === 'string') { - return { - label: block.heading ?? `Metric ${index + 1}`, - value: item, - }; - } - if (typeof item === 'object' && item) { - const record = item as Record; - const label = record.label ?? record.title ?? `Metric ${index + 1}`; - const value = record.value ?? record.metric ?? record.score; - if (!value) return null; - return { - label: String(label), - value: String(value), - description: record.description ? String(record.description) : undefined, - }; - } - return null; - }) - .filter((stat): stat is StatItem => Boolean(stat)); -} - -function normalizeColumns( - candidate: StructuredContent['columns'], - featureCount: number, -): FeatureGridBlockProps['columns'] { - const inferred = typeof candidate === 'number' ? candidate : featureCount >= 4 ? 4 : featureCount === 2 ? 2 : 3; - if (inferred <= 2) return 2; - if (inferred >= 4) return 4; - return 3; -} - -function buildFallbackHero( - page: SiteStructure['pages'][number] | PageBlueprint | undefined, - structure: SiteStructure | undefined, -): PageBlock { - return { - type: 'hero', - heading: page?.title ?? 'Site Builder preview', - subheading: structure?.site?.hero_message ?? 'Preview updates as the AI hydrates your blueprint.', - content: Array.isArray(structure?.site?.secondary_navigation) ? structure?.site?.secondary_navigation : [], - }; -} - -function buildFallbackSections(page: SiteStructure['pages'][number] | PageBlueprint | undefined) { - return [ - , - , - ]; -} - -function buildSidebarInsights( - page: SiteStructure['pages'][number] | PageBlueprint | undefined, - structure: SiteStructure | undefined, -) { - return [ - { - label: 'Primary CTA', - value: page?.primary_cta ?? 'Book a demo', - }, - { - label: 'Tone', - value: structure?.site?.tone ?? 'Confident & clear', - }, - { - label: 'Status', - value: page?.status ?? 'Draft', - }, - ]; -} - - - diff --git a/site-builder/src/pages/preview/__tests__/PreviewCanvas.test.tsx b/site-builder/src/pages/preview/__tests__/PreviewCanvas.test.tsx deleted file mode 100644 index 2061e194..00000000 --- a/site-builder/src/pages/preview/__tests__/PreviewCanvas.test.tsx +++ /dev/null @@ -1,106 +0,0 @@ -import { describe, it, expect, vi, beforeEach } from 'vitest'; -import { render, screen } from '@testing-library/react'; -import { PreviewCanvas } from '../PreviewCanvas'; -import { useSiteDefinitionStore } from '../../../state/siteDefinitionStore'; - -vi.mock('../../../state/siteDefinitionStore'); - -describe('PreviewCanvas', () => { - const mockSelectPage = vi.fn(); - - beforeEach(() => { - vi.clearAllMocks(); - }); - - it('shows placeholder when no structure or pages', () => { - (useSiteDefinitionStore as any).mockReturnValue({ - structure: undefined, - pages: [], - selectedSlug: undefined, - selectPage: mockSelectPage, - }); - - render(); - - expect(screen.getByText(/generate a blueprint to see live previews/i)).toBeInTheDocument(); - }); - - it('renders pages from structure', () => { - const mockStructure = { - site: { name: 'Test Site', primary_navigation: ['home', 'about'] }, - pages: [ - { slug: 'home', title: 'Home', type: 'home', blocks: [] }, - { slug: 'about', title: 'About', type: 'about', blocks: [] }, - ], - }; - - (useSiteDefinitionStore as any).mockReturnValue({ - structure: mockStructure, - pages: [], - selectedSlug: 'home', - selectPage: mockSelectPage, - }); - - render(); - - expect(screen.getByText('Home')).toBeInTheDocument(); - // Check for navigation button specifically (there are multiple "home" elements) - const navButtons = screen.getAllByText('home'); - expect(navButtons.length).toBeGreaterThan(0); - }); - - it('renders pages from pages array when structure not available', () => { - const mockPages = [ - { - id: 1, - site_blueprint: 1, - slug: 'services', - title: 'Services', - type: 'services', - status: 'ready', - order: 0, - blocks_json: [], - }, - ]; - - (useSiteDefinitionStore as any).mockReturnValue({ - structure: undefined, - pages: mockPages, - selectedSlug: 'services', - selectPage: mockSelectPage, - }); - - render(); - - expect(screen.getByText('Services')).toBeInTheDocument(); - }); - - it('renders page blocks when available', () => { - const mockStructure = { - site: { name: 'Test Site' }, - pages: [ - { - slug: 'home', - title: 'Home', - type: 'home', - blocks: [ - { type: 'hero', heading: 'Welcome', subheading: 'Get started today' }, - ], - }, - ], - }; - - (useSiteDefinitionStore as any).mockReturnValue({ - structure: mockStructure, - pages: [], - selectedSlug: 'home', - selectPage: mockSelectPage, - }); - - render(); - - expect(screen.getByText('Welcome')).toBeInTheDocument(); - expect(screen.getByText('Get started today')).toBeInTheDocument(); - }); -}); - diff --git a/site-builder/src/pages/wizard/WizardPage.tsx b/site-builder/src/pages/wizard/WizardPage.tsx deleted file mode 100644 index 7c444076..00000000 --- a/site-builder/src/pages/wizard/WizardPage.tsx +++ /dev/null @@ -1,185 +0,0 @@ -import { useCallback, useEffect, useMemo, useState } from 'react'; -import { Loader2, PlayCircle, RefreshCw } from 'lucide-react'; -import { useBuilderStore } from '../../state/builderStore'; -import { useSiteDefinitionStore } from '../../state/siteDefinitionStore'; -import { BusinessDetailsStep } from './steps/BusinessDetailsStep'; -import { BriefStep } from './steps/BriefStep'; -import { ObjectivesStep } from './steps/ObjectivesStep'; -import { StyleStep } from './steps/StyleStep'; -import { Card } from '../../components/common/Card'; -import { ProgressModal } from '../../components/common/ProgressModal'; -import { useTaskProgress } from '../../hooks/useTaskProgress'; -import { builderApi } from '../../api/builder.api'; - -const stepTitles = ['Business', 'Brief', 'Objectives', 'Style']; - -export function WizardPage() { - const { - form, - currentStep, - setField, - updateStyle, - addObjective, - removeObjective, - nextStep, - previousStep, - setStep, - submitWizard, - isSubmitting, - error, - activeBlueprint, - refreshPages, - structureTaskId, - setStructureTaskId, - } = useBuilderStore(); - const structure = useSiteDefinitionStore((state) => state.structure); - const setStructure = useSiteDefinitionStore((state) => state.setStructure); - const [showProgressModal, setShowProgressModal] = useState(false); - const [progressMessage, setProgressMessage] = useState('Initializing Site Builder AI…'); - - const syncLatestStructure = useCallback(async () => { - if (!activeBlueprint) return; - try { - const latestBlueprint = await builderApi.getBlueprint(activeBlueprint.id); - if (latestBlueprint.structure_json) { - setStructure(latestBlueprint.structure_json); - } - await refreshPages(activeBlueprint.id); - } catch (syncError) { - const message = syncError instanceof Error ? syncError.message : 'Unable to sync blueprint'; - useBuilderStore.setState({ error: message }); - } finally { - setStructureTaskId(null); - } - }, [activeBlueprint, refreshPages, setStructure, setStructureTaskId]); - - const taskProgress = useTaskProgress(structureTaskId, { - onUpdate: (meta) => { - if (meta?.message) { - setProgressMessage(meta.message); - } - }, - onComplete: async () => { - setProgressMessage('Site structure ready!'); - await syncLatestStructure(); - setTimeout(() => setShowProgressModal(false), 500); - }, - onError: (message) => { - useBuilderStore.setState({ error: message }); - setShowProgressModal(false); - setStructureTaskId(null); - }, - }); - - useEffect(() => { - if (structureTaskId) { - setShowProgressModal(true); - setProgressMessage('Sending request to Site Builder AI…'); - } - }, [structureTaskId]); - - const stepComponents = useMemo( - () => [ - , - , - , - , - ], - [form, setField, addObjective, removeObjective, updateStyle], - ); - - return ( -
- -
- {stepTitles.map((title, idx) => ( - - ))} -
- -
{stepComponents[currentStep]}
- -
- - {currentStep < stepComponents.length - 1 ? ( - - ) : ( - - )} -
- - {error &&

{error}

} -
- - {activeBlueprint && ( - refreshPages(activeBlueprint.id)} disabled={isSubmitting}> - - Sync pages - - } - > -
-
- Status - {activeBlueprint.status} -
-
- Structure - {structure?.pages?.length ?? 0} pages -
-
-
- )} - { - if (taskProgress.status === 'processing') { - return; - } - setShowProgressModal(false); - setStructureTaskId(null); - }} - title="Generating site structure" - message={progressMessage} - progress={{ - current: Math.round(taskProgress.percentage), - total: 100, - }} - taskId={structureTaskId || undefined} - /> -
- ); -} - - diff --git a/site-builder/src/pages/wizard/__tests__/WizardPage.test.tsx b/site-builder/src/pages/wizard/__tests__/WizardPage.test.tsx deleted file mode 100644 index d5d7b664..00000000 --- a/site-builder/src/pages/wizard/__tests__/WizardPage.test.tsx +++ /dev/null @@ -1,187 +0,0 @@ -import { describe, it, expect, vi, beforeEach } from 'vitest'; -import { render, screen, fireEvent } from '@testing-library/react'; -import { WizardPage } from '../WizardPage'; -import { useBuilderStore } from '../../../state/builderStore'; -import { useSiteDefinitionStore } from '../../../state/siteDefinitionStore'; - -// Mock stores -vi.mock('../../../state/builderStore'); -vi.mock('../../../state/siteDefinitionStore'); - -describe('WizardPage', () => { - const mockSetField = vi.fn(); - const mockNextStep = vi.fn(); - const mockPreviousStep = vi.fn(); - const mockSetStep = vi.fn(); - const mockUpdateStyle = vi.fn(); - const mockAddObjective = vi.fn(); - const mockRemoveObjective = vi.fn(); - const mockSubmitWizard = vi.fn(); - const mockSetStructureTaskId = vi.fn(); - const mockRefreshPages = vi.fn(); - const mockSetStructure = vi.fn(); - - beforeEach(() => { - vi.clearAllMocks(); - (useBuilderStore as any).mockReturnValue({ - form: { - siteId: null, - sectorId: null, - siteName: '', - businessType: '', - industry: '', - targetAudience: '', - hostingType: 'igny8_sites', - businessBrief: '', - objectives: [], - style: {}, - }, - currentStep: 0, - isSubmitting: false, - error: undefined, - activeBlueprint: undefined, - structureTaskId: null, - setField: mockSetField, - nextStep: mockNextStep, - previousStep: mockPreviousStep, - setStep: mockSetStep, - updateStyle: mockUpdateStyle, - addObjective: mockAddObjective, - removeObjective: mockRemoveObjective, - submitWizard: mockSubmitWizard, - refreshPages: mockRefreshPages, - setStructureTaskId: mockSetStructureTaskId, - }); - (useSiteDefinitionStore as any).mockImplementation((selector?: (state: any) => any) => { - const state = { - structure: undefined, - setStructure: mockSetStructure, - }; - return selector ? selector(state) : state; - }); - }); - - it('renders wizard with step indicators', () => { - render(); - - expect(screen.getByText('Site builder wizard')).toBeInTheDocument(); - expect(screen.getByText('Business')).toBeInTheDocument(); - expect(screen.getByText('Brief')).toBeInTheDocument(); - expect(screen.getByText('Objectives')).toBeInTheDocument(); - expect(screen.getByText('Style')).toBeInTheDocument(); - }); - - it('allows navigation between steps', () => { - render(); - - const briefButton = screen.getByText('Brief'); - fireEvent.click(briefButton); - - expect(mockSetStep).toHaveBeenCalledWith(1); - }); - - it('disables back button on first step', () => { - render(); - - const backButton = screen.getByText('Back'); - expect(backButton).toBeDisabled(); - }); - - it('enables back button after first step', () => { - (useBuilderStore as any).mockReturnValue({ - form: {}, - currentStep: 1, - isSubmitting: false, - error: undefined, - activeBlueprint: undefined, - structureTaskId: null, - setField: mockSetField, - nextStep: mockNextStep, - previousStep: mockPreviousStep, - setStep: mockSetStep, - updateStyle: mockUpdateStyle, - addObjective: mockAddObjective, - removeObjective: mockRemoveObjective, - submitWizard: mockSubmitWizard, - refreshPages: mockRefreshPages, - setStructureTaskId: mockSetStructureTaskId, - }); - - render(); - - const backButton = screen.getByText('Back'); - expect(backButton).not.toBeDisabled(); - - fireEvent.click(backButton); - expect(mockPreviousStep).toHaveBeenCalled(); - }); - - it('shows error message when present', () => { - (useBuilderStore as any).mockReturnValue({ - form: {}, - currentStep: 0, - isSubmitting: false, - error: 'Test error message', - activeBlueprint: undefined, - structureTaskId: null, - setField: mockSetField, - nextStep: mockNextStep, - previousStep: mockPreviousStep, - setStep: mockSetStep, - updateStyle: mockUpdateStyle, - addObjective: mockAddObjective, - removeObjective: mockRemoveObjective, - submitWizard: mockSubmitWizard, - refreshPages: mockRefreshPages, - setStructureTaskId: mockSetStructureTaskId, - }); - - render(); - - expect(screen.getByText('Test error message')).toBeInTheDocument(); - }); - - it('shows loading state when submitting', () => { - (useBuilderStore as any).mockReturnValue({ - form: { - siteId: null, - sectorId: null, - siteName: '', - businessType: '', - industry: '', - targetAudience: '', - hostingType: 'igny8_sites', - businessBrief: '', - objectives: [], - style: { - palette: 'Vibrant modern palette', - typography: 'Sans-serif', - personality: 'Confident', - heroImagery: 'Real people', - }, - }, - currentStep: 3, - isSubmitting: true, - error: undefined, - activeBlueprint: undefined, - structureTaskId: null, - setField: mockSetField, - nextStep: mockNextStep, - previousStep: mockPreviousStep, - setStep: mockSetStep, - updateStyle: mockUpdateStyle, - addObjective: mockAddObjective, - removeObjective: mockRemoveObjective, - submitWizard: mockSubmitWizard, - refreshPages: mockRefreshPages, - setStructureTaskId: mockSetStructureTaskId, - }); - - render(); - - // When submitting, button text changes to "Generating…" - const submitButton = screen.getByText(/generating/i); - expect(submitButton).toBeDisabled(); - }); -}); - diff --git a/site-builder/src/pages/wizard/steps/BriefStep.tsx b/site-builder/src/pages/wizard/steps/BriefStep.tsx deleted file mode 100644 index d29af11e..00000000 --- a/site-builder/src/pages/wizard/steps/BriefStep.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import type { BuilderFormData } from '../../../types/siteBuilder'; -import { Card } from '../../../components/common/Card'; - -interface Props { - data: BuilderFormData; - onChange: (key: K, value: BuilderFormData[K]) => void; -} - -export function BriefStep({ data, onChange }: Props) { - return ( - -