diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000..2074a2f
Binary files /dev/null and b/.DS_Store differ
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..de9bb74
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,20 @@
+node_modules
+.next
+.git
+.env
+.env.*
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# Mac/OS files
+.DS_Store
+
+# IDE files
+.vscode/
+.idea/
+
+# Ignore test coverage
+coverage/
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3c3629e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+node_modules
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..e57c3f7
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,36 @@
+# --- STAGE 1: BUILDER ---
+FROM node:20-alpine AS builder
+WORKDIR /app
+
+# Install dependencies
+COPY package*.json ./
+RUN npm install
+
+# Copy source code
+COPY . .
+
+# Build Next.js app
+# NEXT_PUBLIC_API_URL should be set during build if used in static generation
+# For production, we usually point to the domain name
+ENV NEXT_PUBLIC_API_URL=https://api.iddaai.com/api
+RUN npm run build
+
+# --- STAGE 2: RUNNER ---
+FROM node:20-alpine AS runner
+WORKDIR /app
+
+ENV NODE_ENV=production
+
+# Copy only necessary files
+COPY --from=builder /app/package*.json ./
+COPY --from=builder /app/.next ./.next
+COPY --from=builder /app/public ./public
+COPY --from=builder /app/node_modules ./node_modules
+COPY --from=builder /app/next.config.ts ./
+# Copy messages for internationalization
+COPY --from=builder /app/messages ./messages
+
+EXPOSE 3000
+
+# Start Next.js
+CMD ["npm", "start"]
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..5f80552
--- /dev/null
+++ b/README.md
@@ -0,0 +1,341 @@
+# 🚀 Enterprise Next.js Boilerplate (Antigravity Edition)
+
+[](https://nextjs.org/)
+[](https://react.dev/)
+[](https://chakra-ui.com/)
+[](https://www.typescriptlang.org/)
+[](https://next-intl-docs.vercel.app/)
+
+> **FOR AI AGENTS & DEVELOPERS:** This documentation is structured to provide deep context, architectural decisions, and operational details to ensure seamless handover to any AI coding assistant (like Antigravity) or human developer.
+
+---
+
+## 🧠 Project Context & Architecture (Read Me First)
+
+This is an **opinionated, production-ready** frontend boilerplate built with Next.js 16 App Router. It is designed to work seamlessly with the companion **typescript-boilerplate-be** NestJS backend.
+
+### 🏗️ Core Philosophy
+
+- **Type Safety First:** Strict TypeScript configuration. DTOs and typed API responses connect frontend to backend.
+- **App Router Native:** Built entirely on Next.js App Router with Server Components and React Server Actions support.
+- **i18n Native:** Localization is baked into routing, API calls, and UI components via `next-intl`.
+- **Theme-First Design:** Chakra UI v3 with custom theme system for consistent, accessible UI.
+- **Auth by Default:** NextAuth.js integration with JWT token management and automatic session handling.
+
+### 📐 Architectural Decision Records (ADR)
+
+_To understand WHY things are the way they are:_
+
+1. **Locale-Based Routing:**
+ - **Mechanism:** All routes are prefixed with locale (e.g., `/tr/dashboard`, `/en/login`).
+ - **Implementation:** `next-intl` plugin with `[locale]` dynamic segment in `app/` directory.
+ - **Config:** `localePrefix: 'always'` ensures consistent URL structure.
+
+2. **API Client with Auto-Auth & Locale:**
+ - **Location:** `src/lib/api/create-api-client.ts`
+ - **Feature:** Automatically injects JWT `Authorization` header from NextAuth session.
+ - **Feature:** Automatically sets `Accept-Language` header based on current locale (cookie or URL path).
+ - **Auto-Logout:** 401 responses trigger automatic signOut and redirect.
+
+3. **Backend Proxy (CORS Solution):**
+ - **Problem:** Local development CORS issues when frontend (port 3001) calls backend (port 3000).
+ - **Solution:** Next.js `rewrites` in `next.config.ts` proxies `/api/backend/*` → `http://localhost:3000/api/*`.
+ - **Usage:** API clients use `/api/backend/...` paths in development.
+
+4. **Provider Composition:**
+ - **Location:** `src/components/ui/provider.tsx`
+ - **Stack:** `SessionProvider` (NextAuth) → `ChakraProvider` (UI) → `ColorModeProvider` (Dark/Light) → `Toaster` (Notifications)
+ - **Why:** Single import in layout provides all necessary contexts.
+
+---
+
+## 🚀 Quick Start for AI & Humans
+
+### 1. Prerequisites
+
+- **Node.js:** v20.19+ (LTS)
+- **Package Manager:** `npm` (Lockfile: `package-lock.json`)
+- **Backend:** Companion NestJS backend running on port 3000 (see `typescript-boilerplate-be`)
+
+### 2. Environment Setup
+
+```bash
+cp .env.example .env.local
+# Edit .env.local with your configuration
+```
+
+**Required Environment Variables:**
+
+| Variable | Description | Example |
+| --------------------------- | --------------------------------------------------------------- | --------------------------- |
+| `NEXTAUTH_URL` | NextAuth callback URL | `http://localhost:3001` |
+| `NEXTAUTH_SECRET` | Authentication secret (generate with `openssl rand -base64 32`) | `abc123...` |
+| `NEXT_PUBLIC_API_URL` | Backend API base URL | `http://localhost:3001/api` |
+| `NEXT_PUBLIC_AUTH_REQUIRED` | Require login for all pages | `true` or `false` |
+
+### 3. Installation & Running
+
+```bash
+# Install dependencies
+npm ci
+
+# Development Mode (HTTPS enabled, port 3001)
+npm run dev
+
+# Production Build
+npm run build
+npm run start
+```
+
+> **Note:** Dev server runs on port 3001 with experimental HTTPS for secure cookie handling.
+
+---
+
+## 🌍 Internationalization (i18n) Guide
+
+Deep integration with `next-intl` provides locale-aware routing and translations.
+
+### Configuration
+
+- **Supported Locales:** `['en', 'tr']`
+- **Default Locale:** `tr`
+- **Locale Detection:** Cookie (`NEXT_LOCALE`) → URL path → Default
+
+### File Structure
+
+```
+messages/
+├── en.json # English translations
+└── tr.json # Turkish translations
+
+src/i18n/
+├── routing.ts # Locale routing configuration
+├── navigation.ts # Typed navigation helpers (Link, useRouter)
+└── request.ts # Server-side i18n setup
+```
+
+### Usage in Components
+
+```tsx
+// Client Component
+"use client";
+import { useTranslations } from "next-intl";
+
+export function MyComponent() {
+ const t = useTranslations("common");
+ return
{t("welcome")} ;
+}
+
+// Navigation with Locale
+import { Link } from "@/i18n/navigation";
+
+ Dashboard; // Auto-prefixes with current locale
+```
+
+### Adding a New Locale
+
+1. Add locale code to `src/i18n/routing.ts`:
+ ```ts
+ export const locales = ["en", "tr", "de"]; // Add 'de'
+ ```
+2. Create `messages/de.json` with translations.
+3. Update `getLocale()` in `create-api-client.ts` if needed.
+
+---
+
+## 🔐 Authentication System
+
+Built on NextAuth.js with JWT strategy for seamless backend integration.
+
+### How It Works
+
+1. **Login:** User submits credentials → `/api/auth/[...nextauth]` → Backend validates → JWT returned.
+2. **Session:** JWT stored in encrypted cookie, accessible via `useSession()` hook.
+3. **API Calls:** `createApiClient()` automatically adds `Authorization: Bearer {token}` header.
+4. **Auto-Refresh:** Token refreshed before expiry (managed by NextAuth).
+
+### Protected Routes
+
+```tsx
+// Use middleware.ts or check session in layout
+import { getServerSession } from "next-auth";
+
+export default async function ProtectedLayout({ children }) {
+ const session = await getServerSession();
+ if (!session) redirect("/login");
+ return <>{children}>;
+}
+```
+
+### Auth Mode Toggle
+
+Set `NEXT_PUBLIC_AUTH_REQUIRED=true` for mandatory authentication across all pages.
+
+---
+
+## 🎨 UI System (Chakra UI v3)
+
+### Theme Configuration
+
+- **Location:** `src/theme/theme.ts`
+- **Font:** Bricolage Grotesque (Google Fonts, variable font)
+- **Color Mode:** Light/Dark with system preference detection
+
+### Component Organization
+
+```
+src/components/
+├── ui/ # Chakra UI wrapper components
+│ ├── provider.tsx # Root provider (Session + Chakra + Theme)
+│ ├── color-mode.tsx # Dark/Light mode toggle
+│ ├── feedback/ # Toaster, alerts, etc.
+│ └── ...
+├── layout/ # Page layout components (Header, Sidebar, Footer)
+├── auth/ # Authentication forms and guards
+└── site/ # Site-specific feature components
+```
+
+### Toast Notifications
+
+```tsx
+import { toaster } from "@/components/ui/feedback/toaster";
+
+// Success toast
+toaster.success({
+ title: "Saved!",
+ description: "Changes saved successfully.",
+});
+
+// Error toast
+toaster.error({ title: "Error", description: "Something went wrong." });
+```
+
+---
+
+## 📡 API Integration
+
+### Creating API Clients
+
+```tsx
+// src/lib/api/auth/login/queries.ts
+import { createApiClient } from "../create-api-client";
+
+const api = createApiClient("/api/backend/auth");
+
+export const loginUser = async (data: LoginDto) => {
+ const response = await api.post("/login", data);
+ return response.data;
+};
+```
+
+### React Query Integration
+
+```tsx
+import { useQuery, useMutation } from "@tanstack/react-query";
+
+// Query hook
+export const useUsers = () =>
+ useQuery({
+ queryKey: ["users"],
+ queryFn: () => apiClient.get("/users"),
+ });
+
+// Mutation hook
+export const useCreateUser = () =>
+ useMutation({
+ mutationFn: (data: CreateUserDto) => apiClient.post("/users", data),
+ });
+```
+
+---
+
+## 📂 System Map (Directory Structure)
+
+```
+src/
+├── app/ # Next.js App Router
+│ ├── [locale]/ # Locale-prefixed routes
+│ │ ├── (auth)/ # Auth pages (login, register)
+│ │ ├── (site)/ # Main site pages
+│ │ ├── (error)/ # Error pages
+│ │ ├── layout.tsx # Root layout with providers
+│ │ └── page.tsx # Home page
+│ └── api/ # Next.js API routes
+│ └── auth/ # NextAuth endpoints
+├── components/ # React components
+│ ├── ui/ # Chakra UI wrappers & base components
+│ ├── layout/ # Layout components (Header, Sidebar)
+│ ├── auth/ # Auth-related components
+│ └── site/ # Feature-specific components
+├── config/ # App configuration
+├── hooks/ # Custom React hooks
+├── i18n/ # Internationalization setup
+├── lib/ # Utilities & services
+│ ├── api/ # API clients (organized by module)
+│ │ ├── auth/ # Auth API (login, register)
+│ │ ├── admin/ # Admin API (roles, users)
+│ │ └── create-api-client.ts # Axios factory with interceptors
+│ ├── services/ # Business logic services
+│ └── utils/ # Helper functions
+├── theme/ # Chakra UI theme configuration
+├── types/ # TypeScript type definitions
+└── proxy.ts # API proxy utilities
+
+messages/ # Translation JSON files
+public/ # Static assets
+```
+
+---
+
+## 🧪 Testing & Development
+
+### Available Scripts
+
+```bash
+npm run dev # Start dev server (HTTPS, port 3001)
+npm run build # Production build
+npm run start # Start production server
+npm run lint # Run ESLint
+```
+
+### Development Tools
+
+- **React Compiler:** Enabled for automatic optimization.
+- **Top Loader:** Visual loading indicator for route transitions.
+- **ESLint + Prettier:** Consistent code formatting.
+
+---
+
+## 🛠️ Troubleshooting (Known Issues)
+
+**1. HTTPS Certificate Warnings in Development**
+
+- **Context:** Dev server uses `--experimental-https` for secure cookies.
+- **Fix:** Accept the self-signed certificate warning in your browser.
+
+**2. Backend Connection Refused**
+
+- **Fix:** Ensure NestJS backend is running on port 3000.
+- **Check:** Run `curl http://localhost:3000/api/health` to verify.
+
+**3. Session Not Persisting**
+
+- **Fix:** Ensure `NEXTAUTH_SECRET` is set and consistent between restarts.
+- **Fix:** Check that cookies are not blocked by browser settings.
+
+**4. Locale Not Detected**
+
+- **Context:** Default falls back to `tr` if cookie/URL detection fails.
+- **Fix:** Clear `NEXT_LOCALE` cookie and refresh.
+
+---
+
+## 🔗 Related Projects
+
+- **Backend:** [typescript-boilerplate-be](../typescript-boilerplate-be) - NestJS backend with Prisma, JWT auth, and i18n.
+
+---
+
+## 📃 License
+
+This project is proprietary and confidential.
diff --git a/certificates/localhost-key.pem b/certificates/localhost-key.pem
new file mode 100644
index 0000000..6a82260
--- /dev/null
+++ b/certificates/localhost-key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC38ryU+6/sNDQR
+OL1pWCKrIms5cTMoSS8UOKhVaHB2n5J4f8pIuAX/sNBycI4/9oFztGGp3UIs+HD4
+dIsOmFZmHJCpAVhivyPD0MeXYq1t6V5VSNMOnH0y7huvWYmFuAWZ9/41QKSkM/an
+oYQQvcvLkuS0vbrYCr0jmndbfBIF4zYQEPyBR/fcS5W4lFCPUojhXlfSOvWN/tuY
+MU5RxOzHbC4DuKnj1Mj/WNBVzpN4BNkBqUakrjhQw2DYhFFlCTxez9+gFPfZXtrm
+EfZjAvOn+BMDUJhNzMZvBoU5rKAEGYmxhT2NHj0rGoEIUPBuiLguvngWl3OXdAQE
+brdyG507AgMBAAECggEAAJnET+A6hNTuzpeW1r847cIhA4EBH8KNas18jzrWEy0W
+N1qDeJVRP7J+G8GOVVsitRQDtaBJVQhCpi0LPzL0JUU2m7araTcikMMfw7jIxDEc
+475nIgcUyZPJd1sdfdhJ/GS46ceaQgcBaS631a4o+jMyl/x+nbH7SCB6/0t6a5Z+
+7cMe/NoDbypGyEo8sEZw6idHBdogZO1E+aLOBfGTkc42jzfV4UCbcuWtpGa3QHDw
+scXEIwHRza5XO8kdn064tHb6JWyjkXh3abeyZU2uoOGFyEZxR0FjxxC579pA2LoB
+qmmXeFo8uVFIs4L0fXSj3ohW1i+I10qSFvFY7SgSIQKBgQDe7RsY5QbuwQxfgeIa
+R8VNHLC5ux02q3bEqCr8UoPZaop4Ckg7gIiHumU6/YK6Qke0w0XEkAy2Fhv2Vby5
+RehgmSZ5+LSXpsW3uutgTMOw/4HaXLlW51icPK0rsdBth6AaOI3uX1j3XzSpgXyI
+6yYQtJnmvDGtNsfkC2+t6uCpWQKBgQDTPTf7kXyBtxti/nLV9z8/15atfJ6lsxVd
+oVWuaQEPUS3VwfBQYFKX/jhSQlXVbu4GrklMhSG8P0Q6glyjk/NiuhRUbQRFv7cu
+6TmXSGWfSvkEQdX+xVsA+rfaCNQu6+cFs0ZnK7pqN41LzwRAvdiyCXHiEi2EyqWw
+GypCWJRUswKBgQCtuDn4kWlwnxHET5PiBPH04Jm7ctwWIVJBeAdfb/H9eLAFUYXu
+kIBUvOVsLeg0u7fjXpS808CEGQCbWz7hZl/q/w3j2PLqhvTm84u/FLMe+E252642
+0bvUrNgKB9wzrpAOPuojyzuqMg/408Y3cH/OXt7b1uYjZGArDtptvm5qqQKBgQC1
+8lgDDshAbnhfZy2AkMtg8RAu9FUuAjeYAzvq0zT/fXvOT5LvmFfr5SOb7tlB0p+h
+D4PBLjblj1T0VI74spoD4qVaJuB0N3LQLEDXxpsJfqlIenCZVmJRUKMFYW9pzvWZ
+WlZ8zRRvItRIhNJz9VHt3+bAw8mDRI08R9m5ddSlswKBgGETkel47kg3l1oR++9s
+RExiQgTPM9mnFXMJhXpTKqTFZ7ETrNCQMui/ghbnBSpGmYRzrQEsftEMIp9rU7Z4
+q6m0F28CtJd3QUazE4t/Y62gUrTpQYGpW9fNqjtY8tEyzjxae5cY3zssB49yYfpQ
+h2KRQnPO3vzLdJMq+PRp2//o
+-----END PRIVATE KEY-----
diff --git a/certificates/localhost.pem b/certificates/localhost.pem
new file mode 100644
index 0000000..fcf6188
--- /dev/null
+++ b/certificates/localhost.pem
@@ -0,0 +1,26 @@
+-----BEGIN CERTIFICATE-----
+MIIEXTCCAsWgAwIBAgIRAJwh1nDeNCaehj5TSbwpPpEwDQYJKoZIhvcNAQELBQAw
+gYkxHjAcBgNVBAoTFW1rY2VydCBkZXZlbG9wbWVudCBDQTEvMC0GA1UECwwmcGl0
+b25AUGl0b25zLU1hY0Jvb2stQWlyLmxvY2FsIChQaXRvbikxNjA0BgNVBAMMLW1r
+Y2VydCBwaXRvbkBQaXRvbnMtTWFjQm9vay1BaXIubG9jYWwgKFBpdG9uKTAeFw0y
+NjA0MTQxMzQ1MjZaFw0yODA3MTQxMzQ1MjZaMFIxJzAlBgNVBAoTHm1rY2VydCBk
+ZXZlbG9wbWVudCBjZXJ0aWZpY2F0ZTEnMCUGA1UECwwecGl0b25AUGl0b25zLU1h
+Y0Jvb2stQWlyLmxvY2FsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
+t/K8lPuv7DQ0ETi9aVgiqyJrOXEzKEkvFDioVWhwdp+SeH/KSLgF/7DQcnCOP/aB
+c7Rhqd1CLPhw+HSLDphWZhyQqQFYYr8jw9DHl2KtbeleVUjTDpx9Mu4br1mJhbgF
+mff+NUCkpDP2p6GEEL3Ly5LktL262Aq9I5p3W3wSBeM2EBD8gUf33EuVuJRQj1KI
+4V5X0jr1jf7bmDFOUcTsx2wuA7ip49TI/1jQVc6TeATZAalGpK44UMNg2IRRZQk8
+Xs/foBT32V7a5hH2YwLzp/gTA1CYTczGbwaFOaygBBmJsYU9jR49KxqBCFDwboi4
+Lr54Fpdzl3QEBG63chudOwIDAQABo3YwdDAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0l
+BAwwCgYIKwYBBQUHAwEwHwYDVR0jBBgwFoAU+PxiJ531CXgmujenTGLWFtdGwW8w
+LAYDVR0RBCUwI4IJbG9jYWxob3N0hwR/AAABhxAAAAAAAAAAAAAAAAAAAAABMA0G
+CSqGSIb3DQEBCwUAA4IBgQAMw+91DrGNCdqLngTCvG8fPU6ikAOBNvuB7Q0tf/q4
+adfgTse/pU7e9lkgChdYSYifh3FStmkaHmYNZg1ljgpMJICUxT2zL7rmOE9GlUqv
+2/umlzZcHE3yC3fLqS8Ik7D5qhAES0HM3WbJLrs4OzRY77iEkDYptgzmZJqMA72j
+CEyfuqRaAMR/QR0D4Lrt8xZlrMA19t8mkdc0GixzlKD0naIISbVyNmXz4Dc2uqv2
+asGWByPm/m4UmocO9rBX/WlylqC7hLffKRiO1sXdIYWjc2GyGCWt5MrVBanXyXFz
+SElBFF5XJbVY5gtw+9sGWXyDOiLaTVOd55Td5Rf1Lst6QKWMMk3vdpUAIXMciAPh
+UiAipbDFwl5Vxjri/nZoCuQWlEOQ6rthKDZJz4qAu4GN1WFeB8pgIPHKkGA9v6Nn
+1ZvnewsNqq6jYy9WUE/Y4NgZPtdoH8dHQiKav7KXu2yVpbR0iaDJP8oRUNhiE8fe
+x41Iim7YWjwoYtc97L194WQ=
+-----END CERTIFICATE-----
diff --git a/eslint.config.mjs b/eslint.config.mjs
new file mode 100644
index 0000000..a5a130a
--- /dev/null
+++ b/eslint.config.mjs
@@ -0,0 +1,25 @@
+import { dirname } from 'path';
+import { fileURLToPath } from 'url';
+import { FlatCompat } from '@eslint/eslintrc';
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = dirname(__filename);
+
+const compat = new FlatCompat({
+ baseDirectory: __dirname,
+});
+
+const eslintConfig = [
+ ...compat.extends('next/core-web-vitals', 'next/typescript', 'prettier'),
+ {
+ ignores: ['node_modules/**', '.next/**', 'out/**', 'build/**', 'next-env.d.ts'],
+ },
+ {
+ rules: {
+ '@typescript-eslint/no-empty-object-type': 'off',
+ '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
+ },
+ },
+];
+
+export default eslintConfig;
diff --git a/lint_errors.txt b/lint_errors.txt
new file mode 100644
index 0000000..6b74b6d
--- /dev/null
+++ b/lint_errors.txt
@@ -0,0 +1,110 @@
+
+> temp_project@0.1.0 lint
+> eslint
+
+
+/Users/piton/Documents/GitHub/Suggest-Bet-FE/src/actions/auth-actions.ts
+ 42:19 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
+ 85:19 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
+
+/Users/piton/Documents/GitHub/Suggest-Bet-FE/src/app/(auth)/login/page.tsx
+ 15:3 warning 'InputGroup' is defined but never used @typescript-eslint/no-unused-vars
+ 16:3 warning 'Stack' is defined but never used @typescript-eslint/no-unused-vars
+ 33:19 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
+ 83:20 error `'` can be escaped with `'`, `‘`, `'`, `’` react/no-unescaped-entities
+
+/Users/piton/Documents/GitHub/Suggest-Bet-FE/src/app/(auth)/register/page.tsx
+ 37:19 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
+
+/Users/piton/Documents/GitHub/Suggest-Bet-FE/src/app/admin/users/page.tsx
+ 14:3 warning 'IconButton' is defined but never used @typescript-eslint/no-unused-vars
+ 24:10 warning 'FaTrash' is defined but never used @typescript-eslint/no-unused-vars
+ 32:38 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
+ 36:52 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
+ 77:21 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
+ 84:30 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
+
+/Users/piton/Documents/GitHub/Suggest-Bet-FE/src/app/page.tsx
+ 124:53 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
+ 135:39 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
+ 139:50 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
+
+/Users/piton/Documents/GitHub/Suggest-Bet-FE/src/app/predictions/page.tsx
+ 13:40 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
+ 139:62 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
+ 158:39 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
+ 168:45 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
+
+/Users/piton/Documents/GitHub/Suggest-Bet-FE/src/app/profile/page.tsx
+ 24:50 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
+ 38:6 warning React Hook useEffect has a missing dependency: 'fetchProfile'. Either include it or remove the dependency array react-hooks/exhaustive-deps
+ 47:17 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
+ 65:17 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
+
+/Users/piton/Documents/GitHub/Suggest-Bet-FE/src/components/auth/login-form.tsx
+ 6:3 warning 'Box' is defined but never used @typescript-eslint/no-unused-vars
+ 10:3 warning 'Stack' is defined but never used @typescript-eslint/no-unused-vars
+ 54:16 error `'` can be escaped with `'`, `‘`, `'`, `’` react/no-unescaped-entities
+
+/Users/piton/Documents/GitHub/Suggest-Bet-FE/src/components/auth/register-form.tsx
+ 6:3 warning 'Box' is defined but never used @typescript-eslint/no-unused-vars
+ 10:3 warning 'Stack' is defined but never used @typescript-eslint/no-unused-vars
+
+/Users/piton/Documents/GitHub/Suggest-Bet-FE/src/components/matches/league-match-list.tsx
+ 4:10 warning 'Box' is defined but never used @typescript-eslint/no-unused-vars
+ 15:42 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
+ 45:49 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
+
+/Users/piton/Documents/GitHub/Suggest-Bet-FE/src/components/matches/match-card.tsx
+ 5:19 warning 'FaTrophy' is defined but never used @typescript-eslint/no-unused-vars
+ 9:47 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
+ 19:17 error Error: Calling setState synchronously within an effect can trigger cascading renders
+
+Effects are intended to synchronize state between React and external systems such as manually updating the DOM, state management libraries, or other platform APIs. In general, the body of an effect should do one or both of the following:
+* Update external systems with the latest state from React.
+* Subscribe for updates from some external system, calling setState in a callback function when external state changes.
+
+Calling setState synchronously within an effect body causes cascading renders that can hurt performance, and is not recommended. (https://react.dev/learn/you-might-not-need-an-effect).
+
+/Users/piton/Documents/GitHub/Suggest-Bet-FE/src/components/matches/match-card.tsx:19:17
+ 17 | try {
+ 18 | const date = new Date(Number(match.mst_utc));
+> 19 | setFormattedDate(date.toLocaleTimeString("tr-TR", { hour: '2-digit', minute: '2-digit' }));
+ | ^^^^^^^^^^^^^^^^ Avoid calling setState() directly within an effect
+ 20 | } catch (e) {
+ 21 | setFormattedDate("-");
+ 22 | } react-hooks/set-state-in-effect
+ 20:22 warning 'e' is defined but never used @typescript-eslint/no-unused-vars
+ 33:21 warning Using ` ` could result in slower LCP and higher bandwidth. Consider using ` ` from `next/image` or a custom image loader to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element @next/next/no-img-element
+ 51:21 warning Using ` ` could result in slower LCP and higher bandwidth. Consider using ` ` from `next/image` or a custom image loader to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element @next/next/no-img-element
+ 71:21 warning Using ` ` could result in slower LCP and higher bandwidth. Consider using ` ` from `next/image` or a custom image loader to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element @next/next/no-img-element
+
+/Users/piton/Documents/GitHub/Suggest-Bet-FE/src/components/predictions/prediction-modal.tsx
+ 8:3 warning 'Select' is defined but never used @typescript-eslint/no-unused-vars
+ 10:3 warning 'Badge' is defined but never used @typescript-eslint/no-unused-vars
+
+/Users/piton/Documents/GitHub/Suggest-Bet-FE/src/components/predictions/prediction-view.tsx
+ 3:85 warning 'Separator' is defined but never used @typescript-eslint/no-unused-vars
+ 12:36 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
+ 45:21 error Unexpected any. Specify a different type @typescript-eslint/no-explicit-any
+
+/Users/piton/Documents/GitHub/Suggest-Bet-FE/src/contexts/AuthContext.tsx
+ 39:7 error Error: Calling setState synchronously within an effect can trigger cascading renders
+
+Effects are intended to synchronize state between React and external systems such as manually updating the DOM, state management libraries, or other platform APIs. In general, the body of an effect should do one or both of the following:
+* Update external systems with the latest state from React.
+* Subscribe for updates from some external system, calling setState in a callback function when external state changes.
+
+Calling setState synchronously within an effect body causes cascading renders that can hurt performance, and is not recommended. (https://react.dev/learn/you-might-not-need-an-effect).
+
+/Users/piton/Documents/GitHub/Suggest-Bet-FE/src/contexts/AuthContext.tsx:39:7
+ 37 |
+ 38 | if (storedToken && storedUser) {
+> 39 | setToken(storedToken);
+ | ^^^^^^^^ Avoid calling setState() directly within an effect
+ 40 | setUser(JSON.parse(storedUser));
+ 41 | // Optional: Verify token validity with a /me endpoint if available
+ 42 | } react-hooks/set-state-in-effect
+
+✖ 45 problems (27 errors, 18 warnings)
+
diff --git a/messages/en.json b/messages/en.json
new file mode 100644
index 0000000..158ecaf
--- /dev/null
+++ b/messages/en.json
@@ -0,0 +1,490 @@
+{
+ "home": "Home",
+ "about": "About",
+ "solutions": "Solutions",
+ "intelligent-transportation-systems": "Intelligent Transportation Systems",
+ "artificial-intelligence": "Artificial Intelligence",
+ "error": {
+ "not-found": "Oops! The page you're looking for doesn't exist.",
+ "404": "404",
+ "back-to-home": "Go back home",
+ "generic": "An unexpected error occurred.",
+ "network": "Network error. Please check your connection.",
+ "unauthorized": "Your session has expired. Please sign in again.",
+ "forbidden": "You don't have permission to access this resource.",
+ "server": "Server error. Please try again later.",
+ "match-not-found": "Match not found.",
+ "prediction-not-found": "Prediction not available for this match."
+ },
+ "email": "E-Mail",
+ "password": "Password",
+ "auth": {
+ "remember-me": "Remember Me",
+ "dont-have-account": "Don't have an account?",
+ "sign-out": "Sign Out",
+ "sign-up": "Sign Up",
+ "sign-in": "Sign In",
+ "welcome-back": "Welcome Back",
+ "subtitle": "Enter your email and password to sign in",
+ "already-have-an-account": "Already have an account?",
+ "create-an-account-now": "Create an account now",
+ "first-name": "First Name",
+ "last-name": "Last Name",
+ "confirm-password": "Confirm Password",
+ "forgot-password": "Forgot Password?",
+ "or-continue-with": "Or continue with",
+ "logging-in": "Signing in...",
+ "registering": "Creating account..."
+ },
+ "all-right-reserved": "All rights reserved.",
+ "privacy-policy": "Privacy Policy",
+ "terms-of-service": "Terms of Service",
+ "name": "Name",
+ "low": "Low",
+ "medium": "Medium",
+ "high": "High",
+
+ "nav": {
+ "home": "Home",
+ "dashboard": "Dashboard",
+ "matches": "Matches",
+ "predictions": "Predictions",
+ "coupon-builder": "Coupon Builder",
+ "coupon-history": "Coupon History",
+ "profile": "Profile",
+ "admin": "Admin Panel",
+ "teams": "Teams",
+ "leagues": "Leagues",
+ "h2h": "Head to Head",
+ "analysis": "Analysis",
+ "spor-toto": "Spor Toto",
+ "how-it-works": "How It Works",
+ "pricing": "Pricing",
+ "contact": "Contact",
+ "coupons": "Coupons",
+ "tools": "Tools"
+ },
+
+ "landing": {
+ "hero-title": "AI-Powered Betting Predictions",
+ "hero-subtitle": "Make smarter bets with our advanced AI prediction engine. Analyze matches, discover value bets, and build winning coupons.",
+ "get-started": "Get Started",
+ "learn-more": "Learn More",
+ "features-title": "Why Choose Suggest Bet?",
+ "feature-ai": "AI Predictions",
+ "feature-ai-desc": "Powered by V20 ensemble model with 95%+ data quality scoring.",
+ "feature-value": "Value Bets",
+ "feature-value-desc": "Find EV+ betting opportunities with expected value analysis.",
+ "feature-coupon": "Smart Coupons",
+ "feature-coupon-desc": "AI builds optimized coupons with 5 different strategies.",
+ "feature-live": "Live Tracking",
+ "feature-live-desc": "Real-time match tracking with live score updates.",
+ "stats-predictions": "Predictions Made",
+ "stats-accuracy": "Accuracy Rate",
+ "stats-users": "Active Users",
+ "stats-matches": "Matches Analyzed"
+ },
+
+ "dashboard": {
+ "title": "Dashboard",
+ "welcome": "Welcome back",
+ "todays-matches": "Today's Matches",
+ "daily-banko": "Daily Banko",
+ "upcoming-predictions": "Upcoming Predictions",
+ "value-bets": "Value Bets",
+ "your-stats": "Your Stats",
+ "view-all": "View All",
+ "no-matches": "No matches available today.",
+ "no-predictions": "No predictions available."
+ },
+
+ "matches": {
+ "title": "Matches",
+ "filter-sport": "Sport",
+ "football": "Football",
+ "basketball": "Basketball",
+ "all-leagues": "All Leagues",
+ "active-leagues": "Active Leagues",
+ "live": "LIVE",
+ "not-started": "Not Started",
+ "finished": "Finished",
+ "no-matches": "No matches found.",
+ "search-teams": "Search teams...",
+ "view-prediction": "View Prediction",
+ "match-details": "Match Details",
+ "lineups": "Lineups",
+ "statistics": "Statistics",
+ "odds": "Odds",
+ "head-to-head": "Head to Head",
+ "recent-matches": "Recent Matches",
+ "home-team": "Home",
+ "away-team": "Away",
+ "vs": "vs"
+ },
+
+ "predictions": {
+ "title": "Predictions",
+ "upcoming": "Upcoming",
+ "value-bets": "Value Bets",
+ "history": "History",
+ "model-version": "Model Version",
+ "confidence": "Win Probability",
+ "risk": "Risk",
+ "risk-level": "Risk Level",
+ "main-pick": "Main Pick",
+ "supporting-picks": "Supporting Picks",
+ "aggressive-pick": "Aggressive Pick",
+ "score-prediction": "Score Prediction",
+ "market-board": "Market Board",
+ "reasoning": "Reasoning Factors",
+ "data-quality": "Data Quality",
+ "engine-breakdown": "Engine Breakdown",
+ "bet-advice": "Bet Advice",
+ "bet-summary": "Bet Summary",
+ "expected-value": "Expected Value",
+ "no-predictions": "No predictions available.",
+ "accuracy": "Accuracy",
+ "total-predictions": "Total Predictions",
+ "correct-predictions": "Correct Predictions",
+ "scenario-top5": "Top 5 Score Scenarios",
+ "prediction-reasons": {
+ "market_signal_dominant": "Market signals strongly support this pick.",
+ "lineup_signal_strong": "Lineup analysis and missing players strength this prediction.",
+ "below_calibrated_conf_threshold": "Calculated confidence level is below the risk threshold.",
+ "negative_model_edge": "The model did not find sufficient value (EV+) in this bet.",
+ "market_passed_all_gates": "Passed all safety and risk checks successfully.",
+ "high_volatility_risk": "High volatility and uncertainty risk detected.",
+ "low_liquidity_risk": "Odds may be unreliable due to low liquidity.",
+ "odds_movement_suspicious": "Suspicious odds movements detected, proceed with caution.",
+ "model_confidence_low": "AI model measured a low probability of success.",
+ "data_quality_issue": "Analysis limited due to missing or inconsistent data.",
+ "playable_pick_found": "High-value playable betting opportunity detected.",
+ "odds_anomaly_detected": "Odds anomaly detected (Bookmaker Traps).",
+ "heavy_favorite_vulnerable": "Favorite team metrics look weak compared to implied odds.",
+ "momentum_loss_detected": "Serious momentum loss and form dip detected for the favorite.",
+ "safe_btts_confirmed": "Both teams to score potential statistically confirmed.",
+ "team_form_signal_dominant": "Team form data is the primary driver for this pick.",
+ "basketball_points_model": "Calculated based on basketball points projection model.",
+ "High Upset Potential detected by UpsetEngine": "High upset potential detected (UpsetEngine).",
+ "market_odds_missing": "Market odds are missing, analysis is limited.",
+ "high_risk_low_data_quality": "High risk: Low data quality.",
+ "lineup_insufficient_for_market": "Lineup data is insufficient for this market.",
+ "lineup_not_confirmed": "Lineup is not officially confirmed yet.",
+ "player_form_signal_strong": "Strong individual player form signals detected.",
+ "player_form_signal_limited": "Insufficient player statistics available.",
+ "limited_data_confidence": "Confidence score reduced due to limited data.",
+ "lineup_signal_weak": "Signal from lineup interaction is weak.",
+ "lineup_probable_xi_used": "Analysis based on probable starting XI.",
+ "missing_full_ms_odds": "Main match result odds are missing.",
+ "lineup_probable_not_confirmed": "Lineup is not confirmed, carrying inherent risk.",
+ "lineup_unavailable": "Pre-match lineup data is unavailable.",
+ "lineup_incomplete": "Some player data in the lineup is missing.",
+ "missing_referee": "Referee information is missing.",
+ "missing_moneyline_odds": "Moneyline odds are missing.",
+ "missing_total_odds": "Over/Under odds are missing.",
+ "missing_spread_odds": "Spread (Handicap) odds are missing.",
+ "no_bet_conditions_met": "The algorithm could not find a safe/valuable bet for this match.",
+ "insufficient_play_score": "Play score is below the playability threshold.",
+ "no_ev_edge_minimum_stake": "Passed safety gates but no mathematical edge — minimum stake applied.",
+ "upset_risk_detected": "High upset risk detected, proceed with caution."
+ },
+ "ev-edge": "EV Edge",
+ "implied-prob": "Market Probability",
+ "model-prob": "Model Probability",
+ "kelly-stake": "Kelly Stake",
+ "edge-positive": "Value Detected",
+ "edge-negative": "No Value",
+ "quant-analysis": "Quantitative Analysis",
+ "vs-bookie": "Model vs Bookie",
+ "engine-breakdown-title": "Engine Breakdown",
+ "engine-team": "Team Strength",
+ "engine-player": "Player Impact",
+ "engine-odds": "Odds Analysis",
+ "engine-referee": "Referee Factor",
+ "bet-advice-play": "PLAY",
+ "bet-advice-pass": "PASS",
+ "market-labels": {
+ "ML": "Moneyline",
+ "MS": "Match Result",
+ "DC": "Double Chance",
+ "TOTAL": "Total Points",
+ "SPREAD": "Spread",
+ "OU15": "Total Goals 1.5",
+ "OU25": "Total Goals 2.5",
+ "OU35": "Total Goals 3.5",
+ "BTTS": "Both Teams To Score",
+ "HT": "Half Time Result",
+ "HTFT": "Half Time / Full Time",
+ "HT/FT": "Half Time / Full Time",
+ "OE": "Odd / Even",
+ "HT_OU05": "First Half 0.5 Goals"
+ },
+ "ui": {
+ "summary-title": "Prediction Summary",
+ "summary-info": "Shows what stands out first and then explains why it stands out.",
+ "main-recommendation": "Main Recommendation",
+ "best-market-copy": "is the strongest option in this market.",
+ "confidence-label": "Confidence",
+ "odds-label": "Odds",
+ "edge-label": "Expected Advantage (Edge)",
+ "edge-info": "Edge is the gap between the model probability and the market probability. If it is positive, the model sees value in this price.",
+ "stake-label": "Suggested Bet Size (Stake)",
+ "stake-label-short": "Bet Size",
+ "stake-info": "Stake is the suggested bet size. 2.0u means a 2-unit bet in your own bankroll plan.",
+ "play-score-label": "Playability Score",
+ "playability-label": "Playability",
+ "quick-read": "Quick read",
+ "lineup-source": "Lineup Source",
+ "model-label": "Model",
+ "engine-info": "Shows which components influence the prediction the most.",
+ "best-single-pick": "Best Single Pick",
+ "alternative-markets": "Alternative Markets",
+ "alternative-markets-info": "Options outside the main recommendation.",
+ "alternative": "Alternative",
+ "pass-market": "Rejected Market",
+ "all-markets-title": "All Markets",
+ "all-markets-info": "Compares every option in a single table.",
+ "market-board-info": "The probability distribution the model sees for each market.",
+ "bet-advice-info": "The model's final action recommendation.",
+ "recommended-stake-inline": "Suggested size"
+ }
+ },
+
+ "coupons": {
+ "title": "Coupon Builder",
+ "builder-title": "Coupon Builder",
+ "builder-subtitle": "Build a coupon from upcoming football matches. Select your own pool or let AI scan the live_matches table automatically.",
+ "history-title": "Coupon History",
+ "step-select": "Select Matches",
+ "step-strategy": "Choose Strategy",
+ "step-suggest": "AI Suggestion",
+ "step-review": "Review & Save",
+ "strategy": "Strategy",
+ "strategy-safe": "Safe",
+ "strategy-balanced": "Balanced",
+ "strategy-risky": "Risky",
+ "strategy-aggressive": "Aggressive",
+ "strategy-value": "Value",
+ "strategy-miracle": "Miracle",
+ "strategy-safe-desc": "Low risk, lower odds, higher win probability",
+ "strategy-balanced-desc": "Balanced risk/reward approach",
+ "strategy-aggressive-desc": "Higher risk, higher potential returns",
+ "strategy-value-desc": "Focus on EV+ value opportunities",
+ "strategy-miracle-desc": "Maximum risk, maximum potential reward",
+ "selected-matches": "Selected Matches",
+ "available-matches": "Available Matches",
+ "total-odd": "Total Odd",
+ "generate-coupon": "Generate AI Coupon",
+ "save-coupon": "Save Coupon",
+ "clear-all": "Clear All",
+ "no-items": "No matches selected yet.",
+ "no-history": "No coupons found.",
+ "no-coupons": "No coupons found.",
+ "no-matches": "No matches available.",
+ "my-stats": "My Betting Stats",
+ "total-coupons": "Total Coupons",
+ "win-rate": "Win Rate",
+ "won": "Won",
+ "lost": "Lost",
+ "pending": "Pending",
+ "my-coupon": "My Coupon",
+ "my-coupon-help": "This panel shows the strategy, the selected match pool, and the bets returned by AI.",
+ "ai-suggest": "AI Suggest",
+ "suggestion-ready": "AI suggestion ready!",
+ "empty-coupon": "Select matches to add to your coupon.",
+ "coupon": "Coupon",
+ "candidate-match-count": "Candidate Matches",
+ "candidate-match-count-help": "How many upcoming football matches are currently available for coupon generation.",
+ "finished-match-count": "Finished Matches",
+ "finished-match-count-help": "Optional reference list of finished football matches. These are never used for coupon prediction.",
+ "selected-match-count": "Selected Matches",
+ "selected-match-count-help": "If you choose matches manually, AI will only build the coupon from this pool.",
+ "suggested-bet-count": "Suggested Bets",
+ "suggested-bet-count-help": "How many bets the AI placed into the coupon suggestion.",
+ "total-odds": "Total Odds",
+ "total-odds-help": "The combined odds of all suggested bets in the coupon.",
+ "candidate-pool-title": "Coupon Candidate Pool",
+ "candidate-pool-help": "Only football matches that have not started yet are listed here. Finished and live matches are excluded.",
+ "candidate-pool-subtitle": "Source: live_matches table • sport: football • status: not started",
+ "match-count-suffix": "matches",
+ "upcoming-badge": "Upcoming",
+ "upcoming-reference": "Upcoming pool",
+ "finished-badge": "Finished",
+ "prediction-locked": "Prediction Locked",
+ "read-only-short": "Read only",
+ "selected-short": "Selected",
+ "select-match": "Select",
+ "match-state": "Match State",
+ "selection-mode": "AI Pool",
+ "manual-pool": "Manual pool",
+ "auto-pool": "Automatic pool",
+ "finished-reference-only": "Reference only",
+ "no-upcoming-matches": "There are no upcoming football matches available for coupon generation right now.",
+ "finished-matches-title": "Finished Matches",
+ "finished-matches-help": "These matches are shown only for reference. They cannot be selected and are filtered out on the backend before any coupon prediction is created.",
+ "finished-matches-subtitle": "Optional archive view. Scores and post-match stats are never sent into the coupon prediction flow.",
+ "show-finished-matches": "Show finished matches",
+ "hide-finished-matches": "Hide finished matches",
+ "no-finished-matches": "No finished football matches were found for the current view.",
+ "manual-selection-active": "AI will only use the matches you selected below.",
+ "automatic-selection-active": "No manual selection yet. AI will pick from the full upcoming match pool.",
+ "selected-matches-panel-title": "Selected Match Pool",
+ "selected-matches-empty": "You have not selected any matches yet. If you continue like this, AI will build from the full upcoming pool.",
+ "remove-match": "Remove",
+ "manual-selection-helper": "Manual mode is active. AI will only evaluate the matches you selected.",
+ "automatic-selection-helper": "Automatic mode is active. AI will evaluate the full upcoming football match pool.",
+ "suggested-bets-title": "AI Suggested Bets",
+ "suggested-bets-title-help": "These are the bets returned by the coupon engine according to your chosen strategy.",
+ "expected-win-rate": "Expected Win Rate",
+ "bet-count": "Bet Count",
+ "confidence-label": "Confidence",
+ "probability-label": "Probability",
+ "risk-label": "Risk",
+ "data-quality-label": "Data Quality",
+ "rejected-matches-title": "Rejected Matches",
+ "no-suggestion-yet": "No coupon has been generated yet. Choose a strategy and click AI Suggest."
+ },
+
+ "profile": {
+ "title": "Profile",
+ "account-settings": "Account Settings",
+ "account-info": "Account Information",
+ "personal-info": "Personal Information",
+ "usage-limits": "Usage Limits",
+ "subscription": "Subscription",
+ "save-changes": "Save Changes",
+ "change-password": "Change Password",
+ "change-password-desc": "Keep your account secure. Use a strong password with at least 8 characters.",
+ "current-password": "Current Password",
+ "new-password": "New Password",
+ "confirm-password": "Confirm Password",
+ "first-name": "First Name",
+ "last-name": "Last Name",
+ "full-name": "Full Name",
+ "email": "Email Address",
+ "role": "Role",
+ "member-since": "Member Since",
+ "betting-stats": "Betting Statistics",
+ "total-coupons": "Total Coupons",
+ "win-rate": "Win Rate",
+ "total-profit": "Total Profit"
+ },
+
+ "leagues": {
+ "title": "Leagues & Teams",
+ "countries": "Countries",
+ "leagues": "Leagues",
+ "countries-leagues": "Countries & Leagues",
+ "search-at-least-2": "Type at least 2 characters to search teams."
+ },
+
+ "h2h": {
+ "title": "Head to Head",
+ "team-1": "Team 1",
+ "team-2": "Team 2",
+ "search-team": "Search for a team...",
+ "compare": "Compare",
+ "draws": "Draws",
+ "no-matches-found": "No head-to-head matches found between these teams."
+ },
+
+ "analysis": {
+ "title": "Multi-Match Analysis",
+ "select-matches": "Select Matches",
+ "analyze-matches": "Analyze Matches",
+ "history": "Analysis History",
+ "selected": "selected",
+ "select-at-least-2": "Select at least 2 matches to analyze.",
+ "analysis-complete": "Analysis complete!",
+ "matches-analyzed": "matches analyzed",
+ "no-history": "No analysis history yet."
+ },
+
+ "spor-toto": {
+ "title": "Spor Toto",
+ "sync-bulletins": "Sync Bulletins",
+ "sync-success": "Bulletins synced successfully!",
+ "select-bulletin": "Select Bulletin",
+ "choose-bulletin": "Choose a bulletin...",
+ "bulletin-label": "Cycle #{cycle} - {date}",
+ "cycle-no": "Cycle No.",
+ "cycle-no-short": "Cycle #{cycle}",
+ "draw-date": "Draw Date",
+ "status": "Status",
+ "matches": "Matches",
+ "choose-strategy": "Choose Strategy",
+ "generate-prediction": "Generate AI Prediction",
+ "selected": "Selected",
+ "strategy-conservative": "Conservative",
+ "strategy-conservative-desc": "100 columns, low risk approach",
+ "strategy-balanced": "Balanced",
+ "strategy-balanced-desc": "500 columns, balanced risk/reward",
+ "strategy-aggressive": "Aggressive",
+ "strategy-aggressive-desc": "2500 columns, maximum coverage",
+ "strategy-formula": "Formula 6%",
+ "strategy-formula-desc": "6% sampling, cost-efficient",
+ "bulletin-history": "Bulletin History",
+ "rollover-stats": "Rollover Stats",
+ "prediction-generated": "Prediction generated successfully!"
+ },
+
+ "admin": {
+ "title": "Admin Panel",
+ "subtitle": "Manage users, monitor predictions, and system overview.",
+ "overview": "Overview",
+ "analytics": "Analytics Overview",
+ "user-management": "User Management",
+ "users": "Users",
+ "settings": "Settings",
+ "usage-limits": "Usage Limits",
+ "total-users": "Total Users",
+ "active-users": "Active Users",
+ "active-matches": "Active Matches",
+ "total-predictions": "Total Predictions",
+ "total-coupons": "Total Coupons",
+ "toggle-active": "Toggle Active",
+ "update-role": "Update Role",
+ "update-subscription": "Update Subscription",
+ "delete-user": "Delete User",
+ "reset-limits": "Reset All Limits",
+ "setting-key": "Setting Key",
+ "setting-value": "Setting Value",
+ "update-setting": "Update",
+ "admin-badge": "Admin",
+ "user-name": "Name",
+ "user-email": "Email",
+ "user-role": "Role",
+ "user-status": "Status",
+ "no-users": "No users found."
+ },
+
+ "common": {
+ "loading": "Loading...",
+ "save": "Save",
+ "cancel": "Cancel",
+ "delete": "Delete",
+ "edit": "Edit",
+ "search": "Search",
+ "filter": "Filter",
+ "sort": "Sort",
+ "next": "Next",
+ "previous": "Previous",
+ "back": "Back",
+ "refresh": "Refresh",
+ "clear": "Clear",
+ "all": "All",
+ "no-data": "No data available.",
+ "confirm": "Confirm",
+ "close": "Close",
+ "actions": "Actions",
+ "status": "Status",
+ "date": "Date",
+ "active": "Active",
+ "inactive": "Inactive",
+ "page": "Page",
+ "of": "of",
+ "items-per-page": "Items per page",
+ "showing": "Showing",
+ "results": "results"
+ }
+}
diff --git a/messages/tr.json b/messages/tr.json
new file mode 100644
index 0000000..1600d1c
--- /dev/null
+++ b/messages/tr.json
@@ -0,0 +1,478 @@
+{
+ "home": "Anasayfa",
+ "about": "Hakkında",
+ "solutions": "Çözümler",
+ "intelligent-transportation-systems": "Akıllı Ulaşım Sistemleri",
+ "artificial-intelligence": "Yapay Zeka",
+ "error": {
+ "not-found": "Aradığınız sayfa bulunamadı.",
+ "404": "404",
+ "back-to-home": "Ana sayfaya dön",
+ "generic": "Beklenmeyen bir hata oluştu.",
+ "network": "Ağ hatası. Lütfen bağlantınızı kontrol edin.",
+ "unauthorized": "Oturumunuz sona erdi. Lütfen tekrar giriş yapın.",
+ "forbidden": "Bu kaynağa erişim yetkiniz yok.",
+ "server": "Sunucu hatası. Lütfen daha sonra tekrar deneyin.",
+ "match-not-found": "Maç bulunamadı.",
+ "prediction-not-found": "Bu maç için tahmin mevcut değil."
+ },
+ "email": "E-Posta",
+ "password": "Şifre",
+ "auth": {
+ "remember-me": "Beni Hatırla",
+ "dont-have-account": "Hesabınız yok mu?",
+ "sign-out": "Çıkış Yap",
+ "sign-up": "Kayıt Ol",
+ "sign-in": "Giriş Yap",
+ "welcome-back": "Tekrar Hoş Geldiniz",
+ "subtitle": "E-posta ve şifrenizle giriş yapın",
+ "already-have-an-account": "Zaten hesabınız var mı?",
+ "create-an-account-now": "Hemen hesap oluşturun",
+ "first-name": "Ad",
+ "last-name": "Soyad",
+ "confirm-password": "Şifreyi Onayla",
+ "forgot-password": "Şifremi Unuttum?",
+ "or-continue-with": "Veya şununla devam edin",
+ "logging-in": "Giriş yapılıyor...",
+ "registering": "Hesap oluşturuluyor..."
+ },
+ "all-right-reserved": "Tüm hakları saklıdır.",
+ "privacy-policy": "Gizlilik Politikası",
+ "terms-of-service": "Kullanım Koşulları",
+ "name": "Ad",
+ "low": "Düşük",
+ "medium": "Orta",
+ "high": "Yüksek",
+
+ "nav": {
+ "home": "Anasayfa",
+ "dashboard": "Kontrol Paneli",
+ "matches": "Maçlar",
+ "predictions": "Tahminler",
+ "coupon-builder": "Kupon Oluşturucu",
+ "coupon-history": "Kupon Geçmişi",
+ "profile": "Profil",
+ "admin": "Yönetim Paneli",
+ "teams": "Takımlar",
+ "leagues": "Ligler",
+ "h2h": "Karşılıklı Karşılaşma",
+ "analysis": "Analiz",
+ "spor-toto": "Spor Toto",
+ "how-it-works": "Nasıl Çalışır",
+ "pricing": "Fiyatlandırma",
+ "contact": "İletişim",
+ "coupons": "Kuponlar",
+ "tools": "Araçlar"
+ },
+
+ "landing": {
+ "hero-title": "Yapay Zeka Destekli Bahis Tahminleri",
+ "hero-subtitle": "Gelişmiş yapay zeka tahmin motorumuz ile daha akıllı bahisler yapın. Maçları analiz edin, değerli bahisleri keşfedin ve kazanan kuponlar oluşturun.",
+ "get-started": "Başla",
+ "learn-more": "Daha Fazla",
+ "features-title": "Neden Suggest Bet?",
+ "feature-ai": "Yapay Zeka Tahminleri",
+ "feature-ai-desc": "%95+ veri kalitesi puanlama ile V20 ensemble modeli tarafından desteklenmektedir.",
+ "feature-value": "Değerli Bahisler",
+ "feature-value-desc": "Beklenen değer analizi ile EV+ bahis fırsatlarını bulun.",
+ "feature-coupon": "Akıllı Kuponlar",
+ "feature-coupon-desc": "Yapay zeka 5 farklı strateji ile optimize edilmiş kuponlar oluşturur.",
+ "feature-live": "Canlı Takip",
+ "feature-live-desc": "Canlı skor güncellemeleri ile gerçek zamanlı maç takibi.",
+ "stats-predictions": "Yapılan Tahmin",
+ "stats-accuracy": "Doğruluk Oranı",
+ "stats-users": "Aktif Kullanıcı",
+ "stats-matches": "Analiz Edilen Maç"
+ },
+
+ "dashboard": {
+ "title": "Kontrol Paneli",
+ "welcome": "Tekrar hoş geldiniz",
+ "todays-matches": "Bugünkü Maçlar",
+ "daily-banko": "Günün Bankosu",
+ "upcoming-predictions": "Yaklaşan Tahminler",
+ "value-bets": "Değerli Bahisler",
+ "your-stats": "İstatistikleriniz",
+ "view-all": "Tümünü Gör",
+ "no-matches": "Bugün maç bulunmuyor.",
+ "no-predictions": "Tahmin bulunmuyor."
+ },
+
+ "matches": {
+ "title": "Maçlar",
+ "filter-sport": "Spor",
+ "football": "Futbol",
+ "basketball": "Basketbol",
+ "all-leagues": "Tüm Ligler",
+ "active-leagues": "Aktif Ligler",
+ "live": "CANLI",
+ "not-started": "Başlamadı",
+ "finished": "Bitti",
+ "no-matches": "Maç bulunamadı.",
+ "search-teams": "Takım ara...",
+ "view-prediction": "Tahmini Gör",
+ "match-details": "Maç Detayları",
+ "lineups": "Kadrolar",
+ "statistics": "İstatistikler",
+ "odds": "Oranlar",
+ "head-to-head": "Karşılıklı Sonuçlar",
+ "recent-matches": "Son Maçlar",
+ "home-team": "Ev Sahibi",
+ "away-team": "Deplasman",
+ "vs": "vs"
+ },
+
+ "predictions": {
+ "title": "Tahminler",
+ "upcoming": "Yaklaşan",
+ "value-bets": "Değerli Bahisler",
+ "history": "Geçmiş",
+ "model-version": "Model Versiyonu",
+ "confidence": "Kazanma Olasılığı",
+ "risk": "Risk",
+ "risk-level": "Risk Seviyesi",
+ "main-pick": "Ana Tahmin",
+ "supporting-picks": "Destekleyici Tahminler",
+ "aggressive-pick": "Agresif Tahmin",
+ "score-prediction": "Skor Tahmini",
+ "market-board": "Market Panosu",
+ "reasoning": "Analiz Faktörleri",
+ "data-quality": "Veri Kalitesi",
+ "engine-breakdown": "Motor Kırılımı",
+ "bet-advice": "Bahis Tavsiyesi",
+ "bet-summary": "Bahis Özeti",
+ "expected-value": "Beklenen Değer",
+ "no-predictions": "Tahmin bulunmuyor.",
+ "accuracy": "Doğruluk",
+ "total-predictions": "Toplam Tahmin",
+ "correct-predictions": "Doğru Tahmin",
+ "scenario-top5": "En Olası 5 Skor Senaryosu",
+ "prediction-reasons": {
+ "market_signal_dominant": "Piyasa sinyalleri bu tercihi güçlü şekilde destekliyor.",
+ "lineup_signal_strong": "Kadro analizi ve eksikler bu tahmini güçlendiriyor.",
+ "below_calibrated_conf_threshold": "Hesaplanan güven seviyesi risk eşiğinin altında kaldı.",
+ "negative_model_edge": "Model, bu bahiste yeterli değer (value) görmedi.",
+ "market_passed_all_gates": "Tüm güvenlik ve risk kontrollerinden başarıyla geçti.",
+ "high_volatility_risk": "Maçta yüksek volatilite ve belirsizlik riski var.",
+ "low_liquidity_risk": "Düşük işlem hacmi nedeniyle oranlar güvenilmez olabilir.",
+ "odds_movement_suspicious": "Anormal oran hareketleri tespit edildi, dikkatli olun.",
+ "model_confidence_low": "Yapay zeka modelinin ölçtüğü kazanma olasılığı düşük.",
+ "data_quality_issue": "Eksik veya tutarsız veri nedeniyle analiz kısıtlı.",
+ "playable_pick_found": "Oynanabilir, değeri yüksek bir bahis fırsatı tespit edildi.",
+ "odds_anomaly_detected": "Oranlarda anomali tespit edildi (Bookmaker Traps).",
+ "heavy_favorite_vulnerable": "Favori takımın verileri beklenen oranlara göre zayıf görünüyor.",
+ "momentum_loss_detected": "Favori takımda ciddi momentum kaybı ve form düşüşü var.",
+ "safe_btts_confirmed": "Karşılıklı gol potansiyeli istatistiksel olarak doğrulandı.",
+ "team_form_signal_dominant": "Takım form verileri bu tercihin ana dayanağıdır.",
+ "upset_risk_detected": "Sürpriz sonuç riski yüksek, dikkatli olun.",
+ "basketball_points_model": "Basketbol sayı projeksiyon modeline göre hesaplandı.",
+ "High Upset Potential detected by UpsetEngine": "Yüksek sürpriz potansiyeli tespit edildi (UpsetEngine).",
+ "market_odds_missing": "Piyasa oranları eksik, analiz kısıtlı.",
+ "high_risk_low_data_quality": "Yüksek risk: Düşük veri kalitesi.",
+ "lineup_insufficient_for_market": "Kadro verisi bu pazar için yetersiz.",
+ "lineup_not_confirmed": "Kadro bilgisi henüz resmi olarak onaylanmadı.",
+ "player_form_signal_strong": "Bireysel oyuncu form sinyalleri güçlü.",
+ "player_form_signal_limited": "Yeterli oyuncu istatistiği bulunmuyor.",
+ "limited_data_confidence": "Sınırlı veri nedeniyle güven skoru yansıtmaları düşürüldü.",
+ "lineup_signal_weak": "Kadro etkileşiminden gelen sinyal zayıf.",
+ "lineup_probable_xi_used": "Tahmini muhtemel 11 kullanılarak analiz edildi.",
+ "missing_full_ms_odds": "Maç sonucu ana hata oranları eksik.",
+ "lineup_probable_not_confirmed": "Kadro henüz netleşmediği için risk içeriyor.",
+ "lineup_unavailable": "Maç öncesi kadro bilgisine ulaşılamadı.",
+ "lineup_incomplete": "Kadrodaki bazı oyuncu verileri eksik.",
+ "missing_referee": "Hakem bilgisi eksik.",
+ "missing_moneyline_odds": "Taraf bahsi oranları eksik.",
+ "missing_total_odds": "Alt/Üst oranları eksik.",
+ "missing_spread_odds": "Handikap oranları eksik.",
+ "no_bet_conditions_met": "Algoritma bu maç için güvenli/değerli bir bahis önerisi bulamadı.",
+ "insufficient_play_score": "Oynanabilirlik skoru eşiğin altında kaldı.",
+ "no_ev_edge_minimum_stake": "Güvenlik kontrollerini geçti ancak matematik avantaj yok — minimum bahis uygulandı."
+ },
+ "ev-edge": "EV Edge",
+ "implied-prob": "Piyasa Olasılığı",
+ "model-prob": "Model Olasılığı",
+ "kelly-stake": "Kelly Bahis",
+ "edge-positive": "Değer Keşfedildi",
+ "edge-negative": "Değer Yok",
+ "quant-analysis": "Kantitatif Analiz",
+ "vs-bookie": "Model vs Bahisçi",
+ "engine-breakdown-title": "Motor Kırılımı",
+ "engine-team": "Takım Gücü",
+ "engine-player": "Oyuncu Etkisi",
+ "engine-odds": "Oran Analizi",
+ "engine-referee": "Hakem Faktörü",
+ "bet-advice-play": "OYNA",
+ "bet-advice-pass": "OYNAMA",
+ "market-labels": {
+ "ML": "Moneyline",
+ "MS": "Maç Sonucu",
+ "DC": "Çifte Şans",
+ "TOTAL": "Toplam Sayı",
+ "SPREAD": "Handikap",
+ "OU15": "Toplam Gol 1.5",
+ "OU25": "Toplam Gol 2.5",
+ "OU35": "Toplam Gol 3.5",
+ "BTTS": "Karşılıklı Gol",
+ "HT": "İlk Yarı Sonucu",
+ "HTFT": "İlk Yarı / Maç Sonu",
+ "HT/FT": "İlk Yarı / Maç Sonu",
+ "OE": "Tek / Çift",
+ "HT_OU05": "İlk Yarı 0.5 Gol"
+ },
+ "ui": {
+ "summary-title": "Tahmin Özeti",
+ "summary-info": "Önce neyin oynanabileceğini, sonra bunun neden öne çıktığını gösterir.",
+ "main-recommendation": "Ana Öneri",
+ "best-market-copy": "marketinde en güçlü seçim.",
+ "confidence-label": "Güven",
+ "odds-label": "Oran",
+ "edge-label": "Beklenen Avantaj (Edge)",
+ "edge-info": "Edge, model olasılığı ile piyasa olasılığı arasındaki farktır. Pozitifse model bu oranı avantajlı görüyor demektir.",
+ "stake-label": "Önerilen Miktar (Stake)",
+ "stake-label-short": "Bahis Miktarı",
+ "stake-info": "Stake, bu bahis için önerilen bahis birimidir. 2.0u, kendi bankroll planınızdaki 2 birimlik bahis anlamına gelir.",
+ "play-score-label": "Oynanabilirlik Puanı",
+ "playability-label": "Oynanabilirlik",
+ "quick-read": "Hızlı yorum",
+ "lineup-source": "Kadronun Kaynağı",
+ "model-label": "Model",
+ "engine-info": "Tahmini en çok hangi bileşenlerin etkilediğini gösterir.",
+ "best-single-pick": "En İyi Tekli Seçim",
+ "alternative-markets": "Alternatif Marketler",
+ "alternative-markets-info": "Ana tahmin dışındaki seçenekler.",
+ "alternative": "Alternatif",
+ "pass-market": "Elenen Market",
+ "all-markets-title": "Tüm Marketler",
+ "all-markets-info": "Bütün seçenekleri tek tabloda karşılaştırır.",
+ "market-board-info": "Modelin her markette gördüğü olasılık dağılımı.",
+ "bet-advice-info": "Modelin nihai aksiyon önerisi.",
+ "recommended-stake-inline": "Önerilen miktar"
+ }
+ },
+
+ "coupons": {
+ "title": "Kupon Oluşturucu",
+ "builder-title": "Kupon Oluşturucu",
+ "builder-subtitle": "Kuponu, henüz başlamamış futbol maçlarından oluşturun. İsterseniz kendi maç havuzunuzu seçin, isterseniz AI live_matches tablosunu otomatik tarasın.",
+ "history-title": "Kupon Geçmişi",
+ "step-select": "Maç Seç",
+ "step-strategy": "Strateji Seç",
+ "step-suggest": "AI Önerisi",
+ "step-review": "İncele ve Kaydet",
+ "strategy": "Strateji",
+ "strategy-safe": "Güvenli",
+ "strategy-balanced": "Dengeli",
+ "strategy-risky": "Riskli",
+ "strategy-aggressive": "Agresif",
+ "strategy-value": "Değer",
+ "strategy-miracle": "Mucize",
+ "strategy-safe-desc": "Düşük risk, düşük oran, yüksek kazanma olasılığı",
+ "strategy-balanced-desc": "Dengeli risk/ödül yaklaşımı",
+ "strategy-aggressive-desc": "Yüksek risk, yüksek potansiyel getiri",
+ "strategy-value-desc": "EV+ değer fırsatlarına odaklanır",
+ "strategy-miracle-desc": "Maksimum risk, maksimum potansiyel ödül",
+ "selected-matches": "Seçilen Maçlar",
+ "available-matches": "Mevcut Maçlar",
+ "total-odd": "Toplam Oran",
+ "generate-coupon": "AI Kuponu Oluştur",
+ "save-coupon": "Kuponu Kaydet",
+ "clear-all": "Tümünü Temizle",
+ "no-items": "Henüz maç seçilmedi.",
+ "no-history": "Kupon bulunamadı.",
+ "no-coupons": "Kupon bulunamadı.",
+ "no-matches": "Maç bulunmuyor.",
+ "my-stats": "Bahis İstatistiklerim",
+ "total-coupons": "Toplam Kupon",
+ "win-rate": "Kazanma Oranı",
+ "won": "Kazandı",
+ "lost": "Kaybetti",
+ "pending": "Beklemede",
+ "my-coupon": "Kuponum",
+ "my-coupon-help": "Bu panelde stratejiyi, seçtiğiniz maç havuzunu ve AI'ın döndürdüğü bahisleri görürsünüz.",
+ "ai-suggest": "AI Öner",
+ "suggestion-ready": "AI önerisi hazır!",
+ "empty-coupon": "Kuponunuza eklemek için maç seçin.",
+ "coupon": "Kupon",
+ "candidate-match-count": "Aday Maç",
+ "candidate-match-count-help": "Kupon oluşturmak için şu anda uygun olan yaklaşan futbol maçı sayısı.",
+ "selected-match-count": "Seçilen Maç",
+ "selected-match-count-help": "Maçları siz seçerseniz AI kuponu sadece bu havuzdan üretir.",
+ "suggested-bet-count": "Önerilen Bahis",
+ "suggested-bet-count-help": "AI'ın oluşturduğu kupon önerisinde kaç bahis olduğu.",
+ "total-odds": "Toplam Oran",
+ "total-odds-help": "Kupondaki tüm önerilen bahislerin birleşik oranı.",
+ "candidate-pool-title": "Kupon Aday Havuzu",
+ "candidate-pool-help": "Burada sadece henüz başlamamış futbol maçları listelenir. Canlı ve bitmiş maçlar dahil edilmez.",
+ "candidate-pool-subtitle": "Kaynak: live_matches tablosu - spor: futbol - durum: başlamamış",
+ "match-count-suffix": "maç",
+ "upcoming-badge": "Yaklaşan",
+ "selected-short": "Seçildi",
+ "select-match": "Seç",
+ "selection-mode": "AI Havuzu",
+ "manual-pool": "Manuel havuz",
+ "auto-pool": "Otomatik havuz",
+ "no-upcoming-matches": "Şu anda kupon oluşturmaya uygun yaklaşan futbol maçı bulunmuyor.",
+ "manual-selection-active": "AI yalnızca aşağıda seçtiğiniz maçları kullanacak.",
+ "automatic-selection-active": "Henüz manuel seçim yok. AI tüm yaklaşan maç havuzundan seçecek.",
+ "selected-matches-panel-title": "Seçili Maç Havuzu",
+ "selected-matches-empty": "Henüz maç seçmediniz. Bu şekilde devam ederseniz AI, tüm yaklaşan maç havuzundan kupon üretir.",
+ "remove-match": "Kaldır",
+ "manual-selection-helper": "Manuel mod aktif. AI sadece sizin seçtiğiniz maçları değerlendirecek.",
+ "automatic-selection-helper": "Otomatik mod aktif. AI tüm yaklaşan futbol maçlarını değerlendirecek.",
+ "match-count-label": "Kupon Maç Sayısı",
+ "match-count-help": "AI'nin oluşturacağı kupon kaç maç içermeli? 2-15 arası seçebilirsiniz. Hiç maç seçmezseniz tüm bülten taranır.",
+ "match-count-auto": "Tüm bülten ({count} maç)",
+ "suggested-bets-title": "AI Önerilen Bahisler",
+ "suggested-bets-title-help": "Bunlar, seçtiğiniz stratejiye göre kupon motorunun döndürdüğü bahislerdir.",
+ "expected-win-rate": "Beklenen Kazanma Oranı",
+ "bet-count": "Bahis Sayısı",
+ "confidence-label": "Güven",
+ "probability-label": "Olasılık",
+ "risk-label": "Risk",
+ "data-quality-label": "Veri Kalitesi",
+ "rejected-matches-title": "Elenen Maçlar",
+ "no-suggestion-yet": "Henüz kupon üretilmedi. Strateji seçip AI Öner butonuna basın."
+ },
+ "profile": {
+ "title": "Profil",
+ "account-settings": "Hesap Ayarları",
+ "account-info": "Hesap Bilgileri",
+ "personal-info": "Kişisel Bilgiler",
+ "usage-limits": "Kullanım Limitleri",
+ "subscription": "Abonelik",
+ "save-changes": "Değişiklikleri Kaydet",
+ "change-password": "Şifre Değiştir",
+ "change-password-desc": "Hesabınızı güvende tutun. En az 8 karakterli güçlü bir şifre kullanın.",
+ "current-password": "Mevcut Şifre",
+ "new-password": "Yeni Şifre",
+ "confirm-password": "Şifreyi Onayla",
+ "first-name": "Ad",
+ "last-name": "Soyad",
+ "full-name": "Ad Soyad",
+ "email": "E-Posta Adresi",
+ "role": "Rol",
+ "member-since": "Üyelik Tarihi",
+ "betting-stats": "Bahis İstatistikleri",
+ "total-coupons": "Toplam Kupon",
+ "win-rate": "Kazanma Oranı",
+ "total-profit": "Toplam Kâr"
+ },
+
+ "leagues": {
+ "title": "Ligler & Takımlar",
+ "countries": "Ülkeler",
+ "leagues": "Ligler",
+ "countries-leagues": "Ülkeler & Ligler",
+ "search-at-least-2": "Takım aramak için en az 2 karakter yazın."
+ },
+
+ "h2h": {
+ "title": "Karşılıklı Karşılaşma",
+ "team-1": "Takım 1",
+ "team-2": "Takım 2",
+ "search-team": "Takım ara...",
+ "compare": "Karşılaştır",
+ "draws": "Beraberlikler",
+ "no-matches-found": "Bu takımlar arasında karşılıklı maç bulunamadı."
+ },
+
+ "analysis": {
+ "title": "Çoklu Maç Analizi",
+ "select-matches": "Maç Seç",
+ "analyze-matches": "Maçları Analiz Et",
+ "history": "Analiz Geçmişi",
+ "selected": "seçili",
+ "select-at-least-2": "Analiz etmek için en az 2 maç seçin.",
+ "analysis-complete": "Analiz tamamlandı!",
+ "matches-analyzed": "maç analiz edildi",
+ "no-history": "Henüz analiz geçmişi yok."
+ },
+
+ "spor-toto": {
+ "title": "Spor Toto",
+ "sync-bulletins": "Bültenleri Senkronize Et",
+ "sync-success": "Bültenler başarıyla senkronize edildi!",
+ "select-bulletin": "Bülten Seç",
+ "choose-bulletin": "Bir bülten seçin...",
+ "bulletin-label": "Döngü #{cycle} - {date}",
+ "cycle-no": "Döngü No.",
+ "cycle-no-short": "Döngü #{cycle}",
+ "draw-date": "Çekiliş Tarihi",
+ "status": "Durum",
+ "matches": "Maçlar",
+ "choose-strategy": "Strateji Seç",
+ "generate-prediction": "Yapay Zeka Tahmini Oluştur",
+ "selected": "Seçili",
+ "strategy-conservative": "Muhafazakâr",
+ "strategy-conservative-desc": "100 kolon, düşük risk yaklaşımı",
+ "strategy-balanced": "Dengeli",
+ "strategy-balanced-desc": "500 kolon, dengeli risk/getiri",
+ "strategy-aggressive": "Agresif",
+ "strategy-aggressive-desc": "2500 kolon, maksimum kapsama",
+ "strategy-formula": "Formül 6%",
+ "strategy-formula-desc": "%6 örnekleme, maliyet etkin",
+ "bulletin-history": "Bülten Geçmişi",
+ "rollover-stats": "Devir İstatistikleri",
+ "prediction-generated": "Tahmin başarıyla oluşturuldu!"
+ },
+
+ "admin": {
+ "title": "Yönetim Paneli",
+ "subtitle": "Kullanıcıları yönetin, tahminleri takip edin ve sistemi izleyin.",
+ "overview": "Genel Bakış",
+ "analytics": "Analitik Genel Bakış",
+ "user-management": "Kullanıcı Yönetimi",
+ "users": "Kullanıcılar",
+ "settings": "Ayarlar",
+ "usage-limits": "Kullanım Limitleri",
+ "total-users": "Toplam Kullanıcı",
+ "active-users": "Aktif Kullanıcı",
+ "active-matches": "Aktif Maçlar",
+ "total-predictions": "Toplam Tahmin",
+ "total-coupons": "Toplam Kupon",
+ "toggle-active": "Aktiflik Değiştir",
+ "update-role": "Rol Güncelle",
+ "update-subscription": "Abonelik Güncelle",
+ "delete-user": "Kullanıcıyı Sil",
+ "reset-limits": "Tüm Limitleri Sıfırla",
+ "setting-key": "Ayar Anahtarı",
+ "setting-value": "Ayar Değeri",
+ "update-setting": "Güncelle",
+ "admin-badge": "Admin",
+ "user-name": "İsim",
+ "user-email": "E-Posta",
+ "user-role": "Rol",
+ "user-status": "Durum",
+ "no-users": "Kullanıcı bulunamadı."
+ },
+
+ "common": {
+ "loading": "Yükleniyor...",
+ "save": "Kaydet",
+ "cancel": "İptal",
+ "delete": "Sil",
+ "edit": "Düzenle",
+ "search": "Ara",
+ "filter": "Filtrele",
+ "sort": "Sırala",
+ "next": "Sonraki",
+ "previous": "Önceki",
+ "back": "Geri",
+ "refresh": "Yenile",
+ "clear": "Temizle",
+ "all": "Tümü",
+ "no-data": "Veri bulunamadı.",
+ "confirm": "Onayla",
+ "close": "Kapat",
+ "actions": "İşlemler",
+ "status": "Durum",
+ "date": "Tarih",
+ "active": "Aktif",
+ "inactive": "Pasif",
+ "page": "Sayfa",
+ "of": "/",
+ "items-per-page": "Sayfa başına öğe",
+ "showing": "Gösterilen",
+ "results": "sonuç"
+ }
+}
diff --git a/next-env.d.ts b/next-env.d.ts
new file mode 100644
index 0000000..c4b7818
--- /dev/null
+++ b/next-env.d.ts
@@ -0,0 +1,6 @@
+///
+///
+import "./.next/dev/types/routes.d.ts";
+
+// NOTE: This file should not be edited
+// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
diff --git a/next.config.ts b/next.config.ts
new file mode 100644
index 0000000..2f2f505
--- /dev/null
+++ b/next.config.ts
@@ -0,0 +1,21 @@
+import type { NextConfig } from "next";
+import createNextIntlPlugin from "next-intl/plugin";
+
+const nextConfig: NextConfig = {
+ output: 'standalone',
+ experimental: {
+ optimizePackageImports: ["@chakra-ui/react"],
+ },
+ reactCompiler: true,
+ async rewrites() {
+ return [
+ {
+ source: "/api/backend/:path*",
+ destination: `${process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3005/api'}/:path*`,
+ },
+ ];
+ },
+};
+
+const withNextIntl = createNextIntlPlugin();
+export default withNextIntl(nextConfig);
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..989ad0f
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,9725 @@
+{
+ "name": "Suggest-Bet-FE-v2",
+ "version": "0.0.1",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "Suggest-Bet-FE-v2",
+ "version": "0.0.1",
+ "dependencies": {
+ "@chakra-ui/react": "^3.28.0",
+ "@emotion/react": "^11.14.0",
+ "@google/genai": "^1.35.0",
+ "@hookform/resolvers": "^5.2.2",
+ "@tanstack/react-query": "^5.90.16",
+ "aos": "^2.3.4",
+ "axios": "^1.13.1",
+ "framer-motion": "^12.34.1",
+ "i18next": "^25.6.0",
+ "next": "16.0.0",
+ "next-auth": "^4.24.13",
+ "next-intl": "^4.4.0",
+ "next-themes": "^0.4.6",
+ "nextjs-toploader": "^3.9.17",
+ "react": "19.2.0",
+ "react-dom": "19.2.0",
+ "react-hook-form": "^7.65.0",
+ "react-icons": "^5.5.0",
+ "yup": "^1.7.1",
+ "zustand": "^5.0.11"
+ },
+ "devDependencies": {
+ "@chakra-ui/cli": "^3.27.1",
+ "@eslint/eslintrc": "^3.3.1",
+ "@types/aos": "^3.0.7",
+ "@types/node": "^20",
+ "@types/react": "19.2.2",
+ "@types/react-dom": "19.2.2",
+ "babel-plugin-react-compiler": "^1.0.0",
+ "cross-env": "^10.1.0",
+ "eslint": "^9.37.0",
+ "eslint-config-next": "16.0.0",
+ "eslint-config-prettier": "^10.1.8",
+ "prettier": "^3.6.2",
+ "typescript": "^5"
+ }
+ },
+ "node_modules/@ark-ui/react": {
+ "version": "5.31.0",
+ "resolved": "https://registry.npmjs.org/@ark-ui/react/-/react-5.31.0.tgz",
+ "integrity": "sha512-XHzq6Y3VcORoMCk4KfkAxauyuk8sTtllb1FaD3dcKfKRxIf6fw1mlAHfGIofuaqtTnP0mt0RX0ohzCsEG7ityQ==",
+ "dependencies": {
+ "@internationalized/date": "3.10.0",
+ "@zag-js/accordion": "1.33.1",
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/angle-slider": "1.33.1",
+ "@zag-js/async-list": "1.33.1",
+ "@zag-js/auto-resize": "1.33.1",
+ "@zag-js/avatar": "1.33.1",
+ "@zag-js/bottom-sheet": "1.33.1",
+ "@zag-js/carousel": "1.33.1",
+ "@zag-js/checkbox": "1.33.1",
+ "@zag-js/clipboard": "1.33.1",
+ "@zag-js/collapsible": "1.33.1",
+ "@zag-js/collection": "1.33.1",
+ "@zag-js/color-picker": "1.33.1",
+ "@zag-js/color-utils": "1.33.1",
+ "@zag-js/combobox": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/date-picker": "1.33.1",
+ "@zag-js/date-utils": "1.33.1",
+ "@zag-js/dialog": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/editable": "1.33.1",
+ "@zag-js/file-upload": "1.33.1",
+ "@zag-js/file-utils": "1.33.1",
+ "@zag-js/floating-panel": "1.33.1",
+ "@zag-js/focus-trap": "1.33.1",
+ "@zag-js/highlight-word": "1.33.1",
+ "@zag-js/hover-card": "1.33.1",
+ "@zag-js/i18n-utils": "1.33.1",
+ "@zag-js/image-cropper": "1.33.1",
+ "@zag-js/json-tree-utils": "1.33.1",
+ "@zag-js/listbox": "1.33.1",
+ "@zag-js/marquee": "1.33.1",
+ "@zag-js/menu": "1.33.1",
+ "@zag-js/navigation-menu": "1.33.1",
+ "@zag-js/number-input": "1.33.1",
+ "@zag-js/pagination": "1.33.1",
+ "@zag-js/password-input": "1.33.1",
+ "@zag-js/pin-input": "1.33.1",
+ "@zag-js/popover": "1.33.1",
+ "@zag-js/presence": "1.33.1",
+ "@zag-js/progress": "1.33.1",
+ "@zag-js/qr-code": "1.33.1",
+ "@zag-js/radio-group": "1.33.1",
+ "@zag-js/rating-group": "1.33.1",
+ "@zag-js/react": "1.33.1",
+ "@zag-js/scroll-area": "1.33.1",
+ "@zag-js/select": "1.33.1",
+ "@zag-js/signature-pad": "1.33.1",
+ "@zag-js/slider": "1.33.1",
+ "@zag-js/splitter": "1.33.1",
+ "@zag-js/steps": "1.33.1",
+ "@zag-js/switch": "1.33.1",
+ "@zag-js/tabs": "1.33.1",
+ "@zag-js/tags-input": "1.33.1",
+ "@zag-js/timer": "1.33.1",
+ "@zag-js/toast": "1.33.1",
+ "@zag-js/toggle": "1.33.1",
+ "@zag-js/toggle-group": "1.33.1",
+ "@zag-js/tooltip": "1.33.1",
+ "@zag-js/tour": "1.33.1",
+ "@zag-js/tree-view": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ },
+ "peerDependencies": {
+ "react": ">=18.0.0",
+ "react-dom": ">=18.0.0"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
+ "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.28.5",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz",
+ "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz",
+ "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.29.0",
+ "@babel/generator": "^7.29.0",
+ "@babel/helper-compilation-targets": "^7.28.6",
+ "@babel/helper-module-transforms": "^7.28.6",
+ "@babel/helpers": "^7.28.6",
+ "@babel/parser": "^7.29.0",
+ "@babel/template": "^7.28.6",
+ "@babel/traverse": "^7.29.0",
+ "@babel/types": "^7.29.0",
+ "@jridgewell/remapping": "^2.3.5",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.29.1",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz",
+ "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==",
+ "dependencies": {
+ "@babel/parser": "^7.29.0",
+ "@babel/types": "^7.29.0",
+ "@jridgewell/gen-mapping": "^0.3.12",
+ "@jridgewell/trace-mapping": "^0.3.28",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-annotate-as-pure": {
+ "version": "7.27.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz",
+ "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.27.3"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz",
+ "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.28.6",
+ "@babel/helper-validator-option": "^7.27.1",
+ "browserslist": "^4.24.0",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-create-class-features-plugin": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.6.tgz",
+ "integrity": "sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.3",
+ "@babel/helper-member-expression-to-functions": "^7.28.5",
+ "@babel/helper-optimise-call-expression": "^7.27.1",
+ "@babel/helper-replace-supers": "^7.28.6",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
+ "@babel/traverse": "^7.28.6",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.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==",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-member-expression-to-functions": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz",
+ "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/traverse": "^7.28.5",
+ "@babel/types": "^7.28.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz",
+ "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==",
+ "dependencies": {
+ "@babel/traverse": "^7.28.6",
+ "@babel/types": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz",
+ "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.28.6",
+ "@babel/helper-validator-identifier": "^7.28.5",
+ "@babel/traverse": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-optimise-call-expression": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz",
+ "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz",
+ "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-replace-supers": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz",
+ "integrity": "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-member-expression-to-functions": "^7.28.5",
+ "@babel/helper-optimise-call-expression": "^7.27.1",
+ "@babel/traverse": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-skip-transparent-expression-wrappers": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz",
+ "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/traverse": "^7.27.1",
+ "@babel/types": "^7.27.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
+ "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==",
+ "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,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz",
+ "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.28.6",
+ "@babel/types": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz",
+ "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==",
+ "dependencies": {
+ "@babel/types": "^7.29.0"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-typescript": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz",
+ "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-typescript": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.6.tgz",
+ "integrity": "sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.27.3",
+ "@babel/helper-create-class-features-plugin": "^7.28.6",
+ "@babel/helper-plugin-utils": "^7.28.6",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1",
+ "@babel/plugin-syntax-typescript": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz",
+ "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.28.6",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz",
+ "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==",
+ "dependencies": {
+ "@babel/code-frame": "^7.28.6",
+ "@babel/parser": "^7.28.6",
+ "@babel/types": "^7.28.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz",
+ "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==",
+ "dependencies": {
+ "@babel/code-frame": "^7.29.0",
+ "@babel/generator": "^7.29.0",
+ "@babel/helper-globals": "^7.28.0",
+ "@babel/parser": "^7.29.0",
+ "@babel/template": "^7.28.6",
+ "@babel/types": "^7.29.0",
+ "debug": "^4.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
+ "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.28.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@chakra-ui/cli": {
+ "version": "3.33.0",
+ "resolved": "https://registry.npmjs.org/@chakra-ui/cli/-/cli-3.33.0.tgz",
+ "integrity": "sha512-WkBm7V/JvnSelCHjmIu0NyjhYY1l6em4ZKXMQJ1lk1EAl1fL2eA1Ul2TZGuaCxzCGSYrxZoLDOgP3Z6WDFU6/A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.26.0",
+ "@babel/parser": "^7.26.0",
+ "@babel/plugin-transform-typescript": "^7.26.0",
+ "@clack/prompts": "0.11.0",
+ "@pandacss/is-valid-prop": "1.8.1",
+ "@types/babel__core": "^7.20.5",
+ "@types/cli-table": "^0.3.4",
+ "@types/debug": "^4.1.12",
+ "@visulima/boxen": "^2.0.10",
+ "bundle-n-require": "1.1.2",
+ "chokidar": "5.0.0",
+ "cli-table": "^0.3.11",
+ "commander": "14.0.3",
+ "debug": "^4.4.3",
+ "dotenv": "^17.2.3",
+ "globby": "14.1.0",
+ "https-proxy-agent": "^7.0.6",
+ "look-it-up": "2.1.0",
+ "node-fetch": "3.3.2",
+ "package-manager-detector": "1.6.0",
+ "prettier": "3.8.1",
+ "recast": "^0.23.0",
+ "scule": "1.3.0",
+ "zod": "^3.25.76"
+ },
+ "bin": {
+ "chakra": "bin/index.js"
+ },
+ "peerDependencies": {
+ "@chakra-ui/react": ">=3.0.0-next.0"
+ }
+ },
+ "node_modules/@chakra-ui/react": {
+ "version": "3.33.0",
+ "resolved": "https://registry.npmjs.org/@chakra-ui/react/-/react-3.33.0.tgz",
+ "integrity": "sha512-HNbUFsFABjVL5IHBxsqtuT+AH/vQT1+xsEWrxnG0GBM2VjlzlMqlqCxNiDyQOsjLZXQC1ciCMbzPNcSCc63Y9w==",
+ "dependencies": {
+ "@ark-ui/react": "^5.31.0",
+ "@emotion/is-prop-valid": "^1.4.0",
+ "@emotion/serialize": "^1.3.3",
+ "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0",
+ "@emotion/utils": "^1.4.2",
+ "@pandacss/is-valid-prop": "^1.4.2",
+ "csstype": "^3.2.3"
+ },
+ "peerDependencies": {
+ "@emotion/react": ">=11",
+ "react": ">=18",
+ "react-dom": ">=18"
+ }
+ },
+ "node_modules/@clack/core": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/@clack/core/-/core-0.5.0.tgz",
+ "integrity": "sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow==",
+ "dev": true,
+ "dependencies": {
+ "picocolors": "^1.0.0",
+ "sisteransi": "^1.0.5"
+ }
+ },
+ "node_modules/@clack/prompts": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-0.11.0.tgz",
+ "integrity": "sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw==",
+ "dev": true,
+ "dependencies": {
+ "@clack/core": "0.5.0",
+ "picocolors": "^1.0.0",
+ "sisteransi": "^1.0.5"
+ }
+ },
+ "node_modules/@emnapi/core": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz",
+ "integrity": "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==",
+ "dev": true,
+ "optional": true,
+ "dependencies": {
+ "@emnapi/wasi-threads": "1.1.0",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/runtime": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz",
+ "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==",
+ "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,
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emotion/babel-plugin": {
+ "version": "11.13.5",
+ "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz",
+ "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.16.7",
+ "@babel/runtime": "^7.18.3",
+ "@emotion/hash": "^0.9.2",
+ "@emotion/memoize": "^0.9.0",
+ "@emotion/serialize": "^1.3.3",
+ "babel-plugin-macros": "^3.1.0",
+ "convert-source-map": "^1.5.0",
+ "escape-string-regexp": "^4.0.0",
+ "find-root": "^1.1.0",
+ "source-map": "^0.5.7",
+ "stylis": "4.2.0"
+ }
+ },
+ "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
+ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="
+ },
+ "node_modules/@emotion/cache": {
+ "version": "11.14.0",
+ "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz",
+ "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==",
+ "dependencies": {
+ "@emotion/memoize": "^0.9.0",
+ "@emotion/sheet": "^1.4.0",
+ "@emotion/utils": "^1.4.2",
+ "@emotion/weak-memoize": "^0.4.0",
+ "stylis": "4.2.0"
+ }
+ },
+ "node_modules/@emotion/hash": {
+ "version": "0.9.2",
+ "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz",
+ "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g=="
+ },
+ "node_modules/@emotion/is-prop-valid": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.4.0.tgz",
+ "integrity": "sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==",
+ "dependencies": {
+ "@emotion/memoize": "^0.9.0"
+ }
+ },
+ "node_modules/@emotion/memoize": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz",
+ "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ=="
+ },
+ "node_modules/@emotion/react": {
+ "version": "11.14.0",
+ "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz",
+ "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==",
+ "dependencies": {
+ "@babel/runtime": "^7.18.3",
+ "@emotion/babel-plugin": "^11.13.5",
+ "@emotion/cache": "^11.14.0",
+ "@emotion/serialize": "^1.3.3",
+ "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0",
+ "@emotion/utils": "^1.4.2",
+ "@emotion/weak-memoize": "^0.4.0",
+ "hoist-non-react-statics": "^3.3.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@emotion/serialize": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz",
+ "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==",
+ "dependencies": {
+ "@emotion/hash": "^0.9.2",
+ "@emotion/memoize": "^0.9.0",
+ "@emotion/unitless": "^0.10.0",
+ "@emotion/utils": "^1.4.2",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@emotion/sheet": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz",
+ "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg=="
+ },
+ "node_modules/@emotion/unitless": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz",
+ "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg=="
+ },
+ "node_modules/@emotion/use-insertion-effect-with-fallbacks": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz",
+ "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==",
+ "peerDependencies": {
+ "react": ">=16.8.0"
+ }
+ },
+ "node_modules/@emotion/utils": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz",
+ "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA=="
+ },
+ "node_modules/@emotion/weak-memoize": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz",
+ "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg=="
+ },
+ "node_modules/@epic-web/invariant": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@epic-web/invariant/-/invariant-1.0.0.tgz",
+ "integrity": "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz",
+ "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz",
+ "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz",
+ "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz",
+ "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz",
+ "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz",
+ "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz",
+ "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz",
+ "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz",
+ "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz",
+ "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz",
+ "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz",
+ "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz",
+ "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz",
+ "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz",
+ "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz",
+ "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz",
+ "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz",
+ "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz",
+ "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz",
+ "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz",
+ "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz",
+ "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz",
+ "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz",
+ "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz",
+ "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz",
+ "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.9.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
+ "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==",
+ "dev": true,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "dependencies": {
+ "@eslint/core": "^0.17.0",
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@floating-ui/core": {
+ "version": "1.7.4",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.4.tgz",
+ "integrity": "sha512-C3HlIdsBxszvm5McXlB8PeOEWfBhcGBTZGkGlWc2U0KFY5IwG5OQEuQ8rq52DZmcHDlPLd+YFBK+cZcytwIFWg==",
+ "dependencies": {
+ "@floating-ui/utils": "^0.2.10"
+ }
+ },
+ "node_modules/@floating-ui/dom": {
+ "version": "1.7.5",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.5.tgz",
+ "integrity": "sha512-N0bD2kIPInNHUHehXhMke1rBGs1dwqvC9O9KYMyyjK7iXt7GAhnro7UlcuYcGdS/yYOlq0MAVgrow8IbWJwyqg==",
+ "dependencies": {
+ "@floating-ui/core": "^1.7.4",
+ "@floating-ui/utils": "^0.2.10"
+ }
+ },
+ "node_modules/@floating-ui/utils": {
+ "version": "0.2.10",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz",
+ "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="
+ },
+ "node_modules/@formatjs/ecma402-abstract": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-3.1.1.tgz",
+ "integrity": "sha512-jhZbTwda+2tcNrs4kKvxrPLPjx8QsBCLCUgrrJ/S+G9YrGHWLhAyFMMBHJBnBoOwuLHd7L14FgYudviKaxkO2Q==",
+ "dependencies": {
+ "@formatjs/fast-memoize": "3.1.0",
+ "@formatjs/intl-localematcher": "0.8.1",
+ "decimal.js": "^10.6.0",
+ "tslib": "^2.8.1"
+ }
+ },
+ "node_modules/@formatjs/fast-memoize": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-3.1.0.tgz",
+ "integrity": "sha512-b5mvSWCI+XVKiz5WhnBCY3RJ4ZwfjAidU0yVlKa3d3MSgKmH1hC3tBGEAtYyN5mqL7N0G5x0BOUYyO8CEupWgg==",
+ "dependencies": {
+ "tslib": "^2.8.1"
+ }
+ },
+ "node_modules/@formatjs/icu-messageformat-parser": {
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-3.5.1.tgz",
+ "integrity": "sha512-sSDmSvmmoVQ92XqWb499KrIhv/vLisJU8ITFrx7T7NZHUmMY7EL9xgRowAosaljhqnj/5iufG24QrdzB6X3ItA==",
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "3.1.1",
+ "@formatjs/icu-skeleton-parser": "2.1.1",
+ "tslib": "^2.8.1"
+ }
+ },
+ "node_modules/@formatjs/icu-skeleton-parser": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-2.1.1.tgz",
+ "integrity": "sha512-PSFABlcNefjI6yyk8f7nyX1DC7NHmq6WaCHZLySEXBrXuLOB2f935YsnzuPjlz+ibhb9yWTdPeVX1OVcj24w2Q==",
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "3.1.1",
+ "tslib": "^2.8.1"
+ }
+ },
+ "node_modules/@formatjs/intl-localematcher": {
+ "version": "0.8.1",
+ "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.8.1.tgz",
+ "integrity": "sha512-xwEuwQFdtSq1UKtQnyTZWC+eHdv7Uygoa+H2k/9uzBVQjDyp9r20LNDNKedWXll7FssT3GRHvqsdJGYSUWqYFA==",
+ "dependencies": {
+ "@formatjs/fast-memoize": "3.1.0",
+ "tslib": "^2.8.1"
+ }
+ },
+ "node_modules/@google/genai": {
+ "version": "1.41.0",
+ "resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.41.0.tgz",
+ "integrity": "sha512-S4WGil+PG0NBQRAx+0yrQuM/TWOLn2gGEy5wn4IsoOI6ouHad0P61p3OWdhJ3aqr9kfj8o904i/jevfaGoGuIQ==",
+ "dependencies": {
+ "google-auth-library": "^10.3.0",
+ "p-retry": "^7.1.1",
+ "protobufjs": "^7.5.4",
+ "ws": "^8.18.0"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "peerDependencies": {
+ "@modelcontextprotocol/sdk": "^1.25.2"
+ },
+ "peerDependenciesMeta": {
+ "@modelcontextprotocol/sdk": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@hookform/resolvers": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/@hookform/resolvers/-/resolvers-5.2.2.tgz",
+ "integrity": "sha512-A/IxlMLShx3KjV/HeTcTfaMxdwy690+L/ZADoeaTltLx+CVuzkeVIPuybK3jrRfw7YZnmdKsVVHAlEPIAEUNlA==",
+ "dependencies": {
+ "@standard-schema/utils": "^0.3.0"
+ },
+ "peerDependencies": {
+ "react-hook-form": "^7.55.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,
+ "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,
+ "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,
+ "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,
+ "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==",
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "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"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@internationalized/date": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.10.0.tgz",
+ "integrity": "sha512-oxDR/NTEJ1k+UFVQElaNIk65E/Z83HK1z1WI3lQyhTtnNg4R5oVXaPzK3jcpKG8UHKDVuDQHzn+wsxSz8RP3aw==",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0"
+ }
+ },
+ "node_modules/@internationalized/number": {
+ "version": "3.6.5",
+ "resolved": "https://registry.npmjs.org/@internationalized/number/-/number-3.6.5.tgz",
+ "integrity": "sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g==",
+ "dependencies": {
+ "@swc/helpers": "^0.5.0"
+ }
+ },
+ "node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@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==",
+ "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,
+ "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==",
+ "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=="
+ },
+ "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==",
+ "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,
+ "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.0.0",
+ "resolved": "https://registry.npmjs.org/@next/env/-/env-16.0.0.tgz",
+ "integrity": "sha512-s5j2iFGp38QsG1LWRQaE2iUY3h1jc014/melHFfLdrsMJPqxqDQwWNwyQTcNoUSGZlCVZuM7t7JDMmSyRilsnA=="
+ },
+ "node_modules/@next/eslint-plugin-next": {
+ "version": "16.0.0",
+ "resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-16.0.0.tgz",
+ "integrity": "sha512-IB7RzmmtrPOrpAgEBR1PIQPD0yea5lggh5cq54m51jHjjljU80Ia+czfxJYMlSDl1DPvpzb8S9TalCc0VMo9Hw==",
+ "dev": true,
+ "dependencies": {
+ "fast-glob": "3.3.1"
+ }
+ },
+ "node_modules/@next/swc-darwin-arm64": {
+ "version": "16.0.0",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.0.0.tgz",
+ "integrity": "sha512-/CntqDCnk5w2qIwMiF0a9r6+9qunZzFmU0cBX4T82LOflE72zzH6gnOjCwUXYKOBlQi8OpP/rMj8cBIr18x4TA==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-darwin-x64": {
+ "version": "16.0.0",
+ "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.0.0.tgz",
+ "integrity": "sha512-hB4GZnJGKa8m4efvTGNyii6qs76vTNl+3dKHTCAUaksN6KjYy4iEO3Q5ira405NW2PKb3EcqWiRaL9DrYJfMHg==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-arm64-gnu": {
+ "version": "16.0.0",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.0.0.tgz",
+ "integrity": "sha512-E2IHMdE+C1k+nUgndM13/BY/iJY9KGCphCftMh7SXWcaQqExq/pJU/1Hgn8n/tFwSoLoYC/yUghOv97tAsIxqg==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-arm64-musl": {
+ "version": "16.0.0",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.0.0.tgz",
+ "integrity": "sha512-xzgl7c7BVk4+7PDWldU+On2nlwnGgFqJ1siWp3/8S0KBBLCjonB6zwJYPtl4MUY7YZJrzzumdUpUoquu5zk8vg==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-x64-gnu": {
+ "version": "16.0.0",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.0.0.tgz",
+ "integrity": "sha512-sdyOg4cbiCw7YUr0F/7ya42oiVBXLD21EYkSwN+PhE4csJH4MSXUsYyslliiiBwkM+KsuQH/y9wuxVz6s7Nstg==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-linux-x64-musl": {
+ "version": "16.0.0",
+ "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.0.0.tgz",
+ "integrity": "sha512-IAXv3OBYqVaNOgyd3kxR4L3msuhmSy1bcchPHxDOjypG33i2yDWvGBwFD94OuuTjjTt/7cuIKtAmoOOml6kfbg==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-win32-arm64-msvc": {
+ "version": "16.0.0",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.0.0.tgz",
+ "integrity": "sha512-bmo3ncIJKUS9PWK1JD9pEVv0yuvp1KPuOsyJTHXTv8KDrEmgV/K+U0C75rl9rhIaODcS7JEb6/7eJhdwXI0XmA==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@next/swc-win32-x64-msvc": {
+ "version": "16.0.0",
+ "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.0.0.tgz",
+ "integrity": "sha512-O1cJbT+lZp+cTjYyZGiDwsOjO3UHHzSqobkPNipdlnnuPb1swfcuY6r3p8dsKU4hAIEO4cO67ZCfVVH/M1ETXA==",
+ "cpu": [
+ "x64"
+ ],
+ "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,
+ "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,
+ "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,
+ "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,
+ "engines": {
+ "node": ">=12.4.0"
+ }
+ },
+ "node_modules/@pandacss/is-valid-prop": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/@pandacss/is-valid-prop/-/is-valid-prop-1.8.1.tgz",
+ "integrity": "sha512-gf2HTBCOboc65Jlb9swAjbffXSIv+A4vzSQ9iHyTCDLMcXTHYjPOQNliI36WkuQgR0pNXggBbQXGNaT9wKcrAw=="
+ },
+ "node_modules/@panva/hkdf": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.2.1.tgz",
+ "integrity": "sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==",
+ "funding": {
+ "url": "https://github.com/sponsors/panva"
+ }
+ },
+ "node_modules/@parcel/watcher": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz",
+ "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "detect-libc": "^2.0.3",
+ "is-glob": "^4.0.3",
+ "node-addon-api": "^7.0.0",
+ "picomatch": "^4.0.3"
+ },
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "@parcel/watcher-android-arm64": "2.5.6",
+ "@parcel/watcher-darwin-arm64": "2.5.6",
+ "@parcel/watcher-darwin-x64": "2.5.6",
+ "@parcel/watcher-freebsd-x64": "2.5.6",
+ "@parcel/watcher-linux-arm-glibc": "2.5.6",
+ "@parcel/watcher-linux-arm-musl": "2.5.6",
+ "@parcel/watcher-linux-arm64-glibc": "2.5.6",
+ "@parcel/watcher-linux-arm64-musl": "2.5.6",
+ "@parcel/watcher-linux-x64-glibc": "2.5.6",
+ "@parcel/watcher-linux-x64-musl": "2.5.6",
+ "@parcel/watcher-win32-arm64": "2.5.6",
+ "@parcel/watcher-win32-ia32": "2.5.6",
+ "@parcel/watcher-win32-x64": "2.5.6"
+ }
+ },
+ "node_modules/@parcel/watcher-android-arm64": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz",
+ "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-darwin-arm64": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz",
+ "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-darwin-x64": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz",
+ "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-freebsd-x64": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz",
+ "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm-glibc": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz",
+ "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm-musl": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz",
+ "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm64-glibc": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz",
+ "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm64-musl": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz",
+ "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-x64-glibc": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz",
+ "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-x64-musl": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz",
+ "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-arm64": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz",
+ "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-ia32": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz",
+ "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==",
+ "cpu": [
+ "ia32"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-x64": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz",
+ "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@protobufjs/aspromise": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
+ "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="
+ },
+ "node_modules/@protobufjs/base64": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
+ "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
+ },
+ "node_modules/@protobufjs/codegen": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
+ "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
+ },
+ "node_modules/@protobufjs/eventemitter": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
+ "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="
+ },
+ "node_modules/@protobufjs/fetch": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
+ "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.1",
+ "@protobufjs/inquire": "^1.1.0"
+ }
+ },
+ "node_modules/@protobufjs/float": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
+ "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="
+ },
+ "node_modules/@protobufjs/inquire": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
+ "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="
+ },
+ "node_modules/@protobufjs/path": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
+ "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="
+ },
+ "node_modules/@protobufjs/pool": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
+ "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="
+ },
+ "node_modules/@protobufjs/utf8": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
+ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
+ },
+ "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
+ },
+ "node_modules/@schummar/icu-type-parser": {
+ "version": "1.21.5",
+ "resolved": "https://registry.npmjs.org/@schummar/icu-type-parser/-/icu-type-parser-1.21.5.tgz",
+ "integrity": "sha512-bXHSaW5jRTmke9Vd0h5P7BtWZG9Znqb8gSDxZnxaGSJnGwPLDPfS+3g0BKzeWqzgZPsIVZkM7m2tbo18cm5HBw=="
+ },
+ "node_modules/@sindresorhus/merge-streams": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz",
+ "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@standard-schema/utils": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz",
+ "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g=="
+ },
+ "node_modules/@swc/core": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.11.tgz",
+ "integrity": "sha512-iLmLTodbYxU39HhMPaMUooPwO/zqJWvsqkrXv1ZI38rMb048p6N7qtAtTp37sw9NzSrvH6oli8EdDygo09IZ/w==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@swc/counter": "^0.1.3",
+ "@swc/types": "^0.1.25"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/swc"
+ },
+ "optionalDependencies": {
+ "@swc/core-darwin-arm64": "1.15.11",
+ "@swc/core-darwin-x64": "1.15.11",
+ "@swc/core-linux-arm-gnueabihf": "1.15.11",
+ "@swc/core-linux-arm64-gnu": "1.15.11",
+ "@swc/core-linux-arm64-musl": "1.15.11",
+ "@swc/core-linux-x64-gnu": "1.15.11",
+ "@swc/core-linux-x64-musl": "1.15.11",
+ "@swc/core-win32-arm64-msvc": "1.15.11",
+ "@swc/core-win32-ia32-msvc": "1.15.11",
+ "@swc/core-win32-x64-msvc": "1.15.11"
+ },
+ "peerDependencies": {
+ "@swc/helpers": ">=0.5.17"
+ },
+ "peerDependenciesMeta": {
+ "@swc/helpers": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@swc/core-darwin-arm64": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.11.tgz",
+ "integrity": "sha512-QoIupRWVH8AF1TgxYyeA5nS18dtqMuxNwchjBIwJo3RdwLEFiJq6onOx9JAxHtuPwUkIVuU2Xbp+jCJ7Vzmgtg==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-darwin-x64": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.11.tgz",
+ "integrity": "sha512-S52Gu1QtPSfBYDiejlcfp9GlN+NjTZBRRNsz8PNwBgSE626/FUf2PcllVUix7jqkoMC+t0rS8t+2/aSWlMuQtA==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-arm-gnueabihf": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.11.tgz",
+ "integrity": "sha512-lXJs8oXo6Z4yCpimpQ8vPeCjkgoHu5NoMvmJZ8qxDyU99KVdg6KwU9H79vzrmB+HfH+dCZ7JGMqMF//f8Cfvdg==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-arm64-gnu": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.11.tgz",
+ "integrity": "sha512-chRsz1K52/vj8Mfq/QOugVphlKPWlMh10V99qfH41hbGvwAU6xSPd681upO4bKiOr9+mRIZZW+EfJqY42ZzRyA==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-arm64-musl": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.11.tgz",
+ "integrity": "sha512-PYftgsTaGnfDK4m6/dty9ryK1FbLk+LosDJ/RJR2nkXGc8rd+WenXIlvHjWULiBVnS1RsjHHOXmTS4nDhe0v0w==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-x64-gnu": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.11.tgz",
+ "integrity": "sha512-DKtnJKIHiZdARyTKiX7zdRjiDS1KihkQWatQiCHMv+zc2sfwb4Glrodx2VLOX4rsa92NLR0Sw8WLcPEMFY1szQ==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-linux-x64-musl": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.11.tgz",
+ "integrity": "sha512-mUjjntHj4+8WBaiDe5UwRNHuEzLjIWBTSGTw0JT9+C9/Yyuh4KQqlcEQ3ro6GkHmBGXBFpGIj/o5VMyRWfVfWw==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-win32-arm64-msvc": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.11.tgz",
+ "integrity": "sha512-ZkNNG5zL49YpaFzfl6fskNOSxtcZ5uOYmWBkY4wVAvgbSAQzLRVBp+xArGWh2oXlY/WgL99zQSGTv7RI5E6nzA==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-win32-ia32-msvc": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.11.tgz",
+ "integrity": "sha512-6XnzORkZCQzvTQ6cPrU7iaT9+i145oLwnin8JrfsLG41wl26+5cNQ2XV3zcbrnFEV6esjOceom9YO1w9mGJByw==",
+ "cpu": [
+ "ia32"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/core-win32-x64-msvc": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.11.tgz",
+ "integrity": "sha512-IQ2n6af7XKLL6P1gIeZACskSxK8jWtoKpJWLZmdXTDj1MGzktUy4i+FvpdtxFmJWNavRWH1VmTr6kAubRDHeKw==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@swc/counter": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
+ "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ=="
+ },
+ "node_modules/@swc/helpers": {
+ "version": "0.5.18",
+ "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.18.tgz",
+ "integrity": "sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==",
+ "dependencies": {
+ "tslib": "^2.8.0"
+ }
+ },
+ "node_modules/@swc/types": {
+ "version": "0.1.25",
+ "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.25.tgz",
+ "integrity": "sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==",
+ "dependencies": {
+ "@swc/counter": "^0.1.3"
+ }
+ },
+ "node_modules/@tanstack/query-core": {
+ "version": "5.90.20",
+ "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.20.tgz",
+ "integrity": "sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ }
+ },
+ "node_modules/@tanstack/react-query": {
+ "version": "5.90.21",
+ "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.21.tgz",
+ "integrity": "sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg==",
+ "dependencies": {
+ "@tanstack/query-core": "5.90.20"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/tannerlinsley"
+ },
+ "peerDependencies": {
+ "react": "^18 || ^19"
+ }
+ },
+ "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,
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@types/aos": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/@types/aos/-/aos-3.0.7.tgz",
+ "integrity": "sha512-sEhyFqvKauUJZDbvAB3Pggynrq6g+2PS4XB3tmUr+mDL1gfDJnwslUC4QQ7/l8UD+LWpr3RxZVR/rHoZrLqZVg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/babel__core": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
+ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "node_modules/@types/babel__generator": {
+ "version": "7.27.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz",
+ "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__template": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
+ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__traverse": {
+ "version": "7.28.0",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz",
+ "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.28.2"
+ }
+ },
+ "node_modules/@types/cli-table": {
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/@types/cli-table/-/cli-table-0.3.4.tgz",
+ "integrity": "sha512-GsALrTL69mlwbAw/MHF1IPTadSLZQnsxe7a80G8l4inN/iEXCOcVeT/S7aRc6hbhqzL9qZ314kHPDQnQ3ev+HA==",
+ "dev": true
+ },
+ "node_modules/@types/debug": {
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
+ "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==",
+ "dev": true,
+ "dependencies": {
+ "@types/ms": "*"
+ }
+ },
+ "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
+ },
+ "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
+ },
+ "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
+ },
+ "node_modules/@types/ms": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
+ "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
+ "dev": true
+ },
+ "node_modules/@types/node": {
+ "version": "20.19.33",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.33.tgz",
+ "integrity": "sha512-Rs1bVAIdBs5gbTIKza/tgpMuG1k3U/UMJLWecIMxNdJFDMzcM5LOiLVRYh3PilWEYDIeUDv7bpiHPLPsbydGcw==",
+ "dependencies": {
+ "undici-types": "~6.21.0"
+ }
+ },
+ "node_modules/@types/parse-json": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz",
+ "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw=="
+ },
+ "node_modules/@types/react": {
+ "version": "19.2.2",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz",
+ "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==",
+ "devOptional": true,
+ "dependencies": {
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "19.2.2",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.2.tgz",
+ "integrity": "sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==",
+ "dev": true,
+ "peerDependencies": {
+ "@types/react": "^19.2.0"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "8.56.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.56.0.tgz",
+ "integrity": "sha512-lRyPDLzNCuae71A3t9NEINBiTn7swyOhvUj3MyUOxb8x6g6vPEFoOU+ZRmGMusNC3X3YMhqMIX7i8ShqhT74Pw==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.12.2",
+ "@typescript-eslint/scope-manager": "8.56.0",
+ "@typescript-eslint/type-utils": "8.56.0",
+ "@typescript-eslint/utils": "8.56.0",
+ "@typescript-eslint/visitor-keys": "8.56.0",
+ "ignore": "^7.0.5",
+ "natural-compare": "^1.4.0",
+ "ts-api-utils": "^2.4.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^8.56.0",
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
+ "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "8.56.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.56.0.tgz",
+ "integrity": "sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "8.56.0",
+ "@typescript-eslint/types": "8.56.0",
+ "@typescript-eslint/typescript-estree": "8.56.0",
+ "@typescript-eslint/visitor-keys": "8.56.0",
+ "debug": "^4.4.3"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/project-service": {
+ "version": "8.56.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.0.tgz",
+ "integrity": "sha512-M3rnyL1vIQOMeWxTWIW096/TtVP+8W3p/XnaFflhmcFp+U4zlxUxWj4XwNs6HbDeTtN4yun0GNTTDBw/SvufKg==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/tsconfig-utils": "^8.56.0",
+ "@typescript-eslint/types": "^8.56.0",
+ "debug": "^4.4.3"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "8.56.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.0.tgz",
+ "integrity": "sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "8.56.0",
+ "@typescript-eslint/visitor-keys": "8.56.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.56.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.0.tgz",
+ "integrity": "sha512-bSJoIIt4o3lKXD3xmDh9chZcjCz5Lk8xS7Rxn+6l5/pKrDpkCwtQNQQwZ2qRPk7TkUYhrq3WPIHXOXlbXP0itg==",
+ "dev": true,
+ "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.56.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.56.0.tgz",
+ "integrity": "sha512-qX2L3HWOU2nuDs6GzglBeuFXviDODreS58tLY/BALPC7iu3Fa+J7EOTwnX9PdNBxUI7Uh0ntP0YWGnxCkXzmfA==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "8.56.0",
+ "@typescript-eslint/typescript-estree": "8.56.0",
+ "@typescript-eslint/utils": "8.56.0",
+ "debug": "^4.4.3",
+ "ts-api-utils": "^2.4.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "8.56.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz",
+ "integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==",
+ "dev": true,
+ "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.56.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.0.tgz",
+ "integrity": "sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/project-service": "8.56.0",
+ "@typescript-eslint/tsconfig-utils": "8.56.0",
+ "@typescript-eslint/types": "8.56.0",
+ "@typescript-eslint/visitor-keys": "8.56.0",
+ "debug": "^4.4.3",
+ "minimatch": "^9.0.5",
+ "semver": "^7.7.3",
+ "tinyglobby": "^0.2.15",
+ "ts-api-utils": "^2.4.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/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,
+ "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,
+ "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.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "8.56.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.0.tgz",
+ "integrity": "sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==",
+ "dev": true,
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.9.1",
+ "@typescript-eslint/scope-manager": "8.56.0",
+ "@typescript-eslint/types": "8.56.0",
+ "@typescript-eslint/typescript-estree": "8.56.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "8.56.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.0.tgz",
+ "integrity": "sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "8.56.0",
+ "eslint-visitor-keys": "^5.0.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.0.tgz",
+ "integrity": "sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==",
+ "dev": true,
+ "engines": {
+ "node": "^20.19.0 || ^22.13.0 || >=24"
+ },
+ "funding": {
+ "url": "https://opencollective.com/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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@visulima/boxen": {
+ "version": "2.0.10",
+ "resolved": "https://registry.npmjs.org/@visulima/boxen/-/boxen-2.0.10.tgz",
+ "integrity": "sha512-ljghUzl32eUxIixARh8HBBJ2SXz2mJoD7C7Tl9/AEerN/PNihq1PMkzX/QPvMYOXpKrwoPt8ISNOc2EUacX5Wg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/prisis"
+ },
+ {
+ "type": "consulting",
+ "url": "https://anolilab.com/support"
+ }
+ ],
+ "os": [
+ "darwin",
+ "linux",
+ "win32"
+ ],
+ "engines": {
+ "node": ">=20.18 <=25.x"
+ }
+ },
+ "node_modules/@zag-js/accordion": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/accordion/-/accordion-1.33.1.tgz",
+ "integrity": "sha512-D80BZxceCIrxaXCi4CWDIzrCNJtojTGysD23C8FOxEGm9pQVuF7NvIdes7lbfUvwlZypMUUvhVlh8kKXN9uyeQ==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/anatomy": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/anatomy/-/anatomy-1.33.1.tgz",
+ "integrity": "sha512-iME14VHGGEPNMakilI6qvEkv9sll4AFZHpeoMLpczesw5hmqQjjNRifDTPR+idqCb8O8PdkAPE9hyMeP+4JjtA=="
+ },
+ "node_modules/@zag-js/angle-slider": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/angle-slider/-/angle-slider-1.33.1.tgz",
+ "integrity": "sha512-Y44IND5koNWD/EMKEWJbuEnzNW9y1WsrQFFvKRsMp/m3n60hiLa8qtZHoZWm8eOZCKFlsjVJ0gueEuZp43nobA==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/rect-utils": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/aria-hidden": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/aria-hidden/-/aria-hidden-1.33.1.tgz",
+ "integrity": "sha512-TpRAtssDHVfra5qxigk7w1NMf/crKu615INu6GAbNNMUBWD1rPZAfxdg/xe/BAcxLy+XM5/q62dVSNvpjXzN3g==",
+ "dependencies": {
+ "@zag-js/dom-query": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/async-list": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/async-list/-/async-list-1.33.1.tgz",
+ "integrity": "sha512-K0OFoN9hKjM5y029kRi52sjiAct1Wl3dbcZShXZypET/Y2rGv4q9ghasuU8jyX2oAoRwBtofwQgg8nrcoxBLFg==",
+ "dependencies": {
+ "@zag-js/core": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/auto-resize": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/auto-resize/-/auto-resize-1.33.1.tgz",
+ "integrity": "sha512-ci+hotx5/1zig1+Z2ljNBZEQ1OWhd6MV/E/X7suXmzK3lfvMb+g4OX2FjkuGqumwZyStrg4kh/ZJ+7Bj1CxRsw==",
+ "dependencies": {
+ "@zag-js/dom-query": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/avatar": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/avatar/-/avatar-1.33.1.tgz",
+ "integrity": "sha512-D8HBPvIVLoty14CDx6wWfdfcalr/pf2FgJ0N7VTgExvZt8t64JWJarL75ZkIB3ROaNe4RMFdzabz1uc7BlcDyg==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/bottom-sheet": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/bottom-sheet/-/bottom-sheet-1.33.1.tgz",
+ "integrity": "sha512-yWTAgbbb7N2B6epoq/Jpkaix8qNJz6OLZ6jDaHuZDnrEoM/LzQTHA77LQbjcWulmggBwX9IKPm1xeqFWXiHmeQ==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/aria-hidden": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dismissable": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/focus-trap": "1.33.1",
+ "@zag-js/remove-scroll": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/carousel": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/carousel/-/carousel-1.33.1.tgz",
+ "integrity": "sha512-FB72jCHhTTn0gXsWwDT/DrGMpBHQTxlKvwjEiBGkcprWVpptN0WGJR+EtX2Si/668sdH/471rew2DKA+h5k6Tw==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/scroll-snap": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/checkbox": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/checkbox/-/checkbox-1.33.1.tgz",
+ "integrity": "sha512-3rIPXB3O7hZukyjKpRAOn+Ob7jByBmDNU7wdpS2HRv7Urv9i5jUExlwayevw/a6JHQaT7mR1dL4culTyX+fJVA==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/focus-visible": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/clipboard": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/clipboard/-/clipboard-1.33.1.tgz",
+ "integrity": "sha512-BcuHY3h7fOgR8yX0JHHN/SIAfZOGwrMF1AXKpqeY9Xq2R0lbDMEyXBwT7rQtQUBWCkoSau1e3Nk8ey1yOsWmYw==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/collapsible": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/collapsible/-/collapsible-1.33.1.tgz",
+ "integrity": "sha512-FnEaoIufmYM4kFUET6gusFD7J5cAu/PY78BQ4BqhT3I6sS9FWiu/eHCCsFf/6BqhtqtiCQoki/O5g0arZqOZfw==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/collection": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/collection/-/collection-1.33.1.tgz",
+ "integrity": "sha512-4Js8oWS0C1zETlQzqJRny63uV/e54R6OerHfJfH9qAzkZuQnhMqZOAA4q6N+5GG6vb8WGB3927jS1A+Zn/pZuQ==",
+ "dependencies": {
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/color-picker": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/color-picker/-/color-picker-1.33.1.tgz",
+ "integrity": "sha512-PjssCiirvGssPPSoCqeAjK8Brh32K29I2eWck6LAK9IL7FMCpUyXKbSJNjtHeDGK60rzI/xNj8aeQgVmaBJ0Xg==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/color-utils": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dismissable": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/popper": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/color-utils": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/color-utils/-/color-utils-1.33.1.tgz",
+ "integrity": "sha512-YJIBn24IE5LcjKUVK8ndm3VY7ferdlJrl1J02s0uDtBbWywQ4TpufVZQ9aEONeazfCJC4/3etaQCiX9RSpW2uA==",
+ "dependencies": {
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/combobox": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/combobox/-/combobox-1.33.1.tgz",
+ "integrity": "sha512-9K2i5P+zf6T9Cqa9idzYXvEC/If5gDDbQWYgqflO18ptB0dTvfKkihBsA4/PEig3Ayvj/UGFTlFlbC17M5aACQ==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/aria-hidden": "1.33.1",
+ "@zag-js/collection": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dismissable": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/popper": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/core": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/core/-/core-1.33.1.tgz",
+ "integrity": "sha512-8hnw0/CFTytcYiIRij4Orpni2a79NSiH6Em+58A9AqMJGX8UE1zh6GsLWgrKQPiEiC8Cf3WgNXgCddJKpm8/Yw==",
+ "dependencies": {
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/date-picker": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/date-picker/-/date-picker-1.33.1.tgz",
+ "integrity": "sha512-PfVvttb83DosW9p9BXRAkNsk/duueicd7sEVdOGfgfIs3QJeVn+jvuli8Z2A0oQCok3VCfBwXd+MiwKjyLRpIg==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/date-utils": "1.33.1",
+ "@zag-js/dismissable": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/live-region": "1.33.1",
+ "@zag-js/popper": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ },
+ "peerDependencies": {
+ "@internationalized/date": ">=3.0.0"
+ }
+ },
+ "node_modules/@zag-js/date-utils": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/date-utils/-/date-utils-1.33.1.tgz",
+ "integrity": "sha512-hnM/IJ4jBHHCcVNfZyjvAI/0suW6c2XFYwcjM6xoGyG4P1x7YU9H9vuhp8mv7XDj4qqQFS/x8+UEcytZG9wtAg==",
+ "peerDependencies": {
+ "@internationalized/date": ">=3.0.0"
+ }
+ },
+ "node_modules/@zag-js/dialog": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/dialog/-/dialog-1.33.1.tgz",
+ "integrity": "sha512-OUjcIby0VSFBULpakDQJL+gtpVR13hvMZDydUm44LF5ygfoe5E7mfp24Q09VGgvbofOZTuwAK5xKTV/AaSX/MQ==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/aria-hidden": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dismissable": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/focus-trap": "1.33.1",
+ "@zag-js/remove-scroll": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/dismissable": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/dismissable/-/dismissable-1.33.1.tgz",
+ "integrity": "sha512-ZER2LFMTdhQxkIMuT3EMg6vZCjVjttDJJP8g6d7kSARcxN75myUG+H8qZqj9JbH5WSF6Xaf++O+LMUgwzIeixw==",
+ "dependencies": {
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/interact-outside": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/dom-query": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/dom-query/-/dom-query-1.33.1.tgz",
+ "integrity": "sha512-Iyl0D3nLvJuMkkuRy22xhj4pkzexUCDlRpCzqIrOMDKsmFka/WV9PIclZKVpMECTi9dEQmJuGTjBVaCOReLu+Q==",
+ "dependencies": {
+ "@zag-js/types": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/editable": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/editable/-/editable-1.33.1.tgz",
+ "integrity": "sha512-uLLwopl5naET76ND+/GZDVMlXaAIwepAhmfNA+Esj4Upgtd3lpD5SNzJiVuyzZ0ewVyp2cuXHHAfNiibhkoFlA==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/interact-outside": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/file-upload": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/file-upload/-/file-upload-1.33.1.tgz",
+ "integrity": "sha512-+1jRkJLUZZYVqZJkDOa5bGosFUM6wU6+i12GavbkVgu5QHRc7VEYlPSlX/qmDxrErI9yC/ZWtoVEVFZ8N6DW0g==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/file-utils": "1.33.1",
+ "@zag-js/i18n-utils": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/file-utils": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/file-utils/-/file-utils-1.33.1.tgz",
+ "integrity": "sha512-x2Vw5JrUElidDSd34x+gydxjkyy3nU6KSr3rSez231MyScj8RtoLCH1BkCLsW86Yc+Mynp8pbHLdjC++AUtKZA==",
+ "dependencies": {
+ "@zag-js/i18n-utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/floating-panel": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/floating-panel/-/floating-panel-1.33.1.tgz",
+ "integrity": "sha512-MKtFyC3xxCUmHEnugR+KMcVIX7FdHsoZfDxcKc74h+2M6FAmk6YB8lByoY9pkCR9ems/5DkHcMU9cVVJ9kiFqA==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/popper": "1.33.1",
+ "@zag-js/rect-utils": "1.33.1",
+ "@zag-js/store": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/focus-trap": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/focus-trap/-/focus-trap-1.33.1.tgz",
+ "integrity": "sha512-aX1YpER7dsegKroNGMnBDfcS14Z9LTdwESSXFDc9C9jFo45qOzfhxmXR+a5rsveMRkvhMFxGffrbpwfvZbRs0A==",
+ "dependencies": {
+ "@zag-js/dom-query": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/focus-visible": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/focus-visible/-/focus-visible-1.33.1.tgz",
+ "integrity": "sha512-xnk2BwO6jYuudj4jMzNYD4AxgaD2sqnLHkwmHImOnVa5frbYziGzevo9iJWC+2THyqQjUXLQ6Zfo6J/Hi3KyNQ==",
+ "dependencies": {
+ "@zag-js/dom-query": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/highlight-word": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/highlight-word/-/highlight-word-1.33.1.tgz",
+ "integrity": "sha512-row6yPiADeraQFDvoiwuXP0F0qTt7gGnwdeWEcoaqGj27DYZSZKXXK03mQWMo6sdi+VU6z79ZqrlE6bnk6fqWQ=="
+ },
+ "node_modules/@zag-js/hover-card": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/hover-card/-/hover-card-1.33.1.tgz",
+ "integrity": "sha512-8f4J0UWqcnEtM5uXtF8a7WbLwo4ornXpHYEPubSLJYFKWsgaPlNtVVX8WNxB9uFFQEB111RfuQSoUrqMlRQ7xw==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dismissable": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/popper": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/i18n-utils": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/i18n-utils/-/i18n-utils-1.33.1.tgz",
+ "integrity": "sha512-7frklMwgbD7YjJqxt9nWhFMxFzrqQyPPu+r8u1hEWHwjD9GZPteHIYIyEKKmpYVQqANMpTEoIZi+oUI8YT+OhQ==",
+ "dependencies": {
+ "@zag-js/dom-query": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/image-cropper": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/image-cropper/-/image-cropper-1.33.1.tgz",
+ "integrity": "sha512-/P+IZapbSvZw7Yudmxll2Pd8/3x6sOebeQW/LghuWUbDi1ilYCjCpsuhlhZrD3NFfiZ+QZfX1+8ofLOiax1g4A==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/interact-outside": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/interact-outside/-/interact-outside-1.33.1.tgz",
+ "integrity": "sha512-XnqwYsGw0GVmjBpDziwWXKE/+KeZLgRnjEpyVr6HMATMGD+c4j6TmIbI9OGEaWliLuwvHdTclkmK4WYTaAGmiw==",
+ "dependencies": {
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/json-tree-utils": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/json-tree-utils/-/json-tree-utils-1.33.1.tgz",
+ "integrity": "sha512-+t42cJY3QJirlXQHDyZmJMdWVoWlAXGUJ3vuGoUBNoHNq+rAte6i/1+VMq/KkNEh/8QehA/4FdtQAstSMVbAEQ=="
+ },
+ "node_modules/@zag-js/listbox": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/listbox/-/listbox-1.33.1.tgz",
+ "integrity": "sha512-8XT+6T82xG3BJwC7VYu/I1W8Hxyjgpke8tB1odQSWOV23pVXXPbol7wQbtoieSVeNDsZD8K12CpB40oRVrcSHA==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/collection": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/focus-visible": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/live-region": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/live-region/-/live-region-1.33.1.tgz",
+ "integrity": "sha512-KbU2wUSMd01fY7dgc9WhvU2x07FxNHKSCrn+fFUnB+Qoy6iiVv0A729JDbzPUUcpBV0BFoQ3qNdBDVyBalbpaQ=="
+ },
+ "node_modules/@zag-js/marquee": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/marquee/-/marquee-1.33.1.tgz",
+ "integrity": "sha512-u5tITcDMZ+L16LKJhIEHzpenxNFosq5BzwUqcF7FD5syEhbA3Jopnq+mWR5CMUaFlbYhRGMSJ1ySNyNwuxU81g==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/menu": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/menu/-/menu-1.33.1.tgz",
+ "integrity": "sha512-QihwaFCgGcrPbJSoP73nt749/rlUANiIrCU//8WWfQTgv0NBJprBD7d3banDNlK9ZSGmvELcpyQ/fKU4cfn0GQ==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dismissable": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/popper": "1.33.1",
+ "@zag-js/rect-utils": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/navigation-menu": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/navigation-menu/-/navigation-menu-1.33.1.tgz",
+ "integrity": "sha512-QnkK8Q7vEQtj7nc3fpzNLkjmtyxz1WGpwdDqpbiemxT8pZT3BxrSDC3n6795t9xhbOGVWjhyMfDw/3xBT/3JYA==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dismissable": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/number-input": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/number-input/-/number-input-1.33.1.tgz",
+ "integrity": "sha512-5YKr8uagIDGXp3hIqo4IUBGxS5WhH0xM1CQf2zimfDWvBOng+Y+MH/4Lwu9wKuyIq/J3SJqsjO+2OOF7u6ju/g==",
+ "dependencies": {
+ "@internationalized/number": "3.6.5",
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/pagination": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/pagination/-/pagination-1.33.1.tgz",
+ "integrity": "sha512-TZxxFEgvkz66Y3rX9ug5Vm1CPoN1PgmR9GuW21W7ob9xSWXC9ZQKwTaC1I6qO83dZqBzRK51Q9K1iCghIb3q/w==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/password-input": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/password-input/-/password-input-1.33.1.tgz",
+ "integrity": "sha512-pJrz50JhQLTfiatehATr40udJYggYmJ7V/7/dBKqthGpMwoaVV3bmtKFSenFGc2mMb5Rlf9KKqHO/dYB7jpNiA==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/pin-input": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/pin-input/-/pin-input-1.33.1.tgz",
+ "integrity": "sha512-q6/DRsIV6ZDKzkFmdzbcsVBm7+I7hMlrsLr/P/jH0/fYE5T9t+1m9ll5j7/5RHFJHQ1WajHpdt5ad5mfXMuxKA==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/popover": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/popover/-/popover-1.33.1.tgz",
+ "integrity": "sha512-layppQOtvKMuJKXlyAA6rW88KfxCilRNS2uZuhJFpPwgASqk5piDdp2G3DA9s0SNTMY8rcNmc197wkDCcGnDew==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/aria-hidden": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dismissable": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/focus-trap": "1.33.1",
+ "@zag-js/popper": "1.33.1",
+ "@zag-js/remove-scroll": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/popper": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/popper/-/popper-1.33.1.tgz",
+ "integrity": "sha512-DNKRh/SRXB2wcvVYK1wvcEufS4vfVXJOv23QUee761bTv4nrPNll5pZFsYEHatiCNkAmO0MRRYA2Sc6jk9nxNA==",
+ "dependencies": {
+ "@floating-ui/dom": "^1.7.5",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/presence": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/presence/-/presence-1.33.1.tgz",
+ "integrity": "sha512-IqrZa+djwkLQiANlp4nS6bq+FOtTYLZOOynJP9zz5+egNtA1qkmCdeBXA5/CgWM83sMmjJEDAe6nmp8darICyQ==",
+ "dependencies": {
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/progress": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/progress/-/progress-1.33.1.tgz",
+ "integrity": "sha512-Pp4h6ChcIOLKSloBBCOcPy9/C2r3YqrSbrcbY47IjZiDg6JPkivVPqScqM3wH8OpKEEyKyljBottZmbKkjQ3Zg==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/qr-code": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/qr-code/-/qr-code-1.33.1.tgz",
+ "integrity": "sha512-8Fc/TwlIkLQYfcvXhxCe+rTsmS+cHJpk/WRNMwKO1QvLZw2mBdNIt2pfoGJf8SdufBv5U3KyzCQ4T9iZ1CaYAQ==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1",
+ "proxy-memoize": "3.0.1",
+ "uqr": "0.1.2"
+ }
+ },
+ "node_modules/@zag-js/radio-group": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/radio-group/-/radio-group-1.33.1.tgz",
+ "integrity": "sha512-W/T8Hea3Z4mWCErm2fJc/EYabxRkKHFJStSClyllqknF3Y+b42MaKGuub1IcACO3pe6csLTkomdxy1qDLWl/dg==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/focus-visible": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/rating-group": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/rating-group/-/rating-group-1.33.1.tgz",
+ "integrity": "sha512-Bb6mv8GE9OpMA+tEwEuR1DOqP9P9ovkeyDaehfDy/hBDT90kCjl2RJ4aCsJINX5k2E+/AD2uv36HcSClqZKiYg==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/react": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/react/-/react-1.33.1.tgz",
+ "integrity": "sha512-TZ66zU99ixsPMWTKaGOF5u4sM9Ki25ZwuGbZXkz8K6mM28UZAt5o+bro6030XI2VLkP0W+VI9cHUFn6AXJPsHw==",
+ "dependencies": {
+ "@zag-js/core": "1.33.1",
+ "@zag-js/store": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ },
+ "peerDependencies": {
+ "react": ">=18.0.0",
+ "react-dom": ">=18.0.0"
+ }
+ },
+ "node_modules/@zag-js/rect-utils": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/rect-utils/-/rect-utils-1.33.1.tgz",
+ "integrity": "sha512-vCIgZF/z8oeYfUhGUgRiNEfOS8on4rUXi4vtL4IvHSdAv5VxZw4ODoLhIzRGT3BwsiMfr8qJ8fmrcR2oFRFQgA=="
+ },
+ "node_modules/@zag-js/remove-scroll": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/remove-scroll/-/remove-scroll-1.33.1.tgz",
+ "integrity": "sha512-5+Mvboqlmv8EdJoixAbGrftFVWZTznsVJn40BuB/6fYQeqdsZ2vFmSmSIr7btFOPcj3BcTMo0SbWNNta3fAOrg==",
+ "dependencies": {
+ "@zag-js/dom-query": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/scroll-area": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/scroll-area/-/scroll-area-1.33.1.tgz",
+ "integrity": "sha512-jJIDViQ3W1NCLNdB/Q4jfL/MnTG0BF5bEHGW5YxaigHMSXs41EVXT/aaNNwQZVlnR48NfHc9S8U9c/4fvIt3EQ==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/scroll-snap": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/scroll-snap/-/scroll-snap-1.33.1.tgz",
+ "integrity": "sha512-GLEb+YJj800ia2zyTFxVZomQ1cFSShazUQ/1uAxX0Lj7+aZK88cZhIn7AI0+yBXTPBS0zrZDhBPsGEDQX+Q9Fw==",
+ "dependencies": {
+ "@zag-js/dom-query": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/select": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/select/-/select-1.33.1.tgz",
+ "integrity": "sha512-eG+Ftdse0zvCAkXBMNZVBlM+KNvFRKHToxlxgid6wOd5QgRGwr4HaJuWaz908nBIZRYMFVvC+lLaygUVORHmGg==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/collection": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dismissable": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/popper": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/signature-pad": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/signature-pad/-/signature-pad-1.33.1.tgz",
+ "integrity": "sha512-bnTuG28F1A5Kdt+tsveBgNFhRG71vBBIoW8xVW+udph+9XhWfxsLC2j/O6QlnPgYEjOPUlG6/4wNT4LHzLQYUQ==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1",
+ "perfect-freehand": "^1.2.2"
+ }
+ },
+ "node_modules/@zag-js/slider": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/slider/-/slider-1.33.1.tgz",
+ "integrity": "sha512-tGbBiSHBXRa5y462QXVQ0YrluwlHsSCVdsInJAkQGkgBGZgikMPvYIHffmno1HVWYZlC/1hvRx7wq+PSfV/vXQ==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/splitter": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/splitter/-/splitter-1.33.1.tgz",
+ "integrity": "sha512-22mwXecfaflGoPivPj4+v2QwI9jdD5pMAgWO0CJUwDE397LtPShn8h8NHd6yTycg/Km25DyIy8wXQpX8oYtxPQ==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/steps": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/steps/-/steps-1.33.1.tgz",
+ "integrity": "sha512-Plo/TRi7lZFngFlJxJrqT4CSYQqdJExVSKa17RXe1lpKHjHBD7D1jHbuekUuPhurV0SS8vaU9iYTcuF1p0T39g==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/store": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/store/-/store-1.33.1.tgz",
+ "integrity": "sha512-FYkrR9IskD5wyKjYUAHWwdGf/C3FmnactfHR9/6dm9YzNO/+jtWxYsFnHQB8dUm9/6VxAZHofw3FbuyPRJ/x3g==",
+ "dependencies": {
+ "proxy-compare": "3.0.1"
+ }
+ },
+ "node_modules/@zag-js/switch": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/switch/-/switch-1.33.1.tgz",
+ "integrity": "sha512-2jl/R4CKLYvk+4cmSYFo3D2gQ+1ts9H7Y4yH98o9rXgPMvdEM9KMKX1FTqJRIY7v6ZkcNbvV/vKP3bDvMdTpug==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/focus-visible": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/tabs": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/tabs/-/tabs-1.33.1.tgz",
+ "integrity": "sha512-Xquhso7jUch9UrG5N+5vNfR8S2bWUk6EDpBBArY0X5oPSnlzgwJcjWh98hH1QyHX3JmWZN4kAfVKUxNdQxRnVw==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/tags-input": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/tags-input/-/tags-input-1.33.1.tgz",
+ "integrity": "sha512-PRRZlVBETX72e8GLg431A/CPr0Vf2dbGAq1ES8Z+3ltQurDCQaq6FQWgSXgNr3Iy+S2h+eSwKPIV7PMpjl1MCg==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/auto-resize": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/interact-outside": "1.33.1",
+ "@zag-js/live-region": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/timer": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/timer/-/timer-1.33.1.tgz",
+ "integrity": "sha512-GgqntefAEQbf66aNgA6NL9Rtrrxcd0/IJVddTj1/xihCnJ8u6AOU4syG5tie0Tpc2caDAntOwlYjpEy3n2AGcA==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/toast": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/toast/-/toast-1.33.1.tgz",
+ "integrity": "sha512-kI2/VJcBQGgHpmuWiIDqPn8ejFEODh5YhjWbnvjGRG+x3XoPuMq6hhxXV6VWJslbZJtTmzxDcP+Xamdrf1hbZA==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dismissable": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/toggle": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/toggle/-/toggle-1.33.1.tgz",
+ "integrity": "sha512-bmHNxuW3GVclvFTqcuLJYbEuqs6v3Sf0d2b3daOvGMZL1FwyL0zEAdo5Pui2hthe7QTaH7MJQIF8yPQ4vhLprg==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/toggle-group": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/toggle-group/-/toggle-group-1.33.1.tgz",
+ "integrity": "sha512-KZaMFN5u26d8elAcdu6LDC7byltpzeoemXHMMa7H/1upS3/98ESKUzx1VlA5SSTAinU4t9+rXoR3VTtP2RJbTw==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/tooltip": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/tooltip/-/tooltip-1.33.1.tgz",
+ "integrity": "sha512-2CmOMp8qvdTYLE1kgZKnE5RiObzpjJcfVdYYRgVqyIli20AAsOxyahE7WlgLwUGjqpzezah+Z20ZOir6x4jsnQ==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/focus-visible": "1.33.1",
+ "@zag-js/popper": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/tour": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/tour/-/tour-1.33.1.tgz",
+ "integrity": "sha512-eRZD4nePguquNkyrlMzpJr7XxXTVTm3Rxw0p5n1qwQYp3urCYIwupZcWXei1OtiYXenqIdbYMBfNtQRev0x1Ig==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dismissable": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/focus-trap": "1.33.1",
+ "@zag-js/interact-outside": "1.33.1",
+ "@zag-js/popper": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/tree-view": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/tree-view/-/tree-view-1.33.1.tgz",
+ "integrity": "sha512-5SiwSGdcqiGoCQl46pvEAgGkM5gTsPpLLPXB2Eqfojm2fm2oev73+1gWsZt1/sX/qsIQ1hH3a2h44rXW1W2IWg==",
+ "dependencies": {
+ "@zag-js/anatomy": "1.33.1",
+ "@zag-js/collection": "1.33.1",
+ "@zag-js/core": "1.33.1",
+ "@zag-js/dom-query": "1.33.1",
+ "@zag-js/types": "1.33.1",
+ "@zag-js/utils": "1.33.1"
+ }
+ },
+ "node_modules/@zag-js/types": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/types/-/types-1.33.1.tgz",
+ "integrity": "sha512-huJdwaeyptKDuZqhhFQRWNiMAJEdei4fTAQ3xIBw07GW27zKwust4Bn0y+8PYlnVVQn2auH4lpIXXwPccFRclQ==",
+ "dependencies": {
+ "csstype": "3.2.3"
+ }
+ },
+ "node_modules/@zag-js/utils": {
+ "version": "1.33.1",
+ "resolved": "https://registry.npmjs.org/@zag-js/utils/-/utils-1.33.1.tgz",
+ "integrity": "sha512-N73enDcveuto5BdYd15m7bu08vd+Re//eufgzGyKPWuzFowEFV77si1v9zZjmK9eXVMTFyde/TPal3aHv4VEJg=="
+ },
+ "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,
+ "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,
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
+ "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
+ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/aos": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/aos/-/aos-2.3.4.tgz",
+ "integrity": "sha512-zh/ahtR2yME4I51z8IttIt4lC1Nw0ktsFtmeDzID1m9naJnWXhCoARaCgNOGXb5CLy3zm+wqmRAEgMYB5E2HUw==",
+ "dependencies": {
+ "classlist-polyfill": "^1.0.3",
+ "lodash.debounce": "^4.0.6",
+ "lodash.throttle": "^4.0.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
+ },
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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": {
+ "version": "0.16.1",
+ "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz",
+ "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==",
+ "dev": true,
+ "dependencies": {
+ "tslib": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "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
+ },
+ "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,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+ },
+ "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,
+ "dependencies": {
+ "possible-typed-array-names": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/axe-core": {
+ "version": "4.11.1",
+ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.1.tgz",
+ "integrity": "sha512-BASOg+YwO2C+346x3LZOeoovTIoTrRqEsqMa6fmfAV0P+U9mFr9NsyOEpiYvFjbc64NMrSswhV50WdXzdb/Z5A==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/axios": {
+ "version": "1.13.5",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz",
+ "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==",
+ "dependencies": {
+ "follow-redirects": "^1.15.11",
+ "form-data": "^4.0.5",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "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,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/babel-plugin-macros": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
+ "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==",
+ "dependencies": {
+ "@babel/runtime": "^7.12.5",
+ "cosmiconfig": "^7.0.0",
+ "resolve": "^1.19.0"
+ },
+ "engines": {
+ "node": ">=10",
+ "npm": ">=6"
+ }
+ },
+ "node_modules/babel-plugin-react-compiler": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-react-compiler/-/babel-plugin-react-compiler-1.0.0.tgz",
+ "integrity": "sha512-Ixm8tFfoKKIPYdCCKYTsqv+Fd4IJ0DQqMyEimo+pxUOMUR9cVPlwTrFt9Avu+3cb6Zp3mAzl+t1MrG2fxxKsxw==",
+ "devOptional": true,
+ "dependencies": {
+ "@babel/types": "^7.26.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/baseline-browser-mapping": {
+ "version": "2.9.19",
+ "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz",
+ "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==",
+ "dev": true,
+ "bin": {
+ "baseline-browser-mapping": "dist/cli.js"
+ }
+ },
+ "node_modules/bignumber.js": {
+ "version": "9.3.1",
+ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz",
+ "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "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,
+ "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,
+ "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"
+ }
+ ],
+ "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/buffer-equal-constant-time": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+ "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
+ },
+ "node_modules/bundle-n-require": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/bundle-n-require/-/bundle-n-require-1.1.2.tgz",
+ "integrity": "sha512-bEk2jakVK1ytnZ9R2AAiZEeK/GxPUM8jvcRxHZXifZDMcjkI4EG/GlsJ2YGSVYT9y/p/gA9/0yDY8rCGsSU6Tg==",
+ "dev": true,
+ "dependencies": {
+ "esbuild": "^0.25.1",
+ "node-eval": "^2.0.0"
+ }
+ },
+ "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,
+ "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==",
+ "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,
+ "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==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001770",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001770.tgz",
+ "integrity": "sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==",
+ "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"
+ }
+ ]
+ },
+ "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,
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz",
+ "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==",
+ "dev": true,
+ "dependencies": {
+ "readdirp": "^5.0.0"
+ },
+ "engines": {
+ "node": ">= 20.19.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/classlist-polyfill": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/classlist-polyfill/-/classlist-polyfill-1.2.0.tgz",
+ "integrity": "sha512-GzIjNdcEtH4ieA2S8NmrSxv7DfEV5fmixQeyTmqmRmRJPGpRBaSnA2a0VrCjyT8iW8JjEdMbKzDotAJf+ajgaQ=="
+ },
+ "node_modules/cli-table": {
+ "version": "0.3.11",
+ "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.11.tgz",
+ "integrity": "sha512-IqLQi4lO0nIB4tcdTpN4LCB9FI3uqrJZK7RC515EnhZ6qBaglkIgICb1wjeAqpdoOabm1+SuQtkXIPdYC93jhQ==",
+ "dev": true,
+ "dependencies": {
+ "colors": "1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.2.0"
+ }
+ },
+ "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=="
+ },
+ "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==",
+ "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=="
+ },
+ "node_modules/colors": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
+ "integrity": "sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.1.90"
+ }
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/commander": {
+ "version": "14.0.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz",
+ "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==",
+ "dev": true,
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "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
+ },
+ "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
+ },
+ "node_modules/cookie": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
+ "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cosmiconfig": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
+ "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
+ "dependencies": {
+ "@types/parse-json": "^4.0.0",
+ "import-fresh": "^3.2.1",
+ "parse-json": "^5.0.0",
+ "path-type": "^4.0.0",
+ "yaml": "^1.10.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/cross-env": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.1.0.tgz",
+ "integrity": "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@epic-web/invariant": "^1.0.0",
+ "cross-spawn": "^7.0.6"
+ },
+ "bin": {
+ "cross-env": "dist/bin/cross-env.js",
+ "cross-env-shell": "dist/bin/cross-env-shell.js"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "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=="
+ },
+ "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
+ },
+ "node_modules/data-uri-to-buffer": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
+ "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "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,
+ "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,
+ "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,
+ "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==",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/decimal.js": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz",
+ "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg=="
+ },
+ "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
+ },
+ "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,
+ "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,
+ "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/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "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==",
+ "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,
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/dotenv": {
+ "version": "17.3.1",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.3.1.tgz",
+ "integrity": "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
+ "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==",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
+ },
+ "node_modules/ecdsa-sig-formatter": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+ "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.286",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz",
+ "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==",
+ "dev": true
+ },
+ "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=="
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz",
+ "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==",
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/es-abstract": {
+ "version": "1.24.1",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz",
+ "integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==",
+ "dev": true,
+ "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==",
+ "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==",
+ "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,
+ "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==",
+ "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==",
+ "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,
+ "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,
+ "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/esbuild": {
+ "version": "0.25.12",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz",
+ "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==",
+ "dev": true,
+ "hasInstallScript": true,
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.25.12",
+ "@esbuild/android-arm": "0.25.12",
+ "@esbuild/android-arm64": "0.25.12",
+ "@esbuild/android-x64": "0.25.12",
+ "@esbuild/darwin-arm64": "0.25.12",
+ "@esbuild/darwin-x64": "0.25.12",
+ "@esbuild/freebsd-arm64": "0.25.12",
+ "@esbuild/freebsd-x64": "0.25.12",
+ "@esbuild/linux-arm": "0.25.12",
+ "@esbuild/linux-arm64": "0.25.12",
+ "@esbuild/linux-ia32": "0.25.12",
+ "@esbuild/linux-loong64": "0.25.12",
+ "@esbuild/linux-mips64el": "0.25.12",
+ "@esbuild/linux-ppc64": "0.25.12",
+ "@esbuild/linux-riscv64": "0.25.12",
+ "@esbuild/linux-s390x": "0.25.12",
+ "@esbuild/linux-x64": "0.25.12",
+ "@esbuild/netbsd-arm64": "0.25.12",
+ "@esbuild/netbsd-x64": "0.25.12",
+ "@esbuild/openbsd-arm64": "0.25.12",
+ "@esbuild/openbsd-x64": "0.25.12",
+ "@esbuild/openharmony-arm64": "0.25.12",
+ "@esbuild/sunos-x64": "0.25.12",
+ "@esbuild/win32-arm64": "0.25.12",
+ "@esbuild/win32-ia32": "0.25.12",
+ "@esbuild/win32-x64": "0.25.12"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "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==",
+ "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,
+ "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.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-16.0.0.tgz",
+ "integrity": "sha512-DWKT1YAO9ex2rK0/EeiPpKU++ghTiG59z6m08/ReLRECOYIaEv17maSCYT8zmFQLwIrY5lhJ+iaJPQdT4sJd4g==",
+ "dev": true,
+ "dependencies": {
+ "@next/eslint-plugin-next": "16.0.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,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint-config-prettier": {
+ "version": "10.1.8",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz",
+ "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==",
+ "dev": true,
+ "bin": {
+ "eslint-config-prettier": "bin/cli.js"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint-config-prettier"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.0.0"
+ }
+ },
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "dependencies": {
+ "@babel/core": "^7.24.4",
+ "@babel/parser": "^7.24.4",
+ "hermes-parser": "^0.25.1",
+ "zod": "^3.25.0 || ^4.0.0",
+ "zod-validation-error": "^3.5.0 || ^4.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-react/node_modules/resolve": {
+ "version": "2.0.0-next.6",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.6.tgz",
+ "integrity": "sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==",
+ "dev": true,
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "is-core-module": "^2.16.1",
+ "node-exports-info": "^1.6.0",
+ "object-keys": "^1.1.1",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
+ "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
+ "dev": true,
+ "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,
+ "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,
+ "dependencies": {
+ "acorn": "^8.15.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz",
+ "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==",
+ "dev": true,
+ "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,
+ "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,
+ "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,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+ },
+ "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
+ },
+ "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,
+ "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,
+ "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
+ },
+ "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
+ },
+ "node_modules/fastq": {
+ "version": "1.20.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
+ "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
+ "dev": true,
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fetch-blob": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
+ "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/jimmywarting"
+ },
+ {
+ "type": "paypal",
+ "url": "https://paypal.me/jimmywarting"
+ }
+ ],
+ "dependencies": {
+ "node-domexception": "^1.0.0",
+ "web-streams-polyfill": "^3.0.3"
+ },
+ "engines": {
+ "node": "^12.20 || >= 14.13"
+ }
+ },
+ "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,
+ "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,
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-root": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
+ "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="
+ },
+ "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,
+ "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,
+ "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
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.15.11",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
+ "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "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,
+ "dependencies": {
+ "is-callable": "^1.2.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/foreground-child": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
+ "dependencies": {
+ "cross-spawn": "^7.0.6",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
+ "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.2",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/formdata-polyfill": {
+ "version": "4.0.10",
+ "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
+ "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
+ "dependencies": {
+ "fetch-blob": "^3.1.2"
+ },
+ "engines": {
+ "node": ">=12.20.0"
+ }
+ },
+ "node_modules/framer-motion": {
+ "version": "12.34.1",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.34.1.tgz",
+ "integrity": "sha512-kcZyNaYQfvE2LlH6+AyOaJAQV4rGp5XbzfhsZpiSZcwDMfZUHhuxLWeyRzf5I7jip3qKRpuimPA9pXXfr111kQ==",
+ "dependencies": {
+ "motion-dom": "^12.34.1",
+ "motion-utils": "^12.29.2",
+ "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/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "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,
+ "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,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gaxios": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.3.tgz",
+ "integrity": "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==",
+ "dependencies": {
+ "extend": "^3.0.2",
+ "https-proxy-agent": "^7.0.1",
+ "node-fetch": "^3.3.2",
+ "rimraf": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/gcp-metadata": {
+ "version": "8.1.2",
+ "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz",
+ "integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==",
+ "dependencies": {
+ "gaxios": "^7.0.0",
+ "google-logging-utils": "^1.0.0",
+ "json-bigint": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "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,
+ "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,
+ "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==",
+ "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==",
+ "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,
+ "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.6",
+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.6.tgz",
+ "integrity": "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==",
+ "dev": true,
+ "dependencies": {
+ "resolve-pkg-maps": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+ }
+ },
+ "node_modules/glob": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
+ "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
+ "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/glob/node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/glob/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true,
+ "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,
+ "dependencies": {
+ "define-properties": "^1.2.1",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/globby": {
+ "version": "14.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz",
+ "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==",
+ "dev": true,
+ "dependencies": {
+ "@sindresorhus/merge-streams": "^2.1.0",
+ "fast-glob": "^3.3.3",
+ "ignore": "^7.0.3",
+ "path-type": "^6.0.0",
+ "slash": "^5.1.0",
+ "unicorn-magic": "^0.3.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globby/node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/globby/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,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/globby/node_modules/ignore": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
+ "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/globby/node_modules/path-type": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz",
+ "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/google-auth-library": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.5.0.tgz",
+ "integrity": "sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==",
+ "dependencies": {
+ "base64-js": "^1.3.0",
+ "ecdsa-sig-formatter": "^1.0.11",
+ "gaxios": "^7.0.0",
+ "gcp-metadata": "^8.0.0",
+ "google-logging-utils": "^1.0.0",
+ "gtoken": "^8.0.0",
+ "jws": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/google-logging-utils": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz",
+ "integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gtoken": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-8.0.0.tgz",
+ "integrity": "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==",
+ "dependencies": {
+ "gaxios": "^7.0.0",
+ "jws": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "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,
+ "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,
+ "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,
+ "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,
+ "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==",
+ "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==",
+ "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==",
+ "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
+ },
+ "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,
+ "dependencies": {
+ "hermes-estree": "0.25.1"
+ }
+ },
+ "node_modules/hoist-non-react-statics": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+ "dependencies": {
+ "react-is": "^16.7.0"
+ }
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/i18next": {
+ "version": "25.8.10",
+ "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.8.10.tgz",
+ "integrity": "sha512-CtPJLMAz1G8sxo+mIzfBjGgLxWs7d6WqIjlmmv9BTsOat4pJIfwZ8cm07n3kFS6bP9c6YwsYutYrwsEeJVBo2g==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://locize.com"
+ },
+ {
+ "type": "individual",
+ "url": "https://locize.com/i18next.html"
+ },
+ {
+ "type": "individual",
+ "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project"
+ }
+ ],
+ "dependencies": {
+ "@babel/runtime": "^7.28.4"
+ },
+ "peerDependencies": {
+ "typescript": "^5"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/icu-minify": {
+ "version": "4.8.3",
+ "resolved": "https://registry.npmjs.org/icu-minify/-/icu-minify-4.8.3.tgz",
+ "integrity": "sha512-65Av7FLosNk7bPbmQx5z5XG2Y3T2GFppcjiXh4z1idHeVgQxlDpAmkGoYI0eFzAvrOnjpWTL5FmPDhsdfRMPEA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/amannn"
+ }
+ ],
+ "dependencies": {
+ "@formatjs/icu-messageformat-parser": "^3.4.0"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "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==",
+ "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,
+ "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,
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "hasown": "^2.0.2",
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/intl-messageformat": {
+ "version": "11.1.2",
+ "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-11.1.2.tgz",
+ "integrity": "sha512-ucSrQmZGAxfiBHfBRXW/k7UC8MaGFlEj4Ry1tKiDcmgwQm1y3EDl40u+4VNHYomxJQMJi9NEI3riDRlth96jKg==",
+ "dependencies": {
+ "@formatjs/ecma402-abstract": "3.1.1",
+ "@formatjs/fast-memoize": "3.1.0",
+ "@formatjs/icu-messageformat-parser": "3.5.1",
+ "tslib": "^2.8.1"
+ }
+ },
+ "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,
+ "dependencies": {
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="
+ },
+ "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,
+ "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,
+ "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,
+ "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,
+ "dependencies": {
+ "semver": "^7.7.1"
+ }
+ },
+ "node_modules/is-bun-module/node_modules/semver": {
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
+ "dev": true,
+ "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,
+ "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==",
+ "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,
+ "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,
+ "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==",
+ "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,
+ "dependencies": {
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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,
+ "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==",
+ "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,
+ "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,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-network-error": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.0.tgz",
+ "integrity": "sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw==",
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
+ },
+ "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,
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.6",
+ "get-proto": "^1.0.0",
+ "has-symbols": "^1.1.0",
+ "set-function-name": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/jackspeak": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/jose": {
+ "version": "4.15.9",
+ "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.9.tgz",
+ "integrity": "sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==",
+ "funding": {
+ "url": "https://github.com/sponsors/panva"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+ },
+ "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,
+ "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==",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/json-bigint": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
+ "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
+ "dependencies": {
+ "bignumber.js": "^9.0.0"
+ }
+ },
+ "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
+ },
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
+ },
+ "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
+ },
+ "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
+ },
+ "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,
+ "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,
+ "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/jwa": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz",
+ "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==",
+ "dependencies": {
+ "buffer-equal-constant-time": "^1.0.1",
+ "ecdsa-sig-formatter": "1.0.11",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/jws": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz",
+ "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==",
+ "dependencies": {
+ "jwa": "^2.0.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "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,
+ "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
+ },
+ "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,
+ "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,
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
+ },
+ "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,
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash.debounce": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="
+ },
+ "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
+ },
+ "node_modules/lodash.throttle": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
+ "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="
+ },
+ "node_modules/long": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz",
+ "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="
+ },
+ "node_modules/look-it-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/look-it-up/-/look-it-up-2.1.0.tgz",
+ "integrity": "sha512-nMoGWW2HurtuJf6XAL56FWTDCWLOTSsanrgwOyaR5Y4e3zfG5N/0cU5xWZSEU3tBxhQugRbV1xL9jb+ug7yZww==",
+ "dev": true
+ },
+ "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==",
+ "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,
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "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==",
+ "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,
+ "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,
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.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,
+ "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,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/motion-dom": {
+ "version": "12.34.1",
+ "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.34.1.tgz",
+ "integrity": "sha512-SC7ZC5dRcGwku2g7EsPvI4q/EzHumUbqsDNumBmZTLFg+goBO5LTJvDu9MAxx+0mtX4IA78B2be/A3aRjY0jnw==",
+ "dependencies": {
+ "motion-utils": "^12.29.2"
+ }
+ },
+ "node_modules/motion-utils": {
+ "version": "12.29.2",
+ "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.29.2.tgz",
+ "integrity": "sha512-G3kc34H2cX2gI63RqU+cZq+zWRRPSsNIOjpdl9TN4AQwC4sgwYPl/Q/Obf/d53nOm569T0fYK+tcoSV50BWx8A=="
+ },
+ "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=="
+ },
+ "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"
+ }
+ ],
+ "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,
+ "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
+ },
+ "node_modules/negotiator": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
+ "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/next": {
+ "version": "16.0.0",
+ "resolved": "https://registry.npmjs.org/next/-/next-16.0.0.tgz",
+ "integrity": "sha512-nYohiNdxGu4OmBzggxy9rczmjIGI+TpR5vbKTsE1HqYwNm1B+YSiugSrFguX6omMOKnDHAmBPY4+8TNJk0Idyg==",
+ "deprecated": "This version has a security vulnerability. Please upgrade to a patched version. See https://nextjs.org/blog/CVE-2025-66478 for more details.",
+ "dependencies": {
+ "@next/env": "16.0.0",
+ "@swc/helpers": "0.5.15",
+ "caniuse-lite": "^1.0.30001579",
+ "postcss": "8.4.31",
+ "styled-jsx": "5.1.6"
+ },
+ "bin": {
+ "next": "dist/bin/next"
+ },
+ "engines": {
+ "node": ">=20.9.0"
+ },
+ "optionalDependencies": {
+ "@next/swc-darwin-arm64": "16.0.0",
+ "@next/swc-darwin-x64": "16.0.0",
+ "@next/swc-linux-arm64-gnu": "16.0.0",
+ "@next/swc-linux-arm64-musl": "16.0.0",
+ "@next/swc-linux-x64-gnu": "16.0.0",
+ "@next/swc-linux-x64-musl": "16.0.0",
+ "@next/swc-win32-arm64-msvc": "16.0.0",
+ "@next/swc-win32-x64-msvc": "16.0.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/next-auth": {
+ "version": "4.24.13",
+ "resolved": "https://registry.npmjs.org/next-auth/-/next-auth-4.24.13.tgz",
+ "integrity": "sha512-sgObCfcfL7BzIK76SS5TnQtc3yo2Oifp/yIpfv6fMfeBOiBJkDWF3A2y9+yqnmJ4JKc2C+nMjSjmgDeTwgN1rQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.20.13",
+ "@panva/hkdf": "^1.0.2",
+ "cookie": "^0.7.0",
+ "jose": "^4.15.5",
+ "oauth": "^0.9.15",
+ "openid-client": "^5.4.0",
+ "preact": "^10.6.3",
+ "preact-render-to-string": "^5.1.19",
+ "uuid": "^8.3.2"
+ },
+ "peerDependencies": {
+ "@auth/core": "0.34.3",
+ "next": "^12.2.5 || ^13 || ^14 || ^15 || ^16",
+ "nodemailer": "^7.0.7",
+ "react": "^17.0.2 || ^18 || ^19",
+ "react-dom": "^17.0.2 || ^18 || ^19"
+ },
+ "peerDependenciesMeta": {
+ "@auth/core": {
+ "optional": true
+ },
+ "nodemailer": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/next-intl": {
+ "version": "4.8.3",
+ "resolved": "https://registry.npmjs.org/next-intl/-/next-intl-4.8.3.tgz",
+ "integrity": "sha512-PvdBDWg+Leh7BR7GJUQbCDVVaBRn37GwDBWc9sv0rVQOJDQ5JU1rVzx9EEGuOGYo0DHAl70++9LQ7HxTawdL7w==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/amannn"
+ }
+ ],
+ "dependencies": {
+ "@formatjs/intl-localematcher": "^0.8.1",
+ "@parcel/watcher": "^2.4.1",
+ "@swc/core": "^1.15.2",
+ "icu-minify": "^4.8.3",
+ "negotiator": "^1.0.0",
+ "next-intl-swc-plugin-extractor": "^4.8.3",
+ "po-parser": "^2.1.1",
+ "use-intl": "^4.8.3"
+ },
+ "peerDependencies": {
+ "next": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0",
+ "typescript": "^5.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/next-intl-swc-plugin-extractor": {
+ "version": "4.8.3",
+ "resolved": "https://registry.npmjs.org/next-intl-swc-plugin-extractor/-/next-intl-swc-plugin-extractor-4.8.3.tgz",
+ "integrity": "sha512-YcaT+R9z69XkGhpDarVFWUprrCMbxgIQYPUaXoE6LGVnLjGdo8hu3gL6bramDVjNKViYY8a/pXPy7Bna0mXORg=="
+ },
+ "node_modules/next-themes": {
+ "version": "0.4.6",
+ "resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.4.6.tgz",
+ "integrity": "sha512-pZvgD5L0IEvX5/9GWyHMf3m8BKiVQwsCMHfoFosXtXBMnaS0ZnIJ9ST4b4NqLVKDEm8QBxoNNGNaBv2JNF6XNA==",
+ "peerDependencies": {
+ "react": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc"
+ }
+ },
+ "node_modules/next/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==",
+ "dependencies": {
+ "tslib": "^2.8.0"
+ }
+ },
+ "node_modules/nextjs-toploader": {
+ "version": "3.9.17",
+ "resolved": "https://registry.npmjs.org/nextjs-toploader/-/nextjs-toploader-3.9.17.tgz",
+ "integrity": "sha512-9OF0KSSLtoSAuNg2LZ3aTl4hR9mBDj5L9s9DZiFCbMlXehyICGjkIz5dVGzuATU2bheJZoBdFgq9w07AKSuQQw==",
+ "dependencies": {
+ "nprogress": "^0.2.0",
+ "prop-types": "^15.8.1"
+ },
+ "funding": {
+ "url": "https://buymeacoffee.com/thesgj"
+ },
+ "peerDependencies": {
+ "next": ">= 6.0.0",
+ "react": ">= 16.0.0",
+ "react-dom": ">= 16.0.0"
+ }
+ },
+ "node_modules/node-addon-api": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
+ "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="
+ },
+ "node_modules/node-domexception": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
+ "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
+ "deprecated": "Use your platform's native DOMException instead",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/jimmywarting"
+ },
+ {
+ "type": "github",
+ "url": "https://paypal.me/jimmywarting"
+ }
+ ],
+ "engines": {
+ "node": ">=10.5.0"
+ }
+ },
+ "node_modules/node-eval": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/node-eval/-/node-eval-2.0.0.tgz",
+ "integrity": "sha512-Ap+L9HznXAVeJj3TJ1op6M6bg5xtTq8L5CU/PJxtkhea/DrIxdTknGKIECKd/v/Lgql95iuMAYvIzBNd0pmcMg==",
+ "dev": true,
+ "dependencies": {
+ "path-is-absolute": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/node-exports-info": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.0.tgz",
+ "integrity": "sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==",
+ "dev": true,
+ "dependencies": {
+ "array.prototype.flatmap": "^1.3.3",
+ "es-errors": "^1.3.0",
+ "object.entries": "^1.1.9",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/node-fetch": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
+ "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
+ "dependencies": {
+ "data-uri-to-buffer": "^4.0.0",
+ "fetch-blob": "^3.1.4",
+ "formdata-polyfill": "^4.0.10"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/node-fetch"
+ }
+ },
+ "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
+ },
+ "node_modules/nprogress": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz",
+ "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA=="
+ },
+ "node_modules/oauth": {
+ "version": "0.9.15",
+ "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz",
+ "integrity": "sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA=="
+ },
+ "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==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-hash": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz",
+ "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "dev": true,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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/oidc-token-hash": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/oidc-token-hash/-/oidc-token-hash-5.2.0.tgz",
+ "integrity": "sha512-6gj2m8cJZ+iSW8bm0FXdGF0YhIQbKrfP4yWTNzxc31U6MOjfEmB1rHvlYvxI1B7t7BCi1F2vYTT6YhtQRG4hxw==",
+ "engines": {
+ "node": "^10.13.0 || >=12.0.0"
+ }
+ },
+ "node_modules/openid-client": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/openid-client/-/openid-client-5.7.1.tgz",
+ "integrity": "sha512-jDBPgSVfTnkIh71Hg9pRvtJc6wTwqjRkN88+gCFtYWrlP4Yx2Dsrow8uPi3qLr/aeymPF3o2+dS+wOpglK04ew==",
+ "dependencies": {
+ "jose": "^4.15.9",
+ "lru-cache": "^6.0.0",
+ "object-hash": "^2.2.0",
+ "oidc-token-hash": "^5.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/panva"
+ }
+ },
+ "node_modules/openid-client/node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/openid-client/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ },
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dev": true,
+ "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,
+ "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,
+ "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,
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-retry": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-7.1.1.tgz",
+ "integrity": "sha512-J5ApzjyRkkf601HpEeykoiCvzHQjWxPAHhyjFcEUP2SWq0+35NKh8TLhpLw+Dkq5TZBFvUM6UigdE9hIVYTl5w==",
+ "dependencies": {
+ "is-network-error": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/package-json-from-dist": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="
+ },
+ "node_modules/package-manager-detector": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz",
+ "integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==",
+ "dev": true
+ },
+ "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==",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parse-json": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "dependencies": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/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,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "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=="
+ },
+ "node_modules/path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+ "dependencies": {
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/path-scurry/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/perfect-freehand": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/perfect-freehand/-/perfect-freehand-1.2.3.tgz",
+ "integrity": "sha512-bHZSfqDHGNlPpgH2yxXgPHlQSPpEbo+qg7li0M78J9vNAi2yjwLeA4x79BEQhX44lEWpCLSFCeRZwpw0niiXPA=="
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/po-parser": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/po-parser/-/po-parser-2.1.1.tgz",
+ "integrity": "sha512-ECF4zHLbUItpUgE3OTtLKlPjeBN+fKEczj2zYjDfCGOzicNs0GK3Vg2IoAYwx7LH/XYw43fZQP6xnZ4TkNxSLQ=="
+ },
+ "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,
+ "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"
+ }
+ ],
+ "dependencies": {
+ "nanoid": "^3.3.6",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/preact": {
+ "version": "10.28.3",
+ "resolved": "https://registry.npmjs.org/preact/-/preact-10.28.3.tgz",
+ "integrity": "sha512-tCmoRkPQLpBeWzpmbhryairGnhW9tKV6c6gr/w+RhoRoKEJwsjzipwp//1oCpGPOchvSLaAPlpcJi9MwMmoPyA==",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/preact"
+ }
+ },
+ "node_modules/preact-render-to-string": {
+ "version": "5.2.6",
+ "resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.6.tgz",
+ "integrity": "sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==",
+ "dependencies": {
+ "pretty-format": "^3.8.0"
+ },
+ "peerDependencies": {
+ "preact": ">=10"
+ }
+ },
+ "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,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz",
+ "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==",
+ "dev": true,
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/pretty-format": {
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz",
+ "integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew=="
+ },
+ "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==",
+ "dependencies": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.13.1"
+ }
+ },
+ "node_modules/property-expr": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz",
+ "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA=="
+ },
+ "node_modules/protobufjs": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz",
+ "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.2",
+ "@protobufjs/base64": "^1.1.2",
+ "@protobufjs/codegen": "^2.0.4",
+ "@protobufjs/eventemitter": "^1.1.0",
+ "@protobufjs/fetch": "^1.1.0",
+ "@protobufjs/float": "^1.0.2",
+ "@protobufjs/inquire": "^1.1.0",
+ "@protobufjs/path": "^1.1.2",
+ "@protobufjs/pool": "^1.1.0",
+ "@protobufjs/utf8": "^1.1.0",
+ "@types/node": ">=13.7.0",
+ "long": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/proxy-compare": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/proxy-compare/-/proxy-compare-3.0.1.tgz",
+ "integrity": "sha512-V9plBAt3qjMlS1+nC8771KNf6oJ12gExvaxnNzN/9yVRLdTv/lc+oJlnSzrdYDAvBfTStPCoiaCOTmTs0adv7Q=="
+ },
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+ },
+ "node_modules/proxy-memoize": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/proxy-memoize/-/proxy-memoize-3.0.1.tgz",
+ "integrity": "sha512-VDdG/VYtOgdGkWJx7y0o7p+zArSf2383Isci8C+BP3YXgMYDoPd3cCBjw0JdWb6YBb9sFiOPbAADDVTPJnh+9g==",
+ "dependencies": {
+ "proxy-compare": "^3.0.0"
+ }
+ },
+ "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,
+ "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"
+ }
+ ]
+ },
+ "node_modules/react": {
+ "version": "19.2.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz",
+ "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "19.2.0",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz",
+ "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==",
+ "dependencies": {
+ "scheduler": "^0.27.0"
+ },
+ "peerDependencies": {
+ "react": "^19.2.0"
+ }
+ },
+ "node_modules/react-hook-form": {
+ "version": "7.71.1",
+ "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.71.1.tgz",
+ "integrity": "sha512-9SUJKCGKo8HUSsCO+y0CtqkqI5nNuaDqTxyqPsZPqIwudpj4rCrAz/jZV+jn57bx5gtZKOh3neQu94DXMc+w5w==",
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/react-hook-form"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17 || ^18 || ^19"
+ }
+ },
+ "node_modules/react-icons": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz",
+ "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==",
+ "peerDependencies": {
+ "react": "*"
+ }
+ },
+ "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=="
+ },
+ "node_modules/readdirp": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz",
+ "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 20.19.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/recast": {
+ "version": "0.23.11",
+ "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.11.tgz",
+ "integrity": "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==",
+ "dev": true,
+ "dependencies": {
+ "ast-types": "^0.16.1",
+ "esprima": "~4.0.0",
+ "source-map": "~0.6.1",
+ "tiny-invariant": "^1.3.3",
+ "tslib": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/recast/node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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,
+ "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,
+ "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==",
+ "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==",
+ "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,
+ "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,
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "5.0.10",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz",
+ "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==",
+ "dependencies": {
+ "glob": "^10.3.7"
+ },
+ "bin": {
+ "rimraf": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "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"
+ }
+ ],
+ "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,
+ "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-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "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,
+ "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,
+ "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=="
+ },
+ "node_modules/scule": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/scule/-/scule-1.3.0.tgz",
+ "integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==",
+ "dev": true
+ },
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "optional": true,
+ "dependencies": {
+ "@img/colour": "^1.0.0",
+ "detect-libc": "^2.1.2",
+ "semver": "^7.7.3"
+ },
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-darwin-arm64": "0.34.5",
+ "@img/sharp-darwin-x64": "0.34.5",
+ "@img/sharp-libvips-darwin-arm64": "1.2.4",
+ "@img/sharp-libvips-darwin-x64": "1.2.4",
+ "@img/sharp-libvips-linux-arm": "1.2.4",
+ "@img/sharp-libvips-linux-arm64": "1.2.4",
+ "@img/sharp-libvips-linux-ppc64": "1.2.4",
+ "@img/sharp-libvips-linux-riscv64": "1.2.4",
+ "@img/sharp-libvips-linux-s390x": "1.2.4",
+ "@img/sharp-libvips-linux-x64": "1.2.4",
+ "@img/sharp-libvips-linuxmusl-arm64": "1.2.4",
+ "@img/sharp-libvips-linuxmusl-x64": "1.2.4",
+ "@img/sharp-linux-arm": "0.34.5",
+ "@img/sharp-linux-arm64": "0.34.5",
+ "@img/sharp-linux-ppc64": "0.34.5",
+ "@img/sharp-linux-riscv64": "0.34.5",
+ "@img/sharp-linux-s390x": "0.34.5",
+ "@img/sharp-linux-x64": "0.34.5",
+ "@img/sharp-linuxmusl-arm64": "0.34.5",
+ "@img/sharp-linuxmusl-x64": "0.34.5",
+ "@img/sharp-wasm32": "0.34.5",
+ "@img/sharp-win32-arm64": "0.34.5",
+ "@img/sharp-win32-ia32": "0.34.5",
+ "@img/sharp-win32-x64": "0.34.5"
+ }
+ },
+ "node_modules/sharp/node_modules/semver": {
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
+ "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==",
+ "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==",
+ "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,
+ "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,
+ "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,
+ "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,
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/sisteransi": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
+ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
+ "dev": true
+ },
+ "node_modules/slash": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz",
+ "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "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
+ },
+ "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,
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "internal-slot": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/string-width-cjs": {
+ "name": "string-width",
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+ },
+ "node_modules/string-width-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string.prototype.includes": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz",
+ "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==",
+ "dev": true,
+ "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,
+ "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,
+ "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,
+ "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,
+ "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,
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "define-properties": "^1.2.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz",
+ "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/strip-ansi-cjs": {
+ "name": "strip-ansi",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
+ "dev": true,
+ "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,
+ "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==",
+ "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/stylis": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz",
+ "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw=="
+ },
+ "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,
+ "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==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/tiny-case": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz",
+ "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q=="
+ },
+ "node_modules/tiny-invariant": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
+ "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==",
+ "dev": true
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.15",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
+ "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
+ "dev": true,
+ "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,
+ "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,
+ "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,
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/toposort": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz",
+ "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg=="
+ },
+ "node_modules/ts-api-utils": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz",
+ "integrity": "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==",
+ "dev": true,
+ "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,
+ "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,
+ "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=="
+ },
+ "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,
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
+ "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
+ "engines": {
+ "node": ">=12.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typed-array-buffer": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
+ "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
+ "dev": true,
+ "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,
+ "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,
+ "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,
+ "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==",
+ "devOptional": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/typescript-eslint": {
+ "version": "8.56.0",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.56.0.tgz",
+ "integrity": "sha512-c7toRLrotJ9oixgdW7liukZpsnq5CZ7PuKztubGYlNppuTqhIoWfhgHo/7EU0v06gS2l/x0i2NEFK1qMIf0rIg==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/eslint-plugin": "8.56.0",
+ "@typescript-eslint/parser": "8.56.0",
+ "@typescript-eslint/typescript-estree": "8.56.0",
+ "@typescript-eslint/utils": "8.56.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/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,
+ "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=="
+ },
+ "node_modules/unicorn-magic": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz",
+ "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "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,
+ "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"
+ }
+ ],
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/uqr": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/uqr/-/uqr-0.1.2.tgz",
+ "integrity": "sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA=="
+ },
+ "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,
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/use-intl": {
+ "version": "4.8.3",
+ "resolved": "https://registry.npmjs.org/use-intl/-/use-intl-4.8.3.tgz",
+ "integrity": "sha512-nLxlC/RH+le6g3amA508Itnn/00mE+J22ui21QhOWo5V9hCEC43+WtnRAITbJW0ztVZphev5X9gvOf2/Dk9PLA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/amannn"
+ }
+ ],
+ "dependencies": {
+ "@formatjs/fast-memoize": "^3.1.0",
+ "@schummar/icu-type-parser": "1.21.5",
+ "icu-minify": "^4.8.3",
+ "intl-messageformat": "^11.1.0"
+ },
+ "peerDependencies": {
+ "react": "^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0"
+ }
+ },
+ "node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "bin": {
+ "uuid": "dist/bin/uuid"
+ }
+ },
+ "node_modules/web-streams-polyfill": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
+ "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "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,
+ "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,
+ "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,
+ "dependencies": {
+ "is-map": "^2.0.3",
+ "is-set": "^2.0.3",
+ "is-weakmap": "^2.0.2",
+ "is-weakset": "^2.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/which-typed-array": {
+ "version": "1.1.20",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz",
+ "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==",
+ "dev": true,
+ "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,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs": {
+ "name": "wrap-ansi",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/ws": {
+ "version": "8.19.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
+ "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true
+ },
+ "node_modules/yaml": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
+ "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/yup": {
+ "version": "1.7.1",
+ "resolved": "https://registry.npmjs.org/yup/-/yup-1.7.1.tgz",
+ "integrity": "sha512-GKHFX2nXul2/4Dtfxhozv701jLQHdf6J34YDh2cEkpqoo8le5Mg6/LrdseVLrFarmFygZTlfIhHx/QKfb/QWXw==",
+ "dependencies": {
+ "property-expr": "^2.0.5",
+ "tiny-case": "^1.0.3",
+ "toposort": "^2.0.2",
+ "type-fest": "^2.19.0"
+ }
+ },
+ "node_modules/zod": {
+ "version": "3.25.76",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+ "dev": 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,
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "peerDependencies": {
+ "zod": "^3.25.0 || ^4.0.0"
+ }
+ },
+ "node_modules/zustand": {
+ "version": "5.0.11",
+ "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.11.tgz",
+ "integrity": "sha512-fdZY+dk7zn/vbWNCYmzZULHRrss0jx5pPFiOuMZ/5HJN6Yv3u+1Wswy/4MpZEkEGhtNH+pwxZB8OKgUBPzYAGg==",
+ "engines": {
+ "node": ">=12.20.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=18.0.0",
+ "immer": ">=9.0.6",
+ "react": ">=18.0.0",
+ "use-sync-external-store": ">=1.2.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "immer": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "use-sync-external-store": {
+ "optional": true
+ }
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..b82d7de
--- /dev/null
+++ b/package.json
@@ -0,0 +1,49 @@
+{
+ "name": "Suggest-Bet-FE-v2",
+ "version": "0.0.1",
+ "private": true,
+ "scripts": {
+ "dev": "cross-env NODE_TLS_REJECT_UNAUTHORIZED=0 next dev --webpack --experimental-https -p 3001",
+ "build": "next build --webpack",
+ "start": "next start",
+ "lint": "eslint"
+ },
+ "dependencies": {
+ "@chakra-ui/react": "^3.28.0",
+ "@emotion/react": "^11.14.0",
+ "@google/genai": "^1.35.0",
+ "@hookform/resolvers": "^5.2.2",
+ "@tanstack/react-query": "^5.90.16",
+ "aos": "^2.3.4",
+ "axios": "^1.13.1",
+ "framer-motion": "^12.34.1",
+ "i18next": "^25.6.0",
+ "next": "16.0.0",
+ "next-auth": "^4.24.13",
+ "next-intl": "^4.4.0",
+ "next-themes": "^0.4.6",
+ "nextjs-toploader": "^3.9.17",
+ "react": "19.2.0",
+ "react-dom": "19.2.0",
+ "react-hook-form": "^7.65.0",
+ "react-icons": "^5.5.0",
+ "yup": "^1.7.1",
+ "zustand": "^5.0.11"
+ },
+ "devDependencies": {
+ "@chakra-ui/cli": "^3.27.1",
+ "@eslint/eslintrc": "^3.3.1",
+ "@types/aos": "^3.0.7",
+ "@types/node": "^20",
+ "@types/react": "19.2.2",
+ "@types/react-dom": "19.2.2",
+ "babel-plugin-react-compiler": "^1.0.0",
+ "cross-env": "^10.1.0",
+ "eslint": "^9.37.0",
+ "eslint-config-next": "16.0.0",
+ "eslint-config-prettier": "^10.1.8",
+ "prettier": "^3.6.2",
+ "typescript": "^5"
+ },
+ "description": "Generated by Frontend CLI"
+}
diff --git a/prompt.md b/prompt.md
new file mode 100644
index 0000000..ab1f496
--- /dev/null
+++ b/prompt.md
@@ -0,0 +1,110 @@
+# 🤖 AI Assistant Context - Next.js Frontend
+
+> Bu dosya, AI asistanların (Claude, GPT, Gemini vb.) projeyi hızlıca anlaması için hazırlanmış bir referans dökümanıdır.
+
+---
+
+## 📚 Projeyi Anlamak İçin Önce Oku
+
+1. **README.md** dosyasını oku - Projenin mimarisi, teknoloji stack'i ve kurulum adımlarını içerir.
+
+```
+README.md
+```
+
+---
+
+## 🎯 Referans Klasörü
+
+`.claude/` klasörü best practice'ler, agent tanımları ve yardımcı scriptler içerir. Görev türüne göre ilgili referansları kullan:
+
+### Skills (Beceri Setleri)
+
+| Beceri | Konum | Ne Zaman Kullan |
+| ------------------- | --------------------------------- | ------------------------------------------ |
+| **Senior QA** | `.claude/skills/senior-qa/` | Test yazarken, coverage analizi yaparken |
+| **Senior Frontend** | `.claude/skills/senior-frontend/` | Component geliştirirken, UI best practices |
+| **Frontend Design** | `.claude/skills/frontend-design/` | Tasarım kararları alırken |
+
+### Agents (Roller)
+
+| Agent | Konum | Açıklama |
+| ------------------------------- | ---------------------------------------------- | ------------------------- |
+| **Frontend Developer** | `.claude/agents/frontend-developer.md` | Genel frontend geliştirme |
+| **Next.js Architecture Expert** | `.claude/agents/nextjs-architecture-expert.md` | Mimari kararlar |
+
+### Commands (Komutlar)
+
+| Komut | Konum | Açıklama |
+| ----------------------- | ------------------------------------------------ | ------------------------ |
+| **Component Generator** | `.claude/commands/nextjs-component-generator.md` | Yeni component oluşturma |
+| **API Tester** | `.claude/commands/nextjs-api-tester.md` | API endpoint test etme |
+
+---
+
+## 🔧 Teknoloji Stack'i (Özet)
+
+- **Framework:** Next.js 16 (App Router)
+- **UI Library:** Chakra UI v3
+- **State Management:** React Query (TanStack)
+- **Auth:** NextAuth.js
+- **i18n:** next-intl
+- **Language:** TypeScript (Strict Mode)
+
+---
+
+## 🏗️ Proje Yapısı Özeti
+
+```
+src/
+├── app/[locale]/ # Locale-based routing
+├── components/ # UI components
+├── lib/api/ # API clients
+├── i18n/ # Internationalization
+└── theme/ # Chakra UI theme
+```
+
+---
+
+## ✅ Görev Bazlı Referans Kullanımı
+
+**Test yazarken:**
+
+```
+.claude/skills/senior-qa/references/testing_strategies.md
+.claude/skills/senior-qa/references/test_automation_patterns.md
+```
+
+**Component geliştirirken:**
+
+```
+.claude/skills/senior-frontend/SKILL.md
+.claude/skills/frontend-design/SKILL.md
+```
+
+**Mimari kararlar alırken:**
+
+```
+.claude/agents/nextjs-architecture-expert.md
+README.md (ADR bölümü)
+```
+
+---
+
+## 💡 Örnek Prompt'lar
+
+### Yeni Component Oluşturma
+
+> "`.claude/skills/senior-frontend/` referanslarını kullanarak, reusable bir `DataTable` component'i oluştur."
+
+### Test Yazma
+
+> "`.claude/skills/senior-qa/references/testing_strategies.md` pattern'lerini kullanarak `LoginForm` için unit test yaz."
+
+### Code Review
+
+> "`.claude/skills/senior-frontend/` best practice'lerine göre `src/components/auth/` klasörünü review et."
+
+---
+
+**Backend Projesi:** `../typescript-boilerplate-be/prompt.md`
diff --git a/public/.DS_Store b/public/.DS_Store
new file mode 100644
index 0000000..8d3e571
Binary files /dev/null and b/public/.DS_Store differ
diff --git a/public/assets/img/sign-in-image.png b/public/assets/img/sign-in-image.png
new file mode 100644
index 0000000..032b812
Binary files /dev/null and b/public/assets/img/sign-in-image.png differ
diff --git a/public/assets/img/sign-up-image.png b/public/assets/img/sign-up-image.png
new file mode 100644
index 0000000..2ded519
Binary files /dev/null and b/public/assets/img/sign-up-image.png differ
diff --git a/public/favicon/android-chrome-192x192.png b/public/favicon/android-chrome-192x192.png
new file mode 100644
index 0000000..7ba9f52
Binary files /dev/null and b/public/favicon/android-chrome-192x192.png differ
diff --git a/public/favicon/android-chrome-512x512.png b/public/favicon/android-chrome-512x512.png
new file mode 100644
index 0000000..90a2413
Binary files /dev/null and b/public/favicon/android-chrome-512x512.png differ
diff --git a/public/favicon/apple-touch-icon.png b/public/favicon/apple-touch-icon.png
new file mode 100644
index 0000000..c664a45
Binary files /dev/null and b/public/favicon/apple-touch-icon.png differ
diff --git a/public/favicon/favicon-16x16.png b/public/favicon/favicon-16x16.png
new file mode 100644
index 0000000..834035c
Binary files /dev/null and b/public/favicon/favicon-16x16.png differ
diff --git a/public/favicon/favicon-32x32.png b/public/favicon/favicon-32x32.png
new file mode 100644
index 0000000..3624c06
Binary files /dev/null and b/public/favicon/favicon-32x32.png differ
diff --git a/public/favicon/favicon.ico b/public/favicon/favicon.ico
new file mode 100644
index 0000000..df65926
Binary files /dev/null and b/public/favicon/favicon.ico differ
diff --git a/public/favicon/site.webmanifest b/public/favicon/site.webmanifest
new file mode 100644
index 0000000..df4e87d
--- /dev/null
+++ b/public/favicon/site.webmanifest
@@ -0,0 +1,19 @@
+{
+ "name": "",
+ "short_name": "",
+ "icons": [
+ {
+ "src": "/favicon/android-chrome-192x192.png",
+ "sizes": "192x192",
+ "type": "image/png"
+ },
+ {
+ "src": "/favicon/android-chrome-512x512.png",
+ "sizes": "512x512",
+ "type": "image/png"
+ }
+ ],
+ "theme_color": "#ffffff",
+ "background_color": "#ffffff",
+ "display": "standalone"
+}
\ No newline at end of file
diff --git a/src/.DS_Store b/src/.DS_Store
new file mode 100644
index 0000000..bd130cc
Binary files /dev/null and b/src/.DS_Store differ
diff --git a/src/app/.DS_Store b/src/app/.DS_Store
new file mode 100644
index 0000000..864c40b
Binary files /dev/null and b/src/app/.DS_Store differ
diff --git a/src/app/[locale]/(auth)/layout.tsx b/src/app/[locale]/(auth)/layout.tsx
new file mode 100644
index 0000000..b533ea9
--- /dev/null
+++ b/src/app/[locale]/(auth)/layout.tsx
@@ -0,0 +1,15 @@
+'use client';
+
+import Footer from '@/components/layout/footer/footer';
+import { Box, Flex } from '@chakra-ui/react';
+
+function AuthLayout({ children }: { children: React.ReactNode }) {
+ return (
+
+ {children}
+
+
+ );
+}
+
+export default AuthLayout;
diff --git a/src/app/[locale]/(auth)/signin/page.tsx b/src/app/[locale]/(auth)/signin/page.tsx
new file mode 100644
index 0000000..38d35dd
--- /dev/null
+++ b/src/app/[locale]/(auth)/signin/page.tsx
@@ -0,0 +1,231 @@
+"use client";
+
+import {
+ Box,
+ Flex,
+ Heading,
+ Input,
+ Link as ChakraLink,
+ Text,
+ ClientOnly,
+} from "@chakra-ui/react";
+import { Button } from "@/components/ui/buttons/button";
+import { Switch } from "@/components/ui/forms/switch";
+import { Field } from "@/components/ui/forms/field";
+import { useTranslations } from "next-intl";
+import signInImage from "../../../../../public/assets/img/sign-in-image.png";
+import { InputGroup } from "@/components/ui/forms/input-group";
+import { BiLock } from "react-icons/bi";
+import { useForm } from "react-hook-form";
+import { yupResolver } from "@hookform/resolvers/yup";
+import * as yup from "yup";
+import { Link, useRouter } from "@/i18n/navigation";
+import { MdMail } from "react-icons/md";
+import { PasswordInput } from "@/components/ui/forms/password-input";
+import { Skeleton } from "@/components/ui/feedback/skeleton";
+import { signIn } from "next-auth/react";
+import { toaster } from "@/components/ui/feedback/toaster";
+import { useState } from "react";
+
+const schema = yup.object({
+ email: yup.string().email().required(),
+ password: yup.string().required(),
+});
+
+type SignInForm = yup.InferType;
+
+const defaultValues = {
+ email: "test@test.com.tr",
+ password: "test1234",
+};
+
+function SignInPage() {
+ const t = useTranslations();
+ const router = useRouter();
+
+ const [loading, setLoading] = useState(false);
+
+ const {
+ handleSubmit,
+ register,
+ formState: { errors },
+ } = useForm({
+ resolver: yupResolver(schema),
+ mode: "onChange",
+ defaultValues,
+ });
+
+ const onSubmit = async (formData: SignInForm) => {
+ try {
+ setLoading(true);
+ const res = await signIn("credentials", {
+ redirect: false,
+ email: formData.email,
+ password: formData.password,
+ });
+
+ if (res?.error) {
+ throw new Error(res.error);
+ }
+
+ router.replace("/home");
+ } catch (error) {
+ toaster.error({
+ title: (error as Error).message || "Giriş yaparken hata oluştu!",
+ type: "error",
+ });
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ return (
+
+
+
+
+
+ {t("auth.welcome-back")}
+
+
+ {t("auth.subtitle")}
+
+
+ }>
+
+
+
+
+ }>
+
+
+
+
+
+ {t("auth.remember-me")}
+
+
+
+ }>
+
+ {t("auth.sign-in")}
+
+
+
+
+
+ {t("auth.dont-have-account")}
+
+ {t("auth.sign-up")}
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default SignInPage;
diff --git a/src/app/[locale]/(auth)/signup/page.tsx b/src/app/[locale]/(auth)/signup/page.tsx
new file mode 100644
index 0000000..1c031c5
--- /dev/null
+++ b/src/app/[locale]/(auth)/signup/page.tsx
@@ -0,0 +1,219 @@
+"use client";
+
+import {
+ Box,
+ Flex,
+ Input,
+ Link as ChakraLink,
+ Text,
+ ClientOnly,
+} from "@chakra-ui/react";
+import signUpImage from "../../../../../public/assets/img/sign-up-image.png";
+import { Button } from "@/components/ui/buttons/button";
+import { Field } from "@/components/ui/forms/field";
+import { useTranslations } from "next-intl";
+import { useForm } from "react-hook-form";
+import * as yup from "yup";
+import { yupResolver } from "@hookform/resolvers/yup";
+import { InputGroup } from "@/components/ui/forms/input-group";
+import { BiLock, BiUser } from "react-icons/bi";
+import { Link } from "@/i18n/navigation";
+import { MdMail } from "react-icons/md";
+import { useRouter } from "next/navigation";
+import { PasswordInput } from "@/components/ui/forms/password-input";
+import { Skeleton } from "@/components/ui/feedback/skeleton";
+import { authService } from "@/lib/api/example/auth/service";
+import { useState } from "react";
+
+const schema = yup.object({
+ name: yup.string().required(),
+ email: yup.string().email().required(),
+ password: yup.string().min(8).required(),
+});
+
+type SignUpForm = yup.InferType;
+
+function SignUpPage() {
+ const t = useTranslations();
+ const router = useRouter();
+ const [isSubmitting, setIsSubmitting] = useState(false);
+
+ const {
+ handleSubmit,
+ register,
+ formState: { errors },
+ } = useForm({ resolver: yupResolver(schema), mode: "onChange" });
+
+ const onSubmit = async (formData: SignUpForm) => {
+ setIsSubmitting(true);
+ try {
+ await authService.register({
+ email: formData.email,
+ password: formData.password,
+ firstName: formData.name,
+ lastName: "",
+ });
+ router.replace("/signin");
+ } catch {
+ // Error handled by api-service interceptor (toast + 422 display)
+ } finally {
+ setIsSubmitting(false);
+ }
+ return formData;
+ };
+
+ return (
+
+
+
+
+ {t("auth.create-an-account-now")}
+
+
+
+
+ }>
+
+
+
+
+ }>
+
+
+
+
+ }>
+
+
+
+
+ }>
+
+ {isSubmitting ? t("auth.registering") : t("auth.sign-up")}
+
+
+
+
+
+
+ {t("auth.already-have-an-account")}
+
+ {t("auth.sign-in")}
+
+
+
+
+
+
+ );
+}
+
+export default SignUpPage;
diff --git a/src/app/[locale]/(error)/[...slug]/page.tsx b/src/app/[locale]/(error)/[...slug]/page.tsx
new file mode 100644
index 0000000..71d4050
--- /dev/null
+++ b/src/app/[locale]/(error)/[...slug]/page.tsx
@@ -0,0 +1,5 @@
+import { notFound } from 'next/navigation';
+
+export default function CatchAllPage() {
+ notFound();
+}
diff --git a/src/app/[locale]/(site)/about/page.tsx b/src/app/[locale]/(site)/about/page.tsx
new file mode 100644
index 0000000..539f1a0
--- /dev/null
+++ b/src/app/[locale]/(site)/about/page.tsx
@@ -0,0 +1,7 @@
+import React from 'react';
+
+function AboutPage() {
+ return AboutPage
;
+}
+
+export default AboutPage;
diff --git a/src/app/[locale]/(site)/admin/page.tsx b/src/app/[locale]/(site)/admin/page.tsx
new file mode 100644
index 0000000..5dce59a
--- /dev/null
+++ b/src/app/[locale]/(site)/admin/page.tsx
@@ -0,0 +1,15 @@
+import { getTranslations } from "next-intl/server";
+import AdminContent from "@/components/admin/admin-content";
+
+export async function generateMetadata() {
+ const t = await getTranslations();
+ return {
+ title: `${t("admin.title")} | Suggest Bet`,
+ description:
+ "Admin panel for managing users, monitoring predictions, and system overview.",
+ };
+}
+
+export default function AdminPage() {
+ return ;
+}
diff --git a/src/app/[locale]/(site)/analysis/page.tsx b/src/app/[locale]/(site)/analysis/page.tsx
new file mode 100644
index 0000000..5dd5ebb
--- /dev/null
+++ b/src/app/[locale]/(site)/analysis/page.tsx
@@ -0,0 +1,14 @@
+import { getTranslations } from "next-intl/server";
+import AnalysisContent from "@/components/analysis/analysis-content";
+
+export async function generateMetadata() {
+ const t = await getTranslations();
+ return {
+ title: `${t("analysis.title")} | Suggest Bet`,
+ description: "AI-powered multi-match analysis for coupon generation.",
+ };
+}
+
+export default function AnalysisPage() {
+ return ;
+}
diff --git a/src/app/[locale]/(site)/coupon-builder/page.tsx b/src/app/[locale]/(site)/coupon-builder/page.tsx
new file mode 100644
index 0000000..b01cd3b
--- /dev/null
+++ b/src/app/[locale]/(site)/coupon-builder/page.tsx
@@ -0,0 +1,15 @@
+import { getTranslations } from "next-intl/server";
+import CouponBuilderContent from "@/components/coupons/coupon-builder-content";
+
+export async function generateMetadata() {
+ const t = await getTranslations();
+ return {
+ title: `${t("coupons.builder-title")} | Suggest Bet`,
+ description:
+ "Build your coupon with AI-powered suggestions. Choose your strategy and let AI optimize your bets.",
+ };
+}
+
+export default function CouponBuilderPage() {
+ return ;
+}
diff --git a/src/app/[locale]/(site)/coupon-history/page.tsx b/src/app/[locale]/(site)/coupon-history/page.tsx
new file mode 100644
index 0000000..855feec
--- /dev/null
+++ b/src/app/[locale]/(site)/coupon-history/page.tsx
@@ -0,0 +1,15 @@
+import { getTranslations } from "next-intl/server";
+import CouponHistoryContent from "@/components/coupons/coupon-history-content";
+
+export async function generateMetadata() {
+ const t = await getTranslations();
+ return {
+ title: `${t("coupons.history-title")} | Suggest Bet`,
+ description:
+ "View your coupon history, track wins and losses, and analyze your betting performance.",
+ };
+}
+
+export default function CouponHistoryPage() {
+ return ;
+}
diff --git a/src/app/[locale]/(site)/dashboard/page.tsx b/src/app/[locale]/(site)/dashboard/page.tsx
new file mode 100644
index 0000000..da3d2ae
--- /dev/null
+++ b/src/app/[locale]/(site)/dashboard/page.tsx
@@ -0,0 +1,16 @@
+import { getTranslations } from "next-intl/server";
+import DashboardContent from "@/components/dashboard/dashboard-content";
+
+export async function generateMetadata() {
+ const t = await getTranslations();
+
+ return {
+ title: `${t("dashboard.title")} | Suggest Bet`,
+ description:
+ "Your personalized betting dashboard with predictions, value bets, and match insights.",
+ };
+}
+
+export default function DashboardPage() {
+ return ;
+}
diff --git a/src/app/[locale]/(site)/h2h/page.tsx b/src/app/[locale]/(site)/h2h/page.tsx
new file mode 100644
index 0000000..1499087
--- /dev/null
+++ b/src/app/[locale]/(site)/h2h/page.tsx
@@ -0,0 +1,14 @@
+import { getTranslations } from "next-intl/server";
+import H2HContent from "@/components/h2h/h2h-content";
+
+export async function generateMetadata() {
+ const t = await getTranslations();
+ return {
+ title: `${t("matches.head-to-head")} | Suggest Bet`,
+ description: "Compare two teams and view their head-to-head match history.",
+ };
+}
+
+export default function H2HPage() {
+ return ;
+}
diff --git a/src/app/[locale]/(site)/home/page.tsx b/src/app/[locale]/(site)/home/page.tsx
new file mode 100644
index 0000000..98b6569
--- /dev/null
+++ b/src/app/[locale]/(site)/home/page.tsx
@@ -0,0 +1,16 @@
+import { getTranslations } from "next-intl/server";
+import HomeContent from "@/components/home/home-content";
+
+export async function generateMetadata() {
+ const t = await getTranslations();
+
+ return {
+ title: `${t("home")} | Suggest Bet`,
+ description:
+ "AI-powered betting predictions. Analyze matches, discover value bets, and build winning coupons.",
+ };
+}
+
+export default function Home() {
+ return ;
+}
diff --git a/src/app/[locale]/(site)/layout.tsx b/src/app/[locale]/(site)/layout.tsx
new file mode 100644
index 0000000..83fed1e
--- /dev/null
+++ b/src/app/[locale]/(site)/layout.tsx
@@ -0,0 +1,21 @@
+'use client';
+
+import { Container, Flex } from '@chakra-ui/react';
+import Header from '@/components/layout/header/header';
+import Footer from '@/components/layout/footer/footer';
+import BackToTop from '@/components/ui/back-to-top';
+
+function MainLayout({ children }: { children: React.ReactNode }) {
+ return (
+
+
+
+ {children}
+
+
+
+
+ );
+}
+
+export default MainLayout;
diff --git a/src/app/[locale]/(site)/leagues/page.tsx b/src/app/[locale]/(site)/leagues/page.tsx
new file mode 100644
index 0000000..cf0ef55
--- /dev/null
+++ b/src/app/[locale]/(site)/leagues/page.tsx
@@ -0,0 +1,14 @@
+import { getTranslations } from "next-intl/server";
+import LeaguesContent from "@/components/leagues/leagues-content";
+
+export async function generateMetadata() {
+ const t = await getTranslations();
+ return {
+ title: `${t("leagues.title")} | Suggest Bet`,
+ description: "Browse football and basketball leagues, countries, and teams.",
+ };
+}
+
+export default function LeaguesPage() {
+ return ;
+}
diff --git a/src/app/[locale]/(site)/matches/[id]/page.tsx b/src/app/[locale]/(site)/matches/[id]/page.tsx
new file mode 100644
index 0000000..3666bfe
--- /dev/null
+++ b/src/app/[locale]/(site)/matches/[id]/page.tsx
@@ -0,0 +1,14 @@
+import { getTranslations } from "next-intl/server";
+import MatchDetailContent from "@/components/matches/match-detail-content";
+
+export async function generateMetadata() {
+ const t = await getTranslations();
+
+ return {
+ title: `${t("matches.match-details")} | Suggest Bet`,
+ };
+}
+
+export default function MatchDetailPage() {
+ return ;
+}
diff --git a/src/app/[locale]/(site)/matches/page.tsx b/src/app/[locale]/(site)/matches/page.tsx
new file mode 100644
index 0000000..930d3e8
--- /dev/null
+++ b/src/app/[locale]/(site)/matches/page.tsx
@@ -0,0 +1,16 @@
+import { getTranslations } from "next-intl/server";
+import MatchesContent from "@/components/matches/matches-content";
+
+export async function generateMetadata() {
+ const t = await getTranslations();
+
+ return {
+ title: `${t("matches.title")} | Suggest Bet`,
+ description:
+ "Browse and analyze upcoming football and basketball matches with AI predictions.",
+ };
+}
+
+export default function MatchesPage() {
+ return ;
+}
diff --git a/src/app/[locale]/(site)/predictions/page.tsx b/src/app/[locale]/(site)/predictions/page.tsx
new file mode 100644
index 0000000..040a7c5
--- /dev/null
+++ b/src/app/[locale]/(site)/predictions/page.tsx
@@ -0,0 +1,15 @@
+import { getTranslations } from "next-intl/server";
+import PredictionsContent from "@/components/predictions/predictions-content";
+
+export async function generateMetadata() {
+ const t = await getTranslations();
+ return {
+ title: `${t("predictions.title")} | Suggest Bet`,
+ description:
+ "AI-powered match predictions with confidence scores, value bets, and prediction history.",
+ };
+}
+
+export default function PredictionsPage() {
+ return ;
+}
diff --git a/src/app/[locale]/(site)/profile/page.tsx b/src/app/[locale]/(site)/profile/page.tsx
new file mode 100644
index 0000000..0a014c4
--- /dev/null
+++ b/src/app/[locale]/(site)/profile/page.tsx
@@ -0,0 +1,15 @@
+import { getTranslations } from "next-intl/server";
+import ProfileContent from "@/components/profile/profile-content";
+
+export async function generateMetadata() {
+ const t = await getTranslations();
+ return {
+ title: `${t("profile.title")} | Suggest Bet`,
+ description:
+ "Manage your profile, view account info, and track your betting statistics.",
+ };
+}
+
+export default function ProfilePage() {
+ return ;
+}
diff --git a/src/app/[locale]/(site)/spor-toto/page.tsx b/src/app/[locale]/(site)/spor-toto/page.tsx
new file mode 100644
index 0000000..c3f78ad
--- /dev/null
+++ b/src/app/[locale]/(site)/spor-toto/page.tsx
@@ -0,0 +1,15 @@
+import { getTranslations } from "next-intl/server";
+import SporTotoContent from "@/components/spor-toto/spor-toto-content";
+
+export async function generateMetadata() {
+ const t = await getTranslations();
+ return {
+ title: `${t("spor-toto.title")} | Suggest Bet`,
+ description:
+ "Spor Toto predictions with AI-powered analysis. Generate optimized system coupons with contrarian parimutuel strategy.",
+ };
+}
+
+export default function SporTotoPage() {
+ return ;
+}
diff --git a/src/app/[locale]/(site)/teams/[id]/page.tsx b/src/app/[locale]/(site)/teams/[id]/page.tsx
new file mode 100644
index 0000000..85b0aae
--- /dev/null
+++ b/src/app/[locale]/(site)/teams/[id]/page.tsx
@@ -0,0 +1,13 @@
+import { getTranslations } from "next-intl/server";
+import TeamDetailContent from "@/components/teams/team-detail-content";
+
+export async function generateMetadata() {
+ const t = await getTranslations();
+ return {
+ title: `${t("nav.teams")} | Suggest Bet`,
+ };
+}
+
+export default function TeamDetailPage() {
+ return ;
+}
diff --git a/src/app/[locale]/(site)/teams/page.tsx b/src/app/[locale]/(site)/teams/page.tsx
new file mode 100644
index 0000000..96a339b
--- /dev/null
+++ b/src/app/[locale]/(site)/teams/page.tsx
@@ -0,0 +1,14 @@
+import { getTranslations } from "next-intl/server";
+import TeamsContent from "@/components/teams/teams-content";
+
+export async function generateMetadata() {
+ const t = await getTranslations();
+ return {
+ title: `${t("nav.teams")} | Suggest Bet`,
+ description: "Search and explore football teams, view match history and stats.",
+ };
+}
+
+export default function TeamsPage() {
+ return ;
+}
diff --git a/src/app/[locale]/global.css b/src/app/[locale]/global.css
new file mode 100644
index 0000000..534afd6
--- /dev/null
+++ b/src/app/[locale]/global.css
@@ -0,0 +1,160 @@
+/* ═══════════════════════════════════════════════════════
+ Suggest-Bet — Global CSS
+ Premium animations, gradients, and utility keyframes
+ ═══════════════════════════════════════════════════════ */
+
+html {
+ scroll-behavior: smooth;
+}
+
+body {
+ overflow-x: hidden;
+}
+
+/* ──────────────────────────────────
+ Custom Animation Keyframes
+ ────────────────────────────────── */
+
+/* Pulsing live indicator */
+@keyframes pulse {
+ 0%, 100% { opacity: 1; transform: scale(1); }
+ 50% { opacity: 0.5; transform: scale(1.3); }
+}
+
+/* Glow ring for CTAs */
+@keyframes glow-ring {
+ 0% { box-shadow: 0 0 0 0 rgba(56, 178, 172, 0.4); }
+ 70% { box-shadow: 0 0 0 12px rgba(56, 178, 172, 0); }
+ 100% { box-shadow: 0 0 0 0 rgba(56, 178, 172, 0); }
+}
+
+/* Shimmer for skeleton loading */
+@keyframes shimmer {
+ 0% { background-position: -200% 0; }
+ 100% { background-position: 200% 0; }
+}
+
+/* Gradient background shift */
+@keyframes gradient-shift {
+ 0% { background-position: 0% 50%; }
+ 50% { background-position: 100% 50%; }
+ 100% { background-position: 0% 50%; }
+}
+
+/* Sparkle float */
+@keyframes sparkle-float {
+ 0%, 100% { transform: translateY(0) rotate(0deg); opacity: 0; }
+ 10% { opacity: 1; }
+ 90% { opacity: 1; }
+ 100% { transform: translateY(-120px) rotate(360deg); opacity: 0; }
+}
+
+/* Subtle float for decorative elements */
+@keyframes float {
+ 0%, 100% { transform: translateY(0); }
+ 50% { transform: translateY(-10px); }
+}
+
+/* Gradient text shimmer */
+@keyframes text-shimmer {
+ 0% { background-position: 0% 50%; }
+ 100% { background-position: 200% 50%; }
+}
+
+/* Rotate for spinners */
+@keyframes spin-slow {
+ from { transform: rotate(0deg); }
+ to { transform: rotate(360deg); }
+}
+
+/* Fade in up — CSS fallback for non-JS */
+@keyframes fadeInUp {
+ from { opacity: 0; transform: translateY(20px); }
+ to { opacity: 1; transform: translateY(0); }
+}
+
+/* ──────────────────────────────────
+ Utility Classes
+ ────────────────────────────────── */
+
+.animate-pulse { animation: pulse 1.5s ease-in-out infinite; }
+.animate-glow { animation: glow-ring 2s infinite; }
+.animate-shimmer {
+ background: linear-gradient(90deg, transparent 25%, rgba(255,255,255,0.08) 50%, transparent 75%);
+ background-size: 200% 100%;
+ animation: shimmer 1.8s ease-in-out infinite;
+}
+.animate-float { animation: float 3s ease-in-out infinite; }
+.animate-spin-slow { animation: spin-slow 8s linear infinite; }
+
+/* Gradient mesh background */
+.gradient-mesh {
+ background:
+ radial-gradient(at 20% 20%, rgba(56, 178, 172, 0.15) 0%, transparent 50%),
+ radial-gradient(at 80% 80%, rgba(128, 90, 213, 0.12) 0%, transparent 50%),
+ radial-gradient(at 50% 50%, rgba(66, 153, 225, 0.08) 0%, transparent 70%);
+}
+
+/* Dark mode gradient mesh */
+[data-theme="dark"] .gradient-mesh,
+.dark .gradient-mesh {
+ background:
+ radial-gradient(at 20% 20%, rgba(56, 178, 172, 0.08) 0%, transparent 50%),
+ radial-gradient(at 80% 80%, rgba(128, 90, 213, 0.06) 0%, transparent 50%),
+ radial-gradient(at 50% 50%, rgba(66, 153, 225, 0.04) 0%, transparent 70%);
+}
+
+/* Animated gradient text */
+.gradient-text {
+ background: linear-gradient(135deg, #38B2AC, #805AD5, #4299E1, #38B2AC);
+ background-size: 300% 300%;
+ -webkit-background-clip: text;
+ background-clip: text;
+ -webkit-text-fill-color: transparent;
+ animation: text-shimmer 4s ease infinite;
+}
+
+/* Glassmorphism card */
+.glass {
+ background: rgba(255, 255, 255, 0.7);
+ backdrop-filter: blur(16px) saturate(180%);
+ -webkit-backdrop-filter: blur(16px) saturate(180%);
+ border: 1px solid rgba(255, 255, 255, 0.3);
+}
+
+[data-theme="dark"] .glass,
+.dark .glass {
+ background: rgba(26, 32, 44, 0.7);
+ border: 1px solid rgba(255, 255, 255, 0.08);
+}
+
+/* ──────────────────────────────────
+ Scrollbar Styling
+ ────────────────────────────────── */
+
+::-webkit-scrollbar {
+ width: 6px;
+ height: 6px;
+}
+
+::-webkit-scrollbar-track {
+ background: transparent;
+}
+
+::-webkit-scrollbar-thumb {
+ background: rgba(128, 128, 128, 0.3);
+ border-radius: 999px;
+}
+
+::-webkit-scrollbar-thumb:hover {
+ background: rgba(128, 128, 128, 0.5);
+}
+
+/* ──────────────────────────────────
+ Selection Color
+ ────────────────────────────────── */
+
+::selection {
+ background: rgba(56, 178, 172, 0.3);
+ color: inherit;
+}
diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx
new file mode 100644
index 0000000..31b6222
--- /dev/null
+++ b/src/app/[locale]/layout.tsx
@@ -0,0 +1,46 @@
+import { Provider } from "@/components/ui/provider";
+import { Bricolage_Grotesque } from "next/font/google";
+import { hasLocale, NextIntlClientProvider } from "next-intl";
+import { notFound } from "next/navigation";
+import { routing } from "@/i18n/routing";
+import { dir } from "i18next";
+import "./global.css";
+
+const bricolage = Bricolage_Grotesque({
+ variable: "--font-bricolage",
+ subsets: ["latin"],
+});
+
+export default async function RootLayout({
+ children,
+ params,
+}: {
+ children: React.ReactNode;
+ params: Promise<{ locale: string }>;
+}) {
+ const { locale } = await params;
+ if (!hasLocale(routing.locales, locale)) {
+ notFound();
+ }
+
+ return (
+
+
+ {/*
+
+ */}
+
+
+
+
+ {children}
+
+
+
+ );
+}
diff --git a/src/app/[locale]/not-found.tsx b/src/app/[locale]/not-found.tsx
new file mode 100644
index 0000000..52cb987
--- /dev/null
+++ b/src/app/[locale]/not-found.tsx
@@ -0,0 +1,30 @@
+import { Link } from '@/i18n/navigation';
+import { Flex, Text, Button, VStack, Heading } from '@chakra-ui/react';
+import { getTranslations } from 'next-intl/server';
+
+export default async function NotFoundPage() {
+ const t = await getTranslations();
+
+ return (
+
+
+
+ {t('error.404')}
+
+
+ {t('error.not-found')}
+
+
+
+ {t('error.back-to-home')}
+
+
+
+
+ );
+}
diff --git a/src/app/[locale]/page.tsx b/src/app/[locale]/page.tsx
new file mode 100644
index 0000000..6cb3303
--- /dev/null
+++ b/src/app/[locale]/page.tsx
@@ -0,0 +1,5 @@
+import { redirect } from 'next/navigation';
+
+export default async function Page() {
+ redirect('/home');
+}
diff --git a/src/app/api/auth/[...nextauth]/route.ts b/src/app/api/auth/[...nextauth]/route.ts
new file mode 100644
index 0000000..890b5f8
--- /dev/null
+++ b/src/app/api/auth/[...nextauth]/route.ts
@@ -0,0 +1,123 @@
+import { authService } from "@/lib/api/example/auth/service";
+import NextAuth from "next-auth";
+import type { NextAuthOptions } from "next-auth";
+import type { JWT } from "next-auth/jwt";
+import type { Session, User } from "next-auth";
+import Credentials from "next-auth/providers/credentials";
+
+function randomToken() {
+ return Math.random().toString(36).substring(2) + Date.now().toString(36);
+}
+
+const isMockMode = process.env.NEXT_PUBLIC_ENABLE_MOCK_MODE === "true";
+
+const authOptions: NextAuthOptions = {
+ providers: [
+ Credentials({
+ name: "Credentials",
+ credentials: {
+ email: { label: "Email", type: "text" },
+ password: { label: "Password", type: "password" },
+ },
+ async authorize(credentials) {
+ try {
+ console.log("Starting authorization with:", {
+ email: credentials?.email,
+ });
+
+ if (!credentials?.email || !credentials?.password) {
+ throw new Error("Email ve şifre gereklidir.");
+ }
+
+ // Eğer mock mod aktifse backend'e gitme
+ if (isMockMode) {
+ console.log("Mock mode active, bypassing backend");
+ return {
+ id: credentials.email,
+ name: credentials.email.split("@")[0],
+ email: credentials.email,
+ accessToken: randomToken(),
+ refreshToken: randomToken(),
+ };
+ }
+
+ // Normal mod: backend'e istek at
+ console.log("Sending login request to backend...");
+ const res = await authService.login({
+ email: credentials.email,
+ password: credentials.password,
+ });
+
+ console.log(
+ "Backend response received:",
+ JSON.stringify(res, null, 2),
+ );
+
+ const response = res;
+
+ // Backend returns ApiResponse
+ // Structure: { data: { accessToken, refreshToken, expiresIn, user }, message, statusCode }
+ if (!res.success || !response?.data?.accessToken) {
+ console.error("Login failed or no access token in response");
+ throw new Error(response?.message || "Giriş başarısız");
+ }
+
+ const { accessToken, refreshToken, user } = response.data;
+
+ console.log("Login successful, creating user session object");
+
+ return {
+ id: user.id,
+ name: user.firstName
+ ? `${user.firstName} ${user.lastName || ""}`.trim()
+ : user.email.split("@")[0],
+ email: user.email,
+ accessToken,
+ refreshToken,
+ roles: user.roles || [],
+ };
+ } catch (error: unknown) {
+ console.error("Authorize error detailed:", error);
+ const err = error as Error & {
+ response?: { data: unknown; status: number };
+ };
+ if (err.response) {
+ console.error("Error response data:", err.response.data);
+ console.error("Error response status:", err.response.status);
+ }
+ throw new Error(
+ err.message || "An error occurred during authentication",
+ );
+ }
+ },
+ }),
+ ],
+ callbacks: {
+ async jwt({ token, user }: { token: JWT; user?: User }) {
+ if (user) {
+ token.accessToken = user.accessToken;
+ token.refreshToken = user.refreshToken;
+ token.id = user.id;
+ token.roles = user.roles;
+ }
+ return token;
+ },
+ async session({ session, token }: { session: Session; token: JWT }) {
+ session.user.id = token.id;
+ session.user.roles = token.roles;
+ session.accessToken = token.accessToken;
+ session.refreshToken = token.refreshToken;
+ return session;
+ },
+ },
+ pages: {
+ signIn: "/signin",
+ error: "/signin",
+ },
+ session: { strategy: "jwt" },
+ secret: process.env.NEXTAUTH_SECRET,
+};
+
+const handler = NextAuth(authOptions);
+
+export { handler as GET, handler as POST };
diff --git a/src/components/.DS_Store b/src/components/.DS_Store
new file mode 100644
index 0000000..1186d71
Binary files /dev/null and b/src/components/.DS_Store differ
diff --git a/src/components/admin/admin-content.tsx b/src/components/admin/admin-content.tsx
new file mode 100644
index 0000000..ab2e075
--- /dev/null
+++ b/src/components/admin/admin-content.tsx
@@ -0,0 +1,283 @@
+"use client";
+
+import {
+ Box,
+ Flex,
+ Heading,
+ Text,
+ SimpleGrid,
+ Card,
+ VStack,
+ HStack,
+ Badge,
+ Spinner,
+ Button,
+ Separator,
+} from "@chakra-ui/react";
+import { useTranslations } from "next-intl";
+import { useColorModeValue } from "@/components/ui/color-mode";
+import {
+ SlideUp,
+ StaggerContainer,
+ StaggerItem,
+ AnimatedCounter,
+} from "@/components/motion";
+import { useAdminAnalytics, useAdminUsers } from "@/lib/api/admin/use-hooks";
+import type { AdminUserDto, AnalyticsOverviewDto } from "@/lib/api/admin/types";
+import { LuUsers, LuChartBar, LuActivity, LuShield } from "react-icons/lu";
+import { useState } from "react";
+
+type AdminTab = "overview" | "users";
+
+// ========================
+// Admin Stat Card
+// ========================
+
+interface AdminStatProps {
+ label: string;
+ value: number;
+ icon: React.ReactNode;
+ colorPalette: string;
+}
+
+function AdminStat({ label, value, icon, colorPalette }: AdminStatProps) {
+ const cardBg = useColorModeValue("white", "gray.800");
+ const borderColor = useColorModeValue("gray.100", "gray.700");
+
+ return (
+
+
+
+
+ {icon}
+
+
+
+
+
+
+ {label}
+
+
+
+
+
+ );
+}
+
+// ========================
+// Admin Content
+// ========================
+
+export default function AdminContent() {
+ const t = useTranslations("admin");
+ const tCommon = useTranslations("common");
+ const [activeTab, setActiveTab] = useState("overview");
+
+ const cardBg = useColorModeValue("white", "gray.800");
+ const borderColor = useColorModeValue("gray.100", "gray.700");
+
+ const { data: analyticsData, isLoading: analyticsLoading } =
+ useAdminAnalytics();
+ const { data: usersData, isLoading: usersLoading } = useAdminUsers();
+
+ const analytics = analyticsData?.data as AnalyticsOverviewDto | undefined;
+ const users = (usersData?.data as AdminUserDto[] | undefined) ?? [];
+
+ const tabs: { key: AdminTab; label: string }[] = [
+ { key: "overview", label: t("overview") },
+ { key: "users", label: t("user-management") },
+ ];
+
+ const getUserDisplayName = (user: AdminUserDto) => {
+ if (user.firstName && user.lastName)
+ return `${user.firstName} ${user.lastName}`;
+ if (user.firstName) return user.firstName;
+ return user.email.split("@")[0];
+ };
+
+ return (
+
+
+
+
+
+ {t("title")}
+
+
+ {t("subtitle")}
+
+
+
+
+ {t("admin-badge")}
+
+
+
+ {/* Tabs */}
+
+ {tabs.map((tab) => (
+ setActiveTab(tab.key)}
+ >
+ {tab.label}
+
+ ))}
+
+
+ {/* Overview Tab */}
+ {activeTab === "overview" &&
+ (analyticsLoading ? (
+
+
+
+ ) : (
+
+
+
+ }
+ colorPalette="primary"
+ />
+
+
+ }
+ colorPalette="green"
+ />
+
+
+ }
+ colorPalette="orange"
+ />
+
+
+ }
+ colorPalette="purple"
+ />
+
+
+
+ ))}
+
+ {/* Users Tab */}
+ {activeTab === "users" &&
+ (usersLoading ? (
+
+
+
+ ) : users.length > 0 ? (
+
+
+
+ {/* Table Header */}
+
+ {t("user-name")}
+ {t("user-email")}
+
+ {t("user-role")}
+
+
+ {t("user-status")}
+
+
+
+ {/* User Rows */}
+ {users.map((user: AdminUserDto, idx: number) => (
+
+ {idx > 0 && }
+
+
+ {getUserDisplayName(user)}
+
+
+ {user.email}
+
+
+
+ {user.role || "User"}
+
+
+
+
+ {user.isActive
+ ? tCommon("active")
+ : tCommon("inactive")}
+
+
+
+
+ ))}
+
+
+
+ ) : (
+
+ {t("no-users")}
+
+ ))}
+
+
+ );
+}
diff --git a/src/components/admin/index.ts b/src/components/admin/index.ts
new file mode 100644
index 0000000..45ffd92
--- /dev/null
+++ b/src/components/admin/index.ts
@@ -0,0 +1 @@
+export { default as AdminContent } from "./admin-content";
diff --git a/src/components/analysis/analysis-content.tsx b/src/components/analysis/analysis-content.tsx
new file mode 100644
index 0000000..e829f0e
--- /dev/null
+++ b/src/components/analysis/analysis-content.tsx
@@ -0,0 +1,237 @@
+"use client";
+
+import {
+ Box,
+ Flex,
+ Heading,
+ Text,
+ Card,
+ VStack,
+ HStack,
+ Badge,
+ Spinner,
+ Button,
+ SimpleGrid,
+} from "@chakra-ui/react";
+import { useTranslations } from "next-intl";
+import { useColorModeValue } from "@/components/ui/color-mode";
+import { SlideUp } from "@/components/motion";
+import {
+ useAnalyzeMatches,
+ useAnalysisHistory,
+} from "@/lib/api/analysis/use-hooks";
+import { useQueryMatches } from "@/lib/api/matches/use-hooks";
+import type { LeagueWithMatchesDto } from "@/lib/api/matches/types";
+import { LuSparkles, LuClock, LuCheck } from "react-icons/lu";
+import { useState } from "react";
+import { toaster } from "@/components/ui/feedback/toaster";
+
+export default function AnalysisContent() {
+ const t = useTranslations("analysis");
+ const tCommon = useTranslations("common");
+
+ const cardBg = useColorModeValue("white", "gray.800");
+ const borderColor = useColorModeValue("gray.100", "gray.700");
+
+ const [selectedMatchIds, setSelectedMatchIds] = useState([]);
+
+ const upcomingMatches = useQueryMatches();
+ const analyzeMutation = useAnalyzeMatches();
+ const historyQuery = useAnalysisHistory();
+ const toast = (opts: { title: string; status: string }) =>
+ toaster.create({
+ title: opts.title,
+ type: opts.status as
+ | "success"
+ | "warning"
+ | "error"
+ | "info"
+ | "loading",
+ });
+
+ const toggleMatch = (id: string) => {
+ setSelectedMatchIds((prev) =>
+ prev.includes(id) ? prev.filter((x) => x !== id) : [...prev, id],
+ );
+ };
+
+ const handleAnalyze = async () => {
+ if (selectedMatchIds.length < 2) {
+ toast({
+ title: t("select-at-least-2"),
+ status: "warning",
+ });
+ return;
+ }
+ await analyzeMutation.mutateAsync({ matchIds: selectedMatchIds });
+ toast({
+ title: t("analysis-complete"),
+ status: "success",
+ });
+ historyQuery.refetch();
+ };
+
+ const allMatches: { id: string; home: string; away: string; date: string }[] =
+ upcomingMatches.data?.data
+ ?.flatMap((league: LeagueWithMatchesDto) =>
+ league.matches?.map((m) => ({
+ id: m.id,
+ home: m.homeTeam?.name || "",
+ away: m.awayTeam?.name || "",
+ date: m.mstUtc ? new Date(m.mstUtc).toLocaleDateString() : "",
+ })),
+ )
+ .filter(Boolean) || [];
+
+ return (
+
+
+
+ {t("title")}
+
+
+
+ {/* Match Selection */}
+
+
+
+
+
+ {t("select-matches")}
+
+ 0 ? "primary" : "gray"
+ }
+ >
+ {selectedMatchIds.length} {t("selected")}
+
+
+
+
+ {upcomingMatches.isPending ? (
+
+
+
+ ) : (
+
+ {allMatches.map((m) => {
+ const isSelected = selectedMatchIds.includes(m.id);
+ return (
+ toggleMatch(m.id)}
+ >
+
+
+ {isSelected ? : null}
+
+
+ {m.home} vs {m.away}
+
+
+
+ {m.date}
+
+
+ );
+ })}
+
+ )}
+
+ {t("analyze-matches")}
+
+
+
+
+
+ {/* Analysis History */}
+
+
+
+
+
+
+ {t("history")}
+
+
+
+
+ {historyQuery.isLoading ? (
+
+
+
+ ) : historyQuery.data?.data?.analyses &&
+ historyQuery.data.data.analyses.length > 0 ? (
+
+ {historyQuery.data.data.analyses.map(
+ (a: {
+ id: string;
+ matchIds: string[];
+ createdAt: string;
+ }) => (
+
+
+
+
+ {a.matchIds.length} {t("matches-analyzed")}
+
+
+ {new Date(a.createdAt).toLocaleString()}
+
+
+
+
+ ),
+ )}
+
+ ) : (
+
+ {t("no-history")}
+
+ )}
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/auth/login-modal.tsx b/src/components/auth/login-modal.tsx
new file mode 100644
index 0000000..b400c8f
--- /dev/null
+++ b/src/components/auth/login-modal.tsx
@@ -0,0 +1,154 @@
+"use client";
+
+import { Box, Heading, Input, Text, VStack } from "@chakra-ui/react";
+import { Button } from "@/components/ui/buttons/button";
+import { Field } from "@/components/ui/forms/field";
+import { InputGroup } from "@/components/ui/forms/input-group";
+import { PasswordInput } from "@/components/ui/forms/password-input";
+import {
+ DialogBody,
+ DialogCloseTrigger,
+ DialogContent,
+ DialogHeader,
+ DialogRoot,
+ DialogTitle,
+} from "@/components/ui/overlays/dialog";
+import { useTranslations } from "next-intl";
+import { useForm } from "react-hook-form";
+import { yupResolver } from "@hookform/resolvers/yup";
+import * as yup from "yup";
+import { signIn } from "next-auth/react";
+import { toaster } from "@/components/ui/feedback/toaster";
+import { useState } from "react";
+import { MdMail } from "react-icons/md";
+import { BiLock } from "react-icons/bi";
+import { Link } from "@/i18n/navigation";
+
+const schema = yup.object({
+ email: yup.string().email().required(),
+ password: yup.string().min(6).required(),
+});
+
+type LoginForm = yup.InferType;
+
+interface LoginModalProps {
+ open: boolean;
+ onOpenChange: (open: boolean) => void;
+}
+
+export function LoginModal({ open, onOpenChange }: LoginModalProps) {
+ const t = useTranslations();
+ const [loading, setLoading] = useState(false);
+
+ const {
+ handleSubmit,
+ register,
+ formState: { errors },
+ } = useForm({
+ resolver: yupResolver(schema),
+ mode: "onChange",
+ });
+
+ const onSubmit = async (formData: LoginForm) => {
+ try {
+ setLoading(true);
+ const res = await signIn("credentials", {
+ redirect: false,
+ email: formData.email,
+ password: formData.password,
+ });
+
+ if (res?.error) {
+ throw new Error(res.error);
+ }
+
+ onOpenChange(false);
+ toaster.success({
+ title: t("auth.login-success") || "Login successful!",
+ type: "success",
+ });
+ } catch (error) {
+ toaster.error({
+ title: (error as Error).message || "Login failed!",
+ type: "error",
+ });
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ return (
+ onOpenChange(e.open)}>
+
+
+
+
+ {t("auth.sign-in")}
+
+
+
+
+
+
+
+
+ }>
+
+
+
+
+
+ }>
+
+
+
+
+
+ {t("auth.sign-in")}
+
+
+
+ {t("auth.dont-have-account")}{" "}
+
+ {t("auth.sign-up")}
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/coupons/coupon-builder-content.tsx b/src/components/coupons/coupon-builder-content.tsx
new file mode 100644
index 0000000..194bf32
--- /dev/null
+++ b/src/components/coupons/coupon-builder-content.tsx
@@ -0,0 +1,1159 @@
+"use client";
+
+import {
+ Badge,
+ Box,
+ Button,
+ Card,
+ Flex,
+ Grid,
+ Heading,
+ HStack,
+ Icon,
+ IconButton,
+ Separator,
+ SimpleGrid,
+ Spinner,
+ Text,
+ VStack,
+} from "@chakra-ui/react";
+import { useLocale, useMessages, useTranslations } from "next-intl";
+import React from "react";
+import {
+ LuBadgeAlert,
+ LuCheck,
+ LuCircleHelp,
+ LuEye,
+ LuEyeOff,
+ LuLayers3,
+ LuListChecks,
+ LuLock,
+ LuRefreshCcw,
+ LuShieldCheck,
+ LuSparkles,
+ LuTarget,
+ LuTrash,
+ LuTrophy,
+} from "react-icons/lu";
+import { SlideUp } from "@/components/motion";
+import { useColorModeValue } from "@/components/ui/color-mode";
+import { Tooltip } from "@/components/ui/overlays/tooltip";
+import { useSuggestCoupon } from "@/lib/api/coupons/use-hooks";
+import type {
+ CouponItemDto,
+ SmartCouponResultDto,
+ SuggestedCouponBetDto,
+} from "@/lib/api/coupons/types";
+import { useQueryMatches } from "@/lib/api/matches/use-hooks";
+import type {
+ LeagueWithMatchesDto,
+ MatchResponseDto,
+} from "@/lib/api/matches/types";
+import type { CouponStrategy } from "@/lib/api/predictions/types";
+import { useCouponStore } from "@/lib/stores/coupon-store";
+import { ApiError } from "@/lib/api/create-api-client";
+
+const formatDate = (ts: number | string, locale: string) =>
+ new Intl.DateTimeFormat(locale, {
+ day: "2-digit",
+ month: "short",
+ hour: "2-digit",
+ minute: "2-digit",
+ }).format(new Date(typeof ts === "string" ? Number(ts) : ts));
+const formatPercent = (v?: number, d = 0) =>
+ v === undefined || Number.isNaN(v) ? "-" : `${v.toFixed(d)}%`;
+const formatOdds = (v?: number) =>
+ v === undefined || Number.isNaN(v) ? "-" : v.toFixed(2);
+const strategyPalette = (s: CouponStrategy) =>
+ ({
+ SAFE: "green",
+ BALANCED: "blue",
+ AGGRESSIVE: "orange",
+ VALUE: "red",
+ MIRACLE: "purple",
+ })[s] || "gray";
+const riskPalette = (v?: string) =>
+ ({ LOW: "green", MEDIUM: "yellow", HIGH: "orange", EXTREME: "red" })[
+ (v || "").toUpperCase()
+ ] || "gray";
+const qualityPalette = (v?: string) =>
+ ({ HIGH: "green", MEDIUM: "yellow", LOW: "red" })[(v || "").toUpperCase()] ||
+ "gray";
+
+function normalizeSmartCouponResult(
+ value: unknown,
+): SmartCouponResultDto | undefined {
+ if (!value || typeof value !== "object") return undefined;
+
+ let payload = value as Record;
+
+ while (
+ payload &&
+ typeof payload === "object" &&
+ !Array.isArray(payload.bets) &&
+ payload.data &&
+ typeof payload.data === "object"
+ ) {
+ payload = payload.data as Record;
+ }
+
+ if (!Array.isArray(payload.bets)) return undefined;
+
+ return {
+ strategy: String(payload.strategy || "BALANCED") as CouponStrategy,
+ generated_at: String(payload.generated_at || ""),
+ match_count: Number(payload.match_count || 0),
+ bets: payload.bets as SuggestedCouponBetDto[],
+ total_odds: Number(payload.total_odds || 0),
+ expected_win_rate: Number(payload.expected_win_rate || 0),
+ rejected_matches: Array.isArray(payload.rejected_matches)
+ ? (payload.rejected_matches as SmartCouponResultDto["rejected_matches"])
+ : [],
+ };
+}
+
+function InfoIcon({ content, label }: { content: string; label: string }) {
+ return (
+
+
+
+
+
+ );
+}
+
+function StatCard({
+ label,
+ value,
+ helper,
+ accent,
+}: {
+ label: string;
+ value: string;
+ helper?: string;
+ accent?: string;
+}) {
+ const bg = useColorModeValue("white", "gray.900");
+ const borderColor = useColorModeValue("gray.200", "gray.700");
+ return (
+
+
+
+ {label}
+
+ {helper ? : null}
+
+
+ {value}
+
+
+ );
+}
+
+function MatchGroups({
+ groups,
+ selectable,
+ selectedIds,
+ locale,
+ onToggle,
+ badgeLabel,
+ secondaryBadge,
+ readOnlyLabel,
+ matchStateLabel,
+ finishedReferenceLabel,
+ t,
+ tCommon,
+}: {
+ groups: LeagueWithMatchesDto[];
+ selectable: boolean;
+ selectedIds: string[];
+ locale: string;
+ onToggle: (id: string) => void;
+ badgeLabel: string;
+ secondaryBadge?: string;
+ readOnlyLabel: string;
+ matchStateLabel: string;
+ finishedReferenceLabel: string;
+ t: ReturnType;
+ tCommon: ReturnType;
+}) {
+ const cardBg = useColorModeValue("white", "gray.800");
+ const mutedBg = useColorModeValue("gray.50", "whiteAlpha.50");
+ const borderColor = useColorModeValue("gray.200", "gray.700");
+ const selectedBorder = useColorModeValue("teal.400", "teal.300");
+ const subtleGreenBg = useColorModeValue("green.50", "green.950");
+
+ return (
+
+ {groups.map((league) => (
+
+
+
+ {league.name}
+
+ {league.country?.name} • {league.matches.length}{" "}
+ {t("match-count-suffix")}
+
+
+
+
+
+ {league.matches.map((match) => {
+ const selected = selectedIds.includes(match.id);
+ return (
+ onToggle(match.id) : undefined}
+ >
+
+
+
+
+ {badgeLabel}
+
+ {selectable && selected ? (
+
+ {t("selected-short")}
+
+ ) : null}
+ {!selectable && secondaryBadge ? (
+
+ {secondaryBadge}
+
+ ) : null}
+
+ {match.matchName}
+
+ {selectable ? (
+ {
+ e.stopPropagation();
+ onToggle(match.id);
+ }}
+ >
+ {selected ? t("selected-short") : t("select-match")}
+
+ ) : (
+
+
+ {readOnlyLabel}
+
+ )}
+
+
+
+
+ {tCommon("date")}
+
+
+ {formatDate(match.mstUtc, locale)}
+
+
+
+
+ {selectable ? t("selection-mode") : matchStateLabel}
+
+
+ {selectable
+ ? selected
+ ? t("manual-pool")
+ : t("auto-pool")
+ : finishedReferenceLabel}
+
+
+
+
+ );
+ })}
+
+
+
+ ))}
+
+ );
+}
+
+export default function CouponBuilderContent() {
+ const t = useTranslations("coupons");
+ const tCommon = useTranslations("common");
+ const locale = useLocale();
+ const messages = useMessages() as {
+ predictions?: { ["market-labels"]?: Record };
+ };
+ const marketLabels = messages?.predictions?.["market-labels"];
+ const copy = React.useCallback(
+ (tr: string, en: string) => (locale === "tr" ? tr : en),
+ [locale],
+ );
+ const cardBg = useColorModeValue("white", "gray.800");
+ const mutedBg = useColorModeValue("gray.50", "whiteAlpha.50");
+ const borderColor = useColorModeValue("gray.200", "gray.700");
+
+ const { items, addItem, clearCoupon, removeItem, strategy, setStrategy } =
+ useCouponStore();
+ const upcomingQuery = useQueryMatches();
+ const finishedQuery = useQueryMatches();
+ const suggestCoupon = useSuggestCoupon();
+
+ const [activeStrategy, setActiveStrategy] = React.useState(
+ strategy || "BALANCED",
+ );
+ const [selectedMatchIds, setSelectedMatchIds] = React.useState([]);
+ const [showFinishedMatches, setShowFinishedMatches] = React.useState(false);
+ const [suggestedCoupon, setSuggestedCoupon] = React.useState<
+ SmartCouponResultDto | undefined
+ >(undefined);
+ const [matchCount, setMatchCount] = React.useState(5); // Default: 5 matches
+
+ React.useEffect(() => {
+ if (!upcomingQuery.data && !upcomingQuery.isPending) {
+ upcomingQuery.mutate({
+ sport: "football",
+ status: "UPCOMING",
+ limit: 40,
+ });
+ }
+ }, [upcomingQuery.data, upcomingQuery.isPending, upcomingQuery.mutate]);
+
+ React.useEffect(() => {
+ if (
+ showFinishedMatches &&
+ !finishedQuery.data &&
+ !finishedQuery.isPending
+ ) {
+ finishedQuery.mutate({
+ sport: "football",
+ status: "FINISHED",
+ limit: 20,
+ });
+ }
+ }, [
+ finishedQuery.data,
+ finishedQuery.isPending,
+ finishedQuery.mutate,
+ showFinishedMatches,
+ ]);
+
+ React.useEffect(() => {
+ const coupon = suggestedCoupon;
+ if (!coupon?.bets?.length) return;
+ clearCoupon();
+ coupon.bets.forEach((bet) =>
+ addItem({
+ matchId: bet.match_id,
+ matchName: bet.match_name,
+ market: bet.market,
+ pick: bet.pick,
+ odd: bet.odds || 0,
+ }),
+ );
+ }, [addItem, clearCoupon, suggestedCoupon]);
+
+ const leagueGroups = upcomingQuery.data?.data ?? [];
+ const finishedLeagueGroups = finishedQuery.data?.data ?? [];
+ const allMatches = React.useMemo(
+ () => leagueGroups.flatMap((l) => l.matches),
+ [leagueGroups],
+ );
+ const allFinishedMatches = React.useMemo(
+ () => finishedLeagueGroups.flatMap((l) => l.matches),
+ [finishedLeagueGroups],
+ );
+ const selectedMatches = React.useMemo(() => {
+ const set = new Set(selectedMatchIds);
+ return allMatches.filter((m) => set.has(m.id));
+ }, [allMatches, selectedMatchIds]);
+
+ const suggestedBets: SuggestedCouponBetDto[] = suggestedCoupon?.bets ?? [];
+ const suggestErrorMessage =
+ suggestCoupon.error instanceof ApiError
+ ? suggestCoupon.error.message
+ : suggestCoupon.error instanceof Error
+ ? suggestCoupon.error.message
+ : undefined;
+ const strategies = [
+ {
+ key: "SAFE" as CouponStrategy,
+ label: t("strategy-safe"),
+ description: t("strategy-safe-desc"),
+ },
+ {
+ key: "BALANCED" as CouponStrategy,
+ label: t("strategy-balanced"),
+ description: t("strategy-balanced-desc"),
+ },
+ {
+ key: "AGGRESSIVE" as CouponStrategy,
+ label: t("strategy-aggressive"),
+ description: t("strategy-aggressive-desc"),
+ },
+ {
+ key: "VALUE" as CouponStrategy,
+ label: t("strategy-value"),
+ description: t("strategy-value-desc"),
+ },
+ ];
+
+ const toggleMatchSelection = (matchId: string) =>
+ setSelectedMatchIds((c) =>
+ c.includes(matchId) ? c.filter((id) => id !== matchId) : [...c, matchId],
+ );
+ const handleSuggest = () => {
+ setStrategy(activeStrategy);
+
+ // If no matches selected, send all upcoming matches for AI to choose from
+ const matchIdsToSend =
+ selectedMatchIds.length > 0
+ ? selectedMatchIds
+ : allMatches.map((m) => m.id); // Send all matches from bulletin
+
+ suggestCoupon.mutate(
+ {
+ matchIds: matchIdsToSend,
+ strategy: activeStrategy,
+ maxMatches: matchCount, // User's desired coupon size
+ },
+ {
+ onSuccess: (response) => {
+ setSuggestedCoupon(normalizeSmartCouponResult(response));
+ },
+ onError: () => {
+ setSuggestedCoupon(undefined);
+ },
+ },
+ );
+ };
+ const handleRefresh = () => {
+ upcomingQuery.reset();
+ upcomingQuery.mutate({ sport: "football", status: "UPCOMING", limit: 40 });
+ if (showFinishedMatches) {
+ finishedQuery.reset();
+ finishedQuery.mutate({
+ sport: "football",
+ status: "FINISHED",
+ limit: 20,
+ });
+ }
+ };
+ const getStoreItemLabel = (item: CouponItemDto) =>
+ `${marketLabels?.[item.market] || item.market}: ${item.pick}`;
+ const finishedMatchCountLabel = copy("Bitmis Mac", "Finished Matches");
+ const finishedMatchCountHelp = copy(
+ "Istege bagli referans listesi. Bu maclar kupon tahminine asla dahil edilmez.",
+ "Optional reference list of finished football matches. These are never used for coupon prediction.",
+ );
+ const finishedBadge = copy("Bitti", "Finished");
+ const predictionLocked = copy("Tahmine Kapali", "Prediction Locked");
+ const readOnlyShort = copy("Salt okunur", "Read only");
+ const matchState = copy("Mac Durumu", "Match State");
+ const finishedReferenceOnly = copy("Sadece referans", "Reference only");
+ const finishedMatchesTitle = copy("Bitmis Maclar", "Finished Matches");
+ const finishedMatchesHelp = copy(
+ "Bu maclar sadece referans icin gosterilir. Secilemezler ve backend tarafinda tahmin olusmadan once kesin olarak filtrelenirler.",
+ "These matches are shown only for reference. They cannot be selected and are filtered out on the backend before any coupon prediction is created.",
+ );
+ const finishedMatchesSubtitle = copy(
+ "Opsiyonel arsiv gorunumu. Skorlar ve mac sonu istatistikleri kupon tahmin akisina hicbir zaman gonderilmez.",
+ "Optional archive view. Scores and post-match stats are never sent into the coupon prediction flow.",
+ );
+ const showFinishedMatchesLabel = copy(
+ "Bitmis maclari goster",
+ "Show finished matches",
+ );
+ const hideFinishedMatchesLabel = copy(
+ "Bitmis maclari gizle",
+ "Hide finished matches",
+ );
+ const noFinishedMatchesLabel = copy(
+ "Bu gorunum icin bitmis futbol maci bulunamadi.",
+ "No finished football matches were found for the current view.",
+ );
+
+ return (
+
+
+
+ {t("builder-title")}
+
+
+ {t("builder-subtitle")}
+
+
+
+
+
+ 0 ? "teal.500" : undefined}
+ />
+ 0 ? "green.500" : undefined}
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+ {t("candidate-pool-title")}
+
+
+
+
+ {t("candidate-pool-subtitle")}
+
+
+
+
+ {tCommon("refresh")}
+
+
+
+
+
+ {upcomingQuery.isPending ? (
+
+
+
+ ) : leagueGroups.length > 0 ? (
+
+
+
+
+
+
+
+
+
+
+ {finishedMatchesTitle}
+
+
+
+
+ {finishedMatchesSubtitle}
+
+
+ setShowFinishedMatches((v) => !v)}
+ >
+ {showFinishedMatches ? : }
+ {showFinishedMatches
+ ? hideFinishedMatchesLabel
+ : showFinishedMatchesLabel}
+
+
+
+
+
+ {showFinishedMatches ? (
+ finishedQuery.isPending ? (
+
+
+
+ ) : finishedLeagueGroups.length > 0 ? (
+
+ ) : (
+
+
+
+ {noFinishedMatchesLabel}
+
+
+
+ )
+ ) : null}
+
+ ) : (
+
+
+
+ {t("no-upcoming-matches")}
+
+
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+ {t("my-coupon")}
+
+
+
+
+ {selectedMatchIds.length > 0
+ ? t("manual-selection-active")
+ : t("automatic-selection-active")}
+
+
+ {items.length > 0 ? (
+
+
+ {tCommon("clear")}
+
+ ) : null}
+
+
+
+
+ {t("strategy")}
+
+
+ {strategies.map((entry) => {
+ const active = activeStrategy === entry.key;
+ const palette = strategyPalette(entry.key);
+ return (
+ setActiveStrategy(entry.key)}
+ >
+
+
+ {entry.label}
+
+ {active ? : null}
+
+
+ {entry.description}
+
+
+ );
+ })}
+
+
+
+
+ {/* Match Count Input */}
+
+
+
+
+
+ {t("match-count-label")}
+
+
+
+
+ {matchCount}
+
+
+ setMatchCount(Number(e.target.value))}
+ style={{
+ width: "100%",
+ accentColor: "teal",
+ cursor: "pointer",
+ }}
+ />
+
+ 2
+
+ {t("match-count-auto", { count: allMatches.length })}
+
+ 15
+
+
+
+
+
+
+
+
+
+
+ {t("selected-matches-panel-title")}
+
+
+
+ {selectedMatchIds.length}
+
+
+ {selectedMatches.length > 0 ? (
+
+ {selectedMatches.map((match: MatchResponseDto) => (
+
+
+
+ {match.matchName}
+
+
+ {formatDate(match.mstUtc, locale)}
+
+
+ toggleMatchSelection(match.id)}
+ >
+ {t("remove-match")}
+
+
+ ))}
+
+ ) : (
+
+
+ {t("selected-matches-empty")}
+
+
+ )}
+
+
+
+
+ {t("ai-suggest")}
+
+
+ {selectedMatchIds.length > 0
+ ? t("manual-selection-helper")
+ : t("automatic-selection-helper")}
+
+
+
+
+
+
+
+
+
+
+ {t("suggested-bets-title")}
+
+
+
+ {suggestedCoupon ? (
+
+ {
+ strategies.find(
+ (e) => e.key === suggestedCoupon.strategy,
+ )?.label
+ }
+
+ ) : null}
+
+
+
+ {suggestedCoupon ? (
+
+
+
+
+ {t("expected-win-rate")}
+
+
+ {formatPercent(
+ suggestedCoupon.expected_win_rate * 100,
+ 0,
+ )}
+
+
+
+
+ {t("bet-count")}
+
+
+ {suggestedCoupon.match_count}
+
+
+
+
+ {suggestedBets.map((bet: SuggestedCouponBetDto) => (
+
+
+
+ {bet.match_name}
+
+ {marketLabels?.[bet.market] || bet.market} •{" "}
+ {bet.pick}
+
+
+
+ {formatOdds(bet.odds)}
+
+
+
+
+
+ {t("confidence-label")}
+
+
+ {formatPercent(bet.confidence, 0)}
+
+
+
+
+ {t("probability-label")}
+
+
+ {formatPercent(bet.probability * 100, 0)}
+
+
+
+
+
+ {t("risk-label")}: {bet.risk_level}
+
+
+ {t("data-quality-label")}: {bet.data_quality}
+
+
+
+ ))}
+
+ {suggestedCoupon.rejected_matches?.length ? (
+
+
+
+
+ {t("rejected-matches-title")}
+
+
+
+ {suggestedCoupon.rejected_matches.map((entry) => (
+
+ {entry.reason}
+
+ ))}
+
+
+ ) : null}
+
+ ) : suggestErrorMessage ? (
+
+
+ {suggestErrorMessage}
+
+
+ ) : (
+
+
+ {t("no-suggestion-yet")}
+
+
+ )}
+
+
+
+
+
+
+
+
+ {t("coupon")}
+
+
+
+
+ {items.length > 0 ? (
+
+ {items.map((item: CouponItemDto) => (
+
+
+
+ {item.matchName || item.matchId}
+
+
+ {getStoreItemLabel(item)}
+
+
+
+
+ {formatOdds(item.odd)}
+
+ removeItem(item.matchId)}
+ >
+ {tCommon("delete")}
+
+
+
+ ))}
+
+ ) : (
+
+ {t("empty-coupon")}
+
+ )}
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/coupons/coupon-history-content.tsx b/src/components/coupons/coupon-history-content.tsx
new file mode 100644
index 0000000..76ecaba
--- /dev/null
+++ b/src/components/coupons/coupon-history-content.tsx
@@ -0,0 +1,186 @@
+"use client";
+
+import {
+ Box,
+ Flex,
+ Heading,
+ Text,
+ Card,
+ VStack,
+ HStack,
+ Badge,
+ Spinner,
+ Separator,
+ Button,
+} from "@chakra-ui/react";
+import { useTranslations } from "next-intl";
+import { useColorModeValue } from "@/components/ui/color-mode";
+import { SlideUp, StaggerContainer, StaggerItem } from "@/components/motion";
+import { useCouponHistory } from "@/lib/api/coupons/use-hooks";
+import type { CouponResponseDto, CouponItemDto } from "@/lib/api/coupons/types";
+import { useState } from "react";
+
+type FilterType = "all" | "pending" | "won" | "lost";
+
+export default function CouponHistoryContent() {
+ const t = useTranslations("coupons");
+ const tCommon = useTranslations("common");
+ const [filter, setFilter] = useState("all");
+
+ const cardBg = useColorModeValue("white", "gray.800");
+ const borderColor = useColorModeValue("gray.100", "gray.700");
+
+ const { data, isLoading } = useCouponHistory();
+ const historyData = data?.data as
+ | { coupons?: CouponResponseDto[] }
+ | undefined;
+ const allCoupons: CouponResponseDto[] = historyData?.coupons ?? [];
+
+ const filteredCoupons =
+ filter === "all"
+ ? allCoupons
+ : allCoupons.filter(
+ (c: CouponResponseDto) => c.status?.toLowerCase() === filter,
+ );
+
+ const statusColors: Record = {
+ pending: "yellow",
+ won: "green",
+ lost: "red",
+ };
+
+ const filters: { key: FilterType; label: string }[] = [
+ { key: "all", label: tCommon("all") },
+ { key: "pending", label: t("pending") },
+ { key: "won", label: t("won") },
+ { key: "lost", label: t("lost") },
+ ];
+
+ return (
+
+
+
+ {t("history-title")}
+
+
+ {/* Filters */}
+
+ {filters.map((f) => (
+ setFilter(f.key)}
+ flexShrink={0}
+ >
+ {f.label}
+
+ ))}
+
+
+ {isLoading ? (
+
+
+
+ ) : filteredCoupons.length > 0 ? (
+
+
+ {filteredCoupons.map((coupon: CouponResponseDto, idx: number) => (
+
+
+
+
+
+
+ {t("coupon")} #{coupon.id?.slice(-6) || idx + 1}
+
+
+ {coupon.status || "—"}
+
+
+
+
+ {t("total-odd")}
+
+
+ {coupon.totalOdd?.toFixed(2) || "—"}
+
+
+
+
+
+ {coupon.items?.map(
+ (item: CouponItemDto, itemIdx: number) => (
+
+ {itemIdx > 0 && }
+
+
+
+ {item.matchId}
+
+
+ {item.market}: {item.pick}
+
+
+
+ {item.odd?.toFixed(2)}
+
+
+
+ ),
+ )}
+
+ {coupon.strategy && (
+
+
+ {t("strategy")}: {coupon.strategy}
+
+
+ {coupon.createdAt &&
+ new Date(coupon.createdAt).toLocaleDateString(
+ "tr-TR",
+ )}
+
+
+ )}
+
+
+
+ ))}
+
+
+ ) : (
+
+ {t("no-coupons")}
+
+ )}
+
+
+ );
+}
diff --git a/src/components/coupons/index.ts b/src/components/coupons/index.ts
new file mode 100644
index 0000000..ea64985
--- /dev/null
+++ b/src/components/coupons/index.ts
@@ -0,0 +1,2 @@
+export { default as CouponBuilderContent } from "./coupon-builder-content";
+export { default as CouponHistoryContent } from "./coupon-history-content";
diff --git a/src/components/dashboard/dashboard-content.tsx b/src/components/dashboard/dashboard-content.tsx
new file mode 100644
index 0000000..83c7f95
--- /dev/null
+++ b/src/components/dashboard/dashboard-content.tsx
@@ -0,0 +1,427 @@
+"use client";
+
+import {
+ Box,
+ Flex,
+ Heading,
+ Text,
+ SimpleGrid,
+ Card,
+ VStack,
+ HStack,
+ Badge,
+ Button,
+} from "@chakra-ui/react";
+import { useTranslations } from "next-intl";
+import { useColorModeValue } from "@/components/ui/color-mode";
+import { SlideUp, StaggerContainer, StaggerItem, ScrollSlideUp } from "@/components/motion";
+import { Skeleton } from "@/components/ui/feedback/skeleton";
+import { MatchCard } from "@/components/matches";
+import { useQueryMatches } from "@/lib/api/matches/use-hooks";
+import {
+ useUpcomingPredictions,
+ useValueBets,
+} from "@/lib/api/predictions/use-hooks";
+import { useUserBettingStats } from "@/lib/api/coupons/use-hooks";
+import { useSession } from "next-auth/react";
+import { LuTrendingUp, LuTarget, LuTicket, LuChartBar } from "react-icons/lu";
+import { useRouter } from "next/navigation";
+import type { LeagueWithMatchesDto, MatchResponseDto } from "@/lib/api/matches/types";
+import type { MatchPredictionDto, ValueBetDto } from "@/lib/api/predictions/types";
+
+// ========================
+// Stats Card
+// ========================
+
+interface StatCardProps {
+ label: string;
+ value: string | number;
+ icon: React.ReactNode;
+ colorPalette?: string;
+}
+
+function StatCard({
+ label,
+ value,
+ icon,
+ colorPalette = "primary",
+}: StatCardProps) {
+ const cardBg = useColorModeValue(
+ "rgba(255, 255, 255, 0.75)",
+ "rgba(26, 32, 44, 0.65)",
+ );
+ const borderColor = useColorModeValue(
+ "rgba(255, 255, 255, 0.8)",
+ "rgba(255, 255, 255, 0.06)",
+ );
+
+ return (
+
+
+
+
+ {icon}
+
+
+
+ {value}
+
+
+ {label}
+
+
+
+
+
+ );
+}
+
+// ========================
+// Value Bet Mini Card
+// ========================
+
+interface ValueBetMiniCardProps {
+ matchName: string;
+ prediction: string;
+ odd: number;
+ expectedValue: number;
+ confidence: number;
+}
+
+function ValueBetMiniCard({
+ matchName,
+ prediction,
+ odd,
+ expectedValue,
+ confidence,
+}: ValueBetMiniCardProps) {
+ const cardBg = useColorModeValue("white", "gray.800");
+ const borderColor = useColorModeValue("gray.100", "gray.700");
+
+ return (
+
+
+ {matchName}
+
+
+
+ {prediction}
+
+
+
+ EV+ {(expectedValue * 100).toFixed(0)}%
+
+
+ {odd.toFixed(2)}
+
+
+
+
+ );
+}
+
+// ========================
+// Dashboard Content
+// ========================
+
+export default function DashboardContent() {
+ const t = useTranslations("dashboard");
+ const tCoupons = useTranslations("coupons");
+ const router = useRouter();
+ const { data: session } = useSession();
+
+ const cardBg = useColorModeValue("white", "gray.800");
+ const borderColor = useColorModeValue("gray.100", "gray.700");
+
+ // Data fetching
+ const queryMatches = useQueryMatches();
+ const { data: upcomingData, isLoading: upcomingLoading } =
+ useUpcomingPredictions();
+ const { data: valueBetsData, isLoading: valueBetsLoading } = useValueBets();
+ const { data: statsData, isLoading: statsLoading } = useUserBettingStats();
+
+ // Trigger match fetch for today
+ if (!queryMatches.data && !queryMatches.isPending) {
+ queryMatches.mutate({ sport: "football", limit: 20 });
+ }
+
+ const todayMatches: MatchResponseDto[] = queryMatches.data?.data?.flatMap((l: LeagueWithMatchesDto) => l.matches) ?? [];
+ const upcomingPredictions: MatchPredictionDto[] = upcomingData?.data?.matches ?? [];
+ const valueBets: ValueBetDto[] = valueBetsData?.data ?? [];
+ const userStats = statsData?.data;
+
+ const userName = session?.user?.name || "";
+
+ return (
+
+
+ {/* Welcome Header */}
+
+
+ {t("title")}
+
+ {userName && (
+
+ {t("welcome")},{" "}
+
+ {userName}
+ {" "}
+ 👋
+
+ )}
+
+
+ {/* Stats Grid */}
+
+
+
+ }
+ colorPalette="primary"
+ />
+
+
+ }
+ colorPalette="green"
+ />
+
+
+ }
+ colorPalette="teal"
+ />
+
+
+ }
+ colorPalette="yellow"
+ />
+
+
+
+
+ {/* Two Column Layout */}
+
+ {/* Left Column — Today's Matches */}
+
+
+
+ {t("todays-matches")}
+
+ router.push("/matches")}
+ >
+ {t("view-all")} →
+
+
+
+ {queryMatches.isPending ? (
+
+ {Array.from({ length: 4 }).map((_, i) => (
+
+ ))}
+
+ ) : todayMatches.length > 0 ? (
+
+
+ {todayMatches.slice(0, 6).map((match: MatchResponseDto) => (
+
+
+
+ ))}
+
+
+ ) : (
+
+
+
+ {t("no-matches")}
+
+
+
+ )}
+
+
+ {/* Right Column — Predictions & Value Bets */}
+
+ {/* Upcoming Predictions */}
+
+
+
+
+ {t("upcoming-predictions")}
+
+ router.push("/predictions")}
+ >
+ {t("view-all")}
+
+
+
+
+ {upcomingLoading ? (
+
+ {Array.from({ length: 3 }).map((_, i) => (
+
+ ))}
+
+ ) : upcomingPredictions.length > 0 ? (
+
+ {upcomingPredictions.slice(0, 4).map((pred: MatchPredictionDto, idx: number) => (
+
+ router.push(`/matches/${pred.match_info.match_id}`)
+ }
+ >
+
+ {pred.match_info.home_team} vs{" "}
+ {pred.match_info.away_team}
+
+ {pred.main_pick && (
+
+
+ {pred.main_pick.pick}
+
+
+ {Math.round(
+ pred.main_pick.calibrated_confidence ??
+ pred.main_pick.confidence,
+ )}
+ %
+
+
+ )}
+
+ ))}
+
+ ) : (
+
+ {t("no-predictions")}
+
+ )}
+
+
+
+ {/* Value Bets */}
+
+
+
+ {t("value-bets")}
+
+
+
+ {valueBetsLoading ? (
+
+ {Array.from({ length: 3 }).map((_, i) => (
+
+ ))}
+
+ ) : valueBets.length > 0 ? (
+
+ {valueBets.slice(0, 5).map((vb: ValueBetDto, idx: number) => (
+
+ ))}
+
+ ) : (
+
+ {t("no-predictions")}
+
+ )}
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/dashboard/index.ts b/src/components/dashboard/index.ts
new file mode 100644
index 0000000..d71a8f8
--- /dev/null
+++ b/src/components/dashboard/index.ts
@@ -0,0 +1 @@
+export { default as DashboardContent } from "./dashboard-content";
diff --git a/src/components/h2h/h2h-content.tsx b/src/components/h2h/h2h-content.tsx
new file mode 100644
index 0000000..f530122
--- /dev/null
+++ b/src/components/h2h/h2h-content.tsx
@@ -0,0 +1,335 @@
+"use client";
+
+import {
+ Box,
+ Flex,
+ Heading,
+ Text,
+ Card,
+ VStack,
+ HStack,
+ Badge,
+ Spinner,
+ Input,
+ Button,
+} from "@chakra-ui/react";
+import { InputGroup } from "@/components/ui/forms/input-group";
+import { useTranslations } from "next-intl";
+import { useColorModeValue } from "@/components/ui/color-mode";
+import { SlideUp } from "@/components/motion";
+import { useSearchTeams, useHeadToHead } from "@/lib/api/leagues/use-hooks";
+import type { TeamDto, HeadToHeadDto } from "@/lib/api/leagues/types";
+import type { MatchResponseDto } from "@/lib/api/matches/types";
+import { LuSearch, LuArrowLeftRight } from "react-icons/lu";
+import { useState, useEffect } from "react";
+import { useDebounce } from "@/hooks/use-debounce";
+
+function TeamSearchInput({
+ label,
+ value,
+ onSelect,
+}: {
+ label: string;
+ value: TeamDto | null;
+ onSelect: (team: TeamDto) => void;
+}) {
+ const t = useTranslations("h2h");
+ const [query, setQuery] = useState("");
+ const debouncedQuery = useDebounce(query, 300);
+ const searchTeams = useSearchTeams(
+ debouncedQuery.length >= 2 ? { q: debouncedQuery } : { q: "" },
+ );
+
+ return (
+
+
+ {label}
+
+ }>
+ {
+ setQuery(e.target.value);
+ if (value) onSelect(null as unknown as TeamDto);
+ }}
+ placeholder={t("search-team")}
+ />
+
+ {debouncedQuery.length >= 2 && !value && searchTeams.data?.data && (
+
+ {searchTeams.data.data.map((team: TeamDto) => (
+ onSelect(team)}
+ align="center"
+ gap={2}
+ >
+ {team.logo ? (
+
+ ) : null}
+ {team.name}
+ {team.sport ? (
+
+ {team.sport}
+
+ ) : null}
+
+ ))}
+
+ )}
+
+ );
+}
+
+export default function H2HContent() {
+ const t = useTranslations("h2h");
+ const tMatches = useTranslations("matches");
+
+ const cardBg = useColorModeValue("white", "gray.800");
+ const borderColor = useColorModeValue("gray.100", "gray.700");
+
+ const [team1, setTeam1] = useState(null);
+ const [team2, setTeam2] = useState(null);
+ const [hasSearched, setHasSearched] = useState(false);
+
+ const h2h = useHeadToHead(
+ team1 && team2
+ ? { team1: team1.id, team2: team2.id }
+ : { team1: "", team2: "" },
+ );
+
+ const handleSearch = () => {
+ if (team1 && team2) {
+ setHasSearched(true);
+ h2h.refetch();
+ }
+ };
+
+ const stats: { label: string; value: number; color: string }[] = h2h.data
+ ?.data
+ ? [
+ {
+ label: team1?.name || t("team1"),
+ value: h2h.data.data.team1Wins,
+ color: "green",
+ },
+ {
+ label: t("draws"),
+ value: h2h.data.data.draws,
+ color: "gray",
+ },
+ {
+ label: team2?.name || t("team2"),
+ value: h2h.data.data.team2Wins,
+ color: "blue",
+ },
+ ]
+ : [];
+
+ return (
+
+
+
+
+
+ {t("title")}
+
+
+
+ {/* Team Selection */}
+
+
+
+
+ setTeam1(t)}
+ />
+
+
+ setTeam2(t)}
+ />
+
+
+ {t("compare")}
+
+
+
+
+
+ {/* Results */}
+ {hasSearched && (
+ <>
+ {/* Stats Bar */}
+ {h2h.isLoading ? (
+
+
+
+ ) : h2h.data?.data ? (
+ <>
+
+ {stats.map((s) => (
+
+
+
+ {s.value}
+
+
+ {s.label}
+
+
+
+ ))}
+
+
+ {/* Match History */}
+
+
+
+ {tMatches("recent-matches")} (
+ {h2h.data.data.matches?.length ?? 0})
+
+
+
+
+ {(
+ h2h.data.data.matches as
+ | MatchResponseDto[]
+ | undefined
+ | null
+ )?.map((match: MatchResponseDto) => {
+ const isHomeTeam1 = match.homeTeam?.id === team1?.id;
+ // Backend returns scoreHome/scoreAway, not homeScore/awayScore
+ const homeScore = Number((match as any).scoreHome ?? 0);
+ const awayScore = Number((match as any).scoreAway ?? 0);
+ const homeWon =
+ (isHomeTeam1 && homeScore > awayScore) ||
+ (!isHomeTeam1 && awayScore > homeScore);
+ const isDraw = homeScore === awayScore;
+
+ // Parse mstUtc - can be bigint string from backend
+ const matchDate = match.mstUtc
+ ? new Date(Number(match.mstUtc)).toLocaleDateString()
+ : "";
+
+ return (
+
+
+
+ {match.homeTeam?.name}
+
+
+ {homeScore ?? 0} - {awayScore ?? 0}
+
+
+ {match.awayTeam?.name}
+
+
+
+ {matchDate}
+
+
+ );
+ })}
+
+
+
+ >
+ ) : (
+
+
+ {t("no-matches-found")}
+
+
+ )}
+ >
+ )}
+
+
+ );
+}
diff --git a/src/components/home/home-content.tsx b/src/components/home/home-content.tsx
new file mode 100644
index 0000000..b9ce7e3
--- /dev/null
+++ b/src/components/home/home-content.tsx
@@ -0,0 +1,377 @@
+"use client";
+
+import {
+ Box,
+ Flex,
+ Heading,
+ Text,
+ Button,
+ SimpleGrid,
+ Card,
+ VStack,
+ HStack,
+ Icon,
+} from "@chakra-ui/react";
+import { useTranslations } from "next-intl";
+import { useRouter } from "next/navigation";
+import { useColorModeValue } from "@/components/ui/color-mode";
+import { motion } from "framer-motion";
+import {
+ ScrollSlideUp,
+ StaggerContainer,
+ StaggerItem,
+ AnimatedCounter,
+ Sparkles,
+ GradientOrb,
+ ScrollScaleIn,
+ springs,
+} from "@/components/motion";
+import { LuBrain, LuTrendingUp, LuTicket, LuRadio } from "react-icons/lu";
+
+const MotionBox = motion.create(Box);
+
+// ========================
+// Feature Card — glassmorphic with hover glow
+// ========================
+
+interface FeatureCardProps {
+ icon: React.ReactNode;
+ title: string;
+ description: string;
+ colorPalette: string;
+}
+
+function FeatureCard({
+ icon,
+ title,
+ description,
+ colorPalette,
+}: FeatureCardProps) {
+ const cardBg = useColorModeValue(
+ "rgba(255, 255, 255, 0.8)",
+ "rgba(26, 32, 44, 0.7)",
+ );
+ const borderColor = useColorModeValue(
+ "rgba(255, 255, 255, 0.6)",
+ "rgba(255, 255, 255, 0.06)",
+ );
+
+ return (
+
+ {/* Hover glow effect */}
+
+
+
+
+ {icon}
+
+
+
+ {title}
+
+
+ {description}
+
+
+
+
+
+ );
+}
+
+// ========================
+// Stat Block — with real counting animation
+// ========================
+
+interface StatBlockProps {
+ value: number;
+ label: string;
+ suffix?: string;
+}
+
+function StatBlock({ value, label, suffix }: StatBlockProps) {
+ return (
+
+
+
+
+
+ {label}
+
+
+ );
+}
+
+// ========================
+// Home Content — Premium
+// ========================
+
+export default function HomeContent() {
+ const t = useTranslations("landing");
+ const router = useRouter();
+
+ const heroBg = useColorModeValue(
+ "linear-gradient(135deg, #E6FFFA 0%, #C4F1F9 25%, #B2F5EA 50%, #81E6D9 75%, #4FD1C5 100%)",
+ "linear-gradient(135deg, #1A202C 0%, #1D4044 30%, #234E52 60%, #285E61 100%)",
+ );
+ const heroTextColor = useColorModeValue("gray.800", "white");
+ const statsBg = useColorModeValue(
+ "rgba(255, 255, 255, 0.6)",
+ "rgba(26, 32, 44, 0.6)",
+ );
+ const statsBorder = useColorModeValue(
+ "rgba(255, 255, 255, 0.8)",
+ "rgba(255, 255, 255, 0.06)",
+ );
+
+ return (
+
+ {/* Hero Section */}
+
+
+ {/* Animated gradient orbs */}
+
+
+
+
+ {/* Sparkle particles */}
+
+
+ {/* Decorative grid pattern */}
+
+
+
+
+
+ {t("hero-title")}
+
+
+
+
+
+ {t("hero-subtitle")}
+
+
+
+
+
+ router.push("/matches")}
+ _hover={{ transform: "scale(1.05)", shadow: "xl" }}
+ transition="all 0.3s"
+ className="animate-glow"
+ >
+ {t("get-started")} →
+
+
+ {t("learn-more")}
+
+
+
+
+
+
+
+ {/* Stats Section — glassmorphic card */}
+
+
+
+
+
+
+
+
+
+
+
+ {/* Features Section */}
+
+
+
+ {t("features-title")}
+
+
+ {t("hero-subtitle")}
+
+
+
+
+
+
+ }
+ title={t("feature-ai")}
+ description={t("feature-ai-desc")}
+ colorPalette="primary"
+ />
+
+
+ }
+ title={t("feature-value")}
+ description={t("feature-value-desc")}
+ colorPalette="green"
+ />
+
+
+ }
+ title={t("feature-coupon")}
+ description={t("feature-coupon-desc")}
+ colorPalette="purple"
+ />
+
+
+ }
+ title={t("feature-live")}
+ description={t("feature-live-desc")}
+ colorPalette="red"
+ />
+
+
+
+
+
+ );
+}
diff --git a/src/components/home/index.ts b/src/components/home/index.ts
new file mode 100644
index 0000000..9b3702a
--- /dev/null
+++ b/src/components/home/index.ts
@@ -0,0 +1 @@
+export { default as HomeContent } from "./home-content";
diff --git a/src/components/layout/footer/footer.tsx b/src/components/layout/footer/footer.tsx
new file mode 100644
index 0000000..3bd3b19
--- /dev/null
+++ b/src/components/layout/footer/footer.tsx
@@ -0,0 +1,68 @@
+"use client";
+
+import { Box, Text, HStack, Flex, Link as ChakraLink } from "@chakra-ui/react";
+import { Link } from "@/i18n/navigation";
+import { useTranslations } from "next-intl";
+
+export default function Footer() {
+ const t = useTranslations();
+
+ return (
+
+
+
+ © {new Date().getFullYear()}{" "}
+
+ Suggest Bet
+
+ . {t("all-right-reserved")}
+
+
+
+
+ {t("privacy-policy")}
+
+
+ {t("terms-of-service")}
+
+
+
+
+ );
+}
diff --git a/src/components/layout/header/header-link.tsx b/src/components/layout/header/header-link.tsx
new file mode 100644
index 0000000..030970b
--- /dev/null
+++ b/src/components/layout/header/header-link.tsx
@@ -0,0 +1,120 @@
+import { Box, Link as ChakraLink, Text } from "@chakra-ui/react";
+import { NavItem } from "@/config/navigation";
+import {
+ MenuContent,
+ MenuItem,
+ MenuRoot,
+ MenuTrigger,
+} from "@/components/ui/overlays/menu";
+import { RxChevronDown } from "react-icons/rx";
+import { useActiveNavItem } from "@/hooks/useActiveNavItem";
+import { Link } from "@/i18n/navigation";
+import { useTranslations } from "next-intl";
+import { useRef, useState } from "react";
+
+function HeaderLink({ item }: { item: NavItem }) {
+ const t = useTranslations("nav");
+ const { isActive, isChildActive } = useActiveNavItem(item);
+ const [open, setOpen] = useState(false);
+ const timeoutRef = useRef(null);
+
+ const handleMouseOpen = () => {
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
+ setOpen(true);
+ };
+
+ const handleMouseClose = () => {
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
+ timeoutRef.current = setTimeout(() => setOpen(false), 150);
+ };
+
+ const activeBg = { base: "primary.50", _dark: "primary.950" };
+ const activeColor = { base: "primary.600", _dark: "primary.300" };
+ const hoverBg = { base: "gray.50", _dark: "gray.800" };
+
+ return (
+
+ {item.children ? (
+
+ setOpen(e.open)}>
+
+
+ {t(item.label)}
+
+
+
+
+ {item.children.map((child) => {
+ const isActiveChild = isChildActive(child.href);
+ return (
+
+
+ {t(child.label)}
+
+
+ );
+ })}
+
+
+
+ ) : (
+
+ {t(item.label)}
+
+ )}
+
+ );
+}
+
+export default HeaderLink;
diff --git a/src/components/layout/header/header.tsx b/src/components/layout/header/header.tsx
new file mode 100644
index 0000000..40a9a97
--- /dev/null
+++ b/src/components/layout/header/header.tsx
@@ -0,0 +1,302 @@
+"use client";
+
+import {
+ Box,
+ Flex,
+ HStack,
+ IconButton,
+ Link as ChakraLink,
+ Stack,
+ VStack,
+ Button,
+ MenuItem,
+ ClientOnly,
+ Text,
+ Separator,
+} from "@chakra-ui/react";
+import { Link, useRouter } from "@/i18n/navigation";
+import { ColorModeButton } from "@/components/ui/color-mode";
+import {
+ PopoverBody,
+ PopoverContent,
+ PopoverRoot,
+ PopoverTrigger,
+} from "@/components/ui/overlays/popover";
+import { RxHamburgerMenu } from "react-icons/rx";
+import { NAV_ITEMS, getVisibleNavItems } from "@/config/navigation";
+import HeaderLink from "./header-link";
+import MobileHeaderLink from "./mobile-header-link";
+import LocaleSwitcher from "@/components/ui/locale-switcher";
+import { useEffect, useState } from "react";
+import { useTranslations } from "next-intl";
+import {
+ MenuContent,
+ MenuRoot,
+ MenuTrigger,
+} from "@/components/ui/overlays/menu";
+import { Avatar } from "@/components/ui/data-display/avatar";
+import { Skeleton } from "@/components/ui/feedback/skeleton";
+import { signOut, useSession } from "next-auth/react";
+import { authConfig } from "@/config/auth";
+import { LoginModal } from "@/components/auth/login-modal";
+import { LuLogIn, LuUser, LuShield, LuZap } from "react-icons/lu";
+import GlobalSearch from "@/components/search/global-search";
+
+export default function Header() {
+ const t = useTranslations();
+ const [isSticky, setIsSticky] = useState(false);
+ const [loginModalOpen, setLoginModalOpen] = useState(false);
+ const router = useRouter();
+ const { data: session, status } = useSession();
+
+ const isAuthenticated = !!session;
+ const isLoading = status === "loading";
+ const visibleItems = getVisibleNavItems(NAV_ITEMS, isAuthenticated);
+
+ useEffect(() => {
+ const handleScroll = () => setIsSticky(window.scrollY >= 10);
+ window.addEventListener("scroll", handleScroll);
+ return () => window.removeEventListener("scroll", handleScroll);
+ }, []);
+
+ const handleLogout = async () => {
+ await signOut({ redirect: false });
+ if (authConfig.isAuthRequired) {
+ router.replace("/signin");
+ }
+ };
+
+ // Desktop auth section
+ const renderAuthSection = () => {
+ if (isLoading) return ;
+
+ if (isAuthenticated) {
+ return (
+
+
+
+
+
+ router.push("/profile")}>
+
+ {t("nav.profile")}
+
+ {session?.user &&
+ session.user.roles?.includes("ADMIN") && (
+ router.push("/admin")}>
+
+ {t("nav.admin")}
+
+ )}
+
+ {t("auth.sign-out")}
+
+
+
+ );
+ }
+
+ return (
+ setLoginModalOpen(true)}
+ >
+
+ {t("auth.sign-in")}
+
+ );
+ };
+
+ // Mobile auth section
+ const renderMobileAuthSection = () => {
+ if (isLoading) return ;
+
+ if (isAuthenticated) {
+ return (
+
+
+
+
+ {session?.user?.name || session?.user?.email}
+
+
+ router.push("/profile")}
+ >
+
+ {t("nav.profile")}
+
+
+ {t("auth.sign-out")}
+
+
+ );
+ }
+
+ return (
+ setLoginModalOpen(true)}
+ >
+
+ {t("auth.sign-in")}
+
+ );
+ };
+
+ return (
+ <>
+
+
+ {/* Logo */}
+
+
+
+
+
+
+ Suggest
+
+
+ BET
+
+
+
+
+ {/* DESKTOP NAVIGATION */}
+
+ {visibleItems.map((item) => (
+
+ ))}
+
+
+ {/* Right side actions */}
+
+ {/* Global Search (Desktop) */}
+
+
+
+
+
+
+
+
+
+ }>
+ {renderAuthSection()}
+
+
+
+ {/* MOBILE NAVIGATION */}
+
+ }>
+
+
+
+
+
+
+
+
+
+ {visibleItems.map((item) => (
+
+ ))}
+
+
+
+ {renderMobileAuthSection()}
+
+
+
+
+
+
+
+
+
+
+ {/* Login Modal */}
+
+ >
+ );
+}
diff --git a/src/components/layout/header/mobile-header-link.tsx b/src/components/layout/header/mobile-header-link.tsx
new file mode 100644
index 0000000..4bf4c3c
--- /dev/null
+++ b/src/components/layout/header/mobile-header-link.tsx
@@ -0,0 +1,117 @@
+import {
+ Text,
+ Box,
+ Link as ChakraLink,
+ useDisclosure,
+ VStack,
+} from "@chakra-ui/react";
+import { RxChevronDown } from "react-icons/rx";
+import { NavItem } from "@/config/navigation";
+import { useActiveNavItem } from "@/hooks/useActiveNavItem";
+import { Link } from "@/i18n/navigation";
+import { useTranslations } from "next-intl";
+
+function MobileHeaderLink({ item }: { item: NavItem }) {
+ const t = useTranslations("nav");
+ const { isActive, isChildActive } = useActiveNavItem(item);
+ const { open, onToggle } = useDisclosure();
+
+ const activeColor = { base: "primary.600", _dark: "primary.300" };
+ const activeBg = { base: "primary.50", _dark: "primary.950" };
+
+ return (
+
+ {item.children ? (
+
+
+ {t(item.label)}
+
+
+ {open && item.children && (
+
+ {item.children.map((child) => {
+ const isActiveChild = isChildActive(child.href);
+ return (
+
+ {t(child.label)}
+
+ );
+ })}
+
+ )}
+
+ ) : (
+
+ {t(item.label)}
+
+ )}
+
+ );
+}
+
+export default MobileHeaderLink;
diff --git a/src/components/leagues/leagues-content.tsx b/src/components/leagues/leagues-content.tsx
new file mode 100644
index 0000000..fb95974
--- /dev/null
+++ b/src/components/leagues/leagues-content.tsx
@@ -0,0 +1,335 @@
+"use client";
+
+import {
+ Box,
+ Flex,
+ Heading,
+ Text,
+ Card,
+ VStack,
+ HStack,
+ Badge,
+ Spinner,
+ Input,
+ Tabs,
+} from "@chakra-ui/react";
+import { useTranslations } from "next-intl";
+import { useColorModeValue } from "@/components/ui/color-mode";
+import { SlideUp } from "@/components/motion";
+import {
+ useCountries,
+ useLeagues,
+ useSearchTeams,
+} from "@/lib/api/leagues/use-hooks";
+import type { CountryDto, LeagueDto, TeamDto } from "@/lib/api/leagues/types";
+import { LuSearch, LuGlobe, LuTrophy, LuUsers } from "react-icons/lu";
+import { useState } from "react";
+import { useDebounce } from "@/hooks/use-debounce";
+import { Link } from "@/i18n/navigation";
+import { InputGroup } from "@/components/ui/forms/input-group";
+import { Link as ChakraLink } from "@chakra-ui/react";
+
+export default function LeaguesContent() {
+ const t = useTranslations("leagues");
+ const tMatches = useTranslations("matches");
+
+ const cardBg = useColorModeValue("white", "gray.800");
+ const borderColor = useColorModeValue("gray.100", "gray.700");
+
+ const [activeTab, setActiveTab] = useState<"leagues" | "teams">("leagues");
+ const [sportFilter, setSportFilter] = useState("");
+ const [searchQuery, setSearchQuery] = useState("");
+ const debouncedQuery = useDebounce(searchQuery, 300);
+
+ const countries = useCountries();
+ const leagues = useLeagues(
+ sportFilter
+ ? { sport: sportFilter as "football" | "basketball" }
+ : undefined,
+ );
+ const searchTeams = useSearchTeams(
+ debouncedQuery.length >= 2 ? { q: debouncedQuery } : { q: "" },
+ );
+
+ return (
+
+
+
+ {t("title")}
+
+
+ setActiveTab(e.value as "leagues" | "teams")}
+ >
+
+
+
+ {t("countries-leagues")}
+
+
+
+ {tMatches("search-teams")}
+
+
+
+ {/* Countries & Leagues Tab */}
+
+
+ {/* Countries Sidebar */}
+
+
+
+
+
+
+ {t("countries")}
+
+
+
+
+ {countries.isLoading ? (
+
+
+
+ ) : (
+
+ {countries.data?.data?.map((country: CountryDto) => (
+
+
+ {country.flag ? (
+
+ ) : null}
+ {country.name}
+
+
+ {country.leagues?.length || 0}
+
+
+ ))}
+
+ )}
+
+
+
+
+ {/* Leagues List */}
+
+
+
+
+
+
+
+ {t("leagues")}
+
+
+
+ setSportFilter("")}
+ >
+ {tMatches("all")}
+
+
+ setSportFilter(
+ sportFilter === "football" ? "" : "football",
+ )
+ }
+ >
+ {tMatches("football")}
+
+
+ setSportFilter(
+ sportFilter === "basketball" ? "" : "basketball",
+ )
+ }
+ >
+ {tMatches("basketball")}
+
+
+
+
+
+ {leagues.isLoading ? (
+
+
+
+ ) : (
+
+ {leagues.data?.data?.map((league: LeagueDto) => (
+
+
+ {league.name}
+
+ {league.country?.name || ""}
+
+
+
+ {league.sport ? (
+
+ {league.sport}
+
+ ) : null}
+ {league.season ? (
+
+ {league.season}
+
+ ) : null}
+
+
+ ))}
+
+ )}
+
+
+
+
+
+
+ {/* Teams Search Tab */}
+
+
+
+ } mb={4}>
+ setSearchQuery(e.target.value)}
+ />
+
+ {debouncedQuery.length < 2 ? (
+
+ {t("search-at-least-2")}
+
+ ) : searchTeams.isLoading ? (
+
+
+
+ ) : (
+
+ {searchTeams.data?.data?.map((team: TeamDto) => (
+
+ {team.logo ? (
+
+ ) : (
+
+ )}
+
+ {team.name}
+
+ {team.country || ""}
+
+
+
+ {team.sport}
+
+
+ ))}
+
+ )}
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/matches/index.ts b/src/components/matches/index.ts
new file mode 100644
index 0000000..d7acc10
--- /dev/null
+++ b/src/components/matches/index.ts
@@ -0,0 +1,7 @@
+export { default as MatchCard } from "./match-card";
+export { default as MatchList } from "./match-list";
+export { default as SportFilter } from "./sport-filter";
+export { default as LeagueSidebar } from "./league-sidebar";
+export { default as PredictionCard } from "./prediction-card";
+export { default as MatchDetailContent } from "./match-detail-content";
+export { default as MatchesContent } from "./matches-content";
diff --git a/src/components/matches/league-sidebar.tsx b/src/components/matches/league-sidebar.tsx
new file mode 100644
index 0000000..2e01b8f
--- /dev/null
+++ b/src/components/matches/league-sidebar.tsx
@@ -0,0 +1,162 @@
+"use client";
+
+import { Box, VStack, Text, Badge, Flex, Image } from "@chakra-ui/react";
+import { useTranslations } from "next-intl";
+import { useColorModeValue } from "@/components/ui/color-mode";
+import type { ActiveLeagueDto } from "@/lib/api/matches/types";
+
+interface LeagueSidebarProps {
+ leagues: ActiveLeagueDto[];
+ selectedLeagueId: string | null;
+ onSelect: (leagueId: string | null) => void;
+ isLoading?: boolean;
+}
+
+export default function LeagueSidebar({
+ leagues,
+ selectedLeagueId,
+ onSelect,
+ isLoading,
+}: LeagueSidebarProps) {
+ const t = useTranslations("matches");
+
+ const bg = useColorModeValue("white", "gray.800");
+ const borderColor = useColorModeValue("gray.100", "gray.700");
+ const activeBg = useColorModeValue("primary.50", "primary.900");
+ const hoverBg = useColorModeValue("gray.50", "gray.750");
+
+ if (isLoading) {
+ return (
+
+
+ {Array.from({ length: 6 }).map((_, i) => (
+
+ ))}
+
+
+ );
+ }
+
+ return (
+
+ {/* Header */}
+
+
+ {t("active-leagues")}
+
+
+
+ {/* All Leagues Option */}
+ onSelect(null)}
+ transition="background 0.15s"
+ borderBottomWidth="1px"
+ borderColor={borderColor}
+ >
+
+ {t("all-leagues")}
+
+
+
+ {/* League List */}
+
+ {leagues.map((league) => {
+ const isActive = selectedLeagueId === league.id;
+ return (
+ onSelect(league.id)}
+ transition="background 0.15s"
+ borderBottomWidth="1px"
+ borderColor={borderColor}
+ >
+
+
+ {league.countryFlag && (
+
+ )}
+
+ {league.name}
+
+
+
+
+ {league.liveCount > 0 && (
+
+ {league.liveCount}
+
+ )}
+
+ {league.matchCount}
+
+
+
+
+ );
+ })}
+
+
+ );
+}
diff --git a/src/components/matches/match-card.tsx b/src/components/matches/match-card.tsx
new file mode 100644
index 0000000..83309d7
--- /dev/null
+++ b/src/components/matches/match-card.tsx
@@ -0,0 +1,228 @@
+"use client";
+
+import {
+ Box,
+ Flex,
+ Text,
+ Badge,
+ HStack,
+ VStack,
+ Image,
+} from "@chakra-ui/react";
+import { useTranslations } from "next-intl";
+import { useRouter } from "next/navigation";
+import { motion } from "framer-motion";
+import { slideUpVariants } from "@/components/motion";
+import type { MatchResponseDto } from "@/lib/api/matches/types";
+import { useColorModeValue } from "@/components/ui/color-mode";
+
+interface MatchCardProps {
+ match: MatchResponseDto;
+}
+
+const MotionBox = motion.create(Box);
+
+export default function MatchCard({ match }: MatchCardProps) {
+ const t = useTranslations("matches");
+ const router = useRouter();
+
+ const cardBg = useColorModeValue("white", "gray.800");
+ const cardBorder = useColorModeValue("gray.100", "gray.700");
+ const hoverBg = useColorModeValue("gray.50", "gray.750");
+ const hoverBorder = useColorModeValue("primary.200", "primary.500");
+
+ const isLive = match.status === "LIVE";
+ const isFinished = match.status === "Finished";
+
+ const statusColor = isLive ? "red" : isFinished ? "gray" : "green";
+ const statusText = isLive
+ ? t("live")
+ : isFinished
+ ? t("finished")
+ : t("not-started");
+
+ const handleClick = () => {
+ router.push(`/matches/${match.id}`);
+ };
+
+ // Date handling from timestamp (mstUtc)
+ const matchDate = new Date(match.mstUtc);
+
+ return (
+
+ {/* Status Badge */}
+
+
+ {isLive && (
+
+ )}
+ {statusText}
+
+
+
+ {matchDate.toLocaleDateString("tr-TR", {
+ day: "2-digit",
+ month: "short",
+ hour: "2-digit",
+ minute: "2-digit",
+ })}
+
+
+
+ {/* Teams */}
+
+ {/* Home Team */}
+
+ {match.homeTeamLogo ? (
+
+ ) : (
+
+
+ {match.homeTeamName?.charAt(0) || "H"}
+
+
+ )}
+
+ {match.homeTeamName}
+
+
+
+ {/* Score or VS */}
+
+ {(isLive || isFinished) &&
+ match.scoreHome !== undefined &&
+ match.scoreAway !== undefined ? (
+
+
+ {match.scoreHome}
+
+
+ -
+
+
+ {match.scoreAway}
+
+
+ ) : (
+
+ {t("vs")}
+
+ )}
+
+
+ {/* Away Team */}
+
+ {match.awayTeamLogo ? (
+
+ ) : (
+
+
+ {match.awayTeamName?.charAt(0) || "A"}
+
+
+ )}
+
+ {match.awayTeamName}
+
+
+
+
+ {/* League Info */}
+ {(match.leagueName || match.countryName) && (
+
+ {/* Flag handling if available in flat response, otherwise skip or pass from parent */}
+
+ {match.countryName && `${match.countryName} • `}
+ {match.leagueName}
+
+
+ )}
+
+ );
+}
diff --git a/src/components/matches/match-detail-content.tsx b/src/components/matches/match-detail-content.tsx
new file mode 100644
index 0000000..4d92d2c
--- /dev/null
+++ b/src/components/matches/match-detail-content.tsx
@@ -0,0 +1,281 @@
+"use client";
+
+import {
+ Box,
+ Flex,
+ Text,
+ Heading,
+ Badge,
+ VStack,
+ HStack,
+ Image,
+ Spinner,
+ Button,
+ Card,
+} from "@chakra-ui/react";
+import { useTranslations } from "next-intl";
+import { useParams, useRouter } from "next/navigation";
+import { useColorModeValue } from "@/components/ui/color-mode";
+import { SlideUp } from "@/components/motion";
+import { useMatchDetails } from "@/lib/api/matches/use-hooks";
+import { usePrediction } from "@/lib/api/predictions/use-hooks";
+import PredictionCard from "@/components/matches/prediction-card";
+import OddsCard from "@/components/matches/odds-card";
+import { LuArrowLeft, LuRefreshCw } from "react-icons/lu";
+
+export default function MatchDetailContent() {
+ const t = useTranslations("matches");
+ const tPred = useTranslations("predictions");
+ const tCommon = useTranslations("common");
+ const params = useParams();
+ const router = useRouter();
+
+ const matchId = params.id as string;
+
+ const { data: matchData, isLoading: matchLoading } = useMatchDetails(matchId);
+ const {
+ data: predictionData,
+ isLoading: predLoading,
+ refetch: refetchPrediction,
+ } = usePrediction(matchId);
+
+ const headerBg = useColorModeValue("white", "gray.800");
+ const borderColor = useColorModeValue("gray.100", "gray.700");
+
+ const match = matchData?.data;
+ const prediction = predictionData?.data;
+
+ if (matchLoading) {
+ return (
+
+
+
+ );
+ }
+
+ if (!match) {
+ return (
+
+
+ {t("no-matches")}
+
+ router.back()}>
+
+ {tCommon("back")}
+
+
+ );
+ }
+
+ const isLive = match.status === "LIVE";
+ const isFinished = match.status === "Finished";
+
+ return (
+
+
+ {/* Back Button */}
+ router.back()}
+ gap={1.5}
+ >
+
+ {tCommon("back")}
+
+ {/* Match Header */}
+
+
+ {/* League Info */}
+ {match.league && (
+
+ {match.league.country?.flag && (
+
+ )}
+
+ {match.league.name}
+
+
+ {isLive && (
+
+ )}
+ {isLive
+ ? t("live")
+ : isFinished
+ ? t("finished")
+ : t("not-started")}
+
+
+ )}
+
+ {/* Teams & Score */}
+
+ {/* Home Team */}
+
+ {match.homeTeam?.logo ? (
+
+ ) : (
+
+
+ {match.homeTeam?.name?.charAt(0) || "H"}
+
+
+ )}
+
+ {match.homeTeam?.name}
+
+
+ {t("home-team")}
+
+
+
+ {/* Score */}
+
+ {match.score && (isLive || isFinished) ? (
+
+
+ {match.score.home}
+
+
+ -
+
+
+ {match.score.away}
+
+
+ ) : (
+
+ {t("vs")}
+
+ )}
+
+ {new Date(match.mstUtc).toLocaleDateString("tr-TR", {
+ weekday: "short",
+ day: "2-digit",
+ month: "short",
+ year: "numeric",
+ hour: "2-digit",
+ minute: "2-digit",
+ })}
+
+
+
+ {/* Away Team */}
+
+ {match.awayTeam?.logo ? (
+
+ ) : (
+
+
+ {match.awayTeam?.name?.charAt(0) || "A"}
+
+
+ )}
+
+ {match.awayTeam?.name}
+
+
+ {t("away-team")}
+
+
+
+
+
+
+ {/* Prediction Section */}
+
+
+
+ {tPred("title")}
+
+ refetchPrediction()}
+ gap={1.5}
+ >
+
+ {tCommon("refresh")}
+
+
+
+ {predLoading ? (
+
+
+
+ ) : prediction ? (
+
+ ) : (
+
+
+
+ {tPred("no-predictions")}
+
+
+
+ )}
+
+
+ {/* Odds Section */}
+ {match.odds && Object.keys(match.odds).length > 0 && (
+
+ )}
+
+
+ );
+}
diff --git a/src/components/matches/match-list.tsx b/src/components/matches/match-list.tsx
new file mode 100644
index 0000000..8fac2bc
--- /dev/null
+++ b/src/components/matches/match-list.tsx
@@ -0,0 +1,203 @@
+"use client";
+
+import { Box, Grid, Text, Flex, Image, HStack, VStack } from "@chakra-ui/react";
+import { useTranslations } from "next-intl";
+import { useColorModeValue } from "@/components/ui/color-mode";
+import { StaggerContainer, StaggerItem, ScrollSlideUp } from "@/components/motion";
+import { Skeleton } from "@/components/ui/feedback/skeleton";
+import MatchCard from "./match-card";
+import type {
+ LeagueWithMatchesDto,
+ MatchResponseDto,
+} from "@/lib/api/matches/types";
+
+// ========================
+// Match Card Skeleton — realistic loading placeholder
+// ========================
+
+function MatchCardSkeleton() {
+ const bg = useColorModeValue("white", "gray.800");
+ const border = useColorModeValue("gray.100", "gray.700");
+
+ return (
+
+ {/* Status + Date */}
+
+
+
+
+
+ {/* Teams */}
+
+ {/* Home */}
+
+
+
+
+
+ {/* VS / Score */}
+
+
+ {/* Away */}
+
+
+
+
+
+
+ {/* League */}
+
+
+
+
+ );
+}
+
+/** Skeleton grid for loading state */
+function MatchListSkeleton() {
+ return (
+
+ {/* Fake league header */}
+
+
+ {Array.from({ length: 6 }).map((_, i) => (
+
+ ))}
+
+
+ );
+}
+
+interface MatchListProps {
+ leagues?: LeagueWithMatchesDto[];
+ flatMatches?: MatchResponseDto[];
+ isLoading?: boolean;
+}
+
+/**
+ * MatchList — renders matches grouped by league, or flat if only flatMatches is provided.
+ */
+export default function MatchList({
+ leagues,
+ flatMatches,
+ isLoading,
+}: MatchListProps) {
+ const t = useTranslations("matches");
+
+ const leagueHeaderBg = useColorModeValue("gray.50", "gray.900");
+ const borderColor = useColorModeValue("gray.200", "gray.700");
+
+ if (isLoading) {
+ return ;
+ }
+
+ // Flat mode — no league grouping
+ if (flatMatches) {
+ if (flatMatches.length === 0) {
+ return (
+
+
+ {t("no-matches")}
+
+
+ );
+ }
+
+ return (
+
+
+ {flatMatches.map((match) => (
+
+
+
+ ))}
+
+
+ );
+ }
+
+ // Grouped mode — grouped by league
+ if (!leagues || leagues.length === 0) {
+ return (
+
+
+ {t("no-matches")}
+
+
+ );
+ }
+
+ return (
+
+ {leagues.map((league) => (
+
+
+ {/* League Header */}
+
+ {league.country?.flagUrl && (
+
+ )}
+
+ {league.country?.name && `${league.country.name} • `}
+ {league.name}
+
+
+ {league.matches.length} {t("title").toLowerCase()}
+
+
+
+ {/* Match Grid */}
+
+ {league.matches.map((match) => (
+
+ ))}
+
+
+
+ ))}
+
+ );
+}
diff --git a/src/components/matches/matches-content.tsx b/src/components/matches/matches-content.tsx
new file mode 100644
index 0000000..bcf2c53
--- /dev/null
+++ b/src/components/matches/matches-content.tsx
@@ -0,0 +1,121 @@
+"use client";
+
+import { Box, Flex, Heading } from "@chakra-ui/react";
+import { useEffect } from "react";
+import { useTranslations } from "next-intl";
+import { SlideUp } from "@/components/motion";
+import { SportFilter, LeagueSidebar, MatchList } from "@/components/matches";
+import { useQueryMatches, useActiveLeagues } from "@/lib/api/matches/use-hooks";
+import { useMatchStore } from "@/lib/stores/match-store";
+
+export default function MatchesContent() {
+ const t = useTranslations("matches");
+
+ const sport = useMatchStore((s) => s.sport);
+ const leagueFilter = useMatchStore((s) => s.leagueFilter);
+ const setSport = useMatchStore((s) => s.setSport);
+ const setLeague = useMatchStore((s) => s.setLeague);
+
+ // Fetch active leagues for sidebar
+ const { data: leaguesData, isLoading: leaguesLoading } =
+ useActiveLeagues(sport);
+ const leagues = leaguesData?.data ?? [];
+
+ // Query matches grouped by league
+ const queryMatches = useQueryMatches();
+
+ // Trigger query on sport/league change
+ const { data: matchesData, isPending: matchesLoading } = (() => {
+ // We use the queryMatches mutation for initial data
+ // but for the UI we want a reactive approach.
+ // Let's use the standard list with league filter
+ return {
+ data: queryMatches.data,
+ isPending: queryMatches.isPending,
+ };
+ })();
+
+ // Auto-trigger query when sport or league changes
+ const handleSportChange = (newSport: typeof sport) => {
+ setSport(newSport);
+ queryMatches.mutate({
+ sport: newSport,
+ leagueId: undefined,
+ limit: 100,
+ });
+ };
+
+ const handleLeagueChange = (leagueId: string | null) => {
+ setLeague(leagueId);
+ queryMatches.mutate({
+ sport,
+ leagueId: leagueId || undefined,
+ limit: 100,
+ });
+ };
+
+ // Initial load
+ useEffect(() => {
+ if (!queryMatches.data && !queryMatches.isPending) {
+ queryMatches.mutate({
+ sport,
+ leagueId: leagueFilter || undefined,
+ limit: 100,
+ });
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, []);
+
+ const matchLeagues = matchesData?.data ?? [];
+
+ return (
+
+
+ {/* Page Header */}
+
+
+ {t("title")}
+
+
+
+
+ {/* Main Content */}
+
+ {/* League Sidebar (Desktop only) */}
+
+
+
+
+ {/* Match List */}
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/matches/odds-card.tsx b/src/components/matches/odds-card.tsx
new file mode 100644
index 0000000..12ae1fb
--- /dev/null
+++ b/src/components/matches/odds-card.tsx
@@ -0,0 +1,155 @@
+"use client";
+
+import {
+ Box,
+ SimpleGrid,
+ Text,
+ Badge,
+ Card,
+ VStack,
+ Flex,
+} from "@chakra-ui/react";
+import { useColorModeValue } from "@/components/ui/color-mode";
+
+interface OddsCardProps {
+ odds?: Record>;
+}
+
+interface MarketBlockProps {
+ title: string;
+ selections: Record;
+}
+
+function MarketBlock({ title, selections }: MarketBlockProps) {
+ const bg = useColorModeValue("gray.50", "gray.800");
+ const borderColor = useColorModeValue("gray.200", "gray.700");
+ const selectionBg = useColorModeValue("white", "gray.700");
+
+ // Sort selections based on common market patterns
+ const sortedKeys = Object.keys(selections).sort((a, b) => {
+ // MS: 1, X, 2
+ if (["1", "X", "2"].includes(a) && ["1", "X", "2"].includes(b)) {
+ const order = ["1", "X", "2"];
+ return order.indexOf(a) - order.indexOf(b);
+ }
+ // Alt/Üst: Alt, Üst
+ if (["Alt", "Üst"].includes(a) && ["Alt", "Üst"].includes(b)) {
+ return a === "Alt" ? -1 : 1; // Alt first
+ }
+ // KG: Var, Yok
+ if (["Var", "Yok"].includes(a) && ["Var", "Yok"].includes(b)) {
+ return a === "Var" ? -1 : 1; // Var first
+ }
+ return a.localeCompare(b);
+ });
+
+ return (
+
+
+
+ {title}
+
+
+
+ {sortedKeys.map((key) => (
+
+
+ {key}
+
+
+ {Number(selections[key].odd).toFixed(2)}
+
+
+ ))}
+
+
+ );
+}
+
+export default function OddsCard({ odds }: OddsCardProps) {
+ const cardBg = useColorModeValue("white", "gray.900");
+ const borderColor = useColorModeValue("gray.100", "gray.800");
+
+ if (!odds || Object.keys(odds).length === 0) {
+ return null;
+ }
+
+ // Define priority markets to show at the top
+ const PRIORITY_MARKETS = [
+ "Maç Sonucu",
+ "2.5 Alt/Üst",
+ "Karşılıklı Gol",
+ "İlk Yarı Sonucu",
+ "1. Yarı Sonucu",
+ "Kart",
+ "Korner",
+ ];
+
+ const marketKeys = Object.keys(odds);
+ const priorityKeys = marketKeys.filter((k) =>
+ PRIORITY_MARKETS.some((pm) => k.includes(pm)),
+ );
+ const otherKeys = marketKeys.filter(
+ (k) => !PRIORITY_MARKETS.some((pm) => k.includes(pm)),
+ );
+
+ // Group similar markets if needed, but simple list for now
+
+ return (
+
+
+
+
+ Canlı İddaa Oranları
+
+
+ {/* Priority Markets Grid */}
+ {priorityKeys.length > 0 && (
+
+ {priorityKeys.map((key) => (
+
+ ))}
+
+ )}
+
+ {/* Other Markets - Show ALL */}
+ {otherKeys.length > 0 && (
+ 0 ? 2 : 0}
+ >
+ {otherKeys.map((key) => (
+
+ ))}
+
+ )}
+
+
+
+ );
+}
diff --git a/src/components/matches/prediction-card.tsx b/src/components/matches/prediction-card.tsx
new file mode 100644
index 0000000..63e1191
--- /dev/null
+++ b/src/components/matches/prediction-card.tsx
@@ -0,0 +1,1128 @@
+"use client";
+
+import {
+ Badge,
+ Box,
+ Card,
+ Flex,
+ Grid,
+ HStack,
+ Icon,
+ IconButton,
+ Separator,
+ SimpleGrid,
+ Text,
+ VStack,
+} from "@chakra-ui/react";
+import { useMessages, useTranslations } from "next-intl";
+import {
+ LuBadgeCheck,
+ LuBrain,
+ LuChartColumn,
+ LuChartNoAxesCombined,
+ LuCircleHelp,
+ LuFlame,
+ LuGauge,
+ LuShieldAlert,
+ LuSparkles,
+ LuTarget,
+ LuTriangleAlert,
+ LuTrendingUp,
+} from "react-icons/lu";
+import { useColorModeValue } from "@/components/ui/color-mode";
+import { Tooltip } from "@/components/ui/overlays/tooltip";
+import type {
+ MarketBoardEntryDto,
+ MatchBetSummaryItemDto,
+ MatchPickDto,
+ MatchPredictionDto,
+ SignalTier,
+} from "@/lib/api/predictions/types";
+import type { SportType } from "@/lib/api/matches/types";
+
+interface PredictionCardProps {
+ prediction: MatchPredictionDto;
+}
+
+function formatReasonFallback(reason: string): string {
+ if (reason.startsWith("risk:")) return formatReasonFallback(reason.slice(5));
+ const evMatch = reason.match(/^ev_edge_([+\-][\d.]+%)_grade_(\w)$/);
+ if (evMatch) return `Beklenen avantaj ${evMatch[1]} (Not ${evMatch[2]})`;
+ const negMatch = reason.match(/^negative_model_edge_([+\-][\d.]+)$/);
+ if (negMatch) return `Model avantajı negatif (${negMatch[1]})`;
+ const thresholdMatch = reason.match(/^below_market_edge_threshold_([+\-]?[\d.]+)$/);
+ if (thresholdMatch) return `Piyasa avantaj eşiğinin altında (${thresholdMatch[1]})`;
+ if (reason === "confidence_interval_too_wide") return "Güven aralığı fazla geniş.";
+ if (reason === "confidence_band_low") return "Güven bandı düşük.";
+ if (reason === "draw_probability_elevated") return "Beraberlik olasılığı yükselmiş görünüyor.";
+ if (reason === "balanced_match_risk") return "Maç dengeli görünüyor, sürpriz riski var.";
+ if (reason === "high_total_goal_volatility") return "Yüksek gol temposu sürpriz riskini artırıyor.";
+ if (reason === "mutual_goal_pressure") return "İki takım da gol tehdidi üretiyor.";
+ if (reason === "late_goal_swing_risk") return "Geç gol veya skor kırılması riski yüksek.";
+ if (reason === "live_match_open_state") return "Canlı maç tamamen açık oyuna dönmüş durumda.";
+ if (reason === "live_match_active_state") return "Canlı maç beklenenden daha hareketli ilerliyor.";
+ if (reason === "live_state_impossible_market") return "Canlı maç durumu bu marketi geçersiz kılıyor.";
+ if (reason === "live_score_exceeds_under_line") return "Canlı skor, alt seçeneğinin üst sınırına çok yaklaştı veya geçti.";
+ if (reason === "score_model_conflicts_with_under_pick") return "Skor ve xG modeli bu alt seçeneğiyle çelişiyor.";
+ if (reason === "score_model_conflicts_with_over_pick") return "Skor ve xG modeli bu üst seçeneğiyle çelişiyor.";
+ if (reason === "market_stack_conflict_over25") return "2.5 üst sinyali bu marketle çelişiyor.";
+ if (reason === "market_stack_conflict_btts") return "KG Var sinyali bu marketle çelişiyor.";
+ if (reason === "live_total_goals_close_to_line") return "Canlı toplam gol sayısı bu çizgiye fazla yaklaştı.";
+ if (reason === "score_model_conflicts_with_btts_no") return "Skor ve xG modeli KG Yok seçeneğiyle çelişiyor.";
+ if (reason === "score_model_conflicts_with_draw_pick") return "Skor modeli beraberlik seçeneğini desteklemiyor.";
+ if (reason === "score_model_conflicts_with_home_pick") return "Skor modeli ev sahibi seçeneğini desteklemiyor.";
+ if (reason === "score_model_conflicts_with_away_pick") return "Skor modeli deplasman seçeneğini desteklemiyor.";
+ if (/^[a-z0-9_]+$/i.test(reason)) {
+ return reason.replace(/_/g, " ").replace(/^\w/, (char) => char.toUpperCase());
+ }
+ return reason;
+}
+
+function formatPercent(value?: number, digits = 0): string {
+ if (value === undefined || value === null || Number.isNaN(value)) return "-";
+ return `${value.toFixed(digits)}%`;
+}
+
+function formatProbability(value?: number, digits = 1): string {
+ if (value === undefined || value === null || Number.isNaN(value)) return "-";
+ return `${(value * 100).toFixed(digits)}%`;
+}
+
+function formatOdds(value?: number | null): string {
+ if (!value || value <= 1.01) return "-";
+ return value.toFixed(2);
+}
+
+function formatUnits(value?: number): string {
+ if (!value || value <= 0) return "-";
+ return `${value.toFixed(1)}u`;
+}
+
+function getRiskPalette(level: string) {
+ switch (level.toUpperCase()) {
+ case "LOW":
+ return "green";
+ case "MEDIUM":
+ return "yellow";
+ case "HIGH":
+ return "orange";
+ case "EXTREME":
+ return "red";
+ default:
+ return "gray";
+ }
+}
+
+function getQualityPalette(label: string) {
+ switch (label.toUpperCase()) {
+ case "HIGH":
+ return "green";
+ case "MEDIUM":
+ return "yellow";
+ case "LOW":
+ return "red";
+ default:
+ return "gray";
+ }
+}
+
+function getConfidenceBandPalette(band?: string) {
+ switch ((band || "").toUpperCase()) {
+ case "HIGH":
+ return "green";
+ case "MEDIUM":
+ return "yellow";
+ case "LOW":
+ return "red";
+ default:
+ return "gray";
+ }
+}
+
+function getConfidenceBandLabel(band?: string) {
+ switch ((band || "").toUpperCase()) {
+ case "HIGH":
+ return "Yüksek";
+ case "MEDIUM":
+ return "Orta";
+ case "LOW":
+ return "Düşük";
+ default:
+ return "Belirsiz";
+ }
+}
+
+function getLineupSourceLabel(source?: string): string {
+ if (source === "confirmed_live") return "Onayli ilk 11";
+ if (source === "probable_xi") return "Muhtemel ilk 11";
+ return source ? formatReasonFallback(source) : "Bilinmiyor";
+}
+
+function formatInterval(
+ interval?: { lower?: number; upper?: number },
+ digits = 0,
+): string {
+ if (
+ !interval ||
+ interval.lower === undefined ||
+ interval.upper === undefined ||
+ Number.isNaN(interval.lower) ||
+ Number.isNaN(interval.upper)
+ ) {
+ return "-";
+ }
+ return `${interval.lower.toFixed(digits)}-${interval.upper.toFixed(digits)}%`;
+}
+
+function getPredictionReasonText(
+ reason: string,
+ reasonMessages?: Record,
+): string {
+ if (
+ reasonMessages &&
+ Object.prototype.hasOwnProperty.call(reasonMessages, reason)
+ ) {
+ return reasonMessages[reason];
+ }
+ return formatReasonFallback(reason);
+}
+
+function getMarketLabel(
+ market: string,
+ marketLabels?: Record,
+): string {
+ if (marketLabels && Object.prototype.hasOwnProperty.call(marketLabels, market)) {
+ return marketLabels[market];
+ }
+
+ const fallbackLabels: Record = {
+ ML: "Moneyline",
+ MS: "Maç Sonucu",
+ DC: "Çifte Şans",
+ TOTAL: "Toplam Sayı",
+ SPREAD: "Handikap",
+ OU15: "Toplam Gol 1.5",
+ OU25: "Toplam Gol 2.5",
+ OU35: "Toplam Gol 3.5",
+ BTTS: "Karşılıklı Gol",
+ HT: "İlk Yarı Sonucu",
+ HT_OU05: "İlk Yarı 0.5 Gol",
+ HT_OU15: "İlk Yarı 1.5 Gol",
+ HTFT: "İlk Yarı / Maç Sonu",
+ "HT/FT": "İlk Yarı / Maç Sonu",
+ OE: "Tek / Çift",
+ CARDS: "Kartlar 4.5",
+ HCAP: "Handikap Sonucu",
+ };
+ if (fallbackLabels[market]) {
+ return fallbackLabels[market];
+ }
+
+ return market;
+}
+
+const MARKET_ORDER = [
+ "ML",
+ "TOTAL",
+ "SPREAD",
+ "MS",
+ "DC",
+ "OU15",
+ "OU25",
+ "OU35",
+ "BTTS",
+ "HT",
+ "HT_OU05",
+ "HT_OU15",
+ "HTFT",
+ "OE",
+ "CARDS",
+ "HCAP",
+];
+
+function getPredictionSport(prediction: MatchPredictionDto): SportType {
+ const explicitSport = prediction.match_info?.sport;
+ if (explicitSport === "basketball" || explicitSport === "football") {
+ return explicitSport;
+ }
+
+ if (
+ prediction.model_version?.toLowerCase().includes("basketball") ||
+ Object.keys(prediction.market_board || {}).some((market) =>
+ ["ML", "TOTAL", "SPREAD"].includes(market),
+ )
+ ) {
+ return "basketball";
+ }
+
+ return "football";
+}
+
+const SIGNAL_TIER_ORDER: SignalTier[] = ["CORE", "VALUE", "LEAN", "LONGSHOT", "PASS"];
+
+function getSignalTierPalette(tier?: SignalTier) {
+ switch (tier) {
+ case "CORE":
+ return "green";
+ case "VALUE":
+ return "blue";
+ case "LEAN":
+ return "orange";
+ case "LONGSHOT":
+ return "pink";
+ default:
+ return "gray";
+ }
+}
+
+function getSignalTierLabel(tier?: SignalTier) {
+ switch (tier) {
+ case "CORE":
+ return "Çekirdek";
+ case "VALUE":
+ return "Değer";
+ case "LEAN":
+ return "Yorum";
+ case "LONGSHOT":
+ return "Sürpriz";
+ default:
+ return "Pas";
+ }
+}
+
+function TooltipIcon({ content }: { content: string }) {
+ return (
+
+
+
+
+
+ );
+}
+
+function SectionTitle({
+ icon,
+ title,
+ info,
+}: {
+ icon: React.ElementType;
+ title: string;
+ info?: string;
+}) {
+ return (
+
+
+
+
+ {title}
+
+
+ {info ? : null}
+
+ );
+}
+
+function MetricTile({
+ label,
+ value,
+ helper,
+ accent,
+}: {
+ label: string;
+ value: string;
+ helper?: string;
+ accent?: string;
+}) {
+ const bg = useColorModeValue("gray.50", "whiteAlpha.50");
+ const borderColor = useColorModeValue("gray.200", "gray.700");
+ return (
+
+
+
+ {label}
+
+ {helper ? : null}
+
+
+ {value}
+
+
+ );
+}
+
+function Bar({
+ value,
+ color,
+ trackBg,
+ height = "8px",
+}: {
+ value: number;
+ color: string;
+ trackBg: string;
+ height?: string;
+}) {
+ return (
+
+
+
+ );
+}
+
+function ReasonList({
+ items,
+ resolveReason,
+}: {
+ items?: string[];
+ resolveReason: (reason: string) => string;
+}) {
+ if (!items?.length) return null;
+ return (
+
+ {items.map((item, index) => (
+
+
+
+ {resolveReason(item)}
+
+
+ ))}
+
+ );
+}
+
+function ProbabilitySplit({
+ modelProb,
+ impliedProb,
+}: {
+ modelProb: number;
+ impliedProb: number;
+}) {
+ const trackBg = useColorModeValue("gray.100", "gray.700");
+ if (!impliedProb || impliedProb <= 0) return null;
+ return (
+
+
+
+ Model {formatProbability(modelProb, 0)}
+
+
+ Piyasa {formatProbability(impliedProb, 0)}
+
+
+
+
+
+
+
+ );
+}
+
+function PickCard({
+ pick,
+ stakeFallback,
+ title,
+ resolveReason,
+ palette,
+ marketLabels,
+ labels,
+}: {
+ pick: MatchPickDto;
+ stakeFallback?: number;
+ title: string;
+ resolveReason: (reason: string) => string;
+ palette: string;
+ marketLabels?: Record;
+ labels: {
+ confidence: string;
+ odds: string;
+ recommendedStake: string;
+ playScore: string;
+ playability: string;
+ };
+}) {
+ const bg = useColorModeValue(`${palette}.50`, `${palette}.950`);
+ const borderColor = useColorModeValue(`${palette}.200`, `${palette}.800`);
+ const trackBg = useColorModeValue("gray.100", "gray.700");
+ const intervalWarningBg = useColorModeValue("orange.50", "orange.950");
+ const intervalWarningBorder = useColorModeValue("orange.200", "orange.800");
+ const confidenceBandPalette = getConfidenceBandPalette(
+ pick.confidence_interval?.band,
+ );
+ return (
+
+
+
+
+
+ {title}
+
+
+ {pick.pick}
+
+
+ {getMarketLabel(pick.market, marketLabels)}
+
+ {pick.bet_grade}
+
+
+ {getSignalTierLabel(pick.signal_tier)}
+
+
+ {getConfidenceBandLabel(pick.confidence_interval?.band)}
+
+ 0 ? "green" : "red"} variant="subtle">
+ EV {pick.ev_edge > 0 ? "+" : ""}
+ {formatPercent(pick.ev_edge * 100, 1)}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {labels.playability}
+
+
+ {formatPercent(pick.play_score, 1)}
+
+
+ 0 ? "green.400" : "orange.400"}
+ trackBg={trackBg}
+ />
+
+
+ {pick.confidence_interval && !pick.confidence_interval.threshold_met ? (
+
+
+ Guven araligi genis. Sinyal olsa bile tek basina oynanmasi onerilmez.
+
+
+ ) : null}
+
+
+ );
+}
+
+function SummaryTable({
+ items,
+ marketLabels,
+ title,
+ info,
+}: {
+ items: MatchBetSummaryItemDto[];
+ marketLabels?: Record;
+ title: string;
+ info: string;
+}) {
+ const cardBg = useColorModeValue("white", "gray.800");
+ const borderColor = useColorModeValue("gray.200", "gray.700");
+ const highlightBg = useColorModeValue("green.50", "green.950");
+ if (!items.length) return null;
+ return (
+
+
+
+
+ {items
+ .slice()
+ .sort((left, right) => {
+ const leftIndex = SIGNAL_TIER_ORDER.indexOf(left.signal_tier || "PASS");
+ const rightIndex = SIGNAL_TIER_ORDER.indexOf(right.signal_tier || "PASS");
+ if (leftIndex !== rightIndex) return leftIndex - rightIndex;
+ return right.calibrated_confidence - left.calibrated_confidence;
+ })
+ .map((item) => (
+
+
+
+ {item.bet_grade}
+
+
+ {getSignalTierLabel(item.signal_tier)}
+
+ {getMarketLabel(item.market, marketLabels)}
+ {item.pick}
+
+
+ {formatOdds(item.odds)}
+ 0 ? "green.500" : "red.500"} fontWeight="semibold">
+ {item.ev_edge > 0 ? "+" : ""}
+ {formatPercent(item.ev_edge * 100, 1)}
+
+ {formatPercent(item.calibrated_confidence, 0)}
+
+ {getConfidenceBandLabel(item.confidence_interval?.band)}
+
+ {formatUnits(item.stake_units)}
+
+
+ ))}
+
+
+
+ );
+}
+
+function MarketBoardSection({
+ marketBoard,
+ betSummary,
+ marketLabels,
+ title,
+ info,
+}: {
+ marketBoard?: Record;
+ betSummary?: MatchBetSummaryItemDto[];
+ marketLabels?: Record;
+ title: string;
+ info: string;
+}) {
+ const cardBg = useColorModeValue("white", "gray.800");
+ const borderColor = useColorModeValue("gray.200", "gray.700");
+ const trackBg = useColorModeValue("gray.100", "gray.700");
+ const innerBg = useColorModeValue("gray.50", "whiteAlpha.50");
+
+ if (!marketBoard || !Object.keys(marketBoard).length) return null;
+
+ const summaryByMarket = new Map((betSummary || []).map((item) => [item.market, item]));
+ const orderedEntries = Object.entries(marketBoard).sort(([left], [right]) => {
+ const leftIndex = MARKET_ORDER.indexOf(left);
+ const rightIndex = MARKET_ORDER.indexOf(right);
+ const safeLeft = leftIndex === -1 ? Number.MAX_SAFE_INTEGER : leftIndex;
+ const safeRight = rightIndex === -1 ? Number.MAX_SAFE_INTEGER : rightIndex;
+ return safeLeft - safeRight;
+ });
+
+ return (
+
+
+
+
+ {orderedEntries.map(([market, entry]) => {
+ if (!entry?.probs) return null;
+ const summary = summaryByMarket.get(market);
+ const interval =
+ summary?.confidence_interval || entry.confidence_interval;
+ return (
+
+
+
+ {market}
+
+ {getMarketLabel(market, marketLabels)}
+
+
+ {summary ? (
+
+ {summary.playable ? "Oynanabilir" : "Riskli"}
+
+ ) : null}
+ {summary?.signal_tier ? (
+
+ {getSignalTierLabel(summary.signal_tier)}
+
+ ) : null}
+ {summary?.bet_grade ? {summary.bet_grade} : null}
+
+
+ {entry.pick ? (
+
+ {entry.pick} ({formatPercent(entry.confidence, 0)})
+
+ ) : null}
+
+
+
+
+
+
+ {interval ? (
+
+ Guven araligi: {formatInterval(interval)}
+
+ ) : null}
+
+ {Object.entries(entry.probs).map(([outcome, probability]) => (
+
+
+
+ {outcome.toUpperCase()}
+
+
+ {formatProbability(probability, 1)}
+
+
+
+
+ ))}
+
+
+ );
+ })}
+
+
+
+ );
+}
+
+function ScoreCard({
+ prediction,
+ sport,
+}: {
+ prediction: MatchPredictionDto;
+ sport: SportType;
+}) {
+ const cardBg = useColorModeValue("white", "gray.800");
+ const borderColor = useColorModeValue("gray.200", "gray.700");
+ const subBg = useColorModeValue("gray.50", "whiteAlpha.50");
+ const isBasketball = sport === "basketball";
+
+ return (
+
+
+
+
+
+
+
+
+
+ {prediction.scenario_top5.map((scenario) => (
+
+
+ {scenario.score}
+
+
+ {formatProbability(scenario.prob, 1)}
+
+
+ ))}
+
+
+
+ );
+}
+
+export default function PredictionCard({ prediction }: PredictionCardProps) {
+ const t = useTranslations("predictions");
+ const messages = useMessages() as {
+ predictions?: {
+ "prediction-reasons"?: Record;
+ "market-labels"?: Record;
+ ui?: Record;
+ };
+ };
+ const marketLabels = messages.predictions?.["market-labels"];
+ const ui = messages.predictions?.ui;
+ const uiText = (key: string, fallback: string) => ui?.[key] || fallback;
+ const resolveReason = (reason: string) =>
+ getPredictionReasonText(reason, messages.predictions?.["prediction-reasons"]);
+
+ const pageBg = useColorModeValue("gray.50", "gray.900");
+ const cardBg = useColorModeValue("white", "gray.800");
+ const borderColor = useColorModeValue("gray.200", "gray.700");
+ const riskPalette = getRiskPalette(prediction.risk.level);
+ const qualityPalette = getQualityPalette(prediction.data_quality.label);
+ const recommendedPick = prediction.main_pick;
+ const mainBandPalette = getConfidenceBandPalette(
+ prediction.bet_advice.confidence_band,
+ );
+ const sport = getPredictionSport(prediction);
+ const isBasketball = sport === "basketball";
+
+ const engineItems = [
+ {
+ key: "team",
+ icon: LuGauge,
+ label: isBasketball ? "Takim Formu" : "Takim Gucu",
+ value: prediction.engine_breakdown.team,
+ color: "blue.400",
+ },
+ {
+ key: "player",
+ icon: LuSparkles,
+ label: isBasketball ? "Kadro Etkisi" : "Oyuncu Etkisi",
+ value: prediction.engine_breakdown.player,
+ color: "green.400",
+ },
+ { key: "odds", icon: LuTrendingUp, label: "Oran Analizi", value: prediction.engine_breakdown.odds, color: "orange.400" },
+ {
+ key: "referee",
+ icon: LuShieldAlert,
+ label: isBasketball ? "Yardimci Sinyaller" : "Hakem Etkisi",
+ value: prediction.engine_breakdown.referee,
+ color: "purple.400",
+ },
+ ];
+
+ return (
+
+
+
+
+
+ {recommendedPick ? (
+
+
+
+
+
+ {uiText("main-recommendation", "Ana Oneri")}
+
+
+ {recommendedPick.pick}
+
+
+ {getMarketLabel(recommendedPick.market, marketLabels)} {uiText("best-market-copy", "marketinde en guclu secim.")}
+
+
+
+ {getConfidenceBandLabel(prediction.bet_advice.confidence_band)}
+
+ {recommendedPick.confidence_interval ? (
+
+ {formatInterval(recommendedPick.confidence_interval)}
+
+ ) : null}
+
+
+
+
+
+
+
+
+ 0 ? "+" : ""}${formatPercent(recommendedPick.ev_edge * 100, 1)}`}
+ helper={uiText(
+ "edge-info",
+ "Edge, model olasiligi ile piyasa olasiligi arasindaki farktir. Pozitifse model bu orani avantajli buluyor demektir.",
+ )}
+ accent={recommendedPick.ev_edge > 0 ? "green.500" : "red.500"}
+ />
+
+
+
+
+
+
+ {uiText("quick-read", "Hizli yorum")}
+
+
+
+
+ ) : null}
+
+
+
+
+
+
+
+
+ {prediction.risk.is_surprise_risk || prediction.risk.warnings?.length ? (
+
+
+
+
+ Risk Yorumu
+
+ {prediction.risk.surprise_comment ||
+ (prediction.risk.surprise_type
+ ? `${resolveReason(prediction.risk.surprise_type)}`
+ : "Model bu maçta ekstra dikkat istiyor.")}
+
+ {prediction.risk.surprise_score !== undefined ? (
+
+ Sürpriz skoru: {formatPercent(prediction.risk.surprise_score, 0)}
+
+ ) : null}
+
+
+
+
+ ) : null}
+
+
+
+
+
+
+
+ {engineItems.map((item) => (
+
+
+
+
+
+ {item.label}
+
+
+
+ +{item.value.toFixed(1)}
+
+
+
+
+ ))}
+
+
+
+
+ {recommendedPick ? (
+
+ ) : null}
+
+ {prediction.supporting_picks?.length ? (
+
+
+
+
+ {prediction.supporting_picks.map((pick) => (
+ 0 ? "blue" : "orange"}
+ marketLabels={marketLabels}
+ labels={{
+ confidence: uiText("confidence-label", "Guven"),
+ odds: uiText("odds-label", "Oran"),
+ recommendedStake: uiText("stake-label-short", "Stake"),
+ playScore: uiText("play-score-label", "Play Score"),
+ playability: uiText("playability-label", "Oynanabilirlik"),
+ }}
+ />
+ ))}
+
+
+
+ ) : null}
+
+
+
+
+
+
+
+
+
+
+
+ {prediction.bet_advice.playable ? "OYNA" : "OYNAMA"}
+
+
+ {getConfidenceBandLabel(prediction.bet_advice.confidence_band)}
+
+
+ {getSignalTierLabel(prediction.bet_advice.signal_tier)}
+
+ {resolveReason(prediction.bet_advice.reason)}
+
+
+ {uiText("recommended-stake-inline", "Onerilen miktar")}: {formatUnits(prediction.bet_advice.suggested_stake_units)}
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/matches/sport-filter.tsx b/src/components/matches/sport-filter.tsx
new file mode 100644
index 0000000..6bea61b
--- /dev/null
+++ b/src/components/matches/sport-filter.tsx
@@ -0,0 +1,44 @@
+"use client";
+
+import { HStack, Button } from "@chakra-ui/react";
+import { useTranslations } from "next-intl";
+import { LuCircleDot } from "react-icons/lu";
+import { MdSportsSoccer, MdSportsBasketball } from "react-icons/md";
+import type { SportType } from "@/lib/api/matches/types";
+
+interface SportFilterProps {
+ value: SportType;
+ onChange: (sport: SportType) => void;
+}
+
+const SPORT_OPTIONS: { value: SportType; icon: React.ReactNode }[] = [
+ { value: "football", icon: },
+ { value: "basketball", icon: },
+];
+
+export default function SportFilter({ value, onChange }: SportFilterProps) {
+ const t = useTranslations("matches");
+
+ return (
+
+ {SPORT_OPTIONS.map((sport) => {
+ const isActive = value === sport.value;
+ return (
+ onChange(sport.value)}
+ variant={isActive ? "solid" : "outline"}
+ colorPalette={isActive ? "primary" : "gray"}
+ size="sm"
+ borderRadius="full"
+ gap={1.5}
+ >
+ {sport.icon}
+ {t(sport.value)}
+ {isActive && }
+
+ );
+ })}
+
+ );
+}
diff --git a/src/components/motion/index.tsx b/src/components/motion/index.tsx
new file mode 100644
index 0000000..59870f7
--- /dev/null
+++ b/src/components/motion/index.tsx
@@ -0,0 +1,470 @@
+"use client";
+
+import {
+ motion,
+ useMotionValue,
+ useTransform,
+ animate,
+ useInView,
+ type HTMLMotionProps,
+} from "framer-motion";
+import { forwardRef, type ReactNode, useEffect, useRef } from "react";
+
+// ========================
+// Shared animation variants
+// ========================
+
+export const fadeInVariants = {
+ hidden: { opacity: 0 },
+ visible: { opacity: 1 },
+};
+
+export const slideUpVariants = {
+ hidden: { opacity: 0, y: 24 },
+ visible: { opacity: 1, y: 0 },
+};
+
+export const slideDownVariants = {
+ hidden: { opacity: 0, y: -24 },
+ visible: { opacity: 1, y: 0 },
+};
+
+export const slideLeftVariants = {
+ hidden: { opacity: 0, x: 40 },
+ visible: { opacity: 1, x: 0 },
+};
+
+export const slideRightVariants = {
+ hidden: { opacity: 0, x: -40 },
+ visible: { opacity: 1, x: 0 },
+};
+
+export const scaleInVariants = {
+ hidden: { opacity: 0, scale: 0.9 },
+ visible: { opacity: 1, scale: 1 },
+};
+
+export const blurInVariants = {
+ hidden: { opacity: 0, filter: "blur(10px)" },
+ visible: { opacity: 1, filter: "blur(0px)" },
+};
+
+export const staggerContainerVariants = {
+ hidden: {},
+ visible: {
+ transition: {
+ staggerChildren: 0.08,
+ },
+ },
+};
+
+// ========================
+// Spring presets
+// ========================
+
+export const springs = {
+ gentle: { type: "spring" as const, stiffness: 120, damping: 14 },
+ bouncy: { type: "spring" as const, stiffness: 300, damping: 15 },
+ snappy: { type: "spring" as const, stiffness: 400, damping: 25 },
+ smooth: { duration: 0.5, ease: [0.25, 0.1, 0.25, 1] as const },
+};
+
+// ========================
+// Generic Motion Wrappers (animate on mount)
+// ========================
+
+interface MotionWrapperProps extends HTMLMotionProps<"div"> {
+ children: ReactNode;
+}
+
+export const FadeIn = forwardRef(
+ ({ children, ...props }, ref) => (
+
+ {children}
+
+ ),
+);
+FadeIn.displayName = "FadeIn";
+
+export const SlideUp = forwardRef(
+ ({ children, ...props }, ref) => (
+
+ {children}
+
+ ),
+);
+SlideUp.displayName = "SlideUp";
+
+export const ScaleIn = forwardRef(
+ ({ children, ...props }, ref) => (
+
+ {children}
+
+ ),
+);
+ScaleIn.displayName = "ScaleIn";
+
+export const BlurIn = forwardRef(
+ ({ children, ...props }, ref) => (
+
+ {children}
+
+ ),
+);
+BlurIn.displayName = "BlurIn";
+
+// ========================
+// Scroll-based motion (whileInView)
+// ========================
+
+interface ScrollMotionProps extends HTMLMotionProps<"div"> {
+ children: ReactNode;
+ /** How much of the element must be visible (0–1). Default: 0.2 */
+ threshold?: number;
+ /** Animate only once? Default: true */
+ once?: boolean;
+}
+
+export const ScrollFadeIn = forwardRef(
+ ({ children, threshold = 0.2, once = true, ...props }, ref) => (
+
+ {children}
+
+ ),
+);
+ScrollFadeIn.displayName = "ScrollFadeIn";
+
+export const ScrollSlideUp = forwardRef(
+ ({ children, threshold = 0.15, once = true, ...props }, ref) => (
+
+ {children}
+
+ ),
+);
+ScrollSlideUp.displayName = "ScrollSlideUp";
+
+export const ScrollScaleIn = forwardRef(
+ ({ children, threshold = 0.2, once = true, ...props }, ref) => (
+
+ {children}
+
+ ),
+);
+ScrollScaleIn.displayName = "ScrollScaleIn";
+
+export const ScrollBlurIn = forwardRef(
+ ({ children, threshold = 0.2, once = true, ...props }, ref) => (
+
+ {children}
+
+ ),
+);
+ScrollBlurIn.displayName = "ScrollBlurIn";
+
+export const ScrollSlideLeft = forwardRef(
+ ({ children, threshold = 0.15, once = true, ...props }, ref) => (
+
+ {children}
+
+ ),
+);
+ScrollSlideLeft.displayName = "ScrollSlideLeft";
+
+export const ScrollSlideRight = forwardRef(
+ ({ children, threshold = 0.15, once = true, ...props }, ref) => (
+
+ {children}
+
+ ),
+);
+ScrollSlideRight.displayName = "ScrollSlideRight";
+
+// ========================
+// Stagger Container — animate children one by one
+// ========================
+
+interface StaggerProps extends HTMLMotionProps<"div"> {
+ children: ReactNode;
+ staggerDelay?: number;
+ /** Use whileInView instead of animate? Default: false */
+ inView?: boolean;
+}
+
+export const StaggerContainer = forwardRef(
+ ({ children, staggerDelay = 0.08, inView = false, ...props }, ref) => {
+ const baseProps = {
+ ref,
+ variants: {
+ hidden: {},
+ visible: { transition: { staggerChildren: staggerDelay } },
+ },
+ ...props,
+ };
+
+ if (inView) {
+ return (
+
+ {children}
+
+ );
+ }
+
+ return (
+
+ {children}
+
+ );
+ },
+);
+StaggerContainer.displayName = "StaggerContainer";
+
+// ========================
+// Stagger Item — use as direct child of StaggerContainer
+// ========================
+
+export const StaggerItem = forwardRef(
+ ({ children, ...props }, ref) => (
+
+ {children}
+
+ ),
+);
+StaggerItem.displayName = "StaggerItem";
+
+// ========================
+// Animated Counter — REAL counting with number interpolation
+// ========================
+
+interface AnimatedCounterProps {
+ /** Target value to count up to */
+ value: number;
+ suffix?: string;
+ prefix?: string;
+ /** Duration in seconds. Default: 2 */
+ duration?: number;
+ /** Only animate when visible? Default: true */
+ inView?: boolean;
+}
+
+export function AnimatedCounter({
+ value,
+ suffix = "",
+ prefix = "",
+ duration = 2,
+ inView = true,
+}: AnimatedCounterProps) {
+ const ref = useRef(null);
+ const motionValue = useMotionValue(0);
+ const rounded = useTransform(motionValue, (latest) =>
+ Intl.NumberFormat("tr-TR").format(Math.round(latest)),
+ );
+ const isInView = useInView(ref, { once: true, amount: 0.5 });
+
+ useEffect(() => {
+ if (!inView || isInView) {
+ const controls = animate(motionValue, value, {
+ duration,
+ ease: [0.25, 0.1, 0.25, 1],
+ });
+ return controls.stop;
+ }
+ }, [motionValue, value, duration, inView, isInView]);
+
+ return (
+
+ {prefix}
+ {rounded}
+ {suffix}
+
+ );
+}
+
+// ========================
+// Sparkle / Particle Effect
+// ========================
+
+interface SparkleProps {
+ /** Number of sparkle particles. Default: 6 */
+ count?: number;
+ /** Color of the sparkle. Default: "primary.300" */
+ color?: string;
+}
+
+export function Sparkles({ count = 6, color = "rgba(56, 178, 172, 0.6)" }: SparkleProps) {
+ return (
+
+ {Array.from({ length: count }).map((_, i) => (
+
+ ))}
+
+ );
+}
+
+// ========================
+// Gradient Orb — decorative floating orb
+// ========================
+
+interface GradientOrbProps {
+ /** CSS color/gradient for the orb */
+ color?: string;
+ /** Size in px */
+ size?: number;
+ /** Position: top, left, right, bottom (CSS values) */
+ top?: string;
+ left?: string;
+ right?: string;
+ bottom?: string;
+ /** Blur amount in px. Default: 60 */
+ blur?: number;
+}
+
+export function GradientOrb({
+ color = "rgba(56, 178, 172, 0.15)",
+ size = 200,
+ top,
+ left,
+ right,
+ bottom,
+ blur = 60,
+}: GradientOrbProps) {
+ return (
+
+ );
+}
diff --git a/src/components/predictions/index.ts b/src/components/predictions/index.ts
new file mode 100644
index 0000000..ddde7bf
--- /dev/null
+++ b/src/components/predictions/index.ts
@@ -0,0 +1 @@
+export { default as PredictionsContent } from "./predictions-content";
diff --git a/src/components/predictions/predictions-content.tsx b/src/components/predictions/predictions-content.tsx
new file mode 100644
index 0000000..964a17f
--- /dev/null
+++ b/src/components/predictions/predictions-content.tsx
@@ -0,0 +1,352 @@
+"use client";
+
+import {
+ Box,
+ Flex,
+ Heading,
+ Text,
+ Badge,
+ VStack,
+ HStack,
+ Card,
+ SimpleGrid,
+ Spinner,
+ Button,
+} from "@chakra-ui/react";
+import { useTranslations } from "next-intl";
+import { useRouter } from "next/navigation";
+import { useColorModeValue } from "@/components/ui/color-mode";
+import { SlideUp, StaggerContainer, StaggerItem } from "@/components/motion";
+import type { SportType } from "@/lib/api/matches/types";
+import {
+ useUpcomingPredictions,
+ useValueBets,
+ usePredictionHistory,
+} from "@/lib/api/predictions/use-hooks";
+import type {
+ MatchPredictionDto,
+ ValueBetDto,
+ PredictionHistoryResponseDto,
+} from "@/lib/api/predictions/types";
+import { useState } from "react";
+
+function getPredictionSport(prediction: MatchPredictionDto): SportType {
+ const explicitSport = prediction.match_info?.sport;
+ if (explicitSport === "basketball" || explicitSport === "football") {
+ return explicitSport;
+ }
+
+ if (
+ prediction.model_version?.toLowerCase().includes("basketball") ||
+ Object.keys(prediction.market_board || {}).some((market) =>
+ ["ML", "TOTAL", "SPREAD"].includes(market),
+ )
+ ) {
+ return "basketball";
+ }
+
+ return "football";
+}
+
+type TabType = "upcoming" | "value-bets" | "history";
+
+export default function PredictionsContent() {
+ const t = useTranslations("predictions");
+ const tMatches = useTranslations("matches");
+ const router = useRouter();
+ const [activeTab, setActiveTab] = useState("upcoming");
+
+ const cardBg = useColorModeValue("white", "gray.800");
+ const borderColor = useColorModeValue("gray.100", "gray.700");
+
+ const { data: upcomingData, isLoading: upcomingLoading } =
+ useUpcomingPredictions();
+ const { data: valueBetsData, isLoading: valueBetsLoading } = useValueBets();
+ const { data: historyData, isLoading: historyLoading } =
+ usePredictionHistory();
+
+ const upcomingPredictions: MatchPredictionDto[] =
+ upcomingData?.data?.matches ?? [];
+ const valueBets: ValueBetDto[] = valueBetsData?.data ?? [];
+ const historyResponse = historyData?.data as
+ | PredictionHistoryResponseDto
+ | undefined;
+ const history = historyResponse?.history ?? [];
+
+ const riskColors: Record = {
+ LOW: "green",
+ MEDIUM: "yellow",
+ HIGH: "orange",
+ "VERY HIGH": "red",
+ };
+
+ const tabs: { key: TabType; label: string }[] = [
+ { key: "upcoming", label: t("upcoming") },
+ { key: "value-bets", label: t("value-bets") },
+ { key: "history", label: t("history") },
+ ];
+
+ return (
+
+
+
+ {t("title")}
+
+
+ {/* Tabs */}
+
+ {tabs.map((tab) => (
+ setActiveTab(tab.key)}
+ flexShrink={0}
+ >
+ {tab.label}
+
+ ))}
+
+
+ {/* Upcoming Predictions Tab */}
+ {activeTab === "upcoming" &&
+ (upcomingLoading ? (
+
+
+
+ ) : upcomingPredictions.length > 0 ? (
+
+
+ {upcomingPredictions.map(
+ (pred: MatchPredictionDto, idx: number) => {
+ const sport = getPredictionSport(pred);
+ return (
+
+
+ router.push(`/matches/${pred.match_info.match_id}`)
+ }
+ >
+
+
+
+ {pred.match_info.home_team} vs{" "}
+ {pred.match_info.away_team}
+
+
+
+ {tMatches(sport)}
+
+
+ {pred.risk?.level}
+
+
+
+
+ {pred.main_pick && (
+
+
+
+
+ {t("main-pick")}
+
+
+ {pred.main_pick.pick}
+
+
+
+
+ {t("confidence")}
+
+
+ {Math.round(
+ pred.main_pick.calibrated_confidence ??
+ pred.main_pick.confidence,
+ )}
+ %
+
+
+
+
+ )}
+
+
+
+ {t("data-quality")}:{" "}
+ {Math.round(
+ (pred.data_quality?.score ?? 0) * 100,
+ )}
+ %
+
+
+ {pred.model_version}
+
+
+
+
+
+ );
+ },
+ )}
+
+
+ ) : (
+
+ {t("no-predictions")}
+
+ ))}
+
+ {/* Value Bets Tab */}
+ {activeTab === "value-bets" &&
+ (valueBetsLoading ? (
+
+
+
+ ) : valueBets.length > 0 ? (
+
+
+ {valueBets.map((vb: ValueBetDto, idx: number) => (
+
+
+
+
+ {vb.matchName}
+
+
+
+ {vb.prediction}
+
+
+ {vb.odd.toFixed(2)}
+
+
+
+
+ EV+ {(vb.expectedValue * 100).toFixed(0)}%
+
+
+ {t("confidence")}: {Math.round(vb.confidence * 100)}
+ %
+
+
+
+
+
+ ))}
+
+
+ ) : (
+
+ {t("no-predictions")}
+
+ ))}
+
+ {/* History Tab */}
+ {activeTab === "history" &&
+ (historyLoading ? (
+
+
+
+ ) : history.length > 0 ? (
+
+
+ {history.map((item: Record, idx: number) => (
+
+
+
+
+
+
+ {String(item.homeTeam ?? "")} vs{" "}
+ {String(item.awayTeam ?? "")}
+
+
+ {String(item.pick ?? "")}
+
+
+
+
+ {String(item.result ?? "pending")}
+
+
+ {typeof item.confidence === "number"
+ ? `${Math.round(item.confidence * 100)}%`
+ : "—"}
+
+
+
+
+
+
+ ))}
+
+
+ ) : (
+
+ {t("no-predictions")}
+
+ ))}
+
+
+ );
+}
diff --git a/src/components/profile/index.ts b/src/components/profile/index.ts
new file mode 100644
index 0000000..3004c1b
--- /dev/null
+++ b/src/components/profile/index.ts
@@ -0,0 +1 @@
+export { default as ProfileContent } from "./profile-content";
diff --git a/src/components/profile/profile-content.tsx b/src/components/profile/profile-content.tsx
new file mode 100644
index 0000000..0a3dc92
--- /dev/null
+++ b/src/components/profile/profile-content.tsx
@@ -0,0 +1,422 @@
+"use client";
+
+import {
+ Box,
+ Flex,
+ Heading,
+ Text,
+ Card,
+ VStack,
+ HStack,
+ Separator,
+ Spinner,
+ Input,
+ Button,
+ IconButton,
+} from "@chakra-ui/react";
+import { useTranslations } from "next-intl";
+import { useColorModeValue } from "@/components/ui/color-mode";
+import { SlideUp } from "@/components/motion";
+import { Avatar } from "@/components/ui/data-display/avatar";
+import { useSession } from "next-auth/react";
+import { useUserBettingStats } from "@/lib/api/coupons/use-hooks";
+import type { UserBettingStatsDto } from "@/lib/api/coupons/types";
+import {
+ LuMail,
+ LuUser,
+ LuCalendar,
+ LuShield,
+ LuTrendingUp,
+ LuTarget,
+ LuTicket,
+ LuPen,
+ LuCheck,
+ LuX,
+ LuLock,
+} from "react-icons/lu";
+import { useState } from "react";
+import { useUpdateProfile, useChangePassword } from "@/lib/api/users/use-hooks";
+import { Field } from "@/components/ui/forms/field";
+import { useForm } from "react-hook-form";
+import * as yup from "yup";
+import { yupResolver } from "@hookform/resolvers/yup";
+import { PasswordInput } from "@/components/ui/forms/password-input";
+import { useRouter } from "next/navigation";
+
+interface InfoRowProps {
+ icon: React.ReactNode;
+ label: string;
+ value: string;
+}
+
+function InfoRow({ icon, label, value }: InfoRowProps) {
+ return (
+
+
+ {icon}
+ {label}
+
+
+ {value}
+
+
+ );
+}
+
+const profileSchema = yup.object({
+ firstName: yup.string().required(),
+ lastName: yup.string().required(),
+});
+
+type ProfileForm = yup.InferType;
+
+const passwordSchema = yup.object({
+ currentPassword: yup.string().required(),
+ newPassword: yup.string().min(8).required(),
+ confirmPassword: yup
+ .string()
+ .oneOf([yup.ref("newPassword")], "Passwords must match")
+ .required(),
+});
+
+type PasswordForm = yup.InferType;
+
+export default function ProfileContent() {
+ const t = useTranslations("profile");
+ const tCommon = useTranslations("common");
+ const { data: session, update: updateSession } = useSession();
+ const { data: statsData, isLoading: statsLoading } = useUserBettingStats();
+
+ const cardBg = useColorModeValue("white", "gray.800");
+ const borderColor = useColorModeValue("gray.100", "gray.700");
+
+ const user = session?.user;
+ const stats = statsData?.data as UserBettingStatsDto | undefined;
+
+ // Edit profile state
+ const [isEditing, setIsEditing] = useState(false);
+ const updateProfile = useUpdateProfile();
+
+ const {
+ handleSubmit: handleProfileSubmit,
+ register: profileRegister,
+ formState: { errors: profileErrors },
+ reset: resetProfile,
+ } = useForm({
+ resolver: yupResolver(profileSchema),
+ mode: "onChange",
+ defaultValues: {
+ firstName: user?.name?.split(" ")[0] || "",
+ lastName: user?.name?.split(" ").slice(1).join(" ") || "",
+ },
+ });
+
+ const onProfileSubmit = async (data: ProfileForm) => {
+ await updateProfile.mutateAsync(data);
+ await updateSession();
+ setIsEditing(false);
+ };
+
+ // Change password state
+ const [showPasswordForm, setShowPasswordForm] = useState(false);
+ const changePassword = useChangePassword();
+ const router = useRouter();
+
+ const {
+ handleSubmit: handlePasswordSubmit,
+ register: passwordRegister,
+ formState: { errors: passwordErrors },
+ reset: resetPassword,
+ } = useForm({
+ resolver: yupResolver(passwordSchema),
+ mode: "onChange",
+ });
+
+ const onPasswordSubmit = async (data: PasswordForm) => {
+ await changePassword.mutateAsync({
+ currentPassword: data.currentPassword,
+ newPassword: data.newPassword,
+ });
+ resetPassword();
+ setShowPasswordForm(false);
+ };
+
+ return (
+
+
+
+ {t("title")}
+
+
+ {/* Profile Card */}
+
+
+
+
+
+
+ {user?.name || "—"}
+
+
+ {user?.email || "—"}
+
+
+
+
+
+
+ {/* Account Info */}
+
+
+
+
+ {t("personal-info")}
+
+ {!isEditing ? (
+ setIsEditing(true)}
+ >
+
+
+ ) : null}
+
+
+
+ {isEditing ? (
+
+
+
+
+
+
+
+
+ {
+ setIsEditing(false);
+ resetProfile();
+ }}
+ >
+
+ {tCommon("cancel")}
+
+
+
+ {tCommon("save")}
+
+
+
+ ) : (
+ <>
+ }
+ label={t("full-name")}
+ value={user?.name || "—"}
+ />
+
+ }
+ label={t("email")}
+ value={user?.email || "—"}
+ />
+
+ }
+ label={t("role")}
+ value={
+ (user as Record)?.roles
+ ? String((user as Record).roles)
+ : "User"
+ }
+ />
+
+ }
+ label={t("member-since")}
+ value="—"
+ />
+ >
+ )}
+
+
+
+ {/* Change Password */}
+
+
+
+
+
+
+ {t("change-password")}
+
+
+ {!showPasswordForm ? (
+ setShowPasswordForm(true)}
+ >
+ {tCommon("edit")}
+
+ ) : null}
+
+
+
+ {showPasswordForm ? (
+
+
+
+
+
+
+
+
+
+
+
+ {
+ setShowPasswordForm(false);
+ resetPassword();
+ }}
+ >
+
+ {tCommon("cancel")}
+
+ router.refresh()}
+ >
+
+ {tCommon("save")}
+
+
+
+ ) : (
+
+ {t("change-password-desc")}
+
+ )}
+
+
+
+ {/* Betting Stats */}
+
+
+
+ {t("betting-stats")}
+
+
+
+ {statsLoading ? (
+
+
+
+ ) : (
+ <>
+ }
+ label={t("total-coupons")}
+ value={String(stats?.totalCoupons ?? "—")}
+ />
+
+ }
+ label={t("win-rate")}
+ value={
+ stats?.winRate != null
+ ? `${Math.round(stats.winRate)}%`
+ : "—"
+ }
+ />
+
+ }
+ label={t("total-profit")}
+ value={stats?.wonBets != null ? String(stats.wonBets) : "—"}
+ />
+ >
+ )}
+
+
+
+
+ );
+}
diff --git a/src/components/search/global-search.tsx b/src/components/search/global-search.tsx
new file mode 100644
index 0000000..0ae37c9
--- /dev/null
+++ b/src/components/search/global-search.tsx
@@ -0,0 +1,230 @@
+"use client";
+
+import { useState, useRef, useEffect, useCallback } from "react";
+import {
+ Box,
+ Flex,
+ Input,
+ Text,
+ VStack,
+ HStack,
+ Image,
+ Spinner,
+} from "@chakra-ui/react";
+import { useColorModeValue } from "@/components/ui/color-mode";
+import { useSearchTeams } from "@/lib/api/leagues/use-hooks";
+import { useRouter } from "@/i18n/navigation";
+import { LuSearch, LuX } from "react-icons/lu";
+import type { TeamDto } from "@/lib/api/leagues/types";
+
+export default function GlobalSearch() {
+ const [query, setQuery] = useState("");
+ const [isOpen, setIsOpen] = useState(false);
+ const [debouncedQuery, setDebouncedQuery] = useState("");
+ const inputRef = useRef(null);
+ const containerRef = useRef(null);
+ const router = useRouter();
+
+ const bg = useColorModeValue("white", "gray.900");
+ const borderColor = useColorModeValue("gray.200", "gray.700");
+ const hoverBg = useColorModeValue("gray.50", "gray.800");
+ const inputBg = useColorModeValue("gray.50", "gray.800");
+
+ // Debounce search input
+ useEffect(() => {
+ const timer = setTimeout(() => setDebouncedQuery(query), 300);
+ return () => clearTimeout(timer);
+ }, [query]);
+
+ const { data: searchData, isLoading } = useSearchTeams({
+ q: debouncedQuery,
+ });
+
+ const teams: TeamDto[] = searchData?.data ?? [];
+
+ // Close dropdown on outside click
+ useEffect(() => {
+ const handleClickOutside = (e: MouseEvent) => {
+ if (
+ containerRef.current &&
+ !containerRef.current.contains(e.target as Node)
+ ) {
+ setIsOpen(false);
+ }
+ };
+ document.addEventListener("mousedown", handleClickOutside);
+ return () => document.removeEventListener("mousedown", handleClickOutside);
+ }, []);
+
+ // Keyboard shortcut: Ctrl+K to focus
+ useEffect(() => {
+ const handleKeyDown = (e: KeyboardEvent) => {
+ if ((e.ctrlKey || e.metaKey) && e.key === "k") {
+ e.preventDefault();
+ inputRef.current?.focus();
+ setIsOpen(true);
+ }
+ if (e.key === "Escape") {
+ setIsOpen(false);
+ inputRef.current?.blur();
+ }
+ };
+ document.addEventListener("keydown", handleKeyDown);
+ return () => document.removeEventListener("keydown", handleKeyDown);
+ }, []);
+
+ const handleTeamClick = useCallback(
+ (team: TeamDto) => {
+ setIsOpen(false);
+ setQuery("");
+ router.push(`/teams/${team.id}`);
+ },
+ [router],
+ );
+
+ return (
+
+ {/* Search Input */}
+
+
+ {
+ setQuery(e.target.value);
+ setIsOpen(true);
+ }}
+ onFocus={() => query.length >= 2 && setIsOpen(true)}
+ placeholder="Takım ara... (Ctrl+K)"
+ variant="flushed"
+ size="sm"
+ px={2}
+ fontSize="sm"
+ />
+ {query && (
+ {
+ setQuery("");
+ setIsOpen(false);
+ }}
+ cursor="pointer"
+ opacity={0.5}
+ _hover={{ opacity: 1 }}
+ flexShrink={0}
+ >
+
+
+ )}
+
+ ⌘K
+
+
+
+ {/* Dropdown Results */}
+ {isOpen && debouncedQuery.length >= 2 && (
+
+ {isLoading ? (
+
+
+
+ ) : teams.length === 0 ? (
+
+
+ Sonuç bulunamadı
+
+
+ ) : (
+
+ {teams.map((team: TeamDto) => (
+ handleTeamClick(team)}
+ gap={3}
+ >
+ {team.logo ? (
+
+ ) : (
+
+
+ {team.name?.charAt(0) || "T"}
+
+
+ )}
+
+
+ {team.name}
+
+ {team.country && (
+
+ {team.country}
+
+ )}
+
+
+ ))}
+
+ )}
+
+ )}
+
+ );
+}
diff --git a/src/components/site/home/home-card.tsx b/src/components/site/home/home-card.tsx
new file mode 100644
index 0000000..71880c7
--- /dev/null
+++ b/src/components/site/home/home-card.tsx
@@ -0,0 +1,3303 @@
+"use client";
+
+import { Button } from "@/components/ui/buttons/button";
+import { CloseButton } from "@/components/ui/buttons/close-button";
+import {
+ ComboboxControl,
+ ComboboxEmpty,
+ ComboboxInput,
+ ComboboxItem,
+ ComboboxLabel,
+ ComboboxRoot,
+} from "@/components/ui/collections/combobox";
+import {
+ ListboxContent,
+ ListboxItem,
+ ListboxItemText,
+ ListboxLabel,
+ ListboxRoot,
+} from "@/components/ui/collections/listbox";
+import {
+ TreeViewBranchControl,
+ TreeViewBranchIndentGuide,
+ TreeViewBranchText,
+ TreeViewItem,
+ TreeViewItemText,
+ TreeViewLabel,
+ TreeViewNode,
+ TreeViewRoot,
+ TreeViewTree,
+} from "@/components/ui/collections/treeview";
+import { Alert } from "@/components/ui/feedback/alert";
+import { EmptyState } from "@/components/ui/feedback/empty-state";
+import {
+ ProgressBar,
+ ProgressLabel,
+ ProgressRoot,
+} from "@/components/ui/feedback/progress";
+import { Status } from "@/components/ui/feedback/status";
+import {
+ ProgressCircleRing,
+ ProgressCircleRoot,
+ ProgressCircleValueText,
+} from "@/components/ui/feedback/progress-circle";
+import {
+ SkeletonCircle,
+ SkeletonText,
+} from "@/components/ui/feedback/skeleton";
+import { Checkbox } from "@/components/ui/forms/checkbox";
+import { CheckboxCard } from "@/components/ui/forms/checkbox-card";
+import {
+ ColorPickerArea,
+ ColorPickerChannelSliders,
+ ColorPickerContent,
+ ColorPickerControl,
+ ColorPickerEyeDropper,
+ ColorPickerInput,
+ ColorPickerLabel,
+ ColorPickerRoot,
+ ColorPickerSliders,
+ ColorPickerSwatchGroup,
+ ColorPickerSwatchTrigger,
+ ColorPickerTrigger,
+ ColorPickerValueText,
+} from "@/components/ui/forms/color-picker";
+import { Field } from "@/components/ui/forms/field";
+import {
+ FileUploadClearTrigger,
+ FileUploadDropzone,
+ FileUploadFileText,
+ FileUploadLabel,
+ FileUploadList,
+ FileUploadRoot,
+ FileUploadTrigger,
+} from "@/components/ui/forms/file-upload";
+import { InputGroup } from "@/components/ui/forms/input-group";
+import {
+ NativeSelectField,
+ NativeSelectRoot,
+} from "@/components/ui/forms/native-select";
+import {
+ NumberInputField,
+ NumberInputRoot,
+} from "@/components/ui/forms/number-input";
+import {
+ PasswordInput,
+ PasswordStrengthMeter,
+} from "@/components/ui/forms/password-input";
+import { PinInput } from "@/components/ui/forms/pin-input";
+import { Radio, RadioGroup } from "@/components/ui/forms/radio";
+import {
+ RadioCardItem,
+ RadioCardLabel,
+ RadioCardRoot,
+} from "@/components/ui/forms/radio-card";
+import { Rating } from "@/components/ui/forms/rating";
+import { SegmentedControl } from "@/components/ui/forms/segmented-control";
+import { Slider } from "@/components/ui/forms/slider";
+import { Switch } from "@/components/ui/forms/switch";
+import {
+ ActionBarContent,
+ ActionBarRoot,
+ ActionBarSelectionTrigger,
+ ActionBarSeparator,
+} from "@/components/ui/overlays/action-bar";
+import {
+ DialogActionTrigger,
+ DialogBody,
+ DialogCloseTrigger,
+ DialogContent,
+ DialogFooter,
+ DialogHeader,
+ DialogRoot,
+ DialogTitle,
+ DialogTrigger,
+} from "@/components/ui/overlays/dialog";
+import {
+ DrawerActionTrigger,
+ DrawerBody,
+ DrawerCloseTrigger,
+ DrawerContent,
+ DrawerFooter,
+ DrawerHeader,
+ DrawerRoot,
+ DrawerTitle,
+ DrawerTrigger,
+} from "@/components/ui/overlays/drawer";
+import {
+ HoverCardArrow,
+ HoverCardContent,
+ HoverCardRoot,
+ HoverCardTrigger,
+} from "@/components/ui/overlays/hover-card";
+import {
+ MenuContent,
+ MenuItem,
+ MenuItemCommand,
+ MenuItemText,
+ MenuRadioItem,
+ MenuRadioItemGroup,
+ MenuRoot,
+ MenuTrigger,
+ MenuTriggerItem,
+} from "@/components/ui/overlays/menu";
+import {
+ PopoverBody,
+ PopoverContent,
+ PopoverFooter,
+ PopoverHeader,
+ PopoverRoot,
+ PopoverTitle,
+ PopoverTrigger,
+} from "@/components/ui/overlays/popover";
+import { InfoTip } from "@/components/ui/overlays/toggle-tip";
+import { Tooltip } from "@/components/ui/overlays/tooltip";
+import {
+ Blockquote,
+ BlockquoteIcon,
+} from "@/components/ui/typography/blockquote";
+import {
+ accordionItems,
+ alertStatuses,
+ alignments,
+ boxData,
+ breadcrumbItems,
+ colorPalettes,
+ countries,
+ fontSizes,
+ formats,
+ frameworks,
+ headings,
+ images,
+ items,
+ itemsTabs,
+ justifications,
+ marks,
+ MAX_FILES,
+ placements,
+ radioCardItems,
+ radioCardItems2,
+ radioItems,
+ rootNode,
+ stats,
+ steps,
+ swatches,
+ variants,
+} from "@/data/constants";
+import {
+ AbsoluteCenter,
+ Badge,
+ Box,
+ ButtonGroup,
+ Card,
+ Center,
+ Checkmark,
+ Circle,
+ ClientOnly,
+ Code,
+ Collapsible,
+ ColorPickerFormatSelect,
+ ColorPickerPositioner,
+ ComboboxContent,
+ createListCollection,
+ createTreeCollection,
+ DownloadTrigger,
+ Flex,
+ Float,
+ For,
+ FormatByte,
+ FormatNumber,
+ Grid,
+ GridItem,
+ Heading,
+ Highlight,
+ HStack,
+ Icon,
+ IconButton,
+ Image,
+ Input,
+ Kbd,
+ Mark,
+ parseColor,
+ Portal,
+ ProgressValueText,
+ ScrollArea,
+ Separator,
+ SimpleGrid,
+ Span,
+ Spinner,
+ Square,
+ Stack,
+ StackSeparator,
+ Strong,
+ Table,
+ Tabs,
+ Text,
+ Textarea,
+ TreeView,
+ useFilter,
+ useHighlight,
+ useListboxItemContext,
+ useListCollection,
+ useTreeViewContext,
+ VStack,
+ Wrap,
+} from "@chakra-ui/react";
+import React from "react";
+import { Fragment } from "react";
+import { FaBell, FaMoon, FaReact, FaSearch, FaSun } from "react-icons/fa";
+import { FaCartShopping } from "react-icons/fa6";
+import {
+ HiCheck,
+ HiColorSwatch,
+ HiShieldCheck,
+ HiSortAscending,
+ HiStar,
+ HiUpload,
+ HiX,
+} from "react-icons/hi";
+import { IoHeart } from "react-icons/io5";
+import {
+ LuCheck,
+ LuChevronRight,
+ LuFile,
+ LuFileUp,
+ LuFolder,
+ LuImageDown,
+ LuPackage,
+ LuPen,
+ LuPercent,
+ LuPhone,
+ LuPhoneForwarded,
+ LuPlus,
+ LuShare,
+ LuShip,
+ LuSquareCheck,
+ LuSquareMinus,
+ LuSquarePlus,
+ LuTrash,
+ LuTrash2,
+ LuUser,
+ LuVoicemail,
+ LuX,
+} from "react-icons/lu";
+import { Md123, Md3dRotation, MdGraphicEq, MdMail } from "react-icons/md";
+import { toaster } from "@/components/ui/feedback/toaster";
+import { Avatar, AvatarGroup } from "@/components/ui/data-display/avatar";
+import {
+ ClipboardButton,
+ ClipboardIconButton,
+ ClipboardInput,
+ ClipboardRoot,
+} from "@/components/ui/data-display/clipboard";
+import {
+ DataListItem,
+ DataListRoot,
+} from "@/components/ui/data-display/data-list";
+import { QrCode } from "@/components/ui/data-display/qr-code";
+import { GiSnake } from "react-icons/gi";
+import {
+ StatDownTrend,
+ StatHelpText,
+ StatLabel,
+ StatRoot,
+ StatUpTrend,
+ StatValueText,
+} from "@/components/ui/data-display/stat";
+import {
+ PaginationItems,
+ PaginationNextTrigger,
+ PaginationPageText,
+ PaginationPrevTrigger,
+ PaginationRoot,
+} from "@/components/ui/disclosure/pagination";
+import { Tag } from "@/components/ui/data-display/tag";
+import {
+ TimelineConnector,
+ TimelineContent,
+ TimelineDescription,
+ TimelineItem,
+ TimelineRoot,
+ TimelineTitle,
+} from "@/components/ui/data-display/timeline";
+import {
+ AccordionItem,
+ AccordionItemContent,
+ AccordionItemTrigger,
+ AccordionRoot,
+} from "@/components/ui/disclosure/accordion";
+import {
+ BreadcrumbLink,
+ BreadcrumbRoot,
+} from "@/components/ui/disclosure/breadcrumb";
+import { LiaSlashSolid } from "react-icons/lia";
+import {
+ StepsCompletedContent,
+ StepsContent,
+ StepsItem,
+ StepsList,
+ StepsNextTrigger,
+ StepsPrevTrigger,
+ StepsRoot,
+} from "@/components/ui/disclosure/steps";
+import { PiSmileyNervous, PiSmileyWink } from "react-icons/pi";
+
+interface Node {
+ id: string;
+ name: string;
+ children?: Node[];
+ childrenCount?: number;
+}
+
+interface TreeNodeProps extends TreeView.NodeProviderProps {
+ onRemove?: (props: TreeView.NodeProviderProps) => void;
+ onAdd?: (props: TreeView.NodeProviderProps) => void;
+}
+
+type ErrorLevel = "L" | "M" | "Q" | "H";
+
+interface Item {
+ id: string;
+ title: string;
+ content: React.ReactNode;
+}
+
+function HomeCard() {
+ const contentRef = React.useRef(null);
+ const [selectedSkills, setSelectedSkills] = React.useState([]);
+ const [selectedImage, setSelectedImage] = React.useState("mountains");
+ const [checked, setChecked] = React.useState(false);
+ const [radioItemValue, setRadioItemValue] = React.useState("asc");
+ const [loading, setLoading] = React.useState(true);
+ const [errorLevel, setErrorLevel] = React.useState("L");
+
+ const chunks = useHighlight({
+ text: "Endless scale, powered by real humans.",
+ query: ["Endless", "real humans."],
+ });
+
+ const downloadData = async () => {
+ const res = await fetch("https://picsum.photos/200/300");
+ return res.blob();
+ };
+
+ const { contains, startsWith } = useFilter({ sensitivity: "base" });
+
+ const { collection: frameworkCollection, filter: frameworkFilter } =
+ useListCollection({
+ initialItems: frameworks,
+ filter: contains,
+ });
+ const { collection: countryCollection, filter: countryFilter } =
+ useListCollection({
+ initialItems: countries,
+ filter: startsWith,
+ limit: 10,
+ });
+
+ const listboxCollection = createListCollection({ items: frameworks });
+ const imagesCollection = createListCollection({ items: images });
+
+ const currentImage = imagesCollection.items.find(
+ (img) => img.value === selectedImage
+ );
+
+ const nodeCollection = createTreeCollection({
+ nodeToValue: (node) => node.id,
+ nodeToString: (node) => node.name,
+ rootNode: rootNode,
+ });
+
+ const [tabs, setTabs] = React.useState- (itemsTabs);
+ const [selectedTab, setSelectedTab] = React.useState
(
+ itemsTabs[0].id
+ );
+
+ const uuid = () => {
+ return Math.random().toString(36).substring(2, 15);
+ };
+
+ const addTab = () => {
+ const newTabs = [...tabs];
+
+ const uid = uuid();
+
+ newTabs.push({
+ id: uid,
+ title: `Tab`,
+ content: `Tab Body`,
+ });
+
+ setTabs(newTabs);
+ setSelectedTab(newTabs[newTabs.length - 1].id);
+ };
+
+ const removeTab = (id: string) => {
+ if (tabs.length >= 1) {
+ const newTabs = [...tabs].filter((tab) => tab.id !== id);
+ setTabs(newTabs);
+ }
+ };
+
+ const [collection, setCollection] = React.useState(nodeCollection);
+ const [selection, setSelection] = React.useState([]);
+
+ const hasSelection = selection.length > 0;
+ const indeterminate = hasSelection && selection.length < items.length;
+
+ const removeNode = (props: TreeNodeProps) => {
+ setCollection(collection.remove([props.indexPath]));
+ };
+
+ const addNode = (props: TreeNodeProps) => {
+ const { node, indexPath } = props;
+ if (!collection.isBranchNode(node)) {
+ return;
+ }
+
+ const children = [
+ {
+ id: `untitled-${Date.now()}`,
+ name: `untitled-${node.children?.length}.tsx`,
+ },
+ ...(node.children || []),
+ ];
+ setCollection(collection.replace(indexPath, { ...node, children }));
+ };
+
+ const handleSelectionChange = (details: { value: string[] }) => {
+ if (details.value.length > 0) {
+ setSelectedImage(details.value[0]);
+ }
+ };
+
+ const ListboxItemCheckmark = () => {
+ const itemState = useListboxItemContext();
+ return (
+
+ );
+ };
+
+ const TreeNodeActions = (props: TreeNodeProps) => {
+ const { onRemove, onAdd, node } = props;
+ const tree = useTreeViewContext();
+ const isBranch = tree.collection.isBranchNode(node);
+ return (
+
+ {
+ e.stopPropagation();
+ onRemove?.(props);
+ }}
+ >
+
+
+ {isBranch && (
+ {
+ e.stopPropagation();
+ onAdd?.(props);
+ tree.expand([node.id]);
+ }}
+ >
+
+
+ )}
+
+ );
+ };
+
+ return (
+
+ {/* Font sizes */}
+
+
+
+ {(fontSize, index) => (
+
+ Text {fontSize as string}
+
+ )}
+
+
+
+ {/* Buttons */}
+
+
+
+
+ Primary (teal):
+
+ {"primary"}
+
+
+ {(palette, index) => (
+
+
+ {palette as string}:
+
+
+
+ {(variant, innerIndex) => (
+
+ {variant as string}
+
+ )}
+
+
+
+ )}
+
+
+
+ Close Button:
+
+
+
+
+
+
+ IconButton:
+
+ {(variant) => (
+
+
+
+
+ {variant}
+
+ )}
+
+
+
+
+
+ Download
+
+
+
+
+ {/* Box */}
+
+
+ Box
+
+
+ This is a box
+
+
+ This is a box with pseudo props
+
+
+ This is a disabled box
+
+
+
+
+
+
+ Superhost
+
+
+
+
+
+
+ {boxData.rating} ({boxData.reviewCount})
+
+
+
+
+ {boxData.title}
+
+
+ {boxData.formattedPrice} • {boxData.beds} beds
+
+
+
+
+ {/* Absolute Center, Center, Square, Circle */}
+
+
+ Absolute Center, Center, Square, Circle
+
+
+
+
+
+ Absolute Center
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Flex */}
+
+ {/* Flex Align */}
+
+ Flex Align
+
+
+ {alignments.map((align) => (
+
+
+
+ {align}
+
+
+
+ ))}
+
+ {/* Flex Justify */}
+
+ Flex Justify
+
+
+
+ {justifications.map((justify) => (
+
+
+
+ {justify}
+
+
+
+ ))}
+
+
+ {/* Float */}
+
+
+ Float
+
+
+ {placements.map((placement, index) => (
+
+ {placement}
+
+
+
+ {++index}
+
+
+
+
+ ))}
+
+
+ {/* Grid */}
+
+
+ Grid
+
+
+
+
+ Sol içerik
+
+
+
+
+
+ Sağ içerik
+
+
+
+
+
+ Alt içerik
+
+
+
+
+ {/* Simple Grid */}
+
+
+ Simple Grid
+
+
+
+ Box1
+
+
+ Box2
+
+
+ Box3
+
+
+ Box4
+
+
+
+ {/* Scroll Area */}
+
+
+ Scroll Area
+
+
+
+
+ {(variant) => (
+
+ {`variant="${variant}"`}
+
+
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit.
+ Consequatur ratione quaerat nulla autem. Rerum, deserunt
+ eius illo sed quas aperiam ad sit tempora ea voluptatum
+ nemo, expedita facere sunt. Accusantium! Laudantium
+ maxime numquam et laboriosam dolore tenetur obcaecati
+ amet aliquid veritatis excepturi sapiente vitae quae
+ beatae sit exercitationem nam praesentium nobis
+ expedita, atque explicabo. Consequatur, nostrum numquam.
+ Iste, perferendis suscipit? Sequi cumque alias nisi
+ deleniti quam perferendis doloremque ducimus facere,
+ officiis tempora, illum laborum accusantium id, autem
+ saepe repellendus. Quos veniam rerum provident officiis
+ libero minima autem, dolor porro eaque. Alias esse
+ quibusdam ratione quas quod, modi aperiam praesentium
+ quam porro consectetur sed unde soluta quo neque quae
+ delectus accusamus fugiat exercitationem, eligendi nobis
+ animi nulla nisi. Similique, enim. Consequatur!
+
+
+
+
+
+ )}
+
+
+
+
+
+
+
+ {Array.from({ length: 12 }, (_, i) => (
+
+ Item {i + 1}
+
+ ))}
+
+
+
+
+
+
+
+
+
+ {/* Separator */}
+
+
+ Separator
+
+ xs
+
+ sm
+
+ md
+
+ lg
+
+
+ Label (start)
+
+
+
+
+
+ Label (end)
+
+
+
+
+ Label (center)
+
+
+
+ {/* Stack */}
+
+
+ Stack
+
+ }>
+
+
+
+ HStack
+
+
+
+
+
+
+ VStack
+
+
+
+
+
+ {/* Blockquote */}
+
+
+ Blockquote
+
+
+
+ Lorem ipsum dolor, sit amet consectetur adipisicing elit.
+
+ }
+ >
+ Türk milletinin istidadı ve kati kararı medeniyet yolunda durmadan,
+ yılmadan ilerlemektir.{" "}
+
+
+
+ {/* Code */}
+
+
+ Code
+
+ {`console.log("Hello, world!")`}
+ {`console.log("Hello, world!")`}
+ {`console.log("Hello, world!")`}
+ {`console.log("Hello, world!")`}
+
+ {/* Heading */}
+
+
+ Heading
+
+
+ {(size, index) => (
+
+ Heading ({size})
+
+ )}
+
+
+ {/* Highlight & Mark */}
+
+
+ Highlight & Mark
+
+
+
+
+ With the Highlight component, you can spotlight, emphasize and
+ accentuate words.
+
+
+
+
+ {(variant) => (
+
+ The design system is a
+ collection of UI elements
+
+ )}
+
+
+
+ {chunks.map((chunk, index) => {
+ return chunk.match ? (
+
+ {chunk.text}
+
+
+ ) : (
+ {chunk.text}
+ );
+ })}
+
+
+
+ {/* Kbd */}
+
+
+ Kbd
+
+
+ ctrl +shift +del
+
+
+ ⌘
+ ⌥
+ ⇧
+ ⌃
+
+
+ Raised
+ Outline
+ Subtle
+ Plain
+
+
+ {/* Checkbox & Checkbox Card */}
+
+
+ Checkbox & Checkbox Card
+
+
+
+ {(variant) => (
+
+ {variant}
+
+ Checkbox
+
+
+ )}
+
+
+
+
+ }
+ addon={
+
+ Some supporting text
+ New
+
+ }
+ />
+
+
+ {/* Color Picker */}
+
+
+ Color Picker
+
+
+
+ Basic Color Picker
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Color Picker + Eye Dropper + Swatches
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {swatches.map((item) => (
+
+ ))}
+
+
+
+
+
+
+ Swatch Only Color:
+
+
+ {swatches.map((item) => (
+
+ ))}
+
+
+
+ Channel Sliders
+
+
+
+
+
+
+
+
+ {(format, index) => (
+
+ )}
+
+
+
+
+
+
+
+ {/* Fields, Input, Select, Textarea, Number Input */}
+
+
+ Fields, Input, Select, Textarea
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ endElement={ }
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* File Upload */}
+
+
+ File Upload
+
+
+
+ Basic File Upload
+
+
+ File Upload
+
+
+
+
+
+
+ Multiple File Upload
+
+
+ File Upload
+
+
+
+
+
+
+ Upload File Input
+ }
+ endElement={
+
+
+
+ }
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Radio Card*/}
+
+
+ Radio Card
+
+
+
+ {(variant) => (
+
+ variant = ({variant})
+
+ {radioCardItems.map((item) => (
+
+ ))}
+
+
+ )}
+
+
+
+ Select framework
+
+ {radioCardItems2.map((item) => (
+ }
+ />
+ ))}
+
+
+
+ {/* Radio */}
+
+
+ Radio
+
+
+
+ {(variant) => (
+
+
+ React
+ Vue
+
+
+ )}
+
+
+
+ {/* Rating */}
+
+
+ Rating
+
+
+
+
+ {(size) => (
+
+ {size}
+
+
+ )}
+
+
+
+ }
+ />
+
+
+
+ {/* Segemented Control */}
+
+
+ Segemented Control
+
+
+
+ Horizontal:
+
+
+
+ Vertical:
+
+
+
+
+ {/* Switch */}
+
+
+ Switch
+
+
+
+ {(variant) => (
+
+ {variant}
+
+ )}
+
+ Invalid Switch
+ , off: }}>
+ Thumb Label Switch
+
+ ,
+ off: ,
+ }}
+ >
+ Track Label Switch
+
+
+
+ {/* Slider */}
+
+
+ Sliders
+
+
+
+
+
+ {(variant) => (
+
+ )}
+
+
+ {(size) => (
+
+ )}
+
+
+
+
+
+
+
+
+
+ }
+ />
+
+
+
+
+ {/* Combobox */}
+
+
+ Combobox
+
+
+ frameworkFilter(e.inputValue)}
+ >
+ Simple Combobox
+
+
+
+
+ No items found
+ {frameworkCollection.items.map((item) => (
+
+ {item.label}
+
+ ))}
+
+
+
+ setSelectedSkills(e.value)}
+ collection={frameworkCollection}
+ onInputValueChange={(e) => frameworkFilter(e.inputValue)}
+ >
+
+ {selectedSkills.map((skill) => (
+ {skill}
+ ))}
+
+ Multiple Combobox
+
+
+
+
+ No items found
+ {frameworkCollection.items.map((item) => (
+
+ {item.label}
+
+ ))}
+
+
+
+ countryFilter(e.inputValue)}
+ >
+ Large Data Combobox
+
+
+
+
+ No items found
+ {countryCollection.items.map((item) => (
+
+ {item.label}
+
+ ))}
+
+
+
+
+ frameworkFilter(e.inputValue)}
+ >
+
+
+
+
+ No items found
+ {frameworkCollection.items.map((item) => (
+
+ {item.label}
+
+ ))}
+
+
+
+
+
+ {/* Listbox */}
+
+
+ Listbox
+
+
+
+
+
+ Select framework
+
+ {listboxCollection.items.map((framework) => (
+
+ {framework.label}
+
+ ))}
+
+
+
+
+
+
+
+ Select framework (with checkmarks)
+
+ {listboxCollection.items.map((framework) => (
+
+
+ {framework.label}
+
+ ))}
+
+
+
+
+
+
+
+
+ {imagesCollection.items.map((image) => (
+
+ {image.label}
+
+ ))}
+
+
+
+
+ {currentImage && (
+
+
+ {currentImage.label}
+
+
+
+ {currentImage.description}
+
+
+ )}
+
+
+
+
+
+ {/* TreeView */}
+
+
+ TreeView
+
+
+
+ Simple TreeView
+
+
+ nodeState.isBranch ? (
+
+ {nodeState.expanded ? (
+
+ ) : (
+
+ )}
+ {node.name}
+
+ ) : (
+ {node.name}
+ )
+ }
+ />
+
+
+
+
+ Remove Indentation + Animation
+
+
+ nodeState.isBranch ? (
+
+
+ {node.name}
+
+ ) : (
+
+
+ {node.name}
+
+ )
+ }
+ />
+
+
+
+
+ Tree Mutation
+
+ }
+ render={({ node, nodeState, indexPath }) =>
+ nodeState.isBranch ? (
+
+
+ {node.name}
+
+
+ ) : (
+
+
+ {node.name}
+
+
+ )
+ }
+ />
+
+
+
+
+ {/* Action Bar */}
+
+
+ Action Bar
+
+
+ setChecked(!!e.checked)}
+ >
+ Show action bar
+
+
+
+ 2 selected
+
+
+
+ Delete
+
+
+
+ Share
+
+ setChecked(false)}
+ colorPalette="red"
+ variant="outline"
+ size="sm"
+ >
+ Cancel
+
+
+
+
+
+ {/* Dialog */}
+
+
+ Dialog
+
+
+
+ {(size) => (
+
+
+
+ Open ({size})
+
+
+
+
+ Dialog Title
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ Sed do eiusmod tempor incididunt ut labore et dolore magna
+ aliqua.
+
+
+
+
+ Cancel
+
+ Save
+
+
+
+
+ )}
+
+
+
+ {/* Drawer */}
+
+
+ Drawer
+
+
+
+ {(size) => (
+
+
+
+ Open ({size})
+
+
+
+
+ Drawer Title
+
+
+ Press the esc key to close the Drawer
+
+
+
+ Cancel
+
+ Save
+
+
+
+
+ )}
+
+
+
+ {/* Hover Cards */}
+
+
+ Hover Cards
+
+
+
+
+ Hover me
+
+
+
+
+
+ Chakra is a Sanskrit word that means disk or
+ wheel, referring to energy centers in the body
+
+
+
+
+
+ {/* Menu */}
+
+
+ Menu
+
+
+
+
+ Menu
+
+
+ Item 1
+ Item 2
+ Item 3
+
+
+
+
+ Commands
+
+
+
+ Copy
+ ⌘K
+
+
+ Paste
+ ⌘L
+
+
+ Cut
+ ⌘M
+
+
+
+
+
+
+
+ Submenu
+
+
+
+ New Text File
+ New File...
+
+
+ Open Recent
+
+
+ Panda
+ Ark UI
+ Chakra v3
+
+
+ Open File...
+ Export
+
+
+
+
+
+
+ Sort
+
+
+
+
+ setRadioItemValue(e.value)}
+ >
+ {radioItems.map((item) => (
+
+ {item.label}
+
+ ))}
+
+
+
+
+
+ {/* Popover */}
+
+
+ Popover
+
+
+
+ {(size) => (
+
+
+ Popover ({size})
+
+
+ Popover Header
+
+
+ Popover Title
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+
+
+ Popover Footer
+
+
+ )}
+
+
+
+ {/* Toggle Tip */}
+
+
+ Toggle Tip
+
+
+
+ File size:
+
+
+
+
+ {/* Tooltip */}
+
+
+ Tooltip
+
+
+
+
+ Hover me
+
+
+
+
+ Right End
+
+
+
+
+ 3
+
+
+
+
+ {/* Alert */}
+
+
+ Alert
+
+
+
+ {(status) => (
+
+ )}
+
+ }
+ title="Black Friday Sale (20% off)"
+ endElement={
+
+ Upgrade
+
+ }
+ >
+ Upgrade your plan to get access to the sale
+
+
+
+ {/* Empty State */}
+
+
+ Empty State
+
+
+ }
+ />
+ }
+ />
+ }
+ >
+
+ Create token
+ Import
+
+
+
+
+ {/* Progress Circle */}
+
+
+ Progress Circle
+
+
+
+ {(size, index) => (
+
+ {size}
+
+
+
+
+ )}
+
+
+
+ 90%
+
+
+
+
+
+
+ {/* Progress */}
+
+
+ Progress
+
+
+
+ {(size, index) => (
+
+ Progress ({size})
+
+
+ )}
+
+
+ Progress Info
+
+
+
+ Progress Indeterminate
+
+
+
+ Animated Striped
+
+ 40%
+
+
+
+ {/* Skeleton */}
+
+
+ Skeleton
+
+
+
+
+
+
+
+
+
+
+ Chakra UI is cool
+
+ setLoading((c) => !c)}>
+ Toggle
+
+
+
+
+
+ {/* Spinner */}
+
+
+ Spinner
+
+
+
+
+ {(size) => }
+
+
+
+
+ Loading...
+
+
+
+
+ {/* Status */}
+
+
+ Status
+
+
+
+ {(value) => (
+
+ {value}
+
+ )}
+
+
+
+ {/* Toast */}
+
+
+ Toast
+
+
+
+ {(type) => (
+
+ toaster.create({
+ title: `Toast status is ${type}`,
+ type: type,
+ })
+ }
+ >
+ {type}
+
+ )}
+
+ toaster.dismiss()}>
+ Close Toasts
+
+
+ toaster.success({
+ title: "Update successful",
+ description: "File saved successfully to the server",
+ action: {
+ label: "Undo",
+ onClick: () => console.log("Undo"),
+ },
+ })
+ }
+ >
+ With Action
+
+ {
+ const promise = new Promise((resolve) => {
+ setTimeout(() => resolve(), 5000);
+ });
+
+ toaster.promise(promise, {
+ success: {
+ title: "Successfully uploaded!",
+ description: "Looks great",
+ },
+ error: {
+ title: "Upload failed",
+ description: "Something wrong with the upload",
+ },
+ loading: { title: "Uploading...", description: "Please wait" },
+ });
+ }}
+ >
+ Promise
+
+
+
+ {/* Avatar */}
+
+
+ Avatar
+
+
+
+ {(size, index) => (
+
+ )}
+
+
+ {(variant) => }
+
+
+
+
+
+
+ {(value, index) => (
+
+ )}
+
+
+
+
+
+
+
+
+
+
+ {/* Badge */}
+
+
+ Badge
+
+
+
+ {(size) => (
+
+ {size}
+
+ )}
+
+
+ {(variant) => (
+
+ {variant}
+
+ )}
+
+
+
+ {/* Card */}
+
+
+ Card
+
+
+
+
+ Sign up
+
+ Fill in the form below to create an account
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Cancel
+ Sign in
+
+
+
+
+
+
+
+
+ Nate Foss
+
+
+ @natefoss
+
+
+
+
+ Nate Foss
+ has requested to join your team. You can approve or decline
+ their request.
+
+
+
+
+
+ Decline
+
+
+
+ Approve
+
+
+
+
+
+
+
+ The perfect latte
+
+ Caffè latte is a coffee beverage of Italian origin made with
+ espresso and steamed milk.
+
+
+ Hot
+ Caffeine
+
+
+
+ Buy Latte
+
+
+
+
+
+ {/* Clipboard */}
+
+
+ Clipboard
+
+
+
+
+
+
+
+
+
+ }>
+
+
+
+
+
+ {/* Data List */}
+
+
+ Data List
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {(stat) => (
+
+ )}
+
+
+
+
+ {/* Icon */}
+
+
+ Icon
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Qr Code */}
+
+
+ Qr Code
+
+
+
+
+
+
+
+ }
+ />
+
+
+
+ setErrorLevel(e.value as ErrorLevel)}
+ />
+
+
+
+
+
+
+
+
+
+
+ {/* Stat */}
+
+
+ Stat
+
+
+
+ Active Users
+
+ 2,200
+
+ 20% more than last month
+
+
+ Revenue
+
+
+
+
+
+ Unique Visitors
+
+ 192.1k
+
+ 18%
+
+
+ Unique Visitors
+
+ 192.1k
+ 12%
+
+
+
+
+ {/* Table */}
+
+
+ Table
+
+
+
+
+
+
+ Product
+ Category
+ Price
+
+
+
+ {items.map((item) => (
+
+ {item.name}
+ {item.category}
+ {item.price}
+
+ ))}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ }
+ onCheckedChange={(changes) => {
+ setSelection(
+ changes.checked ? items.map((item) => item.name) : []
+ );
+ }}
+ />
+
+ Product
+ Category
+ Price
+
+
+
+ {items.map((item) => (
+
+
+ {
+ setSelection((prev) =>
+ changes.checked
+ ? [...prev, item.name]
+ : selection.filter((name) => name !== item.name)
+ );
+ }}
+ />
+
+ {item.name}
+ {item.category}
+ ${item.price}
+
+ ))}
+
+
+
+
+
+ {selection.length} selected
+
+
+
+ Delete ⌫
+
+
+ Share T
+
+
+
+
+
+
+ {/* Tag */}
+
+
+ Tag
+
+
+
+ {(variant) => (
+
+ Gray
+
+ Gray
+
+ }>
+ Gray
+
+
+ )}
+
+
+ {(size) => (
+
+ }
+ >
+ Emily ({size})
+
+ )}
+
+
+
+ {/* Timeline */}
+
+
+ Timeline
+
+
+
+
+ } />
+
+ Product Shipped
+ 13th May 2021
+
+ We shipped your product via FedEx and it
+ should arrive within 3-5 business days.
+
+
+
+
+ } />
+
+ Order Confirmed
+ 18th May 2021
+
+
+
+ } />
+
+ Order Delivered
+
+ 20th May 2021, 10:30am
+
+
+
+
+
+
+ } />
+
+
+
+ Lucas Moras has changed
+ 3 labels on
+ Jan 1, 2024
+
+
+
+
+
+ } />
+
+
+
+ Jenna Smith removed
+ Enas
+ on Jan 12, 2024
+
+
+
+
+
+ } />
+
+
+
+ Erica commented
+ on Jan 12, 2024
+
+
+
+ Lorem ipsum dolor sit amet consectetur adipisicing elit.
+ Laborum possimus doloremque cumque voluptates neque,
+ aspernatur temporibus fugiat minima consequuntur similique
+ voluptatibus voluptatem id blanditiis iusto perferendis
+ repudiandae officiis nesciunt eius.
+
+
+
+ 👏 2
+
+
+
+
+
+
+
+ } />
+
+
+
+
+
+
+
+
+
+
+ Placed Order
+
+
+
+
+
+ Prepared Order
+
+
+
+
+
+
+
+
+
+ Order Delivered
+
+
+
+
+
+ {/* Accordion */}
+
+
+ Accordion
+
+
+
+ {accordionItems.map((item, index) => (
+
+
+ {item.title}
+
+ {item.text}
+
+ ))}
+
+
+ {accordionItems.map((item, index) => (
+
+
+ {item.title} multiple
+
+ {item.text}
+
+ ))}
+
+
+
+ {/* Breadcrumb */}
+
+
+ Breadcrumb
+
+
+
+ {breadcrumbItems.map((item, index) => (
+
+ {item.label}
+
+ ))}
+
+ }>
+ {breadcrumbItems.map((item, index) => (
+
+ {item.label}
+
+ ))}
+
+
+
+ {/* Collapsible */}
+
+
+ Collapsible
+
+
+
+
+
+
+
+ Toggle
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit.
+ Laboriosam, mollitia perferendis tenetur nisi sint inventore
+ dolorum labore alias? Temporibus atque explicabo suscipit
+ voluptate corrupti quidem labore natus fuga. Ut, reiciendis.
+
+
+
+
+
+ Toggle Collapse (Unmount on exit)
+
+
+
+ If you inspect the DOM, you'll notice that the content is
+ unmounted when collapsed. This is useful for performance reasons
+ when you have a lot of collapsible content.
+
+
+
+
+
+ {/* Pagination */}
+
+
+ Pagination
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Steps */}
+
+
+ Step
+
+
+
+
+ {steps.map((step, index) => (
+
+ ))}
+
+
+ {steps.map((step, index) => (
+
+ {step.description}
+
+ ))}
+
+ All steps are complete!
+
+
+
+
+ Prev
+
+
+ Next
+
+
+
+
+
+ {steps.map((step, index) => (
+
+
+
+ }
+ completedIcon={
+
+
+
+ }
+ />
+ ))}
+
+
+ {steps.map((step, index) => (
+
+ {step.description}
+
+ ))}
+
+ All steps are complete!
+
+
+
+
+ Prev
+
+
+ Next
+
+
+
+
+
+ {steps.map((step, index) => (
+
+ ))}
+
+
+
+ {steps.map((step, index) => (
+
+ {step.description}
+
+ ))}
+
+
+ All steps are complete!
+
+
+
+
+ {/* Tabs */}
+
+
+ Tabs
+
+
+
+ {(variant) => (
+
+
+
+
+ Members
+
+
+
+ Projects
+
+
+
+ Settings
+
+
+
+ Manage your team members
+
+
+ Manage your projects
+
+
+ Manage your tasks for freelancers
+
+
+ )}
+
+ setSelectedTab(e.value)}
+ >
+
+ {tabs.map((item) => (
+
+ {item.title}{" "}
+ {
+ e.stopPropagation();
+ removeTab(item.id);
+ }}
+ />
+
+ ))}
+
+ Add Tab
+
+
+
+
+ {tabs.map((item) => (
+
+
+ {item.content} {item.id}
+
+
+ Dolore ex esse laboris elit magna esse sunt. Pariatur in
+ veniam Lorem est occaecat do magna nisi mollit ipsum sit
+ adipisicing fugiat ex. Pariatur ullamco exercitation ea qui
+ adipisicing. Id cupidatat aute id ut excepteur exercitation
+ magna pariatur. Mollit irure irure reprehenderit pariatur
+ eiusmod proident Lorem deserunt duis cillum mollit.
+
+
+ ))}
+
+
+
+
+ {/* Format Number */}
+
+
+ Format Number
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Format Byte */}
+
+
+ Format Byte
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Client Only */}
+
+
+ Client Only
+
+ }>
+ {() => (
+
+ Current URL: {window.location.href}
+ Screen width: {window.innerWidth}px
+
+ )}
+
+
+
+ );
+}
+
+export default HomeCard;
diff --git a/src/components/spor-toto/spor-toto-content.tsx b/src/components/spor-toto/spor-toto-content.tsx
new file mode 100644
index 0000000..7626e53
--- /dev/null
+++ b/src/components/spor-toto/spor-toto-content.tsx
@@ -0,0 +1,386 @@
+"use client";
+
+import {
+ Box,
+ Flex,
+ Heading,
+ Text,
+ Card,
+ VStack,
+ HStack,
+ Badge,
+ Spinner,
+ Button,
+ Table,
+} from "@chakra-ui/react";
+import { useTranslations } from "next-intl";
+import { useColorModeValue } from "@/components/ui/color-mode";
+import { SlideUp, StaggerContainer, StaggerItem } from "@/components/motion";
+import {
+ useBulletins,
+ useGeneratePrediction,
+ useSyncBulletin,
+ useRolloverHistory,
+} from "@/lib/api/spor-toto/use-hooks";
+import type {
+ SporTotoBulletinDto,
+ SporTotoPredictionResultDto,
+} from "@/lib/api/spor-toto/service";
+import {
+ LuRefreshCw,
+ LuSparkles,
+ LuTrendingUp,
+ LuTicket,
+} from "react-icons/lu";
+import { useState } from "react";
+import { toaster } from "@/components/ui/feedback/toaster";
+import {
+ NativeSelectRoot,
+ NativeSelectField,
+} from "@/components/ui/forms/native-select";
+
+type PredictionStrategy =
+ | "CONSERVATIVE"
+ | "BALANCED"
+ | "AGGRESSIVE"
+ | "FORMULA_6PCT";
+
+export default function SporTotoContent() {
+ const t = useTranslations("spor-toto");
+ const tCommon = useTranslations("common");
+
+ const cardBg = useColorModeValue("white", "gray.800");
+ const borderColor = useColorModeValue("gray.100", "gray.700");
+
+ const [selectedBulletin, setSelectedBulletin] = useState("");
+ const [strategy, setStrategy] = useState("BALANCED");
+
+ const bulletins = useBulletins();
+ const rolloverHistory = useRolloverHistory(10);
+ const syncBulletin = useSyncBulletin();
+ const generatePrediction = useGeneratePrediction();
+ const toast = (opts: { title: string; status: string }) =>
+ toaster.create({
+ title: opts.title,
+ type: opts.status as
+ | "success"
+ | "warning"
+ | "error"
+ | "info"
+ | "loading",
+ });
+
+ const handleSync = async () => {
+ await syncBulletin.mutateAsync();
+ toast({
+ title: t("sync-success"),
+ status: "success",
+ });
+ bulletins.refetch();
+ };
+
+ const handlePredict = async () => {
+ if (!selectedBulletin) {
+ toast({
+ title: t("select-bulletin"),
+ status: "warning",
+ });
+ return;
+ }
+ const result = await generatePrediction.mutateAsync({
+ bulletinId: selectedBulletin,
+ strategy,
+ });
+ toast({
+ title: t("prediction-generated"),
+ status: "success",
+ });
+ };
+
+ const strategies: {
+ value: PredictionStrategy;
+ label: string;
+ desc: string;
+ }[] = [
+ {
+ value: "CONSERVATIVE",
+ label: t("strategy-conservative"),
+ desc: t("strategy-conservative-desc"),
+ },
+ {
+ value: "BALANCED",
+ label: t("strategy-balanced"),
+ desc: t("strategy-balanced-desc"),
+ },
+ {
+ value: "AGGRESSIVE",
+ label: t("strategy-aggressive"),
+ desc: t("strategy-aggressive-desc"),
+ },
+ {
+ value: "FORMULA_6PCT",
+ label: t("strategy-formula"),
+ desc: t("strategy-formula-desc"),
+ },
+ ];
+
+ return (
+
+
+
+
+ {t("title")}
+
+
+
+ {t("sync-bulletins")}
+
+
+
+
+
+ {/* Left Column - Bulletin Selection & Prediction */}
+
+ {/* Bulletin Selection */}
+
+
+
+ {t("select-bulletin")}
+
+
+
+ {bulletins.isLoading ? (
+
+
+
+ ) : (
+
+ setSelectedBulletin(e.target.value)}
+ placeholder={t("choose-bulletin")}
+ >
+ {bulletins.data?.data?.map((b: SporTotoBulletinDto) => (
+
+ {t("bulletin-label", {
+ cycle: b.gameCycleNo,
+ date: new Date(b.drawDate).toLocaleDateString(),
+ })}
+
+ ))}
+
+
+ )}
+
+
+
+ {/* Strategy Selection */}
+
+
+
+ {t("choose-strategy")}
+
+
+
+
+ {strategies.map((s) => (
+ setStrategy(s.value)}
+ _hover={{ borderColor: "primary.300" }}
+ >
+
+
+
+ {s.label}
+
+ {s.desc}
+
+
+
+ {strategy === s.value ? : null}
+ {strategy === s.value ? t("selected") : ""}
+
+
+
+
+ ))}
+
+
+ {t("generate-prediction")}
+
+
+
+
+ {/* Bulletins List */}
+
+
+
+ {t("bulletin-history")}
+
+
+
+ {bulletins.isLoading ? (
+
+
+
+ ) : (
+
+
+
+
+ {t("cycle-no")}
+
+
+ {t("draw-date")}
+
+ {t("status")}
+
+ {t("matches")}
+
+
+
+
+ {bulletins.data?.data?.map((b: SporTotoBulletinDto) => (
+ setSelectedBulletin(b.id)}
+ bg={
+ selectedBulletin === b.id
+ ? "primary.50"
+ : "transparent"
+ }
+ >
+ {b.gameCycleNo}
+
+ {new Date(b.drawDate).toLocaleDateString()}
+
+
+
+ {b.status}
+
+
+ {b.matches?.length || 0}
+
+ ))}
+
+
+ )}
+
+
+
+
+ {/* Right Column - Rollover Stats */}
+
+
+
+
+
+
+ {t("rollover-stats")}
+
+
+
+
+ {rolloverHistory.isLoading ? (
+
+ ) : (
+
+ {rolloverHistory.data?.data
+ ?.slice(0, 5)
+ .map(
+ (item: {
+ gameCycleNo: number;
+ rolloverAmount: number;
+ drawDate: string;
+ }) => (
+
+
+
+ {t("cycle-no-short", {
+ cycle: item.gameCycleNo,
+ })}
+
+
+ {new Date(item.drawDate).toLocaleDateString()}
+
+
+
+
+
+
+ {new Intl.NumberFormat("tr-TR", {
+ style: "currency",
+ currency: "TRY",
+ }).format(item.rolloverAmount)}
+
+
+
+
+ ),
+ )}
+
+ )}
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/teams/team-detail-content.tsx b/src/components/teams/team-detail-content.tsx
new file mode 100644
index 0000000..150237f
--- /dev/null
+++ b/src/components/teams/team-detail-content.tsx
@@ -0,0 +1,330 @@
+"use client";
+
+import {
+ Box,
+ Flex,
+ Text,
+ Heading,
+ Badge,
+ VStack,
+ HStack,
+ Image,
+ Spinner,
+ Button,
+ Card,
+ Table,
+} from "@chakra-ui/react";
+import { useTranslations } from "next-intl";
+import { useParams, useRouter } from "next/navigation";
+import { useColorModeValue } from "@/components/ui/color-mode";
+import { SlideUp, FadeIn } from "@/components/motion";
+import { useTeamById, useTeamMatches } from "@/lib/api/leagues/use-hooks";
+import { LuArrowLeft, LuCalendar, LuTrophy } from "react-icons/lu";
+import type { MatchResponseDto } from "@/lib/api/matches/types";
+
+function getMatchTimestamp(match: MatchResponseDto): number {
+ const raw = typeof match.mstUtc === "string" ? Number(match.mstUtc) : match.mstUtc;
+ return Number.isFinite(raw) ? raw : 0;
+}
+
+function getMatchStatus(match: MatchResponseDto): string {
+ return String(match.status || (match as Record).state || "").toUpperCase();
+}
+
+function isMatchFinished(match: MatchResponseDto): boolean {
+ const status = getMatchStatus(match);
+ return status === "FT" || status === "FINISHED" || status === "POSTGAME" || status === "POST_GAME";
+}
+
+function isMatchLive(match: MatchResponseDto): boolean {
+ const status = getMatchStatus(match);
+ return status === "LIVE" || status === "INPROGRESS" || status === "IN_PROGRESS";
+}
+
+function getTeamSideName(team: MatchResponseDto["homeTeam"] | MatchResponseDto["awayTeam"], fallback?: unknown): string {
+ return String(team?.name || fallback || "");
+}
+
+function getTeamSideLogo(team: MatchResponseDto["homeTeam"] | MatchResponseDto["awayTeam"], fallback?: unknown): string {
+ return String(team?.logo || team?.logoUrl || fallback || "");
+}
+
+function getLeagueLabel(match: MatchResponseDto): string {
+ return String(match.leagueName || match.league?.name || "");
+}
+
+export default function TeamDetailContent() {
+ const t = useTranslations();
+ const params = useParams();
+ const router = useRouter();
+
+ const teamId = params.id as string;
+
+ const { data: teamData, isLoading: teamLoading } = useTeamById(teamId);
+ const { data: matchesData, isLoading: matchesLoading } = useTeamMatches(teamId, { limit: 30 });
+
+ const cardBg = useColorModeValue("white", "gray.800");
+ const borderColor = useColorModeValue("gray.100", "gray.700");
+
+ const team = teamData?.data;
+ const matches: MatchResponseDto[] = matchesData?.data ?? [];
+
+ if (teamLoading) {
+ return (
+
+
+
+ );
+ }
+
+ if (!team) {
+ return (
+
+ Takım bulunamadı
+ router.back()}>
+ Geri
+
+
+ );
+ }
+
+ // Separate past and upcoming matches
+ const isFinished = (m: MatchResponseDto) => isMatchFinished(m);
+
+ const pastMatches = matches.filter((m: MatchResponseDto) => isFinished(m));
+ const upcomingMatches = matches.filter((m: MatchResponseDto) => !isFinished(m));
+
+ const getStatusBadge = (match: MatchResponseDto) => {
+ if (isMatchLive(match))
+ return (
+
+ Canlı
+
+ );
+ if (isMatchFinished(match))
+ return (
+
+ Bitti
+
+ );
+ return (
+
+ Yaklaşan
+
+ );
+ };
+
+ return (
+
+
+ {/* Back Button */}
+ router.back()} gap={1.5}>
+
+ Geri
+
+
+ {/* Team Header */}
+
+
+
+ {team.logo ? (
+
+ ) : (
+
+
+ {team.name?.charAt(0) || "T"}
+
+
+ )}
+
+
+ {team.name}
+
+ {team.country && (
+
+ 🌍 {team.country}
+
+ )}
+
+
+
+ {matches.length} Maç
+
+
+
+ {upcomingMatches.length} Yaklaşan
+
+
+
+
+
+
+
+ {/* Upcoming Matches */}
+ {upcomingMatches.length > 0 && (
+
+
+
+ 📅 Yaklaşan Maçlar
+
+
+ {upcomingMatches.map((match: MatchResponseDto) => (
+ router.push(`/tr/matches/${match.id}`)}
+ />
+ ))}
+
+
+
+ )}
+
+ {/* Past Matches */}
+
+
+
+ 📊 Geçmiş Maçlar
+
+ {matchesLoading ? (
+
+
+
+ ) : pastMatches.length === 0 ? (
+
+ Geçmiş maç bulunamadı
+
+ ) : (
+
+ {pastMatches.map((match: MatchResponseDto) => (
+ router.push(`/tr/matches/${match.id}`)}
+ />
+ ))}
+
+ )}
+
+
+
+
+ );
+}
+
+// ─────────────────────────────────────────────────
+// Match Row Component
+// ─────────────────────────────────────────────────
+
+interface MatchRowProps {
+ match: MatchResponseDto;
+ cardBg: string;
+ borderColor: string;
+ statusBadge: React.ReactNode;
+ onClick: () => void;
+}
+
+function MatchRow({ match, cardBg, borderColor, statusBadge, onClick }: MatchRowProps) {
+ const hoverBg = useColorModeValue("gray.50", "gray.700");
+ const matchTimestamp = getMatchTimestamp(match);
+ const homeTeamName = getTeamSideName(match.homeTeam, match.homeTeamName);
+ const awayTeamName = getTeamSideName(match.awayTeam, match.awayTeamName);
+ const homeTeamLogo = getTeamSideLogo(match.homeTeam, match.homeTeamLogo);
+ const awayTeamLogo = getTeamSideLogo(match.awayTeam, match.awayTeamLogo);
+ const leagueLabel = getLeagueLabel(match);
+ const hasScore = isMatchFinished(match) || isMatchLive(match);
+
+ return (
+
+
+
+
+ {/* Home Team */}
+
+
+ {homeTeamName}
+
+ {homeTeamLogo ? (
+
+ ) : (
+
+ {homeTeamName?.charAt(0)}
+
+ )}
+
+
+ {/* Score / VS */}
+
+ {hasScore && match.scoreHome !== undefined && match.scoreHome !== null ? (
+
+ {match.scoreHome} - {match.scoreAway}
+
+ ) : (
+
+ vs
+
+ )}
+
+ {matchTimestamp
+ ? new Date(matchTimestamp).toLocaleDateString("tr-TR", {
+ day: "2-digit",
+ month: "short",
+ })
+ : "-"}
+
+
+
+ {/* Away Team */}
+
+ {awayTeamLogo ? (
+
+ ) : (
+
+ {awayTeamName?.charAt(0)}
+
+ )}
+
+ {awayTeamName}
+
+
+
+
+ {/* Status + League */}
+
+ {leagueLabel && (
+
+ {leagueLabel}
+
+ )}
+ {statusBadge}
+
+
+
+
+ );
+}
diff --git a/src/components/teams/teams-content.tsx b/src/components/teams/teams-content.tsx
new file mode 100644
index 0000000..658d097
--- /dev/null
+++ b/src/components/teams/teams-content.tsx
@@ -0,0 +1,147 @@
+"use client";
+
+import { useState } from "react";
+import {
+ Box,
+ Flex,
+ Input,
+ Text,
+ VStack,
+ HStack,
+ Heading,
+ Image,
+ Spinner,
+ Card,
+} from "@chakra-ui/react";
+import { useTranslations } from "next-intl";
+import { useColorModeValue } from "@/components/ui/color-mode";
+import { SlideUp } from "@/components/motion";
+import { useSearchTeams } from "@/lib/api/leagues/use-hooks";
+import { useRouter } from "@/i18n/navigation";
+import { LuSearch } from "react-icons/lu";
+import type { TeamDto } from "@/lib/api/leagues/types";
+
+export default function TeamsContent() {
+ const t = useTranslations();
+ const [query, setQuery] = useState("");
+ const router = useRouter();
+
+ const cardBg = useColorModeValue("white", "gray.800");
+ const borderColor = useColorModeValue("gray.100", "gray.700");
+ const hoverBg = useColorModeValue("gray.50", "gray.700");
+
+ const { data: searchData, isLoading } = useSearchTeams({ q: query });
+ const teams: TeamDto[] = searchData?.data ?? [];
+
+ return (
+
+
+
+ 🔍 {t("nav.teams")}
+
+
+ {/* Search Bar */}
+
+
+ setQuery(e.target.value)}
+ placeholder="Takım adı yazın... (min 2 karakter)"
+ variant="flushed"
+ size="lg"
+ fontSize="md"
+ />
+
+
+ {/* Results */}
+ {isLoading ? (
+
+
+
+ ) : query.length < 2 ? (
+
+ ⚽
+
+ Aramak istediğiniz takımın adını yazın
+
+
+ Örnek: Galatasaray, Barcelona, Manchester City
+
+
+ ) : teams.length === 0 ? (
+
+ Sonuç bulunamadı
+
+ ) : (
+
+ {teams.map((team: TeamDto) => (
+ router.push(`/teams/${team.id}`)}
+ >
+
+
+ {team.logo ? (
+
+ ) : (
+
+
+ {team.name?.charAt(0) || "T"}
+
+
+ )}
+
+
+ {team.name}
+
+ {team.country && (
+
+ {team.country}
+
+ )}
+
+
+ →
+
+
+
+
+ ))}
+
+ )}
+
+
+ );
+}
diff --git a/src/components/ui/back-to-top.tsx b/src/components/ui/back-to-top.tsx
new file mode 100644
index 0000000..c708b89
--- /dev/null
+++ b/src/components/ui/back-to-top.tsx
@@ -0,0 +1,53 @@
+'use client';
+
+import { useEffect, useState } from 'react';
+import { Icon, IconButton, Presence } from '@chakra-ui/react';
+import { FiChevronUp } from 'react-icons/fi';
+
+const BackToTop = () => {
+ const [isVisible, setIsVisible] = useState(false);
+
+ useEffect(() => {
+ const handleScroll = () => {
+ setIsVisible(window.pageYOffset > 300);
+ };
+
+ window.addEventListener('scroll', handleScroll);
+ return () => window.removeEventListener('scroll', handleScroll);
+ }, []);
+
+ const scrollToTop = () => {
+ window.scrollTo({
+ top: 0,
+ behavior: 'smooth',
+ });
+ };
+
+ return (
+
+
+
+
+
+
+
+ );
+};
+
+export default BackToTop;
diff --git a/src/components/ui/buttons/button.tsx b/src/components/ui/buttons/button.tsx
new file mode 100644
index 0000000..19e9c8a
--- /dev/null
+++ b/src/components/ui/buttons/button.tsx
@@ -0,0 +1,33 @@
+import type { ButtonProps as ChakraButtonProps } from '@chakra-ui/react';
+import { AbsoluteCenter, Button as ChakraButton, Span, Spinner } from '@chakra-ui/react';
+import * as React from 'react';
+
+interface ButtonLoadingProps {
+ loading?: boolean;
+ loadingText?: React.ReactNode;
+}
+
+export interface ButtonProps extends ChakraButtonProps, ButtonLoadingProps {}
+
+export const Button = React.forwardRef(function Button(props, ref) {
+ const { loading, disabled, loadingText, children, ...rest } = props;
+ return (
+
+ {loading && !loadingText ? (
+ <>
+
+
+
+ {children}
+ >
+ ) : loading && loadingText ? (
+ <>
+
+ {loadingText}
+ >
+ ) : (
+ children
+ )}
+
+ );
+});
diff --git a/src/components/ui/buttons/close-button.tsx b/src/components/ui/buttons/close-button.tsx
new file mode 100644
index 0000000..e92e7b5
--- /dev/null
+++ b/src/components/ui/buttons/close-button.tsx
@@ -0,0 +1,14 @@
+import type { ButtonProps } from '@chakra-ui/react';
+import { IconButton as ChakraIconButton } from '@chakra-ui/react';
+import * as React from 'react';
+import { LuX } from 'react-icons/lu';
+
+export type CloseButtonProps = ButtonProps;
+
+export const CloseButton = React.forwardRef(function CloseButton(props, ref) {
+ return (
+
+ {props.children ?? }
+
+ );
+});
diff --git a/src/components/ui/buttons/link-button.tsx b/src/components/ui/buttons/link-button.tsx
new file mode 100644
index 0000000..921cf49
--- /dev/null
+++ b/src/components/ui/buttons/link-button.tsx
@@ -0,0 +1,11 @@
+'use client';
+
+import type { HTMLChakraProps, RecipeProps } from '@chakra-ui/react';
+import { createRecipeContext } from '@chakra-ui/react';
+
+export interface LinkButtonProps extends HTMLChakraProps<'a', RecipeProps<'button'>> {}
+
+const { withContext } = createRecipeContext({ key: 'button' });
+
+// Replace "a" with your framework's link component
+export const LinkButton = withContext('a');
diff --git a/src/components/ui/buttons/toggle.tsx b/src/components/ui/buttons/toggle.tsx
new file mode 100644
index 0000000..b70ee71
--- /dev/null
+++ b/src/components/ui/buttons/toggle.tsx
@@ -0,0 +1,44 @@
+'use client';
+
+import type { ButtonProps } from '@chakra-ui/react';
+import { Button, Toggle as ChakraToggle, useToggleContext } from '@chakra-ui/react';
+import * as React from 'react';
+
+interface ToggleProps extends ChakraToggle.RootProps {
+ variant?: keyof typeof variantMap;
+ size?: ButtonProps['size'];
+}
+
+const variantMap = {
+ solid: { on: 'solid', off: 'outline' },
+ surface: { on: 'surface', off: 'outline' },
+ subtle: { on: 'subtle', off: 'ghost' },
+ ghost: { on: 'subtle', off: 'ghost' },
+} as const;
+
+export const Toggle = React.forwardRef(function Toggle(props, ref) {
+ const { variant = 'subtle', size, children, ...rest } = props;
+ const variantConfig = variantMap[variant];
+
+ return (
+
+
+ {children}
+
+
+ );
+});
+
+interface ToggleBaseButtonProps extends Omit {
+ variant: Record<'on' | 'off', ButtonProps['variant']>;
+}
+
+const ToggleBaseButton = React.forwardRef(
+ function ToggleBaseButton(props, ref) {
+ const toggle = useToggleContext();
+ const { variant, ...rest } = props;
+ return ;
+ },
+);
+
+export const ToggleIndicator = ChakraToggle.Indicator;
diff --git a/src/components/ui/collections/combobox.tsx b/src/components/ui/collections/combobox.tsx
new file mode 100644
index 0000000..258e3af
--- /dev/null
+++ b/src/components/ui/collections/combobox.tsx
@@ -0,0 +1,91 @@
+'use client';
+
+import { Combobox as ChakraCombobox, Portal } from '@chakra-ui/react';
+import { CloseButton } from '@/components/ui/buttons/close-button';
+import * as React from 'react';
+
+interface ComboboxControlProps extends ChakraCombobox.ControlProps {
+ clearable?: boolean;
+}
+
+export const ComboboxControl = React.forwardRef(
+ function ComboboxControl(props, ref) {
+ const { children, clearable, ...rest } = props;
+ return (
+
+ {children}
+
+ {clearable && }
+
+
+
+ );
+ },
+);
+
+const ComboboxClearTrigger = React.forwardRef(
+ function ComboboxClearTrigger(props, ref) {
+ return (
+
+
+
+ );
+ },
+);
+
+interface ComboboxContentProps extends ChakraCombobox.ContentProps {
+ portalled?: boolean;
+ portalRef?: React.RefObject;
+}
+
+export const ComboboxContent = React.forwardRef(
+ function ComboboxContent(props, ref) {
+ const { portalled = true, portalRef, ...rest } = props;
+ return (
+
+
+
+
+
+ );
+ },
+);
+
+export const ComboboxItem = React.forwardRef(
+ function ComboboxItem(props, ref) {
+ const { item, children, ...rest } = props;
+ return (
+
+ {children}
+
+
+ );
+ },
+);
+
+export const ComboboxRoot = React.forwardRef(
+ function ComboboxRoot(props, ref) {
+ return ;
+ },
+) as ChakraCombobox.RootComponent;
+
+interface ComboboxItemGroupProps extends ChakraCombobox.ItemGroupProps {
+ label: React.ReactNode;
+}
+
+export const ComboboxItemGroup = React.forwardRef(
+ function ComboboxItemGroup(props, ref) {
+ const { children, label, ...rest } = props;
+ return (
+
+ {label}
+ {children}
+
+ );
+ },
+);
+
+export const ComboboxLabel = ChakraCombobox.Label;
+export const ComboboxInput = ChakraCombobox.Input;
+export const ComboboxEmpty = ChakraCombobox.Empty;
+export const ComboboxItemText = ChakraCombobox.ItemText;
diff --git a/src/components/ui/collections/listbox.tsx b/src/components/ui/collections/listbox.tsx
new file mode 100644
index 0000000..2cea1d1
--- /dev/null
+++ b/src/components/ui/collections/listbox.tsx
@@ -0,0 +1,28 @@
+'use client';
+
+import { Listbox as ChakraListbox } from '@chakra-ui/react';
+import * as React from 'react';
+
+export const ListboxRoot = React.forwardRef(function ListboxRoot(props, ref) {
+ return ;
+}) as ChakraListbox.RootComponent;
+
+export const ListboxContent = React.forwardRef(
+ function ListboxContent(props, ref) {
+ return ;
+ },
+);
+
+export const ListboxItem = React.forwardRef(function ListboxItem(props, ref) {
+ const { children, ...rest } = props;
+ return (
+
+ {children}
+
+
+ );
+});
+
+export const ListboxLabel = ChakraListbox.Label;
+export const ListboxItemText = ChakraListbox.ItemText;
+export const ListboxEmpty = ChakraListbox.Empty;
diff --git a/src/components/ui/collections/select.tsx b/src/components/ui/collections/select.tsx
new file mode 100644
index 0000000..cf9f33b
--- /dev/null
+++ b/src/components/ui/collections/select.tsx
@@ -0,0 +1,118 @@
+'use client';
+
+import type { CollectionItem } from '@chakra-ui/react';
+import { Select as ChakraSelect, Portal } from '@chakra-ui/react';
+import { CloseButton } from '../buttons/close-button';
+import * as React from 'react';
+
+interface SelectTriggerProps extends ChakraSelect.ControlProps {
+ clearable?: boolean;
+}
+
+export const SelectTrigger = React.forwardRef(
+ function SelectTrigger(props, ref) {
+ const { children, clearable, ...rest } = props;
+ return (
+
+ {children}
+
+ {clearable && }
+
+
+
+ );
+ },
+);
+
+const SelectClearTrigger = React.forwardRef(
+ function SelectClearTrigger(props, ref) {
+ return (
+
+
+
+ );
+ },
+);
+
+interface SelectContentProps extends ChakraSelect.ContentProps {
+ portalled?: boolean;
+ portalRef?: React.RefObject;
+}
+
+export const SelectContent = React.forwardRef(function SelectContent(props, ref) {
+ const { portalled = true, portalRef, ...rest } = props;
+ return (
+
+
+
+
+
+ );
+});
+
+export const SelectItem = React.forwardRef(function SelectItem(props, ref) {
+ const { item, children, ...rest } = props;
+ return (
+
+ {children}
+
+
+ );
+});
+
+interface SelectValueTextProps extends Omit {
+ children?(items: CollectionItem[]): React.ReactNode;
+}
+
+export const SelectValueText = React.forwardRef(
+ function SelectValueText(props, ref) {
+ const { children, ...rest } = props;
+ return (
+
+
+ {(select) => {
+ const items = select.selectedItems;
+ if (items.length === 0) return props.placeholder;
+ if (children) return children(items);
+ if (items.length === 1) return select.collection.stringifyItem(items[0]);
+ return `${items.length} selected`;
+ }}
+
+
+ );
+ },
+);
+
+export const SelectRoot = React.forwardRef(function SelectRoot(props, ref) {
+ return (
+
+ {props.asChild ? (
+ props.children
+ ) : (
+ <>
+
+ {props.children}
+ >
+ )}
+
+ );
+}) as ChakraSelect.RootComponent;
+
+interface SelectItemGroupProps extends ChakraSelect.ItemGroupProps {
+ label: React.ReactNode;
+}
+
+export const SelectItemGroup = React.forwardRef(
+ function SelectItemGroup(props, ref) {
+ const { children, label, ...rest } = props;
+ return (
+
+ {label}
+ {children}
+
+ );
+ },
+);
+
+export const SelectLabel = ChakraSelect.Label;
+export const SelectItemText = ChakraSelect.ItemText;
diff --git a/src/components/ui/collections/treeview.tsx b/src/components/ui/collections/treeview.tsx
new file mode 100644
index 0000000..e7ffd36
--- /dev/null
+++ b/src/components/ui/collections/treeview.tsx
@@ -0,0 +1,60 @@
+'use client';
+
+import { TreeView as ChakraTreeView } from '@chakra-ui/react';
+import * as React from 'react';
+
+export const TreeViewRoot = React.forwardRef(
+ function TreeViewRoot(props, ref) {
+ return ;
+ },
+);
+
+interface TreeViewTreeProps extends ChakraTreeView.TreeProps {}
+
+export const TreeViewTree = React.forwardRef(function TreeViewTree(props, ref) {
+ const { ...rest } = props;
+ return ;
+});
+
+export const TreeViewBranch = React.forwardRef(
+ function TreeViewBranch(props, ref) {
+ return ;
+ },
+);
+
+export const TreeViewBranchControl = React.forwardRef(
+ function TreeViewBranchControl(props, ref) {
+ return ;
+ },
+);
+
+export const TreeViewItem = React.forwardRef(
+ function TreeViewItem(props, ref) {
+ return ;
+ },
+);
+
+export const TreeViewLabel = ChakraTreeView.Label;
+export const TreeViewBranchIndicator = ChakraTreeView.BranchIndicator;
+export const TreeViewBranchText = ChakraTreeView.BranchText;
+export const TreeViewBranchContent = ChakraTreeView.BranchContent;
+export const TreeViewBranchIndentGuide = ChakraTreeView.BranchIndentGuide;
+export const TreeViewItemText = ChakraTreeView.ItemText;
+export const TreeViewNode = ChakraTreeView.Node;
+export const TreeViewNodeProvider = ChakraTreeView.NodeProvider;
+
+export const TreeView = {
+ Root: TreeViewRoot,
+ Label: TreeViewLabel,
+ Tree: TreeViewTree,
+ Branch: TreeViewBranch,
+ BranchControl: TreeViewBranchControl,
+ BranchIndicator: TreeViewBranchIndicator,
+ BranchText: TreeViewBranchText,
+ BranchContent: TreeViewBranchContent,
+ BranchIndentGuide: TreeViewBranchIndentGuide,
+ Item: TreeViewItem,
+ ItemText: TreeViewItemText,
+ Node: TreeViewNode,
+ NodeProvider: TreeViewNodeProvider,
+};
diff --git a/src/components/ui/color-mode.tsx b/src/components/ui/color-mode.tsx
new file mode 100644
index 0000000..acf8290
--- /dev/null
+++ b/src/components/ui/color-mode.tsx
@@ -0,0 +1,108 @@
+'use client';
+
+import type { IconButtonProps, SpanProps } from '@chakra-ui/react';
+import { ClientOnly, IconButton, Skeleton, Span } from '@chakra-ui/react';
+import { ThemeProvider, useTheme } from 'next-themes';
+import type { ThemeProviderProps } from 'next-themes';
+import * as React from 'react';
+import { LuMoon, LuSun } from 'react-icons/lu';
+
+export interface ColorModeProviderProps extends ThemeProviderProps {}
+
+export function ColorModeProvider(props: ColorModeProviderProps) {
+ return ;
+}
+
+export type ColorMode = 'light' | 'dark';
+
+export interface UseColorModeReturn {
+ colorMode: ColorMode;
+ setColorMode: (colorMode: ColorMode) => void;
+ toggleColorMode: () => void;
+}
+
+export function useColorMode(): UseColorModeReturn {
+ const { resolvedTheme, setTheme, forcedTheme } = useTheme();
+ const colorMode = forcedTheme || resolvedTheme;
+ const toggleColorMode = () => {
+ setTheme(resolvedTheme === 'dark' ? 'light' : 'dark');
+ };
+ return {
+ colorMode: colorMode as ColorMode,
+ setColorMode: setTheme,
+ toggleColorMode,
+ };
+}
+
+export function useColorModeValue(light: T, dark: T) {
+ const { colorMode } = useColorMode();
+ const [mounted, setMounted] = React.useState(false);
+
+ React.useEffect(() => setMounted(true), []);
+
+ if (!mounted) {
+ return light;
+ }
+ return colorMode === 'dark' ? dark : light;
+}
+
+export function ColorModeIcon() {
+ const { colorMode } = useColorMode();
+ return colorMode === 'dark' ? : ;
+}
+
+interface ColorModeButtonProps extends Omit {}
+
+export const ColorModeButton = React.forwardRef(
+ function ColorModeButton(props, ref) {
+ const { toggleColorMode } = useColorMode();
+ return (
+ }>
+
+
+
+
+ );
+ },
+);
+
+export const LightMode = React.forwardRef(function LightMode(props, ref) {
+ return (
+
+ );
+});
+
+export const DarkMode = React.forwardRef(function DarkMode(props, ref) {
+ return (
+
+ );
+});
diff --git a/src/components/ui/data-display/avatar.tsx b/src/components/ui/data-display/avatar.tsx
new file mode 100644
index 0000000..2a7023f
--- /dev/null
+++ b/src/components/ui/data-display/avatar.tsx
@@ -0,0 +1,26 @@
+import { Avatar as ChakraAvatar, AvatarGroup as ChakraAvatarGroup } from '@chakra-ui/react';
+import * as React from 'react';
+
+type ImageProps = React.ImgHTMLAttributes;
+
+export interface AvatarProps extends ChakraAvatar.RootProps {
+ name?: string;
+ src?: string;
+ srcSet?: string;
+ loading?: ImageProps['loading'];
+ icon?: React.ReactElement;
+ fallback?: React.ReactNode;
+}
+
+export const Avatar = React.forwardRef(function Avatar(props, ref) {
+ const { name, src, srcSet, loading, icon, fallback, children, ...rest } = props;
+ return (
+
+ {icon || fallback}
+
+ {children}
+
+ );
+});
+
+export const AvatarGroup = ChakraAvatarGroup;
diff --git a/src/components/ui/data-display/clipboard.tsx b/src/components/ui/data-display/clipboard.tsx
new file mode 100644
index 0000000..1612855
--- /dev/null
+++ b/src/components/ui/data-display/clipboard.tsx
@@ -0,0 +1,79 @@
+import type { ButtonProps, InputProps } from '@chakra-ui/react';
+import { Button, Clipboard as ChakraClipboard, IconButton, Input } from '@chakra-ui/react';
+import * as React from 'react';
+import { LuCheck, LuClipboard, LuLink } from 'react-icons/lu';
+
+const ClipboardIcon = React.forwardRef(
+ function ClipboardIcon(props, ref) {
+ return (
+ } {...props} ref={ref}>
+
+
+ );
+ },
+);
+
+const ClipboardCopyText = React.forwardRef(
+ function ClipboardCopyText(props, ref) {
+ return (
+
+ Copy
+
+ );
+ },
+);
+
+export const ClipboardLabel = React.forwardRef(
+ function ClipboardLabel(props, ref) {
+ return (
+
+ );
+ },
+);
+
+export const ClipboardButton = React.forwardRef(function ClipboardButton(props, ref) {
+ return (
+
+
+
+
+
+
+ );
+});
+
+export const ClipboardLink = React.forwardRef(function ClipboardLink(props, ref) {
+ return (
+
+
+
+
+
+
+ );
+});
+
+export const ClipboardIconButton = React.forwardRef(
+ function ClipboardIconButton(props, ref) {
+ return (
+
+
+
+
+
+
+ );
+ },
+);
+
+export const ClipboardInput = React.forwardRef(
+ function ClipboardInputElement(props, ref) {
+ return (
+
+
+
+ );
+ },
+);
+
+export const ClipboardRoot = ChakraClipboard.Root;
diff --git a/src/components/ui/data-display/data-list.tsx b/src/components/ui/data-display/data-list.tsx
new file mode 100644
index 0000000..f2ad27a
--- /dev/null
+++ b/src/components/ui/data-display/data-list.tsx
@@ -0,0 +1,26 @@
+import { DataList as ChakraDataList } from '@chakra-ui/react';
+import { InfoTip } from '@/components/ui/overlays/toggle-tip';
+import * as React from 'react';
+
+export const DataListRoot = ChakraDataList.Root;
+
+interface ItemProps extends ChakraDataList.ItemProps {
+ label: React.ReactNode;
+ value: React.ReactNode;
+ info?: React.ReactNode;
+ grow?: boolean;
+}
+
+export const DataListItem = React.forwardRef(function DataListItem(props, ref) {
+ const { label, info, value, children, grow, ...rest } = props;
+ return (
+
+
+ {label}
+ {info && {info} }
+
+ {value}
+ {children}
+
+ );
+});
diff --git a/src/components/ui/data-display/qr-code.tsx b/src/components/ui/data-display/qr-code.tsx
new file mode 100644
index 0000000..c9dc2ce
--- /dev/null
+++ b/src/components/ui/data-display/qr-code.tsx
@@ -0,0 +1,20 @@
+import { QrCode as ChakraQrCode } from '@chakra-ui/react';
+import * as React from 'react';
+
+export interface QrCodeProps extends Omit {
+ fill?: string;
+ overlay?: React.ReactNode;
+}
+
+export const QrCode = React.forwardRef(function QrCode(props, ref) {
+ const { children, fill, overlay, ...rest } = props;
+ return (
+
+
+
+
+ {children}
+ {overlay && {overlay} }
+
+ );
+});
diff --git a/src/components/ui/data-display/stat.tsx b/src/components/ui/data-display/stat.tsx
new file mode 100644
index 0000000..626a1dd
--- /dev/null
+++ b/src/components/ui/data-display/stat.tsx
@@ -0,0 +1,53 @@
+import { Badge, type BadgeProps, Stat as ChakraStat, FormatNumber } from '@chakra-ui/react';
+import { InfoTip } from '@/components/ui/overlays/toggle-tip';
+import * as React from 'react';
+
+interface StatLabelProps extends ChakraStat.LabelProps {
+ info?: React.ReactNode;
+}
+
+export const StatLabel = React.forwardRef(function StatLabel(props, ref) {
+ const { info, children, ...rest } = props;
+ return (
+
+ {children}
+ {info && {info} }
+
+ );
+});
+
+interface StatValueTextProps extends ChakraStat.ValueTextProps {
+ value?: number;
+ formatOptions?: Intl.NumberFormatOptions;
+}
+
+export const StatValueText = React.forwardRef(function StatValueText(props, ref) {
+ const { value, formatOptions, children, ...rest } = props;
+ return (
+
+ {children || (value != null && )}
+
+ );
+});
+
+export const StatUpTrend = React.forwardRef(function StatUpTrend(props, ref) {
+ return (
+
+
+ {props.children}
+
+ );
+});
+
+export const StatDownTrend = React.forwardRef(function StatDownTrend(props, ref) {
+ return (
+
+
+ {props.children}
+
+ );
+});
+
+export const StatRoot = ChakraStat.Root;
+export const StatHelpText = ChakraStat.HelpText;
+export const StatValueUnit = ChakraStat.ValueUnit;
diff --git a/src/components/ui/data-display/tag.tsx b/src/components/ui/data-display/tag.tsx
new file mode 100644
index 0000000..f5ce4c5
--- /dev/null
+++ b/src/components/ui/data-display/tag.tsx
@@ -0,0 +1,26 @@
+import { Tag as ChakraTag } from '@chakra-ui/react';
+import * as React from 'react';
+
+export interface TagProps extends ChakraTag.RootProps {
+ startElement?: React.ReactNode;
+ endElement?: React.ReactNode;
+ onClose?: VoidFunction;
+ closable?: boolean;
+}
+
+export const Tag = React.forwardRef(function Tag(props, ref) {
+ const { startElement, endElement, onClose, closable = !!onClose, children, ...rest } = props;
+
+ return (
+
+ {startElement && {startElement} }
+ {children}
+ {endElement && {endElement} }
+ {closable && (
+
+
+
+ )}
+
+ );
+});
diff --git a/src/components/ui/data-display/timeline.tsx b/src/components/ui/data-display/timeline.tsx
new file mode 100644
index 0000000..def87e9
--- /dev/null
+++ b/src/components/ui/data-display/timeline.tsx
@@ -0,0 +1,25 @@
+import { Timeline as ChakraTimeline } from '@chakra-ui/react';
+import * as React from 'react';
+
+interface TimelineConnectorProps extends ChakraTimeline.IndicatorProps {
+ icon?: React.ReactNode;
+}
+
+export const TimelineConnector = React.forwardRef(function TimelineConnector(
+ { icon, ...props },
+ ref,
+) {
+ return (
+
+
+ {icon}
+
+ );
+});
+
+export const TimelineRoot = ChakraTimeline.Root;
+export const TimelineContent = ChakraTimeline.Content;
+export const TimelineItem = ChakraTimeline.Item;
+export const TimelineIndicator = ChakraTimeline.Indicator;
+export const TimelineTitle = ChakraTimeline.Title;
+export const TimelineDescription = ChakraTimeline.Description;
diff --git a/src/components/ui/disclosure/accordion.tsx b/src/components/ui/disclosure/accordion.tsx
new file mode 100644
index 0000000..39f07ab
--- /dev/null
+++ b/src/components/ui/disclosure/accordion.tsx
@@ -0,0 +1,45 @@
+import { Accordion, HStack } from '@chakra-ui/react';
+import * as React from 'react';
+import { LuChevronDown } from 'react-icons/lu';
+
+interface AccordionItemTriggerProps extends Accordion.ItemTriggerProps {
+ indicatorPlacement?: 'start' | 'end';
+}
+
+export const AccordionItemTrigger = React.forwardRef(
+ function AccordionItemTrigger(props, ref) {
+ const { children, indicatorPlacement = 'end', ...rest } = props;
+ return (
+
+ {indicatorPlacement === 'start' && (
+
+
+
+ )}
+
+ {children}
+
+ {indicatorPlacement === 'end' && (
+
+
+
+ )}
+
+ );
+ },
+);
+
+interface AccordionItemContentProps extends Accordion.ItemContentProps {}
+
+export const AccordionItemContent = React.forwardRef(
+ function AccordionItemContent(props, ref) {
+ return (
+
+
+
+ );
+ },
+);
+
+export const AccordionRoot = Accordion.Root;
+export const AccordionItem = Accordion.Item;
diff --git a/src/components/ui/disclosure/breadcrumb.tsx b/src/components/ui/disclosure/breadcrumb.tsx
new file mode 100644
index 0000000..2889cae
--- /dev/null
+++ b/src/components/ui/disclosure/breadcrumb.tsx
@@ -0,0 +1,35 @@
+import { Breadcrumb, type SystemStyleObject } from '@chakra-ui/react';
+import * as React from 'react';
+
+export interface BreadcrumbRootProps extends Breadcrumb.RootProps {
+ separator?: React.ReactNode;
+ separatorGap?: SystemStyleObject['gap'];
+}
+
+export const BreadcrumbRoot = React.forwardRef(
+ function BreadcrumbRoot(props, ref) {
+ const { separator, separatorGap, children, ...rest } = props;
+
+ const validChildren = React.Children.toArray(children).filter(React.isValidElement);
+
+ return (
+
+
+ {validChildren.map((child, index) => {
+ const last = index === validChildren.length - 1;
+ return (
+
+ {child}
+ {!last && {separator} }
+
+ );
+ })}
+
+
+ );
+ },
+);
+
+export const BreadcrumbLink = Breadcrumb.Link;
+export const BreadcrumbCurrentLink = Breadcrumb.CurrentLink;
+export const BreadcrumbEllipsis = Breadcrumb.Ellipsis;
diff --git a/src/components/ui/disclosure/pagination.tsx b/src/components/ui/disclosure/pagination.tsx
new file mode 100644
index 0000000..cacd24c
--- /dev/null
+++ b/src/components/ui/disclosure/pagination.tsx
@@ -0,0 +1,182 @@
+'use client';
+
+import type { ButtonProps, TextProps } from '@chakra-ui/react';
+import {
+ Button,
+ Pagination as ChakraPagination,
+ IconButton,
+ Text,
+ createContext,
+ usePaginationContext,
+} from '@chakra-ui/react';
+import * as React from 'react';
+import { HiChevronLeft, HiChevronRight, HiMiniEllipsisHorizontal } from 'react-icons/hi2';
+import { LinkButton } from '@/components/ui/buttons/link-button';
+
+interface ButtonVariantMap {
+ current: ButtonProps['variant'];
+ default: ButtonProps['variant'];
+ ellipsis: ButtonProps['variant'];
+}
+
+type PaginationVariant = 'outline' | 'solid' | 'subtle';
+
+interface ButtonVariantContext {
+ size: ButtonProps['size'];
+ variantMap: ButtonVariantMap;
+ getHref?: (page: number) => string;
+}
+
+const [RootPropsProvider, useRootProps] = createContext({
+ name: 'RootPropsProvider',
+});
+
+export interface PaginationRootProps extends Omit {
+ size?: ButtonProps['size'];
+ variant?: PaginationVariant;
+ getHref?: (page: number) => string;
+}
+
+const variantMap: Record = {
+ outline: { default: 'ghost', ellipsis: 'plain', current: 'outline' },
+ solid: { default: 'outline', ellipsis: 'outline', current: 'solid' },
+ subtle: { default: 'ghost', ellipsis: 'plain', current: 'subtle' },
+};
+
+export const PaginationRoot = React.forwardRef(
+ function PaginationRoot(props, ref) {
+ const { size = 'sm', variant = 'outline', getHref, ...rest } = props;
+ return (
+
+
+
+ );
+ },
+);
+
+export const PaginationEllipsis = React.forwardRef(
+ function PaginationEllipsis(props, ref) {
+ const { size, variantMap } = useRootProps();
+ return (
+
+
+
+
+
+ );
+ },
+);
+
+export const PaginationItem = React.forwardRef(
+ function PaginationItem(props, ref) {
+ const { page } = usePaginationContext();
+ const { size, variantMap, getHref } = useRootProps();
+
+ const current = page === props.value;
+ const variant = current ? variantMap.current : variantMap.default;
+
+ if (getHref) {
+ return (
+
+ {props.value}
+
+ );
+ }
+
+ return (
+
+
+ {props.value}
+
+
+ );
+ },
+);
+
+export const PaginationPrevTrigger = React.forwardRef(
+ function PaginationPrevTrigger(props, ref) {
+ const { size, variantMap, getHref } = useRootProps();
+ const { previousPage } = usePaginationContext();
+
+ if (getHref) {
+ return (
+
+
+
+ );
+ }
+
+ return (
+
+
+
+
+
+ );
+ },
+);
+
+export const PaginationNextTrigger = React.forwardRef(
+ function PaginationNextTrigger(props, ref) {
+ const { size, variantMap, getHref } = useRootProps();
+ const { nextPage } = usePaginationContext();
+
+ if (getHref) {
+ return (
+
+
+
+ );
+ }
+
+ return (
+
+
+
+
+
+ );
+ },
+);
+
+export const PaginationItems = (props: React.HTMLAttributes) => {
+ return (
+
+ {({ pages }) =>
+ pages.map((page, index) => {
+ return page.type === 'ellipsis' ? (
+
+ ) : (
+
+ );
+ })
+ }
+
+ );
+};
+
+interface PageTextProps extends TextProps {
+ format?: 'short' | 'compact' | 'long';
+}
+
+export const PaginationPageText = React.forwardRef(
+ function PaginationPageText(props, ref) {
+ const { format = 'compact', ...rest } = props;
+ const { page, totalPages, pageRange, count } = usePaginationContext();
+ const content = React.useMemo(() => {
+ if (format === 'short') return `${page} / ${totalPages}`;
+ if (format === 'compact') return `${page} of ${totalPages}`;
+ return `${pageRange.start + 1} - ${Math.min(pageRange.end, count)} of ${count}`;
+ }, [format, page, totalPages, pageRange, count]);
+
+ return (
+
+ {content}
+
+ );
+ },
+);
diff --git a/src/components/ui/disclosure/steps.tsx b/src/components/ui/disclosure/steps.tsx
new file mode 100644
index 0000000..e761664
--- /dev/null
+++ b/src/components/ui/disclosure/steps.tsx
@@ -0,0 +1,73 @@
+import { Box, Steps as ChakraSteps } from '@chakra-ui/react';
+import * as React from 'react';
+import { LuCheck } from 'react-icons/lu';
+
+interface StepInfoProps {
+ title?: React.ReactNode;
+ description?: React.ReactNode;
+}
+
+export interface StepsItemProps extends Omit, StepInfoProps {
+ completedIcon?: React.ReactNode;
+ icon?: React.ReactNode;
+ disableTrigger?: boolean;
+}
+
+export const StepsItem = React.forwardRef(function StepsItem(props, ref) {
+ const { title, description, completedIcon, icon, disableTrigger, ...rest } = props;
+ return (
+
+
+
+ } incomplete={icon || } />
+
+
+
+
+
+ );
+});
+
+const StepInfo = (props: StepInfoProps) => {
+ const { title, description } = props;
+
+ if (title && description) {
+ return (
+
+ {title}
+ {description}
+
+ );
+ }
+
+ return (
+ <>
+ {title && {title} }
+ {description && {description} }
+ >
+ );
+};
+
+interface StepsIndicatorProps {
+ completedIcon: React.ReactNode;
+ icon?: React.ReactNode;
+}
+
+export const StepsIndicator = React.forwardRef(
+ function StepsIndicator(props, ref) {
+ const { icon = , completedIcon } = props;
+ return (
+
+
+
+ );
+ },
+);
+
+export const StepsList = ChakraSteps.List;
+export const StepsRoot = ChakraSteps.Root;
+export const StepsContent = ChakraSteps.Content;
+export const StepsCompletedContent = ChakraSteps.CompletedContent;
+
+export const StepsNextTrigger = ChakraSteps.NextTrigger;
+export const StepsPrevTrigger = ChakraSteps.PrevTrigger;
diff --git a/src/components/ui/feedback/alert.tsx b/src/components/ui/feedback/alert.tsx
new file mode 100644
index 0000000..aa25bd7
--- /dev/null
+++ b/src/components/ui/feedback/alert.tsx
@@ -0,0 +1,27 @@
+import { Alert as ChakraAlert } from '@chakra-ui/react';
+import * as React from 'react';
+
+export interface AlertProps extends Omit {
+ startElement?: React.ReactNode;
+ endElement?: React.ReactNode;
+ title?: React.ReactNode;
+ icon?: React.ReactElement;
+}
+
+export const Alert = React.forwardRef(function Alert(props, ref) {
+ const { title, children, icon, startElement, endElement, ...rest } = props;
+ return (
+
+ {startElement || {icon} }
+ {children ? (
+
+ {title}
+ {children}
+
+ ) : (
+ {title}
+ )}
+ {endElement}
+
+ );
+});
diff --git a/src/components/ui/feedback/empty-state.tsx b/src/components/ui/feedback/empty-state.tsx
new file mode 100644
index 0000000..da3b9b1
--- /dev/null
+++ b/src/components/ui/feedback/empty-state.tsx
@@ -0,0 +1,28 @@
+import { EmptyState as ChakraEmptyState, VStack } from '@chakra-ui/react';
+import * as React from 'react';
+
+export interface EmptyStateProps extends ChakraEmptyState.RootProps {
+ title: string;
+ description?: string;
+ icon?: React.ReactNode;
+}
+
+export const EmptyState = React.forwardRef(function EmptyState(props, ref) {
+ const { title, description, icon, children, ...rest } = props;
+ return (
+
+
+ {icon && {icon} }
+ {description ? (
+
+ {title}
+ {description}
+
+ ) : (
+ {title}
+ )}
+ {children}
+
+
+ );
+});
diff --git a/src/components/ui/feedback/progress-circle.tsx b/src/components/ui/feedback/progress-circle.tsx
new file mode 100644
index 0000000..6c837c4
--- /dev/null
+++ b/src/components/ui/feedback/progress-circle.tsx
@@ -0,0 +1,32 @@
+import type { SystemStyleObject } from '@chakra-ui/react';
+import { AbsoluteCenter, ProgressCircle as ChakraProgressCircle } from '@chakra-ui/react';
+import * as React from 'react';
+
+interface ProgressCircleRingProps extends ChakraProgressCircle.CircleProps {
+ trackColor?: SystemStyleObject['stroke'];
+ cap?: SystemStyleObject['strokeLinecap'];
+}
+
+export const ProgressCircleRing = React.forwardRef(
+ function ProgressCircleRing(props, ref) {
+ const { trackColor, cap, color, ...rest } = props;
+ return (
+
+
+
+
+ );
+ },
+);
+
+export const ProgressCircleValueText = React.forwardRef(
+ function ProgressCircleValueText(props, ref) {
+ return (
+
+
+
+ );
+ },
+);
+
+export const ProgressCircleRoot = ChakraProgressCircle.Root;
diff --git a/src/components/ui/feedback/progress.tsx b/src/components/ui/feedback/progress.tsx
new file mode 100644
index 0000000..2d3f875
--- /dev/null
+++ b/src/components/ui/feedback/progress.tsx
@@ -0,0 +1,30 @@
+import { Progress as ChakraProgress } from '@chakra-ui/react';
+import { InfoTip } from '../overlays/toggle-tip';
+import * as React from 'react';
+
+export const ProgressBar = React.forwardRef(
+ function ProgressBar(props, ref) {
+ return (
+
+
+
+ );
+ },
+);
+
+export interface ProgressLabelProps extends ChakraProgress.LabelProps {
+ info?: React.ReactNode;
+}
+
+export const ProgressLabel = React.forwardRef(function ProgressLabel(props, ref) {
+ const { children, info, ...rest } = props;
+ return (
+
+ {children}
+ {info && {info} }
+
+ );
+});
+
+export const ProgressRoot = ChakraProgress.Root;
+export const ProgressValueText = ChakraProgress.ValueText;
diff --git a/src/components/ui/feedback/skeleton.tsx b/src/components/ui/feedback/skeleton.tsx
new file mode 100644
index 0000000..e88e835
--- /dev/null
+++ b/src/components/ui/feedback/skeleton.tsx
@@ -0,0 +1,35 @@
+import type { SkeletonProps as ChakraSkeletonProps, CircleProps } from '@chakra-ui/react';
+import { Skeleton as ChakraSkeleton, Circle, Stack } from '@chakra-ui/react';
+import * as React from 'react';
+
+export interface SkeletonCircleProps extends ChakraSkeletonProps {
+ size?: CircleProps['size'];
+}
+
+export const SkeletonCircle = React.forwardRef(
+ function SkeletonCircle(props, ref) {
+ const { size, ...rest } = props;
+ return (
+
+
+
+ );
+ },
+);
+
+export interface SkeletonTextProps extends ChakraSkeletonProps {
+ noOfLines?: number;
+}
+
+export const SkeletonText = React.forwardRef(function SkeletonText(props, ref) {
+ const { noOfLines = 3, gap, ...rest } = props;
+ return (
+
+ {Array.from({ length: noOfLines }).map((_, index) => (
+
+ ))}
+
+ );
+});
+
+export const Skeleton = ChakraSkeleton;
diff --git a/src/components/ui/feedback/status.tsx b/src/components/ui/feedback/status.tsx
new file mode 100644
index 0000000..2031d0c
--- /dev/null
+++ b/src/components/ui/feedback/status.tsx
@@ -0,0 +1,27 @@
+import type { ColorPalette } from '@chakra-ui/react';
+import { Status as ChakraStatus } from '@chakra-ui/react';
+import * as React from 'react';
+
+type StatusValue = 'success' | 'error' | 'warning' | 'info';
+
+export interface StatusProps extends ChakraStatus.RootProps {
+ value?: StatusValue;
+}
+
+const statusMap: Record = {
+ success: 'green',
+ error: 'red',
+ warning: 'orange',
+ info: 'blue',
+};
+
+export const Status = React.forwardRef(function Status(props, ref) {
+ const { children, value = 'info', ...rest } = props;
+ const colorPalette = rest.colorPalette ?? statusMap[value];
+ return (
+
+
+ {children}
+
+ );
+});
diff --git a/src/components/ui/feedback/toaster.tsx b/src/components/ui/feedback/toaster.tsx
new file mode 100644
index 0000000..05465e5
--- /dev/null
+++ b/src/components/ui/feedback/toaster.tsx
@@ -0,0 +1,28 @@
+'use client';
+
+import { Toaster as ChakraToaster, Portal, Spinner, Stack, Toast, createToaster } from '@chakra-ui/react';
+
+export const toaster = createToaster({
+ placement: 'bottom-end',
+ pauseOnPageIdle: true,
+});
+
+export const Toaster = () => {
+ return (
+
+
+ {(toast) => (
+
+ {toast.type === 'loading' ? : }
+
+ {toast.title && {toast.title} }
+ {toast.description && {toast.description} }
+
+ {toast.action && {toast.action.label} }
+ {toast.closable && }
+
+ )}
+
+
+ );
+};
diff --git a/src/components/ui/forms/checkbox-card.tsx b/src/components/ui/forms/checkbox-card.tsx
new file mode 100644
index 0000000..815a86b
--- /dev/null
+++ b/src/components/ui/forms/checkbox-card.tsx
@@ -0,0 +1,49 @@
+import { CheckboxCard as ChakraCheckboxCard } from '@chakra-ui/react';
+import * as React from 'react';
+
+export interface CheckboxCardProps extends ChakraCheckboxCard.RootProps {
+ icon?: React.ReactElement;
+ label?: React.ReactNode;
+ description?: React.ReactNode;
+ addon?: React.ReactNode;
+ indicator?: React.ReactNode | null;
+ indicatorPlacement?: 'start' | 'end' | 'inside';
+ inputProps?: React.InputHTMLAttributes;
+}
+
+export const CheckboxCard = React.forwardRef(function CheckboxCard(props, ref) {
+ const {
+ inputProps,
+ label,
+ description,
+ icon,
+ addon,
+ indicator = ,
+ indicatorPlacement = 'end',
+ ...rest
+ } = props;
+
+ const hasContent = label || description || icon;
+ const ContentWrapper = indicator ? ChakraCheckboxCard.Content : React.Fragment;
+
+ return (
+
+
+
+ {indicatorPlacement === 'start' && indicator}
+ {hasContent && (
+
+ {icon}
+ {label && {label} }
+ {description && {description} }
+ {indicatorPlacement === 'inside' && indicator}
+
+ )}
+ {indicatorPlacement === 'end' && indicator}
+
+ {addon && {addon} }
+
+ );
+});
+
+export const CheckboxCardIndicator = ChakraCheckboxCard.Indicator;
diff --git a/src/components/ui/forms/checkbox.tsx b/src/components/ui/forms/checkbox.tsx
new file mode 100644
index 0000000..dcf3524
--- /dev/null
+++ b/src/components/ui/forms/checkbox.tsx
@@ -0,0 +1,19 @@
+import { Checkbox as ChakraCheckbox } from '@chakra-ui/react';
+import * as React from 'react';
+
+export interface CheckboxProps extends ChakraCheckbox.RootProps {
+ icon?: React.ReactNode;
+ inputProps?: React.InputHTMLAttributes;
+ rootRef?: React.RefObject;
+}
+
+export const Checkbox = React.forwardRef(function Checkbox(props, ref) {
+ const { icon, children, inputProps, rootRef, ...rest } = props;
+ return (
+
+
+ {icon || }
+ {children != null && {children} }
+
+ );
+});
diff --git a/src/components/ui/forms/color-picker.tsx b/src/components/ui/forms/color-picker.tsx
new file mode 100644
index 0000000..6024c54
--- /dev/null
+++ b/src/components/ui/forms/color-picker.tsx
@@ -0,0 +1,174 @@
+import type { IconButtonProps, StackProps } from '@chakra-ui/react';
+import { ColorPicker as ChakraColorPicker, For, IconButton, Portal, Span, Stack, Text, VStack } from '@chakra-ui/react';
+import * as React from 'react';
+import { LuCheck, LuPipette } from 'react-icons/lu';
+
+export const ColorPickerTrigger = React.forwardRef<
+ HTMLButtonElement,
+ ChakraColorPicker.TriggerProps & { fitContent?: boolean }
+>(function ColorPickerTrigger(props, ref) {
+ const { fitContent, ...rest } = props;
+ return (
+
+ {props.children || }
+
+ );
+});
+
+export const ColorPickerInput = React.forwardRef<
+ HTMLInputElement,
+ Omit
+>(function ColorHexInput(props, ref) {
+ return ;
+});
+
+interface ColorPickerContentProps extends ChakraColorPicker.ContentProps {
+ portalled?: boolean;
+ portalRef?: React.RefObject;
+}
+
+export const ColorPickerContent = React.forwardRef(
+ function ColorPickerContent(props, ref) {
+ const { portalled = true, portalRef, ...rest } = props;
+ return (
+
+
+
+
+
+ );
+ },
+);
+
+export const ColorPickerInlineContent = React.forwardRef(
+ function ColorPickerInlineContent(props, ref) {
+ return ;
+ },
+);
+
+export const ColorPickerSliders = React.forwardRef(function ColorPickerSliders(props, ref) {
+ return (
+
+
+
+
+ );
+});
+
+export const ColorPickerArea = React.forwardRef(
+ function ColorPickerArea(props, ref) {
+ return (
+
+
+
+
+ );
+ },
+);
+
+export const ColorPickerEyeDropper = React.forwardRef(
+ function ColorPickerEyeDropper(props, ref) {
+ return (
+
+
+
+
+
+ );
+ },
+);
+
+export const ColorPickerChannelSlider = React.forwardRef(
+ function ColorPickerSlider(props, ref) {
+ return (
+
+
+
+
+
+ );
+ },
+);
+
+export const ColorPickerSwatchTrigger = React.forwardRef<
+ HTMLButtonElement,
+ ChakraColorPicker.SwatchTriggerProps & {
+ swatchSize?: ChakraColorPicker.SwatchTriggerProps['boxSize'];
+ }
+>(function ColorPickerSwatchTrigger(props, ref) {
+ const { swatchSize, children, ...rest } = props;
+ return (
+
+ {children || (
+
+
+
+
+
+ )}
+
+ );
+});
+
+export const ColorPickerRoot = React.forwardRef(
+ function ColorPickerRoot(props, ref) {
+ return (
+
+ {props.children}
+
+
+ );
+ },
+);
+
+const formatMap = {
+ rgba: ['red', 'green', 'blue', 'alpha'],
+ hsla: ['hue', 'saturation', 'lightness', 'alpha'],
+ hsba: ['hue', 'saturation', 'brightness', 'alpha'],
+ hexa: ['hex', 'alpha'],
+} as const;
+
+export const ColorPickerChannelInputs = React.forwardRef(
+ function ColorPickerChannelInputs(props, ref) {
+ const channels = formatMap[props.format];
+ return (
+
+ {channels.map((channel) => (
+
+
+
+ {channel.charAt(0).toUpperCase()}
+
+
+ ))}
+
+ );
+ },
+);
+
+export const ColorPickerChannelSliders = React.forwardRef(
+ function ColorPickerChannelSliders(props, ref) {
+ const channels = formatMap[props.format];
+ return (
+
+
+ {(channel) => (
+
+
+ {channel}
+
+
+
+ )}
+
+
+ );
+ },
+);
+
+export const ColorPickerLabel = ChakraColorPicker.Label;
+export const ColorPickerControl = ChakraColorPicker.Control;
+export const ColorPickerValueText = ChakraColorPicker.ValueText;
+export const ColorPickerValueSwatch = ChakraColorPicker.ValueSwatch;
+export const ColorPickerChannelInput = ChakraColorPicker.ChannelInput;
+export const ColorPickerSwatchGroup = ChakraColorPicker.SwatchGroup;
diff --git a/src/components/ui/forms/field.tsx b/src/components/ui/forms/field.tsx
new file mode 100644
index 0000000..6bf73db
--- /dev/null
+++ b/src/components/ui/forms/field.tsx
@@ -0,0 +1,26 @@
+import { Field as ChakraField } from '@chakra-ui/react';
+import * as React from 'react';
+
+export interface FieldProps extends Omit {
+ label?: React.ReactNode;
+ helperText?: React.ReactNode;
+ errorText?: React.ReactNode;
+ optionalText?: React.ReactNode;
+}
+
+export const Field = React.forwardRef(function Field(props, ref) {
+ const { label, children, helperText, errorText, optionalText, ...rest } = props;
+ return (
+
+ {label && (
+
+ {label}
+
+
+ )}
+ {children}
+ {helperText && {helperText} }
+ {errorText && {errorText} }
+
+ );
+});
diff --git a/src/components/ui/forms/file-upload.tsx b/src/components/ui/forms/file-upload.tsx
new file mode 100644
index 0000000..2d1cf52
--- /dev/null
+++ b/src/components/ui/forms/file-upload.tsx
@@ -0,0 +1,150 @@
+'use client';
+
+import type { ButtonProps, RecipeProps } from '@chakra-ui/react';
+import {
+ Button,
+ FileUpload as ChakraFileUpload,
+ Icon,
+ IconButton,
+ Span,
+ Text,
+ useFileUploadContext,
+ useRecipe,
+} from '@chakra-ui/react';
+import * as React from 'react';
+import { LuFile, LuUpload, LuX } from 'react-icons/lu';
+
+export interface FileUploadRootProps extends ChakraFileUpload.RootProps {
+ inputProps?: React.InputHTMLAttributes;
+}
+
+export const FileUploadRoot = React.forwardRef(
+ function FileUploadRoot(props, ref) {
+ const { children, inputProps, ...rest } = props;
+ return (
+
+
+ {children}
+
+ );
+ },
+);
+
+export interface FileUploadDropzoneProps extends ChakraFileUpload.DropzoneProps {
+ label: React.ReactNode;
+ description?: React.ReactNode;
+}
+
+export const FileUploadDropzone = React.forwardRef(
+ function FileUploadDropzone(props, ref) {
+ const { children, label, description, ...rest } = props;
+ return (
+
+
+
+
+
+ {label}
+ {description && {description} }
+
+ {children}
+
+ );
+ },
+);
+
+interface VisibilityProps {
+ showSize?: boolean;
+ clearable?: boolean;
+}
+
+interface FileUploadItemProps extends VisibilityProps {
+ file: File;
+}
+
+const FileUploadItem = React.forwardRef(function FileUploadItem(props, ref) {
+ const { file, showSize, clearable } = props;
+ return (
+
+
+
+
+
+
+
+ {showSize ? (
+
+
+
+
+ ) : (
+
+ )}
+
+ {clearable && (
+
+
+
+
+
+ )}
+
+ );
+});
+
+interface FileUploadListProps extends VisibilityProps, ChakraFileUpload.ItemGroupProps {
+ files?: File[];
+}
+
+export const FileUploadList = React.forwardRef(
+ function FileUploadList(props, ref) {
+ const { showSize, clearable, files, ...rest } = props;
+
+ const fileUpload = useFileUploadContext();
+ const acceptedFiles = files ?? fileUpload.acceptedFiles;
+
+ if (acceptedFiles.length === 0) return null;
+
+ return (
+
+ {acceptedFiles.map((file) => (
+
+ ))}
+
+ );
+ },
+);
+
+type Assign = Omit & U;
+
+interface FileInputProps extends Assign> {
+ placeholder?: React.ReactNode;
+}
+
+export const FileInput = React.forwardRef(function FileInput(props, ref) {
+ const inputRecipe = useRecipe({ key: 'input' });
+ const [recipeProps, restProps] = inputRecipe.splitVariantProps(props);
+ const { placeholder = 'Select file(s)', ...rest } = restProps;
+ return (
+
+
+
+ {({ acceptedFiles }) => {
+ if (acceptedFiles.length === 1) {
+ return {acceptedFiles[0].name} ;
+ }
+ if (acceptedFiles.length > 1) {
+ return {acceptedFiles.length} files ;
+ }
+ return {placeholder} ;
+ }}
+
+
+
+ );
+});
+
+export const FileUploadLabel = ChakraFileUpload.Label;
+export const FileUploadClearTrigger = ChakraFileUpload.ClearTrigger;
+export const FileUploadTrigger = ChakraFileUpload.Trigger;
+export const FileUploadFileText = ChakraFileUpload.FileText;
diff --git a/src/components/ui/forms/input-group.tsx b/src/components/ui/forms/input-group.tsx
new file mode 100644
index 0000000..bd885de
--- /dev/null
+++ b/src/components/ui/forms/input-group.tsx
@@ -0,0 +1,50 @@
+import type { BoxProps, InputElementProps } from '@chakra-ui/react';
+import { Group, InputElement } from '@chakra-ui/react';
+import * as React from 'react';
+
+export interface InputGroupProps extends BoxProps {
+ startElementProps?: InputElementProps;
+ endElementProps?: InputElementProps;
+ startElement?: React.ReactNode;
+ endElement?: React.ReactNode;
+ children: React.ReactElement;
+ startOffset?: InputElementProps['paddingStart'];
+ endOffset?: InputElementProps['paddingEnd'];
+}
+
+export const InputGroup = React.forwardRef(function InputGroup(props, ref) {
+ const {
+ startElement,
+ startElementProps,
+ endElement,
+ endElementProps,
+ children,
+ startOffset = '6px',
+ endOffset = '6px',
+ ...rest
+ } = props;
+
+ const child = React.Children.only>(children);
+
+ return (
+
+ {startElement && (
+
+ {startElement}
+
+ )}
+ {React.cloneElement(child, {
+ ...(startElement && {
+ ps: `calc(var(--input-height) - ${startOffset})`,
+ }),
+ ...(endElement && { pe: `calc(var(--input-height) - ${endOffset})` }),
+ ...children.props,
+ })}
+ {endElement && (
+
+ {endElement}
+
+ )}
+
+ );
+});
diff --git a/src/components/ui/forms/native-select.tsx b/src/components/ui/forms/native-select.tsx
new file mode 100644
index 0000000..4b2d7bd
--- /dev/null
+++ b/src/components/ui/forms/native-select.tsx
@@ -0,0 +1,52 @@
+'use client';
+
+import { NativeSelect as Select } from '@chakra-ui/react';
+import * as React from 'react';
+
+interface NativeSelectRootProps extends Select.RootProps {
+ icon?: React.ReactNode;
+}
+
+export const NativeSelectRoot = React.forwardRef(
+ function NativeSelect(props, ref) {
+ const { icon, children, ...rest } = props;
+ return (
+
+ {children}
+ {icon}
+
+ );
+ },
+);
+
+interface NativeSelectItem {
+ value: string;
+ label: string;
+ disabled?: boolean;
+}
+
+interface NativeSelectFieldProps extends Select.FieldProps {
+ items?: Array;
+}
+
+export const NativeSelectField = React.forwardRef(
+ function NativeSelectField(props, ref) {
+ const { items: itemsProp, children, ...rest } = props;
+
+ const items = React.useMemo(
+ () => itemsProp?.map((item) => (typeof item === 'string' ? { label: item, value: item } : item)),
+ [itemsProp],
+ );
+
+ return (
+
+ {children}
+ {items?.map((item) => (
+
+ {item.label}
+
+ ))}
+
+ );
+ },
+);
diff --git a/src/components/ui/forms/number-input.tsx b/src/components/ui/forms/number-input.tsx
new file mode 100644
index 0000000..07ce370
--- /dev/null
+++ b/src/components/ui/forms/number-input.tsx
@@ -0,0 +1,21 @@
+import { NumberInput as ChakraNumberInput } from '@chakra-ui/react';
+import * as React from 'react';
+
+export interface NumberInputProps extends ChakraNumberInput.RootProps {}
+
+export const NumberInputRoot = React.forwardRef(function NumberInput(props, ref) {
+ const { children, ...rest } = props;
+ return (
+
+ {children}
+
+
+
+
+
+ );
+});
+
+export const NumberInputField = ChakraNumberInput.Input;
+export const NumberInputScrubber = ChakraNumberInput.Scrubber;
+export const NumberInputLabel = ChakraNumberInput.Label;
diff --git a/src/components/ui/forms/password-input.tsx b/src/components/ui/forms/password-input.tsx
new file mode 100644
index 0000000..7425aef
--- /dev/null
+++ b/src/components/ui/forms/password-input.tsx
@@ -0,0 +1,136 @@
+'use client';
+
+import type { ButtonProps, GroupProps, InputProps, StackProps } from '@chakra-ui/react';
+import { Box, HStack, IconButton, Input, InputGroup, Stack, mergeRefs, useControllableState } from '@chakra-ui/react';
+import { useTranslations } from 'next-intl';
+import * as React from 'react';
+import { LuEye, LuEyeOff } from 'react-icons/lu';
+
+export interface PasswordVisibilityProps {
+ /**
+ * The default visibility state of the password input.
+ */
+ defaultVisible?: boolean;
+ /**
+ * The controlled visibility state of the password input.
+ */
+ visible?: boolean;
+ /**
+ * Callback invoked when the visibility state changes.
+ */
+ onVisibleChange?: (visible: boolean) => void;
+ /**
+ * Custom icons for the visibility toggle button.
+ */
+ visibilityIcon?: { on: React.ReactNode; off: React.ReactNode };
+}
+
+export interface PasswordInputProps extends InputProps, PasswordVisibilityProps {
+ rootProps?: GroupProps;
+}
+
+export const PasswordInput = React.forwardRef(function PasswordInput(props, ref) {
+ const {
+ rootProps,
+ defaultVisible,
+ visible: visibleProp,
+ onVisibleChange,
+ visibilityIcon = { on: , off: },
+ ...rest
+ } = props;
+
+ const [visible, setVisible] = useControllableState({
+ value: visibleProp,
+ defaultValue: defaultVisible || false,
+ onChange: onVisibleChange,
+ });
+
+ const inputRef = React.useRef(null);
+
+ return (
+ {
+ if (rest.disabled) return;
+ if (e.button !== 0) return;
+ e.preventDefault();
+ setVisible(!visible);
+ }}
+ >
+ {visible ? visibilityIcon.off : visibilityIcon.on}
+
+ }
+ {...rootProps}
+ >
+
+
+ );
+});
+
+const VisibilityTrigger = React.forwardRef(function VisibilityTrigger(props, ref) {
+ return (
+
+ );
+});
+
+interface PasswordStrengthMeterProps extends StackProps {
+ max?: number;
+ value: number;
+}
+
+export const PasswordStrengthMeter = React.forwardRef(
+ function PasswordStrengthMeter(props, ref) {
+ const { max = 4, value, ...rest } = props;
+ const t = useTranslations();
+
+ function getColorPalette(percent: number) {
+ switch (true) {
+ case percent < 33:
+ return { label: t('low'), colorPalette: 'red' };
+ case percent < 66:
+ return { label: t('medium'), colorPalette: 'orange' };
+ default:
+ return { label: t('high'), colorPalette: 'green' };
+ }
+ }
+
+ const percent = (value / max) * 100;
+ const { label, colorPalette } = getColorPalette(percent);
+
+ return (
+
+
+ {Array.from({ length: max }).map((_, index) => (
+
+ ))}
+
+ {label && {label} }
+
+ );
+ },
+);
diff --git a/src/components/ui/forms/pin-input.tsx b/src/components/ui/forms/pin-input.tsx
new file mode 100644
index 0000000..564fefb
--- /dev/null
+++ b/src/components/ui/forms/pin-input.tsx
@@ -0,0 +1,25 @@
+import { PinInput as ChakraPinInput, Group } from '@chakra-ui/react';
+import * as React from 'react';
+
+export interface PinInputProps extends ChakraPinInput.RootProps {
+ rootRef?: React.RefObject;
+ count?: number;
+ inputProps?: React.InputHTMLAttributes;
+ attached?: boolean;
+}
+
+export const PinInput = React.forwardRef(function PinInput(props, ref) {
+ const { count = 4, inputProps, rootRef, attached, ...rest } = props;
+ return (
+
+
+
+
+ {Array.from({ length: count }).map((_, index) => (
+
+ ))}
+
+
+
+ );
+});
diff --git a/src/components/ui/forms/radio-card.tsx b/src/components/ui/forms/radio-card.tsx
new file mode 100644
index 0000000..5394f8f
--- /dev/null
+++ b/src/components/ui/forms/radio-card.tsx
@@ -0,0 +1,51 @@
+import { RadioCard } from '@chakra-ui/react';
+import * as React from 'react';
+
+interface RadioCardItemProps extends RadioCard.ItemProps {
+ icon?: React.ReactElement;
+ label?: React.ReactNode;
+ description?: React.ReactNode;
+ addon?: React.ReactNode;
+ indicator?: React.ReactNode | null;
+ indicatorPlacement?: 'start' | 'end' | 'inside';
+ inputProps?: React.InputHTMLAttributes;
+}
+
+export const RadioCardItem = React.forwardRef(function RadioCardItem(props, ref) {
+ const {
+ inputProps,
+ label,
+ description,
+ addon,
+ icon,
+ indicator = ,
+ indicatorPlacement = 'end',
+ ...rest
+ } = props;
+
+ const hasContent = label || description || icon;
+ const ContentWrapper = indicator ? RadioCard.ItemContent : React.Fragment;
+
+ return (
+
+
+
+ {indicatorPlacement === 'start' && indicator}
+ {hasContent && (
+
+ {icon}
+ {label && {label} }
+ {description && {description} }
+ {indicatorPlacement === 'inside' && indicator}
+
+ )}
+ {indicatorPlacement === 'end' && indicator}
+
+ {addon && {addon} }
+
+ );
+});
+
+export const RadioCardRoot = RadioCard.Root;
+export const RadioCardLabel = RadioCard.Label;
+export const RadioCardItemIndicator = RadioCard.ItemIndicator;
diff --git a/src/components/ui/forms/radio.tsx b/src/components/ui/forms/radio.tsx
new file mode 100644
index 0000000..427ddfb
--- /dev/null
+++ b/src/components/ui/forms/radio.tsx
@@ -0,0 +1,20 @@
+import { RadioGroup as ChakraRadioGroup } from '@chakra-ui/react';
+import * as React from 'react';
+
+export interface RadioProps extends ChakraRadioGroup.ItemProps {
+ rootRef?: React.RefObject;
+ inputProps?: React.InputHTMLAttributes;
+}
+
+export const Radio = React.forwardRef(function Radio(props, ref) {
+ const { children, inputProps, rootRef, ...rest } = props;
+ return (
+
+
+
+ {children && {children} }
+
+ );
+});
+
+export const RadioGroup = ChakraRadioGroup.Root;
diff --git a/src/components/ui/forms/rating.tsx b/src/components/ui/forms/rating.tsx
new file mode 100644
index 0000000..4b3ec10
--- /dev/null
+++ b/src/components/ui/forms/rating.tsx
@@ -0,0 +1,25 @@
+import { RatingGroup } from '@chakra-ui/react';
+import * as React from 'react';
+
+export interface RatingProps extends RatingGroup.RootProps {
+ icon?: React.ReactElement;
+ count?: number;
+ label?: React.ReactNode;
+}
+
+export const Rating = React.forwardRef(function Rating(props, ref) {
+ const { icon, count = 5, label, ...rest } = props;
+ return (
+
+ {label && {label} }
+
+
+ {Array.from({ length: count }).map((_, index) => (
+
+
+
+ ))}
+
+
+ );
+});
diff --git a/src/components/ui/forms/segmented-control.tsx b/src/components/ui/forms/segmented-control.tsx
new file mode 100644
index 0000000..f1cd298
--- /dev/null
+++ b/src/components/ui/forms/segmented-control.tsx
@@ -0,0 +1,42 @@
+'use client';
+
+import { For, SegmentGroup } from '@chakra-ui/react';
+import * as React from 'react';
+
+interface Item {
+ value: string;
+ label: React.ReactNode;
+ disabled?: boolean;
+}
+
+export interface SegmentedControlProps extends SegmentGroup.RootProps {
+ items: Array;
+}
+
+function normalize(items: Array): Item[] {
+ return items.map((item) => {
+ if (typeof item === 'string') return { value: item, label: item };
+ return item;
+ });
+}
+
+export const SegmentedControl = React.forwardRef(
+ function SegmentedControl(props, ref) {
+ const { items, ...rest } = props;
+ const data = React.useMemo(() => normalize(items), [items]);
+
+ return (
+
+
+
+ {(item) => (
+
+ {item.label}
+
+
+ )}
+
+
+ );
+ },
+);
diff --git a/src/components/ui/forms/slider.tsx b/src/components/ui/forms/slider.tsx
new file mode 100644
index 0000000..9b9a385
--- /dev/null
+++ b/src/components/ui/forms/slider.tsx
@@ -0,0 +1,78 @@
+import { Slider as ChakraSlider, For, HStack } from '@chakra-ui/react';
+import * as React from 'react';
+
+export interface SliderProps extends ChakraSlider.RootProps {
+ marks?: Array;
+ label?: React.ReactNode;
+ showValue?: boolean;
+ thumb?: React.ReactNode;
+}
+
+export const Slider = React.forwardRef(function Slider(props, ref) {
+ const { marks: marksProp, label, showValue, thumb, ...rest } = props;
+ const value = props.defaultValue ?? props.value;
+
+ const marks = marksProp?.map((mark) => {
+ if (typeof mark === 'number') return { value: mark, label: undefined };
+ return mark;
+ });
+
+ const hasMarkLabel = !!marks?.some((mark) => mark.label);
+
+ return (
+
+ {label && !showValue && {label} }
+ {label && showValue && (
+
+ {label}
+
+
+ )}
+
+
+
+
+
+
+
+
+ );
+});
+
+function SliderThumbs(props: { value?: number[]; thumb?: React.ReactNode }) {
+ const { value, thumb } = props;
+ return (
+
+ {(_, index) => (
+
+
+ {thumb}
+
+ )}
+
+ );
+}
+
+interface SliderMarksProps {
+ marks?: Array;
+}
+
+const SliderMarks = React.forwardRef(function SliderMarks(props, ref) {
+ const { marks } = props;
+ if (!marks?.length) return null;
+
+ return (
+
+ {marks.map((mark, index) => {
+ const value = typeof mark === 'number' ? mark : mark.value;
+ const label = typeof mark === 'number' ? undefined : mark.label;
+ return (
+
+
+ {label}
+
+ );
+ })}
+
+ );
+});
diff --git a/src/components/ui/forms/stepper-input.tsx b/src/components/ui/forms/stepper-input.tsx
new file mode 100644
index 0000000..a5677da
--- /dev/null
+++ b/src/components/ui/forms/stepper-input.tsx
@@ -0,0 +1,45 @@
+import { HStack, IconButton, NumberInput } from '@chakra-ui/react';
+import * as React from 'react';
+import { LuMinus, LuPlus } from 'react-icons/lu';
+
+export interface StepperInputProps extends NumberInput.RootProps {
+ label?: React.ReactNode;
+}
+
+export const StepperInput = React.forwardRef(function StepperInput(props, ref) {
+ const { label, ...rest } = props;
+ return (
+
+ {label && {label} }
+
+
+
+
+
+
+ );
+});
+
+const DecrementTrigger = React.forwardRef(
+ function DecrementTrigger(props, ref) {
+ return (
+
+
+
+
+
+ );
+ },
+);
+
+const IncrementTrigger = React.forwardRef(
+ function IncrementTrigger(props, ref) {
+ return (
+
+
+
+
+
+ );
+ },
+);
diff --git a/src/components/ui/forms/switch.tsx b/src/components/ui/forms/switch.tsx
new file mode 100644
index 0000000..bce7a5c
--- /dev/null
+++ b/src/components/ui/forms/switch.tsx
@@ -0,0 +1,28 @@
+import { Switch as ChakraSwitch } from '@chakra-ui/react';
+import * as React from 'react';
+
+export interface SwitchProps extends ChakraSwitch.RootProps {
+ inputProps?: React.InputHTMLAttributes;
+ rootRef?: React.RefObject;
+ trackLabel?: { on: React.ReactNode; off: React.ReactNode };
+ thumbLabel?: { on: React.ReactNode; off: React.ReactNode };
+}
+
+export const Switch = React.forwardRef(function Switch(props, ref) {
+ const { inputProps, children, rootRef, trackLabel, thumbLabel, ...rest } = props;
+
+ return (
+
+
+
+
+ {thumbLabel && (
+ {thumbLabel?.on}
+ )}
+
+ {trackLabel && {trackLabel.on} }
+
+ {children != null && {children} }
+
+ );
+});
diff --git a/src/components/ui/locale-switcher.tsx b/src/components/ui/locale-switcher.tsx
new file mode 100644
index 0000000..a647ca7
--- /dev/null
+++ b/src/components/ui/locale-switcher.tsx
@@ -0,0 +1,67 @@
+'use client';
+
+import React, { useTransition } from 'react';
+import { Locale, useLocale } from 'next-intl';
+import {
+ SelectContent,
+ SelectItem,
+ SelectRoot,
+ SelectTrigger,
+ SelectValueText,
+} from '@/components/ui/collections/select';
+import { useParams } from 'next/navigation';
+import { createListCollection } from '@chakra-ui/react';
+import { usePathname, useRouter } from '@/i18n/navigation';
+
+const LocaleSwitcher = () => {
+ const locale = useLocale();
+ const [isPending, startTransition] = useTransition();
+ const router = useRouter();
+ const pathname = usePathname();
+ const params = useParams();
+
+ const collections = createListCollection({
+ items: [
+ { label: 'English', value: 'en' },
+ { label: 'Türkçe', value: 'tr' },
+ ],
+ });
+
+ function onSelectChange({ value }: { value: string[] }) {
+ const nextLocale = value.at(0) as Locale;
+ startTransition(() => {
+ router.replace(
+ // @ts-expect-error -- TypeScript will validate that only known `params`
+ // are used in combination with a given `pathname`. Since the two will
+ // always match for the current route, we can skip runtime checks.
+ { pathname, params },
+ { locale: nextLocale },
+ );
+ });
+ }
+ return (
+
+
+
+
+
+ {collections.items.map((collection) => (
+
+ {collection.label}
+
+ ))}
+
+
+ );
+};
+
+export default LocaleSwitcher;
diff --git a/src/components/ui/overlays/action-bar.tsx b/src/components/ui/overlays/action-bar.tsx
new file mode 100644
index 0000000..10b60a9
--- /dev/null
+++ b/src/components/ui/overlays/action-bar.tsx
@@ -0,0 +1,38 @@
+import { ActionBar, Portal } from '@chakra-ui/react';
+import { CloseButton } from '@/components/ui/buttons/close-button';
+import * as React from 'react';
+
+interface ActionBarContentProps extends ActionBar.ContentProps {
+ portalled?: boolean;
+ portalRef?: React.RefObject;
+}
+
+export const ActionBarContent = React.forwardRef(
+ function ActionBarContent(props, ref) {
+ const { children, portalled = true, portalRef, ...rest } = props;
+
+ return (
+
+
+
+ {children}
+
+
+
+ );
+ },
+);
+
+export const ActionBarCloseTrigger = React.forwardRef(
+ function ActionBarCloseTrigger(props, ref) {
+ return (
+
+
+
+ );
+ },
+);
+
+export const ActionBarRoot = ActionBar.Root;
+export const ActionBarSelectionTrigger = ActionBar.SelectionTrigger;
+export const ActionBarSeparator = ActionBar.Separator;
diff --git a/src/components/ui/overlays/dialog.tsx b/src/components/ui/overlays/dialog.tsx
new file mode 100644
index 0000000..8454e60
--- /dev/null
+++ b/src/components/ui/overlays/dialog.tsx
@@ -0,0 +1,46 @@
+import { Dialog as ChakraDialog, Portal } from '@chakra-ui/react';
+import { CloseButton } from '@/components/ui/buttons/close-button';
+import * as React from 'react';
+
+interface DialogContentProps extends ChakraDialog.ContentProps {
+ portalled?: boolean;
+ portalRef?: React.RefObject;
+ backdrop?: boolean;
+}
+
+export const DialogContent = React.forwardRef(function DialogContent(props, ref) {
+ const { children, portalled = true, portalRef, backdrop = true, ...rest } = props;
+
+ return (
+
+ {backdrop && }
+
+
+ {children}
+
+
+
+ );
+});
+
+export const DialogCloseTrigger = React.forwardRef(
+ function DialogCloseTrigger(props, ref) {
+ return (
+
+
+ {props.children}
+
+
+ );
+ },
+);
+
+export const DialogRoot = ChakraDialog.Root;
+export const DialogFooter = ChakraDialog.Footer;
+export const DialogHeader = ChakraDialog.Header;
+export const DialogBody = ChakraDialog.Body;
+export const DialogBackdrop = ChakraDialog.Backdrop;
+export const DialogTitle = ChakraDialog.Title;
+export const DialogDescription = ChakraDialog.Description;
+export const DialogTrigger = ChakraDialog.Trigger;
+export const DialogActionTrigger = ChakraDialog.ActionTrigger;
diff --git a/src/components/ui/overlays/drawer.tsx b/src/components/ui/overlays/drawer.tsx
new file mode 100644
index 0000000..6c1de16
--- /dev/null
+++ b/src/components/ui/overlays/drawer.tsx
@@ -0,0 +1,42 @@
+import { Drawer as ChakraDrawer, Portal } from '@chakra-ui/react';
+import { CloseButton } from '@/components/ui/buttons/close-button';
+import * as React from 'react';
+
+interface DrawerContentProps extends ChakraDrawer.ContentProps {
+ portalled?: boolean;
+ portalRef?: React.RefObject;
+ offset?: ChakraDrawer.ContentProps['padding'];
+}
+
+export const DrawerContent = React.forwardRef(function DrawerContent(props, ref) {
+ const { children, portalled = true, portalRef, offset, ...rest } = props;
+ return (
+
+
+
+ {children}
+
+
+
+ );
+});
+
+export const DrawerCloseTrigger = React.forwardRef(
+ function DrawerCloseTrigger(props, ref) {
+ return (
+
+
+
+ );
+ },
+);
+
+export const DrawerTrigger = ChakraDrawer.Trigger;
+export const DrawerRoot = ChakraDrawer.Root;
+export const DrawerFooter = ChakraDrawer.Footer;
+export const DrawerHeader = ChakraDrawer.Header;
+export const DrawerBody = ChakraDrawer.Body;
+export const DrawerBackdrop = ChakraDrawer.Backdrop;
+export const DrawerDescription = ChakraDrawer.Description;
+export const DrawerTitle = ChakraDrawer.Title;
+export const DrawerActionTrigger = ChakraDrawer.ActionTrigger;
diff --git a/src/components/ui/overlays/hover-card.tsx b/src/components/ui/overlays/hover-card.tsx
new file mode 100644
index 0000000..71c7d15
--- /dev/null
+++ b/src/components/ui/overlays/hover-card.tsx
@@ -0,0 +1,34 @@
+import { HoverCard, Portal } from '@chakra-ui/react';
+import * as React from 'react';
+
+interface HoverCardContentProps extends HoverCard.ContentProps {
+ portalled?: boolean;
+ portalRef?: React.RefObject;
+}
+
+export const HoverCardContent = React.forwardRef(
+ function HoverCardContent(props, ref) {
+ const { portalled = true, portalRef, ...rest } = props;
+
+ return (
+
+
+
+
+
+ );
+ },
+);
+
+export const HoverCardArrow = React.forwardRef(
+ function HoverCardArrow(props, ref) {
+ return (
+
+
+
+ );
+ },
+);
+
+export const HoverCardRoot = HoverCard.Root;
+export const HoverCardTrigger = HoverCard.Trigger;
diff --git a/src/components/ui/overlays/menu.tsx b/src/components/ui/overlays/menu.tsx
new file mode 100644
index 0000000..7eb87ba
--- /dev/null
+++ b/src/components/ui/overlays/menu.tsx
@@ -0,0 +1,99 @@
+'use client';
+
+import { AbsoluteCenter, Menu as ChakraMenu, Portal } from '@chakra-ui/react';
+import * as React from 'react';
+import { LuCheck, LuChevronRight } from 'react-icons/lu';
+
+interface MenuContentProps extends ChakraMenu.ContentProps {
+ portalled?: boolean;
+ portalRef?: React.RefObject;
+}
+
+export const MenuContent = React.forwardRef(function MenuContent(props, ref) {
+ const { portalled = true, portalRef, ...rest } = props;
+ return (
+
+
+
+
+
+ );
+});
+
+export const MenuArrow = React.forwardRef(function MenuArrow(props, ref) {
+ return (
+
+
+
+ );
+});
+
+export const MenuCheckboxItem = React.forwardRef(
+ function MenuCheckboxItem(props, ref) {
+ return (
+
+
+
+
+
+
+ {props.children}
+
+ );
+ },
+);
+
+export const MenuRadioItem = React.forwardRef(
+ function MenuRadioItem(props, ref) {
+ const { children, ...rest } = props;
+ return (
+
+
+
+
+
+
+ {children}
+
+ );
+ },
+);
+
+export const MenuItemGroup = React.forwardRef(
+ function MenuItemGroup(props, ref) {
+ const { title, children, ...rest } = props;
+ return (
+
+ {title && {title} }
+ {children}
+
+ );
+ },
+);
+
+export interface MenuTriggerItemProps extends ChakraMenu.ItemProps {
+ startIcon?: React.ReactNode;
+}
+
+export const MenuTriggerItem = React.forwardRef(
+ function MenuTriggerItem(props, ref) {
+ const { startIcon, children, ...rest } = props;
+ return (
+
+ {startIcon}
+ {children}
+
+
+ );
+ },
+);
+
+export const MenuRadioItemGroup = ChakraMenu.RadioItemGroup;
+export const MenuContextTrigger = ChakraMenu.ContextTrigger;
+export const MenuRoot = ChakraMenu.Root;
+export const MenuSeparator = ChakraMenu.Separator;
+
+export const MenuItem = ChakraMenu.Item;
+export const MenuItemText = ChakraMenu.ItemText;
+export const MenuItemCommand = ChakraMenu.ItemCommand;
+export const MenuTrigger = ChakraMenu.Trigger;
diff --git a/src/components/ui/overlays/popover.tsx b/src/components/ui/overlays/popover.tsx
new file mode 100644
index 0000000..37a172c
--- /dev/null
+++ b/src/components/ui/overlays/popover.tsx
@@ -0,0 +1,49 @@
+import { Popover as ChakraPopover, Portal } from '@chakra-ui/react';
+import { CloseButton } from '../buttons/close-button';
+import * as React from 'react';
+
+interface PopoverContentProps extends ChakraPopover.ContentProps {
+ portalled?: boolean;
+ portalRef?: React.RefObject;
+}
+
+export const PopoverContent = React.forwardRef(
+ function PopoverContent(props, ref) {
+ const { portalled = true, portalRef, ...rest } = props;
+ return (
+
+
+
+
+
+ );
+ },
+);
+
+export const PopoverArrow = React.forwardRef(
+ function PopoverArrow(props, ref) {
+ return (
+
+
+
+ );
+ },
+);
+
+export const PopoverCloseTrigger = React.forwardRef(
+ function PopoverCloseTrigger(props, ref) {
+ return (
+
+
+
+ );
+ },
+);
+
+export const PopoverTitle = ChakraPopover.Title;
+export const PopoverDescription = ChakraPopover.Description;
+export const PopoverFooter = ChakraPopover.Footer;
+export const PopoverHeader = ChakraPopover.Header;
+export const PopoverRoot = ChakraPopover.Root;
+export const PopoverBody = ChakraPopover.Body;
+export const PopoverTrigger = ChakraPopover.Trigger;
diff --git a/src/components/ui/overlays/toggle-tip.tsx b/src/components/ui/overlays/toggle-tip.tsx
new file mode 100644
index 0000000..c841c08
--- /dev/null
+++ b/src/components/ui/overlays/toggle-tip.tsx
@@ -0,0 +1,48 @@
+import { Popover as ChakraPopover, IconButton, type IconButtonProps, Portal } from '@chakra-ui/react';
+import * as React from 'react';
+import { HiOutlineInformationCircle } from 'react-icons/hi';
+
+export interface ToggleTipProps extends ChakraPopover.RootProps {
+ showArrow?: boolean;
+ portalled?: boolean;
+ portalRef?: React.RefObject;
+ content?: React.ReactNode;
+ contentProps?: ChakraPopover.ContentProps;
+}
+
+export const ToggleTip = React.forwardRef(function ToggleTip(props, ref) {
+ const { showArrow, children, portalled = true, content, contentProps, portalRef, ...rest } = props;
+
+ return (
+
+ {children}
+
+
+
+ {showArrow && (
+
+
+
+ )}
+ {content}
+
+
+
+
+ );
+});
+
+export interface InfoTipProps extends Partial {
+ buttonProps?: IconButtonProps | undefined;
+}
+
+export const InfoTip = React.forwardRef(function InfoTip(props, ref) {
+ const { children, buttonProps, ...rest } = props;
+ return (
+
+
+
+
+
+ );
+});
diff --git a/src/components/ui/overlays/tooltip.tsx b/src/components/ui/overlays/tooltip.tsx
new file mode 100644
index 0000000..1d8ca66
--- /dev/null
+++ b/src/components/ui/overlays/tooltip.tsx
@@ -0,0 +1,35 @@
+import { Tooltip as ChakraTooltip, Portal } from '@chakra-ui/react';
+import * as React from 'react';
+
+export interface TooltipProps extends ChakraTooltip.RootProps {
+ showArrow?: boolean;
+ portalled?: boolean;
+ portalRef?: React.RefObject;
+ content: React.ReactNode;
+ contentProps?: ChakraTooltip.ContentProps;
+ disabled?: boolean;
+}
+
+export const Tooltip = React.forwardRef(function Tooltip(props, ref) {
+ const { showArrow, children, disabled, portalled = true, content, contentProps, portalRef, ...rest } = props;
+
+ if (disabled) return children;
+
+ return (
+
+ {children}
+
+
+
+ {showArrow && (
+
+
+
+ )}
+ {content}
+
+
+
+
+ );
+});
diff --git a/src/components/ui/provider.tsx b/src/components/ui/provider.tsx
new file mode 100644
index 0000000..73a44a9
--- /dev/null
+++ b/src/components/ui/provider.tsx
@@ -0,0 +1,26 @@
+"use client";
+
+import { ChakraProvider } from "@chakra-ui/react";
+import { SessionProvider } from "next-auth/react";
+import { ColorModeProvider, type ColorModeProviderProps } from "./color-mode";
+import { system } from "../../theme/theme";
+import { Toaster } from "./feedback/toaster";
+import TopLoader from "./top-loader";
+import ReactQueryProvider from "@/providers/react-query-provider";
+import AOSProvider from "@/providers/aos-provider";
+
+export function Provider(props: ColorModeProviderProps) {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/ui/top-loader.tsx b/src/components/ui/top-loader.tsx
new file mode 100644
index 0000000..92a5c4f
--- /dev/null
+++ b/src/components/ui/top-loader.tsx
@@ -0,0 +1,10 @@
+'use client';
+
+import NextTopLoader from 'nextjs-toploader';
+import { useToken } from '@chakra-ui/react';
+
+export default function TopLoader() {
+ const [color] = useToken('colors', ['primary.500']);
+
+ return ;
+}
diff --git a/src/components/ui/typography/blockquote.tsx b/src/components/ui/typography/blockquote.tsx
new file mode 100644
index 0000000..ad25362
--- /dev/null
+++ b/src/components/ui/typography/blockquote.tsx
@@ -0,0 +1,27 @@
+import { Blockquote as ChakraBlockquote } from '@chakra-ui/react';
+import * as React from 'react';
+
+export interface BlockquoteProps extends ChakraBlockquote.RootProps {
+ cite?: React.ReactNode;
+ citeUrl?: string;
+ icon?: React.ReactNode;
+ showDash?: boolean;
+}
+
+export const Blockquote = React.forwardRef(function Blockquote(props, ref) {
+ const { children, cite, citeUrl, showDash, icon, ...rest } = props;
+
+ return (
+
+ {icon}
+ {children}
+ {cite && (
+
+ {showDash ? <>—> : null} {cite}
+
+ )}
+
+ );
+});
+
+export const BlockquoteIcon = ChakraBlockquote.Icon;
diff --git a/src/components/ui/typography/prose.tsx b/src/components/ui/typography/prose.tsx
new file mode 100644
index 0000000..28c313c
--- /dev/null
+++ b/src/components/ui/typography/prose.tsx
@@ -0,0 +1,275 @@
+'use client';
+
+import { chakra } from '@chakra-ui/react';
+
+const TRAILING_PSEUDO_REGEX = /(::?[\w-]+(?:\([^)]*\))?)+$/;
+const EXCLUDE_CLASSNAME = '.not-prose';
+function inWhere(selector: T): T {
+ const rebuiltSelector = selector.startsWith('& ') ? selector.slice(2) : selector;
+ const match = selector.match(TRAILING_PSEUDO_REGEX);
+ const pseudo = match ? match[0] : '';
+ const base = match ? selector.slice(0, -match[0].length) : rebuiltSelector;
+ return `& :where(${base}):not(${EXCLUDE_CLASSNAME}, ${EXCLUDE_CLASSNAME} *)${pseudo}` as T;
+}
+
+export const Prose = chakra('div', {
+ base: {
+ color: 'fg.muted',
+ maxWidth: '65ch',
+ fontSize: 'sm',
+ lineHeight: '1.7em',
+ [inWhere('& p')]: {
+ marginTop: '1em',
+ marginBottom: '1em',
+ },
+ [inWhere('& blockquote')]: {
+ marginTop: '1.285em',
+ marginBottom: '1.285em',
+ paddingInline: '1.285em',
+ borderInlineStartWidth: '0.25em',
+ color: 'fg',
+ },
+ [inWhere('& a')]: {
+ color: 'fg',
+ textDecoration: 'underline',
+ textUnderlineOffset: '3px',
+ textDecorationThickness: '2px',
+ textDecorationColor: 'border.muted',
+ fontWeight: '500',
+ },
+ [inWhere('& strong')]: {
+ fontWeight: '600',
+ },
+ [inWhere('& a strong')]: {
+ color: 'inherit',
+ },
+ [inWhere('& h1')]: {
+ fontSize: '2.15em',
+ letterSpacing: '-0.02em',
+ marginTop: '0',
+ marginBottom: '0.8em',
+ lineHeight: '1.2em',
+ },
+ [inWhere('& h2')]: {
+ fontSize: '1.4em',
+ letterSpacing: '-0.02em',
+ marginTop: '1.6em',
+ marginBottom: '0.8em',
+ lineHeight: '1.4em',
+ },
+ [inWhere('& h3')]: {
+ fontSize: '1.285em',
+ letterSpacing: '-0.01em',
+ marginTop: '1.5em',
+ marginBottom: '0.4em',
+ lineHeight: '1.5em',
+ },
+ [inWhere('& h4')]: {
+ marginTop: '1.4em',
+ marginBottom: '0.5em',
+ letterSpacing: '-0.01em',
+ lineHeight: '1.5em',
+ },
+ [inWhere('& img')]: {
+ marginTop: '1.7em',
+ marginBottom: '1.7em',
+ borderRadius: 'lg',
+ boxShadow: 'inset',
+ },
+ [inWhere('& picture')]: {
+ marginTop: '1.7em',
+ marginBottom: '1.7em',
+ },
+ [inWhere('& picture > img')]: {
+ marginTop: '0',
+ marginBottom: '0',
+ },
+ [inWhere('& video')]: {
+ marginTop: '1.7em',
+ marginBottom: '1.7em',
+ },
+ [inWhere('& kbd')]: {
+ fontSize: '0.85em',
+ borderRadius: 'xs',
+ paddingTop: '0.15em',
+ paddingBottom: '0.15em',
+ paddingInlineEnd: '0.35em',
+ paddingInlineStart: '0.35em',
+ fontFamily: 'inherit',
+ color: 'fg.muted',
+ '--shadow': 'colors.border',
+ boxShadow: '0 0 0 1px var(--shadow),0 1px 0 1px var(--shadow)',
+ },
+ [inWhere('& code')]: {
+ fontSize: '0.925em',
+ letterSpacing: '-0.01em',
+ borderRadius: 'md',
+ borderWidth: '1px',
+ padding: '0.25em',
+ },
+ [inWhere('& pre code')]: {
+ fontSize: 'inherit',
+ letterSpacing: 'inherit',
+ borderWidth: 'inherit',
+ padding: '0',
+ },
+ [inWhere('& h2 code')]: {
+ fontSize: '0.9em',
+ },
+ [inWhere('& h3 code')]: {
+ fontSize: '0.8em',
+ },
+ [inWhere('& pre')]: {
+ backgroundColor: 'bg.subtle',
+ marginTop: '1.6em',
+ marginBottom: '1.6em',
+ borderRadius: 'md',
+ fontSize: '0.9em',
+ paddingTop: '0.65em',
+ paddingBottom: '0.65em',
+ paddingInlineEnd: '1em',
+ paddingInlineStart: '1em',
+ overflowX: 'auto',
+ fontWeight: '400',
+ },
+ [inWhere('& ol')]: {
+ marginTop: '1em',
+ marginBottom: '1em',
+ paddingInlineStart: '1.5em',
+ },
+ [inWhere('& ul')]: {
+ marginTop: '1em',
+ marginBottom: '1em',
+ paddingInlineStart: '1.5em',
+ },
+ [inWhere('& li')]: {
+ marginTop: '0.285em',
+ marginBottom: '0.285em',
+ },
+ [inWhere('& ol > li')]: {
+ paddingInlineStart: '0.4em',
+ listStyleType: 'decimal',
+ '&::marker': {
+ color: 'fg.muted',
+ },
+ },
+ [inWhere('& ul > li')]: {
+ paddingInlineStart: '0.4em',
+ listStyleType: 'disc',
+ '&::marker': {
+ color: 'fg.muted',
+ },
+ },
+ [inWhere('& > ul > li p')]: {
+ marginTop: '0.5em',
+ marginBottom: '0.5em',
+ },
+ [inWhere('& > ul > li > p:first-of-type')]: {
+ marginTop: '1em',
+ },
+ [inWhere('& > ul > li > p:last-of-type')]: {
+ marginBottom: '1em',
+ },
+ [inWhere('& > ol > li > p:first-of-type')]: {
+ marginTop: '1em',
+ },
+ [inWhere('& > ol > li > p:last-of-type')]: {
+ marginBottom: '1em',
+ },
+ [inWhere('& ul ul, ul ol, ol ul, ol ol')]: {
+ marginTop: '0.5em',
+ marginBottom: '0.5em',
+ },
+ [inWhere('& dl')]: {
+ marginTop: '1em',
+ marginBottom: '1em',
+ },
+ [inWhere('& dt')]: {
+ fontWeight: '600',
+ marginTop: '1em',
+ },
+ [inWhere('& dd')]: {
+ marginTop: '0.285em',
+ paddingInlineStart: '1.5em',
+ },
+ [inWhere('& hr')]: {
+ marginTop: '2.25em',
+ marginBottom: '2.25em',
+ },
+ [inWhere('& :is(h1,h2,h3,h4,h5,hr) + *')]: {
+ marginTop: '0',
+ },
+ [inWhere('& table')]: {
+ width: '100%',
+ tableLayout: 'auto',
+ textAlign: 'start',
+ lineHeight: '1.5em',
+ marginTop: '2em',
+ marginBottom: '2em',
+ },
+ [inWhere('& thead')]: {
+ borderBottomWidth: '1px',
+ color: 'fg',
+ },
+ [inWhere('& tbody tr')]: {
+ borderBottomWidth: '1px',
+ borderBottomColor: 'border',
+ },
+ [inWhere('& thead th')]: {
+ paddingInlineEnd: '1em',
+ paddingBottom: '0.65em',
+ paddingInlineStart: '1em',
+ fontWeight: 'medium',
+ textAlign: 'start',
+ },
+ [inWhere('& thead th:first-of-type')]: {
+ paddingInlineStart: '0',
+ },
+ [inWhere('& thead th:last-of-type')]: {
+ paddingInlineEnd: '0',
+ },
+ [inWhere('& tbody td, tfoot td')]: {
+ paddingTop: '0.65em',
+ paddingInlineEnd: '1em',
+ paddingBottom: '0.65em',
+ paddingInlineStart: '1em',
+ },
+ [inWhere('& tbody td:first-of-type, tfoot td:first-of-type')]: {
+ paddingInlineStart: '0',
+ },
+ [inWhere('& tbody td:last-of-type, tfoot td:last-of-type')]: {
+ paddingInlineEnd: '0',
+ },
+ [inWhere('& figure')]: {
+ marginTop: '1.625em',
+ marginBottom: '1.625em',
+ },
+ [inWhere('& figure > *')]: {
+ marginTop: '0',
+ marginBottom: '0',
+ },
+ [inWhere('& figcaption')]: {
+ fontSize: '0.85em',
+ lineHeight: '1.25em',
+ marginTop: '0.85em',
+ color: 'fg.muted',
+ },
+ [inWhere('& h1, h2, h3, h4')]: {
+ color: 'fg',
+ fontWeight: '600',
+ },
+ },
+ variants: {
+ size: {
+ md: {
+ fontSize: 'sm',
+ },
+ lg: {
+ fontSize: 'md',
+ },
+ },
+ },
+ defaultVariants: {
+ size: 'md',
+ },
+});
diff --git a/src/config/auth.ts b/src/config/auth.ts
new file mode 100644
index 0000000..2fb3c3f
--- /dev/null
+++ b/src/config/auth.ts
@@ -0,0 +1,24 @@
+/**
+ * Auth Configuration
+ * Controls whether authentication is required for the app
+ */
+
+export const authConfig = {
+ // If true, users must login to access the app
+ // If false, app is public with optional login
+ isAuthRequired: process.env.NEXT_PUBLIC_AUTH_REQUIRED === "true",
+
+ // Public routes that don't require authentication (when auth is required)
+ publicRoutes: ["/signin", "/signup", "/forgot-password"],
+
+ // Routes that should always be protected (even when auth is optional)
+ protectedRoutes: ["/admin", "/settings", "/profile"],
+};
+
+export const isPublicRoute = (pathname: string): boolean => {
+ return authConfig.publicRoutes.some((route) => pathname.includes(route));
+};
+
+export const isProtectedRoute = (pathname: string): boolean => {
+ return authConfig.protectedRoutes.some((route) => pathname.includes(route));
+};
diff --git a/src/config/base-url.ts b/src/config/base-url.ts
new file mode 100644
index 0000000..375014d
--- /dev/null
+++ b/src/config/base-url.ts
@@ -0,0 +1,17 @@
+const isServer = typeof window === "undefined";
+
+const apiUrl = isServer
+ ? process.env.SERVER_API_URL ||
+ process.env.NEXT_PUBLIC_API_URL ||
+ "http://localhost:3005/api"
+ : process.env.NEXT_PUBLIC_API_URL || "/api/backend";
+
+const baseUrl = {
+ // Main API Endpoint (Backend)
+ // Logic: Server uses direct HTTP, Client uses Proxy to avoid Mixed Content
+ auth: apiUrl,
+ admin: apiUrl,
+ core: apiUrl,
+};
+
+export default baseUrl;
diff --git a/src/config/navigation.ts b/src/config/navigation.ts
new file mode 100644
index 0000000..f2e204e
--- /dev/null
+++ b/src/config/navigation.ts
@@ -0,0 +1,85 @@
+export type NavItem = {
+ label: string; // i18n key under "nav.*"
+ href: string;
+ protected?: boolean; // Requires authentication
+ public?: boolean; // Accessible without auth
+ onlyPublic?: boolean; // Visible only when NOT logged in
+ visible?: boolean; // false = exists as route but hidden from nav
+ children?: NavItem[];
+ icon?: string; // icon identifier for visual enhancement
+};
+
+/**
+ * Returns nav items filtered by auth state and visibility.
+ */
+export function getVisibleNavItems(
+ items: NavItem[],
+ isAuthenticated: boolean,
+): NavItem[] {
+ return items.filter((item) => {
+ // Hidden items never show in nav
+ if (item.visible === false) return false;
+ // onlyPublic items hide when authenticated
+ if (item.onlyPublic && isAuthenticated) return false;
+ // Protected items hide when not authenticated
+ if (item.protected && !isAuthenticated) return false;
+ return true;
+ });
+}
+
+export const NAV_ITEMS: NavItem[] = [
+ // Public — always visible in nav
+ { label: "home", href: "/home", public: true },
+ { label: "matches", href: "/matches", public: true },
+ { label: "leagues", href: "/leagues", public: true },
+ { label: "h2h", href: "/h2h", public: true },
+
+ // Protected — grouped for cleaner nav
+ { label: "dashboard", href: "/dashboard", protected: true },
+ { label: "predictions", href: "/predictions", protected: true },
+
+ // Coupon dropdown group
+ {
+ label: "coupons",
+ href: "/coupon-builder",
+ protected: true,
+ children: [
+ { label: "coupon-builder", href: "/coupon-builder", protected: true },
+ { label: "coupon-history", href: "/coupon-history", protected: true },
+ ],
+ },
+
+ // Analysis dropdown group
+ {
+ label: "tools",
+ href: "/analysis",
+ protected: true,
+ children: [
+ { label: "analysis", href: "/analysis", protected: true },
+ { label: "spor-toto", href: "/spor-toto", protected: true },
+ ],
+ },
+
+ // Hidden routes (exist as routes but not in nav)
+ { label: "profile", href: "/profile", protected: true, visible: false },
+ { label: "admin", href: "/admin", protected: true, visible: false },
+
+ // Only public — hidden when logged in
+ {
+ label: "how-it-works",
+ href: "/how-it-works",
+ onlyPublic: true,
+ visible: false,
+ },
+ { label: "pricing", href: "/pricing", onlyPublic: true, visible: false },
+ { label: "contact", href: "/contact", onlyPublic: true, visible: false },
+
+ // Hidden routes (no nav entry, but route exists)
+ {
+ label: "privacy-and-security-policy",
+ href: "/privacy-and-security-policy",
+ visible: false,
+ },
+ { label: "information-notice", href: "/information-notice", visible: false },
+ { label: "terms-of-use", href: "/terms-of-use", visible: false },
+];
diff --git a/src/data/constants.ts b/src/data/constants.ts
new file mode 100644
index 0000000..da0cd4e
--- /dev/null
+++ b/src/data/constants.ts
@@ -0,0 +1,490 @@
+import { ButtonProps } from '@/components/ui/buttons/button';
+import { ColorPickerColorFormat } from '@chakra-ui/react';
+
+export const colorPalettes: ButtonProps['colorPalette'][] = [
+ 'current',
+ 'blue',
+ 'red',
+ 'green',
+ 'yellow',
+ 'gray',
+ 'orange',
+ 'pink',
+ 'purple',
+ 'cyan',
+];
+export const variants: ButtonProps['variant'][] = ['subtle', 'outline', 'ghost', 'solid', 'plain', 'surface'];
+export const fontSizes: ButtonProps['fontSize'][] = [
+ '2xs',
+ 'xs',
+ 'sm',
+ 'md',
+ 'lg',
+ 'xl',
+ '2xl',
+ '3xl',
+ '4xl',
+ '5xl',
+ '6xl',
+ '7xl',
+ '8xl',
+ '9xl',
+];
+
+export const boxData = {
+ imageUrl: 'https://bit.ly/2Z4KKcF',
+ imageAlt: 'Rear view of modern home with pool',
+ beds: 3,
+ title: 'Modern home in city center in the heart of historic Los Angeles',
+ formattedPrice: '$435',
+ reviewCount: 34,
+ rating: 4.5,
+};
+
+export const alignments = ['flex-start', 'center', 'flex-end'] as const;
+export const justifications = [
+ 'flex-start',
+ 'center',
+ 'flex-end',
+ 'space-between',
+ 'space-around',
+ 'space-evenly',
+] as const;
+
+export const placements = [
+ 'bottom-end',
+ 'bottom-start',
+ 'top-end',
+ 'top-start',
+ 'bottom-center',
+ 'top-center',
+ 'middle-center',
+ 'middle-end',
+ 'middle-start',
+] as const;
+
+export const headings = ['xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl', '4xl', '5xl', '6xl', '7xl'] as const;
+
+export const swatches = ['red', 'green', 'blue', 'purple', 'orange', 'pink'] as const;
+
+export const formats: ColorPickerColorFormat[] = ['hsla', 'hsba', 'rgba'];
+
+export const MAX_FILES = 3;
+
+export const radioCardItems = [
+ { value: 'next', title: 'Next.js' },
+ { value: 'vite', title: 'Vite' },
+];
+
+export const radioCardItems2 = [
+ { value: 'next', title: 'Next.js', description: 'Best for apps' },
+ { value: 'vite', title: 'Vite', description: 'Best for SPAs' },
+ { value: 'remix', title: 'Remix', description: 'Best for server-side rendering' },
+];
+
+export const marks = [
+ { value: 10, label: '10' },
+ { value: 50, label: '50' },
+ { value: 90, label: '90' },
+];
+
+export const frameworks = [
+ { label: 'React', value: 'react' },
+ { label: 'Solid', value: 'solid' },
+ { label: 'Vue', value: 'vue' },
+ { label: 'Angular', value: 'angular' },
+ { label: 'Svelte', value: 'svelte' },
+ { label: 'Preact', value: 'preact' },
+ { label: 'Qwik', value: 'qwik' },
+ { label: 'Lit', value: 'lit' },
+ { label: 'Alpine.js', value: 'alpinejs' },
+ { label: 'Ember', value: 'ember' },
+ { label: 'Next.js', value: 'nextjs' },
+];
+
+export const countries = [
+ { value: 'AD', label: 'Andorra', emoji: '🇦🇩' },
+ { value: 'AE', label: 'United Arab Emirates', emoji: '🇦🇪' },
+ { value: 'AF', label: 'Afghanistan', emoji: '🇦🇫' },
+ { value: 'AG', label: 'Antigua and Barbuda', emoji: '🇦🇬' },
+ { value: 'AI', label: 'Anguilla', emoji: '🇦🇮' },
+ { value: 'AL', label: 'Albania', emoji: '🇦🇱' },
+ { value: 'AM', label: 'Armenia', emoji: '🇦🇲' },
+ { value: 'AO', label: 'Angola', emoji: '🇦🇴' },
+ { value: 'AQ', label: 'Antarctica', emoji: '🇦🇶' },
+ { value: 'AR', label: 'Argentina', emoji: '🇦🇷' },
+ { value: 'AS', label: 'American Samoa', emoji: '🇦🇸' },
+ { value: 'AT', label: 'Austria', emoji: '🇦🇹' },
+ { value: 'AU', label: 'Australia', emoji: '🇦🇺' },
+ { value: 'AW', label: 'Aruba', emoji: '🇦🇼' },
+ { value: 'AX', label: 'Åland Islands', emoji: '🇦🇽' },
+ { value: 'AZ', label: 'Azerbaijan', emoji: '🇦🇿' },
+ { value: 'BA', label: 'Bosnia and Herzegovina', emoji: '🇧🇦' },
+ { value: 'BB', label: 'Barbados', emoji: '🇧🇧' },
+ { value: 'BD', label: 'Bangladesh', emoji: '🇧🇩' },
+ { value: 'BE', label: 'Belgium', emoji: '🇧🇪' },
+ { value: 'BF', label: 'Burkina Faso', emoji: '🇧🇫' },
+ { value: 'BG', label: 'Bulgaria', emoji: '🇧🇬' },
+ { value: 'BH', label: 'Bahrain', emoji: '🇧🇭' },
+ { value: 'BI', label: 'Burundi', emoji: '🇧🇮' },
+ { value: 'BJ', label: 'Benin', emoji: '🇧🇯' },
+ { value: 'BL', label: 'Saint Barthélemy', emoji: '🇧🇱' },
+ { value: 'BM', label: 'Bermuda', emoji: '🇧🇲' },
+ { value: 'BN', label: 'Brunei Darussalam', emoji: '🇧🇳' },
+ { value: 'BO', label: 'Bolivia, Plurinational State of', emoji: '🇧🇴' },
+ { value: 'BQ', label: 'Bonaire, Sint Eustatius and Saba', emoji: '🇧🇶' },
+ { value: 'BR', label: 'Brazil', emoji: '🇧🇷' },
+ { value: 'BS', label: 'Bahamas', emoji: '🇧🇸' },
+ { value: 'BT', label: 'Bhutan', emoji: '🇧🇹' },
+ { value: 'BV', label: 'Bouvet Island', emoji: '🇧🇻' },
+ { value: 'BW', label: 'Botswana', emoji: '🇧🇼' },
+ { value: 'BY', label: 'Belarus', emoji: '🇧🇾' },
+ { value: 'BZ', label: 'Belize', emoji: '🇧🇿' },
+ { value: 'CA', label: 'Canada', emoji: '🇨🇦' },
+ { value: 'CC', label: 'Cocos (Keeling) Islands', emoji: '🇨🇨' },
+ { value: 'CD', label: 'Congo, Democratic Republic of the', emoji: '🇨🇩' },
+ { value: 'CF', label: 'Central African Republic', emoji: '🇨🇫' },
+ { value: 'CG', label: 'Congo', emoji: '🇨🇬' },
+ { value: 'CH', label: 'Switzerland', emoji: '🇨🇭' },
+ { value: 'CI', label: "Côte d'Ivoire", emoji: '🇨🇮' },
+ { value: 'CK', label: 'Cook Islands', emoji: '🇨🇰' },
+ { value: 'CL', label: 'Chile', emoji: '🇨🇱' },
+ { value: 'CM', label: 'Cameroon', emoji: '🇨🇲' },
+ { value: 'CN', label: 'China', emoji: '🇨🇳' },
+ { value: 'CO', label: 'Colombia', emoji: '🇨🇴' },
+ { value: 'CR', label: 'Costa Rica', emoji: '🇨🇷' },
+ { value: 'CU', label: 'Cuba', emoji: '🇨🇺' },
+ { value: 'CV', label: 'Cabo Verde', emoji: '🇨🇻' },
+ { value: 'CW', label: 'Curaçao', emoji: '🇨🇼' },
+ { value: 'CX', label: 'Christmas Island', emoji: '🇨🇽' },
+ { value: 'CY', label: 'Cyprus', emoji: '🇨🇾' },
+ { value: 'CZ', label: 'Czechia', emoji: '🇨🇿' },
+ { value: 'DE', label: 'Germany', emoji: '🇩🇪' },
+ { value: 'DJ', label: 'Djibouti', emoji: '🇩🇯' },
+ { value: 'DK', label: 'Denmark', emoji: '🇩🇰' },
+ { value: 'DM', label: 'Dominica', emoji: '🇩🇲' },
+ { value: 'DO', label: 'Dominican Republic', emoji: '🇩🇴' },
+ { value: 'DZ', label: 'Algeria', emoji: '🇩🇿' },
+ { value: 'EC', label: 'Ecuador', emoji: '🇪🇨' },
+ { value: 'EE', label: 'Estonia', emoji: '🇪🇪' },
+ { value: 'EG', label: 'Egypt', emoji: '🇪🇬' },
+ { value: 'EH', label: 'Western Sahara', emoji: '🇪🇭' },
+ { value: 'ER', label: 'Eritrea', emoji: '🇪🇷' },
+ { value: 'ES', label: 'Spain', emoji: '🇪🇸' },
+ { value: 'ET', label: 'Ethiopia', emoji: '🇪🇹' },
+ { value: 'FI', label: 'Finland', emoji: '🇫🇮' },
+ { value: 'FJ', label: 'Fiji', emoji: '🇫🇯' },
+ { value: 'FK', label: 'Falkland Islands (Malvinas)', emoji: '🇫🇰' },
+ { value: 'FM', label: 'Micronesia, Federated States of', emoji: '🇫🇲' },
+ { value: 'FO', label: 'Faroe Islands', emoji: '🇫🇴' },
+ { value: 'FR', label: 'France', emoji: '🇫🇷' },
+ { value: 'GA', label: 'Gabon', emoji: '🇬🇦' },
+ {
+ value: 'GB',
+ label: 'United Kingdom of Great Britain and Northern Ireland',
+ emoji: '🇬🇧',
+ },
+ { value: 'GD', label: 'Grenada', emoji: '🇬🇩' },
+ { value: 'GE', label: 'Georgia', emoji: '🇬🇪' },
+ { value: 'GF', label: 'French Guiana', emoji: '🇬🇫' },
+ { value: 'GG', label: 'Guernsey', emoji: '🇬🇬' },
+ { value: 'GH', label: 'Ghana', emoji: '🇬🇭' },
+ { value: 'GI', label: 'Gibraltar', emoji: '🇬🇮' },
+ { value: 'GL', label: 'Greenland', emoji: '🇬🇱' },
+ { value: 'GM', label: 'Gambia', emoji: '🇬🇲' },
+ { value: 'GN', label: 'Guinea', emoji: '🇬🇳' },
+ { value: 'GP', label: 'Guadeloupe', emoji: '🇬🇵' },
+ { value: 'GQ', label: 'Equatorial Guinea', emoji: '🇬🇶' },
+ { value: 'GR', label: 'Greece', emoji: '🇬🇷' },
+ {
+ value: 'GS',
+ label: 'South Georgia and the South Sandwich Islands',
+ emoji: '🇬🇸',
+ },
+ { value: 'GT', label: 'Guatemala', emoji: '🇬🇹' },
+ { value: 'GU', label: 'Guam', emoji: '🇬🇺' },
+ { value: 'GW', label: 'Guinea-Bissau', emoji: '🇬🇼' },
+ { value: 'GY', label: 'Guyana', emoji: '🇬🇾' },
+ { value: 'HK', label: 'Hong Kong', emoji: '🇭🇰' },
+ { value: 'HM', label: 'Heard Island and McDonald Islands', emoji: '🇭🇲' },
+ { value: 'HN', label: 'Honduras', emoji: '🇭🇳' },
+ { value: 'HR', label: 'Croatia', emoji: '🇭🇷' },
+ { value: 'HT', label: 'Haiti', emoji: '🇭🇹' },
+ { value: 'HU', label: 'Hungary', emoji: '🇭🇺' },
+ { value: 'ID', label: 'Indonesia', emoji: '🇮🇩' },
+ { value: 'IE', label: 'Ireland', emoji: '🇮🇪' },
+ { value: 'IL', label: 'Israel', emoji: '🇮🇱' },
+ { value: 'IM', label: 'Isle of Man', emoji: '🇮🇲' },
+ { value: 'IN', label: 'India', emoji: '🇮🇳' },
+ { value: 'IO', label: 'British Indian Ocean Territory', emoji: '🇮🇴' },
+ { value: 'IQ', label: 'Iraq', emoji: '🇮🇶' },
+ { value: 'IR', label: 'Iran, Islamic Republic of', emoji: '🇮🇷' },
+ { value: 'IS', label: 'Iceland', emoji: '🇮🇸' },
+ { value: 'IT', label: 'Italy', emoji: '🇮🇹' },
+ { value: 'JE', label: 'Jersey', emoji: '🇯🇪' },
+ { value: 'JM', label: 'Jamaica', emoji: '🇯🇲' },
+ { value: 'JO', label: 'Jordan', emoji: '🇯🇴' },
+ { value: 'JP', label: 'Japan', emoji: '🇯🇵' },
+ { value: 'KE', label: 'Kenya', emoji: '🇰🇪' },
+ { value: 'KG', label: 'Kyrgyzstan', emoji: '🇰🇬' },
+ { value: 'KH', label: 'Cambodia', emoji: '🇰🇭' },
+ { value: 'KI', label: 'Kiribati', emoji: '🇰🇮' },
+ { value: 'KM', label: 'Comoros', emoji: '🇰🇲' },
+ { value: 'KN', label: 'Saint Kitts and Nevis', emoji: '🇰🇳' },
+ { value: 'KP', label: "Korea, Democratic People's Republic of", emoji: '🇰🇵' },
+ { value: 'KR', label: 'Korea, Republic of', emoji: '🇰🇷' },
+ { value: 'KW', label: 'Kuwait', emoji: '🇰🇼' },
+ { value: 'KY', label: 'Cayman Islands', emoji: '🇰🇾' },
+ { value: 'KZ', label: 'Kazakhstan', emoji: '🇰🇿' },
+ { value: 'LA', label: "Lao People's Democratic Republic", emoji: '🇱🇦' },
+ { value: 'LB', label: 'Lebanon', emoji: '🇱🇧' },
+ { value: 'LC', label: 'Saint Lucia', emoji: '🇱🇨' },
+ { value: 'LI', label: 'Liechtenstein', emoji: '🇱🇮' },
+ { value: 'LK', label: 'Sri Lanka', emoji: '🇱🇰' },
+ { value: 'LR', label: 'Liberia', emoji: '🇱🇷' },
+ { value: 'LS', label: 'Lesotho', emoji: '🇱🇸' },
+ { value: 'LT', label: 'Lithuania', emoji: '🇱🇹' },
+ { value: 'LU', label: 'Luxembourg', emoji: '🇱🇺' },
+ { value: 'LV', label: 'Latvia', emoji: '🇱🇻' },
+ { value: 'LY', label: 'Libya', emoji: '🇱🇾' },
+ { value: 'MA', label: 'Morocco', emoji: '🇲🇦' },
+ { value: 'MC', label: 'Monaco', emoji: '🇲🇨' },
+ { value: 'MD', label: 'Moldova, Republic of', emoji: '🇲🇩' },
+ { value: 'ME', label: 'Montenegro', emoji: '🇲🇪' },
+ { value: 'MF', label: 'Saint Martin, (French part)', emoji: '🇲🇫' },
+ { value: 'MG', label: 'Madagascar', emoji: '🇲🇬' },
+ { value: 'MH', label: 'Marshall Islands', emoji: '🇲🇭' },
+ { value: 'MK', label: 'North Macedonia', emoji: '🇲🇰' },
+ { value: 'ML', label: 'Mali', emoji: '🇲🇱' },
+ { value: 'MM', label: 'Myanmar', emoji: '🇲🇲' },
+ { value: 'MN', label: 'Mongolia', emoji: '🇲🇳' },
+ { value: 'MO', label: 'Macao', emoji: '🇲🇴' },
+ { value: 'MP', label: 'Northern Mariana Islands', emoji: '🇲🇵' },
+ { value: 'MQ', label: 'Martinique', emoji: '🇲🇶' },
+ { value: 'MR', label: 'Mauritania', emoji: '🇲🇷' },
+ { value: 'MS', label: 'Montserrat', emoji: '🇲🇸' },
+ { value: 'MT', label: 'Malta', emoji: '🇲🇹' },
+ { value: 'MU', label: 'Mauritius', emoji: '🇲🇺' },
+ { value: 'MV', label: 'Maldives', emoji: '🇲🇻' },
+ { value: 'MW', label: 'Malawi', emoji: '🇲🇼' },
+ { value: 'MX', label: 'Mexico', emoji: '🇲🇽' },
+ { value: 'MY', label: 'Malaysia', emoji: '🇲🇾' },
+ { value: 'MZ', label: 'Mozambique', emoji: '🇲🇿' },
+ { value: 'NA', label: 'Namibia', emoji: '🇳🇦' },
+ { value: 'NC', label: 'New Caledonia', emoji: '🇳🇨' },
+ { value: 'NE', label: 'Niger', emoji: '🇳🇪' },
+ { value: 'NF', label: 'Norfolk Island', emoji: '🇳🇫' },
+ { value: 'NG', label: 'Nigeria', emoji: '🇳🇬' },
+ { value: 'NI', label: 'Nicaragua', emoji: '🇳🇮' },
+ { value: 'NL', label: 'Netherlands', emoji: '🇳🇱' },
+ { value: 'NO', label: 'Norway', emoji: '🇳🇴' },
+ { value: 'NP', label: 'Nepal', emoji: '🇳🇵' },
+ { value: 'NR', label: 'Nauru', emoji: '🇳🇷' },
+ { value: 'NU', label: 'Niue', emoji: '🇳🇺' },
+ { value: 'NZ', label: 'New Zealand', emoji: '🇳🇿' },
+ { value: 'OM', label: 'Oman', emoji: '🇴🇲' },
+ { value: 'PA', label: 'Panama', emoji: '🇵🇦' },
+ { value: 'PE', label: 'Peru', emoji: '🇵🇪' },
+ { value: 'PF', label: 'French Polynesia', emoji: '🇵🇫' },
+ { value: 'PG', label: 'Papua New Guinea', emoji: '🇵🇬' },
+ { value: 'PH', label: 'Philippines', emoji: '🇵🇭' },
+ { value: 'PK', label: 'Pakistan', emoji: '🇵🇰' },
+ { value: 'PL', label: 'Poland', emoji: '🇵🇱' },
+ { value: 'PM', label: 'Saint Pierre and Miquelon', emoji: '🇵🇲' },
+ { value: 'PN', label: 'Pitcairn', emoji: '🇵🇳' },
+ { value: 'PR', label: 'Puerto Rico', emoji: '🇵🇷' },
+ { value: 'PS', label: 'Palestine, State of', emoji: '🇵🇸' },
+ { value: 'PT', label: 'Portugal', emoji: '🇵🇹' },
+ { value: 'PW', label: 'Palau', emoji: '🇵🇼' },
+ { value: 'PY', label: 'Paraguay', emoji: '🇵🇾' },
+ { value: 'QA', label: 'Qatar', emoji: '🇶🇦' },
+ { value: 'RE', label: 'Réunion', emoji: '🇷🇪' },
+ { value: 'RO', label: 'Romania', emoji: '🇷🇴' },
+ { value: 'RS', label: 'Serbia', emoji: '🇷🇸' },
+ { value: 'RU', label: 'Russian Federation', emoji: '🇷🇺' },
+ { value: 'RW', label: 'Rwanda', emoji: '🇷🇼' },
+ { value: 'SA', label: 'Saudi Arabia', emoji: '🇸🇦' },
+ { value: 'SB', label: 'Solomon Islands', emoji: '🇸🇧' },
+ { value: 'SC', label: 'Seychelles', emoji: '🇸🇨' },
+ { value: 'SD', label: 'Sudan', emoji: '🇸🇩' },
+ { value: 'SE', label: 'Sweden', emoji: '🇸🇪' },
+ { value: 'SG', label: 'Singapore', emoji: '🇸🇬' },
+ {
+ value: 'SH',
+ label: 'Saint Helena, Ascension and Tristan da Cunha',
+ emoji: '🇸🇭',
+ },
+ { value: 'SI', label: 'Slovenia', emoji: '🇸🇮' },
+ { value: 'SJ', label: 'Svalbard and Jan Mayen', emoji: '🇸🇯' },
+ { value: 'SK', label: 'Slovakia', emoji: '🇸🇰' },
+ { value: 'SL', label: 'Sierra Leone', emoji: '🇸🇱' },
+ { value: 'SM', label: 'San Marino', emoji: '🇸🇲' },
+ { value: 'SN', label: 'Senegal', emoji: '🇸🇳' },
+ { value: 'SO', label: 'Somalia', emoji: '🇸🇴' },
+ { value: 'SR', label: 'Suriname', emoji: '🇸🇷' },
+ { value: 'SS', label: 'South Sudan', emoji: '🇸🇸' },
+ { value: 'ST', label: 'Sao Tome and Principe', emoji: '🇸🇹' },
+ { value: 'SV', label: 'El Salvador', emoji: '🇸🇻' },
+ { value: 'SX', label: 'Sint Maarten, (Dutch part)', emoji: '🇸🇽' },
+ { value: 'SY', label: 'Syrian Arab Republic', emoji: '🇸🇾' },
+ { value: 'SZ', label: 'Eswatini', emoji: '🇸🇿' },
+ { value: 'TC', label: 'Turks and Caicos Islands', emoji: '🇹🇨' },
+ { value: 'TD', label: 'Chad', emoji: '🇹🇩' },
+ { value: 'TF', label: 'French Southern Territories', emoji: '🇹🇫' },
+ { value: 'TG', label: 'Togo', emoji: '🇹🇬' },
+ { value: 'TH', label: 'Thailand', emoji: '🇹🇭' },
+ { value: 'TJ', label: 'Tajikistan', emoji: '🇹🇯' },
+ { value: 'TK', label: 'Tokelau', emoji: '🇹🇰' },
+ { value: 'TL', label: 'Timor-Leste', emoji: '🇹🇱' },
+ { value: 'TM', label: 'Turkmenistan', emoji: '🇹🇲' },
+ { value: 'TN', label: 'Tunisia', emoji: '🇹🇳' },
+ { value: 'TO', label: 'Tonga', emoji: '🇹🇴' },
+ { value: 'TR', label: 'Türkiye', emoji: '🇹🇷' },
+ { value: 'TT', label: 'Trinidad and Tobago', emoji: '🇹🇹' },
+ { value: 'TV', label: 'Tuvalu', emoji: '🇹🇻' },
+ { value: 'TW', label: 'Taiwan, Province of China', emoji: '🇹🇼' },
+ { value: 'TZ', label: 'Tanzania, United Republic of', emoji: '🇹🇿' },
+ { value: 'UA', label: 'Ukraine', emoji: '🇺🇦' },
+ { value: 'UG', label: 'Uganda', emoji: '🇺🇬' },
+ { value: 'UM', label: 'United States Minor Outlying Islands', emoji: '🇺🇲' },
+ { value: 'US', label: 'United States of America', emoji: '🇺🇸' },
+ { value: 'UY', label: 'Uruguay', emoji: '🇺🇾' },
+ { value: 'UZ', label: 'Uzbekistan', emoji: '🇺🇿' },
+ { value: 'VA', label: 'Holy See', emoji: '🇻🇦' },
+ { value: 'VC', label: 'Saint Vincent and the Grenadines', emoji: '🇻🇨' },
+ { value: 'VE', label: 'Venezuela, Bolivarian Republic of', emoji: '🇻🇪' },
+ { value: 'VG', label: 'Virgin Islands, British', emoji: '🇻🇬' },
+ { value: 'VI', label: 'Virgin Islands, U.S.', emoji: '🇻🇮' },
+ { value: 'VN', label: 'Viet Nam', emoji: '🇻🇳' },
+ { value: 'VU', label: 'Vanuatu', emoji: '🇻🇺' },
+ { value: 'WF', label: 'Wallis and Futuna', emoji: '🇼🇫' },
+ { value: 'WS', label: 'Samoa', emoji: '🇼🇸' },
+ { value: 'YE', label: 'Yemen', emoji: '🇾🇪' },
+ { value: 'YT', label: 'Mayotte', emoji: '🇾🇹' },
+ { value: 'ZA', label: 'South Africa', emoji: '🇿🇦' },
+ { value: 'ZM', label: 'Zambia', emoji: '🇿🇲' },
+ { value: 'ZW', label: 'Zimbabwe', emoji: '🇿🇼' },
+];
+
+export const images = [
+ {
+ label: 'Mountain Landscape',
+ value: 'mountains',
+ description: 'Scenic mountain view',
+ url: 'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=400&h=300&fit=crop',
+ },
+ {
+ label: 'Ocean Waves',
+ value: 'ocean',
+ description: 'Peaceful ocean scene',
+ url: 'https://images.unsplash.com/photo-1505142468610-359e7d316be0?w=400&h=300&fit=crop',
+ },
+ {
+ label: 'Forest Path',
+ value: 'forest',
+ description: 'Tranquil forest trail',
+ url: 'https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=400&h=300&fit=crop',
+ },
+ {
+ label: 'City Skyline',
+ value: 'city',
+ description: 'Urban cityscape at night',
+ url: 'https://images.unsplash.com/photo-1449824913935-59a10b8d2000?w=400&h=300&fit=crop',
+ },
+ {
+ label: 'Desert Dunes',
+ value: 'desert',
+ description: 'Golden sand dunes',
+ url: 'https://images.unsplash.com/photo-1509316975850-ff9c5deb0cd9?w=400&h=300&fit=crop',
+ },
+];
+
+export const rootNode = {
+ id: 'ROOT',
+ name: '',
+ children: [
+ {
+ id: 'node_modules',
+ name: 'node_modules',
+ children: [
+ { id: 'node_modules/zag-js', name: 'zag-js' },
+ { id: 'node_modules/pandacss', name: 'panda' },
+ {
+ id: 'node_modules/@types',
+ name: '@types',
+ children: [
+ { id: 'node_modules/@types/react', name: 'react' },
+ { id: 'node_modules/@types/react-dom', name: 'react-dom' },
+ ],
+ },
+ ],
+ },
+ {
+ id: 'src',
+ name: 'src',
+ children: [
+ { id: 'src/app.tsx', name: 'app.tsx' },
+ { id: 'src/index.ts', name: 'index.ts' },
+ ],
+ },
+ { id: 'panda.config', name: 'panda.config.ts' },
+ { id: 'package.json', name: 'package.json' },
+ { id: 'renovate.json', name: 'renovate.json' },
+ { id: 'readme.md', name: 'README.md' },
+ ],
+};
+
+export const radioItems = [
+ { label: 'Ascending', value: 'asc' },
+ { label: 'Descending', value: 'desc' },
+];
+
+export const alertStatuses = ['success', 'warning', 'error', 'info', 'neutral'] as const;
+
+export const stats = [
+ { label: 'New Users', value: '234', diff: -12, helpText: 'Till date' },
+ { label: 'Sales', value: '£12,340', diff: 12, helpText: 'Last 30 days' },
+ { label: 'Revenue', value: '3,450', diff: 4.5, helpText: 'Last 30 days' },
+];
+
+export const items = [
+ { id: 1, name: 'Laptop', category: 'Electronics', price: 999.99 },
+ { id: 2, name: 'Coffee Maker', category: 'Home Appliances', price: 49.99 },
+ { id: 3, name: 'Desk Chair', category: 'Furniture', price: 150.0 },
+ { id: 4, name: 'Smartphone', category: 'Electronics', price: 799.99 },
+ { id: 5, name: 'Headphones', category: 'Accessories', price: 199.99 },
+];
+
+export const accordionItems = [
+ { value: 'a', title: 'First Item', text: 'Some value 1...' },
+ { value: 'b', title: 'Second Item', text: 'Some value 2...' },
+ { value: 'c', title: 'Third Item', text: 'Some value 3...' },
+];
+
+export const breadcrumbItems = [
+ { href: '#', label: 'Home' },
+ { href: '#', label: 'Library' },
+ { href: '#', label: 'Data' },
+];
+
+export const steps = [
+ {
+ title: 'Step 1',
+ description: 'Step 1 description',
+ },
+ {
+ title: 'Step 2',
+ description: 'Step 2 description',
+ },
+ {
+ title: 'Step 3',
+ description: 'Step 3 description',
+ },
+];
+
+export const itemsTabs = [
+ { id: '1', title: 'Tab', content: 'Tab Content' },
+ { id: '2', title: 'Tab', content: 'Tab Content' },
+ { id: '3', title: 'Tab', content: 'Tab Content' },
+ { id: '4', title: 'Tab', content: 'Tab Content' },
+];
diff --git a/src/hooks/use-debounce.ts b/src/hooks/use-debounce.ts
new file mode 100644
index 0000000..42fd6e0
--- /dev/null
+++ b/src/hooks/use-debounce.ts
@@ -0,0 +1,20 @@
+import { useState, useEffect } from "react";
+
+/**
+ * Debounces a value by delaying updates until after `delay` ms.
+ */
+export function useDebounce(value: T, delay: number): T {
+ const [debouncedValue, setDebouncedValue] = useState(value);
+
+ useEffect(() => {
+ const timer = setTimeout(() => {
+ setDebouncedValue(value);
+ }, delay);
+
+ return () => {
+ clearTimeout(timer);
+ };
+ }, [value, delay]);
+
+ return debouncedValue;
+}
diff --git a/src/hooks/useActiveNavItem.tsx b/src/hooks/useActiveNavItem.tsx
new file mode 100644
index 0000000..8efcc5a
--- /dev/null
+++ b/src/hooks/useActiveNavItem.tsx
@@ -0,0 +1,26 @@
+'use client';
+
+import { NavItem } from '@/config/navigation';
+import { usePathname } from 'next/navigation';
+import { useLocale } from 'next-intl';
+
+export const useActiveNavItem = (item: NavItem) => {
+ const path = usePathname();
+ const locale = useLocale();
+ const prefixedHref = `/${locale}${item.href}`;
+
+ const normalize = (url: string) => url.replace(/\/$/, '');
+ const currentPath = normalize(path);
+ const target = normalize(prefixedHref);
+
+ const hasActiveChild = item.children
+ ? item.children.some((child) => currentPath.startsWith(normalize(`/${locale}${child.href}`)))
+ : false;
+
+ const isActive =
+ target === `/${locale}` ? currentPath === `/${locale}` : currentPath.startsWith(target) || hasActiveChild;
+
+ const isChildActive = (href: string) => currentPath === `/${locale}${href}`;
+
+ return { isActive, isChildActive };
+};
diff --git a/src/i18n/navigation.ts b/src/i18n/navigation.ts
new file mode 100644
index 0000000..3ae8130
--- /dev/null
+++ b/src/i18n/navigation.ts
@@ -0,0 +1,6 @@
+import { createNavigation } from 'next-intl/navigation';
+import { routing } from './routing';
+
+// Lightweight wrappers around Next.js' navigation
+// APIs that consider the routing configuration
+export const { Link, redirect, usePathname, useRouter, getPathname } = createNavigation(routing);
diff --git a/src/i18n/request.ts b/src/i18n/request.ts
new file mode 100644
index 0000000..fbc039d
--- /dev/null
+++ b/src/i18n/request.ts
@@ -0,0 +1,14 @@
+import { getRequestConfig } from 'next-intl/server';
+import { hasLocale } from 'next-intl';
+import { routing } from './routing';
+
+export default getRequestConfig(async ({ requestLocale }) => {
+ // Typically corresponds to the `[locale]` segment
+ const requested = await requestLocale;
+ const locale = hasLocale(routing.locales, requested) ? requested : routing.defaultLocale;
+
+ return {
+ locale,
+ messages: (await import(`../../messages/${locale}.json`)).default,
+ };
+});
diff --git a/src/i18n/routing.ts b/src/i18n/routing.ts
new file mode 100644
index 0000000..1009a68
--- /dev/null
+++ b/src/i18n/routing.ts
@@ -0,0 +1,11 @@
+import { defineRouting } from 'next-intl/routing';
+
+export const locales = ['en', 'tr'];
+export const defaultLocale = 'tr';
+
+export const routing = defineRouting({
+ locales,
+ defaultLocale,
+ localePrefix: 'always',
+ localeCookie: true,
+});
diff --git a/src/lib/.DS_Store b/src/lib/.DS_Store
new file mode 100644
index 0000000..de773b4
Binary files /dev/null and b/src/lib/.DS_Store differ
diff --git a/src/lib/api/admin/service.ts b/src/lib/api/admin/service.ts
new file mode 100644
index 0000000..1a9676d
--- /dev/null
+++ b/src/lib/api/admin/service.ts
@@ -0,0 +1,128 @@
+import { apiRequest } from "@/lib/api/api-service";
+import { ApiResponse, PaginatedData } from "@/types/api-response";
+import type {
+ AdminPaginationParams,
+ AdminUserDto,
+ AnalyticsOverviewDto,
+ SettingDto,
+ UpdateSettingDto,
+ UpdateUserRoleDto,
+ UpdateUserSubscriptionDto,
+ UsageLimitDto,
+} from "./types";
+
+/**
+ * Admin Service
+ * Backend: /api/admin/*
+ */
+
+// Analytics
+const getAnalyticsOverview = () => {
+ return apiRequest>({
+ url: "/admin/analytics/overview",
+ client: "admin",
+ method: "get",
+ });
+};
+
+// Settings
+const getAllSettings = () => {
+ return apiRequest>>({
+ url: "/admin/settings",
+ client: "admin",
+ method: "get",
+ });
+};
+
+const updateSetting = (key: string, dto: UpdateSettingDto) => {
+ return apiRequest>({
+ url: `/admin/settings/${key}`,
+ client: "admin",
+ method: "put",
+ data: dto,
+ });
+};
+
+// Usage Limits
+const getAllUsageLimits = (params?: AdminPaginationParams) => {
+ return apiRequest>>({
+ url: "/admin/usage-limits",
+ client: "admin",
+ method: "get",
+ params,
+ });
+};
+
+const resetAllUsageLimits = () => {
+ return apiRequest>({
+ url: "/admin/usage-limits/reset-all",
+ client: "admin",
+ method: "post",
+ });
+};
+
+// Users
+const getAllUsers = (params?: AdminPaginationParams) => {
+ return apiRequest>>({
+ url: "/admin/users",
+ client: "admin",
+ method: "get",
+ params,
+ });
+};
+
+const getUserById = (id: string) => {
+ return apiRequest>({
+ url: `/admin/users/${id}`,
+ client: "admin",
+ method: "get",
+ });
+};
+
+const deleteUser = (id: string) => {
+ return apiRequest>({
+ url: `/admin/users/${id}`,
+ client: "admin",
+ method: "delete",
+ });
+};
+
+const updateUserRole = (id: string, dto: UpdateUserRoleDto) => {
+ return apiRequest>({
+ url: `/admin/users/${id}/role`,
+ client: "admin",
+ method: "put",
+ data: dto,
+ });
+};
+
+const updateUserSubscription = (id: string, dto: UpdateUserSubscriptionDto) => {
+ return apiRequest>({
+ url: `/admin/users/${id}/subscription`,
+ client: "admin",
+ method: "put",
+ data: dto,
+ });
+};
+
+const toggleUserActive = (id: string) => {
+ return apiRequest