-
-
-
+
+
-
{target.weight}x
+
{target.weight}x
-
-
-
+
+
+
-
-
+
+
@@ -71,13 +75,24 @@ export default function KeywordsPage() {
-
-
AI_FILTERING_TEMPLATE
-
You can define a natural language description for the LLM to verify against. e.g. "Item must not be broken. Must include power cable. Ignore 'box only' listings."
-
- // Enter custom instructions for the Analyst Agent here...
+
+
+
+
+
+
Global AI Filtering Template
-
+
Define a natural language description for the LLM to verify against globally. For example: "Item must not be broken. Must include power cable. Ignore 'box only' listings."
+
+
);
-}
+}
\ No newline at end of file
diff --git a/frontend/app/layout.tsx b/frontend/app/layout.tsx
index 5055068..6f43edb 100644
--- a/frontend/app/layout.tsx
+++ b/frontend/app/layout.tsx
@@ -2,13 +2,15 @@ import type { Metadata } from "next";
import { Inter, JetBrains_Mono } from "next/font/google";
import "./globals.css";
import Navbar from "@/components/Navbar";
+import { ThemeProvider } from "@/components/theme-provider";
+import PageTransition from "@/components/PageTransition";
const inter = Inter({ subsets: ["latin"], variable: "--font-inter" });
const jetbrainsMono = JetBrains_Mono({ subsets: ["latin"], variable: "--font-mono" });
export const metadata: Metadata = {
- title: "BidWraith | The AI Auction Sniper That Never Sleeps",
- description: "BidWraith continuously watches global auction sites, finds under-priced deals, and sends real-time alerts. Catch every deal before anyone else.",
+ title: "BidWraith | AI Auction Intelligence",
+ description: "BidWraith is the smartest way to track global auction sites. Get real-time alerts and beat the competition.",
};
export default function RootLayout({
@@ -17,14 +19,23 @@ export default function RootLayout({
children: React.ReactNode;
}>) {
return (
-
-
- {/* Ambient background particles/grid layer could go here */}
-
-
-
- {children}
-
+
+
+
+ {/* Fun tech subtle background grid */}
+
+
+
+
+ {children}
+
+
+
);
diff --git a/frontend/app/listings/page.tsx b/frontend/app/listings/page.tsx
index 75c4d6e..d486d3f 100644
--- a/frontend/app/listings/page.tsx
+++ b/frontend/app/listings/page.tsx
@@ -1,69 +1,121 @@
"use client";
import { motion } from 'framer-motion';
-import { ExternalLink, Clock, Brain } from 'lucide-react';
+import { ExternalLink, Clock, Brain, Download, RefreshCw, ShoppingCart, Info } from 'lucide-react';
const mockListings = [
- { id: 1, title: 'Lenovo ThinkPad T14 Gen 3 AMD Ryzen 7', price: '$450.00', estValue: '$800.00', site: 'eBay US', time: '14m 30s', verdict: 'HIGH_OPPORTUNITY' },
- { id: 2, title: 'NVIDIA RTX 3080 Founders Edition', price: '$320.00', estValue: '$450.00', site: 'HiBid', time: '1h 12m', verdict: 'GOOD_DEAL' },
- { id: 3, title: 'Lot of 10x iPhone 12 Pro 128GB Unlocked', price: '$1200.00', estValue: '$2500.00', site: 'ShopGoodwill', time: '4h 05m', verdict: 'RESELLER_DREAM' },
- { id: 4, title: 'Sony A7IV Mirrorless Camera Body', price: '$1500.00', estValue: '$1900.00', site: 'eBay UK', time: '5m 10s', verdict: 'URGENT' },
+ { id: 1, title: 'Lenovo ThinkPad T14 Gen 3 AMD Ryzen 7', price: '$450.00', estValue: '$800.00', site: 'eBay US', time: '14m 30s', verdict: 'HIGH_OPPORTUNITY', image: '💻' },
+ { id: 2, title: 'NVIDIA RTX 3080 Founders Edition', price: '$320.00', estValue: '$450.00', site: 'HiBid', time: '1h 12m', verdict: 'GOOD_DEAL', image: '🎮' },
+ { id: 3, title: 'Lot of 10x iPhone 12 Pro 128GB Unlocked', price: '$1200.00', estValue: '$2500.00', site: 'ShopGoodwill', time: '4h 05m', verdict: 'RESELLER_DREAM', image: '📱' },
+ { id: 4, title: 'Sony A7IV Mirrorless Camera Body', price: '$1500.00', estValue: '$1900.00', site: 'eBay UK', time: '5m 10s', verdict: 'URGENT', image: '📸' },
];
+const containerVariants = {
+ hidden: { opacity: 0 },
+ show: {
+ opacity: 1,
+ transition: {
+ staggerChildren: 0.1,
+ delayChildren: 0.2
+ }
+ }
+};
+
+const itemVariants = {
+ hidden: { opacity: 0, y: 30, scale: 0.95 },
+ show: { opacity: 1, y: 0, scale: 1, transition: { type: "spring" as const, stiffness: 300, damping: 24 } }
+};
+
export default function ListingsPage() {
return (
-
-
+
+
+
+
-
ACTIVE_LISTINGS
-
Filtered lots currently matching your target criteria.
+
+ Active Deals
+
+
Live opportunities filtered by your AI agents.
-
-
Export CSV
-
Force Refresh
+
+
+ Export
+
+
+
+ Refresh
+
-
+
-
- {mockListings.map((lot, i) => (
+
+ {mockListings.map((lot) => (
-
-
- [IMAGE_DATA]
+
+
-
+
-
-
{lot.title}
-
- {lot.verdict}
+
+
{lot.title}
+
+ {lot.verdict.replace('_', ' ')}
-
-
{lot.site}
-
{lot.time}
-
Verified
+
+ {lot.site}
+ Ends in {lot.time}
+ AI Verified
-
-
-
{lot.price}
-
Est. Value: {lot.estValue}
+
+
+
{lot.price}
+
+ Est: {lot.estValue}
+
-
- ANALYZE LOT
-
+
+ Analyze Lot
+
))}
-
+
);
}
diff --git a/frontend/app/page.tsx b/frontend/app/page.tsx
index 7e966b4..75797f4 100644
--- a/frontend/app/page.tsx
+++ b/frontend/app/page.tsx
@@ -1,113 +1,194 @@
"use client";
-import { motion } from 'framer-motion';
-import { ArrowRight, Crosshair, Brain, BellRing, Ghost } from 'lucide-react';
+import { motion, useScroll, useTransform } from 'framer-motion';
+import { Rocket, Target, Zap, ShieldCheck, Cpu, ChevronRight } from 'lucide-react';
import Link from 'next/link';
-import GlitchText from '@/components/GlitchText';
+import dynamic from 'next/dynamic';
+
+const Hero3D = dynamic(() => import('@/components/Hero3D'), { ssr: false });
const features = [
{
- icon: Crosshair,
+ icon: Target,
title: "Always-On Radar",
description: "Monitors dozens of auction sites simultaneously. The engine never sleeps, so you never miss an ending lot.",
+ color: "text-blue-500",
+ bg: "bg-blue-500/10"
},
{
- icon: Brain,
+ icon: Cpu,
title: "AI-Grade Filtering",
description: "External LLMs score and filter every lot against your precise custom targets. We drop the noise and show only true deals.",
+ color: "text-purple-500",
+ bg: "bg-purple-500/10"
},
{
- icon: BellRing,
+ icon: Zap,
title: "Real-Time Comms",
description: "Instant alerts delivered via Telegram, Discord, or Email the minute a high-value lot appears or is about to close.",
+ color: "text-yellow-500",
+ bg: "bg-yellow-500/10"
},
{
- icon: Ghost,
+ icon: ShieldCheck,
title: "Stealth Engine",
description: "Human-like browsing algorithms bypass standard detection, ensuring reliable intelligence gathering from any platform.",
+ color: "text-green-500",
+ bg: "bg-green-500/10"
}
];
export default function LandingPage() {
+ const { scrollYProgress } = useScroll();
+ const yHero = useTransform(scrollYProgress, [0, 1], ["0%", "50%"]);
+ const opacityHero = useTransform(scrollYProgress, [0, 0.2], [1, 0]);
+
return (
-
+
+
+ {/* Dynamic 3D Background */}
+
+
+
+
+ {/* Dynamic Background Blob Elements */}
+
+
+
+
+
{/* Hero Section */}
-
+
-
-
- System v4 Deployed
-
-
+
+
+
+
+
+ System v5 Neural Engine Online
+
+
The AI Sniper That
-
+ Never Sleeps
-
- BidWraith watches every global auction site, scores every lot with AI, and alerts you the moment a real deal drops.
+
+ BidWraith watches every global auction site, scores every lot with deep AI, and alerts you the moment a real deal drops. Get the ultimate edge.
-
-
- Initialize Console
+
+
+
+
+ Initialize Console
-
- Read Briefing
+
+ Explore Tech
+
- {/* Stats Strip */}
-
-
-
-
-
-
-
-
100%
-
Stealth Rate
+ {/* Stats Strip with Scroll Reveal */}
+
+
+
+
+
+ {[
+ { label: 'Uptime', value: '24/7', color: 'text-primary' },
+ { label: 'Alert Latency', value: '< 1s', color: 'text-accent' },
+ { label: 'API Endpoints', value: '42', color: 'text-blue-500' },
+ { label: 'Stealth Rate', value: '100%', color: 'text-green-500' }
+ ].map((stat, i) => (
+
+
+ {stat.value}
+
+ {stat.label}
+
+ ))}
-
+
{/* Features Section */}
-
-
-
-
Core Directives
-
Advanced architecture designed to give you an unfair advantage in the global market.
-
+
+
+
+ Core Capabilities
+ Advanced architecture designed to give you an unfair advantage in the global market.
+
-
+
{features.map((feature, idx) => (
-
-
- {feature.title}
-
+
+
+
+
+ {feature.title}
+
{feature.description}
@@ -116,28 +197,30 @@ export default function LandingPage() {
- {/* Diagram Section */}
-
-
-
The Execution Pipeline
-
-
Targets & Rules
-
-
Ghost Scraper
-
-
AI Analysis
-
-
Real-time Alerts
+ {/* Footer CTA with 3D feel */}
+
+
+
+
+
+
+
Ready to dominate?
+
+ Start Sniping Now
+
+
-
-
-
- {/* Footer CTA */}
-
- Ready to dominate the market?
-
- > ACCESS_SYSTEM_NOW _
-
+
+
);
diff --git a/frontend/app/settings/page.tsx b/frontend/app/settings/page.tsx
index 8ce8053..392e097 100644
--- a/frontend/app/settings/page.tsx
+++ b/frontend/app/settings/page.tsx
@@ -1,98 +1,177 @@
"use client";
import { motion } from 'framer-motion';
-import { Save, Bell, Shield, Database, Cpu } from 'lucide-react';
+import { Save, Bell, Shield, Database, Cpu, Settings, MessageSquare, Sliders, HardDrive, Trash2 } from 'lucide-react';
+
+const containerVariants = {
+ hidden: { opacity: 0 },
+ show: {
+ opacity: 1,
+ transition: {
+ staggerChildren: 0.1,
+ }
+ }
+};
+
+const itemVariants = {
+ hidden: { opacity: 0, y: 20, scale: 0.95 },
+ show: { opacity: 1, y: 0, scale: 1, transition: { type: "spring" as const, stiffness: 300, damping: 24 } }
+};
export default function SettingsPage() {
return (
-
-
+
+
+
+
+
-
SYSTEM_CONFIG
-
Adjust core parameters, AI models, and notification routing.
+
+ System Config
+
+
Adjust core parameters, AI models, and notification routing.
-
- COMMIT_CHANGES
-
-
+
+
+
+ Save Changes
+
+
-
-
-
- AI_ENGINE_SETTINGS
-
+
+
+ {/* AI Settings */}
+
+
+
+
+ AI Engine Preferences
+
+
-
Primary Provider
-
- Anthropic (Claude 3.5 Sonnet)
- OpenAI (GPT-4o)
- Groq (Llama 3 70B)
- Ollama (Local)
-
+
Primary Provider
+
+
+ Anthropic (Claude 3.5 Sonnet)
+ OpenAI (GPT-4o)
+ Groq (Llama 3 70B)
+ Ollama (Local)
+
+
â–¼
+
-
Strictness Level
-
- High (Miss deals, zero noise)
- Balanced
- Low (Catch everything, more noise)
-
+
Strictness Level
+
+
+ High (Miss deals, zero noise)
+ Balanced
+ Low (Catch everything, more noise)
+
+
â–¼
+
-
-
- ALERT_ROUTING
-
-
-
-
Telegram Bot
-
Status: Connected (@BidWraithBot)
+ {/* Alert Routing */}
+
+
+
+
+ Alert Routing
+
+
+
+
+
+
+
Telegram Bot
+
+ Connected (@BidWraithBot)
+
+
-
-
-
-
-
Discord Webhook
-
Status: Not Configured
+
+
-
-
+
+
+
+
+
+
Discord Webhook
+
Not Configured
+
+
+
+
+
+
-
-
- STEALTH_MODE
-
+
+ {/* Stealth Mode */}
+
+
+
+
+ Stealth Mode
+
+
-
- DATA_MANAGEMENT
-
-
Export Database Backup
-
Clear Old Logs (>30d)
-
FACTORY RESET
+ {/* Data Management */}
+
+
+
+ Data Management
+
+
+
+ Export Database
+
+
+ Purge Old Logs
+
-
+
);
}
diff --git a/frontend/app/sites/page.tsx b/frontend/app/sites/page.tsx
index 4d78bc7..f7ef1d3 100644
--- a/frontend/app/sites/page.tsx
+++ b/frontend/app/sites/page.tsx
@@ -1,7 +1,7 @@
"use client";
import { motion } from 'framer-motion';
-import { ShieldCheck, ShieldAlert, Cpu, Terminal } from 'lucide-react';
+import { ShieldCheck, ShieldAlert, Cpu, Network, PauseCircle, PlayCircle, Plus } from 'lucide-react';
const mockSites = [
{ id: 1, name: 'eBay US', url: 'ebay.com', status: 'healthy', lag: '240ms', lastScrape: '2s ago' },
@@ -12,14 +12,16 @@ const mockSites = [
export default function SitesPage() {
return (
-
-
+
+
-
NETWORK_NODES
-
Manage auction platforms targeted by the scraping engine.
+
+ Network Nodes
+
+
Manage and monitor the auction platforms your agents are scraping.
-
- ADAPT_NEW_SITE
+
+ Add New Site
@@ -27,64 +29,79 @@ export default function SitesPage() {
{mockSites.map((site, i) => (
-
{site.name}
-
{site.url}
+
{site.name}
+
{site.url}
+
+
+ {site.status === 'healthy' ? (
+
+ ) : (
+
+ )}
- {site.status === 'healthy' ? (
-
- ) : (
-
- )}
-
-
-
Latency:
-
{site.lag}
+
+
+ Latency
+ {site.lag}
-
-
Last Ping:
-
{site.lastScrape}
+
+ Last Ping
+ {site.lastScrape}
-
-
Selectors:
-
Verified
+
+ Selectors
+ Verified
-
-
- Inspect
+
+
+ Inspect
-
- Pause
+
+
))}
-
-
- AUTO_ADAPTATION_ENGINE
-
-
- Ghost Node can autonomously learn new site structures. Provide a target URL, and the Scout Agent will attempt to generate valid CSS selectors for listings, prices, and countdown timers.
+
+
+
+
+
+
Auto-Adaptation Engine
+
+
+ The engine can autonomously learn new site structures. Provide a target URL, and the Scout Agent will attempt to generate valid selectors for listings, prices, and countdown timers.
-
+
);
-}
+}
\ No newline at end of file
diff --git a/frontend/components/GlitchText.tsx b/frontend/components/GlitchText.tsx
deleted file mode 100644
index 447cd19..0000000
--- a/frontend/components/GlitchText.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-"use client";
-
-import React from 'react';
-
-export default function GlitchText({ text, className = "" }: { text: string; className?: string }) {
- return (
-
-
- {text}
-
-
- );
-}
diff --git a/frontend/components/Hero3D.tsx b/frontend/components/Hero3D.tsx
new file mode 100644
index 0000000..13e3483
--- /dev/null
+++ b/frontend/components/Hero3D.tsx
@@ -0,0 +1,106 @@
+"use client";
+
+import { useRef, useState } from "react";
+import { Canvas, useFrame } from "@react-three/fiber";
+import {
+ Float,
+ MeshDistortMaterial,
+ Environment,
+ ContactShadows,
+ Lightformer,
+ PerspectiveCamera
+} from "@react-three/drei";
+import * as THREE from "three";
+import { useTheme } from "next-themes";
+
+function FloatingShape() {
+ const mesh = useRef
(null);
+ const { theme, resolvedTheme } = useTheme();
+ const [hovered, setHovered] = useState(false);
+
+ const currentTheme = theme === "system" ? resolvedTheme : theme;
+ const isDark = currentTheme === "dark";
+
+ const color = isDark ? "#6366f1" : "#8b5cf6"; // primary or accent colors
+ const emissive = isDark ? "#3730a3" : "#4c1d95";
+
+ // Animate on interaction
+ useFrame((state) => {
+ if (mesh.current) {
+ mesh.current.rotation.x = THREE.MathUtils.lerp(mesh.current.rotation.x, hovered ? state.mouse.y * 0.5 : state.clock.getElapsedTime() * 0.2, 0.1);
+ mesh.current.rotation.y = THREE.MathUtils.lerp(mesh.current.rotation.y, hovered ? state.mouse.x * 0.5 : state.clock.getElapsedTime() * 0.3, 0.1);
+ }
+ });
+
+ return (
+
+ setHovered(true)}
+ onPointerOut={() => setHovered(false)}
+ scale={hovered ? 1.1 : 1}
+ >
+
+
+
+
+ );
+}
+
+export default function Hero3D() {
+ const { theme, resolvedTheme } = useTheme();
+ const currentTheme = theme === "system" ? resolvedTheme : theme;
+ const isDark = currentTheme === "dark";
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/frontend/components/Navbar.tsx b/frontend/components/Navbar.tsx
index ec9eb7c..3f6b5b4 100644
--- a/frontend/components/Navbar.tsx
+++ b/frontend/components/Navbar.tsx
@@ -2,9 +2,9 @@
import Link from 'next/link';
import { usePathname } from 'next/navigation';
-import { Activity, LayoutDashboard, List, Search, Globe, Settings, TerminalSquare } from 'lucide-react';
-import GlitchText from './GlitchText';
+import { LayoutDashboard, List, Search, Globe, Settings, TerminalSquare, Rocket } from 'lucide-react';
import { motion } from 'framer-motion';
+import { ThemeToggle } from './theme-toggle';
const navItems = [
{ name: 'Dashboard', href: '/dashboard', icon: LayoutDashboard },
@@ -19,41 +19,62 @@ export default function Navbar() {
const pathname = usePathname();
return (
-
+
-
-
+
+
+
+
+ BidWraith
+
-
- {navItems.map((item) => {
+
+ {navItems.map((item, idx) => {
const isActive = pathname.startsWith(item.href);
return (
-
- {item.name}
{isActive && (
)}
+
+ {item.name}
);
})}
-
-
- SYSTEM_ONLINE
-
+
+
+
+ SYSTEM_ACTIVE
+
-
+
);
}
diff --git a/frontend/components/PageTransition.tsx b/frontend/components/PageTransition.tsx
new file mode 100644
index 0000000..ee9bdb7
--- /dev/null
+++ b/frontend/components/PageTransition.tsx
@@ -0,0 +1,22 @@
+"use client";
+
+import { motion } from "framer-motion";
+import { usePathname } from "next/navigation";
+import { ReactNode } from "react";
+
+export default function PageTransition({ children }: { children: ReactNode }) {
+ const pathname = usePathname();
+
+ return (
+
+ {children}
+
+ );
+}
diff --git a/frontend/components/theme-provider.tsx b/frontend/components/theme-provider.tsx
new file mode 100644
index 0000000..e018a73
--- /dev/null
+++ b/frontend/components/theme-provider.tsx
@@ -0,0 +1,11 @@
+"use client"
+
+import * as React from "react"
+import { ThemeProvider as NextThemesProvider } from "next-themes"
+
+export function ThemeProvider({
+ children,
+ ...props
+}: React.ComponentProps) {
+ return {children}
+}
\ No newline at end of file
diff --git a/frontend/components/theme-toggle.tsx b/frontend/components/theme-toggle.tsx
new file mode 100644
index 0000000..2cf91a5
--- /dev/null
+++ b/frontend/components/theme-toggle.tsx
@@ -0,0 +1,20 @@
+"use client"
+
+import * as React from "react"
+import { Moon, Sun } from "lucide-react"
+import { useTheme } from "next-themes"
+
+export function ThemeToggle() {
+ const { theme, setTheme } = useTheme()
+
+ return (
+ setTheme(theme === "dark" ? "light" : "dark")}
+ className="relative inline-flex h-9 w-9 items-center justify-center rounded-md bg-secondary/20 hover:bg-secondary/40 text-secondary-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
+ aria-label="Toggle theme"
+ >
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index f78b023..1104da7 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -14,14 +14,20 @@
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-slot": "^1.2.4",
"@radix-ui/react-toast": "^1.2.15",
+ "@react-three/drei": "^10.7.7",
+ "@react-three/fiber": "^9.5.0",
"@tanstack/react-query": "^5.90.21",
+ "@types/three": "^0.183.1",
"class-variance-authority": "^0.7.1",
"motion": "^12.36.0",
"next": "16.1.6",
+ "next-themes": "^0.4.6",
"radix-ui": "^1.4.3",
"react": "19.2.3",
"react-dom": "19.2.3",
"shadcn": "^4.0.6",
+ "three": "^0.183.2",
+ "three-stdlib": "^2.36.1",
"tw-animate-css": "^1.4.0",
"zustand": "^5.0.11"
},
@@ -550,7 +556,6 @@
"version": "7.28.6",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz",
"integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==",
- "dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -746,6 +751,12 @@
"node": ">=20.19.0"
}
},
+ "node_modules/@dimforge/rapier3d-compat": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/@dimforge/rapier3d-compat/-/rapier3d-compat-0.12.0.tgz",
+ "integrity": "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==",
+ "license": "Apache-2.0"
+ },
"node_modules/@dnd-kit/accessibility": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@dnd-kit/accessibility/-/accessibility-3.1.1.tgz",
@@ -2329,6 +2340,12 @@
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
+ "node_modules/@mediapipe/tasks-vision": {
+ "version": "0.10.17",
+ "resolved": "https://registry.npmjs.org/@mediapipe/tasks-vision/-/tasks-vision-0.10.17.tgz",
+ "integrity": "sha512-CZWV/q6TTe8ta61cZXjfnnHsfWIdFhms03M9T7Cnd5y2mdpylJM0rF1qRq+wsQVRMLz1OYPVEBU9ph2Bx8cxrg==",
+ "license": "Apache-2.0"
+ },
"node_modules/@modelcontextprotocol/sdk": {
"version": "1.27.1",
"resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.27.1.tgz",
@@ -2391,6 +2408,18 @@
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"license": "MIT"
},
+ "node_modules/@monogrid/gainmap-js": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/@monogrid/gainmap-js/-/gainmap-js-3.4.0.tgz",
+ "integrity": "sha512-2Z0FATFHaoYJ8b+Y4y4Hgfn3FRFwuU5zRrk+9dFWp4uGAdHGqVEdP7HP+gLA3X469KXHmfupJaUbKo1b/aDKIg==",
+ "license": "MIT",
+ "dependencies": {
+ "promise-worker-transferable": "^1.0.4"
+ },
+ "peerDependencies": {
+ "three": ">= 0.159.0"
+ }
+ },
"node_modules/@mswjs/interceptors": {
"version": "0.41.3",
"resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.41.3.tgz",
@@ -4313,6 +4342,94 @@
"integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==",
"license": "MIT"
},
+ "node_modules/@react-three/drei": {
+ "version": "10.7.7",
+ "resolved": "https://registry.npmjs.org/@react-three/drei/-/drei-10.7.7.tgz",
+ "integrity": "sha512-ff+J5iloR0k4tC++QtD/j9u3w5fzfgFAWDtAGQah9pF2B1YgOq/5JxqY0/aVoQG5r3xSZz0cv5tk2YuBob4xEQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.26.0",
+ "@mediapipe/tasks-vision": "0.10.17",
+ "@monogrid/gainmap-js": "^3.0.6",
+ "@use-gesture/react": "^10.3.1",
+ "camera-controls": "^3.1.0",
+ "cross-env": "^7.0.3",
+ "detect-gpu": "^5.0.56",
+ "glsl-noise": "^0.0.0",
+ "hls.js": "^1.5.17",
+ "maath": "^0.10.8",
+ "meshline": "^3.3.1",
+ "stats-gl": "^2.2.8",
+ "stats.js": "^0.17.0",
+ "suspend-react": "^0.1.3",
+ "three-mesh-bvh": "^0.8.3",
+ "three-stdlib": "^2.35.6",
+ "troika-three-text": "^0.52.4",
+ "tunnel-rat": "^0.1.2",
+ "use-sync-external-store": "^1.4.0",
+ "utility-types": "^3.11.0",
+ "zustand": "^5.0.1"
+ },
+ "peerDependencies": {
+ "@react-three/fiber": "^9.0.0",
+ "react": "^19",
+ "react-dom": "^19",
+ "three": ">=0.159"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@react-three/fiber": {
+ "version": "9.5.0",
+ "resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-9.5.0.tgz",
+ "integrity": "sha512-FiUzfYW4wB1+PpmsE47UM+mCads7j2+giRBltfwH7SNhah95rqJs3ltEs9V3pP8rYdS0QlNne+9Aj8dS/SiaIA==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.17.8",
+ "@types/webxr": "*",
+ "base64-js": "^1.5.1",
+ "buffer": "^6.0.3",
+ "its-fine": "^2.0.0",
+ "react-use-measure": "^2.1.7",
+ "scheduler": "^0.27.0",
+ "suspend-react": "^0.1.3",
+ "use-sync-external-store": "^1.4.0",
+ "zustand": "^5.0.3"
+ },
+ "peerDependencies": {
+ "expo": ">=43.0",
+ "expo-asset": ">=8.4",
+ "expo-file-system": ">=11.0",
+ "expo-gl": ">=11.0",
+ "react": ">=19 <19.3",
+ "react-dom": ">=19 <19.3",
+ "react-native": ">=0.78",
+ "three": ">=0.156"
+ },
+ "peerDependenciesMeta": {
+ "expo": {
+ "optional": true
+ },
+ "expo-asset": {
+ "optional": true
+ },
+ "expo-file-system": {
+ "optional": true
+ },
+ "expo-gl": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ },
+ "react-native": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@rolldown/pluginutils": {
"version": "1.0.0-rc.3",
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz",
@@ -5198,6 +5315,12 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/@tweenjs/tween.js": {
+ "version": "23.1.3",
+ "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz",
+ "integrity": "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==",
+ "license": "MIT"
+ },
"node_modules/@tybys/wasm-util": {
"version": "0.10.1",
"resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
@@ -5280,6 +5403,12 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@types/draco3d": {
+ "version": "1.4.10",
+ "resolved": "https://registry.npmjs.org/@types/draco3d/-/draco3d-1.4.10.tgz",
+ "integrity": "sha512-AX22jp8Y7wwaBgAixaSvkoG4M/+PlAcm3Qs4OW8yT9DM4xUpWKeFhLueTAyZF39pviAdcDdeJoACapiAceqNcw==",
+ "license": "MIT"
+ },
"node_modules/@types/estree": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
@@ -5311,11 +5440,16 @@
"undici-types": "~6.21.0"
}
},
+ "node_modules/@types/offscreencanvas": {
+ "version": "2019.7.3",
+ "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.3.tgz",
+ "integrity": "sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A==",
+ "license": "MIT"
+ },
"node_modules/@types/react": {
"version": "19.2.14",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
"integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
- "devOptional": true,
"license": "MIT",
"dependencies": {
"csstype": "^3.2.2"
@@ -5331,18 +5465,54 @@
"@types/react": "^19.2.0"
}
},
+ "node_modules/@types/react-reconciler": {
+ "version": "0.28.9",
+ "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.9.tgz",
+ "integrity": "sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*"
+ }
+ },
+ "node_modules/@types/stats.js": {
+ "version": "0.17.4",
+ "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.4.tgz",
+ "integrity": "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==",
+ "license": "MIT"
+ },
"node_modules/@types/statuses": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@types/statuses/-/statuses-2.0.6.tgz",
"integrity": "sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==",
"license": "MIT"
},
+ "node_modules/@types/three": {
+ "version": "0.183.1",
+ "resolved": "https://registry.npmjs.org/@types/three/-/three-0.183.1.tgz",
+ "integrity": "sha512-f2Pu5Hrepfgavttdye3PsH5RWyY/AvdZQwIVhrc4uNtvF7nOWJacQKcoVJn0S4f0yYbmAE6AR+ve7xDcuYtMGw==",
+ "license": "MIT",
+ "dependencies": {
+ "@dimforge/rapier3d-compat": "~0.12.0",
+ "@tweenjs/tween.js": "~23.1.3",
+ "@types/stats.js": "*",
+ "@types/webxr": ">=0.5.17",
+ "@webgpu/types": "*",
+ "fflate": "~0.8.2",
+ "meshoptimizer": "~1.0.1"
+ }
+ },
"node_modules/@types/validate-npm-package-name": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/validate-npm-package-name/-/validate-npm-package-name-4.0.2.tgz",
"integrity": "sha512-lrpDziQipxCEeK5kWxvljWYhUvOiB2A9izZd9B2AFarYAkqZshb4lPbRs7zKEic6eGtH8V/2qJW+dPp9OtF6bw==",
"license": "MIT"
},
+ "node_modules/@types/webxr": {
+ "version": "0.5.24",
+ "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.24.tgz",
+ "integrity": "sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==",
+ "license": "MIT"
+ },
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.57.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.57.0.tgz",
@@ -5907,6 +6077,24 @@
"win32"
]
},
+ "node_modules/@use-gesture/core": {
+ "version": "10.3.1",
+ "resolved": "https://registry.npmjs.org/@use-gesture/core/-/core-10.3.1.tgz",
+ "integrity": "sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw==",
+ "license": "MIT"
+ },
+ "node_modules/@use-gesture/react": {
+ "version": "10.3.1",
+ "resolved": "https://registry.npmjs.org/@use-gesture/react/-/react-10.3.1.tgz",
+ "integrity": "sha512-Yy19y6O2GJq8f7CHf7L0nxL8bf4PZCPaVOCgJrusOeFHY1LvHgYXnmnXg6N5iwAnbgbZCDjo60SiM6IPJi9C5g==",
+ "license": "MIT",
+ "dependencies": {
+ "@use-gesture/core": "10.3.1"
+ },
+ "peerDependencies": {
+ "react": ">= 16.8.0"
+ }
+ },
"node_modules/@vitejs/plugin-react": {
"version": "5.1.4",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.4.tgz",
@@ -6039,6 +6227,12 @@
"url": "https://opencollective.com/vitest"
}
},
+ "node_modules/@webgpu/types": {
+ "version": "0.1.69",
+ "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.69.tgz",
+ "integrity": "sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ==",
+ "license": "BSD-3-Clause"
+ },
"node_modules/accepts": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
@@ -6480,6 +6674,26 @@
"dev": true,
"license": "MIT"
},
+ "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"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/baseline-browser-mapping": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz",
@@ -6496,7 +6710,6 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz",
"integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==",
- "dev": true,
"license": "MIT",
"dependencies": {
"require-from-string": "^2.0.2"
@@ -6582,6 +6795,30 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
+ "node_modules/buffer": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.2.1"
+ }
+ },
"node_modules/bundle-name": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz",
@@ -6663,6 +6900,19 @@
"node": ">=6"
}
},
+ "node_modules/camera-controls": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/camera-controls/-/camera-controls-3.1.2.tgz",
+ "integrity": "sha512-xkxfpG2ECZ6Ww5/9+kf4mfg1VEYAoe9aDSY+IwF0UEs7qEzwy0aVRfs2grImIECs/PoBtWFrh7RXsQkwG922JA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=22.0.0",
+ "npm": ">=10.5.1"
+ },
+ "peerDependencies": {
+ "three": ">=0.126.1"
+ }
+ },
"node_modules/caniuse-lite": {
"version": "1.0.30001777",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001777.tgz",
@@ -6965,6 +7215,24 @@
}
}
},
+ "node_modules/cross-env": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
+ "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==",
+ "license": "MIT",
+ "dependencies": {
+ "cross-spawn": "^7.0.1"
+ },
+ "bin": {
+ "cross-env": "src/bin/cross-env.js",
+ "cross-env-shell": "src/bin/cross-env-shell.js"
+ },
+ "engines": {
+ "node": ">=10.14",
+ "npm": ">=6",
+ "yarn": ">=1"
+ }
+ },
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -7042,7 +7310,6 @@
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
- "devOptional": true,
"license": "MIT"
},
"node_modules/damerau-levenshtein": {
@@ -7279,6 +7546,15 @@
"node": ">=6"
}
},
+ "node_modules/detect-gpu": {
+ "version": "5.0.70",
+ "resolved": "https://registry.npmjs.org/detect-gpu/-/detect-gpu-5.0.70.tgz",
+ "integrity": "sha512-bqerEP1Ese6nt3rFkwPnGbsUF9a4q+gMmpTVVOEzoCyeCc+y7/RvJnQZJx1JwhgQI5Ntg0Kgat8Uu7XpBqnz1w==",
+ "license": "MIT",
+ "dependencies": {
+ "webgl-constants": "^1.1.1"
+ }
+ },
"node_modules/detect-libc": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
@@ -7337,6 +7613,12 @@
"url": "https://dotenvx.com"
}
},
+ "node_modules/draco3d": {
+ "version": "1.5.7",
+ "resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.5.7.tgz",
+ "integrity": "sha512-m6WCKt/erDXcw+70IJXnG7M3awwQPAsZvJGX5zY7beBqpELw6RDGkYVU0W43AFxye4pDZ5i2Lbyc/NNGqwjUVQ==",
+ "license": "Apache-2.0"
+ },
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
@@ -8371,6 +8653,12 @@
"node": "^12.20 || >= 14.13"
}
},
+ "node_modules/fflate": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
+ "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==",
+ "license": "MIT"
+ },
"node_modules/figures": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz",
@@ -8826,6 +9114,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/glsl-noise": {
+ "version": "0.0.0",
+ "resolved": "https://registry.npmjs.org/glsl-noise/-/glsl-noise-0.0.0.tgz",
+ "integrity": "sha512-b/ZCF6amfAUb7dJM/MxRs7AetQEahYzJ8PtgfrmEdtw6uyGOr+ZSGtgjFm6mfsBkxJ4d2W7kg+Nlqzqvn3Bc0w==",
+ "license": "MIT"
+ },
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
@@ -8968,6 +9262,12 @@
"hermes-estree": "0.25.1"
}
},
+ "node_modules/hls.js": {
+ "version": "1.6.15",
+ "resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.6.15.tgz",
+ "integrity": "sha512-E3a5VwgXimGHwpRGV+WxRTKeSp2DW5DI5MWv34ulL3t5UNmyJWCQ1KmLEHbYzcfThfXG8amBL+fCYPneGHC4VA==",
+ "license": "Apache-2.0"
+ },
"node_modules/hono": {
"version": "4.12.7",
"resolved": "https://registry.npmjs.org/hono/-/hono-4.12.7.tgz",
@@ -9062,6 +9362,26 @@
"url": "https://opencollective.com/express"
}
},
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
"node_modules/ignore": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
@@ -9071,6 +9391,12 @@
"node": ">= 4"
}
},
+ "node_modules/immediate": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
+ "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
+ "license": "MIT"
+ },
"node_modules/import-fresh": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
@@ -9755,6 +10081,18 @@
"node": ">= 0.4"
}
},
+ "node_modules/its-fine": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/its-fine/-/its-fine-2.0.0.tgz",
+ "integrity": "sha512-KLViCmWx94zOvpLwSlsx6yOCeMhZYaxrJV87Po5k/FoZzcPSahvK5qJ7fYhS61sZi5ikmh2S3Hz55A2l3U69ng==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/react-reconciler": "^0.28.9"
+ },
+ "peerDependencies": {
+ "react": "^19.0.0"
+ }
+ },
"node_modules/jiti": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
@@ -9971,6 +10309,15 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/lie": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
+ "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
+ "license": "MIT",
+ "dependencies": {
+ "immediate": "~3.0.5"
+ }
+ },
"node_modules/lightningcss": {
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz",
@@ -10344,6 +10691,16 @@
"lz-string": "bin/bin.js"
}
},
+ "node_modules/maath": {
+ "version": "0.10.8",
+ "resolved": "https://registry.npmjs.org/maath/-/maath-0.10.8.tgz",
+ "integrity": "sha512-tRvbDF0Pgqz+9XUa4jjfgAQ8/aPKmQdWXilFu2tMy4GWj4NOsx99HlULO4IeREfbO3a0sA145DZYyvXPkybm0g==",
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/three": ">=0.134.0",
+ "three": ">=0.134.0"
+ }
+ },
"node_modules/magic-string": {
"version": "0.30.21",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
@@ -10406,6 +10763,21 @@
"node": ">= 8"
}
},
+ "node_modules/meshline": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/meshline/-/meshline-3.3.1.tgz",
+ "integrity": "sha512-/TQj+JdZkeSUOl5Mk2J7eLcYTLiQm2IDzmlSvYm7ov15anEcDJ92GHqqazxTSreeNgfnYu24kiEvvv0WlbCdFQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "three": ">=0.137"
+ }
+ },
+ "node_modules/meshoptimizer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-1.0.1.tgz",
+ "integrity": "sha512-Vix+QlA1YYT3FwmBBZ+49cE5y/b+pRrcXKqGpS5ouh33d3lSp2PoTpCw19E0cKDFWalembrHnIaZetf27a+W2g==",
+ "license": "MIT"
+ },
"node_modules/micromatch": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
@@ -10713,6 +11085,16 @@
}
}
},
+ "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==",
+ "license": "MIT",
+ "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/postcss": {
"version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
@@ -11338,6 +11720,12 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/potpack": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/potpack/-/potpack-1.0.2.tgz",
+ "integrity": "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==",
+ "license": "ISC"
+ },
"node_modules/powershell-utils": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/powershell-utils/-/powershell-utils-0.1.0.tgz",
@@ -11413,6 +11801,22 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/promise-worker-transferable": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/promise-worker-transferable/-/promise-worker-transferable-1.0.4.tgz",
+ "integrity": "sha512-bN+0ehEnrXfxV2ZQvU2PetO0n4gqBD4ulq3MI1WOPLgr7/Mg9yRQkX5+0v1vagr74ZTsl7XtzlaYDo2EuCeYJw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "is-promise": "^2.1.0",
+ "lie": "^3.0.2"
+ }
+ },
+ "node_modules/promise-worker-transferable/node_modules/is-promise": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
+ "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==",
+ "license": "MIT"
+ },
"node_modules/prompts": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
@@ -11731,6 +12135,21 @@
}
}
},
+ "node_modules/react-use-measure": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.7.tgz",
+ "integrity": "sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": ">=16.13",
+ "react-dom": ">=16.13"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/recast": {
"version": "0.23.11",
"resolved": "https://registry.npmjs.org/recast/-/recast-0.23.11.tgz",
@@ -12495,6 +12914,32 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/stats-gl": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/stats-gl/-/stats-gl-2.4.2.tgz",
+ "integrity": "sha512-g5O9B0hm9CvnM36+v7SFl39T7hmAlv541tU81ME8YeSb3i1CIP5/QdDeSB3A0la0bKNHpxpwxOVRo2wFTYEosQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/three": "*",
+ "three": "^0.170.0"
+ },
+ "peerDependencies": {
+ "@types/three": "*",
+ "three": "*"
+ }
+ },
+ "node_modules/stats-gl/node_modules/three": {
+ "version": "0.170.0",
+ "resolved": "https://registry.npmjs.org/three/-/three-0.170.0.tgz",
+ "integrity": "sha512-FQK+LEpYc0fBD+J8g6oSEyyNzjp+Q7Ks1C568WWaoMRLW+TkNNWmenWeGgJjV105Gd+p/2ql1ZcjYvNiPZBhuQ==",
+ "license": "MIT"
+ },
+ "node_modules/stats.js": {
+ "version": "0.17.0",
+ "resolved": "https://registry.npmjs.org/stats.js/-/stats.js-0.17.0.tgz",
+ "integrity": "sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==",
+ "license": "MIT"
+ },
"node_modules/statuses": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
@@ -12819,6 +13264,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/suspend-react": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/suspend-react/-/suspend-react-0.1.3.tgz",
+ "integrity": "sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": ">=17.0"
+ }
+ },
"node_modules/symbol-tree": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
@@ -12869,6 +13323,44 @@
"url": "https://opencollective.com/webpack"
}
},
+ "node_modules/three": {
+ "version": "0.183.2",
+ "resolved": "https://registry.npmjs.org/three/-/three-0.183.2.tgz",
+ "integrity": "sha512-di3BsL2FEQ1PA7Hcvn4fyJOlxRRgFYBpMTcyOgkwJIaDOdJMebEFPA+t98EvjuljDx4hNulAGwF6KIjtwI5jgQ==",
+ "license": "MIT"
+ },
+ "node_modules/three-mesh-bvh": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/three-mesh-bvh/-/three-mesh-bvh-0.8.3.tgz",
+ "integrity": "sha512-4G5lBaF+g2auKX3P0yqx+MJC6oVt6sB5k+CchS6Ob0qvH0YIhuUk1eYr7ktsIpY+albCqE80/FVQGV190PmiAg==",
+ "license": "MIT",
+ "peerDependencies": {
+ "three": ">= 0.159.0"
+ }
+ },
+ "node_modules/three-stdlib": {
+ "version": "2.36.1",
+ "resolved": "https://registry.npmjs.org/three-stdlib/-/three-stdlib-2.36.1.tgz",
+ "integrity": "sha512-XyGQrFmNQ5O/IoKm556ftwKsBg11TIb301MB5dWNicziQBEs2g3gtOYIf7pFiLa0zI2gUwhtCjv9fmjnxKZ1Cg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/draco3d": "^1.4.0",
+ "@types/offscreencanvas": "^2019.6.4",
+ "@types/webxr": "^0.5.2",
+ "draco3d": "^1.4.1",
+ "fflate": "^0.6.9",
+ "potpack": "^1.0.1"
+ },
+ "peerDependencies": {
+ "three": ">=0.128.0"
+ }
+ },
+ "node_modules/three-stdlib/node_modules/fflate": {
+ "version": "0.6.10",
+ "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz",
+ "integrity": "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==",
+ "license": "MIT"
+ },
"node_modules/tiny-invariant": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz",
@@ -13013,6 +13505,36 @@
"node": ">=20"
}
},
+ "node_modules/troika-three-text": {
+ "version": "0.52.4",
+ "resolved": "https://registry.npmjs.org/troika-three-text/-/troika-three-text-0.52.4.tgz",
+ "integrity": "sha512-V50EwcYGruV5rUZ9F4aNsrytGdKcXKALjEtQXIOBfhVoZU9VAqZNIoGQ3TMiooVqFAbR1w15T+f+8gkzoFzawg==",
+ "license": "MIT",
+ "dependencies": {
+ "bidi-js": "^1.0.2",
+ "troika-three-utils": "^0.52.4",
+ "troika-worker-utils": "^0.52.0",
+ "webgl-sdf-generator": "1.1.1"
+ },
+ "peerDependencies": {
+ "three": ">=0.125.0"
+ }
+ },
+ "node_modules/troika-three-utils": {
+ "version": "0.52.4",
+ "resolved": "https://registry.npmjs.org/troika-three-utils/-/troika-three-utils-0.52.4.tgz",
+ "integrity": "sha512-NORAStSVa/BDiG52Mfudk4j1FG4jC4ILutB3foPnfGbOeIs9+G5vZLa0pnmnaftZUGm4UwSoqEpWdqvC7zms3A==",
+ "license": "MIT",
+ "peerDependencies": {
+ "three": ">=0.125.0"
+ }
+ },
+ "node_modules/troika-worker-utils": {
+ "version": "0.52.0",
+ "resolved": "https://registry.npmjs.org/troika-worker-utils/-/troika-worker-utils-0.52.0.tgz",
+ "integrity": "sha512-W1CpvTHykaPH5brv5VHLfQo9D1OYuo0cSBEUQFFT/nBUzM8iD6Lq2/tgG/f1OelbAS1WtaTPQzE5uM49egnngw==",
+ "license": "MIT"
+ },
"node_modules/ts-api-utils": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.4.0.tgz",
@@ -13068,6 +13590,43 @@
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD"
},
+ "node_modules/tunnel-rat": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/tunnel-rat/-/tunnel-rat-0.1.2.tgz",
+ "integrity": "sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ==",
+ "license": "MIT",
+ "dependencies": {
+ "zustand": "^4.3.2"
+ }
+ },
+ "node_modules/tunnel-rat/node_modules/zustand": {
+ "version": "4.5.7",
+ "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz",
+ "integrity": "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==",
+ "license": "MIT",
+ "dependencies": {
+ "use-sync-external-store": "^1.2.2"
+ },
+ "engines": {
+ "node": ">=12.7.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=16.8",
+ "immer": ">=9.0.6",
+ "react": ">=16.8"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "immer": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/tw-animate-css": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.4.0.tgz",
@@ -13443,6 +14002,15 @@
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
"license": "MIT"
},
+ "node_modules/utility-types": {
+ "version": "3.11.0",
+ "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz",
+ "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
"node_modules/validate-npm-package-name": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-7.0.2.tgz",
@@ -13680,6 +14248,17 @@
"node": ">= 8"
}
},
+ "node_modules/webgl-constants": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/webgl-constants/-/webgl-constants-1.1.1.tgz",
+ "integrity": "sha512-LkBXKjU5r9vAW7Gcu3T5u+5cvSvh5WwINdr0C+9jpzVB41cjQAP5ePArDtk/WHYdVj0GefCgM73BA7FlIiNtdg=="
+ },
+ "node_modules/webgl-sdf-generator": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/webgl-sdf-generator/-/webgl-sdf-generator-1.1.1.tgz",
+ "integrity": "sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA==",
+ "license": "MIT"
+ },
"node_modules/webidl-conversions": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index 1f9aa45..59af528 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -24,14 +24,20 @@
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-slot": "^1.2.4",
"@radix-ui/react-toast": "^1.2.15",
+ "@react-three/drei": "^10.7.7",
+ "@react-three/fiber": "^9.5.0",
"@tanstack/react-query": "^5.90.21",
+ "@types/three": "^0.183.1",
"class-variance-authority": "^0.7.1",
"motion": "^12.36.0",
"next": "16.1.6",
+ "next-themes": "^0.4.6",
"radix-ui": "^1.4.3",
"react": "19.2.3",
"react-dom": "19.2.3",
"shadcn": "^4.0.6",
+ "three": "^0.183.2",
+ "three-stdlib": "^2.36.1",
"tw-animate-css": "^1.4.0",
"zustand": "^5.0.11"
},