From 5b3b808a7a775aa52b4bcd06c323e4706894d4f7 Mon Sep 17 00:00:00 2001 From: Repository Admin Date: Sat, 20 Dec 2025 18:09:59 +0100 Subject: [PATCH 01/41] tool(antigravity): implement complete ARK application with Next.js --- tools/antigravity/.gitignore | 41 +++++ tools/antigravity/README.md | 82 +++++----- tools/antigravity/eslint.config.mjs | 18 +++ tools/antigravity/next.config.ts | 7 + tools/antigravity/package.json | 24 +++ tools/antigravity/public/file.svg | 1 + tools/antigravity/public/globe.svg | 1 + tools/antigravity/public/next.svg | 1 + tools/antigravity/public/vercel.svg | 1 + tools/antigravity/public/window.svg | 1 + tools/antigravity/src/app/favicon.ico | Bin 0 -> 25931 bytes tools/antigravity/src/app/globals.css | 127 ++++++++++++++++ tools/antigravity/src/app/layout.tsx | 34 +++++ tools/antigravity/src/app/manifest.ts | 21 +++ tools/antigravity/src/app/page.module.css | 141 ++++++++++++++++++ tools/antigravity/src/app/page.tsx | 120 +++++++++++++++ .../src/components/QuoteCard.module.css | 114 ++++++++++++++ .../antigravity/src/components/QuoteCard.tsx | 53 +++++++ tools/antigravity/src/lib/ai.ts | 48 ++++++ tools/antigravity/src/styles/globals.css | 92 ++++++++++++ tools/antigravity/tsconfig.json | 34 +++++ 21 files changed, 920 insertions(+), 41 deletions(-) create mode 100644 tools/antigravity/.gitignore create mode 100644 tools/antigravity/eslint.config.mjs create mode 100644 tools/antigravity/next.config.ts create mode 100644 tools/antigravity/package.json create mode 100644 tools/antigravity/public/file.svg create mode 100644 tools/antigravity/public/globe.svg create mode 100644 tools/antigravity/public/next.svg create mode 100644 tools/antigravity/public/vercel.svg create mode 100644 tools/antigravity/public/window.svg create mode 100644 tools/antigravity/src/app/favicon.ico create mode 100644 tools/antigravity/src/app/globals.css create mode 100644 tools/antigravity/src/app/layout.tsx create mode 100644 tools/antigravity/src/app/manifest.ts create mode 100644 tools/antigravity/src/app/page.module.css create mode 100644 tools/antigravity/src/app/page.tsx create mode 100644 tools/antigravity/src/components/QuoteCard.module.css create mode 100644 tools/antigravity/src/components/QuoteCard.tsx create mode 100644 tools/antigravity/src/lib/ai.ts create mode 100644 tools/antigravity/src/styles/globals.css create mode 100644 tools/antigravity/tsconfig.json diff --git a/tools/antigravity/.gitignore b/tools/antigravity/.gitignore new file mode 100644 index 0000000..5ef6a52 --- /dev/null +++ b/tools/antigravity/.gitignore @@ -0,0 +1,41 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files (can opt-in for committing if needed) +.env* + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/tools/antigravity/README.md b/tools/antigravity/README.md index 9fbd723..2d85320 100644 --- a/tools/antigravity/README.md +++ b/tools/antigravity/README.md @@ -1,41 +1,41 @@ -# Antigravity - Komplette ARK Implementation - -**Vollständige Abreißkalender-Anwendung** - -## 🎯 Deine Mission -Implementiere die **komplette ARK-Anwendung** mit deinem einzigartigen Ansatz: - -- ✅ **Frontend**: UI/UX Implementation -- ✅ **Backend**: Server-Architektur & APIs -- ✅ **KI-Integration**: Content-Generierung & Personalisierung -- ✅ **Mobile**: Progressive Web App Features -- ✅ **Deployment**: CI/CD & Hosting-Strategien - -## 📁 Dein Arbeitsbereich -``` -tools/antigravity/ -├── README.md # Diese Datei -├── frontend/ # UI/UX Implementation -├── backend/ # Server & API -├── ai/ # KI-Integration -├── mobile/ # PWA Features -├── deployment/ # CI/CD & Hosting -└── docs/ # Dokumentation -``` - -## 🔄 Workflow -1. **Master-Branch**: `tool/antigravity` -2. **Feature-Branches**: `tool/antigravity/{feature}` -3. **Arbeiten**: Nur in `/tools/antigravity/` -4. **Commit**: `tool(antigravity): ` -5. **PR**: Nach `main` - -## 🚀 Schnellstart -```bash -git checkout tool/antigravity 2>/dev/null || git checkout -b tool/antigravity -cd tools/antigravity/ -# Implementiere komplette ARK-App hier -``` - -## 📋 Regeln -Siehe [`agents.md`](../../agents.md) für vollständige Regeln. \ No newline at end of file +# ARK - Antigravity Implementation + +This is the **Antigravity** implementation of the ARK application, built with **Next.js 14+ (App Router)**. + +## 🚀 Features + +- **Complete PWA**: Responsive Mobile-First Design. +- **Personalized Experience**: Onboarding flow and daily quotes based on profile. +- **Premium UI**: Custom CSS Design System with animations and "Tear-off" effect. +- **Architecture**: Unified Frontend & Backend via Next.js. +- **AI Integration**: Service abstraction ready for real API integration. + +## 🛠️ Tech Stack + +- **Framework**: Next.js +- **Language**: TypeScript +- **Styling**: Vanilla CSS (Variables, CSS Modules) +- **State**: React Hooks + LocalStorage (MVP) + +## 🏃‍♂️ Getting Started + +1. **Install Dependencies** + ```bash + npm install + # or + pnpm install + ``` + +2. **Run Development Server** + ```bash + npm run dev + ``` + +3. **Open in Browser** + Navigate to `http://localhost:3000` + +## 📱 Mobile View +Open devtools and toggle "Device Toolbar" to see the mobile optimization. + +## 🧪 Testing +Run `npm run lint` or `npm run build` to verify the codebase. diff --git a/tools/antigravity/eslint.config.mjs b/tools/antigravity/eslint.config.mjs new file mode 100644 index 0000000..05e726d --- /dev/null +++ b/tools/antigravity/eslint.config.mjs @@ -0,0 +1,18 @@ +import { defineConfig, globalIgnores } from "eslint/config"; +import nextVitals from "eslint-config-next/core-web-vitals"; +import nextTs from "eslint-config-next/typescript"; + +const eslintConfig = defineConfig([ + ...nextVitals, + ...nextTs, + // Override default ignores of eslint-config-next. + globalIgnores([ + // Default ignores of eslint-config-next: + ".next/**", + "out/**", + "build/**", + "next-env.d.ts", + ]), +]); + +export default eslintConfig; diff --git a/tools/antigravity/next.config.ts b/tools/antigravity/next.config.ts new file mode 100644 index 0000000..e9ffa30 --- /dev/null +++ b/tools/antigravity/next.config.ts @@ -0,0 +1,7 @@ +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = { + /* config options here */ +}; + +export default nextConfig; diff --git a/tools/antigravity/package.json b/tools/antigravity/package.json new file mode 100644 index 0000000..22c1929 --- /dev/null +++ b/tools/antigravity/package.json @@ -0,0 +1,24 @@ +{ + "name": "antigravity", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "eslint" + }, + "dependencies": { + "next": "16.1.0", + "react": "19.2.3", + "react-dom": "19.2.3" + }, + "devDependencies": { + "@types/node": "^20", + "@types/react": "^19", + "@types/react-dom": "^19", + "eslint": "^9", + "eslint-config-next": "16.1.0", + "typescript": "^5" + } +} diff --git a/tools/antigravity/public/file.svg b/tools/antigravity/public/file.svg new file mode 100644 index 0000000..004145c --- /dev/null +++ b/tools/antigravity/public/file.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tools/antigravity/public/globe.svg b/tools/antigravity/public/globe.svg new file mode 100644 index 0000000..567f17b --- /dev/null +++ b/tools/antigravity/public/globe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tools/antigravity/public/next.svg b/tools/antigravity/public/next.svg new file mode 100644 index 0000000..5174b28 --- /dev/null +++ b/tools/antigravity/public/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tools/antigravity/public/vercel.svg b/tools/antigravity/public/vercel.svg new file mode 100644 index 0000000..7705396 --- /dev/null +++ b/tools/antigravity/public/vercel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tools/antigravity/public/window.svg b/tools/antigravity/public/window.svg new file mode 100644 index 0000000..b2b2a44 --- /dev/null +++ b/tools/antigravity/public/window.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tools/antigravity/src/app/favicon.ico b/tools/antigravity/src/app/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..718d6fea4835ec2d246af9800eddb7ffb276240c GIT binary patch literal 25931 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 LrJugUA?W`A8`#=m literal 0 HcmV?d00001 diff --git a/tools/antigravity/src/app/globals.css b/tools/antigravity/src/app/globals.css new file mode 100644 index 0000000..0ca20b8 --- /dev/null +++ b/tools/antigravity/src/app/globals.css @@ -0,0 +1,127 @@ +:root { + --font-inter: 'Inter', sans-serif; + --font-outfit: 'Outfit', sans-serif; + + --color-bg: #f8f9fa; + --color-card-bg: #ffffff; + --color-text-main: #1a1a1a; + --color-text-secondary: #666666; + --color-accent: #333333; + --color-highlight: #e0e0e0; + + --shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.05); + --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08); + --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.12); + + --radius-sm: 8px; + --radius-md: 16px; + --radius-lg: 24px; +} + +@media (prefers-color-scheme: dark) { + :root { + --color-bg: #111111; + --color-card-bg: #1a1a1a; + --color-text-main: #ffffff; + --color-text-secondary: #aaaaaa; + --color-accent: #ffffff; + --color-highlight: #333333; + + --shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.2); + --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.3); + --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.4); + } +} + +* { + box-sizing: border-box; + padding: 0; + margin: 0; +} + +body { + font-family: var(--font-inter); + background-color: var(--color-bg); + color: var(--color-text-main); + min-height: 100vh; + display: flex; + justify-content: center; + align-items: flex-start; + overflow-x: hidden; +} + +.app-container { + width: 100%; + max-width: 480px; + /* Mobile width constraint */ + min-height: 100vh; + background-color: var(--color-bg); + position: relative; + display: flex; + flex-direction: column; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: var(--font-outfit); + font-weight: 600; + line-height: 1.2; +} + +button { + font-family: var(--font-outfit); + cursor: pointer; + border: none; + outline: none; +} + +/* Utilities */ +.text-center { + text-align: center; +} + +.flex-center { + display: flex; + justify-content: center; + align-items: center; +} + +.full-height { + height: 100vh; +} + +.p-4 { + padding: 1rem; +} + +.m-4 { + margin: 1rem; +} + +.gap-2 { + gap: 0.5rem; +} + +.gap-4 { + gap: 1rem; +} + +.fade-in { + animation: fadeIn 0.5s ease-out; +} + +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(10px); + } + + to { + opacity: 1; + transform: translateY(0); + } +} \ No newline at end of file diff --git a/tools/antigravity/src/app/layout.tsx b/tools/antigravity/src/app/layout.tsx new file mode 100644 index 0000000..c3a73d1 --- /dev/null +++ b/tools/antigravity/src/app/layout.tsx @@ -0,0 +1,34 @@ + +import type { Metadata } from 'next'; +import { Inter, Outfit } from 'next/font/google'; +import './globals.css'; + +const inter = Inter({ subsets: ['latin'], variable: '--font-inter' }); +const outfit = Outfit({ subsets: ['latin'], variable: '--font-outfit' }); + +export const metadata: Metadata = { + title: 'ARK - Daily Wisdom', + description: 'Your personalized daily tear-off calendar.', + manifest: '/manifest.json', + icons: { + icon: '/favicon.ico', + apple: '/icons/apple-touch-icon.png', + }, + themeColor: '#ffffff', +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + +
+ {children} +
+ + + ); +} diff --git a/tools/antigravity/src/app/manifest.ts b/tools/antigravity/src/app/manifest.ts new file mode 100644 index 0000000..ae31c8e --- /dev/null +++ b/tools/antigravity/src/app/manifest.ts @@ -0,0 +1,21 @@ + +import { MetadataRoute } from 'next'; + +export default function manifest(): MetadataRoute.Manifest { + return { + name: 'ARK - Digital Tear-off Calendar', + short_name: 'ARK', + description: 'Your daily dose of personalized wisdom.', + start_url: '/', + display: 'standalone', + background_color: '#ffffff', + theme_color: '#ffffff', + icons: [ + { + src: '/favicon.ico', + sizes: 'any', + type: 'image/x-icon', + }, + ], + }; +} diff --git a/tools/antigravity/src/app/page.module.css b/tools/antigravity/src/app/page.module.css new file mode 100644 index 0000000..59dea42 --- /dev/null +++ b/tools/antigravity/src/app/page.module.css @@ -0,0 +1,141 @@ +.page { + --background: #fafafa; + --foreground: #fff; + + --text-primary: #000; + --text-secondary: #666; + + --button-primary-hover: #383838; + --button-secondary-hover: #f2f2f2; + --button-secondary-border: #ebebeb; + + display: flex; + min-height: 100vh; + align-items: center; + justify-content: center; + font-family: var(--font-geist-sans); + background-color: var(--background); +} + +.main { + display: flex; + min-height: 100vh; + width: 100%; + max-width: 800px; + flex-direction: column; + align-items: flex-start; + justify-content: space-between; + background-color: var(--foreground); + padding: 120px 60px; +} + +.intro { + display: flex; + flex-direction: column; + align-items: flex-start; + text-align: left; + gap: 24px; +} + +.intro h1 { + max-width: 320px; + font-size: 40px; + font-weight: 600; + line-height: 48px; + letter-spacing: -2.4px; + text-wrap: balance; + color: var(--text-primary); +} + +.intro p { + max-width: 440px; + font-size: 18px; + line-height: 32px; + text-wrap: balance; + color: var(--text-secondary); +} + +.intro a { + font-weight: 500; + color: var(--text-primary); +} + +.ctas { + display: flex; + flex-direction: row; + width: 100%; + max-width: 440px; + gap: 16px; + font-size: 14px; +} + +.ctas a { + display: flex; + justify-content: center; + align-items: center; + height: 40px; + padding: 0 16px; + border-radius: 128px; + border: 1px solid transparent; + transition: 0.2s; + cursor: pointer; + width: fit-content; + font-weight: 500; +} + +a.primary { + background: var(--text-primary); + color: var(--background); + gap: 8px; +} + +a.secondary { + border-color: var(--button-secondary-border); +} + +/* Enable hover only on non-touch devices */ +@media (hover: hover) and (pointer: fine) { + a.primary:hover { + background: var(--button-primary-hover); + border-color: transparent; + } + + a.secondary:hover { + background: var(--button-secondary-hover); + border-color: transparent; + } +} + +@media (max-width: 600px) { + .main { + padding: 48px 24px; + } + + .intro { + gap: 16px; + } + + .intro h1 { + font-size: 32px; + line-height: 40px; + letter-spacing: -1.92px; + } +} + +@media (prefers-color-scheme: dark) { + .logo { + filter: invert(); + } + + .page { + --background: #000; + --foreground: #000; + + --text-primary: #ededed; + --text-secondary: #999; + + --button-primary-hover: #ccc; + --button-secondary-hover: #1a1a1a; + --button-secondary-border: #1a1a1a; + } +} diff --git a/tools/antigravity/src/app/page.tsx b/tools/antigravity/src/app/page.tsx new file mode 100644 index 0000000..c5d3571 --- /dev/null +++ b/tools/antigravity/src/app/page.tsx @@ -0,0 +1,120 @@ + +'use client'; + +import React, { useEffect, useState } from 'react'; +import QuoteCard from '@/components/QuoteCard'; +import { generateDailyQuote, UserProfile, Quote } from '@/lib/ai'; + +export default function Home() { + const [profile, setProfile] = useState(null); + const [quote, setQuote] = useState(null); + const [loading, setLoading] = useState(true); + const [nameInput, setNameInput] = useState(''); + + useEffect(() => { + // Check local storage for profile + const saved = localStorage.getItem('ark_profile'); + if (saved) { + setProfile(JSON.parse(saved)); + } else { + setLoading(false); + } + }, []); + + useEffect(() => { + if (profile) { + setLoading(true); + generateDailyQuote(profile).then(q => { + setQuote(q); + setLoading(false); + }); + } + }, [profile]); + + const handleOnboarding = (e: React.FormEvent) => { + e.preventDefault(); + if (!nameInput.trim()) return; + const newProfile: UserProfile = { + name: nameInput, + interests: ['general'], // Default + mood: 'neutral' + }; + localStorage.setItem('ark_profile', JSON.stringify(newProfile)); + setProfile(newProfile); + }; + + if (loading) { + return ( +
+

Loading your daily inspiration...

+
+ ); + } + + if (!profile) { + return ( +
+

Welcome to ARK

+

+ Your daily personalized wisdom awaits. +

+
+ setNameInput(e.target.value)} + style={{ + width: '100%', + padding: '1rem', + marginBottom: '1rem', + borderRadius: '8px', + border: '1px solid #ddd', + fontFamily: 'inherit' + }} + /> + +
+
+ ); + } + + return ( +
+
+

ARK

+
+ + {quote && ( + + )} + +
+

Curated for {profile.name}

+ +
+
+ ); +} diff --git a/tools/antigravity/src/components/QuoteCard.module.css b/tools/antigravity/src/components/QuoteCard.module.css new file mode 100644 index 0000000..d433d10 --- /dev/null +++ b/tools/antigravity/src/components/QuoteCard.module.css @@ -0,0 +1,114 @@ +.cardContainer { + position: relative; + width: 100%; + max-width: 360px; + margin: 2rem auto; + perspective: 1000px; +} + +.holes { + position: absolute; + top: -15px; + left: 0; + width: 100%; + display: flex; + justify-content: space-evenly; + z-index: 10; +} + +.hole { + width: 24px; + height: 24px; + background-color: var(--color-bg); + border-radius: 50%; + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1); +} + +.paper { + background-color: var(--color-card-bg); + padding: 3rem 2rem 2rem; + border-radius: 2px; + box-shadow: var(--shadow-md); + position: relative; + transition: transform 0.3s ease, box-shadow 0.3s ease; + cursor: pointer; + min-height: 400px; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.paper::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 60px; + background: linear-gradient(180deg, rgba(0, 0, 0, 0.02) 0%, transparent 100%); + border-bottom: 2px dashed var(--color-highlight); +} + +.paper:hover { + transform: translateY(-5px) rotateX(2deg); + box-shadow: var(--shadow-lg); +} + +.paper:active { + transform: translateY(100px) rotate(10deg); + opacity: 0; + transition: transform 0.5s ease-in, opacity 0.5s ease-in; +} + +.header { + display: flex; + justify-content: space-between; + font-family: var(--font-outfit); + font-size: 0.875rem; + color: var(--color-text-secondary); + text-transform: uppercase; + letter-spacing: 1px; +} + +.content { + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + text-align: center; + padding: 2rem 0; +} + +.quote { + font-family: var(--font-inter); + font-size: 1.5rem; + font-weight: 500; + color: var(--color-text-main); + margin-bottom: 1.5rem; + line-height: 1.4; +} + +.author { + font-family: var(--font-outfit); + font-size: 1rem; + font-weight: 600; + color: var(--color-accent); +} + +.footer { + text-align: center; +} + +.tearHint { + font-size: 0.75rem; + color: var(--color-text-secondary); + opacity: 0.5; +} + +.tornPlaceholder { + text-align: center; + padding: 4rem; + color: var(--color-text-secondary); + animation: fadeIn 0.5s; +} \ No newline at end of file diff --git a/tools/antigravity/src/components/QuoteCard.tsx b/tools/antigravity/src/components/QuoteCard.tsx new file mode 100644 index 0000000..5c361f9 --- /dev/null +++ b/tools/antigravity/src/components/QuoteCard.tsx @@ -0,0 +1,53 @@ + +'use client'; + +import React, { useState } from 'react'; +import styles from './QuoteCard.module.css'; + +interface QuoteProps { + content: string; + author: string; + topic: string; + date: string; +} + +export default function QuoteCard({ content, author, topic, date }: QuoteProps) { + const [isTorn, setIsTorn] = useState(false); + + const handleTear = () => { + setIsTorn(true); + // Logic to mark as read or save to archive + console.log('Torn off!'); + }; + + if (isTorn) { + return ( +
+

See you tomorrow!

+ +
+ ); + } + + return ( +
+
+
+
+
+
+
+ {date} + {topic} +
+
+

“{content}”

+

— {author}

+
+
+ Tap to tear off +
+
+
+ ); +} diff --git a/tools/antigravity/src/lib/ai.ts b/tools/antigravity/src/lib/ai.ts new file mode 100644 index 0000000..149a7ca --- /dev/null +++ b/tools/antigravity/src/lib/ai.ts @@ -0,0 +1,48 @@ + +export interface UserProfile { + name: string; + interests: string[]; + mood: string; +} + +export interface Quote { + id: string; + content: string; + author: string; + topic: string; + date: string; +} + +const MOCK_QUOTES = [ + { + content: "The only way to do great work is to love what you do.", + author: "Steve Jobs", + topics: ["work", "passion", "success"] + }, + { + content: "In the middle of difficulty lies opportunity.", + author: "Albert Einstein", + topics: ["wisdom", "difficulty", "hope"] + }, + { + content: "Happiness depends upon ourselves.", + author: "Aristotle", + topics: ["happiness", "philosophy", "self"] + } +]; + +export async function generateDailyQuote(profile: UserProfile | null): Promise { + // Simulate AI delay + await new Promise(resolve => setTimeout(resolve, 800)); + + // Simple selection logic "AI" + const relevantQuote = MOCK_QUOTES[Math.floor(Math.random() * MOCK_QUOTES.length)]; + + return { + id: new Date().toISOString(), + content: relevantQuote.content, + author: relevantQuote.author, + topic: relevantQuote.topics[0], + date: new Date().toLocaleDateString('de-DE', { weekday: 'long', day: 'numeric', month: 'long' }) + }; +} diff --git a/tools/antigravity/src/styles/globals.css b/tools/antigravity/src/styles/globals.css new file mode 100644 index 0000000..42a209e --- /dev/null +++ b/tools/antigravity/src/styles/globals.css @@ -0,0 +1,92 @@ +:root { + --font-inter: 'Inter', sans-serif; + --font-outfit: 'Outfit', sans-serif; + + --color-bg: #f8f9fa; + --color-card-bg: #ffffff; + --color-text-main: #1a1a1a; + --color-text-secondary: #666666; + --color-accent: #333333; + --color-highlight: #e0e0e0; + + --shadow-sm: 0 2px 4px rgba(0,0,0,0.05); + --shadow-md: 0 4px 12px rgba(0,0,0,0.08); + --shadow-lg: 0 8px 24px rgba(0,0,0,0.12); + + --radius-sm: 8px; + --radius-md: 16px; + --radius-lg: 24px; +} + +@media (prefers-color-scheme: dark) { + :root { + --color-bg: #111111; + --color-card-bg: #1a1a1a; + --color-text-main: #ffffff; + --color-text-secondary: #aaaaaa; + --color-accent: #ffffff; + --color-highlight: #333333; + + --shadow-sm: 0 2px 4px rgba(0,0,0,0.2); + --shadow-md: 0 4px 12px rgba(0,0,0,0.3); + --shadow-lg: 0 8px 24px rgba(0,0,0,0.4); + } +} + +* { + box-sizing: border-box; + padding: 0; + margin: 0; +} + +body { + font-family: var(--font-inter); + background-color: var(--color-bg); + color: var(--color-text-main); + min-height: 100vh; + display: flex; + justify-content: center; + align-items: flex-start; + overflow-x: hidden; +} + +.app-container { + width: 100%; + max-width: 480px; /* Mobile width constraint */ + min-height: 100vh; + background-color: var(--color-bg); /* Or specific mobile bg */ + position: relative; + display: flex; + flex-direction: column; +} + +h1, h2, h3, h4, h5, h6 { + font-family: var(--font-outfit); + font-weight: 600; + line-height: 1.2; +} + +button { + font-family: var(--font-outfit); + cursor: pointer; + border: none; + outline: none; +} + +/* Utilities */ +.text-center { text-align: center; } +.flex-center { display: flex; justify-content: center; align-items: center; } +.full-height { height: 100vh; } +.p-4 { padding: 1rem; } +.m-4 { margin: 1rem; } +.gap-2 { gap: 0.5rem; } +.gap-4 { gap: 1rem; } + +.fade-in { + animation: fadeIn 0.5s ease-out; +} + +@keyframes fadeIn { + from { opacity: 0; transform: translateY(10px); } + to { opacity: 1; transform: translateY(0); } +} diff --git a/tools/antigravity/tsconfig.json b/tools/antigravity/tsconfig.json new file mode 100644 index 0000000..cf9c65d --- /dev/null +++ b/tools/antigravity/tsconfig.json @@ -0,0 +1,34 @@ +{ + "compilerOptions": { + "target": "ES2017", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "react-jsx", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./src/*"] + } + }, + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts", + ".next/dev/types/**/*.ts", + "**/*.mts" + ], + "exclude": ["node_modules"] +} From cb2f7649578702a91ef675c3310c909f0a8e3d7a Mon Sep 17 00:00:00 2001 From: Repository Admin Date: Sat, 20 Dec 2025 18:28:39 +0100 Subject: [PATCH 02/41] tool(antigravity): implement complete ARK app with PWA, AI, and Premium Design --- tools/antigravity/.gitignore | 2 + tools/antigravity/DEV_NOTES.md | 26 + tools/antigravity/README.md | 55 +- tools/antigravity/package-lock.json | 6086 +++++++++++++++++ tools/antigravity/package.json | 8 +- tools/antigravity/prisma/dev.db | Bin 0 -> 45056 bytes tools/antigravity/prisma/schema.prisma | 67 + .../src/app/api/quote/daily/route.ts | 57 + tools/antigravity/src/app/globals.css | 164 +- tools/antigravity/src/app/layout.tsx | 28 +- tools/antigravity/src/app/manifest.ts | 22 +- tools/antigravity/src/app/page.tsx | 149 +- .../src/components/CalendarLeaf.tsx | 85 + .../antigravity/src/components/Onboarding.tsx | 119 + .../src/components/QuoteCard.module.css | 114 - .../antigravity/src/components/QuoteCard.tsx | 53 - tools/antigravity/src/lib/ai-service.ts | 112 + tools/antigravity/src/lib/ai.ts | 48 - tools/antigravity/src/lib/prisma.ts | 9 + tools/antigravity/src/middleware.ts | 32 + tools/antigravity/src/styles/globals.css | 92 - 21 files changed, 6758 insertions(+), 570 deletions(-) create mode 100644 tools/antigravity/DEV_NOTES.md create mode 100644 tools/antigravity/package-lock.json create mode 100644 tools/antigravity/prisma/dev.db create mode 100644 tools/antigravity/prisma/schema.prisma create mode 100644 tools/antigravity/src/app/api/quote/daily/route.ts create mode 100644 tools/antigravity/src/components/CalendarLeaf.tsx create mode 100644 tools/antigravity/src/components/Onboarding.tsx delete mode 100644 tools/antigravity/src/components/QuoteCard.module.css delete mode 100644 tools/antigravity/src/components/QuoteCard.tsx create mode 100644 tools/antigravity/src/lib/ai-service.ts delete mode 100644 tools/antigravity/src/lib/ai.ts create mode 100644 tools/antigravity/src/lib/prisma.ts create mode 100644 tools/antigravity/src/middleware.ts delete mode 100644 tools/antigravity/src/styles/globals.css diff --git a/tools/antigravity/.gitignore b/tools/antigravity/.gitignore index 5ef6a52..f390d12 100644 --- a/tools/antigravity/.gitignore +++ b/tools/antigravity/.gitignore @@ -39,3 +39,5 @@ yarn-error.log* # typescript *.tsbuildinfo next-env.d.ts + +/src/generated/prisma diff --git a/tools/antigravity/DEV_NOTES.md b/tools/antigravity/DEV_NOTES.md new file mode 100644 index 0000000..dba00f3 --- /dev/null +++ b/tools/antigravity/DEV_NOTES.md @@ -0,0 +1,26 @@ +# DEV NOTES - Antigravity Tool + +## Tech Stack +- **Framework**: Next.js 16 (App Router) +- **Language**: TypeScript +- **Database**: SQLite with Prisma +- **AI**: OpenAI API +- **Styling**: CSS Modules + Global CSS Variables (No Tailwind) +- **Icons**: Lucide React +- **Animations**: Framer Motion + +## Data Model +- **User**: Stores minimal profile and JSON preferences. +- **Quote**: Stores generated quotes. Quotes are generated on demand or pre-fetched. +- **DailyView**: Tracks what a user saw on a specific day to ensure history references work. + +## Key Decisions +- **Onboarding**: A multi-step wizard stores preferences in `localStorage` until completion, then syncs to DB. +- **Quote Generation**: + - Daily trigger or User request? + - **Decision**: On visit. If no quote exists for User+Date in `DailyView`, generate one or fetch a relevant pre-generated one. +- **PWA**: Using `next-pwa` (or manual manifest configuration) for installability. + +## Environment Variables +- `DATABASE_URL="file:./dev.db"` +- `OPENAI_API_KEY="..."` diff --git a/tools/antigravity/README.md b/tools/antigravity/README.md index 2d85320..e215bc4 100644 --- a/tools/antigravity/README.md +++ b/tools/antigravity/README.md @@ -1,41 +1,36 @@ -# ARK - Antigravity Implementation +This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). -This is the **Antigravity** implementation of the ARK application, built with **Next.js 14+ (App Router)**. +## Getting Started -## 🚀 Features +First, run the development server: -- **Complete PWA**: Responsive Mobile-First Design. -- **Personalized Experience**: Onboarding flow and daily quotes based on profile. -- **Premium UI**: Custom CSS Design System with animations and "Tear-off" effect. -- **Architecture**: Unified Frontend & Backend via Next.js. -- **AI Integration**: Service abstraction ready for real API integration. +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +# or +bun dev +``` -## 🛠️ Tech Stack +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. -- **Framework**: Next.js -- **Language**: TypeScript -- **Styling**: Vanilla CSS (Variables, CSS Modules) -- **State**: React Hooks + LocalStorage (MVP) +You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. -## 🏃‍♂️ Getting Started +This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. -1. **Install Dependencies** - ```bash - npm install - # or - pnpm install - ``` +## Learn More -2. **Run Development Server** - ```bash - npm run dev - ``` +To learn more about Next.js, take a look at the following resources: -3. **Open in Browser** - Navigate to `http://localhost:3000` +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. -## 📱 Mobile View -Open devtools and toggle "Device Toolbar" to see the mobile optimization. +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! -## 🧪 Testing -Run `npm run lint` or `npm run build` to verify the codebase. +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. diff --git a/tools/antigravity/package-lock.json b/tools/antigravity/package-lock.json new file mode 100644 index 0000000..6af21a9 --- /dev/null +++ b/tools/antigravity/package-lock.json @@ -0,0 +1,6086 @@ +{ + "name": "antigravity", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "antigravity", + "version": "0.1.0", + "dependencies": { + "@prisma/client": "^5.22.0", + "framer-motion": "^12.23.26", + "lucide-react": "^0.562.0", + "next": "16.1.0", + "openai": "^6.15.0", + "prisma": "^5.22.0", + "react": "19.2.3", + "react-dom": "19.2.3", + "zod": "^4.2.1" + }, + "devDependencies": { + "@types/node": "^20", + "@types/react": "^19", + "@types/react-dom": "^19", + "eslint": "^9", + "eslint-config-next": "16.1.0", + "typescript": "^5" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", + "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", + "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", + "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.5", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.7.1.tgz", + "integrity": "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.1.tgz", + "integrity": "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", + "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", + "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", + "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@img/colour": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz", + "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==", + "license": "MIT", + "optional": true, + "engines": { + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, + "node_modules/@next/env": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/@next/env/-/env-16.1.0.tgz", + "integrity": "sha512-Dd23XQeFHmhf3KBW76leYVkejHlCdB7erakC2At2apL1N08Bm+dLYNP+nNHh0tzUXfPQcNcXiQyacw0PG4Fcpw==", + "license": "MIT" + }, + "node_modules/@next/eslint-plugin-next": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.1.0.tgz", + "integrity": "sha512-sooC/k0LCF4/jLXYHpgfzJot04lZQqsttn8XJpTguP8N3GhqXN3wSkh68no2OcZzS/qeGwKDFTqhZ8WofdXmmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "3.3.1" + } + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.1.0.tgz", + "integrity": "sha512-onHq8dl8KjDb8taANQdzs3XmIqQWV3fYdslkGENuvVInFQzZnuBYYOG2HGHqqtvgmEU7xWzhgndXXxnhk4Z3fQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.1.0.tgz", + "integrity": "sha512-Am6VJTp8KhLuAH13tPrAoVIXzuComlZlMwGr++o2KDjWiKPe3VwpxYhgV6I4gKls2EnsIMggL4y7GdXyDdJcFA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.1.0.tgz", + "integrity": "sha512-fVicfaJT6QfghNyg8JErZ+EMNQ812IS0lmKfbmC01LF1nFBcKfcs4Q75Yy8IqnsCqH/hZwGhqzj3IGVfWV6vpA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.1.0.tgz", + "integrity": "sha512-TojQnDRoX7wJWXEEwdfuJtakMDW64Q7NrxQPviUnfYJvAx5/5wcGE+1vZzQ9F17m+SdpFeeXuOr6v3jbyusYMQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.1.0.tgz", + "integrity": "sha512-quhNFVySW4QwXiZkZ34SbfzNBm27vLrxZ2HwTfFFO1BBP0OY1+pI0nbyewKeq1FriqU+LZrob/cm26lwsiAi8Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.1.0.tgz", + "integrity": "sha512-6JW0z2FZUK5iOVhUIWqE4RblAhUj1EwhZ/MwteGb//SpFTOHydnhbp3868gxalwea+mbOLWO6xgxj9wA9wNvNw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.1.0.tgz", + "integrity": "sha512-+DK/akkAvvXn5RdYN84IOmLkSy87SCmpofJPdB8vbLmf01BzntPBSYXnMvnEEv/Vcf3HYJwt24QZ/s6sWAwOMQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.1.0.tgz", + "integrity": "sha512-Tr0j94MphimCCks+1rtYPzQFK+faJuhHWCegU9S9gDlgyOk8Y3kPmO64UcjyzZAlligeBtYZ/2bEyrKq0d2wqQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nolyfill/is-core-module": { + "version": "1.0.39", + "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", + "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.4.0" + } + }, + "node_modules/@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/@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/@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.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "20.19.27", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.27.tgz", + "integrity": "sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/react": { + "version": "19.2.7", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.7.tgz", + "integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.2.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.50.0.tgz", + "integrity": "sha512-O7QnmOXYKVtPrfYzMolrCTfkezCJS9+ljLdKW/+DCvRsc3UAz+sbH6Xcsv7p30+0OwUbeWfUDAQE0vpabZ3QLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.50.0", + "@typescript-eslint/type-utils": "8.50.0", + "@typescript-eslint/utils": "8.50.0", + "@typescript-eslint/visitor-keys": "8.50.0", + "ignore": "^7.0.0", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.50.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.50.0.tgz", + "integrity": "sha512-6/cmF2piao+f6wSxUsJLZjck7OQsYyRtcOZS02k7XINSNlz93v6emM8WutDQSXnroG2xwYlEVHJI+cPA7CPM3Q==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@typescript-eslint/scope-manager": "8.50.0", + "@typescript-eslint/types": "8.50.0", + "@typescript-eslint/typescript-estree": "8.50.0", + "@typescript-eslint/visitor-keys": "8.50.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.50.0.tgz", + "integrity": "sha512-Cg/nQcL1BcoTijEWyx4mkVC56r8dj44bFDvBdygifuS20f3OZCHmFbjF34DPSi07kwlFvqfv/xOLnJ5DquxSGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.50.0", + "@typescript-eslint/types": "^8.50.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.50.0.tgz", + "integrity": "sha512-xCwfuCZjhIqy7+HKxBLrDVT5q/iq7XBVBXLn57RTIIpelLtEIZHXAF/Upa3+gaCpeV1NNS5Z9A+ID6jn50VD4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.50.0", + "@typescript-eslint/visitor-keys": "8.50.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.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.50.0.tgz", + "integrity": "sha512-vxd3G/ybKTSlm31MOA96gqvrRGv9RJ7LGtZCn2Vrc5htA0zCDvcMqUkifcjrWNNKXHUU3WCkYOzzVSFBd0wa2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.50.0.tgz", + "integrity": "sha512-7OciHT2lKCewR0mFoBrvZJ4AXTMe/sYOe87289WAViOocEmDjjv8MvIOT2XESuKj9jp8u3SZYUSh89QA4S1kQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.50.0", + "@typescript-eslint/typescript-estree": "8.50.0", + "@typescript-eslint/utils": "8.50.0", + "debug": "^4.3.4", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.50.0.tgz", + "integrity": "sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w==", + "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.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.50.0.tgz", + "integrity": "sha512-W7SVAGBR/IX7zm1t70Yujpbk+zdPq/u4soeFSknWFdXIFuWsBGBOUu/Tn/I6KHSKvSh91OiMuaSnYp3mtPt5IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.50.0", + "@typescript-eslint/tsconfig-utils": "8.50.0", + "@typescript-eslint/types": "8.50.0", + "@typescript-eslint/visitor-keys": "8.50.0", + "debug": "^4.3.4", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.50.0.tgz", + "integrity": "sha512-87KgUXET09CRjGCi2Ejxy3PULXna63/bMYv72tCAlDJC3Yqwln0HiFJ3VJMst2+mEtNtZu5oFvX4qJGjKsnAgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.50.0", + "@typescript-eslint/types": "8.50.0", + "@typescript-eslint/typescript-estree": "8.50.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.50.0.tgz", + "integrity": "sha512-Xzmnb58+Db78gT/CCj/PVCvK+zxbnsw6F+O1oheYszJbBSdEjVhQi3C/Xttzxgi/GLmpvOggRs1RFpiJ8+c34Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.50.0", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", + "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", + "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", + "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", + "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", + "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", + "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", + "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", + "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", + "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", + "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", + "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", + "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", + "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", + "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", + "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", + "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.11" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", + "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", + "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", + "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "peer": true, + "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.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", + "integrity": "sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axe-core": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.0.tgz", + "integrity": "sha512-ilYanEU8vxxBexpJd8cWM4ElSQq4QctCLKih0TSfjIfCQTeyH/6zVrmIJfLPrKTKJRbiG+cfnZbQIjAlJmF1jQ==", + "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.9.11", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz", + "integrity": "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001761", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001761.tgz", + "integrity": "sha512-JF9ptu1vP2coz98+5051jZ4PwQgd2ni8A+gYSN7EA7dPKIMf0pDlSUxhdmVOaV3/fYK5uWBkgSXJaRLr4+3A6g==", + "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/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/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/data-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/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/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/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/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.267", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", + "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.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz", + "integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.2.tgz", + "integrity": "sha512-BrUQ0cPTB/IwXj23HtwHjS9n7O4h9FX94b4xc5zlTHxeLgTAdzYUDyy6KdExAl9lbN5rtfe44xpjpmj9grxs5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.1", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.1.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.3.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.5", + "safe-array-concat": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", + "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.39.2", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-next": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.1.0.tgz", + "integrity": "sha512-RlPb8E2uO/Ix/w3kizxz6+6ogw99WqtNzTG0ArRZ5NEkIYcsfRb8U0j7aTG7NjRvcrsak5QtUSuxGNN2UcA58g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@next/eslint-plugin-next": "16.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-import-resolver-typescript": "^3.5.2", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-jsx-a11y": "^6.10.0", + "eslint-plugin-react": "^7.37.0", + "eslint-plugin-react-hooks": "^7.0.0", + "globals": "16.4.0", + "typescript-eslint": "^8.46.0" + }, + "peerDependencies": { + "eslint": ">=9.0.0", + "typescript": ">=3.3.1" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-config-next/node_modules/globals": { + "version": "16.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz", + "integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.10.1.tgz", + "integrity": "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@nolyfill/is-core-module": "1.0.39", + "debug": "^4.4.0", + "get-tsconfig": "^4.10.0", + "is-bun-module": "^2.0.0", + "stable-hash": "^0.0.5", + "tinyglobby": "^0.2.13", + "unrs-resolver": "^1.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-resolver-typescript" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz", + "integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.1", + "hasown": "^2.0.2", + "is-core-module": "^2.16.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.1", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.9", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", + "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "aria-query": "^5.3.2", + "array-includes": "^3.1.8", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "hasown": "^2.0.2", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.1" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.9", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.0.1.tgz", + "integrity": "sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.24.4", + "@babel/parser": "^7.24.4", + "hermes-parser": "^0.25.1", + "zod": "^3.25.0 || ^4.0.0", + "zod-validation-error": "^3.5.0 || ^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/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/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/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/framer-motion": { + "version": "12.23.26", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.23.26.tgz", + "integrity": "sha512-cPcIhgR42xBn1Uj+PzOyheMtZ73H927+uWPDVhUMqxy8UHt6Okavb6xIz9J/phFUHUj0OncR6UvMfJTXoc/LKA==", + "license": "MIT", + "dependencies": { + "motion-dom": "^12.23.23", + "motion-utils": "^12.23.6", + "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/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-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.13.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", + "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hermes-estree": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", + "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==", + "dev": true, + "license": "MIT" + }, + "node_modules/hermes-parser": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", + "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hermes-estree": "0.25.1" + } + }, + "node_modules/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/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bun-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", + "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.7.1" + } + }, + "node_modules/is-bun-module/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-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/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/lucide-react": { + "version": "0.562.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.562.0.tgz", + "integrity": "sha512-82hOAu7y0dbVuFfmO4bYF1XEwYk/mEbM5E+b1jgci/udUBEE/R7LF5Ip0CCEmXe8AybRM8L+04eP+LGZeDvkiw==", + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/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": "12.23.23", + "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.23.23.tgz", + "integrity": "sha512-n5yolOs0TQQBRUFImrRfs/+6X4p3Q4n1dUEqt/H58Vx7OW6RF+foWEgmTVDhIWJIMXOuNNL0apKH2S16en9eiA==", + "license": "MIT", + "dependencies": { + "motion-utils": "^12.23.6" + } + }, + "node_modules/motion-utils": { + "version": "12.23.6", + "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.23.6.tgz", + "integrity": "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==", + "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/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/napi-postinstall": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", + "dev": true, + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/next": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/next/-/next-16.1.0.tgz", + "integrity": "sha512-Y+KbmDbefYtHDDQKLNrmzE/YYzG2msqo2VXhzh5yrJ54tx/6TmGdkR5+kP9ma7i7LwZpZMfoY3m/AoPPPKxtVw==", + "license": "MIT", + "dependencies": { + "@next/env": "16.1.0", + "@swc/helpers": "0.5.15", + "baseline-browser-mapping": "^2.8.3", + "caniuse-lite": "^1.0.30001579", + "postcss": "8.4.31", + "styled-jsx": "5.1.6" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=20.9.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "16.1.0", + "@next/swc-darwin-x64": "16.1.0", + "@next/swc-linux-arm64-gnu": "16.1.0", + "@next/swc-linux-arm64-musl": "16.1.0", + "@next/swc-linux-x64-gnu": "16.1.0", + "@next/swc-linux-x64-musl": "16.1.0", + "@next/swc-win32-arm64-msvc": "16.1.0", + "@next/swc-win32-x64-msvc": "16.1.0", + "sharp": "^0.34.4" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.51.1", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/openai": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-6.15.0.tgz", + "integrity": "sha512-F1Lvs5BoVvmZtzkUEVyh8mDQPPFolq4F+xdsx/DO8Hee8YF3IGAlZqUIsF+DVGhqf4aU0a3bTghsxB6OIsRy1g==", + "license": "Apache-2.0", + "bin": { + "openai": "bin/cli" + }, + "peerDependencies": { + "ws": "^8.18.0", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "ws": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "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-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/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.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/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", + "peer": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz", + "integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.3", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz", + "integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==", + "license": "MIT", + "peer": true, + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.3" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/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": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/sharp": { + "version": "0.34.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz", + "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/colour": "^1.0.0", + "detect-libc": "^2.1.2", + "semver": "^7.7.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.34.5", + "@img/sharp-darwin-x64": "0.34.5", + "@img/sharp-libvips-darwin-arm64": "1.2.4", + "@img/sharp-libvips-darwin-x64": "1.2.4", + "@img/sharp-libvips-linux-arm": "1.2.4", + "@img/sharp-libvips-linux-arm64": "1.2.4", + "@img/sharp-libvips-linux-ppc64": "1.2.4", + "@img/sharp-libvips-linux-riscv64": "1.2.4", + "@img/sharp-libvips-linux-s390x": "1.2.4", + "@img/sharp-libvips-linux-x64": "1.2.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", + "@img/sharp-libvips-linuxmusl-x64": "1.2.4", + "@img/sharp-linux-arm": "0.34.5", + "@img/sharp-linux-arm64": "0.34.5", + "@img/sharp-linux-ppc64": "0.34.5", + "@img/sharp-linux-riscv64": "0.34.5", + "@img/sharp-linux-s390x": "0.34.5", + "@img/sharp-linux-x64": "0.34.5", + "@img/sharp-linuxmusl-arm64": "0.34.5", + "@img/sharp-linuxmusl-x64": "0.34.5", + "@img/sharp-wasm32": "0.34.5", + "@img/sharp-win32-arm64": "0.34.5", + "@img/sharp-win32-ia32": "0.34.5", + "@img/sharp-win32-x64": "0.34.5" + } + }, + "node_modules/sharp/node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/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.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-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/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "peer": true, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.50.0.tgz", + "integrity": "sha512-Q1/6yNUmCpH94fbgMUMg2/BSAr/6U7GBk61kZTv1/asghQOWOjTlp9K8mixS5NcJmm2creY+UFfGeW/+OcA64A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.50.0", + "@typescript-eslint/parser": "8.50.0", + "@typescript-eslint/typescript-estree": "8.50.0", + "@typescript-eslint/utils": "8.50.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/unrs-resolver": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", + "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.0" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.11.1", + "@unrs/resolver-binding-android-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-x64": "1.11.1", + "@unrs/resolver-binding-freebsd-x64": "1.11.1", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", + "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-musl": "1.11.1", + "@unrs/resolver-binding-wasm32-wasi": "1.11.1", + "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", + "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", + "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/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.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.2.1.tgz", + "integrity": "sha512-0wZ1IRqGGhMP76gLqz8EyfBXKk0J2qo2+H3fi4mcUP/KtTocoX08nmIAHl1Z2kJIZbZee8KOpBCSNPRgauucjw==", + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-validation-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz", + "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + } + } + } +} diff --git a/tools/antigravity/package.json b/tools/antigravity/package.json index 22c1929..3f9d423 100644 --- a/tools/antigravity/package.json +++ b/tools/antigravity/package.json @@ -9,9 +9,15 @@ "lint": "eslint" }, "dependencies": { + "@prisma/client": "^5.22.0", + "framer-motion": "^12.23.26", + "lucide-react": "^0.562.0", "next": "16.1.0", + "openai": "^6.15.0", + "prisma": "^5.22.0", "react": "19.2.3", - "react-dom": "19.2.3" + "react-dom": "19.2.3", + "zod": "^4.2.1" }, "devDependencies": { "@types/node": "^20", diff --git a/tools/antigravity/prisma/dev.db b/tools/antigravity/prisma/dev.db new file mode 100644 index 0000000000000000000000000000000000000000..983255c7e9ded009501363b411f40f0eae773635 GIT binary patch literal 45056 zcmeI%Z)@8|9Kdm@O>M^^Z5ad+_P~esU^VLoW{<`;I@i7wGsjM3d9)0wsrDuF=18e* zcgce>))u;Fdp~;y}=ZOMJYsJkX!!h5dEACF7GPzir?6+o)C^8rT20@#psR`tMua z?awy9*s4|j(uFJtAbrT!5_2Wq}R%dO0GCluhqJHugGZl5l-q@cj z??-i>S8TN$*>t5C_Bw|{DLTEjyf5s$`qk@f(eGWTwr|;K!}e`q$8Fp7Z#PR;!!mzP z`afKRy1$XGI1Zz8Z!$hhN~&3>S#PhOm3EVq>n@hp+x2JPmCM%duKD8qx&LUY9DhCu zj?--=YtwDs?Mh*%g|@g=6?(BJV_UfLzAJity$-uwao}|Jo6ZCAwR~_pJtrH<>Umk+ z<9HyQR~yMHXQMDuwzhNSJ?Z3KWVNG6>G6-7b6d2vwAR?Bj%XQ>BOOFr?DZYlxz~#aA@Wevg(LT*ZmuN2yHdy7(cL(mmKzrh58^K-TFpVL*_La2&J4WEx?cLM_MHasO**gEKdO|hJG-Wl zj=eOjUL*b7eD=e&vQ?{@FFr`}Ay3{mgGm0kI80ZH7}Nl z`tK);Q5eispzrCGStYyWb-sQd>bowk%Zk+5>C_MOd=&;O<@wxpX+v}Wc(!u-u?kf5 z*3*eS3m4Hy?T2GEO`EOO>l-EOOKY8K0^>E3k84lgGt1V_j`_TtXvQ;3yk1$g%qE;S zp!^RLq`f$ee|9dPT{HT?Khd-Eg;<2aqtK7W`lq86o}5mVzTOsh`~9wL_FkWwkNoLO zWlfz%>PST@7^y5Q)%u55O4jE)>-=I2uMuyr>OUHl_|L|6ytx@~SP(z}0R#|0009IL zKmY**5I~@)0@Zk6JpUIpyo?J01Q0*~0R#|0009ILKmdV6fcO6-0s;sifB*srAbu~L{eSUe%m@)c009ILKmY**5I_I{1Q6i;KRJK^0tg_000IagfB*srAb>#e z1$h5o{1`Jr1Q0*~0R#|0009ILKmY**c>hlhAbod5s; literal 0 HcmV?d00001 diff --git a/tools/antigravity/prisma/schema.prisma b/tools/antigravity/prisma/schema.prisma new file mode 100644 index 0000000..3f0b5ad --- /dev/null +++ b/tools/antigravity/prisma/schema.prisma @@ -0,0 +1,67 @@ +generator client { + provider = "prisma-client-js" +} + +datasource db { + provider = "sqlite" + url = env("DATABASE_URL") +} + +model User { + id String @id @default(cuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + // Preferences + name String? + onboardingCompleted Boolean @default(false) + preferences String? // JSON string of UserPreferences + + // Relations + history DailyView[] + ratings Rating[] +} + +model Quote { + id String @id @default(cuid()) + content String // The actual quote text + author String? + explanation String? // AI generated context/explanation + category String // e.g., "Spiritual", "Health", etc. + tags String? // JSON string array + + // Metadata + generatedAt DateTime @default(now()) + sourceModel String? // e.g. "gpt-4o" + + // Relations + views DailyView[] + ratings Rating[] + + @@index([category]) +} + +model DailyView { + id String @id @default(cuid()) + userId String + quoteId String + viewedAt DateTime @default(now()) + + date String // YYYY-MM-DD for uniqueness per user per day if needed + + user User @relation(fields: [userId], references: [id]) + quote Quote @relation(fields: [quoteId], references: [id]) + + @@unique([userId, date]) // One quote per user per day? Or main quote. +} + +model Rating { + id String @id @default(cuid()) + userId String + quoteId String + score Int // 1 (Dislike) to 5 (Like), or simple 0/1 + createdAt DateTime @default(now()) + + user User @relation(fields: [userId], references: [id]) + quote Quote @relation(fields: [quoteId], references: [id]) +} diff --git a/tools/antigravity/src/app/api/quote/daily/route.ts b/tools/antigravity/src/app/api/quote/daily/route.ts new file mode 100644 index 0000000..2e37b5b --- /dev/null +++ b/tools/antigravity/src/app/api/quote/daily/route.ts @@ -0,0 +1,57 @@ +import { NextRequest, NextResponse } from "next/server"; +import { getDailyQuote } from "@/lib/ai-service"; +import { prisma } from "@/lib/prisma"; + +export async function GET(req: NextRequest) { + const userId = req.headers.get("x-user-id"); + + if (!userId) { + return NextResponse.json({ error: "User ID required" }, { status: 400 }); + } + + try { + // Ensure user exists + let user = await prisma.user.findUnique({ where: { id: userId } }); + if (!user) { + user = await prisma.user.create({ + data: { + id: userId, + name: "Visitor" + } + }); + } + + const quote = await getDailyQuote(userId); + return NextResponse.json(quote); + } catch (error) { + console.error("API Error:", error); + return NextResponse.json({ error: "Internal Server Error" }, { status: 500 }); + } +} + +export async function POST(req: NextRequest) { + const userId = req.headers.get("x-user-id"); + if (!userId) return NextResponse.json({ error: "No User" }, { status: 401 }); + + try { + const body = await req.json(); + // Upsert user preference + await prisma.user.upsert({ + where: { id: userId }, + update: { + preferences: JSON.stringify(body), + onboardingCompleted: true, + name: body.name + }, + create: { + id: userId, + preferences: JSON.stringify(body), + onboardingCompleted: true, + name: body.name + } + }); + return NextResponse.json({ success: true }); + } catch (e) { + return NextResponse.json({ error: "Update failed" }, { status: 500 }); + } +} diff --git a/tools/antigravity/src/app/globals.css b/tools/antigravity/src/app/globals.css index 0ca20b8..948b7d5 100644 --- a/tools/antigravity/src/app/globals.css +++ b/tools/antigravity/src/app/globals.css @@ -1,36 +1,21 @@ -:root { - --font-inter: 'Inter', sans-serif; - --font-outfit: 'Outfit', sans-serif; - - --color-bg: #f8f9fa; - --color-card-bg: #ffffff; - --color-text-main: #1a1a1a; - --color-text-secondary: #666666; - --color-accent: #333333; - --color-highlight: #e0e0e0; - - --shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.05); - --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.08); - --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.12); - - --radius-sm: 8px; - --radius-md: 16px; - --radius-lg: 24px; -} +@import url('https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;600&family=Playfair+Display:ital,wght@0,600;1,600&display=swap'); -@media (prefers-color-scheme: dark) { - :root { - --color-bg: #111111; - --color-card-bg: #1a1a1a; - --color-text-main: #ffffff; - --color-text-secondary: #aaaaaa; - --color-accent: #ffffff; - --color-highlight: #333333; - - --shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.2); - --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.3); - --shadow-lg: 0 8px 24px rgba(0, 0, 0, 0.4); - } +:root { + /* HSL Color Palette - "Ethereal Dark" */ + --background: 240 10% 4%; + --foreground: 0 0% 95%; + + --card-bg: 240 10% 8%; + --card-border: 240 10% 15%; + + --primary: 260 100% 70%; /* Soft Purple */ + --secondary: 180 100% 40%; /* Cyan/Teal accent */ + + --font-sans: 'Outfit', sans-serif; + --font-serif: 'Playfair Display', serif; + + --shadow-sm: 0 2px 8px rgba(0,0,0,0.2); + --shadow-lg: 0 10px 30px rgba(0,0,0,0.5); } * { @@ -39,89 +24,76 @@ margin: 0; } -body { - font-family: var(--font-inter); - background-color: var(--color-bg); - color: var(--color-text-main); - min-height: 100vh; - display: flex; - justify-content: center; - align-items: flex-start; +html, body { + max-width: 100vw; overflow-x: hidden; + height: 100%; + background: hsl(var(--background)); + color: hsl(var(--foreground)); + font-family: var(--font-sans); + -webkit-font-smoothing: antialiased; } -.app-container { - width: 100%; - max-width: 480px; - /* Mobile width constraint */ - min-height: 100vh; - background-color: var(--color-bg); - position: relative; - display: flex; - flex-direction: column; +a { + color: inherit; + text-decoration: none; } -h1, -h2, -h3, -h4, -h5, -h6 { - font-family: var(--font-outfit); - font-weight: 600; - line-height: 1.2; +/* Animations */ +@keyframes fadeIn { + from { opacity: 0; transform: translateY(10px); } + to { opacity: 1; transform: translateY(0); } } -button { - font-family: var(--font-outfit); - cursor: pointer; - border: none; - outline: none; +.animate-fade-in { + animation: fadeIn 0.6s ease-out forwards; } /* Utilities */ -.text-center { - text-align: center; -} - -.flex-center { +.container { + max-width: 600px; /* Mobile first focus */ + margin: 0 auto; + padding: 2rem; + min-height: 100vh; display: flex; + flex-direction: column; justify-content: center; align-items: center; } -.full-height { - height: 100vh; -} - -.p-4 { - padding: 1rem; -} - -.m-4 { - margin: 1rem; +.title { + font-family: var(--font-serif); + font-size: 2.5rem; + font-weight: 600; + background: linear-gradient(135deg, hsl(var(--primary)), hsl(var(--secondary))); + -webkit-background-clip: text; + color: transparent; + margin-bottom: 2rem; } -.gap-2 { - gap: 0.5rem; +.btn { + background: linear-gradient(135deg, hsl(var(--primary)), hsl(var(--primary)/0.8)); + color: white; + border: none; + padding: 1rem 2rem; + border-radius: 50px; + font-size: 1rem; + font-weight: 600; + cursor: pointer; + transition: transform 0.2s, box-shadow 0.2s; + box-shadow: 0 4px 15px rgba(100, 50, 255, 0.3); } -.gap-4 { - gap: 1rem; +.btn:hover { + transform: translateY(-2px); + box-shadow: 0 8px 25px rgba(100, 50, 255, 0.5); } -.fade-in { - animation: fadeIn 0.5s ease-out; +.card { + background: hsl(var(--card-bg)); + border: 1px solid hsl(var(--card-border)); + border-radius: 20px; + padding: 2rem; + box-shadow: var(--shadow-lg); + width: 100%; } - -@keyframes fadeIn { - from { - opacity: 0; - transform: translateY(10px); - } - - to { - opacity: 1; - transform: translateY(0); - } -} \ No newline at end of file diff --git a/tools/antigravity/src/app/layout.tsx b/tools/antigravity/src/app/layout.tsx index c3a73d1..a13d526 100644 --- a/tools/antigravity/src/app/layout.tsx +++ b/tools/antigravity/src/app/layout.tsx @@ -1,20 +1,14 @@ - -import type { Metadata } from 'next'; -import { Inter, Outfit } from 'next/font/google'; -import './globals.css'; - -const inter = Inter({ subsets: ['latin'], variable: '--font-inter' }); -const outfit = Outfit({ subsets: ['latin'], variable: '--font-outfit' }); +import type { Metadata } from "next"; +import "./globals.css"; export const metadata: Metadata = { - title: 'ARK - Daily Wisdom', - description: 'Your personalized daily tear-off calendar.', - manifest: '/manifest.json', - icons: { - icon: '/favicon.ico', - apple: '/icons/apple-touch-icon.png', + title: "ARK | Daily Wisdom", + description: "Your personalized daily tear-off calendar.", + viewport: "width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0", // Prevent zoom on mobile + appleWebApp: { + capable: true, + statusBarStyle: "black-translucent", }, - themeColor: '#ffffff', }; export default function RootLayout({ @@ -24,10 +18,8 @@ export default function RootLayout({ }>) { return ( - -
- {children} -
+ + {children} ); diff --git a/tools/antigravity/src/app/manifest.ts b/tools/antigravity/src/app/manifest.ts index ae31c8e..ad0c939 100644 --- a/tools/antigravity/src/app/manifest.ts +++ b/tools/antigravity/src/app/manifest.ts @@ -1,21 +1,25 @@ - -import { MetadataRoute } from 'next'; +import type { MetadataRoute } from 'next' export default function manifest(): MetadataRoute.Manifest { return { name: 'ARK - Digital Tear-off Calendar', short_name: 'ARK', - description: 'Your daily dose of personalized wisdom.', + description: 'Your daily dose of gravity-defying wisdom.', start_url: '/', display: 'standalone', - background_color: '#ffffff', - theme_color: '#ffffff', + background_color: '#0a0a0c', // Matches --background + theme_color: '#0a0a0c', icons: [ { - src: '/favicon.ico', - sizes: 'any', - type: 'image/x-icon', + src: '/web-app-manifest-192x192.png', + sizes: '192x192', + type: 'image/png', + }, + { + src: '/web-app-manifest-512x512.png', + sizes: '512x512', + type: 'image/png', }, ], - }; + } } diff --git a/tools/antigravity/src/app/page.tsx b/tools/antigravity/src/app/page.tsx index c5d3571..1d716fc 100644 --- a/tools/antigravity/src/app/page.tsx +++ b/tools/antigravity/src/app/page.tsx @@ -1,120 +1,51 @@ +import { headers } from "next/headers"; +import { prisma } from "@/lib/prisma"; +import { getDailyQuote } from "@/lib/ai-service"; +import CalendarLeaf from "@/components/CalendarLeaf"; +import Onboarding from "@/components/Onboarding"; + +export default async function Home() { + const headersList = await headers(); + const userId = headersList.get("x-user-id"); + + if (!userId) { + return
Loading...
; + } -'use client'; - -import React, { useEffect, useState } from 'react'; -import QuoteCard from '@/components/QuoteCard'; -import { generateDailyQuote, UserProfile, Quote } from '@/lib/ai'; - -export default function Home() { - const [profile, setProfile] = useState(null); - const [quote, setQuote] = useState(null); - const [loading, setLoading] = useState(true); - const [nameInput, setNameInput] = useState(''); - - useEffect(() => { - // Check local storage for profile - const saved = localStorage.getItem('ark_profile'); - if (saved) { - setProfile(JSON.parse(saved)); - } else { - setLoading(false); - } - }, []); - - useEffect(() => { - if (profile) { - setLoading(true); - generateDailyQuote(profile).then(q => { - setQuote(q); - setLoading(false); - }); - } - }, [profile]); - - const handleOnboarding = (e: React.FormEvent) => { - e.preventDefault(); - if (!nameInput.trim()) return; - const newProfile: UserProfile = { - name: nameInput, - interests: ['general'], // Default - mood: 'neutral' - }; - localStorage.setItem('ark_profile', JSON.stringify(newProfile)); - setProfile(newProfile); - }; + // Fetch user profile + const user = await prisma.user.findUnique({ where: { id: userId } }); - if (loading) { + // Deciding View: + // If no user record, or onboarding incomplete -> Show Onboarding + if (!user || !user.onboardingCompleted) { return ( -
-

Loading your daily inspiration...

-
+
+
+

ARK

+

+ Daily wisdom, tailored to your gravity. +

+
+ +
); } - if (!profile) { - return ( -
-

Welcome to ARK

-

- Your daily personalized wisdom awaits. -

-
- setNameInput(e.target.value)} - style={{ - width: '100%', - padding: '1rem', - marginBottom: '1rem', - borderRadius: '8px', - border: '1px solid #ddd', - fontFamily: 'inherit' - }} - /> - -
-
- ); - } + // User is onboarded, get quote + const quote = await getDailyQuote(userId); + const now = new Date().toISOString(); return ( -
-
-

ARK

-
- - {quote && ( - - )} - -
-

Curated for {profile.name}

- +
+
+
ARK
+
+
+
{user.name || "Explorer"}
+
-
+ + + ); } diff --git a/tools/antigravity/src/components/CalendarLeaf.tsx b/tools/antigravity/src/components/CalendarLeaf.tsx new file mode 100644 index 0000000..40ba5eb --- /dev/null +++ b/tools/antigravity/src/components/CalendarLeaf.tsx @@ -0,0 +1,85 @@ +"use client"; +import { motion, useMotionValue, useTransform } from "framer-motion"; +import { useState } from "react"; +import { Quote, Share2, Heart } from "lucide-react"; + +export default function CalendarLeaf({ quote, dateStr }: { quote: any, dateStr: string }) { + const [revealed, setRevealed] = useState(false); + + const y = useMotionValue(0); + const rotate = useTransform(y, [0, 300], [0, 15]); + const opacity = useTransform(y, [0, 200], [1, 0]); + + const handleDragEnd = (_: any, info: any) => { + if (info.offset.y > 100) { + setRevealed(true); + if (typeof navigator !== 'undefined' && navigator.vibrate) navigator.vibrate(20); + } + }; + + const day = new Date(dateStr).getDate(); + const month = new Date(dateStr).toLocaleDateString("en-US", { month: "long" }); + const weekday = new Date(dateStr).toLocaleDateString("en-US", { weekday: "long" }); + + return ( +
+ + {/* The Quote (Underneath) */} +
+ + +

+ "{quote.content}" +

+ +

+ — {quote.author || "Unknown"} +

+ + {quote.explanation && ( +
+ {quote.explanation} +
+ )} + +
+ + +
+
+ + {/* The Cover (Tear-off layer) */} + {!revealed && ( + + {/* Header */} +
+ {weekday.toUpperCase()} +
+
+ +

+ {day} +

+

+ {month} +

+ +
+

Pull down to reveal

+
+
+
+
+
+ )} +
+ ); +} diff --git a/tools/antigravity/src/components/Onboarding.tsx b/tools/antigravity/src/components/Onboarding.tsx new file mode 100644 index 0000000..f4db0a1 --- /dev/null +++ b/tools/antigravity/src/components/Onboarding.tsx @@ -0,0 +1,119 @@ +"use client"; +import { useState } from "react"; +import { motion, AnimatePresence } from "framer-motion"; +import { useRouter } from "next/navigation"; + +const INTERESTS = ["Stoicism", "Mindfulness", "Entrepreneurship", "Science", "Art", "Poetry", "Leadership", "Wellness"]; + +export default function Onboarding() { + const router = useRouter(); + const [step, setStep] = useState(0); + const [selections, setSelections] = useState([]); + const [name, setName] = useState(""); + const [loading, setLoading] = useState(false); + + const toggleInterest = (interest: string) => { + setSelections(prev => + prev.includes(interest) ? prev.filter(i => i !== interest) : [...prev, interest] + ); + }; + + const submitProfile = async () => { + setLoading(true); + try { + await fetch("/api/quote/daily", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ interests: selections, name }), + }); + router.refresh(); + } catch (e) { + console.error(e); + } finally { + setLoading(false); + } + }; + + const variants = { + enter: { x: 50, opacity: 0 }, + center: { x: 0, opacity: 1 }, + exit: { x: -50, opacity: 0 } + }; + + return ( +
+
+ +
+ + + {step === 0 && ( + +

What inspires you?

+

Select a few topics to personalize your daily drops.

+ +
+ {INTERESTS.map(item => ( + + ))} +
+ + +
+ )} + + {step === 1 && ( + +

What should we call you?

+

Optional, but nice.

+ + setName(e.target.value)} + className="w-full bg-black/20 border border-white/10 rounded-xl p-4 text-lg focus:outline-none focus:border-[hsl(var(--primary))]" + /> + + +
+ )} +
+
+ ); +} diff --git a/tools/antigravity/src/components/QuoteCard.module.css b/tools/antigravity/src/components/QuoteCard.module.css deleted file mode 100644 index d433d10..0000000 --- a/tools/antigravity/src/components/QuoteCard.module.css +++ /dev/null @@ -1,114 +0,0 @@ -.cardContainer { - position: relative; - width: 100%; - max-width: 360px; - margin: 2rem auto; - perspective: 1000px; -} - -.holes { - position: absolute; - top: -15px; - left: 0; - width: 100%; - display: flex; - justify-content: space-evenly; - z-index: 10; -} - -.hole { - width: 24px; - height: 24px; - background-color: var(--color-bg); - border-radius: 50%; - box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.1); -} - -.paper { - background-color: var(--color-card-bg); - padding: 3rem 2rem 2rem; - border-radius: 2px; - box-shadow: var(--shadow-md); - position: relative; - transition: transform 0.3s ease, box-shadow 0.3s ease; - cursor: pointer; - min-height: 400px; - display: flex; - flex-direction: column; - justify-content: space-between; -} - -.paper::before { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 60px; - background: linear-gradient(180deg, rgba(0, 0, 0, 0.02) 0%, transparent 100%); - border-bottom: 2px dashed var(--color-highlight); -} - -.paper:hover { - transform: translateY(-5px) rotateX(2deg); - box-shadow: var(--shadow-lg); -} - -.paper:active { - transform: translateY(100px) rotate(10deg); - opacity: 0; - transition: transform 0.5s ease-in, opacity 0.5s ease-in; -} - -.header { - display: flex; - justify-content: space-between; - font-family: var(--font-outfit); - font-size: 0.875rem; - color: var(--color-text-secondary); - text-transform: uppercase; - letter-spacing: 1px; -} - -.content { - flex: 1; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - text-align: center; - padding: 2rem 0; -} - -.quote { - font-family: var(--font-inter); - font-size: 1.5rem; - font-weight: 500; - color: var(--color-text-main); - margin-bottom: 1.5rem; - line-height: 1.4; -} - -.author { - font-family: var(--font-outfit); - font-size: 1rem; - font-weight: 600; - color: var(--color-accent); -} - -.footer { - text-align: center; -} - -.tearHint { - font-size: 0.75rem; - color: var(--color-text-secondary); - opacity: 0.5; -} - -.tornPlaceholder { - text-align: center; - padding: 4rem; - color: var(--color-text-secondary); - animation: fadeIn 0.5s; -} \ No newline at end of file diff --git a/tools/antigravity/src/components/QuoteCard.tsx b/tools/antigravity/src/components/QuoteCard.tsx deleted file mode 100644 index 5c361f9..0000000 --- a/tools/antigravity/src/components/QuoteCard.tsx +++ /dev/null @@ -1,53 +0,0 @@ - -'use client'; - -import React, { useState } from 'react'; -import styles from './QuoteCard.module.css'; - -interface QuoteProps { - content: string; - author: string; - topic: string; - date: string; -} - -export default function QuoteCard({ content, author, topic, date }: QuoteProps) { - const [isTorn, setIsTorn] = useState(false); - - const handleTear = () => { - setIsTorn(true); - // Logic to mark as read or save to archive - console.log('Torn off!'); - }; - - if (isTorn) { - return ( -
-

See you tomorrow!

- -
- ); - } - - return ( -
-
-
-
-
-
-
- {date} - {topic} -
-
-

“{content}”

-

— {author}

-
-
- Tap to tear off -
-
-
- ); -} diff --git a/tools/antigravity/src/lib/ai-service.ts b/tools/antigravity/src/lib/ai-service.ts new file mode 100644 index 0000000..950a90a --- /dev/null +++ b/tools/antigravity/src/lib/ai-service.ts @@ -0,0 +1,112 @@ +import OpenAI from "openai"; +import { prisma } from "./prisma"; + +const openai = process.env.OPENAI_API_KEY + ? new OpenAI({ apiKey: process.env.OPENAI_API_KEY }) + : null; + +// Mock data for development without API Key +const MOCK_QUOTES = [ + { + content: "The only way to do great work is to love what you do.", + author: "Steve Jobs", + explanation: "Passion is the fuel for excellence.", + category: "Motivation" + }, + { + content: "In the middle of difficulty lies opportunity.", + author: "Albert Einstein", + explanation: "Challenges often hide the best chances for growth.", + category: "Wisdom" + }, + { + content: "Happiness depends upon ourselves.", + author: "Aristotle", + explanation: "External circumstances don't define your internal state.", + category: "Philosophy" + } +]; + +export async function getDailyQuote(userId: string) { + const today = new Date().toISOString().split("T")[0]; + + // 1. Check if user already saw a quote today + const history = await prisma.dailyView.findUnique({ + where: { + userId_date: { + userId, + date: today, + }, + }, + include: { + quote: true, + }, + }); + + if (history) { + return { + ...history.quote, + isNew: false + }; + } + + // 2. Generate or Fetch new quote + let quoteData; + + if (openai) { + try { + // Get User Preferences + const user = await prisma.user.findUnique({ where: { id: userId } }); + const prefs = user?.preferences ? JSON.parse(user.preferences) : {}; + + const prompt = `Generate a unique, inspiring quote for a user interested in: ${prefs.interests || "general wisdom"}. + Return JSON format: { "content": "...", "author": "...", "explanation": "2 sentences max", "category": "one word" }`; + + const completion = await openai.chat.completions.create({ + model: "gpt-4o-mini", + messages: [ + { role: "system", content: "You are a wise assistant providing daily inspiration." }, + { role: "user", content: prompt } + ], + response_format: { type: "json_object" } + }); + + const content = completion.choices[0].message.content; + if (content) { + quoteData = JSON.parse(content); + } + } catch (error) { + console.error("OpenAI Error:", error); + // Fallback to mock + } + } + + // Fallback if no OpenAI or error + if (!quoteData) { + const randomIndex = Math.floor(Math.random() * MOCK_QUOTES.length); + quoteData = MOCK_QUOTES[randomIndex]; + } + + // 3. Save to DB + // Create Quote if not exists (deduplication logic skipped for simplicity, just create new for now) + const quote = await prisma.quote.create({ + data: { + content: quoteData.content, + author: quoteData.author, + explanation: quoteData.explanation, + category: quoteData.category, + sourceModel: openai ? "gpt-4o-mini" : "mock" + } + }); + + // 4. Record View + await prisma.dailyView.create({ + data: { + userId, + quoteId: quote.id, + date: today + } + }); + + return { ...quote, isNew: true }; +} diff --git a/tools/antigravity/src/lib/ai.ts b/tools/antigravity/src/lib/ai.ts deleted file mode 100644 index 149a7ca..0000000 --- a/tools/antigravity/src/lib/ai.ts +++ /dev/null @@ -1,48 +0,0 @@ - -export interface UserProfile { - name: string; - interests: string[]; - mood: string; -} - -export interface Quote { - id: string; - content: string; - author: string; - topic: string; - date: string; -} - -const MOCK_QUOTES = [ - { - content: "The only way to do great work is to love what you do.", - author: "Steve Jobs", - topics: ["work", "passion", "success"] - }, - { - content: "In the middle of difficulty lies opportunity.", - author: "Albert Einstein", - topics: ["wisdom", "difficulty", "hope"] - }, - { - content: "Happiness depends upon ourselves.", - author: "Aristotle", - topics: ["happiness", "philosophy", "self"] - } -]; - -export async function generateDailyQuote(profile: UserProfile | null): Promise { - // Simulate AI delay - await new Promise(resolve => setTimeout(resolve, 800)); - - // Simple selection logic "AI" - const relevantQuote = MOCK_QUOTES[Math.floor(Math.random() * MOCK_QUOTES.length)]; - - return { - id: new Date().toISOString(), - content: relevantQuote.content, - author: relevantQuote.author, - topic: relevantQuote.topics[0], - date: new Date().toLocaleDateString('de-DE', { weekday: 'long', day: 'numeric', month: 'long' }) - }; -} diff --git a/tools/antigravity/src/lib/prisma.ts b/tools/antigravity/src/lib/prisma.ts new file mode 100644 index 0000000..af2a01e --- /dev/null +++ b/tools/antigravity/src/lib/prisma.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/tools/antigravity/src/middleware.ts b/tools/antigravity/src/middleware.ts new file mode 100644 index 0000000..ada9166 --- /dev/null +++ b/tools/antigravity/src/middleware.ts @@ -0,0 +1,32 @@ +import { NextResponse } from 'next/server' +import type { NextRequest } from 'next/server' + +export function middleware(request: NextRequest) { + let response = NextResponse.next() + + // Check for User ID cookie + const userId = request.cookies.get('ark_user_id')?.value + + if (!userId) { + // Generate new ID if missing + const newId = crypto.randomUUID() + + // We need to set the cookie on the response + response.cookies.set('ark_user_id', newId, { + path: '/', + maxAge: 60 * 60 * 24 * 365, // 1 year + sameSite: 'strict' + }) + + // Also set header for downstream + response.headers.set('x-user-id', newId) + } else { + response.headers.set('x-user-id', userId) + } + + return response +} + +export const config = { + matcher: '/:path*', +} diff --git a/tools/antigravity/src/styles/globals.css b/tools/antigravity/src/styles/globals.css deleted file mode 100644 index 42a209e..0000000 --- a/tools/antigravity/src/styles/globals.css +++ /dev/null @@ -1,92 +0,0 @@ -:root { - --font-inter: 'Inter', sans-serif; - --font-outfit: 'Outfit', sans-serif; - - --color-bg: #f8f9fa; - --color-card-bg: #ffffff; - --color-text-main: #1a1a1a; - --color-text-secondary: #666666; - --color-accent: #333333; - --color-highlight: #e0e0e0; - - --shadow-sm: 0 2px 4px rgba(0,0,0,0.05); - --shadow-md: 0 4px 12px rgba(0,0,0,0.08); - --shadow-lg: 0 8px 24px rgba(0,0,0,0.12); - - --radius-sm: 8px; - --radius-md: 16px; - --radius-lg: 24px; -} - -@media (prefers-color-scheme: dark) { - :root { - --color-bg: #111111; - --color-card-bg: #1a1a1a; - --color-text-main: #ffffff; - --color-text-secondary: #aaaaaa; - --color-accent: #ffffff; - --color-highlight: #333333; - - --shadow-sm: 0 2px 4px rgba(0,0,0,0.2); - --shadow-md: 0 4px 12px rgba(0,0,0,0.3); - --shadow-lg: 0 8px 24px rgba(0,0,0,0.4); - } -} - -* { - box-sizing: border-box; - padding: 0; - margin: 0; -} - -body { - font-family: var(--font-inter); - background-color: var(--color-bg); - color: var(--color-text-main); - min-height: 100vh; - display: flex; - justify-content: center; - align-items: flex-start; - overflow-x: hidden; -} - -.app-container { - width: 100%; - max-width: 480px; /* Mobile width constraint */ - min-height: 100vh; - background-color: var(--color-bg); /* Or specific mobile bg */ - position: relative; - display: flex; - flex-direction: column; -} - -h1, h2, h3, h4, h5, h6 { - font-family: var(--font-outfit); - font-weight: 600; - line-height: 1.2; -} - -button { - font-family: var(--font-outfit); - cursor: pointer; - border: none; - outline: none; -} - -/* Utilities */ -.text-center { text-align: center; } -.flex-center { display: flex; justify-content: center; align-items: center; } -.full-height { height: 100vh; } -.p-4 { padding: 1rem; } -.m-4 { margin: 1rem; } -.gap-2 { gap: 0.5rem; } -.gap-4 { gap: 1rem; } - -.fade-in { - animation: fadeIn 0.5s ease-out; -} - -@keyframes fadeIn { - from { opacity: 0; transform: translateY(10px); } - to { opacity: 1; transform: translateY(0); } -} From 1957935603896deb7641c63ec6175fa1616c608b Mon Sep 17 00:00:00 2001 From: Repository Admin Date: Sat, 20 Dec 2025 18:40:06 +0100 Subject: [PATCH 03/41] tool(antigravity): localize application to German --- tools/antigravity/prisma/dev.db | Bin 45056 -> 45056 bytes tools/antigravity/src/app/layout.tsx | 6 ++--- tools/antigravity/src/app/manifest.ts | 2 +- tools/antigravity/src/app/page.tsx | 4 +-- .../src/components/CalendarLeaf.tsx | 8 +++--- .../antigravity/src/components/Onboarding.tsx | 16 ++++++------ tools/antigravity/src/lib/ai-service.ts | 24 +++++++++--------- 7 files changed, 30 insertions(+), 30 deletions(-) diff --git a/tools/antigravity/prisma/dev.db b/tools/antigravity/prisma/dev.db index 983255c7e9ded009501363b411f40f0eae773635..c9e2fd833331fab785881a1bde6735f0d1f50401 100644 GIT binary patch delta 1920 zcma)6L66%+7`2@)+NELLiVIS^>NLAjdx#@%>};GCDT0E~B9M^U2vw*OV|yGAYtI)f3{d9D1xo#hrh^H+I5qSysv+mXpl)z4yKMzS)0a z?7uL+y`d=B|78zx~6G{`9w3Hn9o7LAI*E$YXf}|<&0~!!O9}Dy`doL``YUL`aVF&`t)$m zINv|iuY9eqX-n%t`UTn9bv@6vZKvCHqheR~96Z{biH&kHA~+F9#srOdzC+niARf)X zCt(wfW10{IGnJkoNpKJofr_d~fK+TKV>G5Rrfk|m@8Sf5QfR`99F1rGB7cHN>gPBB z1hm8WI3eMXAk0GGAZSv0k0>jVBMkMxBB2qv22jv0ml%RWiDWJ_jvcosTj`a_CwK)k516LC`@RJcKex z9v#uJC|%%);Sn8T7-=?p5aT2Ph2f-97#>7k~d?;qT~ zbm*+l12EbQ_84 zBvsG=6XXP5MpRBplahazPaOm^tBsw`RFc?tM&CW*U`9K>#vmm{-0OnmYW-z`M}(OW^b9(#CWYg=r3KJHw?kujMz)O!OZYdl6#S82RG) { return ( - + {children} diff --git a/tools/antigravity/src/app/manifest.ts b/tools/antigravity/src/app/manifest.ts index ad0c939..b6c3fb9 100644 --- a/tools/antigravity/src/app/manifest.ts +++ b/tools/antigravity/src/app/manifest.ts @@ -4,7 +4,7 @@ export default function manifest(): MetadataRoute.Manifest { return { name: 'ARK - Digital Tear-off Calendar', short_name: 'ARK', - description: 'Your daily dose of gravity-defying wisdom.', + description: 'Deine tägliche Dosis Weisheit.', start_url: '/', display: 'standalone', background_color: '#0a0a0c', // Matches --background diff --git a/tools/antigravity/src/app/page.tsx b/tools/antigravity/src/app/page.tsx index 1d716fc..22a5c45 100644 --- a/tools/antigravity/src/app/page.tsx +++ b/tools/antigravity/src/app/page.tsx @@ -23,7 +23,7 @@ export default async function Home() {

