From fa8e0c58ce7f9f870ff4ab71b827f1c8b126837d Mon Sep 17 00:00:00 2001 From: renato97 Date: Tue, 21 Jul 2026 15:31:46 -0300 Subject: [PATCH] =?UTF-8?q?feat:=20Puente=20May=C3=BAscula-Min=C3=BAscula?= =?UTF-8?q?=20+=20TTS=20SpeechSynthesis=20+=20E2E=20fixes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .atl/.skill-registry.cache.json | 3 + .atl/skill-registry.md | 38 + .gitignore | 11 + Dockerfile | 38 + PLAN.md | 219 + app/api/auth/[...all]/route.ts | 4 + app/api/children/route.ts | 57 + app/api/curriculum/grade/route.ts | 39 + app/api/curriculum/next/route.ts | 13 + app/api/curriculum/progress/route.ts | 77 + app/api/dashboard/summary/route.ts | 159 + app/api/fsrs/grade/route.ts | 57 + app/api/fsrs/next/route.ts | 35 + app/api/milestones/route.ts | 36 + app/api/pairing/route.ts | 98 + app/api/sessions/sync/route.ts | 36 + app/api/tts/route.ts | 49 + app/child/layout.tsx | 26 + app/child/lectura/page.tsx | 167 + app/child/logros/page.tsx | 78 + app/child/numeros/page.tsx | 167 + app/child/page.tsx | 34 + app/child/pairing/page.tsx | 90 + app/globals.css | 52 + app/layout.tsx | 38 + app/page.tsx | 19 + app/parent/auth/login/page.tsx | 79 + app/parent/auth/pairing/page.tsx | 144 + app/parent/auth/register/page.tsx | 88 + app/parent/configuracion/page.tsx | 36 + app/parent/dashboard/page.tsx | 293 + app/parent/layout.tsx | 86 + app/parent/page.tsx | 21 + components.json | 20 + components/child/audio-unlock.tsx | 43 + components/child/cpa-exercise.tsx | 33 + components/child/cuisenaire-rod.tsx | 58 + components/child/gato-mascota.tsx | 56 + components/child/no-child-error.tsx | 53 + components/child/temporizador-visual.tsx | 76 + components/child/trazo-letra.tsx | 158 + components/child/vocal-card.tsx | 43 + components/exercises/ejercicio-conciencia.tsx | 57 + components/exercises/ejercicio-eleccion.tsx | 46 + components/exercises/ejercicio-lectura.tsx | 56 + components/exercises/ejercicio-palabra.tsx | 60 + components/exercises/ejercicio-secuencia.tsx | 54 + .../exercises/ejercicio-sensibilizacion.tsx | 61 + components/exercises/ejercicio-trazo.tsx | 66 + components/exercises/exercise-dispatcher.tsx | 34 + components/parent/error-patterns-chart.tsx | 68 + components/parent/metric-card.tsx | 26 + components/parent/milestones-list.tsx | 40 + components/parent/skill-mastery-chart.tsx | 61 + components/parent/weekly-activity-chart.tsx | 52 + components/ui/avatar.tsx | 50 + components/ui/badge.tsx | 36 + components/ui/button.tsx | 56 + components/ui/card.tsx | 79 + components/ui/input.tsx | 22 + components/ui/label.tsx | 26 + components/ui/progress.tsx | 28 + components/ui/skeleton.tsx | 15 + components/ui/tabs.tsx | 55 + curriculum/index.ts | 46 + curriculum/lectura/etapa-1.ts | 218 + curriculum/lectura/etapa-2.ts | 345 + curriculum/lectura/etapa-3.ts | 269 + curriculum/lectura/etapa-4.ts | 235 + curriculum/lectura/etapa-5.ts | 293 + curriculum/lectura/etapa-6.ts | 119 + curriculum/lectura/etapa-7.ts | 109 + curriculum/lectura/etapa-8.ts | 147 + curriculum/lectura/etapa-9.ts | 176 + curriculum/numeros/etapa-1.ts | 82 + curriculum/numeros/etapa-2.ts | 99 + curriculum/numeros/etapa-3.ts | 107 + curriculum/numeros/etapa-4.ts | 83 + curriculum/numeros/etapa-5.ts | 90 + curriculum/numeros/etapa-6.ts | 95 + curriculum/numeros/etapa-7.ts | 103 + curriculum/numeros/etapa-8.ts | 214 + curriculum/types.ts | 54 + docker-compose.yml | 45 + dominios-libres.md | 40 + e2e/api-curriculum.spec.ts | 71 + e2e/exercise-content.spec.ts | 78 + e2e/pairing-flow.spec.ts | 50 + eslint.config.mjs | 14 + lib/auth-client.ts | 9 + lib/auth.ts | 31 + lib/curriculum/engine.ts | 124 + lib/db.ts | 9 + lib/fsrs.ts | 50 + lib/pedagogia/borel-maisonny.ts | 67 + lib/pedagogia/cpa-progression.ts | 56 + lib/pedagogia/cuisenaire.ts | 47 + lib/pedagogia/errorless.ts | 63 + lib/session-client.ts | 53 + lib/speech.ts | 29 + lib/utils.ts | 6 + middleware.ts | 55 + next.config.ts | 8 + package-lock.json | 7681 +++++++++++++++++ package.json | 50 + playwright.config.ts | 22 + postcss.config.js | 6 + .../20260720161822_init/migration.sql | 180 + prisma/migrations/migration_lock.toml | 3 + prisma/schema.prisma | 180 + public/icon.svg | 13 + .../0ad066a5d29f3f2a2a1c7c17dd082a79.wav | Bin 0 -> 56206 bytes .../1178ef73e06c257fdb9ec2b72ae6e781.wav | Bin 0 -> 57006 bytes .../4d186321c1a7f0f354b297e8914ab240.wav | Bin 0 -> 35182 bytes .../75043ff664f05dfc0d863251555d7745.wav | Bin 0 -> 181328 bytes .../7efecaecce8338e591042f8e26137bf7.wav | Bin 0 -> 101324 bytes .../d852f92d887c3788efb8c08c38788969.wav | Bin 0 -> 51466 bytes tailwind.config.ts | 70 + test-results/.last-run.json | 4 + tsconfig.json | 40 + 120 files changed, 16013 insertions(+) create mode 100644 .atl/.skill-registry.cache.json create mode 100644 .atl/skill-registry.md create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 PLAN.md create mode 100644 app/api/auth/[...all]/route.ts create mode 100644 app/api/children/route.ts create mode 100644 app/api/curriculum/grade/route.ts create mode 100644 app/api/curriculum/next/route.ts create mode 100644 app/api/curriculum/progress/route.ts create mode 100644 app/api/dashboard/summary/route.ts create mode 100644 app/api/fsrs/grade/route.ts create mode 100644 app/api/fsrs/next/route.ts create mode 100644 app/api/milestones/route.ts create mode 100644 app/api/pairing/route.ts create mode 100644 app/api/sessions/sync/route.ts create mode 100644 app/api/tts/route.ts create mode 100644 app/child/layout.tsx create mode 100644 app/child/lectura/page.tsx create mode 100644 app/child/logros/page.tsx create mode 100644 app/child/numeros/page.tsx create mode 100644 app/child/page.tsx create mode 100644 app/child/pairing/page.tsx create mode 100644 app/globals.css create mode 100644 app/layout.tsx create mode 100644 app/page.tsx create mode 100644 app/parent/auth/login/page.tsx create mode 100644 app/parent/auth/pairing/page.tsx create mode 100644 app/parent/auth/register/page.tsx create mode 100644 app/parent/configuracion/page.tsx create mode 100644 app/parent/dashboard/page.tsx create mode 100644 app/parent/layout.tsx create mode 100644 app/parent/page.tsx create mode 100644 components.json create mode 100644 components/child/audio-unlock.tsx create mode 100644 components/child/cpa-exercise.tsx create mode 100644 components/child/cuisenaire-rod.tsx create mode 100644 components/child/gato-mascota.tsx create mode 100644 components/child/no-child-error.tsx create mode 100644 components/child/temporizador-visual.tsx create mode 100644 components/child/trazo-letra.tsx create mode 100644 components/child/vocal-card.tsx create mode 100644 components/exercises/ejercicio-conciencia.tsx create mode 100644 components/exercises/ejercicio-eleccion.tsx create mode 100644 components/exercises/ejercicio-lectura.tsx create mode 100644 components/exercises/ejercicio-palabra.tsx create mode 100644 components/exercises/ejercicio-secuencia.tsx create mode 100644 components/exercises/ejercicio-sensibilizacion.tsx create mode 100644 components/exercises/ejercicio-trazo.tsx create mode 100644 components/exercises/exercise-dispatcher.tsx create mode 100644 components/parent/error-patterns-chart.tsx create mode 100644 components/parent/metric-card.tsx create mode 100644 components/parent/milestones-list.tsx create mode 100644 components/parent/skill-mastery-chart.tsx create mode 100644 components/parent/weekly-activity-chart.tsx create mode 100644 components/ui/avatar.tsx create mode 100644 components/ui/badge.tsx create mode 100644 components/ui/button.tsx create mode 100644 components/ui/card.tsx create mode 100644 components/ui/input.tsx create mode 100644 components/ui/label.tsx create mode 100644 components/ui/progress.tsx create mode 100644 components/ui/skeleton.tsx create mode 100644 components/ui/tabs.tsx create mode 100644 curriculum/index.ts create mode 100644 curriculum/lectura/etapa-1.ts create mode 100644 curriculum/lectura/etapa-2.ts create mode 100644 curriculum/lectura/etapa-3.ts create mode 100644 curriculum/lectura/etapa-4.ts create mode 100644 curriculum/lectura/etapa-5.ts create mode 100644 curriculum/lectura/etapa-6.ts create mode 100644 curriculum/lectura/etapa-7.ts create mode 100644 curriculum/lectura/etapa-8.ts create mode 100644 curriculum/lectura/etapa-9.ts create mode 100644 curriculum/numeros/etapa-1.ts create mode 100644 curriculum/numeros/etapa-2.ts create mode 100644 curriculum/numeros/etapa-3.ts create mode 100644 curriculum/numeros/etapa-4.ts create mode 100644 curriculum/numeros/etapa-5.ts create mode 100644 curriculum/numeros/etapa-6.ts create mode 100644 curriculum/numeros/etapa-7.ts create mode 100644 curriculum/numeros/etapa-8.ts create mode 100644 curriculum/types.ts create mode 100644 docker-compose.yml create mode 100644 dominios-libres.md create mode 100644 e2e/api-curriculum.spec.ts create mode 100644 e2e/exercise-content.spec.ts create mode 100644 e2e/pairing-flow.spec.ts create mode 100644 eslint.config.mjs create mode 100644 lib/auth-client.ts create mode 100644 lib/auth.ts create mode 100644 lib/curriculum/engine.ts create mode 100644 lib/db.ts create mode 100644 lib/fsrs.ts create mode 100644 lib/pedagogia/borel-maisonny.ts create mode 100644 lib/pedagogia/cpa-progression.ts create mode 100644 lib/pedagogia/cuisenaire.ts create mode 100644 lib/pedagogia/errorless.ts create mode 100644 lib/session-client.ts create mode 100644 lib/speech.ts create mode 100644 lib/utils.ts create mode 100644 middleware.ts create mode 100644 next.config.ts create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 playwright.config.ts create mode 100644 postcss.config.js create mode 100644 prisma/migrations/20260720161822_init/migration.sql create mode 100644 prisma/migrations/migration_lock.toml create mode 100644 prisma/schema.prisma create mode 100644 public/icon.svg create mode 100644 public/tts-cache/0ad066a5d29f3f2a2a1c7c17dd082a79.wav create mode 100644 public/tts-cache/1178ef73e06c257fdb9ec2b72ae6e781.wav create mode 100644 public/tts-cache/4d186321c1a7f0f354b297e8914ab240.wav create mode 100644 public/tts-cache/75043ff664f05dfc0d863251555d7745.wav create mode 100644 public/tts-cache/7efecaecce8338e591042f8e26137bf7.wav create mode 100644 public/tts-cache/d852f92d887c3788efb8c08c38788969.wav create mode 100644 tailwind.config.ts create mode 100644 test-results/.last-run.json create mode 100644 tsconfig.json diff --git a/.atl/.skill-registry.cache.json b/.atl/.skill-registry.cache.json new file mode 100644 index 0000000..abda2d6 --- /dev/null +++ b/.atl/.skill-registry.cache.json @@ -0,0 +1,3 @@ +{ + "fingerprint": "ee41cd16aee142978eedd00dcf1854a07a534d9e" +} diff --git a/.atl/skill-registry.md b/.atl/skill-registry.md new file mode 100644 index 0000000..b0d53ee --- /dev/null +++ b/.atl/skill-registry.md @@ -0,0 +1,38 @@ +# Skill Registry — edueasy + + + +Last updated: 2026-07-20 + +## Sources scanned + +- /home/ren/.config/opencode/skills +- /home/ren/.codex/skills + +## Contract + +**Delegator use only.** This registry is an index, not a summary. Any agent that launches subagents reads it to select relevant skills, then passes exact `SKILL.md` paths for the subagent to read before work. + +`SKILL.md` remains the source of truth. Do not inject generated summaries or compact rules by default; pass paths so subagents load the full runtime contract and preserve author intent. + +## Skills + +| Skill | Trigger / description | Scope | Path | +| --- | --- | --- | --- | +| `branch-pr` | Create Gentle AI pull requests with issue-first checks. Trigger: creating, opening, or preparing PRs for review. | user | `/home/ren/.config/opencode/skills/branch-pr/SKILL.md` | +| `chained-pr` | Trigger: PRs over 400 lines, stacked PRs, review slices. Split oversized changes into chained PRs that protect review focus. | user | `/home/ren/.config/opencode/skills/chained-pr/SKILL.md` | +| `cognitive-doc-design` | Design docs that reduce cognitive load. Trigger: writing guides, READMEs, RFCs, onboarding, architecture, or review-facing docs. | user | `/home/ren/.config/opencode/skills/cognitive-doc-design/SKILL.md` | +| `comment-writer` | Write warm, direct collaboration comments. Trigger: PR feedback, issue replies, reviews, Slack messages, or GitHub comments. | user | `/home/ren/.config/opencode/skills/comment-writer/SKILL.md` | +| `go-testing` | Trigger: Go tests, go test coverage, Bubbletea teatest, golden files. Apply focused Go testing patterns. | user | `/home/ren/.config/opencode/skills/go-testing/SKILL.md` | +| `issue-creation` | Create Gentle AI issues with issue-first checks. Trigger: creating GitHub issues, bug reports, or feature requests. | user | `/home/ren/.config/opencode/skills/issue-creation/SKILL.md` | +| `judgment-day` | Trigger: judgment day, dual review, adversarial review, juzgar. Run blind dual review, fix confirmed issues, then re-judge. | user | `/home/ren/.config/opencode/skills/judgment-day/SKILL.md` | +| `skill-creator` | Trigger: new skills, agent instructions, documenting AI usage patterns. Create LLM-first skills with valid frontmatter. | user | `/home/ren/.config/opencode/skills/skill-creator/SKILL.md` | +| `skill-improver` | Trigger: improve skills, audit skills, refactor skills, skill quality. Audit and upgrade existing LLM-first skills. | user | `/home/ren/.config/opencode/skills/skill-improver/SKILL.md` | +| `work-unit-commits` | Plan commits as reviewable work units. Trigger: implementation, commit splitting, chained PRs, or keeping tests and docs with code. | user | `/home/ren/.config/opencode/skills/work-unit-commits/SKILL.md` | + +## Loading protocol + +1. Match task context and target files against the `Trigger / description` column. +2. Pass only the matching `Path` values to the subagent under `## Skills to load before work`. +3. Instruct the subagent to read those exact `SKILL.md` files before reading, writing, reviewing, testing, or creating artifacts. +4. If no matching skill exists, proceed without project skill injection and report `skill_resolution: none`. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c34c34 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +node_modules/ +.next/ +*.tsbuildinfo +next-env.d.ts +.env +.env.local +.env*.local +.env.local +.env*.local +.cache/ +dist/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d988054 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,38 @@ +# Stage 1: Install dependencies +FROM node:22-alpine AS deps +WORKDIR /app +COPY package.json package-lock.json ./ +RUN npm ci + +# Stage 2: Build +FROM node:22-alpine AS builder +WORKDIR /app +COPY --from=deps /app/node_modules ./node_modules +COPY . . +ENV NEXT_TELEMETRY_DISABLED=1 +RUN npx prisma generate +RUN npm run build + +# Stage 3: Production +FROM node:22-alpine AS runner +WORKDIR /app + +ENV NODE_ENV=production +ENV NEXT_TELEMETRY_DISABLED=1 + +RUN addgroup --system --gid 1001 nodejs +RUN adduser --system --uid 1001 nextjs + +COPY --from=builder /app/public ./public +COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ +COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static +COPY --from=builder --chown=nextjs:nodejs /app/prisma ./prisma + +USER nextjs + +EXPOSE 3000 + +ENV PORT=3000 +ENV HOSTNAME="0.0.0.0" + +CMD ["node", "server.js"] diff --git a/PLAN.md b/PLAN.md new file mode 100644 index 0000000..ad88ed2 --- /dev/null +++ b/PLAN.md @@ -0,0 +1,219 @@ +# EduEasy — Plan de Plataforma + +## Arquitectura General + +Plataforma educativa para una nena de 8 años con déficit de atención, baja abstractividad, que no sabe leer ni contar (bases malas en 1er grado). Dos caras en un mismo server: + +| App | Dominio | Dispositivo | Usuario | +|-----|---------|-------------|---------| +| **Aprendizaje** | `mate.cbcren.online` | iPad Air 4 (solo dedo) | La nena | +| **Dashboard** | `simulacro.cbcren.online` | Poco F6 Pro | La mamá | + +**Stack**: Next.js 15 + React 19 + TypeScript estricto + Tailwind CSS + shadcn/ui + Better Auth + Prisma + PostgreSQL + ts-fsrs +**Deploy**: All-in-one Docker (un proceso Next.js + Postgres) en red `caddy` del server existente (194.163.191.200) + +## Decisiones de Diseño Cerradas + +| Decisión | Respuesta | +|----------|-----------| +| **Mascota** | 🐱 **Gato** — guía las sesiones con instrucciones en audio, celebra logros, da feedback en errorless learning. Sin nombre fijo aún. | +| **Paleta** | **Calmada** — fondo `#FFF8F0` crema/beige, primario `#8CB8A0` verde salvia, secundario `#6B8FA3` azul medio, acento `#D4A574` terracota, texto `#2D3436` (no negro puro). Bajas saturaciones en todos. | +| **Audio** | **TTS por ahora** (Web Speech API, voz es-ES femenina). Se reemplaza por grabaciones reales es-AR en Fase 4+ cuando el contenido esté validado. | + +--- + +## Pedagogía (Métodos Europeos) + +| Área | Método | Aplicación | +|------|--------|------------| +| **Lectura** | Borel-Maisonny (FR) | Cada fonema tiene un gesto físico + sonido. La nena hace el gesto en el aire + traza con el dedo en la pantalla + escucha el audio. | +| **Lectura** | Jolly Phonics (UK) adaptado | Orden de aprendizaje: no A-B-C, sino por frecuencia de uso. Vocales primero (A, E, I, O, U) + consonantes sonoras continuas (S, M, L, N). | +| **Lectura** | Método silábico | Español = 5 vocales puras, sílabas CV, CVC, CCV. Silabeo sistemático desde el día 1. | +| **Numeración** | CPA (Concrete-Pictórico-Abstracto) | **Concreto**: objetos (tapitas virtuales para contar). **Pictórico**: dibujos de objetos. **Abstracto**: el número símbolo. | +| **Numeración** | Regletas Cuisenaire (Bélgica) | Cantidad como barra de color. 1=blanco, 2=rojo, 3=verde claro... La nena ve y toca la cantidad sin "contar" abstractamente. | +| **Internalización** | Galperin (URSS) | **1. Mano**: manipular objetos. **2. Voz externa**: decir en voz alta. **3. Voz interna**: susurrar. **4. Mental**: hacerlo en la cabeza. | +| **Errores** | Errorless learning | **Nunca** se muestra "incorrecto". Si titubea, el sistema da la pista más obvia (modelado). Si persiste el error, fadea la ayuda. | +| **Refuerzo** | Fijo y predecible | Sin slots, sin FOMO, sin rachas ansiosas. Estrellita predecible después de cada ronda completa. | +| **Sesiones** | Chunking estructurado | 10-15 min máximo. Temporizador visual tipo Time Timer. Micro-pausa motora cada 5 min (saltar, aplaudir). | + +--- + +## Stack Técnico + +``` +Frontend: Next.js 15 (App Router) + React 19 + TypeScript + Tailwind CSS +UI Lib: shadcn/ui (componentes base) +Auth: Better Auth (login mamá + QR pairing → JWT device-bound para nena) +DB: PostgreSQL + Prisma ORM +Spaced Rep: ts-fsrs (Free Spaced Repetition Scheduler) +Canvas: perfect-freehand (trazo con dedo) + @use-gesture/react +Audio: Web Speech API (TTS es-ES/es-MX, confirmado: TTS por ahora → reemplazar con grabaciones reales es-AR en Fase 4+) +Animación: framer-motion (transiciones lentas 300-500ms, sin sparkles) +Charts: Recharts (dashboard mamá) +Deploy: Docker + red caddy existente +``` + +### Repos reutilizados +- `ts-fsrs` (npm) — algoritmo FSRS de repetición espaciada +- `perfect-freehand` (npm) — trazado fluido con dedo (Excalidraw) +- Better Auth (npm) — auth + device pairing +- shadcn/ui (npm) — componentes base de UI +- Math Learning Center apps — referencia UX de manipulativos virtuales (number-rack, ten-frames) + +--- + +## Modelo de Datos + +```prisma +model Family { id, name, created_at } +model Parent { id, family_id, email, name, auth_provider } +model Child { id, family_id, name, avatar, birthdate, profile_notes } +model Device { id, child_id, device_fingerprint, paired_at, last_seen, role } +model Session { id, child_id, started_at, ended_at, duration_sec, skills_practiced } +model SkillAttempt { id, session_id, skill_code, prompt_level, correct, response_ms } +model FsrsCard { id, child_id, skill_code, due_at, stability, difficulty, reps, lapses } +model Milestone { id, child_id, skill_code, reached_at } +``` + +--- + +## Estructura del Proyecto + +``` +/home/ren/edueasy/ +├── app/ +│ ├── globals.css +│ ├── layout.tsx # Raíz (fonts, metadata) +│ ├── page.tsx # Redirige según host +│ ├── child/ # mate.cbcren.online +│ │ ├── layout.tsx # Layout infantil (gato, audio siempre presente) +│ │ ├── page.tsx # Menú principal de la nena +│ │ ├── sesion/ +│ │ └── logros/ +│ ├── parent/ # simulacro.cbcren.online +│ │ ├── layout.tsx # Layout dashboard + sidebar +│ │ ├── page.tsx # Dashboard principal +│ │ ├── auth/login/ +│ │ ├── auth/pairing/ +│ │ └── configuracion/ +│ └── api/ +│ ├── auth/[...all]/ # Better Auth handler +│ ├── pairing/ # QR pairing endpoint +│ └── sessions/sync/ # Sync offline → server +├── components/ +│ ├── ui/ # shadcn/ui +│ ├── child/ # Componentes de la nena +│ │ ├── gato-mascota +│ │ ├── trazo-letra (canvas tracing) +│ │ ├── vocal-card +│ │ ├── cuisenaire-rod +│ │ ├── temporizador-visual +│ │ └── boton-grande (60-80px) +│ └── parent/ # Componentes del dashboard +├── lib/ +│ ├── db.ts (Prisma client) +│ ├── auth.ts (Better Auth server) +│ ├── auth-client.ts +│ ├── speech.ts (Web Speech API) +│ ├── fsrs.ts (ts-fsrs wrapper) +│ └── pedagogia/ +│ ├── borel-maisonny.ts (fonemas + gestos) +│ ├── cuisenaire.ts (regletas) +│ ├── errorless.ts (prompt fading) +│ └── cpa-progression.ts (CPA estados) +├── prisma/schema.prisma +├── middleware.ts (host-based routing) +├── Dockerfile +├── docker-compose.yml +├── package.json +├── tsconfig.json +├── next.config.ts +├── tailwind.config.ts +├── postcss.config.js +├── components.json (shadcn/ui) +└── .env.local +``` + +--- + +## UX Constraints (iPad Air 4 + Dedo) + +- **Touch targets**: 60–80px mínimo (baselines adultos 44px no alcanzan para niños) +- **Drag > Tap** para interacciones principales +- **Una sola acción focal** por pantalla +- **100% iconografía + audio** (la nena NO LEE) +- **Sin "X roja"** nunca — sonido neutro + mascota dice "probemos juntas" +- **Fondo claro baja saturación** (crema/beige) + acentos verde salvia + azul medio +- **Botón "Tocá para empezar"** en cada sesión (unlock AudioContext en iOS Safari) +- **Persistencia al backend siempre** (Safari evicta IndexedDB a 7 días) + +### iOS Safari Técnico +- Audio: .m4a primario + .mp3 fallback. **NUNCA .ogg**. +- AudioContext: requiere user gesture para desbloquear. +- `100dvh` en vez de `100vh` (barra de Safari). +- `touch-action: manipulation` para eliminar delay 300ms. +- inputs con `font-size: 16px` mínimo (evita zoom automático). + +--- + +## Roadmap + +### Fase 0 — Fundaciones (1-2 sem) +- [x] Repositorio + package.json + configs +- [x] Docker + docker-compose +- [x] Prisma schema + migración +- [x] Better Auth + QR pairing +- [x] Design system base (gato mascota, paleta, component primitives) +- [x] Caddy config update + +### Fase 1 — Lectura MVP +- [ ] Módulo vocales: A, E, I, O, U +- [ ] Audio TTS para cada fonema + palabra ejemplo +- [ ] Gesto Borel-Maisonny (animación + instrucción) +- [ ] Trazo con dedo (canvas + perfect-freehand) +- [ ] Sesión guiada 10 min + temporizador visual +- [ ] Errorless learning + fading automático +- [ ] Logros por vocal completada + +### Fase 2 — Numeración MVP +- [ ] Módulo cantidades 1-5 (expandir a 10) +- [ ] CPA: objetos → imagen → símbolo +- [ ] Regletas Cuisenaire virtuales (arrastrar, comparar) +- [ ] Conteo one-to-one con arrastre +- [ ] Galperin: mano → voz → cabeza + +### Fase 3 — Adaptativo + Dashboard +- [ ] ts-fsrs: repaso espaciado por skill +- [ ] Dashboard mamá: streak, tiempo, mastery %, último resumen +- [ ] Push notifications al Poco F6 Pro +- [ ] QR pairing funcional +- [ ] Export de progreso + +### Fase 4+ (futuro) +- [ ] Consonantes y sílabas completas +- [ ] Números 11-100, suma/resta +- [ ] Grabaciones de audio real (es-AR) +- [ ] IA adaptativa (Ollama/Open WebUI) + +--- + +## Diseño Visual + +**Mascota**: 🐱 Gato (sin nombre definido — que la nena lo nombre). +- Guía las sesiones, da instrucciones en audio, celebra logros. +- Animaciones suaves (no bruscas), tamaño grande en pantalla. + +**Paleta**: +- Fondo: `#FFF8F0` (crema suave) +- Primario: `#8CB8A0` (verde salvia) +- Secundario: `#6B8FA3` (azul medio) +- Acento: `#D4A574` (terracota suave) +- Texto: `#2D3436` (gris oscuro, no negro puro) +- Correcto: `#7FB685` (verde suave, no brillante) + +**Tipografía**: +- Títulos: Fredoka One (redondeada, amigable, legible) +- Interface: Inter (sistema, para dashboard de la mamá) +- La nena no ve texto — solo escucha. Las letras aparecen grandes, claras, bien trazadas. + +--- diff --git a/app/api/auth/[...all]/route.ts b/app/api/auth/[...all]/route.ts new file mode 100644 index 0000000..5cd4846 --- /dev/null +++ b/app/api/auth/[...all]/route.ts @@ -0,0 +1,4 @@ +import { auth } from "@/lib/auth" +import { toNextJsHandler } from "better-auth/next-js" + +export const { POST, GET } = toNextJsHandler(auth) diff --git a/app/api/children/route.ts b/app/api/children/route.ts new file mode 100644 index 0000000..e303597 --- /dev/null +++ b/app/api/children/route.ts @@ -0,0 +1,57 @@ +import { NextRequest, NextResponse } from "next/server" +import { prisma } from "@/lib/db" +import { auth } from "@/lib/auth" + +export async function GET(request: NextRequest) { + const session = await auth.api.getSession({ headers: request.headers }) + if (!session?.user?.id) { + return NextResponse.json({ error: "No autorizado" }, { status: 401 }) + } + + const parent = await prisma.parent.findUnique({ + where: { id: session.user.id }, + include: { + family: { + include: { children: true }, + }, + }, + }) + + if (!parent || !parent.family) { + return NextResponse.json({ error: "Parent or family not found" }, { status: 404 }) + } + + return NextResponse.json(parent.family.children) +} + +export async function POST(request: Request) { + const session = await auth.api.getSession({ headers: request.headers }) + if (!session?.user?.id) { + return NextResponse.json({ error: "No autorizado" }, { status: 401 }) + } + + const { name, birthdate, profileNotes } = await request.json() + if (!name) { + return NextResponse.json({ error: "name required" }, { status: 400 }) + } + + const parent = await prisma.parent.findUnique({ + where: { id: session.user.id }, + select: { familyId: true }, + }) + + if (!parent || !parent.familyId) { + return NextResponse.json({ error: "Parent has no family" }, { status: 400 }) + } + + const child = await prisma.child.create({ + data: { + name, + birthdate: birthdate ? new Date(birthdate) : undefined, + profileNotes, + familyId: parent.familyId, + }, + }) + + return NextResponse.json(child, { status: 201 }) +} diff --git a/app/api/curriculum/grade/route.ts b/app/api/curriculum/grade/route.ts new file mode 100644 index 0000000..ccee70a --- /dev/null +++ b/app/api/curriculum/grade/route.ts @@ -0,0 +1,39 @@ +import { NextRequest, NextResponse } from "next/server" +import { prisma } from "@/lib/db" + +export async function POST(request: NextRequest) { + try { + const { childId, exerciseId, skillCode, correct, promptLevel, responseMs, errorType, stage } = await request.json() + + if (!childId || !exerciseId || !skillCode) { + return NextResponse.json({ error: "Missing required fields" }, { status: 400 }) + } + + const sessionLog = await prisma.sessionLog.findFirst({ + where: { childId }, + orderBy: { startedAt: "desc" }, + }) + + if (!sessionLog) { + return NextResponse.json({ error: "No active session" }, { status: 400 }) + } + + await prisma.skillAttempt.create({ + data: { + sessionLogId: sessionLog.id, + skillCode, + promptLevel: promptLevel ?? 0, + correct, + responseMs: responseMs ?? null, + errorType: errorType ?? null, + exerciseId, + stage: stage ?? null, + }, + }) + + return NextResponse.json({ success: true }) + } catch (error) { + console.error("Curriculum grade error:", error) + return NextResponse.json({ error: "Internal error" }, { status: 500 }) + } +} diff --git a/app/api/curriculum/next/route.ts b/app/api/curriculum/next/route.ts new file mode 100644 index 0000000..9672526 --- /dev/null +++ b/app/api/curriculum/next/route.ts @@ -0,0 +1,13 @@ +import { NextRequest, NextResponse } from "next/server" +import { getNextExercise } from "@/lib/curriculum/engine" + +export async function GET(request: NextRequest) { + const childId = request.nextUrl.searchParams.get("childId") + const topic = (request.nextUrl.searchParams.get("topic") || "lectura") as "lectura" | "numeros" + if (!childId) { + return NextResponse.json({ error: "childId required" }, { status: 400 }) + } + + const exercise = await getNextExercise(childId, topic) + return NextResponse.json(exercise || { id: null, done: true }) +} diff --git a/app/api/curriculum/progress/route.ts b/app/api/curriculum/progress/route.ts new file mode 100644 index 0000000..6da0953 --- /dev/null +++ b/app/api/curriculum/progress/route.ts @@ -0,0 +1,77 @@ +import { NextRequest, NextResponse } from "next/server" +import { prisma } from "@/lib/db" +import { initCurriculum, getLecturaStages, getNumerosStages } from "@/curriculum/index" +import { getCurrentStage, getNextExercise } from "@/lib/curriculum/engine" + +export async function GET(request: NextRequest) { + const childId = request.nextUrl.searchParams.get("childId") + const topic = (request.nextUrl.searchParams.get("topic") || "lectura") as "lectura" | "numeros" + if (!childId) { + return NextResponse.json({ error: "childId required" }, { status: 400 }) + } + + await initCurriculum() + + const stages = topic === "lectura" ? getLecturaStages() : getNumerosStages() + const stageKeys = Object.keys(stages).map(Number).sort((a, b) => a - b) + + const progress = prisma.curriculumProgress.findMany({ + where: { childId, topic }, + orderBy: { stage: "asc" }, + }) + + const allAttempts = prisma.skillAttempt.findMany({ + where: { + exerciseId: { not: null }, + stage: { not: null }, + sessionLog: { childId }, + }, + select: { exerciseId: true, correct: true }, + }) + + const [progressRows, attempts] = await Promise.all([progress, allAttempts]) + + const mastered = new Set( + attempts.filter((a) => a.correct).map((a) => a.exerciseId), + ) + + const stagesInfo = stageKeys.map((sk) => { + const s = stages[sk] + const total = s?.exercises?.length || 0 + const completed = s?.exercises?.filter((e) => mastered.has(e.id)).length || 0 + const prog = progressRows.find((p) => p.stage === sk) + return { + stage: sk, + name: s?.name || `Etapa ${sk}`, + total, + completed, + unlocked: !!prog, + completedAt: prog?.completedAt || null, + percent: total > 0 ? Math.round((completed / total) * 100) : 0, + } + }) + + const errorTypes = await prisma.skillAttempt.groupBy({ + by: ["errorType"], + where: { + errorType: { not: null }, + sessionLog: { childId }, + }, + _count: { errorType: true }, + }) + + const errorPatterns = errorTypes.map((e) => ({ + errorType: e.errorType, + count: e._count.errorType, + })) + + const activeProgress = progressRows.find((p) => !p.completedAt) + const currentStage = activeProgress?.stage || 1 + + return NextResponse.json({ + currentStage, + stages: stagesInfo, + errorPatterns, + hasActiveSession: true, + }) +} diff --git a/app/api/dashboard/summary/route.ts b/app/api/dashboard/summary/route.ts new file mode 100644 index 0000000..43161b1 --- /dev/null +++ b/app/api/dashboard/summary/route.ts @@ -0,0 +1,159 @@ +import { NextRequest, NextResponse } from "next/server" +import { prisma } from "@/lib/db" + +export async function GET(request: NextRequest) { + const childId = request.nextUrl.searchParams.get("childId") + if (!childId) { + return NextResponse.json({ error: "childId required" }, { status: 400 }) + } + + const today = new Date() + today.setHours(0, 0, 0, 0) + + const [totalSessions, todaySessions, milestones, fsrsCards, lastSession, weeklySessions, milestoneRecords, curriculumProgress, errorPatterns, allAttempts] = + await Promise.all([ + prisma.sessionLog.count({ where: { childId } }), + prisma.sessionLog.count({ + where: { childId, startedAt: { gte: today } }, + }), + prisma.milestone.count({ where: { childId } }), + prisma.fsrsCard.findMany({ where: { childId } }), + prisma.sessionLog.findFirst({ + where: { childId }, + orderBy: { startedAt: "desc" }, + include: { skillAttempts: true }, + }), + prisma.sessionLog.findMany({ + where: { childId, startedAt: { gte: new Date(Date.now() - 7 * 86400000) } }, + orderBy: { startedAt: "asc" }, + select: { startedAt: true, durationSec: true }, + }), + prisma.milestone.findMany({ + where: { childId }, + orderBy: { reachedAt: "desc" }, + select: { skillCode: true, reachedAt: true }, + }), + prisma.curriculumProgress.findMany({ + where: { childId }, + orderBy: { stage: "asc" }, + }), + prisma.skillAttempt.findMany({ + where: { + errorType: { not: null }, + sessionLog: { childId }, + }, + select: { errorType: true }, + }), + prisma.skillAttempt.findMany({ + where: { + correct: false, + exerciseId: { not: null }, + sessionLog: { childId }, + }, + select: { exerciseId: true, errorType: true }, + }), + ]) + + const todayMinutes = todaySessions > 0 + ? await prisma.sessionLog.aggregate({ + where: { childId, startedAt: { gte: today } }, + _sum: { durationSec: true }, + }).then((r) => Math.round((r._sum.durationSec ?? 0) / 60)) + : 0 + + const totalSkills = fsrsCards.length + const masteredSkills = fsrsCards.filter((c) => c.reps >= 5 && c.stability > 30).length + const masteryPercent = totalSkills > 0 ? Math.round((masteredSkills / totalSkills) * 100) : 0 + + const weeklyData = weeklySessions.map((s) => ({ + date: s.startedAt.toISOString().slice(0, 10), + minutes: Math.round((s.durationSec ?? 0) / 60), + })) + + const skillBreakdown = fsrsCards.map((c) => ({ + skillCode: c.skillCode, + stability: c.stability, + difficulty: c.difficulty, + reps: c.reps, + due: c.dueAt.toISOString(), + })) + + const streak = await calculateStreak(childId) + + const totalErrors = allAttempts.length + const errorTypeCount = errorPatterns.reduce>((acc, e) => { + const key = e.errorType || "sin-clasificar" + acc[key] = (acc[key] || 0) + 1 + return acc + }, {}) + + const stageProgress = curriculumProgress.map((cp) => ({ + topic: cp.topic, + stage: cp.stage, + completedAt: cp.completedAt?.toISOString() || null, + })) + + return NextResponse.json({ + totalSessions, + todaySessions, + todayMinutes, + masteryPercent, + masteredSkills, + totalSkills, + milestones, + streak, + weeklyData, + skillBreakdown, + milestoneData: milestoneRecords, + stageProgress, + errorTypeCount, + totalErrors, + lastSession: lastSession + ? { + startedAt: lastSession.startedAt.toISOString(), + durationSec: lastSession.durationSec, + skillsPracticed: lastSession.skillsPracticed, + correctCount: lastSession.skillAttempts.filter((a) => a.correct).length, + totalAttempts: lastSession.skillAttempts.length, + } + : null, + }) +} + +async function calculateStreak(childId: string): Promise { + const logs = await prisma.sessionLog.findMany({ + where: { childId }, + orderBy: { startedAt: "desc" }, + select: { startedAt: true }, + }) + + if (logs.length === 0) return 0 + + const days = [ + ...new Set(logs.map((l) => l.startedAt.toISOString().slice(0, 10))), + ].sort() + .reverse() + + let streak = 1 + const today = new Date().toISOString().slice(0, 10) + + if (days[0] !== today && days[0] !== getYesterday()) return 0 + + for (let i = 1; i < days.length; i++) { + const prev = new Date(days[i - 1]) + const curr = new Date(days[i]) + const diff = (prev.getTime() - curr.getTime()) / 86400000 + if (Math.round(diff) === 1) { + streak++ + } else { + break + } + } + return streak +} + +function getYesterday(): string { + const d = new Date() + d.setDate(d.getDate() - 1) + return d.toISOString().slice(0, 10) +} diff --git a/app/api/fsrs/grade/route.ts b/app/api/fsrs/grade/route.ts new file mode 100644 index 0000000..b44c815 --- /dev/null +++ b/app/api/fsrs/grade/route.ts @@ -0,0 +1,57 @@ +import { NextRequest, NextResponse } from "next/server" +import { prisma } from "@/lib/db" +import { buildFsrsCard, gradeCard, skillCodeFromGrade } from "@/lib/fsrs" + +export async function POST(request: NextRequest) { + try { + const { childId, skillCode, correct, responseMs } = await request.json() + if (!childId || !skillCode) { + return NextResponse.json({ error: "childId and skillCode required" }, { status: 400 }) + } + + const existingCard = await prisma.fsrsCard.findFirst({ + where: { childId, skillCode }, + }) + + const grade = skillCodeFromGrade(correct, responseMs ?? 5000) + const baseCard = buildFsrsCard({ + stability: existingCard?.stability, + difficulty: existingCard?.difficulty, + reps: existingCard?.reps, + lapses: existingCard?.lapses, + due: existingCard?.dueAt, + }) + + const { card: updatedCard } = gradeCard(baseCard, grade) + + if (existingCard) { + await prisma.fsrsCard.update({ + where: { id: existingCard.id }, + data: { + dueAt: updatedCard.due, + stability: updatedCard.stability, + difficulty: updatedCard.difficulty, + reps: updatedCard.reps, + lapses: updatedCard.lapses, + }, + }) + } else { + await prisma.fsrsCard.create({ + data: { + childId, + skillCode, + dueAt: updatedCard.due, + stability: updatedCard.stability, + difficulty: updatedCard.difficulty, + reps: updatedCard.reps, + lapses: updatedCard.lapses, + }, + }) + } + + return NextResponse.json({ success: true }) + } catch (error) { + console.error("FSRS grade error:", error) + return NextResponse.json({ error: "Internal error" }, { status: 500 }) + } +} diff --git a/app/api/fsrs/next/route.ts b/app/api/fsrs/next/route.ts new file mode 100644 index 0000000..d502596 --- /dev/null +++ b/app/api/fsrs/next/route.ts @@ -0,0 +1,35 @@ +import { NextRequest, NextResponse } from "next/server" +import { prisma } from "@/lib/db" +import { buildFsrsCard, getRetrievability } from "@/lib/fsrs" + +export async function GET(request: NextRequest) { + const childId = request.nextUrl.searchParams.get("childId") + if (!childId) { + return NextResponse.json({ error: "childId required" }, { status: 400 }) + } + + const dueCard = await prisma.fsrsCard.findFirst({ + where: { + childId, + dueAt: { lte: new Date() }, + }, + orderBy: { dueAt: "asc" }, + }) + + if (dueCard) { + const card = buildFsrsCard({ + stability: dueCard.stability, + difficulty: dueCard.difficulty, + reps: dueCard.reps, + lapses: dueCard.lapses, + due: dueCard.dueAt, + }) + return NextResponse.json({ + ...dueCard, + cardId: dueCard.id, + retrievability: getRetrievability(card), + }) + } + + return NextResponse.json({ skillCode: null }) +} diff --git a/app/api/milestones/route.ts b/app/api/milestones/route.ts new file mode 100644 index 0000000..d9bc44d --- /dev/null +++ b/app/api/milestones/route.ts @@ -0,0 +1,36 @@ +import { NextRequest, NextResponse } from "next/server" +import { prisma } from "@/lib/db" + +export async function GET(request: NextRequest) { + const childId = request.nextUrl.searchParams.get("childId") + if (!childId) { + return NextResponse.json({ error: "childId required" }, { status: 400 }) + } + const milestones = await prisma.milestone.findMany({ + where: { childId }, + orderBy: { reachedAt: "desc" }, + }) + return NextResponse.json(milestones) +} + +export async function POST(request: Request) { + try { + const { childId, skillCode } = await request.json() + if (!childId || !skillCode) { + return NextResponse.json({ error: "childId and skillCode required" }, { status: 400 }) + } + const existing = await prisma.milestone.findUnique({ + where: { childId_skillCode: { childId, skillCode } }, + }) + if (existing) { + return NextResponse.json(existing) + } + const milestone = await prisma.milestone.create({ + data: { childId, skillCode }, + }) + return NextResponse.json(milestone, { status: 201 }) + } catch (error) { + console.error("Milestone error:", error) + return NextResponse.json({ error: "Internal error" }, { status: 500 }) + } +} diff --git a/app/api/pairing/route.ts b/app/api/pairing/route.ts new file mode 100644 index 0000000..14f161e --- /dev/null +++ b/app/api/pairing/route.ts @@ -0,0 +1,98 @@ +import { NextResponse } from "next/server" +import { prisma } from "@/lib/db" +import { randomUUID } from "crypto" + +export async function POST(request: Request) { + try { + const { deviceFingerprint, pairingCode, childId, action } = await request.json() + + if (action === "generate") { + if (!childId) { + return NextResponse.json({ error: "childId required" }, { status: 400 }) + } + const code = randomUUID().slice(0, 8).toUpperCase() + await prisma.pendingPairing.create({ + data: { + code, + childId, + expiresAt: new Date(Date.now() + 10 * 60 * 1000), + }, + }) + return NextResponse.json({ pairingCode: code }) + } + + if (pairingCode) { + const pending = await prisma.pendingPairing.findUnique({ + where: { code: pairingCode }, + }) + if (!pending || pending.expiresAt < new Date()) { + return NextResponse.json({ error: "Código inválido o expirado" }, { status: 404 }) + } + + const targetChildId = childId || pending.childId + if (!targetChildId) { + return NextResponse.json({ error: "Sin niño asociado" }, { status: 400 }) + } + + if (childId && !pending.childId) { + await prisma.pendingPairing.update({ + where: { id: pending.id }, + data: { childId }, + }) + } + + const fp = deviceFingerprint || pending.deviceFingerprint + if (!fp) { + return NextResponse.json({ error: "Se requiere deviceFingerprint" }, { status: 400 }) + } + + const device = await prisma.device.create({ + data: { + childId: targetChildId, + deviceFingerprint: fp, + role: "child", + }, + include: { child: true }, + }) + + await prisma.pendingPairing.delete({ where: { id: pending.id } }) + + return NextResponse.json({ + success: true, + childId: device.childId, + childName: device.child.name, + }) + } + + if (deviceFingerprint) { + const existingDevice = await prisma.device.findFirst({ + where: { deviceFingerprint }, + }) + if (existingDevice) { + return NextResponse.json({ + paired: true, + childId: existingDevice.childId, + role: existingDevice.role, + }) + } + + const code = randomUUID().slice(0, 8).toUpperCase() + await prisma.pendingPairing.create({ + data: { + code, + deviceFingerprint, + expiresAt: new Date(Date.now() + 10 * 60 * 1000), + }, + }) + return NextResponse.json({ + paired: false, + pairingCode: code, + }) + } + + return NextResponse.json({ error: "Invalid request" }, { status: 400 }) + } catch (error) { + console.error("Pairing error:", error) + return NextResponse.json({ error: "Internal error" }, { status: 500 }) + } +} diff --git a/app/api/sessions/sync/route.ts b/app/api/sessions/sync/route.ts new file mode 100644 index 0000000..38cc23d --- /dev/null +++ b/app/api/sessions/sync/route.ts @@ -0,0 +1,36 @@ +import { NextRequest, NextResponse } from "next/server" +import { prisma } from "@/lib/db" + +export async function POST(request: NextRequest) { + try { + const body = await request.json() + const { childId, session, attempts } = body + + if (!childId || !session) { + return NextResponse.json({ error: "Missing required fields" }, { status: 400 }) + } + + const sessionLog = await prisma.sessionLog.create({ + data: { + childId, + startedAt: new Date(session.startedAt), + endedAt: session.endedAt ? new Date(session.endedAt) : undefined, + durationSec: session.durationSec, + skillsPracticed: session.skillsPracticed, + skillAttempts: { + create: (attempts || []).map((a: any) => ({ + skillCode: a.skillCode, + promptLevel: a.promptLevel ?? 0, + correct: a.correct, + responseMs: a.responseMs, + })), + }, + }, + }) + + return NextResponse.json({ success: true, sessionId: sessionLog.id }) + } catch (error) { + console.error("Sync error:", error) + return NextResponse.json({ error: "Internal error" }, { status: 500 }) + } +} diff --git a/app/api/tts/route.ts b/app/api/tts/route.ts new file mode 100644 index 0000000..a115528 --- /dev/null +++ b/app/api/tts/route.ts @@ -0,0 +1,49 @@ +import { NextRequest, NextResponse } from "next/server" +import { execSync } from "child_process" +import { existsSync, mkdirSync } from "fs" +import { createHash } from "crypto" +import { readFile, mkdir } from "fs/promises" +import { join } from "path" + +const CACHE_DIR = join(process.cwd(), "public", "tts-cache") + +async function ensureCacheDir() { + if (!existsSync(CACHE_DIR)) { + await mkdir(CACHE_DIR, { recursive: true }) + } +} + +function getCachePath(text: string): string { + const hash = createHash("md5").update(text).digest("hex") + return join(CACHE_DIR, `${hash}.wav`) +} + +export async function GET(request: NextRequest) { + const text = request.nextUrl.searchParams.get("text") + if (!text || text.length > 200) { + return NextResponse.json({ error: "text param required (max 200 chars)" }, { status: 400 }) + } + + await ensureCacheDir() + const cachePath = getCachePath(text) + + if (!existsSync(cachePath)) { + try { + execSync( + `espeak-ng -v es-mx -s 140 -p 60 "${text.replace(/"/g, '\\"')}" -w "${cachePath}"`, + { timeout: 10000 }, + ) + } catch { + return NextResponse.json({ error: "TTS generation failed" }, { status: 500 }) + } + } + + const audioBuffer = await readFile(cachePath) + return new NextResponse(audioBuffer, { + headers: { + "Content-Type": "audio/wav", + "Content-Length": audioBuffer.length.toString(), + "Cache-Control": "public, max-age=31536000, immutable", + }, + }) +} diff --git a/app/child/layout.tsx b/app/child/layout.tsx new file mode 100644 index 0000000..d273529 --- /dev/null +++ b/app/child/layout.tsx @@ -0,0 +1,26 @@ +"use client" + +import { useEffect, useState } from "react" +import AudioUnlock from "@/components/child/audio-unlock" + +export default function ChildLayout({ + children, +}: { + children: React.ReactNode +}) { + const [audioReady, setAudioReady] = useState(false) + + useEffect(() => { + document.body.style.overscrollBehavior = "none" + }, []) + + if (!audioReady) { + return setAudioReady(true)} /> + } + + return ( +
+ {children} +
+ ) +} diff --git a/app/child/lectura/page.tsx b/app/child/lectura/page.tsx new file mode 100644 index 0000000..7d55bb6 --- /dev/null +++ b/app/child/lectura/page.tsx @@ -0,0 +1,167 @@ +"use client" + +import { useState, useCallback, useEffect, useRef } from "react" +import { motion, AnimatePresence } from "framer-motion" +import { GatoMascota } from "@/components/child/gato-mascota" +import NoChildError from "@/components/child/no-child-error" +import TemporizadorVisual from "@/components/child/temporizador-visual" +import ExerciseDispatcher from "@/components/exercises/exercise-dispatcher" +import { speak, stopSpeaking } from "@/lib/speech" +import type { Exercise } from "@/curriculum/types" + +const CHILD_ID_KEY = "edueasy_child_id" + +type PageState = "loading" | "ready" | "complete" | "error" + +export default function LecturaSesion() { + const [pageState, setPageState] = useState("loading") + const [exercise, setExercise] = useState(null) + const [running, setRunning] = useState(true) + const [score, setScore] = useState(0) + const [totalAttempts, setTotalAttempts] = useState(0) + const childIdRef = useRef("") + const startedAtRef = useRef(new Date().toISOString()) + + const getChildId = useCallback(() => { + const id = localStorage.getItem(CHILD_ID_KEY) || "" + childIdRef.current = id + return id + }, []) + + const fetchNext = useCallback(async () => { + const childId = getChildId() + if (!childId) { + setPageState("error") + return null + } + + try { + const res = await fetch(`/api/curriculum/next?childId=${childId}&topic=lectura`) + const data = await res.json() + if (data.done || !data.id) { + setPageState("complete") + return null + } + setExercise(data) + setPageState("ready") + return data + } catch { + setPageState("error") + return null + } + }, [getChildId]) + + useEffect(() => { + fetchNext() + }, [fetchNext]) + + const gradeAttempt = useCallback(async (ex: Exercise, correct: boolean) => { + const childId = childIdRef.current + if (!childId || !ex) return + + setTotalAttempts((t) => t + 1) + if (correct) setScore((s) => s + 1) + + const errorType = !correct + ? ex.errorType || "discriminacion-auditiva" + : null + + try { + await fetch("/api/curriculum/grade", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + childId, + exerciseId: ex.id, + skillCode: ex.skillCode, + correct, + promptLevel: 0, + responseMs: 3000, + errorType, + stage: ex.stage, + }), + }) + } catch { + // silent + } + }, []) + + const handleComplete = useCallback( + async (correct: boolean) => { + if (!exercise) return + await gradeAttempt(exercise, correct) + stopSpeaking() + if (correct) { + await speak("¡Muy bien!") + await new Promise((r) => setTimeout(r, 800)) + } + fetchNext() + }, + [exercise, gradeAttempt, fetchNext], + ) + + const resetSession = useCallback(() => { + setScore(0) + setTotalAttempts(0) + setRunning(true) + startedAtRef.current = new Date().toISOString() + fetchNext() + }, [fetchNext]) + + if (pageState === "loading") { + return ( +
+ +
+ ) + } + + if (pageState === "error") { + return + } + + if (pageState === "complete") { + return ( +
+ +

+ Aciertos: {score}/{totalAttempts} +

+ +
+ ) + } + + return ( +
+ { + setRunning(false) + setPageState("complete") + }} + running={running} + /> + + + + {exercise && ( + + )} + + +
+ ) +} diff --git a/app/child/logros/page.tsx b/app/child/logros/page.tsx new file mode 100644 index 0000000..9dcbddd --- /dev/null +++ b/app/child/logros/page.tsx @@ -0,0 +1,78 @@ +"use client" + +import { useState, useEffect } from "react" +import { motion } from "framer-motion" +import { GatoMascota } from "@/components/child/gato-mascota" + +const ALL_SKILLS = [ + { id: "vocal-a", label: "Letra A", emoji: "✈️" }, + { id: "vocal-e", label: "Letra E", emoji: "🐘" }, + { id: "vocal-i", label: "Letra I", emoji: "🏔️" }, + { id: "vocal-o", label: "Letra O", emoji: "🐻" }, + { id: "vocal-u", label: "Letra U", emoji: "🍇" }, + { id: "numero-1", label: "Número 1", emoji: "1️⃣" }, + { id: "numero-2", label: "Número 2", emoji: "2️⃣" }, + { id: "numero-3", label: "Número 3", emoji: "3️⃣" }, + { id: "numero-4", label: "Número 4", emoji: "4️⃣" }, + { id: "numero-5", label: "Número 5", emoji: "5️⃣" }, +] + +const CHILD_ID_KEY = "edueasy_child_id" + +export default function LogrosPage() { + const [milestones, setMilestones] = useState([]) + const [loading, setLoading] = useState(true) + + useEffect(() => { + const childId = localStorage.getItem(CHILD_ID_KEY) + if (!childId) { + setLoading(false) + return + } + fetch(`/api/milestones?childId=${childId}`) + .then((r) => r.json()) + .then((data) => { + if (Array.isArray(data)) { + setMilestones(data.map((m: any) => m.skillCode)) + } + }) + .catch(() => {}) + .finally(() => setLoading(false)) + }, []) + + const completedCount = milestones.length + + return ( +
+ + +

+ {completedCount} de {ALL_SKILLS.length} completados +

+ + {loading ? ( +

Cargando...

+ ) : ( +
+ {ALL_SKILLS.map((skill, i) => { + const completed = milestones.includes(skill.id) + return ( + + {skill.emoji} + {skill.label} + + ) + })} +
+ )} +
+ ) +} diff --git a/app/child/numeros/page.tsx b/app/child/numeros/page.tsx new file mode 100644 index 0000000..b7fbed2 --- /dev/null +++ b/app/child/numeros/page.tsx @@ -0,0 +1,167 @@ +"use client" + +import { useState, useCallback, useEffect, useRef } from "react" +import { motion, AnimatePresence } from "framer-motion" +import { GatoMascota } from "@/components/child/gato-mascota" +import NoChildError from "@/components/child/no-child-error" +import TemporizadorVisual from "@/components/child/temporizador-visual" +import ExerciseDispatcher from "@/components/exercises/exercise-dispatcher" +import { speak, stopSpeaking } from "@/lib/speech" + +const CHILD_ID_KEY = "edueasy_child_id" +const META_KEY = "edueasy_child_meta" + +type PageState = "loading" | "ready" | "complete" | "error" + +export default function NumerosSesion() { + const [pageState, setPageState] = useState("loading") + const [exercise, setExercise] = useState(null) + const [running, setRunning] = useState(true) + const [score, setScore] = useState(0) + const [totalAttempts, setTotalAttempts] = useState(0) + const childIdRef = useRef("") + const startedAtRef = useRef(new Date().toISOString()) + + const getChildId = useCallback(() => { + const id = localStorage.getItem(CHILD_ID_KEY) || "" + childIdRef.current = id + return id + }, []) + + const fetchNext = useCallback(async () => { + const childId = getChildId() + if (!childId) { + setPageState("error") + return null + } + + try { + const res = await fetch(`/api/curriculum/next?childId=${childId}&topic=numeros`) + const data = await res.json() + if (data.done || !data.id) { + setPageState("complete") + return null + } + setExercise(data) + setPageState("ready") + return data + } catch { + setPageState("error") + return null + } + }, [getChildId]) + + useEffect(() => { + fetchNext() + }, [fetchNext]) + + const gradeAttempt = useCallback(async (ex: any, correct: boolean) => { + const childId = childIdRef.current + if (!childId || !ex) return + + setTotalAttempts((t) => t + 1) + if (correct) setScore((s) => s + 1) + + const errorType = !correct + ? ex.errorType || "discriminacion-auditiva" + : null + + try { + await fetch("/api/curriculum/grade", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + childId, + exerciseId: ex.id, + skillCode: ex.skillCode, + correct, + promptLevel: 0, + responseMs: 3000, + errorType, + stage: ex.stage, + }), + }) + } catch { + // silent + } + }, []) + + const handleComplete = useCallback( + async (correct: boolean) => { + if (!exercise) return + await gradeAttempt(exercise, correct) + stopSpeaking() + if (correct) { + await speak("¡Muy bien!") + await new Promise((r) => setTimeout(r, 800)) + } + fetchNext() + }, + [exercise, gradeAttempt, fetchNext], + ) + + const resetSession = useCallback(() => { + setScore(0) + setTotalAttempts(0) + setRunning(true) + startedAtRef.current = new Date().toISOString() + fetchNext() + }, [fetchNext]) + + if (pageState === "loading") { + return ( +
+ +
+ ) + } + + if (pageState === "error") { + return + } + + if (pageState === "complete") { + return ( +
+ +

+ Aciertos: {score}/{totalAttempts} +

+ +
+ ) + } + + return ( +
+ { + setRunning(false) + setPageState("complete") + }} + running={running} + /> + + + + {exercise && ( + + )} + + +
+ ) +} diff --git a/app/child/page.tsx b/app/child/page.tsx new file mode 100644 index 0000000..e1ff5de --- /dev/null +++ b/app/child/page.tsx @@ -0,0 +1,34 @@ +"use client" + +import { useRouter } from "next/navigation" +import { GatoMascota } from "@/components/child/gato-mascota" + +const activities = [ + { id: "lectura", label: "Letras", icon: "Aa", color: "bg-primary" }, + { id: "numeros", label: "Números", icon: "123", color: "bg-accent" }, + { id: "logros", label: "Mis logros", icon: "⭐", color: "bg-warning" }, + { id: "pairing", label: "iPad nuevo", icon: "🔗", color: "bg-secondary" }, +] + +export default function ChildHome() { + const router = useRouter() + + return ( +
+ + +
+ {activities.map((a) => ( + + ))} +
+
+ ) +} diff --git a/app/child/pairing/page.tsx b/app/child/pairing/page.tsx new file mode 100644 index 0000000..fe1587c --- /dev/null +++ b/app/child/pairing/page.tsx @@ -0,0 +1,90 @@ +"use client" + +import { useState } from "react" +import { useRouter } from "next/navigation" +import { GatoMascota } from "@/components/child/gato-mascota" +import { speak } from "@/lib/speech" + +const CHILD_ID_KEY = "edueasy_child_id" + +export default function ChildPairingPage() { + const [code, setCode] = useState("") + const [loading, setLoading] = useState(false) + const [error, setError] = useState("") + const [paired, setPaired] = useState(false) + const router = useRouter() + + const handlePair = async (e: React.FormEvent) => { + e.preventDefault() + setLoading(true) + setError("") + + const deviceFingerprint = `child-${navigator.userAgent.slice(0, 64)}` + const res = await fetch("/api/pairing", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + pairingCode: code.toUpperCase(), + deviceFingerprint, + }), + }) + const data = await res.json() + + if (data.error) { + setError(data.error) + setLoading(false) + return + } + + localStorage.setItem(CHILD_ID_KEY, data.childId) + setPaired(true) + speak("¡Emparejado! Ahora podemos aprender juntos") + } + + if (paired) { + return ( +
+ + +
+ ) + } + + return ( +
+ + +
+ setCode(e.target.value.toUpperCase())} + placeholder="Código" + maxLength={8} + className="w-full rounded-2xl border-2 border-primary bg-white px-6 py-4 text-center text-3xl tracking-[0.5em] uppercase font-display font-bold focus:outline-none focus:ring-4 focus:ring-primary/30" + autoFocus + /> + {error &&

{error}

} + + +
+
+ ) +} diff --git a/app/globals.css b/app/globals.css new file mode 100644 index 0000000..8871305 --- /dev/null +++ b/app/globals.css @@ -0,0 +1,52 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@import url('https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600;700&family=Inter:wght@400;500;600;700&display=swap'); + +@layer base { + :root { + --radius: 1rem; + --background: 38 100% 97%; + --foreground: 200 6% 19%; + --primary: 150 22% 64%; + --primary-foreground: 0 0% 100%; + --secondary: 200 24% 53%; + --secondary-foreground: 0 0% 100%; + --accent: 30 48% 64%; + --accent-foreground: 0 0% 100%; + --muted: 30 20% 88%; + --muted-foreground: 200 4% 40%; + --card: 0 0% 100%; + --border: 30 20% 88%; + --ring: 150 22% 64%; + --success: 130 25% 61%; + --destructive: 0 62% 68%; + --warning: 35 85% 62%; + } +} + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground font-sans; + overscroll-behavior: none; + -webkit-overflow-scrolling: touch; + } +} + +@layer utilities { + .touch-target { + @apply min-h-[60px] min-w-[60px]; + } + .touch-target-lg { + @apply min-h-[80px] min-w-[80px]; + } +} + +/* iOS Safari quirks fixes */ +input, textarea { + font-size: 16px !important; +} diff --git a/app/layout.tsx b/app/layout.tsx new file mode 100644 index 0000000..f867b28 --- /dev/null +++ b/app/layout.tsx @@ -0,0 +1,38 @@ +import type { Metadata, Viewport } from "next" +import { Inter } from "next/font/google" +import "./globals.css" + +const inter = Inter({ subsets: ["latin"], variable: "--font-inter" }) + +export const metadata: Metadata = { + title: "EduEasy", + description: "Plataforma educativa infantil", + appleWebApp: { + capable: true, + statusBarStyle: "default", + title: "EduEasy", + }, +} + +export const viewport: Viewport = { + width: "device-width", + initialScale: 1, + maximumScale: 1, + viewportFit: "cover", +} + +export default function RootLayout({ + children, +}: { + children: React.ReactNode +}) { + return ( + + + + + + {children} + + ) +} diff --git a/app/page.tsx b/app/page.tsx new file mode 100644 index 0000000..8d35acc --- /dev/null +++ b/app/page.tsx @@ -0,0 +1,19 @@ +"use client" + +import { useEffect } from "react" +import { useRouter } from "next/navigation" + +export default function RootPage() { + const router = useRouter() + + useEffect(() => { + const host = window.location.hostname + if (host.includes("simulacro")) { + router.replace("/parent") + } else { + router.replace("/child") + } + }, [router]) + + return null +} diff --git a/app/parent/auth/login/page.tsx b/app/parent/auth/login/page.tsx new file mode 100644 index 0000000..3ddfc4c --- /dev/null +++ b/app/parent/auth/login/page.tsx @@ -0,0 +1,79 @@ +"use client" + +import { useState } from "react" +import { useRouter } from "next/navigation" +import { authClient } from "@/lib/auth-client" + +export default function LoginPage() { + const [email, setEmail] = useState("") + const [password, setPassword] = useState("") + const [loading, setLoading] = useState(false) + const [error, setError] = useState("") + const router = useRouter() + + const handleLogin = async (e: React.FormEvent) => { + e.preventDefault() + setLoading(true) + setError("") + + const { error: err } = await authClient.signIn.email({ + email, + password, + }) + + if (err) { + setError(err.message || "Error al iniciar sesión") + setLoading(false) + return + } + + router.push("/parent") + } + + return ( +
+
+

+ EduEasy · Mamá +

+ + {error && ( +

{error}

+ )} + + setEmail(e.target.value)} + className="w-full rounded-xl border border-border bg-white px-4 py-3 text-base focus:outline-none focus:ring-2 focus:ring-primary" + required + /> + + setPassword(e.target.value)} + className="w-full rounded-xl border border-border bg-white px-4 py-3 text-base focus:outline-none focus:ring-2 focus:ring-primary" + required + /> + + + +

+ ¿No tenés cuenta?{" "} + + Crear cuenta + +

+
+
+ ) +} diff --git a/app/parent/auth/pairing/page.tsx b/app/parent/auth/pairing/page.tsx new file mode 100644 index 0000000..b2acc2f --- /dev/null +++ b/app/parent/auth/pairing/page.tsx @@ -0,0 +1,144 @@ +"use client" + +import { useState, useEffect } from "react" +import { authClient } from "@/lib/auth-client" +import { useRouter } from "next/navigation" +import { GatoMascota } from "@/components/child/gato-mascota" + +interface ChildSummary { + id: string + name: string | null +} + +export default function PairingPage() { + const [code, setCode] = useState("") + const [loading, setLoading] = useState(false) + const [error, setError] = useState("") + const [paired, setPaired] = useState(false) + const [children, setChildren] = useState([]) + const [selectedChildId, setSelectedChildId] = useState("") + const { data: session } = authClient.useSession() + const router = useRouter() + + useEffect(() => { + fetch("/api/children") + .then((r) => r.json()) + .then((list) => { + if (Array.isArray(list)) { + setChildren(list) + if (list.length > 0) setSelectedChildId(list[0].id) + } + }) + .catch(() => {}) + }, []) + + const handlePairing = async (e: React.FormEvent) => { + e.preventDefault() + setLoading(true) + setError("") + + if (!selectedChildId) { + setError("Seleccioná un niño") + setLoading(false) + return + } + + try { + const res = await fetch("/api/pairing", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + pairingCode: code.toUpperCase(), + childId: selectedChildId, + }), + }) + const data = await res.json() + + if (data.error) { + setError(data.error) + setLoading(false) + return + } + + setPaired(true) + } catch { + setError("Error de conexión") + } + setLoading(false) + } + + if (!session) { + return ( +
+

Iniciá sesión primero para emparejar

+ +
+ ) + } + + return ( +
+

Emparejar iPad

+ + {paired ? ( +
+ + +
+ ) : ( +
+

+ Ingresá el código de 8 caracteres que aparece en el iPad +

+ + {children.length > 0 && ( +
+ {children.map((c) => ( + + ))} +
+ )} + + setCode(e.target.value.toUpperCase())} + placeholder="Código de 8 letras" + maxLength={8} + className="w-full rounded-xl border border-border bg-white px-4 py-3 text-center text-2xl tracking-widest uppercase focus:outline-none focus:ring-2 focus:ring-primary" + autoFocus + /> + {error &&

{error}

} + +
+ )} +
+ ) +} diff --git a/app/parent/auth/register/page.tsx b/app/parent/auth/register/page.tsx new file mode 100644 index 0000000..5ae5d3e --- /dev/null +++ b/app/parent/auth/register/page.tsx @@ -0,0 +1,88 @@ +"use client" + +import { useState } from "react" +import { useRouter } from "next/navigation" +import { authClient } from "@/lib/auth-client" + +export default function RegisterPage() { + const [email, setEmail] = useState("") + const [password, setPassword] = useState("") + const [name, setName] = useState("") + const [loading, setLoading] = useState(false) + const [error, setError] = useState("") + const router = useRouter() + + const handleRegister = async (e: React.FormEvent) => { + e.preventDefault() + setLoading(true) + setError("") + + const { error: err } = await authClient.signUp.email({ + email, + password, + name: name || "", + }) + + if (err) { + setError(err.message || "Error al registrarse") + setLoading(false) + return + } + + router.push("/parent") + } + + return ( +
+
+

+ Crear cuenta · Mamá +

+ + {error &&

{error}

} + + setName(e.target.value)} + className="w-full rounded-xl border border-border bg-white px-4 py-3 text-base focus:outline-none focus:ring-2 focus:ring-primary" + /> + + setEmail(e.target.value)} + className="w-full rounded-xl border border-border bg-white px-4 py-3 text-base focus:outline-none focus:ring-2 focus:ring-primary" + required + /> + + setPassword(e.target.value)} + minLength={8} + className="w-full rounded-xl border border-border bg-white px-4 py-3 text-base focus:outline-none focus:ring-2 focus:ring-primary" + required + /> + + + +

+ ¿Ya tenés cuenta?{" "} + + Iniciá sesión + +

+
+
+ ) +} diff --git a/app/parent/configuracion/page.tsx b/app/parent/configuracion/page.tsx new file mode 100644 index 0000000..9b827bc --- /dev/null +++ b/app/parent/configuracion/page.tsx @@ -0,0 +1,36 @@ +"use client" + +import { authClient } from "@/lib/auth-client" +import { useRouter } from "next/navigation" + +export default function ConfigPage() { + const { data: session } = authClient.useSession() + const router = useRouter() + + return ( +
+

Configuración

+ +
+
+

Email

+

{session?.user?.email || "—"}

+
+ + + + +
+
+ ) +} diff --git a/app/parent/dashboard/page.tsx b/app/parent/dashboard/page.tsx new file mode 100644 index 0000000..577a08b --- /dev/null +++ b/app/parent/dashboard/page.tsx @@ -0,0 +1,293 @@ +"use client" + +import { useState, useEffect } from "react" +import { useRouter } from "next/navigation" +import { authClient } from "@/lib/auth-client" +import { MetricCard } from "@/components/parent/metric-card" +import { WeeklyActivityChart } from "@/components/parent/weekly-activity-chart" +import { SkillMasteryChart } from "@/components/parent/skill-mastery-chart" +import { MilestonesList } from "@/components/parent/milestones-list" +import ErrorPatternsChart from "@/components/parent/error-patterns-chart" + +interface ChildSummary { + id: string + name: string | null +} + +interface DashboardData { + totalSessions: number + todaySessions: number + todayMinutes: number + masteryPercent: number + masteredSkills: number + totalSkills: number + milestones: number + milestoneData: { skillCode: string; reachedAt: string }[] + streak: number + weeklyData: { date: string; minutes: number }[] + skillBreakdown: { skillCode: string; stability: number; reps: number }[] + stageProgress: { topic: string; stage: number; completedAt: string | null }[] + errorTypeCount: Record + totalErrors: number + lastSession: { + startedAt: string + durationSec: number + skillsPracticed: string + correctCount: number + totalAttempts: number + } | null +} + +export default function ParentDashboard() { + const { data: session, isPending } = authClient.useSession() + const router = useRouter() + const [children, setChildren] = useState([]) + const [selectedChildId, setSelectedChildId] = useState("") + const [data, setData] = useState(null) + const [loading, setLoading] = useState(true) + const [creating, setCreating] = useState(false) + const [newChildName, setNewChildName] = useState("") + const [pairingCode, setPairingCode] = useState("") + + useEffect(() => { + fetch("/api/children") + .then((r) => r.json()) + .then((list) => { + if (Array.isArray(list)) { + setChildren(list) + if (list.length > 0) setSelectedChildId(list[0].id) + } + }) + .catch(() => {}) + }, []) + + useEffect(() => { + if (!selectedChildId) { + setLoading(false) + return + } + setLoading(true) + fetch(`/api/dashboard/summary?childId=${selectedChildId}`) + .then((r) => r.json()) + .then(setData) + .catch(() => {}) + .finally(() => setLoading(false)) + }, [selectedChildId]) + + const handleCreateChild = async () => { + if (!newChildName.trim()) return + setCreating(true) + const res = await fetch("/api/children", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ name: newChildName.trim() }), + }) + if (res.ok) { + const child = await res.json() + setChildren((prev) => [...prev, child]) + setSelectedChildId(child.id) + setNewChildName("") + } + setCreating(false) + } + + const handleGeneratePairingCode = async () => { + if (!selectedChildId) return + const res = await fetch("/api/pairing", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ action: "generate", childId: selectedChildId }), + }) + const data = await res.json() + if (data.pairingCode) { + setPairingCode(data.pairingCode) + } + } + + useEffect(() => { + if (!isPending && !session) { + router.push("/parent/auth/login") + } + }, [session, isPending, router]) + + if (isPending || !session) { + return ( +
Cargando...
+ ) + } + + const selectedChild = children.find((c) => c.id === selectedChildId) + + return ( +
+
+
+

Dashboard

+

+ Bienvenida, {session.user?.name || "Mamá"} +

+
+
+ + {children.length === 0 ? ( +
+

Agregar un niño

+
+ setNewChildName(e.target.value)} + placeholder="Nombre de la nena" + className="flex-1 rounded-xl border border-border bg-white px-4 py-3 text-base focus:outline-none focus:ring-2 focus:ring-primary" + /> + +
+
+ ) : ( + <> +
+ {children.map((c) => ( + + ))} +
+ + {loading ? ( +
Cargando...
+ ) : data ? ( +
+
+ + 0 ? `${data.todaySessions} sesiones` : undefined} + variant="success" + /> + + +
+ +
+

+ Actividad semanal +

+ +
+ +
+

+ Maestría por skill +

+ +
+ +
+

Logros

+ +
+ + {data.stageProgress.length > 0 && ( +
+

Progreso curricular

+
+ {data.stageProgress.map((sp) => ( +
+ + {sp.topic === "lectura" ? "Lectura" : "Números"} — Etapa {sp.stage} + + + {sp.completedAt ? "✅ Completada" : "🔵 En curso"} + +
+ ))} +
+
+ )} + + {data.totalErrors > 0 && ( +
+

Patrones de error

+ +
+ )} + + {data.lastSession && ( +
+

Última sesión

+
+

{new Date(data.lastSession.startedAt).toLocaleDateString("es-AR")}

+

+ {Math.round((data.lastSession.durationSec ?? 0) / 60)} min ·{" "} + {data.lastSession.correctCount}/{data.lastSession.totalAttempts} correctas +

+

Skills: {data.lastSession.skillsPracticed || "—"}

+
+
+ )} + +
+ + +
+
+ ) : ( +
+ Seleccioná un niño para ver su progreso +
+ )} + + )} + + {pairingCode && ( +
+
+

Código de emparejamiento

+

+ Ingresá este código en el iPad de la nena +

+

+ {pairingCode} +

+ +
+
+ )} +
+ ) +} diff --git a/app/parent/layout.tsx b/app/parent/layout.tsx new file mode 100644 index 0000000..9051c1a --- /dev/null +++ b/app/parent/layout.tsx @@ -0,0 +1,86 @@ +"use client" + +import { useState } from "react" +import Link from "next/link" +import { usePathname } from "next/navigation" +import { authClient } from "@/lib/auth-client" +import { cn } from "@/lib/utils" + +const navItems = [ + { href: "/parent/dashboard", label: "Dashboard", emoji: "📊" }, + { href: "/parent/configuracion", label: "Configuración", emoji: "⚙️" }, +] + +export default function ParentLayout({ children }: { children: React.ReactNode }) { + const pathname = usePathname() + const { data: session } = authClient.useSession() + const [sidebarOpen, setSidebarOpen] = useState(false) + + if ( + pathname.startsWith("/parent/auth") + ) { + return
{children}
+ } + + return ( +
+
+
+ +

EduEasy

+
+
+ + {session?.user?.name || "Mamá"} + + +
+
+ + {sidebarOpen && ( +
setSidebarOpen(false)} + > + +
+ )} + +
{children}
+
+ ) +} diff --git a/app/parent/page.tsx b/app/parent/page.tsx new file mode 100644 index 0000000..168d0a4 --- /dev/null +++ b/app/parent/page.tsx @@ -0,0 +1,21 @@ +"use client" + +import { useEffect } from "react" +import { useRouter } from "next/navigation" +import { authClient } from "@/lib/auth-client" + +export default function ParentPage() { + const { data: session, isPending } = authClient.useSession() + const router = useRouter() + + useEffect(() => { + if (isPending) return + if (session) { + router.replace("/parent/dashboard") + } else { + router.replace("/parent/auth/login") + } + }, [session, isPending, router]) + + return null +} diff --git a/components.json b/components.json new file mode 100644 index 0000000..53f6fc3 --- /dev/null +++ b/components.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "default", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "tailwind.config.ts", + "css": "app/globals.css", + "baseColor": "slate", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + } +} diff --git a/components/child/audio-unlock.tsx b/components/child/audio-unlock.tsx new file mode 100644 index 0000000..d1dd0b9 --- /dev/null +++ b/components/child/audio-unlock.tsx @@ -0,0 +1,43 @@ +"use client" + +import { useState } from "react" +import { motion } from "framer-motion" +import { GatoMascota } from "./gato-mascota" + +interface AudioUnlockProps { + onUnlock: () => void +} + +export default function AudioUnlock({ onUnlock }: AudioUnlockProps) { + const [pressed, setPressed] = useState(false) + + const handleUnlock = () => { + if (typeof window !== "undefined") { + const AudioCtx = window.AudioContext || (window as any).webkitAudioContext + if (AudioCtx) { + const ctx = new AudioCtx() + ctx.resume().then(() => { + ctx.close() + }) + } + } + setPressed(true) + setTimeout(onUnlock, 600) + } + + return ( +
+ + + + {pressed ? "¡Empezamos!" : "TOCÁ ACÁ"} + +
+ ) +} diff --git a/components/child/cpa-exercise.tsx b/components/child/cpa-exercise.tsx new file mode 100644 index 0000000..b89d7e3 --- /dev/null +++ b/components/child/cpa-exercise.tsx @@ -0,0 +1,33 @@ +"use client" + +import { speak } from "@/lib/speech" + +export interface CPAExerciseProps { + value: number + stage: "concrete" | "pictoric" | "abstract" + onCorrect: () => void + onIncorrect: () => void +} + +export function generateCPAItems(value: number, stage: string): Array<{ emoji: string; id: number }> { + const pool = ["🍎", "🐱", "⭐", "🌸", "🎈", "🐶", "🍪", "🌈", "🦋", "🧸"] + return Array.from({ length: value }, (_, i) => ({ + emoji: pool[i % pool.length], + id: i, + })) +} + +export function speakCPAInstruction(value: number, stage: string) { + if (stage === "concrete") { + speak(`Tocá ${value} ${getItemName(value)}`) + } else if (stage === "pictoric") { + speak(`¿Cuántos hay? Señalá el número`) + } else { + speak(`¿Este número es el ${value}?`) + } +} + +function getItemName(n: number): string { + if (n === 1) return "elemento" + return "elementos" +} diff --git a/components/child/cuisenaire-rod.tsx b/components/child/cuisenaire-rod.tsx new file mode 100644 index 0000000..6c14661 --- /dev/null +++ b/components/child/cuisenaire-rod.tsx @@ -0,0 +1,58 @@ +"use client" + +import { useState } from "react" +import { motion } from "framer-motion" + +export interface CuisenaireRodProps { + value: number + color: string + length: number + draggable?: boolean + onDrop?: (value: number) => void +} + +const rodColors: Record = { + 1: "#FFFFFF", + 2: "#E74C3C", + 3: "#2ECC71", + 4: "#E91E63", + 5: "#F1C40F", + 6: "#1ABC9C", + 7: "#2C3E50", + 8: "#3498DB", + 9: "#9B59B6", + 10: "#E67E22", +} + +const rodLengths: Record = { + 1: 20, 2: 40, 3: 60, 4: 80, 5: 100, + 6: 120, 7: 140, 8: 160, 9: 180, 10: 200, +} + +export { rodColors, rodLengths } + +export function CuisenaireRod({ value, color, length, draggable = false }: CuisenaireRodProps) { + const [isDragging, setIsDragging] = useState(false) + + return ( + setIsDragging(true)} + onDragEnd={() => setIsDragging(false)} + dragConstraints={{ left: -400, right: 400, top: -300, bottom: 300 }} + /> + ) +} diff --git a/components/child/gato-mascota.tsx b/components/child/gato-mascota.tsx new file mode 100644 index 0000000..4a785d9 --- /dev/null +++ b/components/child/gato-mascota.tsx @@ -0,0 +1,56 @@ +"use client" + +import { motion } from "framer-motion" + +interface GatoMascotaProps { + mood?: "happy" | "thinking" | "celebrate" | "coach" + message?: string + size?: "sm" | "md" | "lg" +} + +const moods = { + happy: { + emoji: "😺", + animation: { y: [0, -5, 0] }, + transition: { repeat: Infinity, duration: 2 }, + }, + thinking: { + emoji: "🤔", + animation: { rotate: [0, -10, 10, 0] }, + transition: { repeat: Infinity, duration: 1.5 }, + }, + celebrate: { + emoji: "🎉", + animation: { scale: [1, 1.2, 1] }, + transition: { repeat: Infinity, duration: 0.8 }, + }, + coach: { + emoji: "🐱", + animation: { y: 0 }, + transition: { duration: 0 }, + }, +} + +export function GatoMascota({ mood = "happy", message, size = "md" }: GatoMascotaProps) { + const config = moods[mood] + const sizeClass = size === "sm" ? "text-3xl" : size === "lg" ? "text-7xl" : "text-5xl" + + return ( +
+ + {config.emoji} + + {message && ( +

+ {message} +

+ )} +
+ ) +} + +export default GatoMascota diff --git a/components/child/no-child-error.tsx b/components/child/no-child-error.tsx new file mode 100644 index 0000000..467c090 --- /dev/null +++ b/components/child/no-child-error.tsx @@ -0,0 +1,53 @@ +"use client" + +import { useRouter } from "next/navigation" +import { GatoMascota } from "./gato-mascota" + +const CHILD_ID_KEY = "edueasy_child_id" + +interface Props { + onRetry?: () => void +} + +export default function NoChildError({ onRetry }: Props) { + const router = useRouter() + const hasChildId = typeof window !== "undefined" && localStorage.getItem(CHILD_ID_KEY) + + return ( +
+ +
+ {hasChildId ? ( +

+ No pude conectar con el servidor. Revisá la conexión. +

+ ) : ( + <> +

Pedile a mamá que te empareje desde su celular.

+

Mamá va a Dashboard → Emparejar nuevo iPad

+ + )} +
+
+ {hasChildId && onRetry && ( + + )} + +
+
+ ) +} diff --git a/components/child/temporizador-visual.tsx b/components/child/temporizador-visual.tsx new file mode 100644 index 0000000..b19eecf --- /dev/null +++ b/components/child/temporizador-visual.tsx @@ -0,0 +1,76 @@ +"use client" + +import { useEffect, useRef, useState } from "react" +import { motion } from "framer-motion" + +interface TemporizadorVisualProps { + durationMinutes: number + onComplete: () => void + running: boolean +} + +export default function TemporizadorVisual({ + durationMinutes, + onComplete, + running, +}: TemporizadorVisualProps) { + const [remaining, setRemaining] = useState(durationMinutes * 60) + const totalSec = durationMinutes * 60 + const intervalRef = useRef(null) + const onCompleteRef = useRef(onComplete) + onCompleteRef.current = onComplete + + useEffect(() => { + if (running) { + intervalRef.current = setInterval(() => { + setRemaining((prev) => { + if (prev <= 1) { + clearInterval(intervalRef.current!) + onCompleteRef.current() + return 0 + } + return prev - 1 + }) + }, 1000) + } else { + if (intervalRef.current) clearInterval(intervalRef.current) + } + + return () => { + if (intervalRef.current) clearInterval(intervalRef.current) + } + }, [running]) + + const fraction = remaining / totalSec + const degrees = fraction * 360 + const minutes = Math.floor(remaining / 60) + const seconds = remaining % 60 + + return ( +
+
+ + + 0.3 ? "#8CB8A0" : "#D4A574"} + strokeWidth="8" + strokeDasharray="264" + strokeDashoffset={264 * (1 - fraction)} + strokeLinecap="round" + className="transition-all duration-1000 ease-linear" + /> + + + {minutes}:{seconds.toString().padStart(2, "0")} + +
+
+ ) +} diff --git a/components/child/trazo-letra.tsx b/components/child/trazo-letra.tsx new file mode 100644 index 0000000..7b4f248 --- /dev/null +++ b/components/child/trazo-letra.tsx @@ -0,0 +1,158 @@ +"use client" + +import { useState, useRef, useCallback, useEffect } from "react" +import { getStroke } from "perfect-freehand" + +interface TrazoLetraProps { + letra: string + color?: string + onComplete?: () => void + promptLevel?: number +} + +export default function TrazoLetra({ + letra, + color = "#8CB8A0", + onComplete, + promptLevel = 0, +}: TrazoLetraProps) { + const canvasRef = useRef(null) + const [isDrawing, setIsDrawing] = useState(false) + const points = useRef([]) + const [showLetter, setShowLetter] = useState(promptLevel < 2) + + useEffect(() => { + if (promptLevel < 2) { + drawLetterGuide(letra) + } + }, [letra, promptLevel]) + + useEffect(() => { + const canvas = canvasRef.current + if (!canvas) return + canvas.style.touchAction = "none" + }, []) + + const drawLetterGuide = (l: string) => { + const canvas = canvasRef.current + if (!canvas) return + const ctx = canvas.getContext("2d") + if (!ctx) return + const w = canvas.width + const h = canvas.height + ctx.clearRect(0, 0, w, h) + + ctx.font = `${h * 0.6}px "Fredoka", sans-serif` + ctx.textAlign = "center" + ctx.textBaseline = "middle" + ctx.globalAlpha = 0.15 + ctx.fillStyle = "#2D3436" + ctx.fillText(l.toUpperCase(), w / 2, h / 2) + ctx.globalAlpha = 1 + } + + const startDrawing = useCallback((e: React.PointerEvent) => { + setIsDrawing(true) + points.current = [[e.clientX, e.clientY, e.pressure || 0.5]] + const canvas = canvasRef.current + if (canvas) canvas.setPointerCapture(e.pointerId) + }, []) + + const draw = useCallback((e: React.PointerEvent) => { + if (!isDrawing) return + points.current.push([e.clientX, e.clientY, e.pressure || 0.5]) + renderStroke() + }, [isDrawing]) + + const endDrawing = useCallback(() => { + setIsDrawing(false) + if (points.current.length > 5 && onComplete) { + onComplete() + } + points.current = [] + }, [onComplete]) + + const renderStroke = () => { + const canvas = canvasRef.current + if (!canvas) return + const ctx = canvas.getContext("2d") + if (!ctx) return + + const stroke = getStroke(points.current, { + size: 12, + thinning: 0.5, + smoothing: 0.5, + streamline: 0.5, + }) + + if (stroke.length < 2) return + + ctx.clearRect(0, 0, canvas.width, canvas.height) + if (showLetter) drawLetterGuide(letra) + + ctx.beginPath() + ctx.moveTo(stroke[0][0], stroke[0][1]) + for (let i = 1; i < stroke.length; i++) { + ctx.lineTo(stroke[i][0], stroke[i][1]) + } + ctx.strokeStyle = color + ctx.lineWidth = 3 + ctx.lineCap = "round" + ctx.lineJoin = "round" + ctx.fillStyle = color + ctx.fill() + + if (promptLevel < 3) { + drawDirectionArrow(ctx, letra) + } + } + + const drawDirectionArrow = (ctx: CanvasRenderingContext2D, l: string) => { + const w = ctx.canvas.width + const h = ctx.canvas.height + ctx.save() + ctx.globalAlpha = 0.3 + ctx.strokeStyle = "#8CB8A0" + ctx.lineWidth = 2 + ctx.fillStyle = "#8CB8A0" + + const arrowPaths: Record = { + a: { sx: w * 0.3, sy: h * 0.7, ex: w * 0.7, ey: h * 0.3 }, + e: { sx: w * 0.3, sy: h * 0.3, ex: w * 0.7, ey: h * 0.7 }, + i: { sx: w * 0.5, sy: h * 0.2, ex: w * 0.5, ey: h * 0.8 }, + o: { sx: w * 0.3, sy: h * 0.3, ex: w * 0.6, ey: h * 0.6 }, + u: { sx: w * 0.3, sy: h * 0.3, ex: w * 0.7, ey: h * 0.5 }, + } + + const path = arrowPaths[l.toLowerCase()] + if (path) { + ctx.beginPath() + ctx.moveTo(path.sx, path.sy) + ctx.lineTo(path.ex, path.ey) + ctx.stroke() + + const angle = Math.atan2(path.ey - path.sy, path.ex - path.sx) + const sz = 6 + ctx.beginPath() + ctx.moveTo(path.ex, path.ey) + ctx.lineTo(path.ex - sz * Math.cos(angle - Math.PI / 6), path.ey - sz * Math.sin(angle - Math.PI / 6)) + ctx.lineTo(path.ex - sz * Math.cos(angle + Math.PI / 6), path.ey - sz * Math.sin(angle + Math.PI / 6)) + ctx.closePath() + ctx.fill() + } + ctx.restore() + } + + return ( + + ) +} diff --git a/components/child/vocal-card.tsx b/components/child/vocal-card.tsx new file mode 100644 index 0000000..eb95cd1 --- /dev/null +++ b/components/child/vocal-card.tsx @@ -0,0 +1,43 @@ +"use client" + +import { motion } from "framer-motion" + +export interface VocalCardProps { + letra: string + fonema: string + palabra: string + imageEmoji: string + color?: string + onClick: () => void + disabled?: boolean +} + +export default function VocalCard({ + letra, + fonema, + palabra, + imageEmoji, + color = "#8CB8A0", + onClick, + disabled = false, +}: VocalCardProps) { + return ( + + + {letra.toUpperCase()} + + {imageEmoji} + + {palabra} + + + ) +} diff --git a/components/exercises/ejercicio-conciencia.tsx b/components/exercises/ejercicio-conciencia.tsx new file mode 100644 index 0000000..f799a3f --- /dev/null +++ b/components/exercises/ejercicio-conciencia.tsx @@ -0,0 +1,57 @@ +"use client" + +import { useState } from "react" +import { motion, AnimatePresence } from "framer-motion" +import { speak } from "@/lib/speech" +import { GatoMascota } from "@/components/child/gato-mascota" +import type { Exercise } from "@/curriculum/types" + +interface Props { + exercise: Exercise + onComplete: (correct: boolean) => void +} + +export default function EjercicioConciencia({ exercise, onComplete }: Props) { + const { content } = exercise + const options = content.options || [] + + const handleChoose = async (opt: (typeof options)[0]) => { + if (content.audioText) await speak(content.audioText) + onComplete(opt.correct) + } + + return ( +
+ + + {content.text && ( +

{content.text}

+ )} + + {content.emoji && ( + + {content.emoji} + + )} + +
+ {options.map((opt, i) => ( + handleChoose(opt)} + className="touch-target-lg rounded-2xl px-8 py-6 text-xl font-display font-bold shadow-md active:scale-95 transition-transform bg-white" + > + {opt.label} + + ))} +
+
+ ) +} diff --git a/components/exercises/ejercicio-eleccion.tsx b/components/exercises/ejercicio-eleccion.tsx new file mode 100644 index 0000000..563b532 --- /dev/null +++ b/components/exercises/ejercicio-eleccion.tsx @@ -0,0 +1,46 @@ +"use client" + +import { motion } from "framer-motion" +import { speak } from "@/lib/speech" +import { GatoMascota } from "@/components/child/gato-mascota" +import type { Exercise } from "@/curriculum/types" + +interface Props { + exercise: Exercise + onComplete: (correct: boolean) => void +} + +export default function EjercicioEleccion({ exercise, onComplete }: Props) { + const { content } = exercise + const options = content.options || [] + + const handleChoose = async (opt: (typeof options)[0]) => { + if (content.audioText) await speak(content.audioText) + onComplete(opt.correct) + } + + return ( +
+ + + {content.text && ( +

{content.text}

+ )} + +
+ {options.map((opt, i) => ( + handleChoose(opt)} + className="touch-target-lg rounded-2xl px-8 py-6 text-3xl font-display font-bold shadow-md active:scale-95 transition-transform bg-white" + > + {opt.label} + + ))} +
+
+ ) +} diff --git a/components/exercises/ejercicio-lectura.tsx b/components/exercises/ejercicio-lectura.tsx new file mode 100644 index 0000000..5483903 --- /dev/null +++ b/components/exercises/ejercicio-lectura.tsx @@ -0,0 +1,56 @@ +"use client" + +import { motion } from "framer-motion" +import { speak } from "@/lib/speech" +import { GatoMascota } from "@/components/child/gato-mascota" +import type { Exercise } from "@/curriculum/types" + +interface Props { + exercise: Exercise + onComplete: (correct: boolean) => void +} + +export default function EjercicioLectura({ exercise, onComplete }: Props) { + const { content } = exercise + const options = content.options || [] + + const handleChoose = async (opt: (typeof options)[0]) => { + if (content.audioText) await speak(content.audioText) + onComplete(opt.correct) + } + + return ( +
+ + + {content.text && ( + +

{content.text}

+
+ )} + + {content.imageEmoji && ( +
{content.imageEmoji}
+ )} + +
+ {options.map((opt, i) => ( + handleChoose(opt)} + className="touch-target-lg rounded-2xl px-8 py-5 text-lg font-display font-bold shadow-md active:scale-95 transition-transform bg-white" + > + {opt.label} + + ))} +
+
+ ) +} diff --git a/components/exercises/ejercicio-palabra.tsx b/components/exercises/ejercicio-palabra.tsx new file mode 100644 index 0000000..3dd3003 --- /dev/null +++ b/components/exercises/ejercicio-palabra.tsx @@ -0,0 +1,60 @@ +"use client" + +import { useState } from "react" +import { motion, AnimatePresence } from "framer-motion" +import { speak } from "@/lib/speech" +import { GatoMascota } from "@/components/child/gato-mascota" +import type { Exercise } from "@/curriculum/types" + +interface Props { + exercise: Exercise + onComplete: (correct: boolean) => void +} + +export default function EjercicioPalabra({ exercise, onComplete }: Props) { + const { content } = exercise + const options = content.options || [] + + const handleChoose = async (opt: (typeof options)[0]) => { + if (opt.id === "escuchar") { + if (content.audioText) await speak(content.audioText) + return + } + onComplete(opt.correct) + } + + return ( +
+ + + {content.imageEmoji && ( + + {content.imageEmoji} + + )} + +
+ {options.map((opt, i) => ( + handleChoose(opt)} + className={`touch-target-lg rounded-2xl px-8 py-6 text-xl font-display font-bold shadow-md active:scale-95 transition-transform ${ + opt.id === "escuchar" + ? "bg-accent text-accent-foreground" + : "bg-white" + }`} + > + {opt.label} + + ))} +
+
+ ) +} diff --git a/components/exercises/ejercicio-secuencia.tsx b/components/exercises/ejercicio-secuencia.tsx new file mode 100644 index 0000000..0c4a93e --- /dev/null +++ b/components/exercises/ejercicio-secuencia.tsx @@ -0,0 +1,54 @@ +"use client" + +import { useState } from "react" +import { motion, Reorder } from "framer-motion" +import { speak } from "@/lib/speech" +import { GatoMascota } from "@/components/child/gato-mascota" +import type { Exercise } from "@/curriculum/types" + +interface Props { + exercise: Exercise + onComplete: (correct: boolean) => void +} + +export default function EjercicioSecuencia({ exercise, onComplete }: Props) { + const { content } = exercise + const sequence = content.sequence || [] + + const [items, setItems] = useState(() => + [...sequence].sort(() => Math.random() - 0.5), + ) + + const handleReorder = (newOrder: string[]) => { + setItems(newOrder) + if (newOrder.every((item, i) => item === sequence[i])) { + if (content.audioText) speak(content.audioText) + onComplete(true) + } + } + + return ( +
+ + + + {items.map((item) => ( + + {item} + + ))} + + +

Arrastrá para ordenar

+
+ ) +} diff --git a/components/exercises/ejercicio-sensibilizacion.tsx b/components/exercises/ejercicio-sensibilizacion.tsx new file mode 100644 index 0000000..ce91564 --- /dev/null +++ b/components/exercises/ejercicio-sensibilizacion.tsx @@ -0,0 +1,61 @@ +"use client" + +import { motion } from "framer-motion" +import { speak } from "@/lib/speech" +import { GatoMascota } from "@/components/child/gato-mascota" +import type { Exercise } from "@/curriculum/types" + +interface Props { + exercise: Exercise + onComplete: (correct: boolean) => void +} + +export default function EjercicioSensibilizacion({ exercise, onComplete }: Props) { + const { content } = exercise + const hasOptions = content.options && content.options.length > 0 + + const handleClick = async (option: { label: string; correct: boolean }) => { + if (content.audioText) await speak(content.audioText) + onComplete(option.correct) + } + + return ( +
+ + + + {content.emoji && {content.emoji}} + + + {hasOptions && ( +
+ {content.options!.map((opt, i) => ( + handleClick(opt)} + className="touch-target-lg rounded-2xl px-8 py-6 text-xl font-display font-bold shadow-md active:scale-95 transition-transform bg-white" + > + {opt.label} + + ))} +
+ )} + + {!hasOptions && ( + + )} +
+ ) +} diff --git a/components/exercises/ejercicio-trazo.tsx b/components/exercises/ejercicio-trazo.tsx new file mode 100644 index 0000000..896ac56 --- /dev/null +++ b/components/exercises/ejercicio-trazo.tsx @@ -0,0 +1,66 @@ +"use client" + +import { motion } from "framer-motion" +import { speak } from "@/lib/speech" +import { GatoMascota } from "@/components/child/gato-mascota" +import TrazoLetra from "@/components/child/trazo-letra" +import type { Exercise } from "@/curriculum/types" + +interface Props { + exercise: Exercise + onComplete: (correct: boolean) => void +} + +export default function EjercicioTrazo({ exercise, onComplete }: Props) { + const { content } = exercise + const charToTrace = content.text && content.text.length === 1 + ? content.text.toUpperCase() + : null + + const handleAudio = async () => { + if (content.audioText) await speak(content.audioText) + } + + return ( +
+ + + {charToTrace ? ( + <> + onComplete(true)} + promptLevel={0} + /> + {content.audioText && ( + + )} + + ) : ( + <> + {content.emoji && ( + + {content.emoji} + + )} + + + )} +
+ ) +} diff --git a/components/exercises/exercise-dispatcher.tsx b/components/exercises/exercise-dispatcher.tsx new file mode 100644 index 0000000..57883fb --- /dev/null +++ b/components/exercises/exercise-dispatcher.tsx @@ -0,0 +1,34 @@ +"use client" + +import dynamic from "next/dynamic" +import type { Exercise, ExerciseType } from "@/curriculum/types" + +const EjercicioSensibilizacion = dynamic(() => import("./ejercicio-sensibilizacion"), { ssr: false }) +const EjercicioConciencia = dynamic(() => import("./ejercicio-conciencia"), { ssr: false }) +const EjercicioEleccion = dynamic(() => import("./ejercicio-eleccion"), { ssr: false }) +const EjercicioSecuencia = dynamic(() => import("./ejercicio-secuencia"), { ssr: false }) +const EjercicioPalabra = dynamic(() => import("./ejercicio-palabra"), { ssr: false }) +const EjercicioLectura = dynamic(() => import("./ejercicio-lectura"), { ssr: false }) +const EjercicioTrazo = dynamic(() => import("./ejercicio-trazo"), { ssr: false }) + +const componentMap: Record void }>> = { + sensibilizacion: EjercicioSensibilizacion, + conciencia: EjercicioConciencia, + trazo: EjercicioTrazo, + eleccion: EjercicioEleccion, + emparejar: EjercicioConciencia, + secuencia: EjercicioSecuencia, + palabra: EjercicioPalabra, + problema: EjercicioLectura, + lectura: EjercicioLectura, +} + +interface Props { + exercise: Exercise + onComplete: (correct: boolean) => void +} + +export default function ExerciseDispatcher({ exercise, onComplete }: Props) { + const Component = componentMap[exercise.type] || EjercicioSensibilizacion + return +} diff --git a/components/parent/error-patterns-chart.tsx b/components/parent/error-patterns-chart.tsx new file mode 100644 index 0000000..f178a8e --- /dev/null +++ b/components/parent/error-patterns-chart.tsx @@ -0,0 +1,68 @@ +"use client" + +const errorLabels: Record = { + "discriminacion-auditiva": "Discriminación auditiva", + "confusion-letra": "Confusión de letra", + "silaba-dificil": "Sílaba difícil", + "omision-letra": "Omisión de letra", + "inversion-letra": "Inversión de letra", +} + +const errorColors: Record = { + "discriminacion-auditiva": "bg-blue-200 text-blue-800", + "confusion-letra": "bg-red-200 text-red-800", + "silaba-dificil": "bg-yellow-200 text-yellow-800", + "omision-letra": "bg-purple-200 text-purple-800", + "inversion-letra": "bg-orange-200 text-orange-800", +} + +interface Props { + data: Record + total: number +} + +export default function ErrorPatternsChart({ data, total }: Props) { + const entries = Object.entries(data) + + if (total === 0) { + return ( +

+ Sin errores registrados. ¡Bien ahí! +

+ ) + } + + return ( +
+ {entries.map(([key, count]) => { + const pct = Math.round((count / total) * 100) + return ( +
+
+ {errorLabels[key] || key} + + {count} ({pct}%) + +
+
+
+
+
+ ) + })} +
+ ) +} diff --git a/components/parent/metric-card.tsx b/components/parent/metric-card.tsx new file mode 100644 index 0000000..0821077 --- /dev/null +++ b/components/parent/metric-card.tsx @@ -0,0 +1,26 @@ +import { cn } from "@/lib/utils" + +interface MetricCardProps { + title: string + value: string | number + subtitle?: string + variant?: "default" | "primary" | "success" | "accent" + className?: string +} + +const variants = { + default: "bg-white", + primary: "bg-primary/10 border-primary/20", + success: "bg-success/10 border-success/20", + accent: "bg-accent/10 border-accent/20", +} + +export function MetricCard({ title, value, subtitle, variant = "default", className }: MetricCardProps) { + return ( +
+

{title}

+

{value}

+ {subtitle &&

{subtitle}

} +
+ ) +} diff --git a/components/parent/milestones-list.tsx b/components/parent/milestones-list.tsx new file mode 100644 index 0000000..4ee4ed7 --- /dev/null +++ b/components/parent/milestones-list.tsx @@ -0,0 +1,40 @@ +interface MilestoneData { + skillCode: string + reachedAt: string +} + +const skillLabels: Record = { + "vocal-a": "Letra A", + "vocal-e": "Letra E", + "vocal-i": "Letra I", + "vocal-o": "Letra O", + "vocal-u": "Letra U", + "numero-1": "Número 1", + "numero-2": "Número 2", + "numero-3": "Número 3", + "numero-4": "Número 4", + "numero-5": "Número 5", +} + +export function MilestonesList({ data }: { data: MilestoneData[] }) { + if (!data || data.length === 0) { + return ( +
+ Todavía no hay logros +
+ ) + } + + return ( +
+ {data.map((m) => ( +
+ {skillLabels[m.skillCode] || m.skillCode} +
+ ))} +
+ ) +} diff --git a/components/parent/skill-mastery-chart.tsx b/components/parent/skill-mastery-chart.tsx new file mode 100644 index 0000000..c1d3ec7 --- /dev/null +++ b/components/parent/skill-mastery-chart.tsx @@ -0,0 +1,61 @@ +"use client" + +import { + RadarChart, + PolarGrid, + PolarAngleAxis, + PolarRadiusAxis, + Radar, + ResponsiveContainer, +} from "recharts" + +interface SkillData { + skillCode: string + stability: number + reps: number +} + +export function SkillMasteryChart({ data }: { data: SkillData[] }) { + if (!data || data.length === 0) { + return ( +
+ Sin skills todavía +
+ ) + } + + const chartData = data + .filter((s) => s.reps > 0) + .slice(0, 8) + .map((s) => ({ + skill: s.skillCode.replace("vocal-", "").replace("numero-", "num "), + mastery: Math.min(Math.round((s.stability / 100) * 100), 100), + })) + + if (chartData.length === 0) { + return ( +
+ Sin skills todavía +
+ ) + } + + return ( +
+ + + + + + + + +
+ ) +} diff --git a/components/parent/weekly-activity-chart.tsx b/components/parent/weekly-activity-chart.tsx new file mode 100644 index 0000000..6f7f4b9 --- /dev/null +++ b/components/parent/weekly-activity-chart.tsx @@ -0,0 +1,52 @@ +"use client" + +import { + BarChart, + Bar, + XAxis, + YAxis, + Tooltip, + ResponsiveContainer, + CartesianGrid, +} from "recharts" + +interface WeeklyData { + date: string + minutes: number +} + +export function WeeklyActivityChart({ data }: { data: WeeklyData[] }) { + if (!data || data.length === 0) { + return ( +
+ No hay actividad esta semana +
+ ) + } + + const daysOfWeek = ["dom", "lun", "mar", "mié", "jue", "vie", "sáb"] + const chartData = data.map((d) => { + const day = new Date(d.date).getDay() + return { + name: daysOfWeek[day], + minutos: d.minutes, + } + }) + + return ( +
+ + + + + + [`${value} min`, "Actividad"]} + /> + + + +
+ ) +} diff --git a/components/ui/avatar.tsx b/components/ui/avatar.tsx new file mode 100644 index 0000000..51e507b --- /dev/null +++ b/components/ui/avatar.tsx @@ -0,0 +1,50 @@ +"use client" + +import * as React from "react" +import * as AvatarPrimitive from "@radix-ui/react-avatar" + +import { cn } from "@/lib/utils" + +const Avatar = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +Avatar.displayName = AvatarPrimitive.Root.displayName + +const AvatarImage = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AvatarImage.displayName = AvatarPrimitive.Image.displayName + +const AvatarFallback = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName + +export { Avatar, AvatarImage, AvatarFallback } diff --git a/components/ui/badge.tsx b/components/ui/badge.tsx new file mode 100644 index 0000000..f000e3e --- /dev/null +++ b/components/ui/badge.tsx @@ -0,0 +1,36 @@ +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const badgeVariants = cva( + "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", + { + variants: { + variant: { + default: + "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", + secondary: + "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", + destructive: + "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", + outline: "text-foreground", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +export interface BadgeProps + extends React.HTMLAttributes, + VariantProps {} + +function Badge({ className, variant, ...props }: BadgeProps) { + return ( +
+ ) +} + +export { Badge, badgeVariants } diff --git a/components/ui/button.tsx b/components/ui/button.tsx new file mode 100644 index 0000000..36496a2 --- /dev/null +++ b/components/ui/button.tsx @@ -0,0 +1,56 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const buttonVariants = cva( + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground hover:bg-primary/90", + destructive: + "bg-destructive text-destructive-foreground hover:bg-destructive/90", + outline: + "border border-input bg-background hover:bg-accent hover:text-accent-foreground", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: "hover:bg-accent hover:text-accent-foreground", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-10 px-4 py-2", + sm: "h-9 rounded-md px-3", + lg: "h-11 rounded-md px-8", + icon: "h-10 w-10", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +) + +export interface ButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean +} + +const Button = React.forwardRef( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : "button" + return ( + + ) + } +) +Button.displayName = "Button" + +export { Button, buttonVariants } diff --git a/components/ui/card.tsx b/components/ui/card.tsx new file mode 100644 index 0000000..f62edea --- /dev/null +++ b/components/ui/card.tsx @@ -0,0 +1,79 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +const Card = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +Card.displayName = "Card" + +const CardHeader = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardHeader.displayName = "CardHeader" + +const CardTitle = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardTitle.displayName = "CardTitle" + +const CardDescription = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardDescription.displayName = "CardDescription" + +const CardContent = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardContent.displayName = "CardContent" + +const CardFooter = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardFooter.displayName = "CardFooter" + +export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } diff --git a/components/ui/input.tsx b/components/ui/input.tsx new file mode 100644 index 0000000..68551b9 --- /dev/null +++ b/components/ui/input.tsx @@ -0,0 +1,22 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +const Input = React.forwardRef>( + ({ className, type, ...props }, ref) => { + return ( + + ) + } +) +Input.displayName = "Input" + +export { Input } diff --git a/components/ui/label.tsx b/components/ui/label.tsx new file mode 100644 index 0000000..5341821 --- /dev/null +++ b/components/ui/label.tsx @@ -0,0 +1,26 @@ +"use client" + +import * as React from "react" +import * as LabelPrimitive from "@radix-ui/react-label" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const labelVariants = cva( + "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" +) + +const Label = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps +>(({ className, ...props }, ref) => ( + +)) +Label.displayName = LabelPrimitive.Root.displayName + +export { Label } diff --git a/components/ui/progress.tsx b/components/ui/progress.tsx new file mode 100644 index 0000000..5c87ea4 --- /dev/null +++ b/components/ui/progress.tsx @@ -0,0 +1,28 @@ +"use client" + +import * as React from "react" +import * as ProgressPrimitive from "@radix-ui/react-progress" + +import { cn } from "@/lib/utils" + +const Progress = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, value, ...props }, ref) => ( + + + +)) +Progress.displayName = ProgressPrimitive.Root.displayName + +export { Progress } diff --git a/components/ui/skeleton.tsx b/components/ui/skeleton.tsx new file mode 100644 index 0000000..01b8b6d --- /dev/null +++ b/components/ui/skeleton.tsx @@ -0,0 +1,15 @@ +import { cn } from "@/lib/utils" + +function Skeleton({ + className, + ...props +}: React.HTMLAttributes) { + return ( +
+ ) +} + +export { Skeleton } diff --git a/components/ui/tabs.tsx b/components/ui/tabs.tsx new file mode 100644 index 0000000..26eb109 --- /dev/null +++ b/components/ui/tabs.tsx @@ -0,0 +1,55 @@ +"use client" + +import * as React from "react" +import * as TabsPrimitive from "@radix-ui/react-tabs" + +import { cn } from "@/lib/utils" + +const Tabs = TabsPrimitive.Root + +const TabsList = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +TabsList.displayName = TabsPrimitive.List.displayName + +const TabsTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +TabsTrigger.displayName = TabsPrimitive.Trigger.displayName + +const TabsContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +TabsContent.displayName = TabsPrimitive.Content.displayName + +export { Tabs, TabsList, TabsTrigger, TabsContent } diff --git a/curriculum/index.ts b/curriculum/index.ts new file mode 100644 index 0000000..154fd34 --- /dev/null +++ b/curriculum/index.ts @@ -0,0 +1,46 @@ +import type { Exercise, Stage, TopicCurriculum } from "./types" + +const lecturaModules: Record = {} +const numerosModules: Record = {} + +async function loadStages( + topic: string, + modules: Record, + stageFiles: number[], +) { + for (const s of stageFiles) { + try { + const mod = await import(`./${topic}/etapa-${s}`) + modules[s] = mod.default + } catch { + // stage not yet implemented + } + } +} + +let lecturaLoaded = false +let numerosLoaded = false + +export function getAllLecturaExercises(): Exercise[] { + const stages = Object.values(getLecturaStages()) + return stages.flatMap((s) => s.exercises || []) +} + +export function getLecturaStages(): Record { + return lecturaModules as Record +} + +export function getNumerosStages(): Record { + return numerosModules as Record +} + +export async function initCurriculum() { + if (!lecturaLoaded) { + await loadStages("lectura", lecturaModules, [1, 2, 3, 4, 5, 6, 7, 8, 9]) + lecturaLoaded = true + } + if (!numerosLoaded) { + await loadStages("numeros", numerosModules, [1, 2, 3, 4, 5, 6, 7, 8]) + numerosLoaded = true + } +} diff --git a/curriculum/lectura/etapa-1.ts b/curriculum/lectura/etapa-1.ts new file mode 100644 index 0000000..a7bbf11 --- /dev/null +++ b/curriculum/lectura/etapa-1.ts @@ -0,0 +1,218 @@ +import type { Stage } from '../types' + +const stage: Stage = { + id: 1, + name: 'Sensibilización al lenguaje escrito', + description: 'Explorar sonidos del entorno, onomatopeyas, ritmo y conciencia de que el lenguaje se puede representar.', + exercises: [ + // --- Sonidos del entorno --- + { + id: 'lec1-sonido-perro', + stage: 1, + skillCode: 'sensibilizacion-sonidos', + type: 'sensibilizacion', + prerequisites: [], + content: { + instruction: 'Escuchá este sonido. ¿Qué animal hace así?', + audioText: '¡El perro hace guau guau!', + options: [ + { label: '🐱 Gato', correct: false }, + { label: '🐕 Perro', correct: true }, + { label: '🐄 Vaca', correct: false }, + ], + emoji: '🐕', + }, + functionalContext: 'Identificar sonidos cotidianos del entorno.', + }, + { + id: 'lec1-sonido-gato', + stage: 1, + skillCode: 'sensibilizacion-sonidos', + type: 'sensibilizacion', + prerequisites: [], + content: { + instruction: '¿Quién hace miau?', + audioText: 'El gato hace miau miau', + options: [ + { label: '🐕 Perro', correct: false }, + { label: '🐄 Vaca', correct: false }, + { label: '🐱 Gato', correct: true }, + ], + emoji: '🐱', + }, + functionalContext: 'Asociar sonidos con animales.', + }, + { + id: 'lec1-sonido-vaca', + stage: 1, + skillCode: 'sensibilizacion-sonidos', + type: 'sensibilizacion', + prerequisites: [], + content: { + instruction: '¿Cuál hace muuuu?', + audioText: 'La vaca hace muuu', + options: [ + { label: '🐄 Vaca', correct: true }, + { label: '🐔 Gallina', correct: false }, + { label: '🐑 Oveja', correct: false }, + ], + emoji: '🐄', + }, + functionalContext: 'Reconocer sonidos de animales.', + }, + { + id: 'lec1-sonido-auto', + stage: 1, + skillCode: 'sensibilizacion-sonidos', + type: 'sensibilizacion', + prerequisites: [], + content: { + instruction: '¿Qué hace run run?', + audioText: 'El auto hace run run', + options: [ + { label: '🚲 Bici', correct: false }, + { label: '🚗 Auto', correct: true }, + { label: '✈️ Avión', correct: false }, + ], + emoji: '🚗', + }, + functionalContext: 'Identificar sonidos de transporte.', + }, + { + id: 'lec1-sonido-lluvia', + stage: 1, + skillCode: 'sensibilizacion-sonidos', + type: 'sensibilizacion', + prerequisites: [], + content: { + instruction: '¿Qué hace pío pío?', + audioText: 'El pajarito hace pío pío', + options: [ + { label: '🐟 Pez', correct: false }, + { label: '🐔 Gallina', correct: false }, + { label: '🐤 Pájaro', correct: true }, + ], + emoji: '🐤', + }, + functionalContext: 'Asociar onomatopeyas con animales.', + }, + // --- Sonidos de la naturaleza --- + { + id: 'lec1-sonido-abeja', + stage: 1, + skillCode: 'sensibilizacion-sonidos', + type: 'sensibilizacion', + prerequisites: [], + content: { + instruction: '¿Quién hace zzzzz?', + audioText: 'La abeja hace zzzz', + options: [ + { label: '🐝 Abeja', correct: true }, + { label: '🦋 Mariposa', correct: false }, + { label: '🐞 Mariquita', correct: false }, + ], + emoji: '🐝', + }, + functionalContext: 'Discriminar sonidos de insectos.', + }, + { + id: 'lec1-sonido-agua', + stage: 1, + skillCode: 'sensibilizacion-sonidos', + type: 'sensibilizacion', + prerequisites: [], + content: { + instruction: '¿Qué suena así: glu glu glu?', + audioText: 'El agua hace glu glu', + options: [ + { label: '💧 Agua', correct: true }, + { label: '🔥 Fuego', correct: false }, + { label: '💨 Viento', correct: false }, + ], + emoji: '💧', + }, + functionalContext: 'Reconocer sonidos del agua.', + }, + // --- Ritmo y rimas --- + { + id: 'lec1-ritmo-palmas', + stage: 1, + skillCode: 'sensibilizacion-ritmo', + type: 'sensibilizacion', + prerequisites: [], + content: { + instruction: '¡Vamos a aplaudir! ¿Podés seguir el ritmo? DA-da-da, DA-da-da', + audioText: 'Vamos a aplaudir juntos', + emoji: '👏', + }, + functionalContext: 'Desarrollar conciencia rítmica.', + }, + { + id: 'lec1-cancion-infantil', + stage: 1, + skillCode: 'sensibilizacion-ritmo', + type: 'sensibilizacion', + prerequisites: [], + content: { + instruction: 'Cantemos juntos: "Estrellita, ¿dónde estás?"', + audioText: 'Estrellita, ¿dónde estás? Me pregunto quién serás', + emoji: '⭐', + }, + functionalContext: 'Explorar ritmo y melodía del lenguaje.', + }, + { + id: 'lec1-silencio-ruido', + stage: 1, + skillCode: 'sensibilizacion-discriminacion', + type: 'sensibilizacion', + prerequisites: [], + content: { + instruction: 'A veces hay silencio, a veces hay ruido. ¿Cuándo escuchamos silencio?', + audioText: 'El silencio es cuando no hay sonido', + options: [ + { label: '🔊 Música fuerte', correct: false }, + { label: '🤫 Todos callados', correct: true }, + { label: '📢 Gritos', correct: false }, + ], + emoji: '🤫', + }, + functionalContext: 'Discriminar presencia y ausencia de sonido.', + }, + { + id: 'lec1-eco', + stage: 1, + skillCode: 'sensibilizacion-eco', + type: 'sensibilizacion', + prerequisites: [], + content: { + instruction: 'Vamos a hacer eco. Decí después de mí: PA... PA... PA', + audioText: 'PA... PA... PA... repetí después de mí', + options: [ + { label: '¡Lo hice!', correct: true }, + ], + emoji: '🔊', + }, + functionalContext: 'Tomar conciencia de la propia producción de sonidos.', + }, + { + id: 'lec1-onomatopeya-coco', + stage: 1, + skillCode: 'sensibilizacion-onomatopeya', + type: 'sensibilizacion', + prerequisites: [], + content: { + instruction: 'El reloj hace: tic-tac, tic-tac. ¿Cuál es el reloj?', + audioText: 'El reloj hace tic tac', + options: [ + { label: '🕐 Reloj', correct: true }, + { label: '📞 Teléfono', correct: false }, + { label: '🚪 Puerta', correct: false }, + ], + emoji: '🕐', + }, + functionalContext: 'Asociar objetos a sus sonidos.', + }, + ], +} + +export default stage diff --git a/curriculum/lectura/etapa-2.ts b/curriculum/lectura/etapa-2.ts new file mode 100644 index 0000000..6f704a4 --- /dev/null +++ b/curriculum/lectura/etapa-2.ts @@ -0,0 +1,345 @@ +import type { Stage } from '../types' + +const stage: Stage = { + id: 2, + name: 'Conciencia fonológica', + description: 'Rimas, conteo de sílabas, identificar sonidos iniciales y segmentación de palabras.', + exercises: [ + // --- Rimas --- + { + id: 'lec2-rima-sol', + stage: 2, + skillCode: 'conciencia-rimas', + type: 'conciencia', + prerequisites: ['lec1-sonido-perro', 'lec1-ritmo-palmas'], + content: { + instruction: '¿Cuál palabra rima con SOL?', + text: 'SOL', + audioText: 'Sol rima con...', + options: [ + { label: 'SOL', correct: false }, + { label: 'CARACOL', correct: true }, + { label: 'LUNA', correct: false }, + ], + emoji: '☀️', + }, + functionalContext: 'Identificar palabras que terminan igual.', + errorType: 'discriminacion-auditiva', + }, + { + id: 'lec2-rima-pan', + stage: 2, + skillCode: 'conciencia-rimas', + type: 'conciencia', + prerequisites: ['lec1-sonido-perro'], + content: { + instruction: '¿Qué rima con PAN?', + text: 'PAN', + audioText: 'Pan rima con...', + options: [ + { label: 'MANO', correct: false }, + { label: 'PAN', correct: false }, + { label: 'CHAPAN', correct: true }, + ], + emoji: '🍞', + }, + functionalContext: 'Reconocer terminaciones comunes.', + errorType: 'discriminacion-auditiva', + }, + { + id: 'lec2-rima-flor', + stage: 2, + skillCode: 'conciencia-rimas', + type: 'conciencia', + prerequisites: ['lec1-sonido-perro'], + content: { + instruction: 'Buscá la palabra que rima con FLOR', + text: 'FLOR', + audioText: 'Flor rima con...', + options: [ + { label: 'COLOR', correct: true }, + { label: 'HOJA', correct: false }, + { label: 'FLOR', correct: false }, + ], + emoji: '🌸', + }, + functionalContext: 'Identificar rimas en palabras conocidas.', + errorType: 'discriminacion-auditiva', + }, + { + id: 'lec2-rima-miel', + stage: 2, + skillCode: 'conciencia-rimas', + type: 'conciencia', + prerequisites: ['lec1-sonido-abeja'], + content: { + instruction: '¿Cuál rima con MIEL?', + text: 'MIEL', + audioText: 'Miel rima con...', + options: [ + { label: 'MIEL', correct: false }, + { label: 'PAN', correct: false }, + { label: 'PINCEL', correct: true }, + ], + emoji: '🍯', + }, + functionalContext: 'Reconocer patrones sonoros finales.', + errorType: 'discriminacion-auditiva', + }, + // --- Conteo de sílabas --- + { + id: 'lec2-silabas-2', + stage: 2, + skillCode: 'conciencia-silabas', + type: 'conciencia', + prerequisites: ['lec1-eco'], + content: { + instruction: 'Vamos a contar: ¿cuántas palmadas tiene MANO? (MA-NO)', + text: 'MANO', + audioText: 'MA-NO, dos palmadas', + options: [ + { label: '👏 Una', correct: false }, + { label: '👏👏 Dos', correct: true }, + { label: '👏👏👏 Tres', correct: false }, + ], + emoji: '✋', + }, + functionalContext: 'Desarrollar conciencia de segmentación silábica.', + errorType: 'discriminacion-auditiva', + }, + { + id: 'lec2-silabas-3', + stage: 2, + skillCode: 'conciencia-silabas', + type: 'conciencia', + prerequisites: ['lec2-silabas-2'], + content: { + instruction: '¿Cuántas partes tiene VENTANA? (VEN-TA-NA)', + text: 'VENTANA', + audioText: 'VEN-TA-NA, tres partes', + options: [ + { label: '👏 Dos', correct: false }, + { label: '👏👏👏 Tres', correct: true }, + { label: '👏👏👏👏 Cuatro', correct: false }, + ], + emoji: '🪟', + }, + functionalContext: 'Segmentar palabras en sílabas.', + errorType: 'discriminacion-auditiva', + }, + { + id: 'lec2-silabas-1', + stage: 2, + skillCode: 'conciencia-silabas', + type: 'conciencia', + prerequisites: ['lec2-silabas-2'], + content: { + instruction: '¿Cuántas palmadas para SOL? (SOL)', + text: 'SOL', + audioText: 'SOL, una sola palmada', + options: [ + { label: '👏 Una', correct: true }, + { label: '👏👏 Dos', correct: false }, + { label: '👏👏👏 Tres', correct: false }, + ], + emoji: '☀️', + }, + functionalContext: 'Reconocer palabras monosílabas.', + errorType: 'discriminacion-auditiva', + }, + { + id: 'lec2-silabas-4', + stage: 2, + skillCode: 'conciencia-silabas', + type: 'conciencia', + prerequisites: ['lec2-silabas-3'], + content: { + instruction: '¿Cuántas palmadas para MARIPOSA? (MA-RI-PO-SA)', + text: 'MARIPOSA', + audioText: 'MA-RI-PO-SA, cuatro partes', + options: [ + { label: '👏 Dos', correct: false }, + { label: '👏👏👏 Tres', correct: false }, + { label: '👏👏👏👏 Cuatro', correct: true }, + ], + emoji: '🦋', + }, + functionalContext: 'Segmentar palabras de 4 sílabas.', + errorType: 'discriminacion-auditiva', + }, + // --- Sílaba inicial --- + { + id: 'lec2-inicial-ma', + stage: 2, + skillCode: 'conciencia-inicial', + type: 'conciencia', + prerequisites: ['lec2-silabas-2'], + content: { + instruction: '¿Cuál empieza como MAMÁ? (MA-MÁ, MA-NO)', + text: 'MAMÁ → MA...', + audioText: 'Mamá empieza con MA', + options: [ + { label: 'MANO', correct: true }, + { label: 'PATO', correct: false }, + { label: 'SAPO', correct: false }, + ], + emoji: '👩', + }, + functionalContext: 'Identificar el sonido inicial de las palabras.', + errorType: 'discriminacion-auditiva', + }, + { + id: 'lec2-inicial-pa', + stage: 2, + skillCode: 'conciencia-inicial', + type: 'conciencia', + prerequisites: ['lec2-inicial-ma'], + content: { + instruction: '¿Cuál empieza como PAPÁ? (PA-PÁ, PA-TO)', + text: 'PAPÁ → PA...', + audioText: 'Papá empieza con PA', + options: [ + { label: 'PERRO', correct: false }, + { label: 'PATO', correct: true }, + { label: 'CASA', correct: false }, + ], + emoji: '👨', + }, + functionalContext: 'Generalizar identificación de sílaba inicial.', + errorType: 'discriminacion-auditiva', + }, + { + id: 'lec2-inicial-ta', + stage: 2, + skillCode: 'conciencia-inicial', + type: 'conciencia', + prerequisites: ['lec2-inicial-pa'], + content: { + instruction: 'Buscá la que empieza como TAZA (TA-ZA, TA-BLA)', + text: 'TAZA → TA...', + audioText: 'Taza empieza con TA', + options: [ + { label: 'MESA', correct: false }, + { label: 'TAMBOR', correct: true }, + { label: 'LÁPIZ', correct: false }, + ], + emoji: '☕', + }, + functionalContext: 'Reconocer sílaba TA al inicio.', + errorType: 'discriminacion-auditiva', + }, + { + id: 'lec2-inicial-sa', + stage: 2, + skillCode: 'conciencia-inicial', + type: 'conciencia', + prerequisites: ['lec2-inicial-ta'], + content: { + instruction: '¿Cuál empieza como SAPO? (SA-PO, SA-LTA)', + text: 'SAPO → SA...', + audioText: 'Sapo empieza con SA', + options: [ + { label: 'SAPO', correct: false }, + { label: 'SALTA', correct: true }, + { label: 'RANA', correct: false }, + ], + emoji: '🐸', + }, + functionalContext: 'Identificar sonido SA al inicio.', + errorType: 'discriminacion-auditiva', + }, + // --- Segmentación --- + { + id: 'lec2-segmentar-casa', + stage: 2, + skillCode: 'conciencia-segmentacion', + type: 'conciencia', + prerequisites: ['lec2-silabas-2', 'lec2-inicial-ma'], + content: { + instruction: 'Separala en partes: CA-SA. ¿Cuál tiene dos partes?', + text: 'CA-SA', + audioText: 'CA-SA', + options: [ + { label: 'SOL', correct: false }, + { label: 'CASA', correct: true }, + { label: 'MARIPOSA', correct: false }, + ], + emoji: '🏠', + }, + functionalContext: 'Segmentar palabras en sílabas.', + errorType: 'omision-letra', + }, + { + id: 'lec2-segmentar-mesa', + stage: 2, + skillCode: 'conciencia-segmentacion', + type: 'conciencia', + prerequisites: ['lec2-segmentar-casa'], + content: { + instruction: 'ME-SA. ¿Cuál es?', + text: 'ME-SA', + audioText: 'ME-SA', + options: [ + { label: 'MESA', correct: true }, + { label: 'MELÓN', correct: false }, + { label: 'SAPO', correct: false }, + ], + emoji: '🪑', + }, + functionalContext: 'Unir segmentos para formar palabras.', + errorType: 'omision-letra', + }, + { + id: 'lec2-segmentar-pato', + stage: 2, + skillCode: 'conciencia-segmentacion', + type: 'conciencia', + prerequisites: ['lec2-segmentar-mesa'], + content: { + instruction: 'PA-TO. ¿Qué palabra formamos?', + text: 'PA-TO', + audioText: 'PA-TO', + options: [ + { label: 'PATO', correct: true }, + { label: 'PERRO', correct: false }, + { label: 'GATO', correct: false }, + ], + emoji: '🦆', + }, + functionalContext: 'Sintetizar sílabas para formar palabras.', + errorType: 'omision-letra', + }, + { + id: 'lec2-ordenar-silabas', + stage: 2, + skillCode: 'conciencia-orden', + type: 'secuencia', + prerequisites: ['lec2-segmentar-pato'], + content: { + instruction: 'Ordená las sílabas para formar una palabra', + audioText: 'Ordená las sílabas', + sequence: ['TO', 'PA'], + emoji: '🧩', + }, + functionalContext: 'Desarrollar habilidad de ordenamiento fonológico.', + errorType: 'inversion-letra', + }, + { + id: 'lec2-ordenar-silabas-2', + stage: 2, + skillCode: 'conciencia-orden', + type: 'secuencia', + prerequisites: ['lec2-ordenar-silabas'], + content: { + instruction: 'Armá la palabra', + audioText: 'Ordená estas sílabas', + sequence: ['SA', 'CA'], + emoji: '🧩', + }, + functionalContext: 'Ordenar sílabas para formar palabras.', + errorType: 'inversion-letra', + }, + ], +} + +export default stage diff --git a/curriculum/lectura/etapa-3.ts b/curriculum/lectura/etapa-3.ts new file mode 100644 index 0000000..4bb65bb --- /dev/null +++ b/curriculum/lectura/etapa-3.ts @@ -0,0 +1,269 @@ +import type { Stage } from '../types' + +function vocalChoice(vocal: string, correctLabel: string, distractors: string[], emoji: string, instruction: string, audioText?: string) { + const options = [ + { label: correctLabel, correct: true, id: vocal }, + ...distractors.map((d) => ({ label: d, correct: false, id: d })), + ].sort(() => Math.random() - 0.5) + + return { + stage: 3, + skillCode: `vocal-${vocal}`, + type: 'eleccion' as const, + prerequisites: getVocalPrereqs(vocal), + content: { + instruction, + text: correctLabel, + options, + audioText: audioText || `${correctLabel}`, + emoji, + color: getVocalColor(vocal), + }, + functionalContext: `Identificar la vocal ${vocal.toUpperCase()} en diferentes contextos.`, + errorType: 'confusion-letra' as const, + } +} + +function getVocalColor(vocal: string): string { + const colors: Record = { a: '#FF6B6B', o: '#4ECDC4', i: '#45B7D1', e: '#96CEB4', u: '#DDA0DD' } + return colors[vocal] || '#FF6B6B' +} + +function getVocalPrereqs(vocal: string): string[] { + const order = ['a', 'o', 'i', 'e', 'u'] + const idx = order.indexOf(vocal) + if (idx === 0) return ['lec2-segmentar-pato'] + return [`vocal-${order[idx - 1]}-completa`] +} + +const gestos: Record = { + a: { gesto: 'Abrí la mano como una boca grande', palabra: 'ÁRBOL', fonema: 'AAA', emoji: '🌳' }, + o: { gesto: 'Redondeá la mano como una O', palabra: 'OJO', fonema: 'OOO', emoji: '👁️' }, + i: { gesto: 'Señalá el cielo con el dedo', palabra: 'INDIO', fonema: 'III', emoji: '🪶' }, + e: { gesto: 'Estirá la mano como una trompa de elefante', palabra: 'ELEFANTE', fonema: 'EEE', emoji: '🐘' }, + u: { gesto: 'Señalá el suelo con la mano', palabra: 'UNO', fonema: 'UUU', emoji: '1️⃣' }, +} + +function buildVocalExercises(vocal: string, index: number): any[] { + const g = gestos[vocal] + const exs: any[] = [] + + // Ejercicio de gesto (sensibilizacion) + exs.push({ + id: `lec3-${vocal}-gesto`, + stage: 3, + skillCode: `vocal-${vocal}`, + type: 'sensibilizacion', + prerequisites: getVocalPrereqs(vocal), + content: { + instruction: `Hacé así para la ${vocal.toUpperCase()}: ${g.gesto}`, + audioText: `Esta es la letra ${vocal.toUpperCase()}. ${g.palabra}. ${g.fonema}`, + emoji: g.emoji, + color: getVocalColor(vocal), + }, + functionalContext: `Aprender el gesto Borel-Maisonny para la vocal ${vocal.toUpperCase()}.`, + }) + + // Reconocer la vocal entre otras + exs.push(vocalChoice( + vocal, vocal.toUpperCase(), + ['A', 'O', 'I', 'E', 'U'].filter((v) => v !== vocal.toUpperCase()), + g.emoji, + `Señalá la letra ${vocal.toUpperCase()}`, + )) + + // ¿Con qué vocal empieza? + exs.push({ + id: `lec3-${vocal}-inicial`, + stage: 3, + skillCode: `vocal-${vocal}`, + type: 'eleccion', + prerequisites: [`lec3-${vocal}-gesto`], + content: { + instruction: `¿Con qué vocal empieza ${g.palabra}?`, + text: g.palabra, + audioText: `${g.palabra} empieza con ${vocal.toUpperCase()}`, + options: [ + { label: vocal.toUpperCase(), correct: true, id: vocal }, + ...['A', 'O', 'I', 'E', 'U'].filter((v) => v !== vocal.toUpperCase()).slice(0, 2).map((v) => ({ label: v, correct: false, id: v })), + ], + emoji: g.emoji, + }, + functionalContext: `Reconocer la vocal inicial en palabras.`, + errorType: 'discriminacion-auditiva', + }) + + // Emparejar imagen con vocal + exs.push({ + id: `lec3-${vocal}-emparejar`, + stage: 3, + skillCode: `vocal-${vocal}`, + type: 'conciencia', + prerequisites: [`lec3-${vocal}-inicial`], + content: { + instruction: `¿Cuál empieza con ${vocal.toUpperCase()}?`, + audioText: `¿Qué empieza con ${vocal.toUpperCase()}?`, + options: [ + { label: g.emoji, correct: true, id: vocal }, + ...Object.entries(gestos) + .filter(([k]) => k !== vocal) + .slice(0, 2) + .map(([k, v]) => ({ label: v.emoji, correct: false, id: k })), + ], + }, + functionalContext: `Asociar la vocal con imágenes que empiezan con ella.`, + errorType: 'confusion-letra', + }) + + // Discriminación auditiva + exs.push({ + id: `lec3-${vocal}-auditiva`, + stage: 3, + skillCode: `vocal-${vocal}`, + type: 'conciencia', + prerequisites: [`lec3-${vocal}-emparejar`], + content: { + instruction: `Escuchá bien. ¿Cuál suena como ${vocal.toUpperCase()}?`, + audioText: `${g.fonema}... ${g.fonema}... como ${g.palabra}`, + options: [ + { label: vocal.toUpperCase(), correct: true, id: vocal }, + ...['A', 'O', 'I', 'E', 'U'].filter((v) => v !== vocal.toUpperCase()).slice(0, 2).map((v) => ({ label: v, correct: false, id: v })), + ], + emoji: '👂', + }, + functionalContext: `Discriminar auditivamente la vocal ${vocal.toUpperCase()}.`, + errorType: 'discriminacion-auditiva', + }) + + // Escribir con el dedo (trazo) + exs.push({ + id: `lec3-${vocal}-trazo`, + stage: 3, + skillCode: `vocal-${vocal}`, + type: 'trazo', + prerequisites: [`lec3-${vocal}-auditiva`], + content: { + instruction: `Trazá la letra ${vocal.toUpperCase()} con tu dedo`, + text: vocal.toUpperCase(), + audioText: `Trazá la ${vocal.toUpperCase()}`, + color: getVocalColor(vocal), + emoji: g.emoji, + }, + functionalContext: `Desarrollar memoria motriz de la vocal ${vocal.toUpperCase()}.`, + errorType: 'confusion-letra', + }) + + // Repaso final + exs.push({ + id: `lec3-${vocal}-completa`, + stage: 3, + skillCode: `vocal-${vocal}`, + type: 'eleccion', + prerequisites: [`lec3-${vocal}-trazo`], + content: { + instruction: `¡Repaso! Señalá la letra ${vocal.toUpperCase()}`, + audioText: `Buscá la ${vocal.toUpperCase()}`, + options: [ + { label: vocal.toUpperCase(), correct: true, id: vocal }, + ...['A', 'O', 'I', 'E', 'U'].filter((v) => v !== vocal.toUpperCase()).map((v) => ({ label: v, correct: false, id: v })), + ], + emoji: g.emoji, + color: getVocalColor(vocal), + }, + functionalContext: `Consolidar reconocimiento de la vocal ${vocal.toUpperCase()}.`, + errorType: 'confusion-letra', + }) + + return exs +} + +// Additional cross-vowel discrimination exercises +const mixedExercises: any[] = [ + { + id: 'lec3-mix-ae', + stage: 3, + skillCode: 'vocal-discriminacion', + type: 'eleccion', + prerequisites: ['lec3-a-completa', 'lec3-e-completa'], + content: { + instruction: '¿Cuál es la A y cuál es la E? Señalá la A', + options: [ + { label: 'A', correct: true, id: 'a' }, + { label: 'E', correct: false, id: 'e' }, + { label: 'O', correct: false, id: 'o' }, + ], + emoji: '🔤', + }, + functionalContext: 'Discriminar entre A y E.', + errorType: 'confusion-letra', + }, + { + id: 'lec3-mix-iu', + stage: 3, + skillCode: 'vocal-discriminacion', + type: 'eleccion', + prerequisites: ['lec3-i-completa', 'lec3-u-completa'], + content: { + instruction: '¿Cuál es la I y cuál es la U? Señalá la I', + options: [ + { label: 'I', correct: true, id: 'i' }, + { label: 'U', correct: false, id: 'u' }, + { label: 'A', correct: false, id: 'a' }, + ], + emoji: '🔤', + }, + functionalContext: 'Discriminar entre I y U.', + errorType: 'confusion-letra', + }, + { + id: 'lec3-mix-ao', + stage: 3, + skillCode: 'vocal-discriminacion', + type: 'eleccion', + prerequisites: ['lec3-a-completa', 'lec3-o-completa'], + content: { + instruction: 'Señalá la letra O', + options: [ + { label: 'A', correct: false, id: 'a' }, + { label: 'O', correct: true, id: 'o' }, + { label: 'U', correct: false, id: 'u' }, + ], + emoji: '🔤', + }, + functionalContext: 'Discriminar entre A y O.', + errorType: 'confusion-letra', + }, + { + id: 'lec3-mix-ei', + stage: 3, + skillCode: 'vocal-discriminacion', + type: 'eleccion', + prerequisites: ['lec3-e-completa', 'lec3-i-completa'], + content: { + instruction: 'Señalá la E', + options: [ + { label: 'I', correct: false, id: 'i' }, + { label: 'E', correct: true, id: 'e' }, + { label: 'U', correct: false, id: 'u' }, + ], + emoji: '🔤', + }, + functionalContext: 'Discriminar entre E e I.', + errorType: 'confusion-letra', + }, +] + +const exercises: any[] = [] +for (const [i, vocal] of ['a', 'o', 'i', 'e', 'u'].entries()) { + exercises.push(...buildVocalExercises(vocal, i)) +} +exercises.push(...mixedExercises) + +const stage: Stage = { + id: 3, + name: 'Vocales A-O-I-E-U', + description: 'Aprender las 5 vocales con gestos Borel-Maisonny, discriminación auditiva y visual, trazo y reconocimiento.', + exercises, +} + +export default stage diff --git a/curriculum/lectura/etapa-4.ts b/curriculum/lectura/etapa-4.ts new file mode 100644 index 0000000..f6a676a --- /dev/null +++ b/curriculum/lectura/etapa-4.ts @@ -0,0 +1,235 @@ +import type { Stage } from '../types' + +type ConInfo = { + letra: string + palabra: string + emoji: string + silabas: string[] + gesto: string +} + +const consonantes: ConInfo[] = [ + { letra: 'M', palabra: 'MAMÁ', emoji: '👩', silabas: ['MA', 'ME', 'MI', 'MO', 'MU'], gesto: 'Manos en la boca como mmm' }, + { letra: 'P', palabra: 'PAPÁ', emoji: '👨', silabas: ['PA', 'PE', 'PI', 'PO', 'PU'], gesto: 'Manos que abren y cierran como pompa' }, + { letra: 'L', palabra: 'LUNA', emoji: '🌙', silabas: ['LA', 'LE', 'LI', 'LO', 'LU'], gesto: 'Lengua arriba como lámpara' }, + { letra: 'S', palabra: 'SOL', emoji: '☀️', silabas: ['SA', 'SE', 'SI', 'SO', 'SU'], gesto: 'Dedos como serpiente sss' }, + { letra: 'T', palabra: 'TASA', emoji: '☕', silabas: ['TA', 'TE', 'TI', 'TO', 'TU'], gesto: 'Golpecito con la mano' }, + { letra: 'N', palabra: 'NIDO', emoji: '🪺', silabas: ['NA', 'NE', 'NI', 'NO', 'NU'], gesto: 'Nariz como nido' }, + { letra: 'D', palabra: 'DEDO', emoji: '👉', silabas: ['DA', 'DE', 'DI', 'DO', 'DU'], gesto: 'Dedo señalando' }, + { letra: 'R', palabra: 'RATÓN', emoji: '🐭', silabas: ['RA', 'RE', 'RI', 'RO', 'RU'], gesto: 'Lengua que vibra como rrr' }, +] + +const exercises: any[] = [] + +for (const con of consonantes) { + // 1. Presentación con gesto + exercises.push({ + id: `lec4-${con.letra.toLowerCase()}-gesto`, + stage: 4, + skillCode: `consonante-${con.letra.toLowerCase()}`, + type: 'sensibilizacion', + prerequisites: con.letra === 'M' ? ['lec3-u-completa'] : [`lec4-${consonantes[consonantes.indexOf(con) - 1].letra.toLowerCase()}-completa`], + content: { + instruction: `Hacé así para la ${con.letra}: ${con.gesto}`, + audioText: `Esta es la letra ${con.letra}. ${con.palabra}. ${con.silabas[0].toLowerCase()}`, + emoji: con.emoji, + }, + functionalContext: `Conocer el gesto asociado a la consonante ${con.letra}.`, + }) + + // 2. Reconocer la consonante + exercises.push({ + id: `lec4-${con.letra.toLowerCase()}-reconocer`, + stage: 4, + skillCode: `consonante-${con.letra.toLowerCase()}`, + type: 'eleccion', + prerequisites: [`lec4-${con.letra.toLowerCase()}-gesto`], + content: { + instruction: `Señalá la letra ${con.letra}`, + text: `Buscá la ${con.letra}`, + audioText: `¿Dónde está la ${con.letra}?`, + options: [ + { label: con.letra, correct: true, id: con.letra.toLowerCase() }, + ...consonantes.filter(c => c.letra !== con.letra).slice(0, 3).map(c => ({ label: c.letra, correct: false, id: c.letra.toLowerCase() })), + ], + emoji: con.emoji, + }, + functionalContext: `Reconocer visualmente la consonante ${con.letra}.`, + errorType: 'confusion-letra', + }) + + // 3. Discriminación auditiva de la sílaba + exercises.push({ + id: `lec4-${con.letra.toLowerCase()}-auditiva`, + stage: 4, + skillCode: `consonante-${con.letra.toLowerCase()}`, + type: 'conciencia', + prerequisites: [`lec4-${con.letra.toLowerCase()}-reconocer`], + content: { + instruction: `Escuchá. ¿Cuál suena como ${con.silabas[0]}?`, + audioText: `${con.silabas[0]}... ${con.silabas[0]}... como ${con.palabra}`, + options: [ + { label: con.silabas[0], correct: true, id: con.silabas[0].toLowerCase() }, + ...consonantes.filter(c => c.letra !== con.letra).slice(0, 2).map(c => ({ label: c.silabas[0], correct: false, id: c.silabas[0].toLowerCase() })), + ], + emoji: '👂', + }, + functionalContext: `Discriminar auditivamente la sílaba ${con.silabas[0]}.`, + errorType: 'discriminacion-auditiva', + }) + + // 4. Emparejar sílaba con vocal + for (let vi = 1; vi < con.silabas.length; vi++) { + const sil = con.silabas[vi] + const vocal = sil[1] + const vocales = ['A', 'E', 'I', 'O', 'U'].filter(v => v !== vocal) + exercises.push({ + id: `lec4-${con.letra.toLowerCase()}-silaba-${sil.toLowerCase()}`, + stage: 4, + skillCode: `consonante-${con.letra.toLowerCase()}-silabas`, + type: 'eleccion', + prerequisites: [`lec4-${con.letra.toLowerCase()}-auditiva`, `lec4-${con.letra.toLowerCase()}-silaba-${con.silabas[vi - 1].toLowerCase()}`], + content: { + instruction: `¿Cuál es ${sil}?`, + text: sil, + audioText: `${sil}... como ${con.palabra.toLowerCase()}`, + options: [ + { label: sil, correct: true, id: sil.toLowerCase() }, + { label: `${con.letra}${vocales[0]}`, correct: false, id: `${con.letra}${vocales[0]}`.toLowerCase() }, + { label: `${con.letra}${vocales[1]}`, correct: false, id: `${con.letra}${vocales[1]}`.toLowerCase() }, + ], + emoji: con.emoji, + }, + functionalContext: `Leer la sílaba ${sil}.`, + errorType: 'confusion-letra', + }) + } + + // 5. Palabra con la consonante + exercises.push({ + id: `lec4-${con.letra.toLowerCase()}-palabra`, + stage: 4, + skillCode: `consonante-${con.letra.toLowerCase()}`, + type: 'palabra', + prerequisites: [`lec4-${con.letra.toLowerCase()}-silaba-${con.silabas[con.silabas.length - 1].toLowerCase()}`], + content: { + instruction: `¿Cuál palabra empieza con ${con.letra}?`, + audioText: `${con.palabra} empieza con ${con.letra}`, + imageEmoji: con.emoji, + options: [ + { label: con.palabra, correct: true, id: con.palabra.toLowerCase() }, + { label: 'CASA', correct: false, id: 'casa' }, + { label: 'GATO', correct: false, id: 'gato' }, + { label: 'Escuchar 👂', correct: false, id: 'escuchar' }, + ], + }, + functionalContext: `Asociar la consonante ${con.letra} con una palabra significativa.`, + errorType: 'discriminacion-auditiva', + }) + + // 6. Final: repaso completo + exercises.push({ + id: `lec4-${con.letra.toLowerCase()}-completa`, + stage: 4, + skillCode: `consonante-${con.letra.toLowerCase()}`, + type: 'eleccion', + prerequisites: [`lec4-${con.letra.toLowerCase()}-palabra`], + content: { + instruction: `¡Repaso! Señalá la letra ${con.letra}`, + audioText: `Buscá la ${con.letra}`, + options: [ + { label: con.letra, correct: true, id: con.letra.toLowerCase() }, + ...consonantes.filter(c => c.letra !== con.letra).slice(0, 3).map(c => ({ label: c.letra, correct: false, id: c.letra.toLowerCase() })), + ], + emoji: con.emoji, + }, + functionalContext: `Consolidar reconocimiento de la consonante ${con.letra}.`, + errorType: 'confusion-letra', + }) +} + +// Cross-consonant discrimination exercises +exercises.push({ + id: 'lec4-mix-mp', + stage: 4, + skillCode: 'consonante-discriminacion', + type: 'eleccion', + prerequisites: ['lec4-m-completa', 'lec4-p-completa'], + content: { + instruction: 'Señalá la M', + options: [ + { label: 'M', correct: true, id: 'm' }, + { label: 'P', correct: false, id: 'p' }, + { label: 'L', correct: false, id: 'l' }, + ], + emoji: '🔤', + }, + functionalContext: 'Discriminar entre M y P.', + errorType: 'confusion-letra', +}) + +exercises.push({ + id: 'lec4-mix-st', + stage: 4, + skillCode: 'consonante-discriminacion', + type: 'eleccion', + prerequisites: ['lec4-s-completa', 'lec4-t-completa'], + content: { + instruction: 'Señalá la T', + options: [ + { label: 'S', correct: false, id: 's' }, + { label: 'T', correct: true, id: 't' }, + { label: 'N', correct: false, id: 'n' }, + ], + emoji: '🔤', + }, + functionalContext: 'Discriminar entre S y T.', + errorType: 'confusion-letra', +}) + +exercises.push({ + id: 'lec4-mix-ld', + stage: 4, + skillCode: 'consonante-discriminacion', + type: 'eleccion', + prerequisites: ['lec4-l-completa', 'lec4-d-completa'], + content: { + instruction: 'Señalá la D', + options: [ + { label: 'L', correct: false, id: 'l' }, + { label: 'D', correct: true, id: 'd' }, + { label: 'R', correct: false, id: 'r' }, + ], + emoji: '🔤', + }, + functionalContext: 'Discriminar entre L y D.', + errorType: 'confusion-letra', +}) + +exercises.push({ + id: 'lec4-mix-nr', + stage: 4, + skillCode: 'consonante-discriminacion', + type: 'eleccion', + prerequisites: ['lec4-n-completa', 'lec4-r-completa'], + content: { + instruction: 'Señalá la R', + options: [ + { label: 'N', correct: false, id: 'n' }, + { label: 'R', correct: true, id: 'r' }, + { label: 'M', correct: false, id: 'm' }, + ], + emoji: '🔤', + }, + functionalContext: 'Discriminar entre N y R.', + errorType: 'confusion-letra', +}) + +const stage: Stage = { + id: 4, + name: 'Consonantes M-P-L-S-T-N-D-R', + description: 'Aprender las consonantes M, P, L, S, T, N, D, R con gestos, sílabas, y palabras significativas.', + exercises, +} + +export default stage diff --git a/curriculum/lectura/etapa-5.ts b/curriculum/lectura/etapa-5.ts new file mode 100644 index 0000000..fb7f5eb --- /dev/null +++ b/curriculum/lectura/etapa-5.ts @@ -0,0 +1,293 @@ +import type { Stage, Exercise } from '../types' + +type Info = { + letra: string + palabra: string + emoji: string + gesto: string + silaba: string + palabraLower: string +} + +const moduleA: Info[] = [ + { letra: 'A', palabra: 'ÁRBOL', emoji: '🌳', gesto: 'Abrí la mano como una boca grande', silaba: 'a', palabraLower: 'árbol' }, + { letra: 'E', palabra: 'ELEFANTE', emoji: '🐘', gesto: 'Estirá la mano como una trompa', silaba: 'e', palabraLower: 'elefante' }, + { letra: 'I', palabra: 'INDIO', emoji: '🪶', gesto: 'Señalá el cielo con el dedo', silaba: 'i', palabraLower: 'indio' }, + { letra: 'O', palabra: 'OJO', emoji: '👁️', gesto: 'Redondeá la mano como una O', silaba: 'o', palabraLower: 'ojo' }, + { letra: 'U', palabra: 'UNO', emoji: '1️⃣', gesto: 'Señalá el suelo con la mano', silaba: 'u', palabraLower: 'uno' }, +] + +const moduleB: Info[] = [ + { letra: 'M', palabra: 'MAMÁ', emoji: '👩', gesto: 'Manos en la boca como mmm', silaba: 'ma', palabraLower: 'mamá' }, + { letra: 'P', palabra: 'PAPÁ', emoji: '👨', gesto: 'Manos que abren y cierran como pompa', silaba: 'pa', palabraLower: 'papá' }, + { letra: 'L', palabra: 'LUNA', emoji: '🌙', gesto: 'Lengua arriba como lámpara', silaba: 'la', palabraLower: 'luna' }, + { letra: 'S', palabra: 'SOL', emoji: '☀️', gesto: 'Dedos como serpiente sss', silaba: 'sa', palabraLower: 'sol' }, +] + +const moduleC: Info[] = [ + { letra: 'T', palabra: 'TASA', emoji: '☕', gesto: 'Golpecito con la mano', silaba: 'ta', palabraLower: 'tasa' }, + { letra: 'N', palabra: 'NIDO', emoji: '🪺', gesto: 'Nariz como nido', silaba: 'na', palabraLower: 'nido' }, + { letra: 'D', palabra: 'DEDO', emoji: '👉', gesto: 'Dedo señalando', silaba: 'da', palabraLower: 'dedo' }, + { letra: 'R', palabra: 'RATÓN', emoji: '🐭', gesto: 'Lengua que vibra como rrr', silaba: 'ra', palabraLower: 'ratón' }, +] + +const allModules = [moduleA, moduleB, moduleC] + +function getDistractors(pool: Info[], current: Info, count: number): Info[] { + return pool.filter((x) => x.letra !== current.letra).slice(0, count) +} + +function getPoolIndex(info: Info): number { + for (let i = 0; i < allModules.length; i++) { + if (allModules[i].find((x) => x.letra === info.letra)) return i + } + return 0 +} + +function buildExercises(): Exercise[] { + const all: Exercise[] = [] + let prevId: string | null = 'lec4-r-completa' + + for (const pool of allModules) { + for (const info of pool) { + const MIN = info.letra.toLowerCase() + const dist = getDistractors(pool, info, 3) + + // 1. Descubrimiento del par + all.push({ + id: `lec5-${MIN}-descubre`, + stage: 5, + skillCode: `puente-${MIN}`, + type: 'sensibilizacion', + prerequisites: prevId ? [prevId] : [], + content: { + instruction: `${info.letra} y ${MIN} suenan igual`, + audioText: `${info.letra} grande y ${MIN} chica suenan igual: ${gestoKey(info.gesto)}`, + emoji: info.emoji, + }, + functionalContext: `Descubrir que ${info.letra} y ${MIN} son la misma letra.`, + }) + prevId = `lec5-${MIN}-descubre` + + // 2. Práctica emparejada: Tocá Mm + const pairOptions = [ + { label: `${info.letra}${MIN}`, correct: true, id: MIN }, + ...dist.map((d) => ({ + label: `${d.letra}${d.letra.toLowerCase()}`, + correct: false, + id: d.letra.toLowerCase(), + })), + ].sort(() => Math.random() - 0.5) + + all.push({ + id: `lec5-${MIN}-pareja`, + stage: 5, + skillCode: `puente-${MIN}`, + type: 'eleccion', + prerequisites: [prevId], + content: { + instruction: `Tocá la ${info.letra}${MIN}`, + audioText: `¿Dónde está ${info.letra}${MIN}?`, + options: pairOptions, + emoji: info.emoji, + }, + functionalContext: `Asociar el par ${info.letra}${MIN}.`, + errorType: 'confusion-letra', + }) + prevId = `lec5-${MIN}-pareja` + + // 3. Buscar mayúscula entre minúsculas: Tocá la M + const mayusOptions = [ + { label: info.letra, correct: true, id: MIN }, + ...dist.map((d) => ({ + label: d.letra.toLowerCase(), + correct: false, + id: `${d.letra.toLowerCase()}-may`, + })), + ].sort(() => Math.random() - 0.5) + + all.push({ + id: `lec5-${MIN}-busca-mayus`, + stage: 5, + skillCode: `puente-${MIN}`, + type: 'eleccion', + prerequisites: [prevId], + content: { + instruction: `Tocá la ${info.letra} grande`, + audioText: `¿Dónde está la ${info.letra} grande?`, + options: mayusOptions, + emoji: info.emoji, + }, + functionalContext: `Reconocer ${info.letra} mayúscula entre minúsculas.`, + errorType: 'confusion-letra', + }) + prevId = `lec5-${MIN}-busca-mayus` + + // 4. Buscar minúscula entre mayúsculas: Tocá la m (CLAVE) + const minusOptions = [ + { label: MIN, correct: true, id: MIN }, + ...dist.map((d) => ({ + label: d.letra, + correct: false, + id: `${d.letra.toLowerCase()}-min`, + })), + ].sort(() => Math.random() - 0.5) + + all.push({ + id: `lec5-${MIN}-busca-minus`, + stage: 5, + skillCode: `puente-${MIN}`, + type: 'eleccion', + prerequisites: [prevId], + content: { + instruction: `Tocá la ${MIN} chica`, + audioText: `¿Dónde está la ${MIN} chica?`, + options: minusOptions, + emoji: info.emoji, + }, + functionalContext: `Reconocer ${MIN} minúscula entre mayúsculas — discriminación clave para dislexia.`, + errorType: 'confusion-letra', + }) + prevId = `lec5-${MIN}-busca-minus` + + // 5. Pareja inversa: ¿Cuál es la pareja de M? → m + const parejaMayusOptions = [ + { label: MIN, correct: true, id: `${MIN}-pm` }, + ...dist.map((d) => ({ + label: d.letra.toLowerCase(), + correct: false, + id: `${d.letra.toLowerCase()}-pm`, + })), + ].sort(() => Math.random() - 0.5) + + all.push({ + id: `lec5-${MIN}-pareja-mayus`, + stage: 5, + skillCode: `puente-${MIN}`, + type: 'eleccion', + prerequisites: [prevId], + content: { + instruction: `¿Cuál es la pareja de ${info.letra}?`, + audioText: `Buscá la ${MIN} chica, pareja de la ${info.letra} grande`, + options: parejaMayusOptions, + emoji: info.emoji, + }, + functionalContext: `Asociar la mayúscula ${info.letra} con su minúscula ${MIN}.`, + errorType: 'confusion-letra', + }) + prevId = `lec5-${MIN}-pareja-mayus` + + // 6. Pareja inversa 2: ¿Cuál es la pareja de m? → M + const parejaMinusOptions = [ + { label: info.letra, correct: true, id: `${MIN}-pm2` }, + ...dist.map((d) => ({ + label: d.letra, + correct: false, + id: `${d.letra.toLowerCase()}-pm2`, + })), + ].sort(() => Math.random() - 0.5) + + all.push({ + id: `lec5-${MIN}-pareja-minus`, + stage: 5, + skillCode: `puente-${MIN}`, + type: 'eleccion', + prerequisites: [prevId], + content: { + instruction: `¿Cuál es la pareja de ${MIN}?`, + audioText: `Buscá la ${info.letra} grande, pareja de la ${MIN} chica`, + options: parejaMinusOptions, + emoji: info.emoji, + }, + functionalContext: `Asociar la minúscula ${MIN} con su mayúscula ${info.letra}.`, + errorType: 'confusion-letra', + }) + prevId = `lec5-${MIN}-pareja-minus` + + // 7. Sílabas en minúscula: Tocá ma + const silabaOptions = [ + { label: info.silaba, correct: true, id: `${MIN}-sil` }, + ...dist.map((d) => ({ + label: d.silaba, + correct: false, + id: `${d.letra.toLowerCase()}-sil`, + })), + ].sort(() => Math.random() - 0.5) + + all.push({ + id: `lec5-${MIN}-silaba`, + stage: 5, + skillCode: `puente-${MIN}`, + type: 'eleccion', + prerequisites: [prevId], + content: { + instruction: `Tocá ${info.silaba}`, + audioText: `¿Dónde está ${info.silaba}?`, + options: silabaOptions, + emoji: info.emoji, + }, + functionalContext: `Leer la sílaba ${info.silaba} en minúscula.`, + errorType: 'confusion-letra', + }) + prevId = `lec5-${MIN}-silaba` + + // 8. Palabra en minúscula: Tocá mamá + const palabraOptions = [ + { label: info.palabraLower, correct: true, id: `${MIN}-pal` }, + ...dist.map((d) => ({ + label: d.palabraLower, + correct: false, + id: `${d.letra.toLowerCase()}-pal`, + })), + ].sort(() => Math.random() - 0.5) + + all.push({ + id: `lec5-${MIN}-palabra`, + stage: 5, + skillCode: `puente-${MIN}`, + type: 'eleccion', + prerequisites: [prevId], + content: { + instruction: `Tocá ${info.palabraLower}`, + audioText: `¿Dónde dice ${info.palabraLower}?`, + options: palabraOptions, + emoji: info.emoji, + }, + functionalContext: `Leer la palabra ${info.palabraLower} en minúscula.`, + errorType: 'confusion-letra', + }) + prevId = `lec5-${MIN}-palabra` + } + } + + return all +} + +function gestoKey(gesto: string): string { + const map: Record = { + 'Abrí': 'a-a-a', + 'Estirá': 'e-e-e', + 'Señalá el cielo': 'i-i-i', + 'Redondeá': 'o-o-o', + 'Señalá el suelo': 'u-u-u', + 'Manos en la boca': 'mmm', + 'Manos que abren': 'p-p-p', + 'Dedos como serpiente': 'sss', + 'Lengua arriba': 'l-l-l', + 'Golpecito': 't-t-t', + 'Nariz como nido': 'n-n-n', + 'Dedo señalando': 'd-d-d', + 'Lengua que vibra': 'rrr', + } + const key = Object.keys(map).find((k) => gesto.startsWith(k)) + return key ? map[key] : gesto +} + +const stage: Stage = { + id: 5, + name: 'Puente Mayúscula-Minúscula', + description: 'Asociar letras mayúsculas con sus correspondientes minúsculas. 8 ejercicios por letra — 104 en total.', + exercises: buildExercises(), +} + +export default stage diff --git a/curriculum/lectura/etapa-6.ts b/curriculum/lectura/etapa-6.ts new file mode 100644 index 0000000..add103b --- /dev/null +++ b/curriculum/lectura/etapa-6.ts @@ -0,0 +1,119 @@ +import type { Stage } from '../types' + +const palabras2silabas = [ + { palabra: 'MAPA', silabas: ['MA', 'PA'], emoji: '🗺️' }, + { palabra: 'PASA', silabas: ['PA', 'SA'], emoji: '🔄' }, + { palabra: 'SALA', silabas: ['SA', 'LA'], emoji: '🏠' }, + { palabra: 'TAPA', silabas: ['TA', 'PA'], emoji: '📦' }, + { palabra: 'LATA', silabas: ['LA', 'TA'], emoji: '🥫' }, + { palabra: 'NIDO', silabas: ['NI', 'DO'], emoji: '🪺' }, + { palabra: 'DEDO', silabas: ['DE', 'DO'], emoji: '👉' }, + { palabra: 'RATO', silabas: ['RA', 'TO'], emoji: '⏰' }, + { palabra: 'MESA', silabas: ['ME', 'SA'], emoji: '🪑' }, + { palabra: 'PATO', silabas: ['PA', 'TO'], emoji: '🦆' }, + { palabra: 'LIMA', silabas: ['LI', 'MA'], emoji: '🍋' }, + { palabra: 'SOPA', silabas: ['SO', 'PA'], emoji: '🥣' }, + { palabra: 'TINA', silabas: ['TI', 'NA'], emoji: '🛁' }, + { palabra: 'MONO', silabas: ['MO', 'NO'], emoji: '🐵' }, + { palabra: 'PINO', silabas: ['PI', 'NO'], emoji: '🌲' }, + { palabra: 'LUNES', silabas: ['LU', 'NES'], emoji: '📅' }, + { palabra: 'SAPO', silabas: ['SA', 'PO'], emoji: '🐸' }, + { palabra: 'TELO', silabas: ['TE', 'LO'], emoji: '🧶' }, + { palabra: 'DAMA', silabas: ['DA', 'MA'], emoji: '👩' }, + { palabra: 'RAMA', silabas: ['RA', 'MA'], emoji: '🌿' }, +] + +const exercises: any[] = [] + +for (const { palabra, silabas, emoji } of palabras2silabas) { + const lowerPalabra = palabra.toLowerCase().replace(/[^a-z]/g, '') + const id = `lec6-palabra-${lowerPalabra}` + const letras = palabra.split('') + const conLetras = letras[0]?.toLowerCase() + const consonantDep = conLetras && ['m', 'p', 'l', 's', 't', 'n', 'd', 'r'].includes(conLetras) + ? `lec4-${conLetras}-completa` + : 'lec3-u-completa' + + // Leer la palabra (ver las sílabas separadas) + exercises.push({ + id: `${id}-leer`, + stage: 6, + skillCode: `silabas-${lowerPalabra}`, + type: 'eleccion', + prerequisites: [consonantDep], + content: { + instruction: `Leé esta palabra: ${silabas.join('-')}`, + text: `${silabas.join(' ')}`, + audioText: `${palabra}: ${silabas.join(', ')}`, + emoji, + options: [ + { label: palabra, correct: true, id: lowerPalabra }, + ...palabras2silabas + .filter(p => p.palabra !== palabra) + .slice(0, 2) + .map(p => ({ label: p.palabra, correct: false, id: p.palabra.toLowerCase() })), + ], + }, + functionalContext: `Leer la palabra ${palabra} combinando sílabas.`, + errorType: 'silaba-dificil', + }) + + // Emparejar con imagen + exercises.push({ + id: `${id}-imagen`, + stage: 6, + skillCode: `silabas-${lowerPalabra}`, + type: 'palabra', + prerequisites: [`${id}-leer`], + content: { + instruction: `¿Cuál palabra es esta?`, + imageEmoji: emoji, + audioText: `¿Qué palabra es?`, + options: [ + ...palabras2silabas + .filter(p => p.palabra !== palabra) + .slice(0, 2) + .map(p => ({ label: p.palabra, correct: false, id: p.palabra.toLowerCase() })), + { label: palabra, correct: true, id: lowerPalabra }, + { label: 'Escuchar 👂', correct: false, id: 'escuchar' }, + ], + }, + functionalContext: `Asociar la palabra ${palabra} con su imagen.`, + errorType: 'confusion-letra', + }) +} + +// Silaba order exercises +const secuencias = [ + { palabra: 'MAPA', silabas: ['PA', 'MA'], emoji: '🗺️' }, + { palabra: 'PATO', silabas: ['TO', 'PA'], emoji: '🦆' }, + { palabra: 'SAPO', silabas: ['PO', 'SA'], emoji: '🐸' }, +] + +for (const { palabra, silabas, emoji } of secuencias) { + const lower = palabra.toLowerCase() + exercises.push({ + id: `lec6-ordenar-${lower}`, + stage: 6, + skillCode: `silabas-orden-${lower}`, + type: 'secuencia', + prerequisites: [`lec6-palabra-${lower}-leer`], + content: { + instruction: `Ordená las sílabas para formar ${palabra}`, + audioText: `Ordená para formar ${palabra}`, + sequence: silabas, + emoji, + }, + functionalContext: `Ordenar sílabas para formar ${palabra}.`, + errorType: 'inversion-letra', + }) +} + +const stage: Stage = { + id: 6, + name: 'Sílabas y palabras de 2 sílabas', + description: 'Combinar consonantes + vocales para formar y leer palabras de 2 sílabas.', + exercises, +} + +export default stage diff --git a/curriculum/lectura/etapa-7.ts b/curriculum/lectura/etapa-7.ts new file mode 100644 index 0000000..0ddce86 --- /dev/null +++ b/curriculum/lectura/etapa-7.ts @@ -0,0 +1,109 @@ +import type { Stage } from '../types' + +const palabras3silabas = [ + { palabra: 'MALETA', silabas: ['MA', 'LE', 'TA'], emoji: '🧳' }, + { palabra: 'PALETA', silabas: ['PA', 'LE', 'TA'], emoji: '🎨' }, + { palabra: 'SALIDA', silabas: ['SA', 'LI', 'DA'], emoji: '🚪' }, + { palabra: 'TELÉFONO', silabas: ['TE', 'LÉ', 'FO', 'NO'], emoji: '📞' }, + { palabra: 'MARIPOSA', silabas: ['MA', 'RI', 'PO', 'SA'], emoji: '🦋' }, + { palabra: 'MUSICA', silabas: ['MU', 'SI', 'CA'], emoji: '🎵' }, + { palabra: 'PLATO', silabas: ['PLA', 'TO'], emoji: '🍽️' }, + { palabra: 'TRISTE', silabas: ['TRIS', 'TE'], emoji: '😢' }, + { palabra: 'PLUMA', silabas: ['PLU', 'MA'], emoji: '🪶' }, + { palabra: 'PANTALLA', silabas: ['PAN', 'TA', 'LLA'], emoji: '📺' }, + { palabra: 'PRIMAVERA', silabas: ['PRI', 'MA', 'VE', 'RA'], emoji: '🌸' }, + { palabra: 'MELÓN', silabas: ['ME', 'LÓN'], emoji: '🍈' }, + { palabra: 'SILLA', silabas: ['SI', 'LLA'], emoji: '🪑' }, + { palabra: 'TORTUGA', silabas: ['TOR', 'TU', 'GA'], emoji: '🐢' }, + { palabra: 'DORMIR', silabas: ['DOR', 'MIR'], emoji: '😴' }, + { palabra: 'RATÓN', silabas: ['RA', 'TÓN'], emoji: '🐭' }, + { palabra: 'NARIZ', silabas: ['NA', 'RIZ'], emoji: '👃' }, + { palabra: 'LÁPIZ', silabas: ['LÁ', 'PIZ'], emoji: '✏️' }, + { palabra: 'DINOSAURIO', silabas: ['DI', 'NO', 'SAU', 'RIO'], emoji: '🦕' }, + { palabra: 'ELEFANTE', silabas: ['E', 'LE', 'FAN', 'TE'], emoji: '🐘' }, +] + +const exercises: any[] = [] + +for (const { palabra, silabas, emoji } of palabras3silabas) { + const lowerPalabra = palabra.toLowerCase().replace(/[^a-záéíóú]/g, '') + + // Read the word + exercises.push({ + id: `lec7-${lowerPalabra}-leer`, + stage: 7, + skillCode: `palabra-${lowerPalabra}`, + type: 'eleccion', + prerequisites: ['lec6-palabra-mapa-leer'], + content: { + instruction: `Leé esta palabra: ${palabra}`, + text: palabra, + audioText: `${palabra}`, + emoji, + options: [ + { label: palabra, correct: true, id: lowerPalabra }, + ...palabras3silabas + .filter(p => p.palabra !== palabra) + .slice(0, 2) + .map(p => ({ label: p.palabra, correct: false, id: p.palabra.toLowerCase().replace(/[^a-záéíóú]/g, '') })), + ], + }, + functionalContext: `Leer la palabra ${palabra}.`, + errorType: 'silaba-dificil', + }) + + // Count syllables + exercises.push({ + id: `lec7-${lowerPalabra}-silabas`, + stage: 7, + skillCode: `palabra-${lowerPalabra}`, + type: 'conciencia', + prerequisites: [`lec7-${lowerPalabra}-leer`], + content: { + instruction: `¿Cuántas sílabas tiene ${palabra}?`, + text: palabra, + audioText: `¿Cuántas sílabas?`, + options: [ + { label: `${'👏'.repeat(silabas.length)} ${silabas.length}`, correct: true, id: `${silabas.length}` }, + { label: `${'👏'.repeat(Math.max(1, silabas.length - 1))} ${silabas.length - 1}`, correct: false, id: `${silabas.length - 1}` }, + { label: `${'👏'.repeat(silabas.length + 1)} ${silabas.length + 1}`, correct: false, id: `${silabas.length + 1}` }, + ], + emoji, + }, + functionalContext: `Contar sílabas en ${palabra}.`, + errorType: 'discriminacion-auditiva', + }) + + // Match image + exercises.push({ + id: `lec7-${lowerPalabra}-imagen`, + stage: 7, + skillCode: `palabra-${lowerPalabra}`, + type: 'palabra', + prerequisites: [`lec7-${lowerPalabra}-silabas`], + content: { + instruction: `¿Qué palabra es?`, + imageEmoji: emoji, + audioText: `¿Cuál es?`, + options: [ + ...palabras3silabas + .filter(p => p.palabra !== palabra) + .slice(0, 2) + .map(p => ({ label: p.palabra, correct: false, id: p.palabra.toLowerCase().replace(/[^a-záéíóú]/g, '') })), + { label: palabra, correct: true, id: lowerPalabra }, + { label: 'Escuchar 👂', correct: false, id: 'escuchar' }, + ], + }, + functionalContext: `Asociar la palabra ${palabra} con su imagen.`, + errorType: 'confusion-letra', + }) +} + +const stage: Stage = { + id: 7, + name: 'Palabras de 3+ sílabas', + description: 'Leer y comprender palabras de 3 o más sílabas con sílabas compuestas.', + exercises, +} + +export default stage diff --git a/curriculum/lectura/etapa-8.ts b/curriculum/lectura/etapa-8.ts new file mode 100644 index 0000000..1d52e6d --- /dev/null +++ b/curriculum/lectura/etapa-8.ts @@ -0,0 +1,147 @@ +import type { Stage } from '../types' + +const frases = [ + { + frase: 'Mi mamá me ama.', + opciones: ['Mi papá me ama.', 'Mi mamá me ama.', 'Mi mamá me mima.'], + correcta: 'Mi mamá me ama.', + emoji: '💕', + }, + { + frase: 'El sol sale temprano.', + opciones: ['La luna sale tarde.', 'El sol sale temprano.', 'El sol se esconde.'], + correcta: 'El sol sale temprano.', + emoji: '☀️', + }, + { + frase: 'La luna está en el cielo.', + opciones: ['El sol está en el mar.', 'La luna está en el cielo.', 'La luna es redonda.'], + correcta: 'La luna está en el cielo.', + emoji: '🌙', + }, + { + frase: 'El pato nada en el lago.', + opciones: ['El pato vuela alto.', 'El pato nada en el lago.', 'El gato nada en el lago.'], + correcta: 'El pato nada en el lago.', + emoji: '🦆', + }, + { + frase: 'Mi gato es muy lindo.', + opciones: ['Mi perro es grande.', 'Mi gato es muy lindo.', 'Mi gato salta alto.'], + correcta: 'Mi gato es muy lindo.', + emoji: '🐱', + }, + { + frase: 'La mariposa vuela entre las flores.', + opciones: ['La mariposa está dormida.', 'La mariposa vuela entre las flores.', 'La abeja hace miel.'], + correcta: 'La mariposa vuela entre las flores.', + emoji: '🦋', + }, + { + frase: 'Tomo leche con galletitas.', + opciones: ['Tomo agua con hielo.', 'Tomo leche con galletitas.', 'Como sopa caliente.'], + correcta: 'Tomo leche con galletitas.', + emoji: '🥛', + }, + { + frase: 'El perro corre en el parque.', + opciones: ['El perro duerme en casa.', 'El perro corre en el parque.', 'El gato corre en el parque.'], + correcta: 'El perro corre en el parque.', + emoji: '🐕', + }, + { + frase: 'Mi hermana tiene un lápiz rojo.', + opciones: ['Mi mamá tiene una mesa.', 'Mi hermana tiene un lápiz rojo.', 'Mi hermana tiene un libro.'], + correcta: 'Mi hermana tiene un lápiz rojo.', + emoji: '✏️', + }, + { + frase: 'La tortuga camina despacio.', + opciones: ['La liebre salta rápido.', 'La tortuga camina despacio.', 'El pez nada veloz.'], + correcta: 'La tortuga camina despacio.', + emoji: '🐢', + }, + { + frase: 'El elefante es muy grande.', + opciones: ['El ratón es chiquito.', 'El elefante es muy grande.', 'El perro es mediano.'], + correcta: 'El elefante es muy grande.', + emoji: '🐘', + }, + { + frase: 'Me gusta pintar con mis dedos.', + opciones: ['Me gusta cantar canciones.', 'Me gusta pintar con mis dedos.', 'Me gusta mirar tele.'], + correcta: 'Me gusta pintar con mis dedos.', + emoji: '🎨', + }, + { + frase: 'El sol es amarillo.', + opciones: ['La luna es blanca.', 'El sol es amarillo.', 'El cielo es azul.'], + correcta: 'El sol es amarillo.', + emoji: '🟡', + }, + { + frase: 'Mi papá me lee un cuento.', + opciones: ['Mi mamá me canta.', 'Mi papá me lee un cuento.', 'Mi papá cocina rico.'], + correcta: 'Mi papá me lee un cuento.', + emoji: '📖', + }, + { + frase: 'La mesa está en la sala.', + opciones: ['La silla está en la cocina.', 'La mesa está en la sala.', 'La cama está en mi pieza.'], + correcta: 'La mesa está en la sala.', + emoji: '🪑', + }, +] + +const exercises: any[] = [] + +for (const { frase, opciones, correcta, emoji } of frases) { + const id = `lec8-${frase.toLowerCase().replace(/[^a-záéíóú]/g, '').slice(0, 20)}` + + exercises.push({ + id: `${id}-leer`, + stage: 8, + skillCode: 'frases', + type: 'lectura', + prerequisites: ['lec7-maleta-leer'], + content: { + instruction: 'Leé esta oración en voz alta', + text: frase, + audioText: frase, + emoji, + options: [ + { label: '¡Leída!', correct: true, id: 'leida' }, + ], + }, + functionalContext: 'Leer oraciones simples.', + }) + + exercises.push({ + id: `${id}-comprender`, + stage: 8, + skillCode: 'frases', + type: 'lectura', + prerequisites: [`${id}-leer`], + content: { + instruction: `¿Cuál oración es la correcta?`, + emoji, + audioText: `¿Cuál es correcta?`, + options: opciones.map(o => ({ + label: o, + correct: o === correcta, + id: o.toLowerCase().replace(/[^a-záéíóú]/g, '').slice(0, 15), + })), + }, + functionalContext: 'Comprender la oración leída.', + errorType: 'omision-letra', + }) +} + +const stage: Stage = { + id: 8, + name: 'Frases y oraciones', + description: 'Leer oraciones simples y comprender su significado.', + exercises, +} + +export default stage diff --git a/curriculum/lectura/etapa-9.ts b/curriculum/lectura/etapa-9.ts new file mode 100644 index 0000000..25161c4 --- /dev/null +++ b/curriculum/lectura/etapa-9.ts @@ -0,0 +1,176 @@ +import type { Stage } from '../types' + +const lecturas = [ + { + texto: 'El sol sale por la mañana. Las flores se abren. Los pájaros cantan. Es un lindo día.', + pregunta: '¿Qué pasa por la mañana?', + opciones: [ + { label: 'La luna sale', correct: false }, + { label: 'El sol sale', correct: true }, + { label: 'Las estrellas brillan', correct: false }, + ], + emoji: '🌄', + }, + { + texto: 'Mamá prepara la mesa. Papá sirve la sopa. Todos comen juntos. Después lavan los platos.', + pregunta: '¿Qué hace papá?', + opciones: [ + { label: 'Lava los platos', correct: false }, + { label: 'Prepara la mesa', correct: false }, + { label: 'Sirve la sopa', correct: true }, + ], + emoji: '🍲', + }, + { + texto: 'El gato de mi casa es negro. Le gusta dormir al sol. Por la noche sale a pasear.', + pregunta: '¿De qué color es el gato?', + opciones: [ + { label: 'Blanco', correct: false }, + { label: 'Negro', correct: true }, + { label: 'Gris', correct: false }, + ], + emoji: '🐈‍⬛', + }, + { + texto: 'La nena juega en el parque. Sube al tobogán. Baja rápido y se ríe. Después juega en la arena.', + pregunta: '¿Dónde juega la nena?', + opciones: [ + { label: 'En su casa', correct: false }, + { label: 'En la escuela', correct: false }, + { label: 'En el parque', correct: true }, + ], + emoji: '🛝', + }, + { + texto: 'En la granja hay vacas, ovejas y gallinas. Las vacas dan leche. Las gallinas ponen huevos.', + pregunta: '¿Qué dan las vacas?', + opciones: [ + { label: 'Huevos', correct: false }, + { label: 'Leche', correct: true }, + { label: 'Lana', correct: false }, + ], + emoji: '🐄', + }, + { + texto: 'Luna tiene cuatro patas, dos orejas largas y una cola corta. Come zanahorias. Es una coneja.', + pregunta: '¿Qué es Luna?', + opciones: [ + { label: 'Un perro', correct: false }, + { label: 'Un gato', correct: false }, + { label: 'Una coneja', correct: true }, + ], + emoji: '🐰', + }, + { + texto: 'El libro de cuentos tiene dibujos lindos. La nena lo mira todas las noches. Su mamá le lee antes de dormir.', + pregunta: '¿Cuándo lee mamá?', + opciones: [ + { label: 'Por la mañana', correct: false }, + { label: 'Antes de dormir', correct: true }, + { label: 'A la tarde', correct: false }, + ], + emoji: '📚', + }, + { + texto: 'La tortuga Tula vive en un estanque. Le gusta nadar y tomar sol en una piedra. Es muy tranquila.', + pregunta: '¿Dónde vive Tula?', + opciones: [ + { label: 'En el mar', correct: false }, + { label: 'En un estanque', correct: true }, + { label: 'En una casa', correct: false }, + ], + emoji: '🐢', + }, + { + texto: 'Tomás tiene tres años. Juega con bloques de colores. Arma una torre muy alta. Después la derriba. ¡Plaf!', + pregunta: '¿Qué arma Tomás?', + opciones: [ + { label: 'Un castillo', correct: false }, + { label: 'Una torre', correct: true }, + { label: 'Un puente', correct: false }, + ], + emoji: '🧱', + }, + { + texto: 'La abuela teje una bufanda roja para el invierno. Usa lana suave y dos agujas. La bufanda queda muy linda.', + pregunta: '¿Qué teje la abuela?', + opciones: [ + { label: 'Un gorro', correct: false }, + { label: 'Una bufanda', correct: true }, + { label: 'Un guante', correct: false }, + ], + emoji: '🧣', + }, + { + texto: 'En la plaza hay un árbol grande. Tiene hojas verdes y flores rosadas. Los pájaros hacen nidos allí.', + pregunta: '¿De qué color son las flores?', + opciones: [ + { label: 'Rosadas', correct: true }, + { label: 'Amarillas', correct: false }, + { label: 'Blancas', correct: false }, + ], + emoji: '🌳', + }, + { + texto: 'El niño se pone las botas de lluvia. Abre el paraguas azul. Salta en los charcos. ¡Qué divertido!', + pregunta: '¿Qué se pone el niño?', + opciones: [ + { label: 'Un abrigo', correct: false }, + { label: 'Botas de lluvia', correct: true }, + { label: 'Un sombrero', correct: false }, + ], + emoji: '☂️', + }, +] + +const exercises: any[] = [] + +for (const { texto, pregunta, opciones, emoji } of lecturas) { + const id = `lec9-${texto.toLowerCase().replace(/[^a-záéíóú]/g, '').slice(0, 15)}` + + exercises.push({ + id: `${id}-texto`, + stage: 9, + skillCode: 'comprension', + type: 'lectura', + prerequisites: ['lec8-frase-mimamameama-leer'], + content: { + instruction: 'Leé este texto', + text: texto, + audioText: texto, + emoji, + options: [ + { label: '¡Leído!', correct: true, id: 'leido' }, + ], + }, + functionalContext: 'Leer un texto corto.', + }) + + exercises.push({ + id: `${id}-pregunta`, + stage: 9, + skillCode: 'comprension', + type: 'lectura', + prerequisites: [`${id}-texto`], + content: { + instruction: `Respondé: ${pregunta}`, + text: texto, + audioText: pregunta, + emoji, + options: [ + ...opciones.map(o => ({ label: o.label, correct: o.correct, id: o.label.toLowerCase().replace(/[^a-záéíóú]/g, '') })), + ], + }, + functionalContext: 'Comprender y responder preguntas sobre el texto.', + errorType: 'omision-letra', + }) +} + +const stage: Stage = { + id: 9, + name: 'Comprensión lectora', + description: 'Leer textos cortos y responder preguntas de comprensión.', + exercises, +} + +export default stage diff --git a/curriculum/numeros/etapa-1.ts b/curriculum/numeros/etapa-1.ts new file mode 100644 index 0000000..cad9fb7 --- /dev/null +++ b/curriculum/numeros/etapa-1.ts @@ -0,0 +1,82 @@ +import type { Stage } from '../types' + +const exercises: any[] = [] + +// Count 1-5 +for (let n = 1; n <= 5; n++) { + const emojis = '⭐'.repeat(n) + exercises.push({ + id: `num1-contar-${n}`, + stage: 1, + skillCode: `contar-${n}`, + type: 'sensibilizacion', + prerequisites: n === 1 ? [] : [`num1-contar-${n - 1}`], + content: { + instruction: `Contá. ¿Cuántas estrellas hay?`, + audioText: `Uno, dos, tres...`, + emoji: emojis, + options: [ + ...Array.from({ length: 5 }, (_, i) => i + 1) + .filter(j => j !== n) + .slice(0, 2) + .map(j => ({ label: String(j), correct: false, id: String(j) })), + { label: String(n), correct: true, id: String(n) }, + ].sort(() => Math.random() - 0.5), + }, + functionalContext: `Contar hasta ${n} elementos.`, + errorType: 'discriminacion-auditiva', + }) +} + +// Recognize written digits 1-5 +for (let n = 1; n <= 5; n++) { + exercises.push({ + id: `num1-digito-${n}`, + stage: 1, + skillCode: `digito-${n}`, + type: 'eleccion', + prerequisites: [`num1-contar-${n}`], + content: { + instruction: `Señalá el número ${n}`, + audioText: `Buscá el número ${n}`, + options: [ + ...Array.from({ length: 5 }, (_, i) => i + 1) + .filter(j => j !== n) + .slice(0, 2) + .map(j => ({ label: String(j), correct: false, id: String(j) })), + { label: String(n), correct: true, id: String(n) }, + ].sort(() => Math.random() - 0.5), + emoji: String(n), + }, + functionalContext: `Reconocer el dígito ${n}.`, + errorType: 'confusion-letra', + }) +} + +// Trace with finger +for (let n = 1; n <= 5; n++) { + exercises.push({ + id: `num1-trazo-${n}`, + stage: 1, + skillCode: `digito-${n}`, + type: 'trazo', + prerequisites: [`num1-digito-${n}`], + content: { + instruction: `Trazá el número ${n} con tu dedo`, + text: String(n), + audioText: `Trazá el número ${n}`, + emoji: '✍️', + }, + functionalContext: `Aprender a trazar el número ${n}.`, + errorType: 'confusion-letra', + }) +} + +const stage: Stage = { + id: 1, + name: 'Conteo del 1 al 5', + description: 'Contar objetos, reconocer dígitos y trazar números del 1 al 5.', + exercises, +} + +export default stage diff --git a/curriculum/numeros/etapa-2.ts b/curriculum/numeros/etapa-2.ts new file mode 100644 index 0000000..46c2608 --- /dev/null +++ b/curriculum/numeros/etapa-2.ts @@ -0,0 +1,99 @@ +import type { Stage } from '../types' + +const exercises: any[] = [] + +// Count 6-10 +for (let n = 6; n <= 10; n++) { + const emojis = '🟢'.repeat(n) + exercises.push({ + id: `num2-contar-${n}`, + stage: 2, + skillCode: `contar-${n}`, + prerequisites: n === 6 ? ['num1-trazo-5'] : [`num2-contar-${n - 1}`], + type: 'sensibilizacion', + content: { + instruction: `¿Cuántos círculos verdes hay?`, + audioText: `Contá los círculos`, + emoji: emojis, + options: [ + ...Array.from({ length: 5 }, (_, i) => i + 6) + .filter(j => j !== n) + .slice(0, 2) + .map(j => ({ label: String(j), correct: false, id: String(j) })), + { label: String(n), correct: true, id: String(n) }, + ].sort(() => Math.random() - 0.5), + }, + functionalContext: `Contar hasta ${n} elementos.`, + errorType: 'discriminacion-auditiva', + }) +} + +// Recognize written digits 6-10 +for (let n = 6; n <= 10; n++) { + exercises.push({ + id: `num2-digito-${n}`, + stage: 2, + skillCode: `digito-${n}`, + type: 'eleccion', + prerequisites: [`num2-contar-${n}`], + content: { + instruction: `Señalá el número ${n}`, + audioText: `Buscá el ${n}`, + options: [ + ...Array.from({ length: 5 }, (_, i) => i + 6) + .filter(j => j !== n) + .slice(0, 2) + .map(j => ({ label: String(j), correct: false, id: String(j) })), + { label: String(n), correct: true, id: String(n) }, + ].sort(() => Math.random() - 0.5), + emoji: String(n), + }, + functionalContext: `Reconocer el dígito ${n}.`, + errorType: 'confusion-letra', + }) +} + +// Order sequence 1-10 +exercises.push({ + id: 'num2-secuencia-1-10', + stage: 2, + skillCode: 'secuencia-1-10', + type: 'secuencia', + prerequisites: ['num2-digito-10'], + content: { + instruction: 'Ordená los números del 1 al 10', + audioText: 'Ordená del 1 al 10', + sequence: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10'], + emoji: '🔢', + }, + functionalContext: 'Conocer la secuencia numérica del 1 al 10.', + errorType: 'inversion-letra', +}) + +// Trace 6-10 +for (let n = 6; n <= 10; n++) { + exercises.push({ + id: `num2-trazo-${n}`, + stage: 2, + skillCode: `digito-${n}`, + type: 'trazo', + prerequisites: [`num2-digito-${n}`, ...(n > 6 ? [`num2-trazo-${n - 1}`] : [])], + content: { + instruction: `Trazá el número ${n} con tu dedo`, + text: String(n), + audioText: `Trazá el ${n}`, + emoji: '✍️', + }, + functionalContext: `Aprender a trazar el número ${n}.`, + errorType: 'confusion-letra', + }) +} + +const stage: Stage = { + id: 2, + name: 'Conteo del 6 al 10', + description: 'Contar objetos, reconocer dígitos y trazar números del 6 al 10, y ordenar del 1 al 10.', + exercises, +} + +export default stage diff --git a/curriculum/numeros/etapa-3.ts b/curriculum/numeros/etapa-3.ts new file mode 100644 index 0000000..2b4895d --- /dev/null +++ b/curriculum/numeros/etapa-3.ts @@ -0,0 +1,107 @@ +import type { Stage } from '../types' + +const exercises: any[] = [] + +// Pair number with quantity +for (let n = 1; n <= 10; n++) { + const emojis = ['🐶', '🐱', '🐰', '🐸', '🐵', '🐼', '🐨', '🦊', '🐻', '🐯'] + const animal = emojis[n - 1] + const howMany = animal.repeat(Math.min(n, 5)) + (n > 5 ? ` (${n})` : '') + + exercises.push({ + id: `num3-cantidad-${n}`, + stage: 3, + skillCode: `correspondencia-${n}`, + type: 'conciencia', + prerequisites: n === 1 ? ['num2-trazo-10'] : [`num3-cantidad-${n - 1}`], + content: { + instruction: `¿Cuántos ${animal} hay?`, + audioText: `Contá los animalitos`, + text: n <= 5 ? animal.repeat(n) : `${animal.repeat(5)}... +${n - 5}`, + options: [ + ...Array.from({ length: 10 }, (_, i) => i + 1) + .filter(j => j !== n) + .slice(0, 2) + .map(j => ({ label: String(j), correct: false, id: String(j) })), + { label: String(n), correct: true, id: String(n) }, + ].sort(() => Math.random() - 0.5), + emoji: animal, + }, + functionalContext: 'Asociar cantidad con número.', + errorType: 'discriminacion-auditiva', + }) +} + +// Match groups that are equal +const pares = [ + { a: '🐶🐶🐶', b: '3️⃣', num: 3 }, + { a: '🐱🐱🐱🐱', b: '4️⃣', num: 4 }, + { a: '🐰🐰🐰🐰🐰', b: '5️⃣', num: 5 }, + { a: '🐸🐸', b: '2️⃣', num: 2 }, + { a: '🐵🐵🐵🐵🐵🐵', b: '6️⃣', num: 6 }, +] + +for (const { a, b, num } of pares) { + exercises.push({ + id: `num3-emparejar-${num}`, + stage: 3, + skillCode: 'correspondencia', + type: 'conciencia', + prerequisites: [`num3-cantidad-${num}`], + content: { + instruction: `¿Cuál número le corresponde a ${a}?`, + audioText: `¿Qué número es?`, + text: a, + options: [ + ...pares.filter(p => p.num !== num).slice(0, 2).map(p => ({ label: p.b, correct: false, id: String(p.num) })), + { label: b, correct: true, id: String(num) }, + ].sort(() => Math.random() - 0.5), + emoji: '🔄', + }, + functionalContext: 'Emparejar grupos con su número.', + errorType: 'confusion-letra', + }) +} + +// More/less comparison +const comparaciones = [ + { a: 3, b: 5, mas: 5, menos: 3 }, + { a: 2, b: 7, mas: 7, menos: 2 }, + { a: 4, b: 4, mas: 4, menos: 4 }, + { a: 6, b: 3, mas: 6, menos: 3 }, + { a: 1, b: 9, mas: 9, menos: 1 }, +] + +for (const { a, b, mas, menos } of comparaciones) { + const idA = '⭐'.repeat(a) + const idB = '⭐'.repeat(b) + exercises.push({ + id: `num3-mas-${a}-${b}`, + stage: 3, + skillCode: 'comparacion', + type: 'conciencia', + prerequisites: [`num3-cantidad-${Math.max(a, b)}`], + content: { + instruction: `¿Dónde hay MÁS?`, + text: `${idA} vs ${idB}`, + audioText: `¿Cuál tiene más?`, + options: [ + { label: `👈 ${a}`, correct: mas === a, id: `izq-${a}` }, + { label: `👉 ${b}`, correct: mas === b, id: `der-${b}` }, + { label: '😐 Igual', correct: a === b, id: 'igual' }, + ], + emoji: '⚖️', + }, + functionalContext: 'Comparar cantidades (más/menos).', + errorType: 'discriminacion-auditiva', + }) +} + +const stage: Stage = { + id: 3, + name: 'Correspondencia uno a uno', + description: 'Asociar cantidades con números, emparejar grupos iguales, comparar más y menos.', + exercises, +} + +export default stage diff --git a/curriculum/numeros/etapa-4.ts b/curriculum/numeros/etapa-4.ts new file mode 100644 index 0000000..bc8793f --- /dev/null +++ b/curriculum/numeros/etapa-4.ts @@ -0,0 +1,83 @@ +import type { Stage } from '../types' + +const exercises: any[] = [] + +for (let n = 11; n <= 20; n++) { + exercises.push({ + id: `num4-contar-${n}`, + stage: 4, + skillCode: `contar-${n}`, + type: 'conciencia', + prerequisites: n === 11 ? ['num3-cantidad-10'] : [`num4-contar-${n - 1}`], + content: { + instruction: `Contá. ¿Cuántos hay? (${n})`, + audioText: `Son ${n}`, + text: `🔵🔵🔵🔵🔵 🟣🟣🟣🟣🟣 ${n > 10 ? `+${n - 10}` : ''}`, + options: [ + ...Array.from({ length: 5 }, (_, i) => n - 2 + i) + .filter(j => j >= 10 && j <= 20 && j !== n) + .slice(0, 2) + .map(j => ({ label: String(j), correct: false, id: String(j) })), + { label: String(n), correct: true, id: String(n) }, + ].sort(() => Math.random() - 0.5), + emoji: String(n), + }, + functionalContext: `Reconocer el número ${n}.`, + errorType: 'confusion-letra', + }) +} + +// Decenas y unidades visual +for (let n = 10; n <= 20; n++) { + const decenas = Math.floor(n / 10) + const unidades = n % 10 + exercises.push({ + id: `num4-descomponer-${n}`, + stage: 4, + skillCode: 'decenas-unidades', + type: 'eleccion', + prerequisites: [`num4-contar-${n}`], + content: { + instruction: `${n} son ${decenas} decena${decenas > 1 ? 's' : ''} y ${unidades} unidades`, + text: `🔟🔟${'●'.repeat(unidades)} = ${n}`, + audioText: `${n} es ${decenas} decenas y ${unidades} unidades`, + options: [ + { label: '🔟 Decenas', correct: false, id: `decenas-${n}` }, + { label: String(n), correct: true, id: String(n) }, + ...Array.from({ length: 3 }, (_, i) => n + i - 1) + .filter(j => j >= 10 && j <= 20 && j !== n) + .slice(0, 1) + .map(j => ({ label: String(j), correct: false, id: String(j) })), + ].sort(() => Math.random() - 0.5), + emoji: '🔟', + }, + functionalContext: 'Introducir decenas y unidades.', + errorType: 'confusion-letra', + }) +} + +// Secuencia 11-20 +exercises.push({ + id: 'num4-secuencia-11-20', + stage: 4, + skillCode: 'secuencia-11-20', + type: 'secuencia', + prerequisites: ['num4-descomponer-20'], + content: { + instruction: 'Ordená los números del 11 al 20', + audioText: 'Ordená del 11 al 20', + sequence: ['11', '12', '13', '14', '15', '16', '17', '18', '19', '20'], + emoji: '🔢', + }, + functionalContext: 'Conocer la secuencia del 11 al 20.', + errorType: 'inversion-letra', +}) + +const stage: Stage = { + id: 4, + name: 'Números del 11 al 20', + description: 'Aprender los números del 11 al 20. Introducir decenas y unidades.', + exercises, +} + +export default stage diff --git a/curriculum/numeros/etapa-5.ts b/curriculum/numeros/etapa-5.ts new file mode 100644 index 0000000..90fc91c --- /dev/null +++ b/curriculum/numeros/etapa-5.ts @@ -0,0 +1,90 @@ +import type { Stage } from '../types' + +const sumas = [ + { a: 1, b: 1, r: 2, emoji: '🐶+🐶' }, + { a: 2, b: 1, r: 3, emoji: '🐱+🐶' }, + { a: 2, b: 2, r: 4, emoji: '🐱+🐱' }, + { a: 3, b: 1, r: 5, emoji: '🐰+🐶' }, + { a: 3, b: 2, r: 5, emoji: '🐰+🐱' }, + { a: 4, b: 1, r: 5, emoji: '🐸+🐶' }, + { a: 5, b: 1, r: 6, emoji: '🐵+🐶' }, + { a: 3, b: 3, r: 6, emoji: '🐰+🐰' }, + { a: 5, b: 2, r: 7, emoji: '🐵+🐱' }, + { a: 4, b: 3, r: 7, emoji: '🐸+🐰' }, + { a: 5, b: 3, r: 8, emoji: '🐵+🐰' }, + { a: 4, b: 4, r: 8, emoji: '🐸+🐸' }, + { a: 5, b: 4, r: 9, emoji: '🐵+🐸' }, + { a: 5, b: 5, r: 10, emoji: '🐵+🐵' }, + { a: 6, b: 1, r: 7, emoji: '🐼+🐶' }, + { a: 6, b: 2, r: 8, emoji: '🐼+🐱' }, + { a: 7, b: 1, r: 8, emoji: '🐨+🐶' }, + { a: 7, b: 2, r: 9, emoji: '🐨+🐱' }, + { a: 8, b: 1, r: 9, emoji: '🦊+🐶' }, + { a: 8, b: 2, r: 10, emoji: '🦊+🐱' }, + { a: 9, b: 1, r: 10, emoji: '🐻+🐶' }, + { a: 3, b: 4, r: 7, emoji: '🐰+🐸' }, + { a: 4, b: 5, r: 9, emoji: '🐸+🐵' }, + { a: 6, b: 3, r: 9, emoji: '🐼+🐰' }, + { a: 7, b: 3, r: 10, emoji: '🐨+🐰' }, +] + +const exercises: any[] = [] + +for (const { a, b, r, emoji } of sumas) { + const id = `num5-suma-${a}-${b}` + exercises.push({ + id, + stage: 5, + skillCode: 'suma', + type: 'problema', + prerequisites: a <= 5 && b <= 5 ? ['num4-secuencia-11-20'] : [`num5-suma-${a}-${b - 1}`], + content: { + instruction: `¿Cuánto es ${a} + ${b}?`, + text: `${a} + ${b} = ?`, + audioText: `${a} más ${b}`, + emoji, + options: [ + ...Array.from({ length: 4 }, (_, i) => r - 2 + i + (i >= 2 ? 2 : 0)) + .filter(j => j >= 1 && j <= 12 && j !== r) + .slice(0, 2) + .map(j => ({ label: String(j), correct: false, id: String(j) })), + { label: String(r), correct: true, id: String(r) }, + ].sort(() => Math.random() - 0.5), + }, + functionalContext: 'Sumar dos números pequeños.', + errorType: 'discriminacion-auditiva', + }) +} + +// Represent sum with objects +for (const { a, b, r } of sumas.slice(0, 8)) { + exercises.push({ + id: `num5-suma-visual-${a}-${b}`, + stage: 5, + skillCode: 'suma-visual', + type: 'conciencia', + prerequisites: [`num5-suma-${a}-${b}`], + content: { + instruction: `${a} + ${b} es lo mismo que...`, + text: `${'●'.repeat(a)} + ${'●'.repeat(b)}`, + audioText: `Juntamos ${a} y ${b}, tenemos ${r}`, + options: [ + { label: '●'.repeat(r), correct: true, id: String(r) }, + { label: '●'.repeat(r + 1), correct: false, id: String(r + 1) }, + { label: '●'.repeat(Math.max(1, r - 1)), correct: false, id: String(r - 1) }, + ], + emoji: '➕', + }, + functionalContext: 'Visualizar la suma como unión de conjuntos.', + errorType: 'discriminacion-auditiva', + }) +} + +const stage: Stage = { + id: 5, + name: 'Sumas simples (1-10)', + description: 'Sumar números del 1 al 10 con ayudas visuales y ejercicios progresivos.', + exercises, +} + +export default stage diff --git a/curriculum/numeros/etapa-6.ts b/curriculum/numeros/etapa-6.ts new file mode 100644 index 0000000..9159f8e --- /dev/null +++ b/curriculum/numeros/etapa-6.ts @@ -0,0 +1,95 @@ +import type { Stage } from '../types' + +const restas = [ + { a: 2, b: 1, r: 1, emoji: '🍎-🍎' }, + { a: 3, b: 1, r: 2, emoji: '🍎🍎-🍎' }, + { a: 3, b: 2, r: 1, emoji: '🍎🍎-🍎🍎' }, + { a: 4, b: 1, r: 3, emoji: '🍪🍪🍪🍪-🍪' }, + { a: 4, b: 2, r: 2, emoji: '🍪🍪🍪🍪-🍪🍪' }, + { a: 5, b: 1, r: 4, emoji: '⭐-⭐' }, + { a: 5, b: 2, r: 3, emoji: '⭐⭐-⭐⭐' }, + { a: 5, b: 3, r: 2, emoji: '⭐⭐⭐-⭐⭐⭐' }, + { a: 5, b: 4, r: 1, emoji: '⭐⭐⭐⭐-⭐⭐⭐⭐' }, + { a: 6, b: 1, r: 5, emoji: '🌸-🌸' }, + { a: 6, b: 2, r: 4, emoji: '🌸🌸-🌸🌸' }, + { a: 6, b: 3, r: 3, emoji: '🌸🌸🌸-🌸🌸🌸' }, + { a: 7, b: 2, r: 5, emoji: '🌻🌻-🌻🌻' }, + { a: 7, b: 3, r: 4, emoji: '🌻🌻🌻-🌻🌻🌻' }, + { a: 8, b: 3, r: 5, emoji: '🍄🍄🍄-🍄🍄🍄' }, + { a: 8, b: 4, r: 4, emoji: '🍄🍄🍄🍄-🍄🍄🍄🍄' }, + { a: 9, b: 4, r: 5, emoji: '🍂🍂🍂🍂-🍂🍂🍂🍂' }, + { a: 9, b: 5, r: 4, emoji: '🍂🍂🍂🍂🍂-🍂🍂🍂🍂🍂' }, + { a: 10, b: 1, r: 9, emoji: '💎-💎' }, + { a: 10, b: 2, r: 8, emoji: '💎💎-💎💎' }, + { a: 10, b: 3, r: 7, emoji: '💎💎💎-💎💎💎' }, + { a: 10, b: 4, r: 6, emoji: '💎💎💎💎-💎💎💎💎' }, + { a: 10, b: 5, r: 5, emoji: '💎💎💎💎💎-💎💎💎💎💎' }, + { a: 8, b: 5, r: 3, emoji: '🍀🍀🍀🍀🍀-🍀🍀🍀🍀🍀' }, + { a: 7, b: 5, r: 2, emoji: '🌺🌺🌺🌺🌺-🌺🌺🌺🌺🌺' }, + { a: 6, b: 5, r: 1, emoji: '🌷🌷🌷🌷🌷-🌷🌷🌷🌷🌷' }, +] + +const exercises: any[] = [] + +for (const { a, b, r, emoji } of restas) { + exercises.push({ + id: `num6-resta-${a}-${b}`, + stage: 6, + skillCode: 'resta', + type: 'problema', + prerequisites: a <= 5 ? ['num5-suma-visual-1-1'] : [`num6-resta-${a - 1}-${Math.max(1, b - 1)}` || 'num5-suma-10-1'], + content: { + instruction: `¿Cuánto es ${a} - ${b}?`, + text: `${a} - ${b} = ?`, + audioText: `${a} menos ${b}`, + emoji, + options: [ + ...Array.from({ length: 4 }, (_, i) => r - 2 + i + (i >= 2 ? 2 : 0)) + .filter(j => j >= 0 && j <= 10 && j !== r) + .slice(0, 2) + .map(j => ({ label: String(j), correct: false, id: String(j) })), + { label: String(r), correct: true, id: String(r) }, + ].sort(() => Math.random() - 0.5), + }, + functionalContext: 'Restar números pequeños.', + errorType: 'discriminacion-auditiva', + }) +} + +// Visual subtraction: take away +const visuales = [ + { a: 3, b: 1, r: 2 }, + { a: 4, b: 2, r: 2 }, + { a: 5, b: 3, r: 2 }, +] +for (const { a, b, r } of visuales) { + exercises.push({ + id: `num6-resta-visual-${a}-${b}`, + stage: 6, + skillCode: 'resta-visual', + type: 'conciencia', + prerequisites: [`num6-resta-${a}-${b}`], + content: { + instruction: `${a} - ${b} = ? Sacamos ${b}`, + text: `${'🟢'.repeat(a)}\nSacamos ${'🔴'.repeat(b)}\nQuedan...`, + audioText: `Sacamos ${b}, quedan ${r}`, + options: [ + { label: '🟢'.repeat(r), correct: true, id: String(r) }, + { label: '🟢'.repeat(r + 2), correct: false, id: String(r + 2) }, + { label: '🟢'.repeat(Math.max(1, r + 1)), correct: false, id: String(r + 1) }, + ], + emoji: '➖', + }, + functionalContext: 'Visualizar la resta como quitar elementos.', + errorType: 'discriminacion-auditiva', + }) +} + +const stage: Stage = { + id: 6, + name: 'Restas simples (1-10)', + description: 'Restar números del 1 al 10 con ayudas visuales.', + exercises, +} + +export default stage diff --git a/curriculum/numeros/etapa-7.ts b/curriculum/numeros/etapa-7.ts new file mode 100644 index 0000000..7a3cf30 --- /dev/null +++ b/curriculum/numeros/etapa-7.ts @@ -0,0 +1,103 @@ +import type { Stage } from '../types' + +const numeros2d = [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 30, 33, 40, 44, 50] + +const exercises: any[] = [] + +for (const n of numeros2d) { + const dec = Math.floor(n / 10) + const uni = n % 10 + const decStr = '🔟'.repeat(dec) + const uniStr = '●'.repeat(uni) + + exercises.push({ + id: `num7-componer-${n}`, + stage: 7, + skillCode: 'valor-posicional', + type: 'eleccion', + prerequisites: n <= 15 ? ['num6-resta-visual-3-1'] : [`num7-componer-${numeros2d[numeros2d.indexOf(n) - 1]}`], + content: { + instruction: `${dec} decenas + ${uni} unidades = ?`, + text: `${dec}×10 + ${uni}×1 = ?`, + audioText: `${n}: ${dec} decenas y ${uni} unidades`, + options: [ + ...Array.from({ length: 4 }, (_, i) => n - 2 + i + (i >= 2 ? 2 : 0)) + .filter(j => j >= 10 && j <= 55 && j !== n) + .slice(0, 2) + .map(j => ({ label: String(j), correct: false, id: String(j) })), + { label: String(n), correct: true, id: String(n) }, + ].sort(() => Math.random() - 0.5), + emoji: decStr, + }, + functionalContext: 'Componer números de 2 dígitos en decenas y unidades.', + errorType: 'confusion-letra', + }) +} + +// Write the number of tens and units +for (const n of [15, 23, 30, 47, 50]) { + const dec = Math.floor(n / 10) + const uni = n % 10 + exercises.push({ + id: `num7-descomponer-${n}`, + stage: 7, + skillCode: 'valor-posicional', + type: 'conciencia', + prerequisites: [`num7-componer-${n}`], + content: { + instruction: `¿Cuántas decenas y unidades tiene ${n}?`, + text: `${n} = ? decenas + ? unidades`, + audioText: `${n} tiene ${dec} decenas y ${uni} unidades`, + options: [ + { label: `${dec} dec, ${uni} uni`, correct: true, id: `d${dec}u${uni}` }, + { label: `${uni} dec, ${dec} uni`, correct: false, id: `d${uni}u${dec}` }, + { label: `${dec + 1} dec, ${Math.max(0, uni - 1)} uni`, correct: false, id: `d${dec + 1}u${Math.max(0, uni - 1)}` }, + ], + emoji: '🔟', + }, + functionalContext: 'Descomponer números en decenas y unidades.', + errorType: 'inversion-letra', + }) +} + +// Compare 2-digit numbers +const comparaciones = [ + { a: 15, b: 20 }, + { a: 23, b: 18 }, + { a: 30, b: 25 }, + { a: 42, b: 39 }, + { a: 50, b: 49 }, +] + +for (const { a, b } of comparaciones) { + const mayor = a > b ? a : b + const menor = a < b ? a : b + exercises.push({ + id: `num7-comparar-${a}-${b}`, + stage: 7, + skillCode: 'comparacion-2d', + type: 'eleccion', + prerequisites: [`num7-descomponer-${mayor}`], + content: { + instruction: `¿Cuál número es más grande?`, + text: `${a} vs ${b}`, + audioText: `¿Cuál es más grande?`, + options: [ + { label: String(a), correct: a === mayor, id: String(a) }, + { label: String(b), correct: b === mayor, id: String(b) }, + ], + emoji: '📏', + }, + functionalContext: 'Comparar números de 2 dígitos.', + errorType: 'confusion-letra', + }) +} + +const stage: Stage = { + id: 7, + name: 'Decenas y unidades', + description: 'Componer y descomponer números de 2 dígitos en decenas y unidades. Comparar números.', + exercises, +} + +export default stage diff --git a/curriculum/numeros/etapa-8.ts b/curriculum/numeros/etapa-8.ts new file mode 100644 index 0000000..02212b5 --- /dev/null +++ b/curriculum/numeros/etapa-8.ts @@ -0,0 +1,214 @@ +import type { Stage } from '../types' + +const problemas = [ + { + text: 'Tenés 2 manzanas. Mamá te da 1 más. ¿Cuántas manzanas tenés?', + respuesta: 3, + opciones: [2, 3, 4], + emoji: '🍎', + op: 'suma', + }, + { + text: 'Hay 3 pájaros en el árbol. 1 se va volando. ¿Cuántos quedan?', + respuesta: 2, + opciones: [1, 2, 4], + emoji: '🐦', + op: 'resta', + }, + { + text: 'Tenés 4 galletitas. Te comés 1. ¿Cuántas te quedan?', + respuesta: 3, + opciones: [2, 3, 5], + emoji: '🍪', + op: 'resta', + }, + { + text: 'En el patio hay 2 perros y 3 gatos. ¿Cuántos animales hay?', + respuesta: 5, + opciones: [3, 4, 5], + emoji: '🐕', + op: 'suma', + }, + { + text: 'Tenés 5 lápices. Tu amiga te presta 2 más. ¿Cuántos lápices tenés ahora?', + respuesta: 7, + opciones: [5, 7, 8], + emoji: '✏️', + op: 'suma', + }, + { + text: 'Hay 6 flores en el jardín. Cortás 2 para mamá. ¿Cuántas quedan?', + respuesta: 4, + opciones: [3, 4, 8], + emoji: '🌸', + op: 'resta', + }, + { + text: 'En la mesa hay 3 platos y 3 vasos. ¿Cuántas cosas hay?', + respuesta: 6, + opciones: [5, 6, 9], + emoji: '🍽️', + op: 'suma', + }, + { + text: 'Tenés 7 stickers. Le das 2 a tu hermana. ¿Cuántos te quedan?', + respuesta: 5, + opciones: [4, 5, 9], + emoji: '⭐', + op: 'resta', + }, + { + text: 'Compraste 8 globos. 3 se explotan. ¿Cuántos globos quedan?', + respuesta: 5, + opciones: [3, 5, 11], + emoji: '🎈', + op: 'resta', + }, + { + text: 'En la pecera hay 4 peces naranjas y 2 azules. ¿Cuántos peces hay?', + respuesta: 6, + opciones: [4, 6, 8], + emoji: '🐠', + op: 'suma', + }, + { + text: 'Tenés 9 bloques. Usás 4 para hacer una torre. ¿Cuántos sobran?', + respuesta: 5, + opciones: [4, 5, 13], + emoji: '🧱', + op: 'resta', + }, + { + text: 'En tu plato hay 5 frutillas y 3 uvas. ¿Cuántas frutas tenés?', + respuesta: 8, + opciones: [5, 8, 15], + emoji: '🍓', + op: 'suma', + }, + { + text: 'Hay 10 libros en el estante. Sacás 4 para leer. ¿Cuántos quedan?', + respuesta: 6, + opciones: [4, 6, 14], + emoji: '📚', + op: 'resta', + }, + { + text: 'Tenés 2 manos. Cada mano tiene 5 dedos. ¿Cuántos dedos tenés en total?', + respuesta: 10, + opciones: [5, 7, 10], + emoji: '🖐️', + op: 'suma', + }, + { + text: 'Compartís 6 caramelos con tu amiga. Le das la mitad. ¿Cuántos te quedan?', + respuesta: 3, + opciones: [2, 3, 6], + emoji: '🍬', + op: 'resta', + }, + { + text: 'Hay 7 días en la semana. Ya pasaron 3. ¿Cuántos días quedan?', + respuesta: 4, + opciones: [3, 4, 10], + emoji: '📅', + op: 'resta', + }, + { + text: 'Viste 3 mariquitas en una hoja y 2 en otra. ¿Cuántas viste?', + respuesta: 5, + opciones: [3, 5, 6], + emoji: '🐞', + op: 'suma', + }, + { + text: 'Tenés 4 monedas. Encontrás 3 más en tu bolsillo. ¿Cuántas tenés?', + respuesta: 7, + opciones: [4, 7, 12], + emoji: '🪙', + op: 'suma', + }, + { + text: 'Son las 3 de la tarde. Pasaron 2 horas. ¿Qué hora es?', + respuesta: 5, + opciones: [1, 5, 6], + emoji: '🕐', + op: 'suma', + }, + { + text: 'El nene tiene 8 años. La nena tiene 3 años menos. ¿Cuántos años tiene la nena?', + respuesta: 5, + opciones: [3, 5, 11], + emoji: '👶', + op: 'resta', + }, + { + text: 'En la granja hay 2 caballos, 3 vacas y 1 cerdo. ¿Cuántos animales?', + respuesta: 6, + opciones: [4, 6, 7], + emoji: '🐴', + op: 'suma', + }, + { + text: 'Papá horneó 12 galletitas. Te comiste 2. ¿Cuántas quedan?', + respuesta: 10, + opciones: [8, 10, 14], + emoji: '🍪', + op: 'resta', + }, + { + text: 'Un tren tiene 4 vagones rojos y 4 azules. ¿Cuántos vagones tiene?', + respuesta: 8, + opciones: [4, 8, 16], + emoji: '🚂', + op: 'suma', + }, + { + text: 'Tenés 5 años. Cuando cumplas 5 más, ¿cuántos vas a tener?', + respuesta: 10, + opciones: [5, 10, 15], + emoji: '🎂', + op: 'suma', + }, + { + text: 'El árbol tiene 10 manzanas. Caen 3. ¿Cuántas manzanas quedan en el árbol?', + respuesta: 7, + opciones: [3, 7, 13], + emoji: '🍎', + op: 'resta', + }, +] + +const exercises: any[] = [] + +for (let i = 0; i < problemas.length; i++) { + const p = problemas[i] + exercises.push({ + id: `num8-problema-${i + 1}`, + stage: 8, + skillCode: 'problemas-cotidianos', + type: 'problema', + prerequisites: i === 0 ? ['num7-comparar-15-20'] : [`num8-problema-${i}`], + content: { + instruction: 'Escuchá bien el problema', + text: p.text, + audioText: p.text, + emoji: p.emoji, + options: p.opciones.map(o => ({ + label: String(o), + correct: o === p.respuesta, + id: String(o), + })).sort(() => Math.random() - 0.5), + }, + functionalContext: 'Resolver problemas matemáticos de la vida cotidiana.', + errorType: p.op === 'resta' ? 'inversion-letra' : 'discriminacion-auditiva', + }) +} + +const stage: Stage = { + id: 8, + name: 'Problemas de la vida cotidiana', + description: 'Resolver problemas cotidianos que requieren sumar y restar números hasta 12.', + exercises, +} + +export default stage diff --git a/curriculum/types.ts b/curriculum/types.ts new file mode 100644 index 0000000..457a82a --- /dev/null +++ b/curriculum/types.ts @@ -0,0 +1,54 @@ +export type ExerciseType = + | "sensibilizacion" + | "conciencia" + | "trazo" + | "eleccion" + | "emparejar" + | "secuencia" + | "palabra" + | "problema" + | "lectura" + +export type ErrorType = + | "discriminacion-auditiva" + | "confusion-letra" + | "silaba-dificil" + | "omision-letra" + | "inversion-letra" + | null + +export interface ExerciseContent { + instruction: string + text?: string + options?: { label: string; correct: boolean; id?: string }[] + pairs?: { left: string; right: string; id: string }[] + sequence?: string[] + emoji?: string + color?: string + audioText?: string + imageEmoji?: string +} + +export interface Exercise { + id: string + stage: number + skillCode: string + type: ExerciseType + content: ExerciseContent + prerequisites: string[] + errorType?: ErrorType + functionalContext?: string +} + +export interface Stage { + id: number + name: string + description: string + exercises: Exercise[] +} + +export interface TopicCurriculum { + topic: string + name: string + stages: Stage[] +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..e276d1b --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,45 @@ +services: + postgres: + image: postgres:16-alpine + container_name: edueasy-db + restart: unless-stopped + environment: + POSTGRES_DB: edueasy + POSTGRES_USER: edueasy + POSTGRES_PASSWORD: edueasy_pass + volumes: + - edueasy_pgdata:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U edueasy -d edueasy"] + interval: 10s + timeout: 5s + retries: 5 + networks: + - caddy + + app: + build: + context: . + dockerfile: Dockerfile + container_name: edueasy + restart: unless-stopped + depends_on: + postgres: + condition: service_healthy + environment: + DATABASE_URL: "postgresql://edueasy:edueasy_pass@postgres:5432/edueasy?schema=public" + BETTER_AUTH_SECRET: "${BETTER_AUTH_SECRET:-change-me-in-production}" + BETTER_AUTH_URL: "${BETTER_AUTH_URL:-https://mate.cbcren.online}" + NODE_ENV: production + networks: + - caddy + labels: + caddy: mate.cbcren.online + caddy.reverse_proxy: "{{upstreams 3000}}" + +networks: + caddy: + external: true + +volumes: + edueasy_pgdata: diff --git a/dominios-libres.md b/dominios-libres.md new file mode 100644 index 0000000..597be0d --- /dev/null +++ b/dominios-libres.md @@ -0,0 +1,40 @@ +# Dominios Libres para Edueasy + +> Generado: 2026-07-20 +> IP del servidor: `194.163.191.200` + +## Dominios disponibles (sin contenedor activo) + +| Dominio | Ex-servicio | Ideal para | +|---------|-------------|------------| +| `mate.cbcren.online` | math-frontend + math-backend | API, dashboard, web app | +| `manga.cbcren.online` | Kavita (lector manga) | Static site, app web | +| `eco2.cbcren.online` | eco2-app (economía) | App Node.js / web | +| `simulacro.cbcren.online` | simulacro-app (flask) | Python app, web app | + +> **Nota:** `am.cbcren.online` (Open WebUI) y `demo2.cbcren.online` (pymesbot) no están libres — responden 401/307, probablemente con contenedor activo. + +## Cómo usar un dominio + +```bash +# 1. Crear el contenedor conectado a la red caddy +docker run -d --name edueasy-api --network caddy edueasy-image + +# 2. Editar /home/ren/immich/Caddyfile agregando: +# mate.cbcren.online { +# reverse_proxy edueasy-api:3000 +# } + +# 3. Recargar Caddy sin downtime +docker exec caddy-ingress caddy reload --config /etc/caddy/Caddyfile +``` + +## Config existente en Caddy (referencia) + +Cada dominio ya está definido en `/home/ren/immich/Caddyfile`. Solo hay que cambiar el `reverse_proxy` al nuevo contenedor: + +```caddy +mate.cbcren.online { + reverse_proxy nuevo-contenedor:3000 +} +``` diff --git a/e2e/api-curriculum.spec.ts b/e2e/api-curriculum.spec.ts new file mode 100644 index 0000000..bc06f48 --- /dev/null +++ b/e2e/api-curriculum.spec.ts @@ -0,0 +1,71 @@ +import { test, expect } from "@playwright/test" + +test.describe("Curriculum API", () => { + test("TTS endpoint generates audio", async ({ request }) => { + const res = await request.get("/api/tts?text=hola%20mundo") + expect(res.ok()).toBeTruthy() + expect(res.headers()["content-type"]).toBe("audio/wav") + const body = await res.body() + expect(body.length).toBeGreaterThan(1000) + }) + + test("TTS requires text param", async ({ request }) => { + const res = await request.get("/api/tts") + expect(res.status()).toBe(400) + const json = await res.json() + expect(json.error).toContain("text param") + }) + + test("TTS text too long returns 400", async ({ request }) => { + const long = "a".repeat(250) + const res = await request.get(`/api/tts?text=${long}`) + expect(res.status()).toBe(400) + }) + + test("curriculum/next requires childId", async ({ request }) => { + const res = await request.get("/api/curriculum/next") + expect(res.status()).toBe(400) + const json = await res.json() + expect(json.error).toContain("childId") + }) + + test("curriculum/next accepts childId param", async ({ request }) => { + const res = await request.get("/api/curriculum/next?childId=any&topic=lectura") + expect(res.status()).toBe(200) + const json = await res.json() + expect(json).toBeDefined() + }) + + test("curriculum/grade missing fields returns 400", async ({ request }) => { + const res = await request.post("/api/curriculum/grade", { + data: {}, + }) + expect(res.status()).toBe(400) + const json = await res.json() + expect(json.error).toBe("Missing required fields") + }) + + test("curriculum/grade validates required fields", async ({ request }) => { + const res = await request.post("/api/curriculum/grade", { + data: { childId: "test", exerciseId: "ex1", skillCode: "test" }, + headers: { "Content-Type": "application/json" }, + }) + expect(res.status()).toBe(400) + const json = await res.json() + expect(json.error).toBe("No active session") + }) + + test("curriculum/progress requires childId", async ({ request }) => { + const res = await request.get("/api/curriculum/progress") + expect(res.status()).toBe(400) + const json = await res.json() + expect(json.error).toContain("childId") + }) + + test("dashboard/summary requires childId", async ({ request }) => { + const res = await request.get("/api/dashboard/summary") + expect(res.status()).toBe(400) + const json = await res.json() + expect(json.error).toContain("childId") + }) +}) diff --git a/e2e/exercise-content.spec.ts b/e2e/exercise-content.spec.ts new file mode 100644 index 0000000..6ab6efb --- /dev/null +++ b/e2e/exercise-content.spec.ts @@ -0,0 +1,78 @@ +import { test, expect } from "@playwright/test" +import { readFileSync } from "fs" +import { join } from "path" + +const lecturaStages = 9 +const numerosStages = 8 + +test.describe("Exercise content integrity", () => { + for (let i = 1; i <= lecturaStages; i++) { + test(`lectura etapa ${i} file exists and has exercises`, () => { + const file = join(process.cwd(), "curriculum", "lectura", `etapa-${i}.ts`) + const content = readFileSync(file, "utf-8") + expect(content.length).toBeGreaterThan(200) + expect(content).toContain("stage") + expect(content).toContain("exercises") + }) + } + + for (let i = 1; i <= numerosStages; i++) { + test(`numeros etapa ${i} file exists and has exercises`, () => { + const file = join(process.cwd(), "curriculum", "numeros", `etapa-${i}.ts`) + const content = readFileSync(file, "utf-8") + expect(content.length).toBeGreaterThan(200) + expect(content).toContain("stage") + expect(content).toContain("exercises") + }) + } + + test("curriculum index imports all stages via loadStages", () => { + const file = join(process.cwd(), "curriculum", "index.ts") + const content = readFileSync(file, "utf-8") + expect(content).toContain("initCurriculum") + expect(content).toContain("loadStages") + expect(content).toContain("[1, 2, 3, 4, 5, 6, 7, 8, 9]") + }) + + test("type definitions export required types", () => { + const file = join(process.cwd(), "curriculum", "types.ts") + const content = readFileSync(file, "utf-8") + expect(content).toContain("export type Exercise") + expect(content).toContain("export interface Stage") + expect(content).toContain("export type ExerciseType") + expect(content).toContain("export type ErrorType") + }) + + test("exercise dispatcher maps all exercise types", () => { + const file = join(process.cwd(), "components", "exercises", "exercise-dispatcher.tsx") + const content = readFileSync(file, "utf-8") + const types = ["sensibilizacion", "conciencia", "trazo", "eleccion", "emparejar", "secuencia", "palabra", "problema", "lectura"] + for (const t of types) { + expect(content).toContain(t) + } + }) + + test("all exercise component files exist", () => { + const components = [ + "ejercicio-sensibilizacion", + "ejercicio-conciencia", + "ejercicio-eleccion", + "ejercicio-secuencia", + "ejercicio-palabra", + "ejercicio-lectura", + "ejercicio-trazo", + "exercise-dispatcher", + ] + for (const c of components) { + const file = join(process.cwd(), "components", "exercises", `${c}.tsx`) + const content = readFileSync(file, "utf-8") + expect(content.length).toBeGreaterThan(100) + } + }) + + test("TTS route exists", () => { + const file = join(process.cwd(), "app", "api", "tts", "route.ts") + const content = readFileSync(file, "utf-8") + expect(content).toContain("espeak-ng") + }) +}) diff --git a/e2e/pairing-flow.spec.ts b/e2e/pairing-flow.spec.ts new file mode 100644 index 0000000..30bf0f8 --- /dev/null +++ b/e2e/pairing-flow.spec.ts @@ -0,0 +1,50 @@ +import { test, expect } from "@playwright/test" + +async function dismissAudioUnlock(page: any) { + const btn = page.getByRole("button", { name: /tocá/i }) + if (await btn.isVisible({ timeout: 2000 }).catch(() => false)) { + await btn.click() + await page.waitForTimeout(1200) + } +} + +test.describe("Pairing flow", () => { + + test("pairing page loads form with code input", async ({ page }) => { + await page.goto("/child/pairing", { waitUntil: "networkidle", timeout: 15000 }) + await dismissAudioUnlock(page) + await expect(page.getByPlaceholder("Código")).toBeVisible({ timeout: 10000 }) + }) + + test("pairing page has submit button", async ({ page }) => { + await page.goto("/child/pairing", { waitUntil: "networkidle", timeout: 15000 }) + await dismissAudioUnlock(page) + await expect(page.getByRole("button", { name: "Listo" })).toBeVisible({ timeout: 10000 }) + }) + + test("pairing code input accepts text", async ({ page }) => { + await page.goto("/child/pairing", { waitUntil: "networkidle", timeout: 15000 }) + await dismissAudioUnlock(page) + const input = page.getByPlaceholder("Código") + await input.fill("ABCD1234") + await expect(input).toHaveValue("ABCD1234") + }) + + test("lectura page shows pairing message when not paired", async ({ page }) => { + await page.goto("/child/lectura", { waitUntil: "networkidle", timeout: 15000 }) + await dismissAudioUnlock(page) + await expect(page.getByText("emparejar", { exact: false }).first()).toBeVisible({ timeout: 10000 }) + }) + + test("numeros page shows pairing message when not paired", async ({ page }) => { + await page.goto("/child/numeros", { waitUntil: "networkidle", timeout: 15000 }) + await dismissAudioUnlock(page) + await expect(page.getByText("emparejar", { exact: false }).first()).toBeVisible({ timeout: 10000 }) + }) + + test("lectura page has ir a emparejar button", async ({ page }) => { + await page.goto("/child/lectura", { waitUntil: "networkidle", timeout: 15000 }) + await dismissAudioUnlock(page) + await expect(page.getByRole("button", { name: /emparejar/i })).toBeVisible({ timeout: 10000 }) + }) +}) diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..0e1a156 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,14 @@ +import { dirname } from "path" +import { fileURLToPath } from "url" +import { FlatCompat } from "@eslint/eslintrc" + +const __filename = fileURLToPath(import.meta.url) +const __dirname = dirname(__filename) + +const compat = new FlatCompat({ baseDirectory: __dirname }) + +const eslintConfig = [ + ...compat.extends("next/core-web-vitals"), +] + +export default eslintConfig diff --git a/lib/auth-client.ts b/lib/auth-client.ts new file mode 100644 index 0000000..cba42e1 --- /dev/null +++ b/lib/auth-client.ts @@ -0,0 +1,9 @@ +"use client" + +import { createAuthClient } from "better-auth/react" + +export const authClient = createAuthClient({ + baseURL: process.env.NEXT_PUBLIC_APP_URL || "http://localhost:3000", +}) + +export const { signIn, signUp, useSession } = authClient diff --git a/lib/auth.ts b/lib/auth.ts new file mode 100644 index 0000000..1d76528 --- /dev/null +++ b/lib/auth.ts @@ -0,0 +1,31 @@ +import { betterAuth } from "better-auth" +import { prismaAdapter } from "better-auth/adapters/prisma" +import { prisma } from "@/lib/db" + +export const auth = betterAuth({ + database: prismaAdapter(prisma, { + provider: "postgresql", + }), + emailAndPassword: { + enabled: true, + }, + user: { + modelName: "Parent", + }, + session: { + modelName: "Session", + }, + databaseHooks: { + user: { + create: { + after: async (user) => { + const family = await prisma.family.create({ data: { name: "" } }) + await prisma.parent.update({ + where: { id: user.id }, + data: { familyId: family.id }, + }) + }, + }, + }, + }, +}) diff --git a/lib/curriculum/engine.ts b/lib/curriculum/engine.ts new file mode 100644 index 0000000..032e613 --- /dev/null +++ b/lib/curriculum/engine.ts @@ -0,0 +1,124 @@ +import { prisma } from "@/lib/db" +import { initCurriculum, getLecturaStages, getNumerosStages, getAllLecturaExercises } from "@/curriculum/index" +import type { Exercise } from "@/curriculum/types" + +const STAGE_THRESHOLD = 0.8 + +async function ensureInitialStage(childId: string, topic: string) { + try { + const exists = await prisma.curriculumProgress.findFirst({ + where: { childId, topic }, + }) + if (!exists) { + await prisma.curriculumProgress.create({ + data: { childId, topic, stage: 1 }, + }) + } + } catch { + // Child may not exist yet in FK constraint — proceed gracefully + } +} + +export async function getCurrentStage(childId: string, topic: string) { + await ensureInitialStage(childId, topic) + const progress = await prisma.curriculumProgress.findFirst({ + where: { childId, topic }, + orderBy: { stage: "asc" }, + }) + return progress +} + +export async function getNextExercise( + childId: string, + topic: "lectura" | "numeros", +): Promise { + await initCurriculum() + await ensureInitialStage(childId, topic) + + const progress = await prisma.curriculumProgress.findFirst({ + where: { childId, topic, completedAt: null }, + orderBy: { stage: "asc" }, + }) + + if (!progress) return null + + const stages = topic === "lectura" ? getLecturaStages() : getNumerosStages() + const stage = stages[progress.stage] + if (!stage || !stage.exercises.length) return null + + const allAttemps = await prisma.skillAttempt.findMany({ + where: { exerciseId: { not: null }, sessionLog: { childId } }, + select: { exerciseId: true, correct: true }, + }) + + const mastered = new Set( + allAttemps + .filter((a) => a.correct) + .map((a) => a.exerciseId), + ) + + const attempted = new Set(allAttemps.map((a) => a.exerciseId)) + + const available = stage.exercises.filter((ex) => { + if (mastered.has(ex.id)) return false + const prereqsMet = ex.prerequisites.every((p) => mastered.has(p)) + return prereqsMet + }) + + if (available.length === 0) { + if (attempted.size > 0 && stage.exercises.length > 0) { + const masteryRatio = mastered.size / stage.exercises.length + if (masteryRatio >= STAGE_THRESHOLD) { + await advanceStage(childId, topic, progress.stage) + return getNextExercise(childId, topic) + } + } + return null + } + + const fsrsCards = await prisma.fsrsCard.findMany({ + where: { childId, skillCode: { in: available.map((e) => e.skillCode) } }, + }) + + const dueMap = new Map(fsrsCards.map((c) => [c.skillCode, c.dueAt.getTime()])) + const now = Date.now() + + const unsorted = [...available] + unsorted.sort((a, b) => { + const dueA = dueMap.get(a.skillCode) ?? 0 + const dueB = dueMap.get(b.skillCode) ?? 0 + const isDueA = dueA <= now ? 0 : 1 + const isDueB = dueB <= now ? 0 : 1 + if (isDueA !== isDueB) return isDueA - isDueB + if (!attempted.has(a.id) && !attempted.has(b.id)) return 0 + if (!attempted.has(a.id)) return -1 + if (!attempted.has(b.id)) return 1 + return dueA - dueB + }) + + return unsorted[0] || null +} + +async function advanceStage(childId: string, topic: string, currentStage: number) { + await prisma.curriculumProgress.updateMany({ + where: { childId, topic, stage: currentStage }, + data: { completedAt: new Date() }, + }) + const nextStage = currentStage + 1 + const exists = await prisma.curriculumProgress.findUnique({ + where: { childId_topic_stage: { childId, topic, stage: nextStage } }, + }) + if (!exists) { + await prisma.curriculumProgress.create({ + data: { childId, topic, stage: nextStage }, + }) + } +} + +export function getErrorTypeForExercise( + exercise: Exercise, + correct: boolean, +): string | null { + if (correct) return null + return exercise.errorType || "discriminacion-auditiva" +} diff --git a/lib/db.ts b/lib/db.ts new file mode 100644 index 0000000..17cca96 --- /dev/null +++ b/lib/db.ts @@ -0,0 +1,9 @@ +import { PrismaClient } from "@prisma/client" + +const globalForPrisma = globalThis as unknown as { + prisma: PrismaClient | undefined +} + +export const prisma = globalForPrisma.prisma ?? new PrismaClient() + +if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma diff --git a/lib/fsrs.ts b/lib/fsrs.ts new file mode 100644 index 0000000..59da7d1 --- /dev/null +++ b/lib/fsrs.ts @@ -0,0 +1,50 @@ +import { fsrs as createFSRS, createEmptyCard, Rating, type Card, type Grade } from "ts-fsrs" + +const scheduler = createFSRS({ maximum_interval: 365, request_retention: 0.9 }) + +export type FsrsGrade = "again" | "hard" | "good" | "easy" + +const gradeMap: Record = { + again: Rating.Again, + hard: Rating.Hard, + good: Rating.Good, + easy: Rating.Easy, +} + +export function buildFsrsCard(params: { + stability?: number + difficulty?: number + reps?: number + lapses?: number + due?: Date +}): Card { + const card = createEmptyCard(params.due ?? new Date()) + return { + ...card, + stability: params.stability ?? card.stability, + difficulty: params.difficulty ?? card.difficulty, + reps: params.reps ?? 0, + lapses: params.lapses ?? 0, + due: params.due ?? card.due, + } +} + +export function gradeCard(card: Card, grade: FsrsGrade, now: Date = new Date()) { + const result = scheduler.next(card, now, gradeMap[grade]) + return { + card: result.card, + log: result.log, + } +} + +export function getRetrievability(card: Card, now: Date = new Date()): number { + const r = scheduler.get_retrievability(card, now, false) + return typeof r === "number" ? r : parseFloat(r) +} + +export function skillCodeFromGrade(correct: boolean, responseMs: number): FsrsGrade { + if (!correct) return "again" + if (responseMs > 8000) return "hard" + if (responseMs > 4000) return "good" + return "easy" +} diff --git a/lib/pedagogia/borel-maisonny.ts b/lib/pedagogia/borel-maisonny.ts new file mode 100644 index 0000000..919d827 --- /dev/null +++ b/lib/pedagogia/borel-maisonny.ts @@ -0,0 +1,67 @@ +export interface Fonema { + letra: string + fonema: string + palabra: string + imageEmoji: string + gesto: string // description of Borel-Maisonny gesture + color: string + orden: number +} + +// Vocales first (Jolly Phonics order adapted for Spanish) +export const vocales: Fonema[] = [ + { + letra: "a", + fonema: "a", + palabra: "avión", + imageEmoji: "✈️", + gesto: "Abrir la mano como si saludaras, con los dedos juntos.", + color: "#E74C3C", + orden: 1, + }, + { + letra: "e", + fonema: "e", + palabra: "elefante", + imageEmoji: "🐘", + gesto: "Señalar hacia la derecha con la mano abierta.", + color: "#3498DB", + orden: 2, + }, + { + letra: "i", + fonema: "i", + palabra: "iglú", + imageEmoji: "🏔️", + gesto: "Señalar hacia arriba con el dedo índice.", + color: "#9B59B6", + orden: 3, + }, + { + letra: "o", + fonema: "o", + palabra: "oso", + imageEmoji: "🐻", + gesto: "Hacer un círculo con la mano frente a la boca.", + color: "#F39C12", + orden: 4, + }, + { + letra: "u", + fonema: "u", + palabra: "uva", + imageEmoji: "🍇", + gesto: "Estirar los dos brazos hacia adelante como un tubo.", + color: "#1ABC9C", + orden: 5, + }, +] + +export function getFonema(letra: string): Fonema | undefined { + return vocales.find((v) => v.letra === letra) +} + +export function getGestoDescription(letra: string): string { + const f = getFonema(letra) + return f?.gesto || "" +} diff --git a/lib/pedagogia/cpa-progression.ts b/lib/pedagogia/cpa-progression.ts new file mode 100644 index 0000000..b2b82a7 --- /dev/null +++ b/lib/pedagogia/cpa-progression.ts @@ -0,0 +1,56 @@ +export type CPAStage = "concrete" | "pictoric" | "abstract" + +export type GalperinStage = "hand" | "external_speech" | "inner_speech" | "mental" | "mastered" + +export interface CPAState { + stage: CPAStage + currentValue: number + attempts: number + mastered: boolean + galperinStage: GalperinStage +} + +export function getCPAProgression(skillValue: number): CPAStage[] { + return ["concrete", "pictoric", "abstract"] +} + +export function createCPAState(value: number): CPAState { + return { + stage: "concrete", + currentValue: value, + attempts: 0, + mastered: false, + galperinStage: "hand", + } +} + +export function advanceStage(state: CPAState): CPAState { + const stages: CPAStage[] = ["concrete", "pictoric", "abstract"] + const currentIdx = stages.indexOf(state.stage) + if (currentIdx < stages.length - 1) { + return { ...state, stage: stages[currentIdx + 1], galperinStage: "hand" } + } + return { ...state, mastered: true } +} + +export function advanceGalperin(stage: GalperinStage): GalperinStage { + const order: GalperinStage[] = ["hand", "external_speech", "inner_speech", "mental", "mastered"] + const idx = order.indexOf(stage) + if (idx < order.length - 1) return order[idx + 1] + return "mastered" +} + +export function getGalperinInstruction(stage: GalperinStage, value: number): string { + switch (stage) { + case "hand": + return `Tocá ${value} cosas con tu dedo` + case "external_speech": + return "Contá en voz alta mientras tocás" + case "inner_speech": + return "Ahora contá susurrando" + case "mental": + return "Pensá el número en tu cabeza y señalalo" + case "mastered": + return "¡Ya sabés este número!" + } +} diff --git a/lib/pedagogia/cuisenaire.ts b/lib/pedagogia/cuisenaire.ts new file mode 100644 index 0000000..c2edcc5 --- /dev/null +++ b/lib/pedagogia/cuisenaire.ts @@ -0,0 +1,47 @@ +export interface Rod { + value: number + color: string + lengthPx: number + label: string +} + +export const rodColors: Record = { + 1: "#FFFFFF", + 2: "#E74C3C", + 3: "#2ECC71", + 4: "#E91E63", + 5: "#F1C40F", + 6: "#1ABC9C", + 7: "#2C3E50", + 8: "#3498DB", + 9: "#9B59B6", + 10: "#E67E22", +} + +const rodLengths: Record = { + 1: 24, + 2: 44, + 3: 64, + 4: 84, + 5: 104, + 6: 124, + 7: 144, + 8: 164, + 9: 184, + 10: 204, +} + +export function getRods(maxValue: number = 10): Rod[] { + return Array.from({ length: maxValue }, (_, i) => ({ + value: i + 1, + color: rodColors[i + 1], + lengthPx: rodLengths[i + 1], + label: `${i + 1}`, + })) +} + +export function compareRods(a: number, b: number): "mayor" | "menor" | "igual" { + if (a > b) return "mayor" + if (a < b) return "menor" + return "igual" +} diff --git a/lib/pedagogia/errorless.ts b/lib/pedagogia/errorless.ts new file mode 100644 index 0000000..0054a06 --- /dev/null +++ b/lib/pedagogia/errorless.ts @@ -0,0 +1,63 @@ +export type PromptLevel = 0 | 1 | 2 | 3 | 4 + +// Galperin stages mapped to prompt levels +export const GALPERIN_STAGES = { + HAND: 0, // Concrete: full model, show the answer + EXTERNAL_SPEECH: 1, // Prompts the child to say out loud + INNER_SPEECH: 2, // Partial prompt, whisper + MENTAL: 3, // Verbal cue only + MASTERED: 4, // No prompt +} as const + +export interface PromptState { + level: PromptLevel + consecutiveCorrect: number + consecutiveIncorrect: number +} + +export function getInitialState(): PromptState { + return { + level: 0, + consecutiveCorrect: 0, + consecutiveIncorrect: 0, + } +} + +export function evaluateResponse( + state: PromptState, + correct: boolean, + masterThreshold: number = 3, + regressThreshold: number = 2, +): PromptState { + if (correct) { + const newCorrect = state.consecutiveCorrect + 1 + const newLevel = + newCorrect >= masterThreshold + ? (Math.min(state.level + 1, 4) as PromptLevel) + : state.level + return { + level: newLevel, + consecutiveCorrect: newCorrect, + consecutiveIncorrect: 0, + } + } + + const newIncorrect = state.consecutiveIncorrect + 1 + const newLevel = + newIncorrect >= regressThreshold + ? (Math.max(state.level - 1, 0) as PromptLevel) + : state.level + return { + level: newLevel, + consecutiveCorrect: 0, + consecutiveIncorrect: newIncorrect, + } +} + +export function shouldShowPrompt(level: PromptLevel): boolean { + return level < 3 +} + +export function isMastered(level: PromptLevel): boolean { + return level >= 4 +} diff --git a/lib/session-client.ts b/lib/session-client.ts new file mode 100644 index 0000000..09f53f3 --- /dev/null +++ b/lib/session-client.ts @@ -0,0 +1,53 @@ +"use client" + +export interface SkillAttemptPayload { + skillCode: string + promptLevel: number + correct: boolean + responseMs: number +} + +export interface SessionPayload { + childId: string + startedAt: string + endedAt: string + durationSec: number + skillsPracticed: string + attempts: SkillAttemptPayload[] +} + +export async function syncSession(payload: SessionPayload): Promise { + try { + const res = await fetch("/api/sessions/sync", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + childId: payload.childId, + session: { + startedAt: payload.startedAt, + endedAt: payload.endedAt, + durationSec: payload.durationSec, + skillsPracticed: payload.skillsPracticed, + }, + attempts: payload.attempts, + }), + }) + const data = await res.json() + return data.sessionId ?? null + } catch { + return null + } +} + +export async function createMilestone(childId: string, skillCode: string): Promise { + try { + const res = await fetch("/api/milestones", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ childId, skillCode }), + }) + return res.ok + } catch { + return false + } +} diff --git a/lib/speech.ts b/lib/speech.ts new file mode 100644 index 0000000..0a61ee3 --- /dev/null +++ b/lib/speech.ts @@ -0,0 +1,29 @@ +"use client" + +let utterance: SpeechSynthesisUtterance | null = null + +export async function speak( + text: string, + _rate = 0.85, +): Promise { + return new Promise((resolve) => { + stopSpeaking() + + const u = new SpeechSynthesisUtterance(text) + u.lang = "es-AR" + u.rate = _rate + + u.onend = () => resolve() + u.onerror = () => resolve() + + utterance = u + speechSynthesis.speak(u) + }) +} + +export function stopSpeaking(): void { + if (utterance) { + speechSynthesis.cancel() + utterance = null + } +} diff --git a/lib/utils.ts b/lib/utils.ts new file mode 100644 index 0000000..bd0c391 --- /dev/null +++ b/lib/utils.ts @@ -0,0 +1,6 @@ +import { clsx, type ClassValue } from "clsx" +import { twMerge } from "tailwind-merge" + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)) +} diff --git a/middleware.ts b/middleware.ts new file mode 100644 index 0000000..d825cfc --- /dev/null +++ b/middleware.ts @@ -0,0 +1,55 @@ +import { NextResponse } from "next/server" +import type { NextRequest } from "next/server" + +const CHILD_HOST = "mate" +const PARENT_HOST = "simulacro" +const isDev = process.env.NODE_ENV === "development" + +export function middleware(request: NextRequest) { + const hostname = request.headers.get("host") || "" + const { pathname } = request.nextUrl + + if ( + pathname.startsWith("/api") || + pathname.startsWith("/_next") || + pathname.startsWith("/static") || + pathname === "/favicon.ico" + ) { + return NextResponse.next() + } + + if (isDev) { + if (pathname.startsWith("/child") || pathname.startsWith("/parent")) { + return NextResponse.next() + } + const url = request.nextUrl.clone() + url.pathname = "/child" + return NextResponse.rewrite(url) + } + + if (hostname.includes(CHILD_HOST)) { + if (pathname === "/" || pathname.startsWith("/child")) { + return NextResponse.next() + } + const url = request.nextUrl.clone() + url.pathname = `/child${pathname === "/" ? "" : pathname}` + return NextResponse.rewrite(url) + } + + if (hostname.includes(PARENT_HOST)) { + if (pathname === "/" || pathname.startsWith("/parent")) { + return NextResponse.next() + } + const url = request.nextUrl.clone() + url.pathname = `/parent${pathname === "/" ? "" : pathname}` + return NextResponse.rewrite(url) + } + + const url = request.nextUrl.clone() + url.pathname = "/child" + return NextResponse.rewrite(url) +} + +export const config = { + matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"], +} diff --git a/next.config.ts b/next.config.ts new file mode 100644 index 0000000..f2f1261 --- /dev/null +++ b/next.config.ts @@ -0,0 +1,8 @@ +import type { NextConfig } from "next" + +const nextConfig: NextConfig = { + output: "standalone", + images: { unoptimized: true }, +} + +export default nextConfig diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..c4de66c --- /dev/null +++ b/package-lock.json @@ -0,0 +1,7681 @@ +{ + "name": "edueasy", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "edueasy", + "version": "0.1.0", + "dependencies": { + "@prisma/client": "^5.20.0", + "@radix-ui/react-avatar": "^1.2.3", + "@radix-ui/react-label": "^2.1.12", + "@radix-ui/react-progress": "^1.1.13", + "@radix-ui/react-slot": "^1.1.0", + "@radix-ui/react-tabs": "^1.1.18", + "@use-gesture/react": "^10.3.0", + "better-auth": "^1.0.0", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", + "framer-motion": "^11.0.0", + "lucide-react": "^0.400.0", + "next": "^15.0.0", + "perfect-freehand": "^1.2.0", + "prisma": "^5.20.0", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "recharts": "^2.12.0", + "tailwind-merge": "^2.5.0", + "tailwindcss-animate": "^1.0.7", + "ts-fsrs": "^4.0.0" + }, + "devDependencies": { + "@playwright/test": "^1.61.1", + "@types/node": "^20.0.0", + "@types/react": "^19.0.0", + "@types/react-dom": "^19.0.0", + "autoprefixer": "^10.5.4", + "eslint": "^8.57.0", + "eslint-config-next": "^15.0.0", + "postcss": "^8.4.0", + "tailwindcss": "^3.4.0", + "typescript": "^5.6.0" + } + }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@better-auth/core": { + "version": "1.6.23", + "resolved": "https://registry.npmjs.org/@better-auth/core/-/core-1.6.23.tgz", + "integrity": "sha512-beEhOs0uVeOxYOZKUfIEBd/nQV2Bd4/6wyLxZ0OFkn6CMTK2Vi+hXuZLnyPBeB6RdHpebEoJWiHqwHxBIxgPDQ==", + "license": "MIT", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.39.0", + "@standard-schema/spec": "^1.1.0", + "zod": "^4.3.6" + }, + "peerDependencies": { + "@better-auth/utils": "0.4.2", + "@better-fetch/fetch": "1.3.1", + "@cloudflare/workers-types": ">=4", + "@opentelemetry/api": "^1.9.0", + "better-call": "1.3.7", + "jose": "^6.1.0", + "kysely": "^0.28.5 || ^0.29.0", + "nanostores": "^1.0.1" + }, + "peerDependenciesMeta": { + "@cloudflare/workers-types": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + } + } + }, + "node_modules/@better-auth/drizzle-adapter": { + "version": "1.6.23", + "resolved": "https://registry.npmjs.org/@better-auth/drizzle-adapter/-/drizzle-adapter-1.6.23.tgz", + "integrity": "sha512-2+/PTVfIP9E7iz6af8TB3lhnowHUj9ljC66kECmHaFEdUqPgzHoWux9epotKwO7XDg2ui4ttWQ8CMeNFLvQeKQ==", + "license": "MIT", + "peerDependencies": { + "@better-auth/core": "^1.6.23", + "@better-auth/utils": "0.4.2", + "drizzle-orm": "^0.45.2" + }, + "peerDependenciesMeta": { + "drizzle-orm": { + "optional": true + } + } + }, + "node_modules/@better-auth/kysely-adapter": { + "version": "1.6.23", + "resolved": "https://registry.npmjs.org/@better-auth/kysely-adapter/-/kysely-adapter-1.6.23.tgz", + "integrity": "sha512-zbNJsMbG09exfkGyvFqBLLqWoMPAUWjxCuUnEK5AsjbYoZeIjj/QGZgdf4CapVWryKxjA9Q6Jlr6fbiPpC3VAg==", + "license": "MIT", + "peerDependencies": { + "@better-auth/core": "^1.6.23", + "@better-auth/utils": "0.4.2", + "kysely": "^0.28.17 || ^0.29.0" + }, + "peerDependenciesMeta": { + "kysely": { + "optional": true + } + } + }, + "node_modules/@better-auth/memory-adapter": { + "version": "1.6.23", + "resolved": "https://registry.npmjs.org/@better-auth/memory-adapter/-/memory-adapter-1.6.23.tgz", + "integrity": "sha512-krIiR0pIVkaKlAzm690n5bcMW4NGbqeMg0HQSD9fz/KcQF/eWLqcq9gG/BhHTj2i/y96qH+W5JWPmaSOS5iTgQ==", + "license": "MIT", + "peerDependencies": { + "@better-auth/core": "^1.6.23", + "@better-auth/utils": "0.4.2" + } + }, + "node_modules/@better-auth/mongo-adapter": { + "version": "1.6.23", + "resolved": "https://registry.npmjs.org/@better-auth/mongo-adapter/-/mongo-adapter-1.6.23.tgz", + "integrity": "sha512-7+QdevitGlKBbP6JbiSk5SBnzPsKV/mDrQBGBn8hwByQLeJwqpqbuBPw7ZI8vzUlFfAAnyFiqwP3Eb8mxnp7pA==", + "license": "MIT", + "peerDependencies": { + "@better-auth/core": "^1.6.23", + "@better-auth/utils": "0.4.2", + "mongodb": "^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "mongodb": { + "optional": true + } + } + }, + "node_modules/@better-auth/prisma-adapter": { + "version": "1.6.23", + "resolved": "https://registry.npmjs.org/@better-auth/prisma-adapter/-/prisma-adapter-1.6.23.tgz", + "integrity": "sha512-2qSdzidq4tkb1eS5TTqb4Nzg0mdZWm3Qky9SYeXeb8PpVQbC2sxqJhEM5mK7y12uU6I8hc64wO9f7AFVNL+6UQ==", + "license": "MIT", + "peerDependencies": { + "@better-auth/core": "^1.6.23", + "@better-auth/utils": "0.4.2", + "@prisma/client": "^5.0.0 || ^6.0.0 || ^7.0.0", + "prisma": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "@prisma/client": { + "optional": true + }, + "prisma": { + "optional": true + } + } + }, + "node_modules/@better-auth/telemetry": { + "version": "1.6.23", + "resolved": "https://registry.npmjs.org/@better-auth/telemetry/-/telemetry-1.6.23.tgz", + "integrity": "sha512-/R2Kb+z2BpDOOWwVHqOk+c0VNpuwfCv4Hp5Yr9003WIZPax/zyNraGLB9CFE8qF2gZW8Dsz419k4I8CPrGzpDA==", + "license": "MIT", + "peerDependencies": { + "@better-auth/core": "^1.6.23", + "@better-auth/utils": "0.4.2", + "@better-fetch/fetch": "1.3.1" + } + }, + "node_modules/@better-auth/utils": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@better-auth/utils/-/utils-0.4.2.tgz", + "integrity": "sha512-AUxrvu+HaaODsUyzDxFgwd/8RZ1yZaYo42LXKSrU2oGgR38pS1ij8nqQKNgtTWoYGpNevNXtCfgTy6loHveW9A==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "^2.0.1" + } + }, + "node_modules/@better-fetch/fetch": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@better-fetch/fetch/-/fetch-1.3.1.tgz", + "integrity": "sha512-ABkD1WhyfPZprKRQI3bhATjeiFuNWC9PXhfGWqL+sg/gKrM977oFrYkdb4msM3hgUGonr7KlOsOFT5TU2rht9g==", + "license": "MIT" + }, + "node_modules/@emnapi/core": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.2.tgz", + "integrity": "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/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/eslintrc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.6.0", + "globals": "^13.19.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": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", + "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", + "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", + "deprecated": "Use @eslint/config-array instead", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.3", + "debug": "^4.3.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.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/object-schema": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", + "integrity": "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", + "integrity": "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", + "integrity": "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", + "integrity": "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", + "integrity": "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", + "integrity": "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", + "integrity": "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", + "integrity": "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==", + "cpu": [ + "riscv64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", + "integrity": "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", + "integrity": "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", + "integrity": "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", + "integrity": "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", + "integrity": "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", + "integrity": "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", + "integrity": "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", + "integrity": "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", + "integrity": "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.2.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", + "integrity": "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", + "integrity": "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", + "integrity": "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", + "integrity": "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.7.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", + "integrity": "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", + "integrity": "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", + "integrity": "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz", + "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.3" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, + "node_modules/@next/env": { + "version": "15.5.20", + "resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.20.tgz", + "integrity": "sha512-dXh51Wvddf8daEyBXryZZEe1FdVxEWx9lgaTseLZUtC1XP/W8Wri+Z+VPOElHlByk23CyqHdc2oVByX7wsTWsw==", + "license": "MIT" + }, + "node_modules/@next/eslint-plugin-next": { + "version": "15.5.20", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-15.5.20.tgz", + "integrity": "sha512-MZUgFpVd9rGSZpb8bNceUWvkAZe6aQw/6h2SSqHQuYzKfaiEUEVPIO6mXqaBmiBEBSN1f1sOc1uV8GCM90oegg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "3.3.1" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "15.5.20", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.20.tgz", + "integrity": "sha512-in0yXG7/pRBVjWeEl7f7ZZETpletSMFKXVS4GJgHENTPVrJFNJKPrYewa9rpZcvdjwFece5fZP0CK34G4PxowA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "15.5.20", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.20.tgz", + "integrity": "sha512-0hsFshdPnTzGJdDTHeHJ+XPUShOpnyp9pUFDwDhqctsA0Cd8NcIVGRPtptYhgYY9DjkKgCDRkXxmgRc+CgT5Wg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "15.5.20", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.20.tgz", + "integrity": "sha512-DMvkoBtAABOzE6pMZRW/xNm7sKqql3wzzzZJ1R/d/rp4BCxv6LykouD3tHjGY8WdQqGpZs11t+R9AtjPxvvljw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "15.5.20", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.20.tgz", + "integrity": "sha512-RQmDfeYBtXV2FSId7dfA1hE6M/T6+g7wdbYnFQ47tw/gUBwV+CccLVejNmCGa9yLDitk83foeg8hl/3DjfYQ5g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "15.5.20", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.20.tgz", + "integrity": "sha512-DkWLEdKajJwdGt27M3i1VEO2kelTvZrK6Pcb7JvW2BY+nofWm7FBsBNDj7g7Pr1NuQ5PLJvqEqYa20GTsBDnKQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "15.5.20", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.20.tgz", + "integrity": "sha512-rAO5b7pKHvX+ExdmJskusDXTNbiNZfptifIPZItbUx+AOXxxTydVBsPt7Oz84DRd5mY8e0DcE8kvLj3AIfjE6w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "15.5.20", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.20.tgz", + "integrity": "sha512-Hp3zFsN8N8Kj9+vY6L4vnZ9EtA9eXyATu0q4EfGbZTiocgPUNSfz8NWhym6xvaOmHpJ8EuoypuU1WejCPsTFtg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "15.5.20", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.20.tgz", + "integrity": "sha512-T/L7CXpR1M0wij/xbF3rT1+7KvSkfOLr7C+ToHHWZTG2eKmb52C5WvsyGCBNtkVvDEUESWkRUbbqSH4rSbOCYQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@noble/ciphers": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-2.2.0.tgz", + "integrity": "sha512-Z6pjIZ/8IJcCGzb2S/0Px5J81yij85xASuk1teLNeg75bfT07MV3a/O2Mtn1I2se43k3lkVEcFaR10N4cgQcZA==", + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.2.0.tgz", + "integrity": "sha512-IYqDGiTXab6FniAgnSdZwgWbomxpy9FtYvLKs7wCUs2a8RkITG+DFGO1DM9cr+E3/RgADRpFjrKVaJ1z6sjtEg==", + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "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==", + "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==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nolyfill/is-core-module": { + "version": "1.0.39", + "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", + "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.4.0" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.43.0.tgz", + "integrity": "sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@playwright/test": { + "version": "1.61.1", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.61.1.tgz", + "integrity": "sha512-8nKv6+0RJSL9FE4jYOEGXnPeM/Hg12qZpmqzZjRh3qM0Y7c3z1mrOTfFLids72RDQYVh9WpLEfR5WdpNX4fkig==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.61.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@prisma/client": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.22.0.tgz", + "integrity": "sha512-M0SVXfyHnQREBKxCgyo7sffrKttwE6R8PMq330MIUF0pTwjUhLbW84pFDlf06B27XyCR++VtjugEnIHdr07SVA==", + "hasInstallScript": true, + "license": "Apache-2.0", + "engines": { + "node": ">=16.13" + }, + "peerDependencies": { + "prisma": "*" + }, + "peerDependenciesMeta": { + "prisma": { + "optional": true + } + } + }, + "node_modules/@prisma/debug": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-5.22.0.tgz", + "integrity": "sha512-AUt44v3YJeggO2ZU5BkXI7M4hu9BF2zzH2iF2V5pyXT/lRTyWiElZ7It+bRH1EshoMRxHgpYg4VB6rCM+mG5jQ==", + "license": "Apache-2.0" + }, + "node_modules/@prisma/engines": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-5.22.0.tgz", + "integrity": "sha512-UNjfslWhAt06kVL3CjkuYpHAWSO6L4kDCVPegV6itt7nD1kSJavd3vhgAEhjglLJJKEdJ7oIqDJ+yHk6qO8gPA==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "5.22.0", + "@prisma/engines-version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", + "@prisma/fetch-engine": "5.22.0", + "@prisma/get-platform": "5.22.0" + } + }, + "node_modules/@prisma/engines-version": { + "version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", + "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2.tgz", + "integrity": "sha512-2PTmxFR2yHW/eB3uqWtcgRcgAbG1rwG9ZriSvQw+nnb7c4uCr3RAcGMb6/zfE88SKlC1Nj2ziUvc96Z379mHgQ==", + "license": "Apache-2.0" + }, + "node_modules/@prisma/fetch-engine": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-5.22.0.tgz", + "integrity": "sha512-bkrD/Mc2fSvkQBV5EpoFcZ87AvOgDxbG99488a5cexp5Ccny+UM6MAe/UFkUC0wLYD9+9befNOqGiIJhhq+HbA==", + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "5.22.0", + "@prisma/engines-version": "5.22.0-44.605197351a3c8bdd595af2d2a9bc3025bca48ea2", + "@prisma/get-platform": "5.22.0" + } + }, + "node_modules/@prisma/get-platform": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-5.22.0.tgz", + "integrity": "sha512-pHhpQdr1UPFpt+zFfnPazhulaZYCUqeIcPpJViYoq9R+D/yw4fjE+CtnsnKzPYm0ddUbeXUzjGVGIRVgPDCk4Q==", + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "5.22.0" + } + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.6.tgz", + "integrity": "sha512-w9hl+724uYEgCGR3bhuRepjBtrNB/6gkhCnAf58Ke+SLbHPPQqVZZB59z60roB+5H+nh3nWTcdJhQdFMEydWmw==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-avatar": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.2.3.tgz", + "integrity": "sha512-peavtnApRB1tABx42tHw+rPU83GSg5tXicMYO/Xi1/lqNcRsF6jkr6L7Njo7gj4q/xtDRDKBkqJvbMtoOMYWtA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.6", + "@radix-ui/react-context": "1.2.0", + "@radix-ui/react-primitive": "2.1.7", + "@radix-ui/react-use-callback-ref": "1.1.2", + "@radix-ui/react-use-is-hydrated": "0.1.1", + "@radix-ui/react-use-layout-effect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.12.tgz", + "integrity": "sha512-nb67INpE0IahJKN7EYPp9m9YGwYeKlnzxT3MwXVkgCskaSJia97kG4T0ywpjNUSSnoJk/uvk12V8vbrEHEj+/Q==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.2.0", + "@radix-ui/react-primitive": "2.1.7", + "@radix-ui/react-slot": "1.3.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.3.tgz", + "integrity": "sha512-rYOP8OMnuuPMQF1uhPVlGNcCDlkokKqGFE3JcxFViIkAXP7EvFWUliJAstrapypaBLJNHbZL6jGhbVDGTwmVhA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.2.0.tgz", + "integrity": "sha512-fOE+JtN9rygNZkCnHRBEP0TAvLldlhyOxMsbwFvTP4nAs+nBmfnna+o/Zski2wkmY1YMrFC0aSzsHoLY47iLrg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.2.tgz", + "integrity": "sha512-C3vFhbyi4SW3PmbAi6Awpu4OzJtd0MxGurvSsYtr7p7nM8RNB3VAF3CUmnp2j50knpkrRcB7+ycVXzgLgF6yNA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.2.tgz", + "integrity": "sha512-orBC88futVpqCmhX1p4cvquNHsELQ+w+vBJnuj3ftETI5bJb0bZn3Tqu3SWN2IOcPycTnMGnhwoermvISt72sA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-label": { + "version": "2.1.12", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.12.tgz", + "integrity": "sha512-dxioNQ7VOrYKKWJIxMRmJPDSWQN0gNCUy3zaqUSBwsuFAiFzI0yLGJr2q3ml07k/HlOk55N8KEfwa1ZgfprJ3w==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.1.7" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.8.tgz", + "integrity": "sha512-0hhyrQdXMaATgq4ammLG9+iPqsXxzZkgTSIxdrJHdfLnXO4Uo5L7BoO3/Xf0AEaettadGZWGGJMw6ujzQvIpGA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.7.tgz", + "integrity": "sha512-bC3NiwsprbxKjuon9l7X6BUTw7FPVzEYaL92MPEY5SCd/9hUTPXVFtVwRix7778wtRsVao+zE062gL79FZleeQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.3.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-progress": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.13.tgz", + "integrity": "sha512-1dUdKDd63Tz9FfbTw20MVr28ohG4v7HOJ1dsavGBBPBS3KGzLOyLKiMJAC1OdgiY18nTSHpD4fULGK5gsLY/ww==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-context": "1.2.0", + "@radix-ui/react-primitive": "2.1.7" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.16.tgz", + "integrity": "sha512-w7lLsTSd3940vFYEshKkHw+NGf7H0QDJPHYsy8NRjDCVbO6ZdKW1X/xoJSYHZtttnrdZiYqbN2O/2uHGB0zasw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.6", + "@radix-ui/react-collection": "1.1.12", + "@radix-ui/react-compose-refs": "1.1.3", + "@radix-ui/react-context": "1.2.0", + "@radix-ui/react-direction": "1.1.2", + "@radix-ui/react-id": "1.1.2", + "@radix-ui/react-primitive": "2.1.7", + "@radix-ui/react-use-callback-ref": "1.1.2", + "@radix-ui/react-use-controllable-state": "1.2.4", + "@radix-ui/react-use-is-hydrated": "0.1.1", + "@radix-ui/react-use-layout-effect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.3.0.tgz", + "integrity": "sha512-MojKku4U/miO8Av4Dkb+ctMAQx7JmY96LmtDQlAarCRtd7rN52QCSzBF+XAvr5S6coSVj9HEPBgHAHKEJVk/WA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.3" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.18.tgz", + "integrity": "sha512-1zq2XkQkK/KfbZn84edytYpOLquhNalra5LXc3NAMKhNRSGtyXqjMv6OyC9jlSuNKpqvQtsb57WKoICNk1v/sQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.6", + "@radix-ui/react-context": "1.2.0", + "@radix-ui/react-direction": "1.1.2", + "@radix-ui/react-id": "1.1.2", + "@radix-ui/react-presence": "1.1.8", + "@radix-ui/react-primitive": "2.1.7", + "@radix-ui/react-roving-focus": "1.1.16", + "@radix-ui/react-use-controllable-state": "1.2.4" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.2.tgz", + "integrity": "sha512-xCso9j1/u8sEgP1RNHjFrXJLApL8LiqOkI1R4ywuN00rxWdYg4oQXuwKLS3i0j5NWLromUD27/4nlxj2UFVvIw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.4.tgz", + "integrity": "sha512-cx2DixxmSfjCcEoRvDvy1NLd6SWK94XFcEEOZUcharUlXbmahFQGKCfwdKZL2ub34iIwOPOEFVF80xb+yfLYiA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.6", + "@radix-ui/react-use-effect-event": "0.0.3", + "@radix-ui/react-use-layout-effect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-effect-event": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.3.tgz", + "integrity": "sha512-6c8ZqvPTWILEKnyVkP53EGRCcpnJiKTC21sS/6R1GF5xKyHJJWQEPfkqlcgUkdRQivd6tb23abUwe4ngWmY0JA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.2" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-is-hydrated": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.1.tgz", + "integrity": "sha512-qwOiz4Tjo8CNnrOLAYUMXeZwDzXgXpvK4TKQPmWLECM9XoWvA6+0Z2/7Ag3A4ivjS4ovbLJPbskkxioFyBhr8A==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.2.tgz", + "integrity": "sha512-jrBWOxZITuGcnjRCM2t2U5ZPkCLxD+Ym6DjfssS5haTj2iiak/DOb64JeN6OdLfLgptb6/e2kKR+ZuTrGoZTPA==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.16.1.tgz", + "integrity": "sha512-TvZbIpeKqGQQ7X0zSCvPH9riMSFQFSggnfBjFZ1mEoILW+UuXCKwOoPcgjMwiUtRqFZ8jWhPJc4um14vC6I4ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "license": "MIT" + }, + "node_modules/@swc/helpers": { + "version": "0.5.15", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", + "integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/d3-array": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz", + "integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==", + "license": "MIT" + }, + "node_modules/@types/d3-color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz", + "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==", + "license": "MIT" + }, + "node_modules/@types/d3-ease": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz", + "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==", + "license": "MIT" + }, + "node_modules/@types/d3-interpolate": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz", + "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==", + "license": "MIT", + "dependencies": { + "@types/d3-color": "*" + } + }, + "node_modules/@types/d3-path": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz", + "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==", + "license": "MIT" + }, + "node_modules/@types/d3-scale": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz", + "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==", + "license": "MIT", + "dependencies": { + "@types/d3-time": "*" + } + }, + "node_modules/@types/d3-shape": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.8.tgz", + "integrity": "sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==", + "license": "MIT", + "dependencies": { + "@types/d3-path": "*" + } + }, + "node_modules/@types/d3-time": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz", + "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==", + "license": "MIT" + }, + "node_modules/@types/d3-timer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz", + "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==", + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.43", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.43.tgz", + "integrity": "sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/react": { + "version": "19.2.17", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", + "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "devOptional": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.64.0.tgz", + "integrity": "sha512-CGvQPBxN3wZLu6Rz2kFUpZeoCm78xUic92ck39KPePkO1NPOwjCqdQnm5Q87tpWw9vcBvW8XLrDXjH9PWYtJ3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.64.0", + "@typescript-eslint/type-utils": "8.64.0", + "@typescript-eslint/utils": "8.64.0", + "@typescript-eslint/visitor-keys": "8.64.0", + "ignore": "^7.0.5", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.64.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.6.tgz", + "integrity": "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.64.0.tgz", + "integrity": "sha512-KA0OshtlcCCXmbfqyZkM5pV3/WNraJf7DkJRLpyrmwPtud57H5BDX7C3k0LPSPxpprfRL+cJDGabF10mvNCoCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.64.0", + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/typescript-estree": "8.64.0", + "@typescript-eslint/visitor-keys": "8.64.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.64.0.tgz", + "integrity": "sha512-tk4WpOJ6IEbGrVHaNmM0YRrwAD3exZlIK3iadQNAxh4YKk6jvUQ4ecq18n+v7+meh+cJ3j+D8nbk8sRKhlwLQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.64.0", + "@typescript-eslint/types": "^8.64.0", + "debug": "^4.4.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.64.0.tgz", + "integrity": "sha512-CXEaFdYXjSTgKhisNkwCcJwTP8Pl+fmRrEQrri4nm3vU743bALrxzLmq7fHG/7e6a5xO0lDYeURpZmBuhHk54w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/visitor-keys": "8.64.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.64.0.tgz", + "integrity": "sha512-2yo8rRNKuzbVWQp5kslhANqZ2uDAeROQHBRZNPu8JDsHmeFNj/XJJhX/FhNUWmkHHvoNsKa6+tHJiig87EzsQw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.64.0.tgz", + "integrity": "sha512-XWG4Fmmv/6SvyS9nH8jWrKs6terwJvE8cyRt1CzYYqzp9OrPhCT4cMc/f7C6RZCwG+qMmiffJS1/qJP8G1URtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/typescript-estree": "8.64.0", + "@typescript-eslint/utils": "8.64.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.64.0.tgz", + "integrity": "sha512-qjhfuTfLXjA4IOzXvz0rTjT01BqEiIgPoUeMwiEjnaHKJMTNo8rH5pYW1a2L/0Dnux2fPC85AeyJoWaGa8WxTA==", + "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.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.64.0.tgz", + "integrity": "sha512-Pztpsn1aCE1oWDvDEfUk31nngvvF7vUB5SwHFEaZIFpvw7WJtqUHHL4plBZDA9HfWJJjL13BdG0YrJInTUvoVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.64.0", + "@typescript-eslint/tsconfig-utils": "8.64.0", + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/visitor-keys": "8.64.0", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", + "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.64.0.tgz", + "integrity": "sha512-aJUGVB3+U0htrrCjoA8qukw8cm8fNCGAxK/tVoS70k8aeb7DETKeFozRiVFIwEeN9WJLsjaP3ph8I60tY2XZoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.64.0", + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/typescript-estree": "8.64.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.64.0.tgz", + "integrity": "sha512-mrtuL8Nsn6gi2H4mo5KMTp823M+3Q19Ew/i+Zlikq20tIMm99C3Ez0dCmkWWnxut20esQvTg8aUSEhMcAOXhEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.64.0", + "eslint-visitor-keys": "^5.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.3.tgz", + "integrity": "sha512-60YRaenCQcVjYEKOcG824+DRGGIQ3VKErcBoAEDJZz5bKIs2ZG+X/H9Nk+Q6EVkwJk5QNApxbrc5QtBSwtrXAg==", + "dev": true, + "license": "ISC" + }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.12.2.tgz", + "integrity": "sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.12.2.tgz", + "integrity": "sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.12.2.tgz", + "integrity": "sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.12.2.tgz", + "integrity": "sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.12.2.tgz", + "integrity": "sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.12.2.tgz", + "integrity": "sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.12.2.tgz", + "integrity": "sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.12.2.tgz", + "integrity": "sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.12.2.tgz", + "integrity": "sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-loong64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-gnu/-/resolver-binding-linux-loong64-gnu-1.12.2.tgz", + "integrity": "sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-loong64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-musl/-/resolver-binding-linux-loong64-musl-1.12.2.tgz", + "integrity": "sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.12.2.tgz", + "integrity": "sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.12.2.tgz", + "integrity": "sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.12.2.tgz", + "integrity": "sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.12.2.tgz", + "integrity": "sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.12.2.tgz", + "integrity": "sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.12.2.tgz", + "integrity": "sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-openharmony-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-openharmony-arm64/-/resolver-binding-openharmony-arm64-1.12.2.tgz", + "integrity": "sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.12.2.tgz", + "integrity": "sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz", + "integrity": "sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.12.2.tgz", + "integrity": "sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.12.2.tgz", + "integrity": "sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@use-gesture/core": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/@use-gesture/core/-/core-10.3.1.tgz", + "integrity": "sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw==", + "license": "MIT" + }, + "node_modules/@use-gesture/react": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/@use-gesture/react/-/react-10.3.1.tgz", + "integrity": "sha512-Yy19y6O2GJq8f7CHf7L0nxL8bf4PZCPaVOCgJrusOeFHY1LvHgYXnmnXg6N5iwAnbgbZCDjo60SiM6IPJi9C5g==", + "license": "MIT", + "dependencies": { + "@use-gesture/core": "10.3.1" + }, + "peerDependencies": { + "react": ">= 16.8.0" + } + }, + "node_modules/acorn": { + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", + "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", + "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/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==", + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/autoprefixer": { + "version": "10.5.4", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.4.tgz", + "integrity": "sha512-MaU0U/za7N3r6brxD4YB/l4NSrFzLPlANv6wEuQVaIPlD3L4W9rFcQPbL/EilY9BHhHvhfcz3gInDLrEtWT4EA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.6", + "caniuse-lite": "^1.0.30001806", + "fraction.js": "^5.3.4", + "picocolors": "^1.1.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.12.1.tgz", + "integrity": "sha512-s7iGf5GaVMxEG0ENN9x+xTr7GFZCb1ZP/1uATUpCEK2X78nDB3RwbtFCo9pGAf9ru+VwoQ464DkaLEeRM08wJA==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.44", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.44.tgz", + "integrity": "sha512-T3ghW+sl/ZJ8w1v/yQx3qvJ9040DWoLBz8JT/CILbAKcFyG9b2MRe75v6W5uXjv6uH1lumK2Kv46y2zSkcej0Q==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/better-auth": { + "version": "1.6.23", + "resolved": "https://registry.npmjs.org/better-auth/-/better-auth-1.6.23.tgz", + "integrity": "sha512-4vOaRd9UiKGKm9R+ej0jjU1es3MiJIiNc9Qq3VCnYqOZ4/nb5272QqTxWYoDxyUXl5x6A2x2we5KZKQO9teTQQ==", + "license": "MIT", + "dependencies": { + "@better-auth/core": "1.6.23", + "@better-auth/drizzle-adapter": "1.6.23", + "@better-auth/kysely-adapter": "1.6.23", + "@better-auth/memory-adapter": "1.6.23", + "@better-auth/mongo-adapter": "1.6.23", + "@better-auth/prisma-adapter": "1.6.23", + "@better-auth/telemetry": "1.6.23", + "@better-auth/utils": "0.4.2", + "@better-fetch/fetch": "1.3.1", + "@noble/ciphers": "^2.1.1", + "@noble/hashes": "^2.0.1", + "better-call": "1.3.7", + "defu": "^6.1.4", + "jose": "^6.1.3", + "kysely": "^0.28.17 || ^0.29.0", + "nanostores": "^1.1.1", + "zod": "^4.3.6" + }, + "peerDependencies": { + "@lynx-js/react": "*", + "@prisma/client": "^5.0.0 || ^6.0.0 || ^7.0.0", + "@sveltejs/kit": "^2.0.0", + "@tanstack/react-start": "^1.0.0", + "@tanstack/solid-start": "^1.0.0", + "better-sqlite3": "^12.0.0", + "drizzle-kit": ">=0.31.4", + "drizzle-orm": "^0.45.2", + "mongodb": "^6.0.0 || ^7.0.0", + "mysql2": "^3.0.0", + "next": "^14.0.0 || ^15.0.0 || ^16.0.0", + "pg": "^8.0.0", + "prisma": "^5.0.0 || ^6.0.0 || ^7.0.0", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0", + "solid-js": "^1.0.0", + "svelte": "^4.0.0 || ^5.0.0", + "vitest": "^2.0.0 || ^3.0.0 || ^4.0.0", + "vue": "^3.0.0" + }, + "peerDependenciesMeta": { + "@lynx-js/react": { + "optional": true + }, + "@prisma/client": { + "optional": true + }, + "@sveltejs/kit": { + "optional": true + }, + "@tanstack/react-start": { + "optional": true + }, + "@tanstack/solid-start": { + "optional": true + }, + "better-sqlite3": { + "optional": true + }, + "drizzle-kit": { + "optional": true + }, + "drizzle-orm": { + "optional": true + }, + "mongodb": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "next": { + "optional": true + }, + "pg": { + "optional": true + }, + "prisma": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "solid-js": { + "optional": true + }, + "svelte": { + "optional": true + }, + "vitest": { + "optional": true + }, + "vue": { + "optional": true + } + } + }, + "node_modules/better-call": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/better-call/-/better-call-1.3.7.tgz", + "integrity": "sha512-Al51/hjp2SSp6CRTa3F2ptcx4yQVS1xWKoY6jcVXqNYOap6mHFP2jUBn5EwIL4iIed1/Sq4hlQ+Umm6EflZG+w==", + "license": "MIT", + "dependencies": { + "@better-auth/utils": "^0.4.0", + "@better-fetch/fetch": "^1.1.21", + "rou3": "^0.7.12", + "set-cookie-parser": "^3.0.1" + }, + "peerDependencies": { + "zod": "^4.0.0" + }, + "peerDependenciesMeta": { + "zod": { + "optional": true + } + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.16", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", + "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", + "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==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.6.tgz", + "integrity": "sha512-FQBYNK15VMslhLHpA7+n+n1GOlF1kId2xcCg7/j95f24AOF6VDYMNH4mFxF7KuaTdv627faazpOAjFzMrfJOUw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.42", + "caniuse-lite": "^1.0.30001803", + "electron-to-chromium": "^1.5.389", + "node-releases": "^2.0.51", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/call-bind": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001806", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz", + "integrity": "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/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/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/class-variance-authority": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", + "integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==", + "license": "Apache-2.0", + "dependencies": { + "clsx": "^2.1.1" + }, + "funding": { + "url": "https://polar.sh/cva" + } + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" + }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "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/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "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/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/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "license": "MIT" + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "license": "ISC", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz", + "integrity": "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "license": "ISC", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "license": "ISC", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "license": "ISC", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "license": "ISC", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "license": "ISC", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js-light": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz", + "integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==", + "license": "MIT" + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/defu": { + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.7.tgz", + "integrity": "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==", + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/didyoumean": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", + "integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==", + "license": "Apache-2.0" + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "license": "MIT" + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.393", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.393.tgz", + "integrity": "sha512-kiDJdIUawuEIcp9XoICKp1iTYDEbgguIPq526N1Q7jIQDeQ3CqoMx71025PI/7E48Ddtw2HuWsVjY7afEgNxmg==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-abstract": { + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", + "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-abstract-get": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-abstract-get/-/es-abstract-get-1.0.0.tgz", + "integrity": "sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.2", + "is-callable": "^1.2.7", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.4.0.tgz", + "integrity": "sha512-c/A0P0oxkACDc+cKWw8evLXK83oBKgn0qPOqCYT4x9uolpCIJAcYvJC9QYKNDRPsTeGyCrQ326jrvgZWdCdK5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.2", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.1.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.3.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.5", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.4.tgz", + "integrity": "sha512-yPDz7wqpg1/mmHLmS3tcfTfbw5f1eryXvyghYBffGdERwe+mV7ZcWzTR8LR17Kvqt3qfPurjlonmnq3MKXIOXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-abstract-get": "^1.0.0", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "is-callable": "^1.2.7", + "is-date-object": "^1.1.0", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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": "8.57.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", + "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.1", + "@humanwhocodes/config-array": "^0.13.0", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-next": { + "version": "15.5.20", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-15.5.20.tgz", + "integrity": "sha512-Pl/I5544gmkcVVWcnaOMfhJSBK8lZ1NCJ+mGBkd2qvbGt2Gi7sEpgHF06OR13a2p6THODlncpvGsZzY2vUqwxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@next/eslint-plugin-next": "15.5.20", + "@rushstack/eslint-patch": "^1.10.3", + "@typescript-eslint/eslint-plugin": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-jsx-a11y": "^6.10.0", + "eslint-plugin-react": "^7.37.0", + "eslint-plugin-react-hooks": "^5.0.0" + }, + "peerDependencies": { + "eslint": "^7.23.0 || ^8.0.0 || ^9.0.0", + "typescript": ">=3.3.1" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.10.tgz", + "integrity": "sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.16.1", + "resolve": "^2.0.0-next.6" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.10.1.tgz", + "integrity": "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@nolyfill/is-core-module": "1.0.39", + "debug": "^4.4.0", + "get-tsconfig": "^4.10.0", + "is-bun-module": "^2.0.0", + "stable-hash": "^0.0.5", + "tinyglobby": "^0.2.13", + "unrs-resolver": "^1.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-resolver-typescript" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.14.0.tgz", + "integrity": "sha512-W2WCRZ9Dqntd+2u8jJcVMV2PKulc6RdLgUUoh/yQr3uB6lo/ZOeGx11sv60/8S4QFFKNslAlWhr9u0Ef7ZW6Ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", + "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "aria-query": "^5.3.2", + "array-includes": "^3.1.8", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "hasown": "^2.0.2", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.1" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.9", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz", + "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "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/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-equals": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.4.1.tgz", + "integrity": "sha512-DjlFSM5Pk9cGcL0q5QXl66eGzx0N6szNgaswwc5ZphlBohjTVJSnGgI+rJVOgOi65qUoQnDZN4nDqi33udtydQ==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.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==", + "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": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.3", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/fraction.js": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-5.3.4.tgz", + "integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/framer-motion": { + "version": "11.18.2", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.18.2.tgz", + "integrity": "sha512-5F5Och7wrvtLVElIpclDT0CBzMVg3dL22B64aZwHtsIY8RB4mXICLrkajK4G9R+ieSAGcgrLeae2SeUTg2pr6w==", + "license": "MIT", + "dependencies": { + "motion-dom": "^11.18.1", + "motion-utils": "^11.18.1", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0 || ^19.0.0", + "react-dom": "^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "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/function.prototype.name": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.2.0.tgz", + "integrity": "sha512-jObKIik1P2QjPHP5nz5BaOtUlfgS0fWo8IUByNXkM+o+02sJOi94em77GwJKQSJ3gfPHdgzLNrHc1uokV4P/ew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2", + "hasown": "^2.0.4", + "is-callable": "^1.2.7", + "is-document.all": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz", + "integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "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/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bun-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", + "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.7.1" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-document.all": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-document.all/-/is-document.all-1.0.0.tgz", + "integrity": "sha512-+XSoyS05OdBbhFuELhgTCpFNHkpBOJqtsZfUFFpe5QTw+9Sjbh8zitxhQkYAo6wV7e1Vb8cAPvpCk9jGam/82g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/jose": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.3.tgz", + "integrity": "sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz", + "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/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": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kysely": { + "version": "0.29.4", + "resolved": "https://registry.npmjs.org/kysely/-/kysely-0.29.4.tgz", + "integrity": "sha512-y5mVgQNkMbs1eK9Xyc0pmNdabN2wHhRYY/5r4W5HrUT1rYCEPeVNSj1RUJeSDKT3U0p+mXCvLgkrFuIafYI6BA==", + "license": "MIT", + "engines": { + "node": ">=22.0.0" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lilconfig": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "license": "MIT" + }, + "node_modules/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": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lucide-react": { + "version": "0.400.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.400.0.tgz", + "integrity": "sha512-rpp7pFHh3Xd93KHixNgB0SqThMHpYNzsGUu69UaQbSZ75Q/J3m5t6EhKyMT3m4w2WOxmJ2mY0tD3vebnXqQryQ==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/motion-dom": { + "version": "11.18.1", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-11.18.1.tgz", + "integrity": "sha512-g76KvA001z+atjfxczdRtw/RXOM3OMSdd1f4DL77qCTF/+avrRJiawSG4yDibEQ215sr9kpinSlX2pCTJ9zbhw==", + "license": "MIT", + "dependencies": { + "motion-utils": "^11.18.1" + } + }, + "node_modules/motion-utils": { + "version": "11.18.1", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-11.18.1.tgz", + "integrity": "sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA==", + "license": "MIT" + }, + "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/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.16", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.16.tgz", + "integrity": "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==", + "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/nanostores": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/nanostores/-/nanostores-1.4.0.tgz", + "integrity": "sha512-i0tloweeudshAEuddpDxcg9Ik6pkPfVsHIgKyf143JrgG7/MOh0+q7BypdLXZPoOP7fOYt1eTcwGkyiVmhJFkA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "engines": { + "node": "^20.0.0 || >=22.0.0" + } + }, + "node_modules/napi-postinstall": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", + "dev": true, + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/next": { + "version": "15.5.20", + "resolved": "https://registry.npmjs.org/next/-/next-15.5.20.tgz", + "integrity": "sha512-cvyS3/geydan1xLtE3FA8VCgdoQ/Gg/dlOldFkFCbB5VcVYJV7090hQLBnvTW2PwT76Z/dHdzDZCsVhZpoOlUA==", + "license": "MIT", + "dependencies": { + "@next/env": "15.5.20", + "@swc/helpers": "0.5.15", + "caniuse-lite": "^1.0.30001579", + "postcss": "8.4.31", + "styled-jsx": "5.1.6" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "15.5.20", + "@next/swc-darwin-x64": "15.5.20", + "@next/swc-linux-arm64-gnu": "15.5.20", + "@next/swc-linux-arm64-musl": "15.5.20", + "@next/swc-linux-x64-gnu": "15.5.20", + "@next/swc-linux-x64-musl": "15.5.20", + "@next/swc-win32-arm64-msvc": "15.5.20", + "@next/swc-win32-x64-msvc": "15.5.20", + "sharp": "^0.34.3" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.51.1", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/next/node_modules/postcss": { + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.6", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/node-exports-info": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.2.tgz", + "integrity": "sha512-kXs9Go0cah0qHVV2v389IXQLdLCeE1xfFtjOAF+iobu0OIoG1pje8At2vMHyaPMiPMnG/LWP50twML21eMcAag==", + "dev": true, + "license": "MIT", + "dependencies": { + "array.prototype.flatmap": "^1.3.3", + "es-errors": "^1.3.0", + "object.entries": "^1.1.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/node-exports-info/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/node-releases": { + "version": "2.0.51", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz", + "integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz", + "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/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/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/perfect-freehand": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/perfect-freehand/-/perfect-freehand-1.2.3.tgz", + "integrity": "sha512-bHZSfqDHGNlPpgH2yxXgPHlQSPpEbo+qg7li0M78J9vNAi2yjwLeA4x79BEQhX44lEWpCLSFCeRZwpw0niiXPA==", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/playwright": { + "version": "1.61.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.61.1.tgz", + "integrity": "sha512-DWnY5o3YbLWK4GovuAVwpqL+1VwGNdUGrRr++8j8PtQQzvAVZUIMjKQ90fY689sEJZJBbZVw1rXaOKSTitkzPQ==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.61.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.61.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.61.1.tgz", + "integrity": "sha512-h7Qlt6m4REp25qvIdvbDtVmD4LqVXfpRxhORv9L0jzETM05p4fuPJ3dKyuSXQxDSbXnmS79HAgi9589lGSpLkg==", + "devOptional": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.5.20", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.20.tgz", + "integrity": "sha512-lW616l85ucIQL+FocMmL7pQFPqBmwejrCMg+iPxyImlrANNJG9NHq/RkyCZopDhd8C3LA03PHRJDjkbGu8vvug==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.16", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-import": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", + "integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==", + "license": "MIT", + "dependencies": { + "postcss-value-parser": "^4.0.0", + "read-cache": "^1.0.0", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "postcss": "^8.0.0" + } + }, + "node_modules/postcss-import/node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/postcss-js": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-4.1.0.tgz", + "integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "camelcase-css": "^2.0.1" + }, + "engines": { + "node": "^12 || ^14 || >= 16" + }, + "peerDependencies": { + "postcss": "^8.4.21" + } + }, + "node_modules/postcss-load-config": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-6.0.1.tgz", + "integrity": "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.1.1" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" + } + }, + "node_modules/postcss-selector-parser": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.4.tgz", + "integrity": "sha512-bIoJLOmjCO1S9XdY/DcnR5hJxvrDir1PbGChrzXG3vw0/FOliy/fA3dmdhQ441kah4gKv+TwckGzex6wNS5cnQ==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "license": "MIT" + }, + "node_modules/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/prisma": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/prisma/-/prisma-5.22.0.tgz", + "integrity": "sha512-vtpjW3XuYCSnMsNVBjLMNkTj6OZbudcPPTPYHqX0CJfpcdWciI1dM8uHETwmDxxiqEwCIE6WvXucWUetJgfu/A==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "@prisma/engines": "5.22.0" + }, + "bin": { + "prisma": "build/index.js" + }, + "engines": { + "node": ">=16.13" + }, + "optionalDependencies": { + "fsevents": "2.3.3" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "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.7", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.7.tgz", + "integrity": "sha512-HNe9WslTbXmFK8o8cmwgAeJFSBvt1bPdHCVKtaaV+WlAN36mpT4hcRpwbf3fY56ar2oIXzsBpOAiIRHAdY0OlQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.7.tgz", + "integrity": "sha512-t0BRVXvbiE/o20Hfw669rLbMCDWtYZLvmJigy2f0MxsXF+71pxhR3xOkspmsO8h3ZlNzyibAmtCa3l4lYKk6gQ==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.7" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, + "node_modules/react-smooth": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.4.tgz", + "integrity": "sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q==", + "license": "MIT", + "dependencies": { + "fast-equals": "^5.0.1", + "prop-types": "^15.8.1", + "react-transition-group": "^4.4.5" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz", + "integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/read-cache": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", + "integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==", + "license": "MIT", + "dependencies": { + "pify": "^2.3.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/recharts": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/recharts/-/recharts-2.15.4.tgz", + "integrity": "sha512-UT/q6fwS3c1dHbXv2uFgYJ9BMFHu3fwnd7AYZaEQhXuYQ4hgsxLvsUXzGdKeZrW5xopzDCvuA2N41WJ88I7zIw==", + "deprecated": "1.x and 2.x branches are no longer active. Bump to Recharts v3 to receive latest features and bugfixes. See https://github.com/recharts/recharts/wiki/3.0-migration-guide", + "license": "MIT", + "dependencies": { + "clsx": "^2.0.0", + "eventemitter3": "^4.0.1", + "lodash": "^4.17.21", + "react-is": "^18.3.1", + "react-smooth": "^4.0.4", + "recharts-scale": "^0.4.4", + "tiny-invariant": "^1.3.1", + "victory-vendor": "^36.6.8" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/recharts-scale": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.5.tgz", + "integrity": "sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==", + "license": "MIT", + "dependencies": { + "decimal.js-light": "^2.4.1" + } + }, + "node_modules/recharts/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "license": "MIT" + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve": { + "version": "2.0.0-next.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.7.tgz", + "integrity": "sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.2", + "node-exports-info": "^1.6.0", + "object-keys": "^1.1.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rou3": { + "version": "0.7.12", + "resolved": "https://registry.npmjs.org/rou3/-/rou3-0.7.12.tgz", + "integrity": "sha512-iFE4hLDuloSWcD7mjdCDhx2bKcIsYbtOTpfH5MHHLSKMOUyjqQXTeZVa289uuwEGEKFoE/BAPbhaU4B774nceg==", + "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==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz", + "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "get-intrinsic": "^1.3.0", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "devOptional": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-cookie-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-3.1.2.tgz", + "integrity": "sha512-5/r/lTwbJ3zQ+qwdUFZYeRNqda7P5HD8zQKqlSjdGt1/S0cjLAphHusj4Y58ahDtWn/g32xrIS58/ikOvwl0Lw==", + "license": "MIT" + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stable-hash": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", + "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==", + "dev": true, + "license": "MIT" + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.includes": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", + "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.11.tgz", + "integrity": "sha512-PwvK7BU+CMTJGYQCTZb5RWXIML92lftJLhQz1tBzgKiqGxJaMlBAa48POXaNAC2s4y8jr3EFqrkF9+44neS46w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.2", + "es-object-atoms": "^1.1.2", + "has-property-descriptors": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.10.tgz", + "integrity": "sha512-2+3aDAOmPTmuFwjDnmJG2ctEkQKVki7vOSqaxkv42Mowj1V6PnvuwFCRrR5lChUux1TBskPjfkeTOhqczDMxTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", + "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/sucrase": { + "version": "3.35.1", + "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz", + "integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "tinyglobby": "^0.2.11", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tailwind-merge": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.6.1.tgz", + "integrity": "sha512-Oo6tHdpZsGpkKG88HJ8RR1rg/RdnEkQEfMoEk2x1XRI3F1AxeU+ijRXpiVUF4UbLfcxxRGw6TbUINKYdWVsQTQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, + "node_modules/tailwindcss": { + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.19.tgz", + "integrity": "sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==", + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "arg": "^5.0.2", + "chokidar": "^3.6.0", + "didyoumean": "^1.2.2", + "dlv": "^1.1.3", + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.2", + "is-glob": "^4.0.3", + "jiti": "^1.21.7", + "lilconfig": "^3.1.3", + "micromatch": "^4.0.8", + "normalize-path": "^3.0.0", + "object-hash": "^3.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.47", + "postcss-import": "^15.1.0", + "postcss-js": "^4.0.1", + "postcss-load-config": "^4.0.2 || ^5.0 || ^6.0", + "postcss-nested": "^6.2.0", + "postcss-selector-parser": "^6.1.2", + "resolve": "^1.22.8", + "sucrase": "^3.35.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tailwindcss-animate": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz", + "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", + "license": "MIT", + "peerDependencies": { + "tailwindcss": ">=3.0.0 || insiders" + } + }, + "node_modules/tailwindcss/node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@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/tailwindcss/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==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/tailwindcss/node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-fsrs": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/ts-fsrs/-/ts-fsrs-4.7.1.tgz", + "integrity": "sha512-uYqKbSCNWLRPT0PfqFFy2rn0YuYz2fKmtgpgHOBd5/DP14oj6diG7P271AwJ8iGrKnmIspzXCF+nTKxict+Lcg==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/ts-interface-checker": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", + "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", + "license": "Apache-2.0" + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.8.tgz", + "integrity": "sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "for-each": "^0.3.5", + "gopd": "^1.2.0", + "is-typed-array": "^1.1.15", + "possible-typed-array-names": "^1.1.0", + "reflect.getprototypeof": "^1.0.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "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/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/unrs-resolver": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.12.2.tgz", + "integrity": "sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.4" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.12.2", + "@unrs/resolver-binding-android-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-x64": "1.12.2", + "@unrs/resolver-binding-freebsd-x64": "1.12.2", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-arm64-musl": "1.12.2", + "@unrs/resolver-binding-linux-loong64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-loong64-musl": "1.12.2", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-musl": "1.12.2", + "@unrs/resolver-binding-linux-s390x-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-musl": "1.12.2", + "@unrs/resolver-binding-openharmony-arm64": "1.12.2", + "@unrs/resolver-binding-wasm32-wasi": "1.12.2", + "@unrs/resolver-binding-win32-arm64-msvc": "1.12.2", + "@unrs/resolver-binding-win32-ia32-msvc": "1.12.2", + "@unrs/resolver-binding-win32-x64-msvc": "1.12.2" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "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/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/victory-vendor": { + "version": "36.9.2", + "resolved": "https://registry.npmjs.org/victory-vendor/-/victory-vendor-36.9.2.tgz", + "integrity": "sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==", + "license": "MIT AND ISC", + "dependencies": { + "@types/d3-array": "^3.0.3", + "@types/d3-ease": "^3.0.0", + "@types/d3-interpolate": "^3.0.1", + "@types/d3-scale": "^4.0.2", + "@types/d3-shape": "^3.1.0", + "@types/d3-time": "^3.0.0", + "@types/d3-timer": "^3.0.0", + "d3-array": "^3.1.6", + "d3-ease": "^3.0.1", + "d3-interpolate": "^3.0.1", + "d3-scale": "^4.0.2", + "d3-shape": "^3.1.0", + "d3-time": "^3.0.0", + "d3-timer": "^3.0.1" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.22", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.22.tgz", + "integrity": "sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/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.4.3", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.4.3.tgz", + "integrity": "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..370b43b --- /dev/null +++ b/package.json @@ -0,0 +1,50 @@ +{ + "name": "edueasy", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint", + "db:generate": "prisma generate", + "db:push": "prisma db push", + "db:migrate": "prisma migrate dev", + "db:studio": "prisma studio" + }, + "dependencies": { + "@prisma/client": "^5.20.0", + "@radix-ui/react-avatar": "^1.2.3", + "@radix-ui/react-label": "^2.1.12", + "@radix-ui/react-progress": "^1.1.13", + "@radix-ui/react-slot": "^1.1.0", + "@radix-ui/react-tabs": "^1.1.18", + "@use-gesture/react": "^10.3.0", + "better-auth": "^1.0.0", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", + "framer-motion": "^11.0.0", + "lucide-react": "^0.400.0", + "next": "^15.0.0", + "perfect-freehand": "^1.2.0", + "prisma": "^5.20.0", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "recharts": "^2.12.0", + "tailwind-merge": "^2.5.0", + "tailwindcss-animate": "^1.0.7", + "ts-fsrs": "^4.0.0" + }, + "devDependencies": { + "@playwright/test": "^1.61.1", + "@types/node": "^20.0.0", + "@types/react": "^19.0.0", + "@types/react-dom": "^19.0.0", + "autoprefixer": "^10.5.4", + "eslint": "^8.57.0", + "eslint-config-next": "^15.0.0", + "postcss": "^8.4.0", + "tailwindcss": "^3.4.0", + "typescript": "^5.6.0" + } +} diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 0000000..cda9e3b --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,22 @@ +import { defineConfig } from "@playwright/test" + +export default defineConfig({ + testDir: "./e2e", + timeout: 30000, + expect: { timeout: 5000 }, + fullyParallel: false, + retries: 0, + workers: 1, + reporter: [["list"]], + use: { + baseURL: "http://localhost:3459", + trace: "on-first-retry", + }, + webServer: { + command: "npx next dev -p 3459", + url: "http://localhost:3459", + reuseExistingServer: false, + timeout: 30000, + + }, +}) diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..33ad091 --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/prisma/migrations/20260720161822_init/migration.sql b/prisma/migrations/20260720161822_init/migration.sql new file mode 100644 index 0000000..b698b9f --- /dev/null +++ b/prisma/migrations/20260720161822_init/migration.sql @@ -0,0 +1,180 @@ +-- CreateTable +CREATE TABLE "Parent" ( + "id" TEXT NOT NULL, + "email" TEXT NOT NULL, + "name" TEXT, + "emailVerified" BOOLEAN NOT NULL DEFAULT false, + "image" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + "familyId" TEXT NOT NULL, + + CONSTRAINT "Parent_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Session" ( + "id" TEXT NOT NULL, + "email" TEXT, + "userId" TEXT, + "parentId" TEXT, + "token" TEXT NOT NULL, + "expiresAt" TIMESTAMP(3) NOT NULL, + "ipAddress" TEXT, + "userAgent" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "Session_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Account" ( + "id" TEXT NOT NULL, + "accountId" TEXT NOT NULL, + "providerId" TEXT NOT NULL, + "parentId" TEXT NOT NULL, + "accessToken" TEXT, + "refreshToken" TEXT, + "idToken" TEXT, + "accessTokenExpiresAt" TIMESTAMP(3), + "scope" TEXT, + "password" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "Account_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Verification" ( + "id" TEXT NOT NULL, + "identifier" TEXT NOT NULL, + "value" TEXT NOT NULL, + "expiresAt" TIMESTAMP(3) NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "Verification_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Family" ( + "id" TEXT NOT NULL, + "name" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "Family_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Child" ( + "id" TEXT NOT NULL, + "name" TEXT, + "avatar" TEXT, + "birthdate" TIMESTAMP(3), + "profileNotes" TEXT, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + "familyId" TEXT NOT NULL, + + CONSTRAINT "Child_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Device" ( + "id" TEXT NOT NULL, + "deviceFingerprint" TEXT NOT NULL, + "pairedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "lastSeen" TIMESTAMP(3) NOT NULL, + "role" TEXT NOT NULL DEFAULT 'child', + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "childId" TEXT NOT NULL, + + CONSTRAINT "Device_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "SessionLog" ( + "id" TEXT NOT NULL, + "startedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "endedAt" TIMESTAMP(3), + "durationSec" INTEGER, + "skillsPracticed" TEXT, + "childId" TEXT NOT NULL, + + CONSTRAINT "SessionLog_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "SkillAttempt" ( + "id" TEXT NOT NULL, + "skillCode" TEXT NOT NULL, + "promptLevel" INTEGER NOT NULL DEFAULT 0, + "correct" BOOLEAN NOT NULL, + "responseMs" INTEGER, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "sessionLogId" TEXT NOT NULL, + + CONSTRAINT "SkillAttempt_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "FsrsCard" ( + "id" TEXT NOT NULL, + "skillCode" TEXT NOT NULL, + "dueAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "stability" DOUBLE PRECISION NOT NULL DEFAULT 0, + "difficulty" DOUBLE PRECISION NOT NULL DEFAULT 0, + "reps" INTEGER NOT NULL DEFAULT 0, + "lapses" INTEGER NOT NULL DEFAULT 0, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + "childId" TEXT NOT NULL, + + CONSTRAINT "FsrsCard_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Milestone" ( + "id" TEXT NOT NULL, + "skillCode" TEXT NOT NULL, + "reachedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "childId" TEXT NOT NULL, + + CONSTRAINT "Milestone_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "Parent_email_key" ON "Parent"("email"); + +-- CreateIndex +CREATE UNIQUE INDEX "Session_token_key" ON "Session"("token"); + +-- AddForeignKey +ALTER TABLE "Parent" ADD CONSTRAINT "Parent_familyId_fkey" FOREIGN KEY ("familyId") REFERENCES "Family"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Session" ADD CONSTRAINT "Session_parentId_fkey" FOREIGN KEY ("parentId") REFERENCES "Parent"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Account" ADD CONSTRAINT "Account_parentId_fkey" FOREIGN KEY ("parentId") REFERENCES "Parent"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Child" ADD CONSTRAINT "Child_familyId_fkey" FOREIGN KEY ("familyId") REFERENCES "Family"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Device" ADD CONSTRAINT "Device_childId_fkey" FOREIGN KEY ("childId") REFERENCES "Child"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "SessionLog" ADD CONSTRAINT "SessionLog_childId_fkey" FOREIGN KEY ("childId") REFERENCES "Child"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "SkillAttempt" ADD CONSTRAINT "SkillAttempt_sessionLogId_fkey" FOREIGN KEY ("sessionLogId") REFERENCES "SessionLog"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "FsrsCard" ADD CONSTRAINT "FsrsCard_childId_fkey" FOREIGN KEY ("childId") REFERENCES "Child"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Milestone" ADD CONSTRAINT "Milestone_childId_fkey" FOREIGN KEY ("childId") REFERENCES "Child"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/migrations/migration_lock.toml b/prisma/migrations/migration_lock.toml new file mode 100644 index 0000000..fbffa92 --- /dev/null +++ b/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (i.e. Git) +provider = "postgresql" \ No newline at end of file diff --git a/prisma/schema.prisma b/prisma/schema.prisma new file mode 100644 index 0000000..8438a42 --- /dev/null +++ b/prisma/schema.prisma @@ -0,0 +1,180 @@ +generator client { + provider = "prisma-client-js" +} + +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +model Parent { + id String @id @default(cuid()) + email String @unique + name String? + emailVerified Boolean @default(false) + image String? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + familyId String? + family Family? @relation(fields: [familyId], references: [id]) + + sessions Session[] + accounts Account[] +} + +model Session { + id String @id @default(cuid()) + email String? + userId String? + parentId String? + parent Parent? @relation(fields: [parentId], references: [id]) + token String @unique + expiresAt DateTime + ipAddress String? + userAgent String? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model Account { + id String @id @default(cuid()) + accountId String + providerId String + userId String + user Parent @relation(fields: [userId], references: [id]) + accessToken String? + refreshToken String? + idToken String? + accessTokenExpiresAt DateTime? + scope String? + password String? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model Verification { + id String @id @default(cuid()) + identifier String + value String + expiresAt DateTime + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} + +model Family { + id String @id @default(cuid()) + name String? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + parents Parent[] + children Child[] +} + +model Child { + id String @id @default(cuid()) + name String? + avatar String? + birthdate DateTime? + profileNotes String? + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + familyId String + family Family @relation(fields: [familyId], references: [id]) + + devices Device[] + sessions SessionLog[] + fsrsCards FsrsCard[] + milestones Milestone[] + curriculumProgress CurriculumProgress[] +} + +model Device { + id String @id @default(cuid()) + deviceFingerprint String + pairedAt DateTime @default(now()) + lastSeen DateTime @updatedAt + role String @default("child") + createdAt DateTime @default(now()) + + childId String + child Child @relation(fields: [childId], references: [id]) +} + +model SessionLog { + id String @id @default(cuid()) + startedAt DateTime @default(now()) + endedAt DateTime? + durationSec Int? + skillsPracticed String? + + childId String + child Child @relation(fields: [childId], references: [id]) + + skillAttempts SkillAttempt[] +} + +model SkillAttempt { + id String @id @default(cuid()) + skillCode String + promptLevel Int @default(0) + correct Boolean + responseMs Int? + errorType String? + exerciseId String? + stage Int? + createdAt DateTime @default(now()) + + sessionLogId String + sessionLog SessionLog @relation(fields: [sessionLogId], references: [id]) +} + +model CurriculumProgress { + id String @id @default(cuid()) + topic String + stage Int + unlockedAt DateTime @default(now()) + completedAt DateTime? + + childId String + child Child @relation(fields: [childId], references: [id]) + + @@unique([childId, topic, stage]) +} + +model FsrsCard { + id String @id @default(cuid()) + skillCode String + dueAt DateTime @default(now()) + stability Float @default(0) + difficulty Float @default(0) + reps Int @default(0) + lapses Int @default(0) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + childId String + child Child @relation(fields: [childId], references: [id]) +} + +model Milestone { + id String @id @default(cuid()) + skillCode String + reachedAt DateTime @default(now()) + + childId String + child Child @relation(fields: [childId], references: [id]) + + @@unique([childId, skillCode]) +} + +model PendingPairing { + id String @id @default(cuid()) + code String @unique + deviceFingerprint String? + childId String? + createdAt DateTime @default(now()) + expiresAt DateTime +} diff --git a/public/icon.svg b/public/icon.svg new file mode 100644 index 0000000..f2237e2 --- /dev/null +++ b/public/icon.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/public/tts-cache/0ad066a5d29f3f2a2a1c7c17dd082a79.wav b/public/tts-cache/0ad066a5d29f3f2a2a1c7c17dd082a79.wav new file mode 100644 index 0000000000000000000000000000000000000000..3c5f6bda9bd388a804bbc24278980de7d47e4fdc GIT binary patch literal 56206 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ℑ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%0D^?R`@oAs~ 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�S?Yk2zACCoxY!0Fy6B;c+ea{JI%x}l{H;3+*3 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 literal 0 HcmV?d00001 diff --git a/public/tts-cache/7efecaecce8338e591042f8e26137bf7.wav b/public/tts-cache/7efecaecce8338e591042f8e26137bf7.wav new file mode 100644 index 0000000000000000000000000000000000000000..75dda70831ae00f8c7f302a98bcd35ceb46f8451 GIT binary patch literal 101324 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 Dp$O>G literal 0 HcmV?d00001 diff --git a/public/tts-cache/d852f92d887c3788efb8c08c38788969.wav b/public/tts-cache/d852f92d887c3788efb8c08c38788969.wav new file mode 100644 index 0000000000000000000000000000000000000000..d97c4383c7d595438913670b2ccba727fc373c83 GIT binary patch literal 51466 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 z z(xN2W21gy|c!vdIWu~K@E7x5@oFwtEb0kX{tUQ&U%S)B2v=V&FMNQCNBp}umpxdZG zmnsGFNZAD3&$)63#YiUuW*P{{(<0!AWhuj88oC~MU|Ufsh({{Yj!Y)2$aR<-^#fLZ z4~UsHV9Gi`s14EaHh+LW!e8T`fEJJN|4)10;TF}^eSP~>hAC7L6kBWoTP(3R#1_Tg zNHkV7YHYEW*kbRU#NNP_1A~l!Zpe{0r=fQh!g&h19 z{DayE-(oKNf#1i^=U4N$_MdQ zf4B~O+L}~|x=6=DXS7S^p=<7d2pH~5R(p@}@`J|o90h78i9A^ls4kjqKm}st# z%A;2P?4KLF8PY&AdQ}QZt0k*=LQI!Ta#J}U%;ct0p>z(M zQzsM;`{By5OpF(ULU)mqoB2JP)vb89s-%voFcNF;FA) z1AkrUA(aPCI97TmlF}8aFJ}8kp@P^aO#+TE2>jLdn0rg&JoE>xP|2*6I>7&FzFZNU zw6)T1aP`Ll_0CqRKs#55+>5D2eK3}LQwyj9pg=e13}m-Nwh3F6bz|k`Gh=XKu4MKx zCzu`31(s*d(p}M!&%)l8!KuCgr;u*w1*V}7TMK8Gf8;sPDb3j?zbTAV%~l z>rqKA6AlP}3%7*}!UkxUQw4)iUKk?W5;};t#Fo-lbd`4OOEbFsT)8fsHJU*m(3!kJ zR-rn99mVbj>glKjjA6% zv8;#x!&tDCOMxaGL|r*WqNKZ6#0A3>>kv-6*7hu+T2A&)X$fu<4zkEB9R6~JI<2z2Lu23(b zF)L5~Mm~c((Gm3Y^ND_N@0b8S_g$>Mg1q=1Sa1fE9*yV?%nj&Lx2YFGr}0TsO;cYp zN1Lu+Z6HjI%u~&)%#`^DlL{7FrRFK-yQWRXvBnOj0^|6|Ohd6gRyR>IjPsI{(FxUn zYVMU%UZjK1e2u-6-F;l;o$u^T9Yu}^hg`O@?CY|9Wx4hv_Sa=c%3hYuuxB~_Zl`yK zzh2;|KiNORUpLS%cqF#r<+in2Im26S;N zr0H1cshDXD1NPwsR#6|7XcI*E<$se~32M&Um~u3SMxid50#^D0@*^;?0;)OGIrHc~ zbOoRlSCJ$0sV`8lCDGOBc-jwFm8n?A2VlVWM-@|-tN~mqnzTdDKNv{zZs23_I1%2< zZ{#OXu>B8f+6lGRAt=}CNLtjVv=om#IS4){Bc(J6&I0ICbHqX@PA*7wz`png-`^9w zzlj}KL7Ag`RMMb&4j|*Lh7xTz<~BUC_&8!KR`@3Buy&LaTC@VpKaYZuJVh}Q4>7CL zlRJSHyn#p1-`H)jQ0N>YJybfA#a`ej^=)-sjjSH5{!RT!vqyJ6qBK%4%EplK7o$J& zgmJm4qv@Hkg0WU)y~u}=?ISsZqR-Kh@P0~UyOX1Vqjv!oK1z8Z41hzy3-1um_wLHB zF3xLCi>sM)oI}7mraNjn?T+q_R7WcZ;|#f~cmuxCftP`9fuO&AAP`6n&E|IsPsC*C zt|{dZ9G<4i8mIvl!1Ly#TnPx(bj;whh$75Kt|DK)lb*vv=CRx#UD{M78Gkk(tc_o= z<3;G34ubDK1XB?Sh^`K`i667%rsPso21Br3Zd4G@a5{}g)zgA%{a{qgsefQ&tY{#=jGb3+I6`N%1T;}I_+1{$)#SzfMd zracIc(--t+Vj>Xv0eEuW%HxE;f{B3*zA@f;o;L1RuJP_}?l~^OImbD~*~pdWN_RP( z`Ocfp&#s4_?Y{nj1;Jl2M-K$*2dzOPUme`X(b7DuCIdC+TIyQ>OzIH&;}y^+*G8;(QbNp9v9cM+S@lpsJOyK;H<^eSeMFUCfZ6D6?2Ju7p8v&U zc3@`E0n@Y;r8-{8Sl1%#p~*Ps_2_l(O8L?~RN55OzZHRbyQLfOl$ec^WIOQJj>re4 z;1<*dt`~&~xE9~{987*vFde#reNzoRX?5(PBgAmbE4pFY+6)dK`KV&6k^8Wla+JQn zTAwJ3uuo+u7e^CofWQqWyOSE^^Y6$8)Ihoq(}SJDHCJs=EmKue6?5lQ4Ky#bXZ2b` z1B2P{G@?ty&k?N+qYPri#)x@|NIqzxUS>#T2Uv~vv58VY&FUGkAS4($}XO7Ptm>R4ZdKH`<+!71~ zuZ3Rl_k=rQK)Q+N(vEC-8nenJ&{uWF1hXpe-=5G}A0_%>s+on;b+tSaZ-P7QV*+e1o#4U6l!@+CliD}V9y!naFe2?HZTB# zIYQhZRhSrk0+(eedc0KNIrWJx@EJqZM09}KxE1*x)plQUBUKGH#G^0t#fQG%>wlyO_{o#dWz;J)kO9X_nK2wHq}|xCQYe2 z3zNccHA~f_;gZrveO&E^dvSF(o4LsD026iqc@f?NhfvQaDb>Kl_X*2|Lg6IeDzq*5 zb?~>qO@4JSKF})A5%Z~yp?Xm68G=8$4|tn+ll}Rj-NF3OEdHNRFKM%o7Mdrl4SXeh zD@*(`F)8$oP#+WYad58+Kt+B=C@Pejx|Q%1lS;J8=-{kXp)$ z^oT4+d?PJ@hn*r%B=*Yr;sN<0)k_>GZXjMD7pZ{yAOneTm|~{O9-&bvBa|W@R=Uf5 ziTh*;jYdGaO3kLfmtM$ss3pWd@^C!K&5*feVuf%(-b;3uhKdK2&D2-q6zLMq>ttyq zs;mC;5F(cxjm)u#XhyTtSmh7$5-Pm|)F3##c@I7yBrAsN6R}SLdPHGR>9!&_tgk|74!X zM)DAyMoxm}zboB~_7KnDV(}BX8xw%Fj7>F2wTJD;ykwfFQ`FZ~t5^*=icQpDb#L@gpDF40{PWt4)S^vbq&A=%BZKwx$8S{f%19wBi0wetK{%lX2-!D`QRt4U? z%=Z>3SWRecDg>Sidxh-aWVw-aCRh!AcE3pPl(C_^k|_Nlj8S%@Ci(@4j0F|%b*Q>W z3yM6R%9d)PQ`{*}Adbr0qoX==GTd@#x@%g8lg zIX5H@B3I`r4%p`a%ttZ)P~kUj2zfAJWrScJFFc-i5Qra|rA49{yzFh0`I8TZ1JWC)o`I+0<= z{^v6E0Q|xWs55>?<$4~I;vCc$2T)f&mD>S_nFgQqv6wof0!b_f*3@}LQTmX_sVDSr z%pG7T2bmVkIr7n+)34t;GYQAJorn7^6LRmpsT}KPo4$o{~h9CU)K=sff zz5p4QkPZR|DixyPu+m4$l8-4o(G$v_gUnFY&(7ouI7W4z<2agq12oeGhZsHSMMQ34 zZrcM{za37-KTvDcCuXA#(?c0C1vp^_(8742zpcTxpuv(9Tjsfy9n8q!s6F|e((vi&H=)CW8V^z~s*SKA58dFRifZ}K)JYU91 z6~%Wv!#@l4<=bM;GD%zsT;PiM9gxLq@IGse+Vm8BR5qjgs0fVjAFPxF>^B`f#9bhW zG3b#>z+RdMPl$L#+68Cne^=xtBA$nOmd1*A28*UH*2;lZdI?^|V?<{sm}n#LS`4J< z9afIQUieqjIuzCQQ8?Yq0b`&JCNi<`STPb_e7#-h0Jh|L6ntV$cXo1~I@NE(yq3Y-fz#h#4`wF&XT{lTJO6~3;xPTod{0sQy(BCAM~6Ti`wFLSG-hb`DHf&s`7Pz8qUi!^9QcAw$a(N_al(frOL_=| zDi!+L@5Sp->5GzG4k`vR7JJ!27sG$30N>+6_7bM9!>EdI)0_cy`EtR`KMcx&O@WwT zY-lLIP1plpjbix{!O`j1`}I{zx!LS7#sT!$#LTDbQVYTU*(Mv5*~BnvAZFT8stdUL zVVP#SHbbY<4bwc}+S6HzMYIQId4@PO_HDNNwhUXh(#+Bkwkyt>At$+4bwXDfks3M9 zGOOI0ii@j8Rkv2@RpC;(i!tY-$H!|E{*1j~s-^~ST@>Z>WCGKe7~yMc-T%4K$IC^V zOV@pg{dA)+_IaCU6JCygH>LQXUFFVqm-=$~8DzR{uEicxBW_Xbi|C2bVN!$5+6o^Ocn zrth}DUQh_}LNu~(cd8Rpk(;jStzM%}SFcemWbiG0(NokhRPQ$p1B`7= zHq#k%2g_V@qOpO#h?_)q5~ur*JA2wLe0f-;F78}3>{Iloai3F58ShN_0qfFcMr0b| zES(Y(E7z-8C#7bswN-*i&CC4}pPRHk`G=&6v1_zCStX2-yP&?GPo#L(6i2>4TsY~2 zt*F)Krtez3bUjXa6kE`ukpFzRY=*0=d!VnDP=UT2@h0YIxf2QP6Sl{v#ZQW_9^2Zo z)o@N-OkI^ygFbhAM||0Ao1yGR*+~0Oj&EF?_f~)s9ZCZI1?N~9(~tR@nE<5!06l=L zEq4-5!hd%Me;RC+eLx9KGDS?KM8>T8T73Z;yhUoWI#bnwJHhOu;5;k87h?Dg!D)eu z{$KrP{X+to!F{0=ftCzPEi#_IhMPH_bNy87RdZA#SBv|=G@-|ktCg3~2}B7DUp=%c z*ef_c*anV)4q=X@SAHdm$)5C4<`ugbHAXJil3U3hfbVY`>IP9=nI&=J1Kt~&73zn# zN1^HbRN)Sc~qb3H(+c3TLG};#-DR z&(_5l@*+1IZN_G%QKo~&b%xHm1zaz3qu4WGa+kLkl-j;@FKJftxj4Vr{bh>ni1$Z% zG&@UMHR5o@Wn<6S_lZv{zy9iZ)z=j^mb)8mh;qc%PpBP#)l#ZiDZk=BNZDkFIYSwO z^UGEhv!6E>f3a$T@mOae3BoK7vb};8O*PZ z;1o52N5&qiRQX9F3JAaNp5+>KpQe(o&W& zSvMgM-U-TaHbDc7GkoL)CdxoFI(h zZ-(ZFri6}$8uB_J1>Q=X6&3jxmCDRwH*;C4PbyM|$mfNc zh6J#jh|r)=D*u}>N?N8YhRg73@X6-W$G}tC%~WPGsr^ckXb`6I5Ba{BF=kL7thwW*}@GsUcFTboS&MQ7# z^1XdnpoEyOdZv3CvB$8(yd+*-aY5DS>Km)nO>)Iui<%v!jyERUi~ZUZ&3!926L`6V zn#i^!)_8|nGm08~9#E2DyHuk4T>EYB7yF-^-uOSfEGc#^Llkux!Cq` z%VQVEl#6{9vova)Nzm^Do9&UbELh8{b=7lRvWM)I9Sa>3oz2|wzMSAVu~b<@#WQ=E z^~_vwBf7I4*d*o=X;l6ecL=`=iQ+}ggDUb)Er#@=Pl(;3uV z=>Dxx{r^vR0fm1~Xa-iX4?jrQD1MO|V4}5$ETmvK1n(e*bFfQUC+1jf>3WnOY{Ode zd+{!~Yg_m%{%7znY6%{kG6Uh6+=cufWuq0Q0Ep#Nu8>>AePCs#fSy4K#1G0P^i>Un z>AaCI4t)yg_^Es^AshPM6ygp%V^c9*F@kOU3Y@1jdKl@HPm5!q8r~!X1W|Y{B#BL= z-bxyEgmtO6>PANVXn0~UMy5wri!6+2ugg_^4Yk=c{*7;oYrB20ZIiWvZL4*EX&38+ zvT5#j{A_BX>Yi4kuN1M`lpE_V-#t0Kk}fGHZfaD9X`1<$m^(2wESvQ+s9a&MC@B5u z*~}a1q9?ZO$C8aDd&($BiS0kQW&$-`uB7I$g4W;9ZtS@hFA5{{i zj#_O=jQZKq$&_hmqdmi}AycID!3Mrl?kra`*J#&Tm*^^S@9@?Q4B@jS@M@{;bP<@X z|A5Od7gPBJnkM(k&%`+Bp3gxUs*(h;2QcRQ$`-O2J(uako?)M(uFHX5dN=b2-Htj7 zf3J(uOmU>J3McWd(ALoV&;-7*&{P~O{Uxh08(0s&>we5rCZ7F@RhX@en^wcWYXi|; zsV&!%GQ{68$=?n9;3(e|%Heo0S2L8+@YlbH8*!e&h4le@8LX>EV9|A;TT^CWQa{So zq$GG+-3P;T3xAJqBX|Xym?%#Jc9uphrnkV|APP4@ZR198g<$^3^bKeQN|a2wNIWLI z;)nAM@#@9zL8p=~UYC|D?cqZB4c!{7#aOVZZooUW2_-5Eq(g#@kHysb8RpXuz}+;+ zyNI`RXVp;cetnGLmO&HwP2|AHD+a6Ht9iqwk{)qWFy!gzoLhFpdchiNYi4zqYHh{# z2|iBV$s}n0(GAsS8ID=T#rIF5D#;aJCcKY1Xr60Kv1G+$M#q>MYO<8Z!mkoVcK`R5 zAEDUQ-u8P*L#xg~Ia*qCikiMJd-LV(hEJs>*$$KEl4rQDW$2cCl3QpvZSEFzD#~rS zX&DeT!1CO9ARNII2#CAXIT1eYQe98nH6cWtSLyj^Kc<^p|K$JoK@NMV!M_e>|I4{fB55&e{C zSrG}bzOa(7!zV+Bb&ek?bP@+hi{&%QM&^76S zNQ*xRJpYupVeYwFAt^&C2ic3F$NV zepiLX;Pu@ST8SUU{ZMl(RrV5jV51+WN8vkd#CB(^vsX~b4x~p>nPduKlm7=s^ao+8 zkSPonW(g;RWU)Z}D0Ki1Cz0o=58$t4Q4?@m#c9lOCJ{a5QQ|t9>qQB zsxpQe1_y#UTD|_c{_BYJh+Yx#5l?kXGy}Pxs0s2D-r=tSwcR%R%d%hWqwINQ1MKyj zZN0sPM$~!kmL^VjOIJCvM%41S#^r}52IDJ7_cf&%b{P!jXXa?*C+$kAgSbQ7p`4@I zG1-bLz_?D8jVwFsY~{Y-h_=luZu7C-$DE=krS}}?Jny{Md?SLh#C%HBJT_3KB4nbP zrfa52rel%aBA#em>=CwH8@1-y#0N10(E$cbXmDfx~Wn03_6Fd zh&!_OGkLT?mMUGrH=QXR1rKT**l&%%H6Y+zb^^@Mu{a%*nJ&ygrX%C0zk_C{1!*FD zU?Vv+5!erHFgO2V^QoP<}%z}Kafyip@TI`iQ;^rDVRik zuzQ}Nw(TZu0WvlltX(f=?W>@AKSaF(n)4mmQ)w>!gP&?MFpZ(&L{vkAr4Y1sU6}@| zBbrgVAK?;7MAVD0L{!t)*49&H(leF!f)Hrqo#<-i=xx7k|I5yS$N$o?$kUULA)m7; znu&0`t!FS=*2iv5;1bp4CPvRU^*3xcl$l7&65|A21NsnH7IT#)R05NyG!F!!#_m%# z+1b?1J6hRZ6+iiS@MF2+0oD{}AMZh555F_$6`xa#_M_pYakuF!(>7zADbMILtkO5t z3}l~>sd5HiC*blP_l)+e^Zey;d2+llaHTBaPf7KO2+Dv-L|1ww{WqSrAQ;Hi$a2aW zsTkdMTQG{6NEM{vm~+oX9hV7?cM7u|jC(J1hKHa49ZYwopo>x_!Od#0xJ8ip18_UZ z<7*3dge~GKX{US*ccF#Iw@{E9kYRpc(wGpq`bVf-au=~0E-A;s&+P+#*EI0EW(lRj z4)Hf|n6i|P;N9urKCp|f%zTeq4zMIeJt3n=jrc(kH@lRR2ykfrJMquu$=e~7^qR|2)6wqa5;wys{}XPXs=4~@Z(*D z-PRuy+bn27AXBH4snwVf43YBSSQ#%hlgeSAj)7D5Al&JqV{598t9NT^Y3FIrY9DDk zXb-E0b2I2BL=&kzpYKoeZgy{R-E!S^Ih^mERotR?GC!E;&b;GN)tA+sb@`F!EOD{h z<2uLmH+PCG(btG5XXH$O8k%Wi=`r|MPAN21nJ$y(1p2sta-=(&yMOa+aNV%0tj~(a zepzPiZ)xcq%u0-^W_^i98$>EmJdBi^4V>TeT%74yx z(dUO#^(p`O!0zB!ev^1tzDiUE+w?v-vtyulJ_3*IIk>wZO)e*$2jcsSbY1#@q3~pR z0DQ~^vIb2sb8xTIQDzO+@gZG>PNg_x<9YIMC?fNPmVy<$W2I0E4agd-4+KsW;72!taLjzBm9;Ru8y z5RO1N0^taRBM^>2I0E4agd-4+KsW;72!taLjzBm9;Ru8y5RO1N0^taRBM^>2I0E4a zgd-4+KsW;72!taLjzBm9;Ru8y5RO1N0^taRBM^>2I0E4agd-4+KsW;72!taLj==vr G5%@oSuF(zv literal 0 HcmV?d00001 diff --git a/tailwind.config.ts b/tailwind.config.ts new file mode 100644 index 0000000..a2f9ebb --- /dev/null +++ b/tailwind.config.ts @@ -0,0 +1,70 @@ +import type { Config } from "tailwindcss" + +const config: Config = { + darkMode: ["class"], + content: [ + "./app/**/*.{ts,tsx}", + "./components/**/*.{ts,tsx}", + ], + theme: { + extend: { + colors: { + background: "#FFF8F0", + foreground: "#2D3436", + primary: { + DEFAULT: "#8CB8A0", + foreground: "#FFFFFF", + }, + secondary: { + DEFAULT: "#6B8FA3", + foreground: "#FFFFFF", + }, + accent: { + DEFAULT: "#D4A574", + foreground: "#FFFFFF", + }, + success: "#7FB685", + muted: "#E8E0D8", + card: "#FFFFFF", + border: "#E8E0D8", + ring: "#8CB8A0", + }, + borderRadius: { + lg: "var(--radius)", + md: "calc(var(--radius) - 2px)", + sm: "calc(var(--radius) - 4px)", + }, + fontFamily: { + display: ["'Fredoka One'", "Fredoka", "sans-serif"], + sans: ["Inter", "system-ui", "sans-serif"], + }, + keyframes: { + "fade-in": { + from: { opacity: "0" }, + to: { opacity: "1" }, + }, + "slide-up": { + from: { transform: "translateY(10px)", opacity: "0" }, + to: { transform: "translateY(0)", opacity: "1" }, + }, + "bounce-soft": { + "0%, 100%": { transform: "translateY(0)" }, + "50%": { transform: "translateY(-5px)" }, + }, + "pulse-soft": { + "0%, 100%": { opacity: "1" }, + "50%": { opacity: "0.7" }, + }, + }, + animation: { + "fade-in": "fade-in 0.4s ease-out", + "slide-up": "slide-up 0.4s ease-out", + "bounce-soft": "bounce-soft 2s ease-in-out infinite", + "pulse-soft": "pulse-soft 2s ease-in-out infinite", + }, + }, + }, + plugins: [require("tailwindcss-animate")], +} + +export default config diff --git a/test-results/.last-run.json b/test-results/.last-run.json new file mode 100644 index 0000000..cbcc1fb --- /dev/null +++ b/test-results/.last-run.json @@ -0,0 +1,4 @@ +{ + "status": "passed", + "failedTests": [] +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..d81d4ee --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,40 @@ +{ + "compilerOptions": { + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": [ + "./*" + ] + }, + "target": "ES2017" + }, + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ] +}