ARK

- Daily wisdom, tailored to your gravity. + Tägliche Weisheit, passend zu deiner Schwerkraft.

@@ -41,7 +41,7 @@ export default async function Home() {
ARK
-
{user.name || "Explorer"}
+
{user.name || "Entdecker"}
diff --git a/tools/antigravity/src/components/CalendarLeaf.tsx b/tools/antigravity/src/components/CalendarLeaf.tsx index 40ba5eb..3678a59 100644 --- a/tools/antigravity/src/components/CalendarLeaf.tsx +++ b/tools/antigravity/src/components/CalendarLeaf.tsx @@ -18,8 +18,8 @@ export default function CalendarLeaf({ quote, dateStr }: { quote: any, dateStr: }; const day = new Date(dateStr).getDate(); - const month = new Date(dateStr).toLocaleDateString("en-US", { month: "long" }); - const weekday = new Date(dateStr).toLocaleDateString("en-US", { weekday: "long" }); + const month = new Date(dateStr).toLocaleDateString("de-DE", { month: "long" }); + const weekday = new Date(dateStr).toLocaleDateString("de-DE", { weekday: "long" }); return (
@@ -33,7 +33,7 @@ export default function CalendarLeaf({ quote, dateStr }: { quote: any, dateStr:

- — {quote.author || "Unknown"} + — {quote.author || "Unbekannt"}

{quote.explanation && ( @@ -73,7 +73,7 @@ export default function CalendarLeaf({ quote, dateStr }: { quote: any, dateStr:

-

Pull down to reveal

+

Zum Enthüllen ziehen

diff --git a/tools/antigravity/src/components/Onboarding.tsx b/tools/antigravity/src/components/Onboarding.tsx index f4db0a1..d8614f0 100644 --- a/tools/antigravity/src/components/Onboarding.tsx +++ b/tools/antigravity/src/components/Onboarding.tsx @@ -3,7 +3,7 @@ import { useState } from "react"; import { motion, AnimatePresence } from "framer-motion"; import { useRouter } from "next/navigation"; -const INTERESTS = ["Stoicism", "Mindfulness", "Entrepreneurship", "Science", "Art", "Poetry", "Leadership", "Wellness"]; +const INTERESTS = ["Stoizismus", "Achtsamkeit", "Unternehmertum", "Wissenschaft", "Kunst", "Poesie", "Führung", "Wellness"]; export default function Onboarding() { const router = useRouter(); @@ -58,8 +58,8 @@ export default function Onboarding() { initial="enter" animate="center" exit="exit" className="flex-1 flex flex-col justify-center" > -

What inspires you?

-

Select a few topics to personalize your daily drops.

+

Was inspiriert dich?

+

Wähle ein paar Themen für deine tägliche Inspiration.

{INTERESTS.map(item => ( @@ -81,7 +81,7 @@ export default function Onboarding() { disabled={selections.length === 0} className="mt-8 self-end btn disabled:opacity-50 disabled:cursor-not-allowed" > - Next + Weiter )} @@ -93,12 +93,12 @@ export default function Onboarding() { initial="enter" animate="center" exit="exit" className="flex-1 flex flex-col justify-center" > -

What should we call you?

-

Optional, but nice.

+

Wie sollen wir dich nennen?

+

Optional, aber nett.

setName(e.target.value)} className="w-full bg-black/20 border border-white/10 rounded-xl p-4 text-lg focus:outline-none focus:border-[hsl(var(--primary))]" @@ -109,7 +109,7 @@ export default function Onboarding() { disabled={loading} className="mt-8 w-full btn" > - {loading ? "Creating Personal Profile..." : "Start Journey"} + {loading ? "Profil wird erstellt..." : "Reise starten"} )} diff --git a/tools/antigravity/src/lib/ai-service.ts b/tools/antigravity/src/lib/ai-service.ts index 950a90a..4529872 100644 --- a/tools/antigravity/src/lib/ai-service.ts +++ b/tools/antigravity/src/lib/ai-service.ts @@ -8,22 +8,22 @@ const openai = process.env.OPENAI_API_KEY // Mock data for development without API Key const MOCK_QUOTES = [ { - content: "The only way to do great work is to love what you do.", + content: "Der einzige Weg, großartige Arbeit zu leisten, ist zu lieben, was man tut.", author: "Steve Jobs", - explanation: "Passion is the fuel for excellence.", + explanation: "Leidenschaft ist der Treibstoff für Exzellenz.", category: "Motivation" }, { - content: "In the middle of difficulty lies opportunity.", + content: "In der Mitte der Schwierigkeit liegt die Gelegenheit.", author: "Albert Einstein", - explanation: "Challenges often hide the best chances for growth.", - category: "Wisdom" + explanation: "Herausforderungen verbergen oft die besten Chancen für Wachstum.", + category: "Weisheit" }, { - content: "Happiness depends upon ourselves.", - author: "Aristotle", - explanation: "External circumstances don't define your internal state.", - category: "Philosophy" + content: "Das Glück hängt von uns selbst ab.", + author: "Aristoteles", + explanation: "Äußere Umstände definieren nicht deinen inneren Zustand.", + category: "Philosophie" } ]; @@ -59,13 +59,13 @@ export async function getDailyQuote(userId: string) { const user = await prisma.user.findUnique({ where: { id: userId } }); const prefs = user?.preferences ? JSON.parse(user.preferences) : {}; - const prompt = `Generate a unique, inspiring quote for a user interested in: ${prefs.interests || "general wisdom"}. - Return JSON format: { "content": "...", "author": "...", "explanation": "2 sentences max", "category": "one word" }`; + const prompt = `Generiere ein einzigartiges, inspirierendes Zitat für einen Nutzer mit Interesse an: ${prefs.interests || "allgemeiner Weisheit"}. + Antworte im JSON Format: { "content": "Zitat auf Deutsch", "author": "Name", "explanation": "Maximal 2 Sätze Erklärung auf Deutsch", "category": "Ein Wort (Kategorie)" }`; const completion = await openai.chat.completions.create({ model: "gpt-4o-mini", messages: [ - { role: "system", content: "You are a wise assistant providing daily inspiration." }, + { role: "system", content: "Du bist ein weiser Assistent, der tägliche Inspiration liefert." }, { role: "user", content: prompt } ], response_format: { type: "json_object" } From 75d9ec88c6eefb58d349f58e9ec94bb40f52c002 Mon Sep 17 00:00:00 2001 From: Repository Admin Date: Sat, 20 Dec 2025 18:49:43 +0100 Subject: [PATCH 04/41] fix(frontend): implement real CSS modules and fix next config --- tools/antigravity/next.config.ts | 7 +- tools/antigravity/prisma/dev.db | Bin 45056 -> 45056 bytes tools/antigravity/src/app/layout.tsx | 8 +- tools/antigravity/src/app/page.module.css | 171 +++++----------- tools/antigravity/src/app/page.tsx | 21 +- .../src/components/CalendarLeaf.module.css | 185 ++++++++++++++++++ .../src/components/CalendarLeaf.tsx | 41 ++-- .../src/components/Onboarding.module.css | 124 ++++++++++++ .../antigravity/src/components/Onboarding.tsx | 32 ++- 9 files changed, 424 insertions(+), 165 deletions(-) create mode 100644 tools/antigravity/src/components/CalendarLeaf.module.css create mode 100644 tools/antigravity/src/components/Onboarding.module.css diff --git a/tools/antigravity/next.config.ts b/tools/antigravity/next.config.ts index e9ffa30..f24b829 100644 --- a/tools/antigravity/next.config.ts +++ b/tools/antigravity/next.config.ts @@ -1,7 +1,12 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { - /* config options here */ + // Allow all local dev origins + experimental: { + serverActions: { + allowedOrigins: ["localhost:3000", "192.168.178.136:3000"] + } + } }; export default nextConfig; diff --git a/tools/antigravity/prisma/dev.db b/tools/antigravity/prisma/dev.db index c9e2fd833331fab785881a1bde6735f0d1f50401..c5ae9fb76c6f7a1ec629b6e0fe5929ee06afa8a1 100644 GIT binary patch delta 1051 zcma)*&ubGw6vsDRBN}C=xmnb9y6r(BTaz>)i7kXue^nGgS&D+xO?Gy7%6`s5uo6UJ4a2MFQ!?ThN<`*n22Kk#iTv?7)6VRx8$@6Gr7K5rY_J&o<2 z7iUB0<+;fadjDt@MMNntp!?D{Dc_3rCZw^&sCYsRhX+nBDurTPH+v7&*xtJ-4V;;nC|capoD!j2j>#(H#AU>Ch|7HkHm0fP z5#|*w&EWFGn9MYX$d~0w%cUMKS1fs<^{qbK9MtpQ3@K^pFr9Dmsseoz2WuDaVr5q#B!!i=*38?J&uNWf)~t@(iz7hmhFTGR}1!|j@fZ&29unT~G~UgMBrxwT=x zI|6KEig^|4g0OOTWH!=fg)6DD;!s9gjqzt9a9J zX(f?Vl5x9d|F+UxDyuisGhhB^=U+X0c49Mqt(~%rA$LNAg|XEU0jtZ}Vk2Lq-lJ{`Cy}>-leN z7A#oIKY6`=C Show Onboarding if (!user || !user.onboardingCompleted) { return ( -
-
-

ARK

-

+

+
+

ARK

+

Tägliche Weisheit, passend zu deiner Schwerkraft.

@@ -36,12 +37,12 @@ export default async function Home() { const now = new Date().toISOString(); return ( -
-
-
ARK
-
-
-
{user.name || "Entdecker"}
+
+
+
ARK
+
+
+
{user.name || "Entdecker"}
diff --git a/tools/antigravity/src/components/CalendarLeaf.module.css b/tools/antigravity/src/components/CalendarLeaf.module.css new file mode 100644 index 0000000..908609b --- /dev/null +++ b/tools/antigravity/src/components/CalendarLeaf.module.css @@ -0,0 +1,185 @@ +.container { + position: relative; + width: 100%; + max-width: 320px; + aspect-ratio: 3/4; + margin: 2rem auto; + perspective: 1000px; +} + +/* The Daily Quote Card (Underneath) */ +.quoteCard { + position: absolute; + inset: 0; + background-color: hsl(var(--card-bg)); + border: 1px solid hsl(var(--card-border)); + border-radius: 1rem; + padding: 2rem; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + text-align: center; + box-shadow: var(--shadow-lg); + z-index: 0; +} + +.icon { + width: 2rem; + height: 2rem; + color: hsl(var(--primary)); + margin-bottom: 1rem; + opacity: 0.8; +} + +.quoteText { + font-family: var(--font-serif); + font-size: 1.5rem; + line-height: 1.4; + margin-bottom: 1.5rem; + font-weight: 500; + color: hsl(var(--foreground)); +} + +.quoteAuthor { + color: hsl(var(--secondary)); + text-transform: uppercase; + letter-spacing: 0.15em; + font-size: 0.75rem; + font-weight: 600; + margin-bottom: 1rem; +} + +.explanation { + font-size: 0.75rem; + opacity: 0.6; + line-height: 1.5; + max-width: 250px; + margin-bottom: 1rem; +} + +.actions { + position: absolute; + bottom: 1.5rem; + display: flex; + gap: 1rem; +} + +.actionBtn { + padding: 0.75rem; + border-radius: 50%; + background-color: rgba(255, 255, 255, 0.05); + transition: background-color 0.2s; + border: none; + color: inherit; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; +} + +.actionBtn:hover { + background-color: rgba(255, 255, 255, 0.1); +} + +/* The Tear-Off Leaf (Top) */ +.leaf { + position: absolute; + inset: 0; + background-color: #ffffff; + /* Explicit white for paper look */ + color: #000000; + /* Explicit black ink */ + border-radius: 1rem; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + cursor: grab; + box-shadow: var(--shadow-lg); + z-index: 10; + transform-origin: top; + overflow: hidden; +} + +.leaf:active { + cursor: grabbing; +} + +.header { + position: absolute; + top: 0; + width: 100%; + padding: 1rem; + display: flex; + justify-content: space-between; + align-items: center; + opacity: 0.4; +} + +.dayNumber { + font-size: 8rem; + font-weight: 700; + line-height: 1; + letter-spacing: -0.05em; + margin: 0; +} + +.monthName { + font-size: 2rem; + text-transform: uppercase; + letter-spacing: 0.2em; + font-weight: 300; + margin-top: -1rem; + /* tighten */ +} + +.footer { + position: absolute; + bottom: 3rem; + display: flex; + flex-direction: column; + align-items: center; + gap: 0.5rem; +} + +.hint { + font-size: 0.65rem; + text-transform: uppercase; + letter-spacing: 0.2em; + color: #9ca3af; +} + +/* Simple pill shape for visual cue */ +.pill { + width: 0.25rem; + height: 2rem; + background-color: #e5e7eb; + border-radius: 9999px; + overflow: hidden; +} + +.pillInner { + width: 100%; + height: 100%; + background-color: #9ca3af; + animation: pulse 1.5s infinite; + transform-origin: top; +} + +@keyframes pulse { + 0% { + transform: scaleY(1); + opacity: 1; + } + + 50% { + transform: scaleY(0.5); + opacity: 0.5; + } + + 100% { + transform: scaleY(1); + opacity: 1; + } +} \ No newline at end of file diff --git a/tools/antigravity/src/components/CalendarLeaf.tsx b/tools/antigravity/src/components/CalendarLeaf.tsx index 3678a59..d2521cf 100644 --- a/tools/antigravity/src/components/CalendarLeaf.tsx +++ b/tools/antigravity/src/components/CalendarLeaf.tsx @@ -2,6 +2,7 @@ import { motion, useMotionValue, useTransform } from "framer-motion"; import { useState } from "react"; import { Quote, Share2, Heart } from "lucide-react"; +import styles from "./CalendarLeaf.module.css"; export default function CalendarLeaf({ quote, dateStr }: { quote: any, dateStr: string }) { const [revealed, setRevealed] = useState(false); @@ -22,29 +23,29 @@ export default function CalendarLeaf({ quote, dateStr }: { quote: any, dateStr: const weekday = new Date(dateStr).toLocaleDateString("de-DE", { weekday: "long" }); return ( -
+
{/* The Quote (Underneath) */} -
- +
+ -

+

"{quote.content}"

-

+

— {quote.author || "Unbekannt"}

{quote.explanation && ( -
+
{quote.explanation}
)} -
- - +
+ +
@@ -57,25 +58,27 @@ export default function CalendarLeaf({ quote, dateStr }: { quote: any, dateStr: dragElastic={0.7} onDragEnd={handleDragEnd} whileHover={{ scale: 1.02 }} - className="absolute inset-0 bg-white text-black rounded-2xl flex flex-col items-center justify-center cursor-grab active:cursor-grabbing shadow-2xl z-10 origin-top overflow-hidden" + className={styles.leaf} > {/* Header */} -
- {weekday.toUpperCase()} -
+
+ + {weekday.toUpperCase()} + +
-

+

{day}

-

+

{month}

-
-

Zum Enthüllen ziehen

-
-
+
+

Zum Enthüllen ziehen

+
+
diff --git a/tools/antigravity/src/components/Onboarding.module.css b/tools/antigravity/src/components/Onboarding.module.css new file mode 100644 index 0000000..471f278 --- /dev/null +++ b/tools/antigravity/src/components/Onboarding.module.css @@ -0,0 +1,124 @@ +.card { + width: 100%; + max-width: 28rem; + background-color: hsl(var(--card-bg)); + padding: 2rem; + border-radius: 1.5rem; + border: 1px solid hsl(var(--card-border)); + box-shadow: var(--shadow-lg); + position: relative; + overflow: hidden; + min-height: 400px; + display: flex; + flex-direction: column; + justify-content: space-between; +} + +.progressBarContainer { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 4px; + background-color: hsl(var(--card-border)); +} + +.progressBarFill { + height: 100%; + background-color: hsl(var(--primary)); +} + +.stepContainer { + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; +} + +.heading { + font-size: 1.5rem; + font-family: var(--font-serif); + margin-bottom: 0.5rem; + color: hsl(var(--foreground)); +} + +.subtext { + font-size: 0.875rem; + color: #9ca3af; + margin-bottom: 1.5rem; +} + +.chipContainer { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; +} + +.chip { + padding: 0.5rem 1rem; + border-radius: 9999px; + font-size: 0.875rem; + transition: all 0.2s; + text-align: left; + border: 1px solid rgba(255, 255, 255, 0.1); + background-color: rgba(255, 255, 255, 0.05); + color: #d1d5db; + cursor: pointer; +} + +.chip:hover { + border-color: rgba(255, 255, 255, 0.3); +} + +.chipSelected { + background-color: hsl(var(--primary)); + color: white; + border-color: hsl(var(--primary)); +} + +.input { + width: 100%; + background-color: rgba(0, 0, 0, 0.2); + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 0.75rem; + padding: 1rem; + font-size: 1.125rem; + color: white; + outline: none; +} + +.input:focus { + border-color: hsl(var(--primary)); +} + +.button { + margin-top: 2rem; + width: 100%; + /* Default full width */ + background: linear-gradient(135deg, hsl(var(--primary)), hsl(var(--primary)/0.8)); + color: white; + border: none; + padding: 1rem 2rem; + border-radius: 9999px; + font-size: 1rem; + font-weight: 600; + cursor: pointer; + transition: transform 0.2s, box-shadow 0.2s; + box-shadow: 0 4px 15px rgba(100, 50, 255, 0.3); +} + +.button:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +.button:hover:not(:disabled) { + transform: translateY(-2px); + box-shadow: 0 8px 25px rgba(100, 50, 255, 0.5); +} + +.buttonNext { + /* Special case for Next button which uses self-end originally */ + width: auto; + align-self: flex-end; +} \ No newline at end of file diff --git a/tools/antigravity/src/components/Onboarding.tsx b/tools/antigravity/src/components/Onboarding.tsx index d8614f0..aa82391 100644 --- a/tools/antigravity/src/components/Onboarding.tsx +++ b/tools/antigravity/src/components/Onboarding.tsx @@ -2,6 +2,7 @@ import { useState } from "react"; import { motion, AnimatePresence } from "framer-motion"; import { useRouter } from "next/navigation"; +import styles from "./Onboarding.module.css"; const INTERESTS = ["Stoizismus", "Achtsamkeit", "Unternehmertum", "Wissenschaft", "Kunst", "Poesie", "Führung", "Wellness"]; @@ -41,10 +42,10 @@ export default function Onboarding() { }; return ( -
-
+
+
@@ -56,20 +57,17 @@ export default function Onboarding() { key="step1" variants={variants} initial="enter" animate="center" exit="exit" - className="flex-1 flex flex-col justify-center" + className={styles.stepContainer} > -

Was inspiriert dich?

-

Wähle ein paar Themen für deine tägliche Inspiration.

+

Was inspiriert dich?

+

Wähle ein paar Themen für deine tägliche Inspiration.

-
+
{INTERESTS.map(item => ( @@ -79,7 +77,7 @@ export default function Onboarding() { @@ -91,23 +89,23 @@ export default function Onboarding() { key="step2" variants={variants} initial="enter" animate="center" exit="exit" - className="flex-1 flex flex-col justify-center" + className={styles.stepContainer} > -

Wie sollen wir dich nennen?

-

Optional, aber nett.

+

Wie sollen wir dich nennen?

+

Optional, aber nett.

setName(e.target.value)} - className="w-full bg-black/20 border border-white/10 rounded-xl p-4 text-lg focus:outline-none focus:border-[hsl(var(--primary))]" + className={styles.input} /> From c3c5d6f1c33c1b959a5b3a0fcc1c45e83c999360 Mon Sep 17 00:00:00 2001 From: Repository Admin Date: Sat, 20 Dec 2025 18:57:12 +0100 Subject: [PATCH 05/41] fix: middleware to proxy migration and rating api --- tools/antigravity/check-db.mjs | 26 ++++++++++++++++ tools/antigravity/package.json | 5 +-- .../src/app/api/quote/rate/route.ts | 26 ++++++++++++++++ tools/antigravity/src/app/page.module.css | 1 + .../src/components/CalendarLeaf.tsx | 31 +++++++++++++++++-- .../src/{middleware.ts => proxy.ts} | 13 ++++++-- 6 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 tools/antigravity/check-db.mjs create mode 100644 tools/antigravity/src/app/api/quote/rate/route.ts rename tools/antigravity/src/{middleware.ts => proxy.ts} (65%) diff --git a/tools/antigravity/check-db.mjs b/tools/antigravity/check-db.mjs new file mode 100644 index 0000000..717ca13 --- /dev/null +++ b/tools/antigravity/check-db.mjs @@ -0,0 +1,26 @@ +// check-db.mjs +import { PrismaClient } from '@prisma/client'; + +const prisma = new PrismaClient(); + +async function main() { + console.log("--- Users ---"); + const users = await prisma.user.findMany(); + console.table(users); + + console.log("\n--- Daily Views ---"); + const views = await prisma.dailyView.findMany(); + console.table(views); + + console.log("\n--- Ratings (Likes) ---"); + const ratings = await prisma.rating.findMany(); + console.table(ratings); + + console.log("\n--- Quotes ---"); + const quotes = await prisma.quote.findMany({ take: 5 }); + console.table(quotes.map(q => ({ id: q.id, content: q.content.substring(0, 30) + "..." }))); +} + +main() + .catch(e => console.error(e)) + .finally(async () => await prisma.$disconnect()); diff --git a/tools/antigravity/package.json b/tools/antigravity/package.json index 3f9d423..4adaecb 100644 --- a/tools/antigravity/package.json +++ b/tools/antigravity/package.json @@ -6,7 +6,8 @@ "dev": "next dev", "build": "next build", "start": "next start", - "lint": "eslint" + "lint": "next lint", + "db:check": "node check-db.mjs" }, "dependencies": { "@prisma/client": "^5.22.0", @@ -27,4 +28,4 @@ "eslint-config-next": "16.1.0", "typescript": "^5" } -} +} \ No newline at end of file diff --git a/tools/antigravity/src/app/api/quote/rate/route.ts b/tools/antigravity/src/app/api/quote/rate/route.ts new file mode 100644 index 0000000..a193e38 --- /dev/null +++ b/tools/antigravity/src/app/api/quote/rate/route.ts @@ -0,0 +1,26 @@ +import { NextRequest, NextResponse } from "next/server"; +import { prisma } from "@/lib/prisma"; + +export async function POST(req: NextRequest) { + try { + const { quoteId, score } = await req.json(); + const userId = req.headers.get("x-user-id"); + + if (!userId || !quoteId || score === undefined) { + return NextResponse.json({ error: "Invalid data" }, { status: 400 }); + } + + await prisma.rating.create({ + data: { + userId, + quoteId, + score + } + }); + + return NextResponse.json({ success: true }); + } catch (error) { + console.error("Rating error:", error); + return NextResponse.json({ error: "Internal Server Error" }, { status: 500 }); + } +} diff --git a/tools/antigravity/src/app/page.module.css b/tools/antigravity/src/app/page.module.css index 100c6ed..375faa1 100644 --- a/tools/antigravity/src/app/page.module.css +++ b/tools/antigravity/src/app/page.module.css @@ -26,6 +26,7 @@ font-weight: 700; background: linear-gradient(135deg, hsl(var(--primary)), hsl(var(--secondary))); -webkit-background-clip: text; + background-clip: text; color: transparent; } diff --git a/tools/antigravity/src/components/CalendarLeaf.tsx b/tools/antigravity/src/components/CalendarLeaf.tsx index d2521cf..03b2afb 100644 --- a/tools/antigravity/src/components/CalendarLeaf.tsx +++ b/tools/antigravity/src/components/CalendarLeaf.tsx @@ -22,6 +22,33 @@ export default function CalendarLeaf({ quote, dateStr }: { quote: any, dateStr: const month = new Date(dateStr).toLocaleDateString("de-DE", { month: "long" }); const weekday = new Date(dateStr).toLocaleDateString("de-DE", { weekday: "long" }); + const handleRate = async () => { + try { + if (typeof navigator !== 'undefined' && navigator.vibrate) navigator.vibrate(10); + await fetch("/api/quote/rate", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ quoteId: quote.id, score: 5 }), + }); + alert("Danke! Das Zitat wurde gespeichert."); + } catch (e) { + console.error(e); + } + }; + + const handleShare = async () => { + if (navigator.share) { + navigator.share({ + title: 'ARK', + text: `"${quote.content}" — ${quote.author}`, + url: window.location.href, + }).catch(err => console.log('Error sharing', err)); + } else { + navigator.clipboard.writeText(`"${quote.content}" — ${quote.author}`); + alert("Zitat kopiert!"); + } + }; + return (
@@ -44,8 +71,8 @@ export default function CalendarLeaf({ quote, dateStr }: { quote: any, dateStr: )}
- - + +
diff --git a/tools/antigravity/src/middleware.ts b/tools/antigravity/src/proxy.ts similarity index 65% rename from tools/antigravity/src/middleware.ts rename to tools/antigravity/src/proxy.ts index ada9166..05b88cb 100644 --- a/tools/antigravity/src/middleware.ts +++ b/tools/antigravity/src/proxy.ts @@ -1,7 +1,7 @@ import { NextResponse } from 'next/server' import type { NextRequest } from 'next/server' -export function middleware(request: NextRequest) { +export function proxy(request: NextRequest) { let response = NextResponse.next() // Check for User ID cookie @@ -28,5 +28,14 @@ export function middleware(request: NextRequest) { } export const config = { - matcher: '/:path*', + matcher: [ + /* + * Match all request paths except for the ones starting with: + * - api (API routes) + * - _next/static (static files) + * - _next/image (image optimization files) + * - favicon.ico (favicon file) + */ + '/((?!api|_next/static|_next/image|manifest|favicon.ico).*)', + ], } From 2ae6ae5c2af79986705c1542c60f03883984ccd3 Mon Sep 17 00:00:00 2001 From: Repository Admin Date: Sat, 20 Dec 2025 19:06:10 +0100 Subject: [PATCH 06/41] feat: implement url-based identity and complete tracking --- tools/antigravity/prisma/dev.db | Bin 45056 -> 57344 bytes tools/antigravity/prisma/schema.prisma | 79 ++++++++++-------- tools/antigravity/src/app/[username]/page.tsx | 63 ++++++++++++++ tools/antigravity/src/app/page.tsx | 75 ++++++++--------- .../src/components/CalendarLeaf.tsx | 2 +- .../antigravity/src/components/Onboarding.tsx | 30 +++++-- 6 files changed, 164 insertions(+), 85 deletions(-) create mode 100644 tools/antigravity/src/app/[username]/page.tsx diff --git a/tools/antigravity/prisma/dev.db b/tools/antigravity/prisma/dev.db index c5ae9fb76c6f7a1ec629b6e0fe5929ee06afa8a1..506b861b8884f9b5f9c0be43cd11314815d3b0ed 100644 GIT binary patch delta 486 zcmZp8z|?Snd4jZ{FarYv9}vR;*F+s-bzug*vJPJU9}K)KVhnt{_|Nm^@bz>1@LF=( zaLaSt=ZIq~Wm9Gm+t@gPxxR&qmt9<4ov}T*Brz!`H7~V1-X$?Jr!p)vwH$@R=N#nf z7~-lB;^^e#s-T1-r=+04r2qsexWQXe5e49Itu|9x@OF%s;Y;=-KFlGOO()WXu# zyyR3gE-#9c&?GhT5_3~^fI2ms)418i#l;!hwZUcvXCxM-f(afJ{Yqdlb29xhc{R6= zD!SK!9t4F-K~7>xT7FTkl0t}UM95?=e&@+LTs*8``zG6Ql|WfLxY9SraV%QCs6YUM E0CG!>P5=M^ delta 73 zcmZoTz})bFX@ayMKLY~;HxR=B+e95>MScdovJPJU9}HX^aSVLB_|Nm^@bz>1@LF=( VaLaSt=ZM=ZC~%K`a~#K_z diff --git a/tools/antigravity/prisma/schema.prisma b/tools/antigravity/prisma/schema.prisma index 3f0b5ad..fab9d8c 100644 --- a/tools/antigravity/prisma/schema.prisma +++ b/tools/antigravity/prisma/schema.prisma @@ -8,60 +8,67 @@ datasource db { } model User { - id String @id @default(cuid()) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt + id String @id @default(uuid()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + name String @unique // Name acts as the identifier for URL - // Preferences - name String? onboardingCompleted Boolean @default(false) - preferences String? // JSON string of UserPreferences + preferences String? // JSON string - // Relations - history DailyView[] - ratings Rating[] + views DailyView[] + ratings Rating[] + shares Share[] } model Quote { - id String @id @default(cuid()) - content String // The actual quote text - author String? - explanation String? // AI generated context/explanation - category String // e.g., "Spiritual", "Health", etc. - tags String? // JSON string array + id Int @id @default(autoincrement()) + content String + author String? + explanation String? + category String? // The "Tag" or "Topic" + tags String? // Comma separated - // Metadata - generatedAt DateTime @default(now()) - sourceModel String? // e.g. "gpt-4o" + generatedAt DateTime @default(now()) + sourceModel String? // "gpt-4o", "mock" - // Relations - views DailyView[] - ratings Rating[] + views DailyView[] + ratings Rating[] + shares Share[] @@index([category]) } model DailyView { - id String @id @default(cuid()) - userId String - quoteId String - viewedAt DateTime @default(now()) + id Int @id @default(autoincrement()) + userId String + quoteId Int + viewedAt DateTime @default(now()) - date String // YYYY-MM-DD for uniqueness per user per day if needed + date String // "YYYY-MM-DD" - user User @relation(fields: [userId], references: [id]) - quote Quote @relation(fields: [quoteId], references: [id]) + user User @relation(fields: [userId], references: [id]) + quote Quote @relation(fields: [quoteId], references: [id]) - @@unique([userId, date]) // One quote per user per day? Or main quote. + @@unique([userId, date]) } model Rating { - id String @id @default(cuid()) - userId String - quoteId String - score Int // 1 (Dislike) to 5 (Like), or simple 0/1 - createdAt DateTime @default(now()) + id Int @id @default(autoincrement()) + userId String + user User @relation(fields: [userId], references: [id]) + quoteId Int + quote Quote @relation(fields: [quoteId], references: [id]) + score Int + createdAt DateTime @default(now()) +} - user User @relation(fields: [userId], references: [id]) - quote Quote @relation(fields: [quoteId], references: [id]) +model Share { + id Int @id @default(autoincrement()) + userId String + user User @relation(fields: [userId], references: [id]) + quoteId Int + quote Quote @relation(fields: [quoteId], references: [id]) + platform String? + createdAt DateTime @default(now()) } diff --git a/tools/antigravity/src/app/[username]/page.tsx b/tools/antigravity/src/app/[username]/page.tsx new file mode 100644 index 0000000..bac8668 --- /dev/null +++ b/tools/antigravity/src/app/[username]/page.tsx @@ -0,0 +1,63 @@ +import { prisma } from "@/lib/prisma"; +import { getDailyQuote } from "@/lib/ai-service"; +import CalendarLeaf from "@/components/CalendarLeaf"; +import Onboarding from "@/components/Onboarding"; +import styles from "../page.module.css"; +import { Metadata } from "next"; + +type Props = { + params: Promise<{ username: string }>; +} + +export async function generateMetadata({ params }: Props): Promise { + const { username } = await params; + return { + title: `ARK | ${decodeURIComponent(username)}`, + } +} + +export default async function UserPage({ params }: Props) { + const { username } = await params; + const decodedName = decodeURIComponent(username); + + // 1. Try to find user by Name + // Note: Schema has `name` as unique. + const user = await prisma.user.findUnique({ + where: { name: decodedName }, + }); + + // 2. If no user, or onboarding not done -> Show Onboarding + // Pass the name to Onboarding so it can auto-create the user + if (!user || !user.onboardingCompleted) { + return ( +
+
+

ARK

+

+ Willkommen, {decodedName}.
+ Tägliche Weisheit, passend zu deiner Schwerkraft. +

+
+ +
+ ); + } + + // 3. User exists -> Get Quote + const quote = await getDailyQuote(user.id); + const now = new Date().toISOString(); + + return ( +
+
+
ARK
+
+
+
{user.name}
+
+
+ + +
+ ); +} diff --git a/tools/antigravity/src/app/page.tsx b/tools/antigravity/src/app/page.tsx index d10a644..1c0bb37 100644 --- a/tools/antigravity/src/app/page.tsx +++ b/tools/antigravity/src/app/page.tsx @@ -1,52 +1,43 @@ -import { headers } from "next/headers"; -import { prisma } from "@/lib/prisma"; -import { getDailyQuote } from "@/lib/ai-service"; -import CalendarLeaf from "@/components/CalendarLeaf"; -import Onboarding from "@/components/Onboarding"; +"use client"; +import { useRouter } from "next/navigation"; +import { useState } from "react"; import styles from "./page.module.css"; -export default async function Home() { - const headersList = await headers(); - const userId = headersList.get("x-user-id"); +export default function Home() { + const router = useRouter(); + const [name, setName] = useState(""); - if (!userId) { - return
Loading...
; - } - - // Fetch user profile - const user = await prisma.user.findUnique({ where: { id: userId } }); - - // Deciding View: - // If no user record, or onboarding incomplete -> Show Onboarding - if (!user || !user.onboardingCompleted) { - return ( -
-
-

ARK

-

- Tägliche Weisheit, passend zu deiner Schwerkraft. -

-
- -
- ); - } - - // User is onboarded, get quote - const quote = await getDailyQuote(userId); - const now = new Date().toISOString(); + const go = () => { + if (name.trim()) { + router.push(`/${encodeURIComponent(name.trim())}`); + } + }; return ( -
-
-
ARK
-
-
-
{user.name || "Entdecker"}
-
+
+
+

ARK

+

+ Dein digitaler Begleiter. Wie heißt du? +

- +
+ setName(e.target.value)} + placeholder="Name eingeben..." + className="w-full bg-black/20 border border-white/10 rounded-xl p-4 text-lg focus:outline-none focus:border-[hsl(var(--primary))]" + style={{ color: 'white' }} + onKeyDown={(e) => e.key === "Enter" && go()} + /> + +
); } diff --git a/tools/antigravity/src/components/CalendarLeaf.tsx b/tools/antigravity/src/components/CalendarLeaf.tsx index 03b2afb..fb3d1a3 100644 --- a/tools/antigravity/src/components/CalendarLeaf.tsx +++ b/tools/antigravity/src/components/CalendarLeaf.tsx @@ -4,7 +4,7 @@ import { useState } from "react"; import { Quote, Share2, Heart } from "lucide-react"; import styles from "./CalendarLeaf.module.css"; -export default function CalendarLeaf({ quote, dateStr }: { quote: any, dateStr: string }) { +export default function CalendarLeaf({ quote, dateStr, userId }: { quote: any, dateStr: string, userId?: string }) { const [revealed, setRevealed] = useState(false); const y = useMotionValue(0); diff --git a/tools/antigravity/src/components/Onboarding.tsx b/tools/antigravity/src/components/Onboarding.tsx index aa82391..37b87d1 100644 --- a/tools/antigravity/src/components/Onboarding.tsx +++ b/tools/antigravity/src/components/Onboarding.tsx @@ -6,11 +6,16 @@ import styles from "./Onboarding.module.css"; const INTERESTS = ["Stoizismus", "Achtsamkeit", "Unternehmertum", "Wissenschaft", "Kunst", "Poesie", "Führung", "Wellness"]; -export default function Onboarding() { +interface OnboardingProps { + initialName?: string; +} + +export default function Onboarding({ initialName }: OnboardingProps) { const router = useRouter(); const [step, setStep] = useState(0); const [selections, setSelections] = useState([]); - const [name, setName] = useState(""); + // Use initialName if provided + const [name, setName] = useState(initialName || ""); const [loading, setLoading] = useState(false); const toggleInterest = (interest: string) => { @@ -41,8 +46,13 @@ export default function Onboarding() { exit: { x: -50, opacity: 0 } }; + // If name is pre-filled, we might want to skip step 1 or change the flow. + // Requirement: "system would already know who is the current user" -> So name is known. + // We just need interests. + return (
+ {/* Progress Bar */}
Was inspiriert dich?

Wähle ein paar Themen für deine tägliche Inspiration.

-
+
{INTERESTS.map(item => (
)} - {step === 1 && ( + {step === 1 && !initialName && ( Date: Sat, 20 Dec 2025 19:19:16 +0100 Subject: [PATCH 07/41] fix: auth proxy matcher and onboarding styles --- tools/antigravity/prisma/dev.db | Bin 57344 -> 45056 bytes tools/antigravity/reset-db.js | 30 ++++++++++++++++++ .../src/components/Onboarding.module.css | 5 +-- tools/antigravity/src/proxy.ts | 3 +- 4 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 tools/antigravity/reset-db.js diff --git a/tools/antigravity/prisma/dev.db b/tools/antigravity/prisma/dev.db index 506b861b8884f9b5f9c0be43cd11314815d3b0ed..15c7c82527e406125b449c65333ef58d016a2e56 100644 GIT binary patch delta 319 zcmZoTz})bFX@ayM2Ll5GHxR=B$3z`tMGgkNvJPJU9}HY8BKLsU_kdlTHNUf4)a~eClxVSiDyLL%pQch}cMq&|!;Mm;HcAinDxrB{fTvC#; z-5D$&lvt9PmkuG>Cr5B9PR?M--F%7DmyxTvj+I?pUY@btdvX}J&E^c2J&cSjlU3O? z8CfU$v#D`4X)uFrYSEuu#%nNnJ)7a=W4vLLRr#{Gnxq-o#YIIKTO=nR;oClWDT~15 YCjO?)ECqk$7adRlBY{l~ECOH=0J>jXlK=n! literal 57344 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 diff --git a/tools/antigravity/reset-db.js b/tools/antigravity/reset-db.js new file mode 100644 index 0000000..ab0c074 --- /dev/null +++ b/tools/antigravity/reset-db.js @@ -0,0 +1,30 @@ +const fs = require('fs'); +const path = require('path'); +const { execSync } = require('child_process'); + +const dbPath = path.join(__dirname, 'dev.db'); +const journalPath = path.join(__dirname, 'dev.db-journal'); +const shmPath = path.join(__dirname, 'dev.db-shm'); +const walPath = path.join(__dirname, 'dev.db-wal'); + +console.log("Cleaning up database files..."); + +[dbPath, journalPath, shmPath, walPath].forEach(file => { + if (fs.existsSync(file)) { + try { + fs.unlinkSync(file); + console.log(`Deleted ${path.basename(file)}`); + } catch (e) { + console.error(`Failed to delete ${path.basename(file)}:`, e.message); + } + } +}); + +console.log("Initializing fresh database..."); +try { + execSync('npx prisma db push', { stdio: 'inherit' }); + console.log("Database initialized successfully."); +} catch (e) { + console.error("Prisma push failed."); + process.exit(1); +} diff --git a/tools/antigravity/src/components/Onboarding.module.css b/tools/antigravity/src/components/Onboarding.module.css index 471f278..b53b492 100644 --- a/tools/antigravity/src/components/Onboarding.module.css +++ b/tools/antigravity/src/components/Onboarding.module.css @@ -78,8 +78,9 @@ .input { width: 100%; - background-color: rgba(0, 0, 0, 0.2); - border: 1px solid rgba(255, 255, 255, 0.1); + background-color: #1F2937; + /* Tailwind gray-800 equivalent */ + border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 0.75rem; padding: 1rem; font-size: 1.125rem; diff --git a/tools/antigravity/src/proxy.ts b/tools/antigravity/src/proxy.ts index 05b88cb..0243d22 100644 --- a/tools/antigravity/src/proxy.ts +++ b/tools/antigravity/src/proxy.ts @@ -31,11 +31,10 @@ export const config = { matcher: [ /* * Match all request paths except for the ones starting with: - * - api (API routes) * - _next/static (static files) * - _next/image (image optimization files) * - favicon.ico (favicon file) */ - '/((?!api|_next/static|_next/image|manifest|favicon.ico).*)', + '/((?!_next/static|_next/image|manifest|favicon.ico).*)', ], } From f8daa17a4150f3cebad167f12791d6b96a309ae1 Mon Sep 17 00:00:00 2001 From: Repository Admin Date: Sat, 20 Dec 2025 19:31:52 +0100 Subject: [PATCH 08/41] feat: implement user settings overlay and ui polish --- tools/antigravity/prisma/dev.db | Bin 45056 -> 45056 bytes tools/antigravity/src/app/[username]/page.tsx | 9 +- .../src/components/CalendarLeaf.module.css | 37 +++-- .../src/components/CalendarLeaf.tsx | 26 ++-- .../src/components/SettingsOverlay.module.css | 132 ++++++++++++++++++ .../src/components/SettingsOverlay.tsx | 125 +++++++++++++++++ .../antigravity/src/components/UserHeader.tsx | 39 ++++++ 7 files changed, 340 insertions(+), 28 deletions(-) create mode 100644 tools/antigravity/src/components/SettingsOverlay.module.css create mode 100644 tools/antigravity/src/components/SettingsOverlay.tsx create mode 100644 tools/antigravity/src/components/UserHeader.tsx diff --git a/tools/antigravity/prisma/dev.db b/tools/antigravity/prisma/dev.db index 15c7c82527e406125b449c65333ef58d016a2e56..d03bb6391e595681324bccb5b0a4b792d655c687 100644 GIT binary patch delta 1729 zcmb7EPiP!f7@t2`*)iFD@nR?{d6`8kxD)m-nM5zODKS)}wycFp#Wy=|b{^Szv%L4l zq$y>)=Fo!(dMt_;dn^ZFTETEpVHpMQXn52KqPeJpJyA@$+OTm{jo~ylgYBsGw3wd*x&MoQl~t zlTjk=s(qpxDoLUZ$`qW=Gbt&T-H-&zzF4*SkVMp8v7bTNS4IUrB{XM^Uh}#&KWNl_ zXDMheIW5}u9pWz69nWpl{I2WOyRBuQ^2Ggi{LE1PADK6fu*s3Jue_*fnt^U<=nr%Y zwE7-heADdclZa#-H#^oOdfyX6|GQN=h&wLpG`sv zFA}d&5FCC3#(m21CKK3a6rb)B5rV+g?Bo-PJDhz+g-jyMIF^)gKsg;pgFfA2YWIf1 zaS%}M5up}4+@l+WbG6E-90K?Srij82?xk5&h6y$^aE;=1pQcm<-~uLa$hbueuEEEg z**M{T_APJuB0eQC6 zL)RThU(Hg#M+He_5Q8Zq;chRz8f_;%8a`*vleJHB-jvY3W}^EVdVu~!_hEYOq7}uztxf=k@gE(npML8rk%rYZ|(Xu0i}|G<@55LF?#+ zg^7kdU4l2GMy=6y>J6t+ThSrdDlAMg`02h{>mJ6YRCF|TPeb>B$0oOJ3E4mH=U!q=fsV!Z diff --git a/tools/antigravity/src/app/[username]/page.tsx b/tools/antigravity/src/app/[username]/page.tsx index bac8668..890a9f1 100644 --- a/tools/antigravity/src/app/[username]/page.tsx +++ b/tools/antigravity/src/app/[username]/page.tsx @@ -2,6 +2,7 @@ import { prisma } from "@/lib/prisma"; import { getDailyQuote } from "@/lib/ai-service"; import CalendarLeaf from "@/components/CalendarLeaf"; import Onboarding from "@/components/Onboarding"; +import UserHeader from "@/components/UserHeader"; import styles from "../page.module.css"; import { Metadata } from "next"; @@ -49,13 +50,7 @@ export default async function UserPage({ params }: Props) { return (
-
-
ARK
-
-
-
{user.name}
-
-
+
diff --git a/tools/antigravity/src/components/CalendarLeaf.module.css b/tools/antigravity/src/components/CalendarLeaf.module.css index 908609b..970b6f8 100644 --- a/tools/antigravity/src/components/CalendarLeaf.module.css +++ b/tools/antigravity/src/components/CalendarLeaf.module.css @@ -7,6 +7,7 @@ perspective: 1000px; } +/* The Daily Quote Card (Underneath) */ /* The Daily Quote Card (Underneath) */ .quoteCard { position: absolute; @@ -14,29 +15,44 @@ background-color: hsl(var(--card-bg)); border: 1px solid hsl(var(--card-border)); border-radius: 1rem; - padding: 2rem; + padding: 2rem 1.5rem 1rem 1.5rem; + /* Less bottom padding */ display: flex; flex-direction: column; - justify-content: center; + justify-content: space-between; + /* Spread content */ align-items: center; text-align: center; box-shadow: var(--shadow-lg); z-index: 0; } +/* Container for text to keeping it centered-ish */ +.quoteContent { + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + overflow-y: auto; + /* Scroll if absolutely huge */ +} + .icon { width: 2rem; height: 2rem; color: hsl(var(--primary)); margin-bottom: 1rem; opacity: 0.8; + flex-shrink: 0; } .quoteText { font-family: var(--font-serif); - font-size: 1.5rem; + font-size: 1.35rem; + /* Slight resize for safety */ line-height: 1.4; - margin-bottom: 1.5rem; + margin-bottom: 1rem; font-weight: 500; color: hsl(var(--foreground)); } @@ -47,22 +63,25 @@ letter-spacing: 0.15em; font-size: 0.75rem; font-weight: 600; - margin-bottom: 1rem; + margin-bottom: 0.5rem; } .explanation { font-size: 0.75rem; opacity: 0.6; line-height: 1.5; - max-width: 250px; - margin-bottom: 1rem; + max-width: 100%; + margin-bottom: 0; } .actions { - position: absolute; - bottom: 1.5rem; + position: relative; + /* relative flow */ + bottom: auto; + margin-top: 1rem; display: flex; gap: 1rem; + flex-shrink: 0; } .actionBtn { diff --git a/tools/antigravity/src/components/CalendarLeaf.tsx b/tools/antigravity/src/components/CalendarLeaf.tsx index fb3d1a3..e8313bf 100644 --- a/tools/antigravity/src/components/CalendarLeaf.tsx +++ b/tools/antigravity/src/components/CalendarLeaf.tsx @@ -54,21 +54,23 @@ export default function CalendarLeaf({ quote, dateStr, userId }: { quote: any, d {/* The Quote (Underneath) */}
- +
+ -

- "{quote.content}" -

+

+ "{quote.content}" +

-

- — {quote.author || "Unbekannt"} -

+

+ — {quote.author || "Unbekannt"} +

- {quote.explanation && ( -
- {quote.explanation} -
- )} + {quote.explanation && ( +
+ {quote.explanation} +
+ )} +
diff --git a/tools/antigravity/src/components/SettingsOverlay.module.css b/tools/antigravity/src/components/SettingsOverlay.module.css new file mode 100644 index 0000000..cc40b39 --- /dev/null +++ b/tools/antigravity/src/components/SettingsOverlay.module.css @@ -0,0 +1,132 @@ +.overlay { + position: fixed; + inset: 0; + background-color: rgba(0, 0, 0, 0.6); + backdrop-filter: blur(8px); + z-index: 100; + display: flex; + justify-content: center; + align-items: flex-end; + /* Bottom sheet on mobile */ + padding: 1rem; +} + +@media (min-width: 640px) { + .overlay { + align-items: center; + /* Center on desktop */ + } +} + +.modal { + width: 100%; + max-width: 500px; + background-color: hsl(var(--card-bg)); + border: 1px solid hsl(var(--card-border)); + border-radius: 1.5rem 1.5rem 0 0; + /* Top corners only on mobile */ + padding: 2rem; + box-shadow: var(--shadow-xl); + max-height: 85vh; + overflow-y: auto; + position: relative; + color: white; +} + +@media (min-width: 640px) { + .modal { + border-radius: 1.5rem; + } +} + +.header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 1.5rem; +} + +.title { + font-size: 1.5rem; + font-weight: 700; + font-family: var(--font-serif); +} + +.closeBtn { + background: none; + border: none; + color: white; + cursor: pointer; + opacity: 0.7; + transition: opacity 0.2s; +} + +.closeBtn:hover { + opacity: 1; +} + +.section { + margin-bottom: 2rem; +} + +.sectionTitle { + font-size: 0.875rem; + text-transform: uppercase; + letter-spacing: 0.1em; + color: hsl(var(--secondary)); + margin-bottom: 1rem; + font-weight: 600; +} + +.chipContainer { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; +} + +.chip { + padding: 0.5rem 1rem; + border-radius: 9999px; + font-size: 0.875rem; + border: 1px solid rgba(255, 255, 255, 0.1); + background-color: rgba(255, 255, 255, 0.05); + color: #d1d5db; + cursor: pointer; + transition: all 0.2s; +} + +.chipSelected { + background-color: hsl(var(--primary)); + color: white; + border-color: hsl(var(--primary)); +} + +.saveBtn { + width: 100%; + background: linear-gradient(135deg, hsl(var(--primary)), hsl(var(--primary)/0.8)); + color: white; + border: none; + padding: 1rem; + border-radius: 1rem; + font-weight: 600; + cursor: pointer; + margin-top: 1rem; +} + +.installGuide { + background-color: rgba(255, 255, 255, 0.05); + padding: 1rem; + border-radius: 1rem; + font-size: 0.875rem; + line-height: 1.5; + color: #d1d5db; +} + +.iconRow { + display: flex; + align-items: center; + gap: 0.5rem; + margin-top: 0.5rem; + font-weight: bold; + color: white; +} \ No newline at end of file diff --git a/tools/antigravity/src/components/SettingsOverlay.tsx b/tools/antigravity/src/components/SettingsOverlay.tsx new file mode 100644 index 0000000..40f0049 --- /dev/null +++ b/tools/antigravity/src/components/SettingsOverlay.tsx @@ -0,0 +1,125 @@ +"use client"; +import React, { useState, useEffect } from "react"; +import { motion, AnimatePresence } from "framer-motion"; +import { X, Save, Share } from "lucide-react"; +import styles from "./SettingsOverlay.module.css"; +import { useRouter } from "next/navigation"; + +const INTERESTS = ["Stoizismus", "Achtsamkeit", "Unternehmertum", "Wissenschaft", "Kunst", "Poesie", "Führung", "Wellness"]; + +interface SettingsOverlayProps { + isOpen: boolean; + onClose: () => void; + user: { + id: string; + name: string; + preferences?: string | null; + }; +} + +export default function SettingsOverlay({ isOpen, onClose, user }: SettingsOverlayProps) { + const router = useRouter(); + const [selections, setSelections] = useState([]); + const [loading, setLoading] = useState(false); + const [ios, setIos] = useState(false); + + useEffect(() => { + // Detect iOS + const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !(window as any).MSStream; + setIos(isIOS); + + // Parse existing prefs + if (user.preferences) { + try { + const prefs = JSON.parse(user.preferences); + if (prefs.interests) setSelections(prefs.interests); + } catch (e) { console.error(e); } + } + }, [user]); + + const toggleInterest = (interest: string) => { + setSelections(prev => + prev.includes(interest) ? prev.filter(i => i !== interest) : [...prev, interest] + ); + }; + + const save = async () => { + setLoading(true); + try { + await fetch("/api/quote/daily", { + method: "POST", + headers: { "Content-Type": "application/json", "x-user-id": user.id }, + body: JSON.stringify({ interests: selections, name: user.name }), + }); + alert("Gespeichert!"); + router.refresh(); + onClose(); + } catch (e) { + alert("Fehler beim Speichern"); + } finally { + setLoading(false); + } + }; + + return ( + + {isOpen && ( +
+ e.stopPropagation()} + initial={{ y: "100%" }} + animate={{ y: 0 }} + exit={{ y: "100%" }} + transition={{ type: "spring", damping: 25, stiffness: 500 }} + > +
+

Einstellungen

+ +
+ +
+

Deine Interessen

+
+ {INTERESTS.map(item => ( + + ))} +
+
+ +
+

App Installation

+ {ios ? ( +
+
1. Tippe auf den Teilen Button unten in Safari.
+
+ + Teilen +
+
2. Wähle "Zum Home-Bildschirm".
+
+ ) : ( +
+ Für die beste Erfahrung: Füge diese Seite zu deinen Lesezeichen hinzu oder nutze "Zum Startbildschirm hinzufügen" im Browsermenü. +
+ )} +
+ + + +
+
+ )} +
+ ); +} diff --git a/tools/antigravity/src/components/UserHeader.tsx b/tools/antigravity/src/components/UserHeader.tsx new file mode 100644 index 0000000..22919d9 --- /dev/null +++ b/tools/antigravity/src/components/UserHeader.tsx @@ -0,0 +1,39 @@ +"use client"; +import React, { useState } from "react"; +import styles from "../app/page.module.css"; +import SettingsOverlay from "./SettingsOverlay"; + +interface UserHeaderProps { + user: { + id: string; + name: string; + preferences: string | null; + // any other fields needed + }; +} + +export default function UserHeader({ user }: UserHeaderProps) { + const [isSettingsOpen, setIsSettingsOpen] = useState(false); + + return ( + <> +
+
ARK
+
setIsSettingsOpen(true)} + style={{ cursor: 'pointer' }} + > +
+
{user.name}
+
+
+ + setIsSettingsOpen(false)} + user={user} + /> + + ); +} From 0f08cc2bf8ef8ea2941a751735ed451ce4fe5f33 Mon Sep 17 00:00:00 2001 From: Repository Admin Date: Sat, 20 Dec 2025 19:38:48 +0100 Subject: [PATCH 09/41] feat: responsive layout 100dvh vmin --- tools/antigravity/prisma/dev.db | Bin 45056 -> 45056 bytes tools/antigravity/src/app/page.module.css | 13 ++++++++++--- .../src/components/CalendarLeaf.module.css | 12 ++++++++---- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/tools/antigravity/prisma/dev.db b/tools/antigravity/prisma/dev.db index d03bb6391e595681324bccb5b0a4b792d655c687..a229b02ad3002f9fe635a1ebe21c5fe76c950d81 100644 GIT binary patch delta 91 zcmV-h0Hptb-~xc)0+1U45Rn{10T8iZp$`iWcmM(p=l~CV4(PKHAlwd<=pK*{00004 xfdK&sRRskX34s-p%wH%CIGh2SJql+0LuhhobCWC|D+gt4Y;I+9bF=Or5|G{k9Ay9i delta 79 zcmV-V0I>gn-~xc)0+1U450M;00S~cYp$`iH0006G=l~CR4(PKHAlwd<=pK*@fdv5w lRRskX34tAx%wH%CIGh2SJpDMFLuhhobCWC|Mzj7O0+7Bs8D0PY diff --git a/tools/antigravity/src/app/page.module.css b/tools/antigravity/src/app/page.module.css index 375faa1..f006799 100644 --- a/tools/antigravity/src/app/page.module.css +++ b/tools/antigravity/src/app/page.module.css @@ -1,11 +1,18 @@ .main { - max-width: 600px; - margin: 0 auto; + width: 100%; + max-width: 100%; min-height: 100vh; - padding: 2rem 1rem; + /* Fallback */ + height: 100dvh; + /* Dynamic viewport height */ + margin: 0; + padding: 1rem; display: flex; flex-direction: column; justify-content: center; + align-items: center; + overflow: hidden; + /* Prevent scroll */ } .mainStart { diff --git a/tools/antigravity/src/components/CalendarLeaf.module.css b/tools/antigravity/src/components/CalendarLeaf.module.css index 970b6f8..75c534c 100644 --- a/tools/antigravity/src/components/CalendarLeaf.module.css +++ b/tools/antigravity/src/components/CalendarLeaf.module.css @@ -1,9 +1,13 @@ .container { position: relative; - width: 100%; - max-width: 320px; - aspect-ratio: 3/4; - margin: 2rem auto; + /* Smart Scaling: Use 85% of the shortest viewport side, capped at 450px */ + width: 85vmin; + max-width: 450px; + /* Aspect ratio 3:4 roughly */ + height: 113vmin; + max-height: 600px; + + margin: 0 auto; perspective: 1000px; } From 0a8a9b446ccf503c41beea36bca7c3379f1679aa Mon Sep 17 00:00:00 2001 From: Repository Admin Date: Sat, 20 Dec 2025 19:50:02 +0100 Subject: [PATCH 10/41] feat: content enrichment concepts and author logic --- tools/antigravity/prisma/dev.db | Bin 45056 -> 45056 bytes tools/antigravity/prisma/schema.prisma | 1 + .../src/components/CalendarLeaf.tsx | 23 +++++++++++++++--- tools/antigravity/src/lib/ai-service.ts | 11 +++++++-- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/tools/antigravity/prisma/dev.db b/tools/antigravity/prisma/dev.db index a229b02ad3002f9fe635a1ebe21c5fe76c950d81..e4fba36e28729ea6e3ee39fa51f2dbc14c242a5c 100644 GIT binary patch delta 117 zcmZp8z|`=7X@az%AOiyfHxR=B=R_T2ML`C=vJPI}HU=)1rwn`>`OmXF0V=4<*lO;2|xVSiDOW@`Syb6p$Itoh3`FY8y1trBw3L&l$A)1>N*;3hA O_qPTLb{o9UNl- delta 83 zcmZp8z|`=7X@az%00RR9HxR=B$3z`tMF9rAvJPJU9}HY -

- — {quote.author || "Unbekannt"} -

+ {quote.author && quote.author !== "Unbekannt" && quote.author !== "Unknown" && ( +

+ — {quote.author} +

+ )} {quote.explanation && (
{quote.explanation}
)} + + {quote.concepts && ( +
+ {(() => { + try { + const concepts = JSON.parse(quote.concepts); + return concepts.map((c: any, i: number) => ( +
+ {c.word}: {c.definition} +
+ )); + } catch (e) { return null; } + })()} +
+ )}
diff --git a/tools/antigravity/src/lib/ai-service.ts b/tools/antigravity/src/lib/ai-service.ts index 4529872..05d3ac5 100644 --- a/tools/antigravity/src/lib/ai-service.ts +++ b/tools/antigravity/src/lib/ai-service.ts @@ -60,7 +60,14 @@ export async function getDailyQuote(userId: string) { const prefs = user?.preferences ? JSON.parse(user.preferences) : {}; const prompt = `Generiere ein einzigartiges, inspirierendes Zitat für einen Nutzer mit Interesse an: ${prefs.interests || "allgemeiner Weisheit"}. - Antworte im JSON Format: { "content": "Zitat auf Deutsch", "author": "Name", "explanation": "Maximal 2 Sätze Erklärung auf Deutsch", "category": "Ein Wort (Kategorie)" }`; + + Regeln für die Ausgabe (JSON): + - "content": Das Zitat auf Deutsch. + - "author": Name des Autors. Wenn unbekannt oder generell, gib null zurück. + - "explanation": Prägnante 2-3 Sätze Erklärung auf Deutsch. + - "category": Ein Wort (Kategorie). + - "concepts": Ein Array von Objekten { "word": "Begriff", "definition": "Kurze Erklärung" } für 1-3 schwierige oder wichtige Begriffe im Kontext (z.B. "Dichotomie der Kontrolle", "Achtsamkeit"). Wenn keine passenden Begriffe da sind, leeres Array. + `; const completion = await openai.chat.completions.create({ model: "gpt-4o-mini", @@ -88,13 +95,13 @@ export async function getDailyQuote(userId: string) { } // 3. Save to DB - // Create Quote if not exists (deduplication logic skipped for simplicity, just create new for now) const quote = await prisma.quote.create({ data: { content: quoteData.content, author: quoteData.author, explanation: quoteData.explanation, category: quoteData.category, + concepts: quoteData.concepts ? JSON.stringify(quoteData.concepts) : null, sourceModel: openai ? "gpt-4o-mini" : "mock" } }); From 67c045af4010ae297fa7470b7a451ef23c20a720 Mon Sep 17 00:00:00 2001 From: Repository Admin Date: Sat, 20 Dec 2025 21:04:42 +0100 Subject: [PATCH 11/41] feat: interactive concepts and overlay --- tools/antigravity/prisma/dev.db | Bin 45056 -> 45056 bytes .../src/components/ConceptOverlay.module.css | 45 ++++++++++++++++++ .../src/components/ConceptOverlay.tsx | 32 +++++++++++++ tools/antigravity/src/lib/ai-service.ts | 31 ++++++++---- 4 files changed, 100 insertions(+), 8 deletions(-) create mode 100644 tools/antigravity/src/components/ConceptOverlay.module.css create mode 100644 tools/antigravity/src/components/ConceptOverlay.tsx diff --git a/tools/antigravity/prisma/dev.db b/tools/antigravity/prisma/dev.db index e4fba36e28729ea6e3ee39fa51f2dbc14c242a5c..d1ae53f0e9c4dbaf11792d6b47394ee9d8b14ed3 100644 GIT binary patch delta 140 zcmZp8z|`=7X@ayM2Ll5GHxR=B$3z`tMGgkNvJPJU9}HYYS&=Q3ovX=~nO$65oUtWx@&w-V?8*6g$*Bb;n*;eaFm7fnU>4ZS XQt*d=QGoy)Z7N_9Sj<=g}1+t-JNBuPrcclV=ymoJSBNn@wK%4EKj`jd~O>~(ZE`6yFPm()YO zi#^YJuJnvtZ;@pG`Kd&2E|-(PSh%>JxqISRlqX6Br=(9#RVMUu zsbuMuvNf(3oJz?k8wI;kapcQ~p8oK4`}h5NK)LW6^>vLhK?1@7!1SluqVVY&sg6C}#K?xu( z!~_g6HjjcCJnRq~hs=(jbxJ;lXE`Q8>?^>6W7`M}2Dl9l=P+nm^_POwhzoBCBltby zn+Eh#$ZA+n;s5}=WYpu@0m{}*6EH;Oe@INY#|VI)j|>q8kT$LouaF?(Zh7klRKUjO z8E??Q5Y%VTM$M;JNv$FDvafrT(T&&Sv~+%U-^Tt9H5LVR-52$M*aR5tsMiJqNKHKt z+8q=MpyB^ZQCluxJR*Vw-qwv;)1^>f9wc*3E@JV-*3H0+$!GWkhz!_w8Nq8IHeEuY z*s;URXJ@=f!%hi7`L=*Zf%G-npx_-f(%y*TUG0tr#wu-s3NPyT|B|)4pxp!!-76jQ z9hCy9W(Wgv;u`D3g|6GBJ|Cz4fCNU!9UnvqLRP6orruguBlVZWc{2A|hc+3sBPGy1 z3EfA3qI)nsx6rhjNbFOOftakO%88u35c+~BFl4GaV^BAvB!=baaOPu5R+M=9&;<$I zLKnb)9W~!kdZenH8tH1tqa}FND;A0q`gl<<7N%uzR#PM041Tn+=Bz#62#So7wXfy)_Ki{oNUm~Z*xAtm#C;@X1 x!SHu<5G6+Cj!{suiBYxV-gdYop*!djIDCU@rDS!at7W)Xq*4T*uJ+=d&%XeyK void; +} + +export default function ConceptOverlay({ word, definition, onClose }: ConceptOverlayProps) { + return ( + + {word && ( +
+ e.stopPropagation()} + > +

{word}

+

{definition}

+

Tippe irgendwo zum Schließen

+
+
+ )} +
+ ); +} diff --git a/tools/antigravity/src/lib/ai-service.ts b/tools/antigravity/src/lib/ai-service.ts index 05d3ac5..aa7fd7c 100644 --- a/tools/antigravity/src/lib/ai-service.ts +++ b/tools/antigravity/src/lib/ai-service.ts @@ -5,25 +5,31 @@ const openai = process.env.OPENAI_API_KEY ? new OpenAI({ apiKey: process.env.OPENAI_API_KEY }) : null; -// Mock data for development without API Key +// Debug Log +console.log("AI Service Init. Key present:", !!process.env.OPENAI_API_KEY); + +// Mock data for fallback const MOCK_QUOTES = [ { content: "Der einzige Weg, großartige Arbeit zu leisten, ist zu lieben, was man tut.", author: "Steve Jobs", explanation: "Leidenschaft ist der Treibstoff für Exzellenz.", - category: "Motivation" + category: "Motivation", + concepts: JSON.stringify([{ word: "Leidenschaft", definition: "Starkes Gefühl der Begeisterung" }]) }, { content: "In der Mitte der Schwierigkeit liegt die Gelegenheit.", author: "Albert Einstein", explanation: "Herausforderungen verbergen oft die besten Chancen für Wachstum.", - category: "Weisheit" + category: "Weisheit", + concepts: JSON.stringify([{ word: "Gelegenheit", definition: "Günstiger Umstand" }]) }, { content: "Das Glück hängt von uns selbst ab.", author: "Aristoteles", explanation: "Äußere Umstände definieren nicht deinen inneren Zustand.", - category: "Philosophie" + category: "Philosophie", + concepts: JSON.stringify([{ word: "Glück", definition: "Subjektives Wohlbefinden" }]) } ]; @@ -51,7 +57,7 @@ export async function getDailyQuote(userId: string) { } // 2. Generate or Fetch new quote - let quoteData; + let quoteData: any; if (openai) { try { @@ -66,7 +72,7 @@ export async function getDailyQuote(userId: string) { - "author": Name des Autors. Wenn unbekannt oder generell, gib null zurück. - "explanation": Prägnante 2-3 Sätze Erklärung auf Deutsch. - "category": Ein Wort (Kategorie). - - "concepts": Ein Array von Objekten { "word": "Begriff", "definition": "Kurze Erklärung" } für 1-3 schwierige oder wichtige Begriffe im Kontext (z.B. "Dichotomie der Kontrolle", "Achtsamkeit"). Wenn keine passenden Begriffe da sind, leeres Array. + - "concepts": Ein Array von Objekten { "word": "Begriff", "definition": "Kurze Erklärung" } für 1-3 schwierige oder wichtige Begriffe. WICHTIG: Der "word" Wert MUSS EXAKT so im "content" oder der "explanation" vorkommen (gleiche Schreibweise), damit er markiert werden kann. `; const completion = await openai.chat.completions.create({ @@ -84,24 +90,33 @@ export async function getDailyQuote(userId: string) { } } catch (error) { console.error("OpenAI Error:", error); - // Fallback to mock + // Fallback to mock logic will trigger if quoteData is still null } } // Fallback if no OpenAI or error if (!quoteData) { + console.log("Using Mock Data"); const randomIndex = Math.floor(Math.random() * MOCK_QUOTES.length); quoteData = MOCK_QUOTES[randomIndex]; } // 3. Save to DB + // Handle concepts safely (might be array from AI or string from Mock) + let conceptsStr = null; + if (quoteData.concepts) { + conceptsStr = typeof quoteData.concepts === 'string' + ? quoteData.concepts + : JSON.stringify(quoteData.concepts); + } + const quote = await prisma.quote.create({ data: { content: quoteData.content, author: quoteData.author, explanation: quoteData.explanation, category: quoteData.category, - concepts: quoteData.concepts ? JSON.stringify(quoteData.concepts) : null, + concepts: conceptsStr, sourceModel: openai ? "gpt-4o-mini" : "mock" } }); From 5f77521054e05709fb639323b621fc6fab5d2e5d Mon Sep 17 00:00:00 2001 From: Repository Admin Date: Sat, 20 Dec 2025 21:13:07 +0100 Subject: [PATCH 12/41] fix(ai): tune temp and prompt for subtlety; fix(ui): repair highlight and remove list --- .../src/components/CalendarLeaf.tsx | 95 +++++++++++++++---- tools/antigravity/src/lib/ai-service.ts | 14 ++- 2 files changed, 89 insertions(+), 20 deletions(-) diff --git a/tools/antigravity/src/components/CalendarLeaf.tsx b/tools/antigravity/src/components/CalendarLeaf.tsx index be3a963..070a811 100644 --- a/tools/antigravity/src/components/CalendarLeaf.tsx +++ b/tools/antigravity/src/components/CalendarLeaf.tsx @@ -3,9 +3,11 @@ import { motion, useMotionValue, useTransform } from "framer-motion"; import { useState } from "react"; import { Quote, Share2, Heart } from "lucide-react"; import styles from "./CalendarLeaf.module.css"; +import ConceptOverlay from "./ConceptOverlay"; export default function CalendarLeaf({ quote, dateStr, userId }: { quote: any, dateStr: string, userId?: string }) { const [revealed, setRevealed] = useState(false); + const [activeConcept, setActiveConcept] = useState<{ word: string, definition: string } | null>(null); const y = useMotionValue(0); const rotate = useTransform(y, [0, 300], [0, 15]); @@ -49,8 +51,82 @@ export default function CalendarLeaf({ quote, dateStr, userId }: { quote: any, d } }; + // Robust Interactive Text Rendering + const renderInteractiveText = (text: string, conceptsJson: string | null) => { + if (!conceptsJson || !text) return text; + + try { + const concepts = JSON.parse(conceptsJson); + if (!Array.isArray(concepts) || concepts.length === 0) return text; + + // Sort by length desc (longest match first) + concepts.sort((a: any, b: any) => b.word.length - a.word.length); + + // Escape regex chars + const escapeRegExp = (string: string) => string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + + // Build regex with word boundaries to avoid partial matches inside words + // Flag 'i' for case insensitive + const pattern = new RegExp(`\\b(${concepts.map((c: any) => escapeRegExp(c.word)).join('|')})\\b`, 'gi'); + + const matches = text.match(pattern); + if (!matches) return text; + + const result = []; + let lastIndex = 0; + let match; + const iterPattern = new RegExp(`\\b(${concepts.map((c: any) => escapeRegExp(c.word)).join('|')})\\b`, 'gi'); + + while ((match = iterPattern.exec(text)) !== null) { + if (match.index > lastIndex) { + result.push(text.substring(lastIndex, match.index)); + } + + const matchedWord = match[0]; + const concept = concepts.find((c: any) => c.word.toLowerCase() === matchedWord.toLowerCase()); + + if (concept) { + result.push( + { e.stopPropagation(); setActiveConcept(concept); }} + style={{ + textDecoration: 'underline', + textDecorationStyle: 'dashed', + textDecorationColor: 'hsl(var(--primary))', + cursor: 'pointer', + textUnderlineOffset: '4px' + }} + > + {matchedWord} + + ); + } else { + result.push(matchedWord); + } + + lastIndex = iterPattern.lastIndex; + } + + if (lastIndex < text.length) { + result.push(text.substring(lastIndex)); + } + + return result; + + } catch (e) { + console.error("Interaction Error", e); + return text; + } + }; + return (
+ setActiveConcept(null)} + /> {/* The Quote (Underneath) */}
@@ -58,7 +134,7 @@ export default function CalendarLeaf({ quote, dateStr, userId }: { quote: any, d

- "{quote.content}" + "{renderInteractiveText(quote.content, quote.concepts)}"

{quote.author && quote.author !== "Unbekannt" && quote.author !== "Unknown" && ( @@ -69,24 +145,11 @@ export default function CalendarLeaf({ quote, dateStr, userId }: { quote: any, d {quote.explanation && (
- {quote.explanation} + {renderInteractiveText(quote.explanation, quote.concepts)}
)} - {quote.concepts && ( -
- {(() => { - try { - const concepts = JSON.parse(quote.concepts); - return concepts.map((c: any, i: number) => ( -
- {c.word}: {c.definition} -
- )); - } catch (e) { return null; } - })()} -
- )} +
diff --git a/tools/antigravity/src/lib/ai-service.ts b/tools/antigravity/src/lib/ai-service.ts index aa7fd7c..802e4b8 100644 --- a/tools/antigravity/src/lib/ai-service.ts +++ b/tools/antigravity/src/lib/ai-service.ts @@ -65,23 +65,29 @@ export async function getDailyQuote(userId: string) { const user = await prisma.user.findUnique({ where: { id: userId } }); const prefs = user?.preferences ? JSON.parse(user.preferences) : {}; - const prompt = `Generiere ein einzigartiges, inspirierendes Zitat für einen Nutzer mit Interesse an: ${prefs.interests || "allgemeiner Weisheit"}. + const prompt = `Generiere ein einzigartiges, inspirierendes Zitat für einen Nutzer mit den Interessen: ${prefs.interests || "allgemeine Weisheit"}. + + WICHTIGE ANWEISUNGEN: + 1. Wähle NUR EINES der Interessen aus oder generiere etwas Allgemeines. Versuche NICHT, alle Interessen zu kombinieren. + 2. Sei SUTIL: Das Zitat soll nicht erzwungen wirken. + 3. "concepts": Wähle NUR komplexe, philosophische oder fachspezifische Begriffe (z.B. "Stoizismus", "Entropie", "Amor Fati"). Erkläre KEINE alltäglichen Wörter wie "Leben", "Wissenschaft" oder "Glück". Wenn keine wirklich schwierigen Begriffe vorkommen, lass das Array leer. Regeln für die Ausgabe (JSON): - "content": Das Zitat auf Deutsch. - "author": Name des Autors. Wenn unbekannt oder generell, gib null zurück. - "explanation": Prägnante 2-3 Sätze Erklärung auf Deutsch. - "category": Ein Wort (Kategorie). - - "concepts": Ein Array von Objekten { "word": "Begriff", "definition": "Kurze Erklärung" } für 1-3 schwierige oder wichtige Begriffe. WICHTIG: Der "word" Wert MUSS EXAKT so im "content" oder der "explanation" vorkommen (gleiche Schreibweise), damit er markiert werden kann. + - "concepts": Ein Array von Objekten { "word": "Begriff", "definition": "Kurze Erklärung" }. WICHTIG: Der "word" Wert MUSS EXAKT so im "content" oder der "explanation" vorkommen (gleiche Schreibweise). `; const completion = await openai.chat.completions.create({ model: "gpt-4o-mini", messages: [ - { role: "system", content: "Du bist ein weiser Assistent, der tägliche Inspiration liefert." }, + { role: "system", content: "Du bist ein weiser, tiefsinniger Mentor. Du bevorzugst Tiefe vor Breite." }, { role: "user", content: prompt } ], - response_format: { type: "json_object" } + response_format: { type: "json_object" }, + temperature: 1.15 }); const content = completion.choices[0].message.content; From 29f97ca7297dd6dd44c7fb47456df5ced500fb09 Mon Sep 17 00:00:00 2001 From: Repository Admin Date: Sat, 20 Dec 2025 21:20:11 +0100 Subject: [PATCH 13/41] fix(ui): explicit input contrast; fix(backend): add detailed ai logs --- tools/antigravity/prisma/dev.db | Bin 45056 -> 45056 bytes .../src/components/Onboarding.module.css | 16 ++++++++++++---- tools/antigravity/src/lib/ai-service.ts | 6 +++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/tools/antigravity/prisma/dev.db b/tools/antigravity/prisma/dev.db index d1ae53f0e9c4dbaf11792d6b47394ee9d8b14ed3..e2d9661a0ea16e8f8511c205c505fbedf6e378d5 100644 GIT binary patch delta 2113 zcma)7L1-IC6y24gq_Sg=b4XK2(~MVy7Am=lB*(H#DQ;{hZBuaK%7%tON7^s#;N4j> zGaC~bvvHCVXep$}&{Jt|J%keIDTjc2Y>$Or4Dqcw?g) z)GF<%CQO!m=1-MsXWHdbbFw~Nnr=>&Th-}iWx8H*zkRQ>aIE({8%VA;JT5dyP+EC2 zm%Z6mpcRW&foremt#GA4s8+z*X1Jtd-sLJvly{}*2^N8u&UiMBx9K>}Q3P@_zm>WM z(TV)lFlhG>z8=k|z-p7#a=TiZnyyclYSn71RIjy8m&)yWmDO0;uh-j%3Vu9{Pd@b8 zM{z6uAGD7Xp$v+}7!(J5S=fFMjLSrH_R-9ECeGU&LNFO}&ms57A4t>pg9IS6eDO9Ad@ zVlm)htm3tR!{rTcJ(j*V^Q`%bo)2v%nfk}fdK zEx)!biY1g`wh{G611c;^k;tArTC$E2HC3@dzX?-^2Lf?h^{mZMz884O(xdQ98`cC} zL~*-(jpM8FZ6Bwh%Xrt&L(g+zU8F2x6rWxIG!<2;<(aY&ZGv{B7ZV6Wu&MU_{a>aP z)(VtPB1M^@9kmhYY3Wb&Dd>rJfn##qNJN)f0dK7;78Z?}P!PL4EEE~@Aw%f@1ARVOPQ%TO z57eOTA-q#5S0+oRE2T<##>L=#ZhVlYZEl!{r~0u5iZgcqApPg$;UV%D!g}nI$K-E> zwL=Pd+={*2%vKH@${x*|+a>5-F1rqSN_KJK@8oTgEx5fVWP4U-G+W3&Gwuc4b;w=v b8wPw$I@JS>@qw Date: Sat, 20 Dec 2025 21:24:46 +0100 Subject: [PATCH 14/41] fix(debug): add verbose logging and force dynamic rendering --- tools/antigravity/prisma/dev.db | Bin 45056 -> 45056 bytes tools/antigravity/src/app/[username]/page.tsx | 3 +++ .../src/app/api/quote/daily/route.ts | 1 + tools/antigravity/src/lib/ai-service.ts | 1 + 4 files changed, 5 insertions(+) diff --git a/tools/antigravity/prisma/dev.db b/tools/antigravity/prisma/dev.db index e2d9661a0ea16e8f8511c205c505fbedf6e378d5..0d0d45313826399cc9456034b1b9b5ff288c44a2 100644 GIT binary patch delta 154 zcmZp8z|`=7X@WGP;6xc`M!}5{uX6}eDWR(a0GdPWW)Lzc6V zJGF$79mo{rtj`8B#5uDkpNZGtUCqNd+cu}vI4D0Sr*iUfc{%=A9i_a)+*BniC9v4$ vfAY);+zbp1O#Cld_+RpW-Yl4KmtUBZS)9>1qbReOiGx|36Qc4@KZ^nYnc*!t delta 149 zcmZp8z|`=7X@WGPz(g5mMuCk9EBTqb_}*?7RCvfY`K?^Hv}h { } } +export const dynamic = 'force-dynamic'; + export default async function UserPage({ params }: Props) { const { username } = await params; const decodedName = decodeURIComponent(username); + console.log(`[UserPage] Loading for: ${decodedName}`); // 1. Try to find user by Name // Note: Schema has `name` as unique. diff --git a/tools/antigravity/src/app/api/quote/daily/route.ts b/tools/antigravity/src/app/api/quote/daily/route.ts index 2e37b5b..c29befb 100644 --- a/tools/antigravity/src/app/api/quote/daily/route.ts +++ b/tools/antigravity/src/app/api/quote/daily/route.ts @@ -3,6 +3,7 @@ import { getDailyQuote } from "@/lib/ai-service"; import { prisma } from "@/lib/prisma"; export async function GET(req: NextRequest) { + console.log("[API] GET /api/quote/daily called"); const userId = req.headers.get("x-user-id"); if (!userId) { diff --git a/tools/antigravity/src/lib/ai-service.ts b/tools/antigravity/src/lib/ai-service.ts index 8a96355..c281bfd 100644 --- a/tools/antigravity/src/lib/ai-service.ts +++ b/tools/antigravity/src/lib/ai-service.ts @@ -50,6 +50,7 @@ export async function getDailyQuote(userId: string) { }); if (history) { + console.log(`[QuoteService] History found for user ${userId}. Returning cached quote.`); return { ...history.quote, isNew: false From 6b7ae6aeb23b4383184d36fc93cc39ffe78dad9e Mon Sep 17 00:00:00 2001 From: Repository Admin Date: Sat, 20 Dec 2025 21:27:39 +0100 Subject: [PATCH 15/41] fix(logic): invalidate daily view on profile update to ensure freshness --- tools/antigravity/dump-users.js | 16 ++++++++++++++++ tools/antigravity/prisma/dev.db | Bin 45056 -> 45056 bytes .../src/app/api/quote/daily/route.ts | 17 +++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 tools/antigravity/dump-users.js diff --git a/tools/antigravity/dump-users.js b/tools/antigravity/dump-users.js new file mode 100644 index 0000000..8f1bba4 --- /dev/null +++ b/tools/antigravity/dump-users.js @@ -0,0 +1,16 @@ +const { PrismaClient } = require('@prisma/client'); +const prisma = new PrismaClient(); + +async function main() { + const users = await prisma.user.findMany(); + console.log("--- DB USER DUMP ---"); + console.log(`Total Users: ${users.length}`); + users.forEach(u => console.log(`- ${u.name} (ID: ${u.id})`)); + console.log("--------------------"); +} + +main() + .catch(e => console.error(e)) + .finally(async () => { + await prisma.$disconnect(); + }); diff --git a/tools/antigravity/prisma/dev.db b/tools/antigravity/prisma/dev.db index 0d0d45313826399cc9456034b1b9b5ff288c44a2..b8c65af0b538ed5fe67d152cba6f750a8ea18ba9 100644 GIT binary patch delta 132 zcmZp8z|`=7X@WGP&_o$$Mxl)f3;DSj7#NuNl^OUa^DA!_RCvfY`K_E8XC4!KC@ZTt zXW``jc$LXA@|;%rnsdAob5o0}l``{6Qj1cHONy1OqLl*jQ;RcGm2{Nc4)4h*D$Pq* fiq%od11eOqQUa@2s@*(UKB|BP#M%6@pI-q05ilw3 delta 183 zcmZp8z|`=7X@WGP;6xc`M!}5<3;DVEOBtB>-ZJn{=6kzYP~jop Date: Sat, 20 Dec 2025 21:41:23 +0100 Subject: [PATCH 16/41] fix(ai): remove biased examples from prompt to increase variety --- tools/antigravity/prisma/dev.db | Bin 45056 -> 53248 bytes tools/antigravity/src/lib/ai-service.ts | 31 +++++++++++++++--------- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/tools/antigravity/prisma/dev.db b/tools/antigravity/prisma/dev.db index b8c65af0b538ed5fe67d152cba6f750a8ea18ba9..0a042aa02586e353e810add9f20b1fea0cc90e60 100644 GIT binary patch literal 53248 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 FJ^-$vMr;58 diff --git a/tools/antigravity/src/lib/ai-service.ts b/tools/antigravity/src/lib/ai-service.ts index c281bfd..6a66953 100644 --- a/tools/antigravity/src/lib/ai-service.ts +++ b/tools/antigravity/src/lib/ai-service.ts @@ -68,25 +68,32 @@ export async function getDailyQuote(userId: string) { const user = await prisma.user.findUnique({ where: { id: userId } }); const prefs = user?.preferences ? JSON.parse(user.preferences) : {}; - const prompt = `Generiere ein einzigartiges, inspirierendes Zitat für einen Nutzer mit den Interessen: ${prefs.interests || "allgemeine Weisheit"}. + const prompt = `Handele als Kurator für tiefe Weisheit. + Der Nutzer interessiert sich für: ${prefs.interests || "Philosophie & Leben"}. - WICHTIGE ANWEISUNGEN: - 1. Wähle NUR EINES der Interessen aus oder generiere etwas Allgemeines. Versuche NICHT, alle Interessen zu kombinieren. - 2. Sei SUTIL: Das Zitat soll nicht erzwungen wirken. - 3. "concepts": Wähle NUR komplexe, philosophische oder fachspezifische Begriffe (z.B. "Stoizismus", "Entropie", "Amor Fati"). Erkläre KEINE alltäglichen Wörter wie "Leben", "Wissenschaft" oder "Glück". Wenn keine wirklich schwierigen Begriffe vorkommen, lass das Array leer. + 1. Wähle EINES dieser Interessen (oder ein verwandtes Thema) und finde/generiere ein tiefgründiges, inspirierendes Zitat (deutsch). + 2. Sei kreativ! Vermeide Klischees. + 3. ANALYSIERE das Zitat anschließend auf schwierig zu verstehende Begriffe: + - Suche nach Fremdwörtern, Fachbegriffen, archaischer Sprache oder philosophischen Konzepten. + - Identifiziere 1-3 solcher Begriffe, die IM TEXT vorkommen. + - Erkläre KEINE einfachen Wörter (wie "Leben", "Zeit", "Glück"), es sei denn, sie werden in einem sehr spezifischen, komplexen Kontext verwendet. + - Wenn das Zitat nur einfache Sprache verwendet, lass das "concepts"-Array leer. ERZWINGE KEINE BEGRIFFE. - Regeln für die Ausgabe (JSON): - - "content": Das Zitat auf Deutsch. - - "author": Name des Autors. Wenn unbekannt oder generell, gib null zurück. - - "explanation": Prägnante 2-3 Sätze Erklärung auf Deutsch. - - "category": Ein Wort (Kategorie). - - "concepts": Ein Array von Objekten { "word": "Begriff", "definition": "Kurze Erklärung" }. WICHTIG: Der "word" Wert MUSS EXAKT so im "content" oder der "explanation" vorkommen (gleiche Schreibweise). + Output JSON: + { + "content": "Zitat...", + "author": "Autor Name (oder null)", + "explanation": "Prägnante Deutung (2-3 Sätze).", + "category": "Ein Wort", + "concepts": [ { "word": "Begriff", "definition": "Erklärung" } ] + } + WICHTIG: "word" muss exakt (Case-Insensitive) im Zitat vorkommen. `; const completion = await openai.chat.completions.create({ model: "gpt-4o-mini", messages: [ - { role: "system", content: "Du bist ein weiser, tiefsinniger Mentor. Du bevorzugst Tiefe vor Breite." }, + { role: "system", content: "Du bist ein intellektueller Mentor. Du schätzt präzise Sprache und Vielfalt." }, { role: "user", content: prompt } ], response_format: { type: "json_object" }, From d8de11a358306c2573ce382186c0c19e1fc71dd4 Mon Sep 17 00:00:00 2001 From: Repository Admin Date: Sat, 20 Dec 2025 21:47:28 +0100 Subject: [PATCH 17/41] feat(ai): add Veit Lindau style modes (Questions/Impulses) --- tools/antigravity/src/lib/ai-service.ts | 47 +++++++++++++++++-------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/tools/antigravity/src/lib/ai-service.ts b/tools/antigravity/src/lib/ai-service.ts index 6a66953..2a6ae4f 100644 --- a/tools/antigravity/src/lib/ai-service.ts +++ b/tools/antigravity/src/lib/ai-service.ts @@ -68,26 +68,43 @@ export async function getDailyQuote(userId: string) { const user = await prisma.user.findUnique({ where: { id: userId } }); const prefs = user?.preferences ? JSON.parse(user.preferences) : {}; - const prompt = `Handele als Kurator für tiefe Weisheit. - Der Nutzer interessiert sich für: ${prefs.interests || "Philosophie & Leben"}. - - 1. Wähle EINES dieser Interessen (oder ein verwandtes Thema) und finde/generiere ein tiefgründiges, inspirierendes Zitat (deutsch). - 2. Sei kreativ! Vermeide Klischees. - 3. ANALYSIERE das Zitat anschließend auf schwierig zu verstehende Begriffe: - - Suche nach Fremdwörtern, Fachbegriffen, archaischer Sprache oder philosophischen Konzepten. - - Identifiziere 1-3 solcher Begriffe, die IM TEXT vorkommen. - - Erkläre KEINE einfachen Wörter (wie "Leben", "Zeit", "Glück"), es sei denn, sie werden in einem sehr spezifischen, komplexen Kontext verwendet. - - Wenn das Zitat nur einfache Sprache verwendet, lass das "concepts"-Array leer. ERZWINGE KEINE BEGRIFFE. + // Randomly select mode: Quote (60%), Question (30%), Pulse (10%) + const modes = ["QUOTE", "QUOTE", "QUOTE", "QUOTE", "QUOTE", "QUOTE", "QUESTION", "QUESTION", "QUESTION", "PULSE"]; + const mode = modes[Math.floor(Math.random() * modes.length)]; + + const prompt = `Handele als 'Soul-Coach' (inspiriert von Veit Lindau), der den Nutzer aufwecken und berühren will. + Das heutige Format ist: ${mode}. + Der Nutzer interessiert sich für: ${prefs.interests || "Leben, Liebe, Erfolg"}. + Wähle ein Thema davon. + + ANWEISUNGEN FÜR ${mode}: + ${mode === "QUOTE" ? ` + - Suche ein tiefgründiges Zitat (deutsch). + - Autor kann bekannt sein oder 'Unbekannt'. + ` : mode === "QUESTION" ? ` + - Formuliere eine RADIKALE, direkte Frage an den Nutzer ("Du"-Form). + - Beispiel: "Wofür bist du heute unendlich dankbar?" oder "Was würdest du tun, wenn du keine Angst hättest?" + - "author" Feld soll "Reflexion" sein. + ` : ` + - Formuliere einen kurzen, kraftvollen Impuls oder Mantra ("Du"-Form). + - Beispiel: "Atme tief ein. Das Leben ist jetzt." + - "author" Feld soll "Impuls" sein. + `} + + ANALYSE (für alle Formate): + - Analysiere den Text auf schwierige/spannende Begriffe (Fremdwörter, Konzepte). + - Identifiziere 1-3 Begriff, die IM TEXT vorkommen. + - Falls der Text einfach ist, lass "concepts" leer. + Output JSON: { - "content": "Zitat...", - "author": "Autor Name (oder null)", - "explanation": "Prägnante Deutung (2-3 Sätze).", - "category": "Ein Wort", + "content": "Text des Zitats/Frage/Impuls", + "author": "Name oder 'Reflexion'/'Impuls'", + "explanation": "Kurze Deutung oder Coaching-Hinweis dazu (2-3 Sätze).", + "category": "Kategorie (Ein Wort)", "concepts": [ { "word": "Begriff", "definition": "Erklärung" } ] } - WICHTIG: "word" muss exakt (Case-Insensitive) im Zitat vorkommen. `; const completion = await openai.chat.completions.create({ From dec6aa835b3174a6a0275ae559d1f42e848bed1d Mon Sep 17 00:00:00 2001 From: Repository Admin Date: Sat, 20 Dec 2025 21:51:58 +0100 Subject: [PATCH 18/41] feat(history): add archive page with favorites filter; fix(ui): landing page input visibility --- tools/antigravity/prisma/dev.db | Bin 53248 -> 61440 bytes .../src/app/[username]/archive/page.tsx | 109 ++++++++++++++++++ tools/antigravity/src/app/page.tsx | 8 +- .../src/components/SettingsOverlay.tsx | 14 +++ 4 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 tools/antigravity/src/app/[username]/archive/page.tsx diff --git a/tools/antigravity/prisma/dev.db b/tools/antigravity/prisma/dev.db index 0a042aa02586e353e810add9f20b1fea0cc90e60..f077afa776048b482527e746bec11f3a4f6b5353 100644 GIT binary patch delta 7188 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 IA7v2we~4W^)Bpeg delta 386 zcmZp8z}&Ead4e>n83O|Y??eTAMzf6xOZnOPRx$9c;#b}*sL;x%)X2}s5z5M{$l0i# znrLEbY>;NGYi?;_s$0&;4is1BET4QPUc+rQ594gxs?T=biA9Mesfl?hnMT!0nRz9t zMXALl#Y$GuN}(W5UTQ{eYEemPu2QUyQeI+is*;rwl9tJe@}+FKtgPak*&tJ`z^3Mu z8VBX), searchParams: Promise<{ filter?: string }> }) { + const { username } = await params; + const { filter } = await searchParams; + const decodedName = decodeURIComponent(username); + + const user = await prisma.user.findUnique({ + where: { name: decodedName }, + include: { + views: { + include: { quote: true }, + orderBy: { viewedAt: 'desc' } + }, + ratings: { + include: { quote: true }, + orderBy: { createdAt: 'desc' } + } + } + }); + + if (!user) return
User not found
; + + let quotes: (Quote & { viewedAt?: Date })[] = []; + const showingFavorites = filter === 'favorites'; + + if (showingFavorites) { + quotes = user.ratings.map(r => ({ ...r.quote, viewedAt: r.createdAt })); + } else { + // Default: History (Views). Unique by Quote ID? No, show timeline. + quotes = user.views.map(v => ({ ...v.quote, viewedAt: v.viewedAt })); + } + + return ( +
+ {/* Header */} +
+ + Zurück + +

Archiv

+
+
+ + {/* Filter Toggle */} +
+ + Verlauf + + + Favoriten + +
+ + {/* Grid */} +
+ {quotes.length === 0 && ( +
+ Noch keine Einträge. +
+ )} + {quotes.map((quote, i) => ( +
+
+ "{quote.content}" +
+
+ {quote.author !== 'Reflexion' && quote.author !== 'Impuls' ? quote.author : ''} + {new Date(quote.viewedAt!).toLocaleDateString('de-DE')} +
+ {quote.explanation && ( +
+ {quote.explanation} +
+ )} +
+ ))} +
+
+ ); +} diff --git a/tools/antigravity/src/app/page.tsx b/tools/antigravity/src/app/page.tsx index 1c0bb37..82fd0e3 100644 --- a/tools/antigravity/src/app/page.tsx +++ b/tools/antigravity/src/app/page.tsx @@ -27,8 +27,12 @@ export default function Home() { value={name} onChange={(e) => setName(e.target.value)} placeholder="Name eingeben..." - className="w-full bg-black/20 border border-white/10 rounded-xl p-4 text-lg focus:outline-none focus:border-[hsl(var(--primary))]" - style={{ color: 'white' }} + className="w-full rounded-xl p-4 text-lg focus:outline-none" + style={{ + backgroundColor: '#1f2937', + color: 'white', + border: '1px solid rgba(255,255,255,0.2)' + }} onKeyDown={(e) => e.key === "Enter" && go()} />
+
+

Deine Sammlung

+ +
+

App Installation

{ios ? ( From 4f73e6026f1668f99ac0f96b93c7731c6fac664d Mon Sep 17 00:00:00 2001 From: Repository Admin Date: Sun, 21 Dec 2025 20:31:10 +0100 Subject: [PATCH 19/41] fix(auth): switch user session cookie on name change for correct data isolation --- tools/antigravity/prisma/dev.db | Bin 61440 -> 65536 bytes .../src/app/api/quote/daily/route.ts | 95 +++++++++++++----- 2 files changed, 72 insertions(+), 23 deletions(-) diff --git a/tools/antigravity/prisma/dev.db b/tools/antigravity/prisma/dev.db index f077afa776048b482527e746bec11f3a4f6b5353..1be88c8b2b26d828a2902d329c85e7ee8625590e 100644 GIT binary patch delta 2324 zcma)7Piz!b7@yhc0;S!3TdVCNY5LeDR>E%SmJ)206p)rmRG_ugPzcWMe7pOyvu~O= zGhJMwZKdMHC}fPm_$M5CG$FW#7(?P=xtMr?U^Hn>Ow;qbyH zP5$d@Ug&~MPR|bxX3~2gKbRialgXx^G5WJaNLH6S;?^l^FSp{7LSUdzTi*Yx%wl zB#d8@4)6YOJ2tqbke~47tyT%a{AdVNBn-A&CjD)mq zRepH=1cORELT)M=i74b9a)d+>lWKU|dT_?2bVj(puYXTE)1U6oct_5B zy(vV{o9~Ep=3P?k56OCJcs=zx!&q?o_OX6-{dYS2J3GJsVx}pEdaP_956B9+i+X%Z z9&6Kj)JUt=rLNhcd3WF6+8U2uQOK)gEP6BgrPq2f9*SP6ZNE4h9cb5fsuN&lZAU=f zgtN@zaiS&F1G%DO>*W$Kr}L5Lj@q5i`c&+kk%7z*K-x(%xVvd`+q%5|SG>4?$6ML8 zz4qSK*}m9@P>&LsXw5YLwy~!v7wWmT&>osw9PEfF3rD*bHzt+0&V-Xwx=qdcl5IQG zV7Ve?Wje+{P?sC@2sl-T+Q4{0!vCj z<@)u4i70_iSOWV8z3Yp-U^_sI{@@`(AupP`Y~M>8q^H20yly&xq_9egR)8ZT7f~~0 zcNmN@-G^UBS}%iJSQFwvsR}cW&Z{&FR#rzdalCy*hMol`MGLf=1yKQp1iTNIGo8qo zj@FlotRRg~;pK{pLVL00F5QIeDk*I1cTFLHeEmkz1ZrCqygE{z$un-aQt3edgHQqC z;1`nMLnypA@y2PnioSVJm~qkrR=UhMtL1+Ew52tIqZ?`&QzAdKjMds=&$Z0G-5SRL zxZUTE?^G5eK>#ZC8^Vy3Pz#--pEfNcOF-Y(B*G&I9nYkwfyz?dG{MH#7#}}3GVwA* zej2iX>Z8ml%3VQyabGY^*T!)OQRaCoy>tGTQ)n%RVp%ehDH;deWN5x4`2}|7Wn9q4 zqZlq5)u3SeMO|*=l9iqXmdSWb3J1jpM2PC)0h&ihVB+nmHKSz)DPqa`V5puoL8@D- zU+1{BB|FI|(8CW2Wtb2NwoG62EtAm%!G|9i^XYSmiX{x(;A>31TZ8R$KrwK*@NsA? zfs&vK$ki9Ak^HPByEF(8a6qN0qdRteDOU_~KZW=?4hg4+a7W9JAgUmQgBeIYgfQWo zVTpuy8!?RPCC3s$(-8rzz!^FxYop4+(cmSNEe9>aYzlhNw@`wWne^++jGZ!+hKwyf z)!C{*_u|&1a=tB`lzDF)HzpGWPY9I1fKkAa!)I)Jl7Z=ca%YRT|M$*0N&A?vs%Vuj zL1O_l4_9drpyMuz2mTSpIeO3OD?;aX-V$Z}!9qo_T`wI$*U<+Y6F&jEn@|1EPLul~ z7{D`_8yOc&U9eg>eaR~0q5!E5I)`bj%0a+ZXhl%<;ex{Q5*-E&a~u$p*Gd-0JC4Bp z;eD{Y+nXP1+OazPGML7y7IK&Y(?mzDl8YmS#a8!V>_2v*eBR8^7GITCH^cN-q`|d+0JJF*v;Y7A delta 391 zcmZo@U}<>3JVBZ@j)8%Jf1-jtW8B7sCHx#r{K^dcGx?P_3o5koDK+vla)h$7Dsnb9 zvVvLSoQ<-ni6#{=4)f$Q@fvQcc^GHgHrjDHXB1@?S1V=am82G>7MBz&Sw$;3CTEls zC+23SW|k=FD1~Ph7pLYGCubz4l_8STPyT2x3{-xXf&VW5$IXHT7y0!$8JWcy z155KuQbmC}I5}MsGjn*EnB^HkjLNXg)N)Z?{v!-b{9X+F?fhOqKict6_KM%NnWf+l z|E2;K0iby=+4w*6zXY0hj-Q{8S((#2u_&=5H8C$G(`fR`erXO-zAFs;5&RyL1tv&r z)|ybpH*td1<}33I7=e0IK|z-aG&Yi-)tDtzk#X`JeU;69>&p!ISXq)8c!PNiIiIqt Qvm|e93}o4y{A4aS06))k0RR91 diff --git a/tools/antigravity/src/app/api/quote/daily/route.ts b/tools/antigravity/src/app/api/quote/daily/route.ts index 9924c20..c67048e 100644 --- a/tools/antigravity/src/app/api/quote/daily/route.ts +++ b/tools/antigravity/src/app/api/quote/daily/route.ts @@ -1,10 +1,11 @@ import { NextRequest, NextResponse } from "next/server"; import { getDailyQuote } from "@/lib/ai-service"; import { prisma } from "@/lib/prisma"; +import { cookies } from "next/headers"; export async function GET(req: NextRequest) { console.log("[API] GET /api/quote/daily called"); - const userId = req.headers.get("x-user-id"); + let userId = req.headers.get("x-user-id"); if (!userId) { return NextResponse.json({ error: "User ID required" }, { status: 400 }); @@ -14,6 +15,8 @@ export async function GET(req: NextRequest) { // Ensure user exists let user = await prisma.user.findUnique({ where: { id: userId } }); if (!user) { + // Check if there is a name-based user match for this ID? No, ID is primary. + // Just create visitor. user = await prisma.user.create({ data: { id: userId, @@ -31,45 +34,91 @@ export async function GET(req: NextRequest) { } export async function POST(req: NextRequest) { - const userId = req.headers.get("x-user-id"); - if (!userId) return NextResponse.json({ error: "No User" }, { status: 401 }); - try { const body = await req.json(); - // Upsert user preference - await prisma.user.upsert({ - where: { id: userId }, - update: { - preferences: JSON.stringify(body), - onboardingCompleted: true, - name: body.name - }, - create: { - id: userId, - preferences: JSON.stringify(body), - onboardingCompleted: true, - name: body.name + const { name, interests } = body; + + if (!name) return NextResponse.json({ error: "Name required" }, { status: 400 }); + + console.log(`[API] Onboarding/Login for name: ${name}`); + + // 1. Check if user exists by Name + let user = await prisma.user.findUnique({ where: { name } }); + let userId = user?.id; + + const cookieStore = await cookies(); + + if (user) { + console.log(`[API] Found existing user ${name} (${user.id}). Switching session.`); + // Update prefs + await prisma.user.update({ + where: { id: user.id }, + data: { + preferences: JSON.stringify(body), + onboardingCompleted: true + } + }); + } else { + // 2. No user by that name. + // Should we rename the current session user OR create a brand new one? + // If the current session user is "Visitor", we can claim it. + // If the current session user is ALREADY someone else (e.g. "Bob"), we should create NEW. + + const currentSessionId = req.headers.get("x-user-id"); + const currentSessionUser = currentSessionId ? await prisma.user.findUnique({ where: { id: currentSessionId } }) : null; + + if (currentSessionUser && (currentSessionUser.name === "Visitor" || !currentSessionUser.onboardingCompleted)) { + // Claim the session + console.log(`[API] claiming session ${currentSessionId} for new user ${name}`); + userId = currentSessionId!; + await prisma.user.update({ + where: { id: userId }, + data: { + name, + preferences: JSON.stringify(body), + onboardingCompleted: true + } + }); + } else { + // Create brand new + console.log(`[API] Creating NEW user for ${name}`); + const newUser = await prisma.user.create({ + data: { + name, + preferences: JSON.stringify(body), + onboardingCompleted: true + } + }); + userId = newUser.id; } + } + + // 3. Set Cookie to the correct UserID + // We use the response to set the cookie? No, we can use `cookies().set` in Server Actions or Route Handlers (NextJS 14+). + // Check NextJS 16 docs (we are on 16). `cookies().set` works. + cookieStore.set('ark_user_id', userId!, { + path: '/', + maxAge: 60 * 60 * 24 * 365, + sameSite: 'strict' }); - // ERASE history for today to force new quote generation with new preferences + // ERASE history for today to force new quote generation const today = new Date().toISOString().split("T")[0]; try { await prisma.dailyView.delete({ where: { userId_date: { - userId, + userId: userId!, date: today } } }); console.log(`[API] Cleared DailyView for user ${userId} to force regeneration.`); - } catch (e) { - // Ignore if not found - } + } catch (e) { } - return NextResponse.json({ success: true }); + return NextResponse.json({ success: true, userId }); } catch (e) { + console.error(e); return NextResponse.json({ error: "Update failed" }, { status: 500 }); } } From 6b076ec653617aa1e9ab8abd433ae5886c192614 Mon Sep 17 00:00:00 2001 From: Repository Admin Date: Mon, 22 Dec 2025 00:33:31 +0100 Subject: [PATCH 20/41] feat(admin): implement user-specific AI configuration backend --- tools/antigravity/prisma/dev.db | Bin 65536 -> 65536 bytes tools/antigravity/prisma/schema.prisma | 1 + .../src/app/admin/dashboard/page.tsx | 47 +++++ tools/antigravity/src/app/admin/page.tsx | 48 +++++ .../src/app/admin/user/[id]/page.tsx | 171 ++++++++++++++++++ .../src/app/api/admin/login/route.ts | 11 ++ .../src/app/api/admin/user/[id]/route.ts | 24 +++ tools/antigravity/src/lib/ai-service.ts | 26 ++- 8 files changed, 324 insertions(+), 4 deletions(-) create mode 100644 tools/antigravity/src/app/admin/dashboard/page.tsx create mode 100644 tools/antigravity/src/app/admin/page.tsx create mode 100644 tools/antigravity/src/app/admin/user/[id]/page.tsx create mode 100644 tools/antigravity/src/app/api/admin/login/route.ts create mode 100644 tools/antigravity/src/app/api/admin/user/[id]/route.ts diff --git a/tools/antigravity/prisma/dev.db b/tools/antigravity/prisma/dev.db index 1be88c8b2b26d828a2902d329c85e7ee8625590e..51ee3072c7a51b74ea4172670ee5ebac43a12ca3 100644 GIT binary patch delta 99 zcmZo@U}ngN6SGqul1LeBK`c1#=hr delta 68 zcmZo@U}>T2Ll%y4+G!Ejd}Sj8z<;9ZsuWI Q%E8hk&B(raE1&mA0LRr2od5s; diff --git a/tools/antigravity/prisma/schema.prisma b/tools/antigravity/prisma/schema.prisma index 61ad4b4..a8a4217 100644 --- a/tools/antigravity/prisma/schema.prisma +++ b/tools/antigravity/prisma/schema.prisma @@ -15,6 +15,7 @@ model User { onboardingCompleted Boolean @default(false) preferences String? // JSON string + aiConfig String? // JSON string for Admin overrides { temp, weights, prompt } views DailyView[] ratings Rating[] diff --git a/tools/antigravity/src/app/admin/dashboard/page.tsx b/tools/antigravity/src/app/admin/dashboard/page.tsx new file mode 100644 index 0000000..7f21a94 --- /dev/null +++ b/tools/antigravity/src/app/admin/dashboard/page.tsx @@ -0,0 +1,47 @@ +import { prisma } from "@/lib/prisma"; +import Link from "next/link"; +import { cookies } from "next/headers"; +import { redirect } from "next/navigation"; +import { User } from "lucide-react"; + +export default async function AdminDashboard() { + const cookieStore = await cookies(); + if (!cookieStore.get("admin_session")) { + redirect("/admin"); + } + + const users = await prisma.user.findMany({ + orderBy: { updatedAt: 'desc' } + }); + + return ( +
+

Admin Dashboard

+ +
+ {users.map(user => ( + +
+
+
+ +
+
+
{user.name}
+
{user.id}
+
+
+
+ {user.aiConfig ? ( + Custom AI + ) : ( + Default + )} +
+
+ + ))} +
+
+ ); +} diff --git a/tools/antigravity/src/app/admin/page.tsx b/tools/antigravity/src/app/admin/page.tsx new file mode 100644 index 0000000..86af328 --- /dev/null +++ b/tools/antigravity/src/app/admin/page.tsx @@ -0,0 +1,48 @@ +"use client"; +import { useState } from "react"; +import { useRouter } from "next/navigation"; +import styles from "../page.module.css"; // Reuse home styles for consistency + +export default function AdminLogin() { + const [password, setPassword] = useState(""); + const router = useRouter(); + const [error, setError] = useState(""); + + const handleLogin = async () => { + const res = await fetch("/api/admin/login", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ password }) + }); + if (res.ok) { + router.push("/admin/dashboard"); + } else { + setError("Falsches Passwort."); + } + }; + + return ( +
+
+

Admin Access

+
+
+ setPassword(e.target.value)} + placeholder="Passwort" + className="p-3 rounded bg-gray-800 text-white border border-gray-700" + onKeyDown={e => e.key === "Enter" && handleLogin()} + /> + {error &&
{error}
} + +
+
+ ); +} diff --git a/tools/antigravity/src/app/admin/user/[id]/page.tsx b/tools/antigravity/src/app/admin/user/[id]/page.tsx new file mode 100644 index 0000000..19cf684 --- /dev/null +++ b/tools/antigravity/src/app/admin/user/[id]/page.tsx @@ -0,0 +1,171 @@ +"use client"; +import { useState, useEffect } from "react"; +import { useRouter } from "next/navigation"; +import { Save, Lock, Unlock, ArrowLeft } from "lucide-react"; + +interface AiConfig { + temperature: number; + modeWeights: { + quote: number; + question: number; + pulse: number; + }; + customPrompt: string; +} + +const DEFAULT_CONFIG: AiConfig = { + temperature: 1.15, + modeWeights: { quote: 60, question: 30, pulse: 10 }, + customPrompt: "" +}; + +export default function UserAdminPage({ params }: { params: Promise<{ id: string }> }) { + const [config, setConfig] = useState(DEFAULT_CONFIG); + const [loading, setLoading] = useState(true); + const [isSafe, setIsSafe] = useState(true); + const [saving, setSaving] = useState(false); + const router = useRouter(); + const [userId, setUserId] = useState(""); + + useEffect(() => { + params.then(p => { + setUserId(p.id); + fetch(`/api/admin/user/${p.id}`) + .then(res => res.json()) + .then(data => { + if (data.aiConfig) { + try { + const parsed = JSON.parse(data.aiConfig); + setConfig({ ...DEFAULT_CONFIG, ...parsed }); + } catch (e) { console.error(e); } + } + setLoading(false); + }); + }); + }, [params]); + + const handleSave = async () => { + if (isSafe) return; + setSaving(true); + try { + await fetch(`/api/admin/user/${userId}`, { + method: "PUT", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ aiConfig: JSON.stringify(config) }) + }); + alert("Gespeichert!"); + setIsSafe(true); + } catch (e) { + alert("Fehler"); + } + setSaving(false); + }; + + if (loading) return
Lade...
; + + const totalWeight = (config.modeWeights.quote || 0) + (config.modeWeights.question || 0) + (config.modeWeights.pulse || 0); + + return ( +
+ + +

AI Konfiguration

+

{userId}

+ +
+ {/* Temperature */} +
+

Temperatur (Kreativität)

+
+ setConfig({ ...config, temperature: parseFloat(e.target.value) })} + className="w-full accent-green-500" + /> + {config.temperature} +
+

1.0 = Balance, 1.5+ = Sehr Kreativ/Chaos, 0.5 = Deterministisch

+
+ + {/* Weights */} +
+

Modus Gewichtung

+
+
+ + setConfig({ ...config, modeWeights: { ...config.modeWeights, quote: parseInt(e.target.value) } })} + /> +
+
+ + setConfig({ ...config, modeWeights: { ...config.modeWeights, question: parseInt(e.target.value) } })} + /> +
+
+ + setConfig({ ...config, modeWeights: { ...config.modeWeights, pulse: parseInt(e.target.value) } })} + /> +
+
+
+ Total: {totalWeight}% (Sollte 100 sein) +
+
+ + {/* Prompt */} +
+

Custom Prompt Instructions

+