enh
This commit is contained in:
parent
97fe8bce64
commit
ca8297af9b
11 changed files with 1812 additions and 6 deletions
570
apps/fallback-ui/src/components/3d/Characters.tsx
Normal file
570
apps/fallback-ui/src/components/3d/Characters.tsx
Normal file
|
|
@ -0,0 +1,570 @@
|
|||
import { useRef, useEffect, useMemo } from 'react';
|
||||
import { useFrame } from '@react-three/fiber';
|
||||
import * as THREE from 'three';
|
||||
|
||||
interface CharacterProps {
|
||||
color: string;
|
||||
isCelebrating: boolean;
|
||||
delay?: number;
|
||||
type: 'flag' | 'flipper' | 'dancer';
|
||||
hairColor?: string;
|
||||
skinTone?: string;
|
||||
holdsFlag?: boolean;
|
||||
index: number;
|
||||
}
|
||||
|
||||
function Character({ color, isCelebrating, delay = 0, type, hairColor = '#2D1B0E', skinTone = '#F5DEB3', holdsFlag = false, index }: CharacterProps) {
|
||||
const groupRef = useRef<THREE.Group>(null);
|
||||
const flagRef = useRef<THREE.Mesh>(null);
|
||||
const leftArmRef = useRef<THREE.Group>(null);
|
||||
const rightArmRef = useRef<THREE.Group>(null);
|
||||
const startTimeRef = useRef<number | null>(null);
|
||||
|
||||
// Create flag texture
|
||||
const flagTexture = useMemo(() => {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = 512;
|
||||
canvas.height = 256;
|
||||
const ctx = canvas.getContext('2d')!;
|
||||
|
||||
// Gradient background - Brand blue colors
|
||||
const gradient = ctx.createLinearGradient(0, 0, 512, 0);
|
||||
gradient.addColorStop(0, '#2E90FA');
|
||||
gradient.addColorStop(1, '#84CAFF');
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.fillRect(0, 0, 512, 256);
|
||||
|
||||
// Add text
|
||||
ctx.fillStyle = '#FFFFFF';
|
||||
ctx.font = 'bold 40px Arial';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.textBaseline = 'middle';
|
||||
ctx.fillText('Freshyo for', 256, 100);
|
||||
ctx.fillText('mahabubnagar', 256, 160);
|
||||
|
||||
// Add decorative border
|
||||
ctx.strokeStyle = '#FFFFFF';
|
||||
ctx.lineWidth = 4;
|
||||
ctx.strokeRect(10, 10, 492, 236);
|
||||
|
||||
const texture = new THREE.TextureLoader().load(canvas.toDataURL());
|
||||
return texture;
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (isCelebrating && startTimeRef.current === null) {
|
||||
startTimeRef.current = Date.now() + delay;
|
||||
}
|
||||
}, [isCelebrating, delay]);
|
||||
|
||||
useFrame((state) => {
|
||||
if (!groupRef.current) return;
|
||||
|
||||
const time = state.clock.getElapsedTime();
|
||||
const currentTime = Date.now();
|
||||
|
||||
if (isCelebrating && startTimeRef.current && currentTime > startTimeRef.current) {
|
||||
const elapsed = (currentTime - startTimeRef.current) / 1000;
|
||||
|
||||
if (type === 'flag') {
|
||||
// FLAG BEARER - Runs around in circles waving the flag
|
||||
const runRadius = 2.5;
|
||||
const runSpeed = 1.5;
|
||||
const angle = elapsed * runSpeed;
|
||||
|
||||
// Circular running path
|
||||
const x = Math.cos(angle) * runRadius;
|
||||
const z = Math.sin(angle) * runRadius;
|
||||
|
||||
// Add some bounce while running
|
||||
const bounce = Math.abs(Math.sin(elapsed * 8)) * 0.15;
|
||||
|
||||
groupRef.current.position.set(x, bounce, z);
|
||||
|
||||
// Face the running direction
|
||||
groupRef.current.rotation.y = -angle + Math.PI / 2;
|
||||
|
||||
// Slight body tilt while running
|
||||
groupRef.current.rotation.z = Math.sin(elapsed * 8) * 0.1;
|
||||
|
||||
} else if (type === 'flipper') {
|
||||
// FLIPPER - Runs in figure-8 pattern while flipping
|
||||
const runSpeed = 2;
|
||||
const t = elapsed * runSpeed;
|
||||
|
||||
// Figure-8 path
|
||||
const x = Math.sin(t) * 2.5;
|
||||
const z = Math.sin(t * 2) * 1.5;
|
||||
|
||||
// Jump and flip
|
||||
const jumpCycle = (elapsed * 2.5) % 1;
|
||||
const jumpHeight = Math.abs(Math.sin(jumpCycle * Math.PI)) * 2;
|
||||
|
||||
groupRef.current.position.set(x, jumpHeight, z);
|
||||
|
||||
// Flip rotation
|
||||
groupRef.current.rotation.x = jumpCycle * Math.PI * 2;
|
||||
groupRef.current.rotation.y = t * 0.5;
|
||||
|
||||
} else if (type === 'dancer') {
|
||||
// DANCER - Moves in larger oval pattern with spins and flips
|
||||
const runSpeed = 1.8;
|
||||
const t = elapsed * runSpeed;
|
||||
|
||||
// Large oval path
|
||||
const x = Math.cos(t) * 3.5;
|
||||
const z = Math.sin(t * 1.5) * 2;
|
||||
|
||||
// Jump and flip
|
||||
const jumpCycle = (elapsed * 2) % 1;
|
||||
const jumpHeight = Math.abs(Math.sin(jumpCycle * Math.PI)) * 2.2;
|
||||
|
||||
groupRef.current.position.set(x, jumpHeight, z);
|
||||
|
||||
// Flip with extra spinning
|
||||
groupRef.current.rotation.x = jumpCycle * Math.PI * 2;
|
||||
groupRef.current.rotation.y = t + Math.sin(elapsed * 3) * 0.5;
|
||||
groupRef.current.rotation.z = Math.sin(elapsed * 4) * 0.3;
|
||||
}
|
||||
} else {
|
||||
// Idle positions
|
||||
const idleTime = time * 2;
|
||||
|
||||
if (type === 'flag') {
|
||||
// Center position
|
||||
groupRef.current.position.set(0, Math.sin(idleTime) * 0.05, 0);
|
||||
groupRef.current.rotation.set(0, Math.sin(time * 0.5) * 0.2, 0);
|
||||
} else if (type === 'flipper') {
|
||||
// Left position
|
||||
groupRef.current.position.set(-2, Math.sin(idleTime + 1) * 0.05, 0.5);
|
||||
groupRef.current.rotation.set(0, 0, 0);
|
||||
} else if (type === 'dancer') {
|
||||
// Right position
|
||||
groupRef.current.position.set(2, Math.sin(idleTime + 2) * 0.05, -0.5);
|
||||
groupRef.current.rotation.set(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Animate flag waving
|
||||
if (flagRef.current && holdsFlag) {
|
||||
const waveIntensity = isCelebrating ? 0.4 : 0.15;
|
||||
flagRef.current.rotation.y = Math.sin(time * 4) * waveIntensity;
|
||||
flagRef.current.rotation.z = Math.sin(time * 3) * 0.08;
|
||||
}
|
||||
|
||||
// Animate arms based on character type and celebration state
|
||||
if (leftArmRef.current && rightArmRef.current) {
|
||||
if (isCelebrating && startTimeRef.current && currentTime > startTimeRef.current) {
|
||||
const elapsed = (currentTime - startTimeRef.current) / 1000;
|
||||
|
||||
if (type === 'flipper' || type === 'dancer') {
|
||||
// Arms point STRAIGHT DOWN by their sides during flip
|
||||
// Left arm
|
||||
leftArmRef.current.rotation.set(Math.PI / 2, 0, -0.1);
|
||||
// Right arm
|
||||
rightArmRef.current.rotation.set(Math.PI / 2, 0, 0.1);
|
||||
} else if (type === 'flag') {
|
||||
// Running arm swing - realistic running motion
|
||||
const swingSpeed = 8;
|
||||
const swingAmp = 0.7;
|
||||
|
||||
// Left arm swings forward when right leg is forward (opposite)
|
||||
leftArmRef.current.rotation.x = Math.sin(elapsed * swingSpeed) * swingAmp;
|
||||
leftArmRef.current.rotation.z = 0.15; // Slight outward angle
|
||||
|
||||
// Right arm opposite to left
|
||||
rightArmRef.current.rotation.x = Math.sin(elapsed * swingSpeed + Math.PI) * swingAmp;
|
||||
rightArmRef.current.rotation.z = -0.15; // Slight outward angle
|
||||
}
|
||||
} else {
|
||||
// Neutral arm position when idle - relaxed at sides, slightly bent
|
||||
leftArmRef.current.rotation.set(0.1, 0, 0.25);
|
||||
rightArmRef.current.rotation.set(0.1, 0, -0.25);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const shirtColor = color;
|
||||
const pantsColor = '#1a1a2e';
|
||||
const shoesColor = '#0f0f1a';
|
||||
|
||||
return (
|
||||
<group ref={groupRef}>
|
||||
{/* SHADOW - follows the character */}
|
||||
<mesh position={[0, 0.02, 0]} rotation={[-Math.PI / 2, 0, 0]}>
|
||||
<circleGeometry args={[0.5, 32]} />
|
||||
<meshBasicMaterial color="#000000" transparent opacity={0.15} />
|
||||
</mesh>
|
||||
|
||||
{/* LEGS */}
|
||||
<group position={[0, 0.35, 0]}>
|
||||
{/* Left Leg */}
|
||||
<mesh position={[-0.12, 0, 0]}>
|
||||
<capsuleGeometry args={[0.09, 0.45, 8, 16]} />
|
||||
<meshStandardMaterial color={pantsColor} roughness={0.6} />
|
||||
</mesh>
|
||||
{/* Right Leg */}
|
||||
<mesh position={[0.12, 0, 0]}>
|
||||
<capsuleGeometry args={[0.09, 0.45, 8, 16]} />
|
||||
<meshStandardMaterial color={pantsColor} roughness={0.6} />
|
||||
</mesh>
|
||||
</group>
|
||||
|
||||
{/* SHOES */}
|
||||
<group position={[0, 0.12, 0.05]}>
|
||||
<mesh position={[-0.12, 0, 0]}>
|
||||
<boxGeometry args={[0.14, 0.1, 0.22]} />
|
||||
<meshStandardMaterial color={shoesColor} roughness={0.5} />
|
||||
</mesh>
|
||||
<mesh position={[0.12, 0, 0]}>
|
||||
<boxGeometry args={[0.14, 0.1, 0.22]} />
|
||||
<meshStandardMaterial color={shoesColor} roughness={0.5} />
|
||||
</mesh>
|
||||
</group>
|
||||
|
||||
{/* TORSO - slightly more rounded */}
|
||||
<mesh position={[0, 0.75, 0]}>
|
||||
<boxGeometry args={[0.38, 0.55, 0.28]} />
|
||||
<meshStandardMaterial color={shirtColor} roughness={0.4} />
|
||||
</mesh>
|
||||
|
||||
{/* LEFT ARM GROUP - Shoulder, upper arm, elbow, lower arm, wrist, hand */}
|
||||
<group
|
||||
ref={leftArmRef}
|
||||
position={[-0.22, 0.98, 0]} // Shoulder position
|
||||
>
|
||||
{/* Upper arm segment */}
|
||||
<mesh position={[0, -0.18, 0]}>
|
||||
<capsuleGeometry args={[0.065, 0.28, 8, 16]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.4} />
|
||||
</mesh>
|
||||
|
||||
{/* Elbow joint */}
|
||||
<mesh position={[0, -0.34, 0]}>
|
||||
<sphereGeometry args={[0.07, 12, 12]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.4} />
|
||||
</mesh>
|
||||
|
||||
{/* Lower arm segment */}
|
||||
<mesh position={[0, -0.48, 0]}>
|
||||
<capsuleGeometry args={[0.06, 0.24, 8, 16]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.4} />
|
||||
</mesh>
|
||||
|
||||
{/* Wrist */}
|
||||
<mesh position={[0, -0.62, 0]}>
|
||||
<cylinderGeometry args={[0.055, 0.05, 0.08, 12]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.4} />
|
||||
</mesh>
|
||||
|
||||
{/* HAND - more realistic palm and fingers */}
|
||||
<group position={[0, -0.72, 0]}>
|
||||
{/* Palm */}
|
||||
<mesh>
|
||||
<boxGeometry args={[0.12, 0.1, 0.08]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.4} />
|
||||
</mesh>
|
||||
|
||||
{/* Fingers - 4 fingers */}
|
||||
<group>
|
||||
{/* Index finger */}
|
||||
<mesh position={[-0.04, -0.08, 0.02]}>
|
||||
<capsuleGeometry args={[0.018, 0.12, 6, 12]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.4} />
|
||||
</mesh>
|
||||
{/* Middle finger */}
|
||||
<mesh position={[0, -0.09, 0.02]}>
|
||||
<capsuleGeometry args={[0.018, 0.13, 6, 12]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.4} />
|
||||
</mesh>
|
||||
{/* Ring finger */}
|
||||
<mesh position={[0.04, -0.08, 0.02]}>
|
||||
<capsuleGeometry args={[0.018, 0.12, 6, 12]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.4} />
|
||||
</mesh>
|
||||
{/* Pinky */}
|
||||
<mesh position={[0.07, -0.06, 0.02]}>
|
||||
<capsuleGeometry args={[0.015, 0.09, 6, 12]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.4} />
|
||||
</mesh>
|
||||
</group>
|
||||
|
||||
{/* Thumb */}
|
||||
<mesh position={[-0.07, -0.03, 0.03]} rotation={[0, 0, -0.5]}>
|
||||
<capsuleGeometry args={[0.02, 0.08, 6, 12]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.4} />
|
||||
</mesh>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
{/* RIGHT ARM GROUP - Shoulder, upper arm, elbow, lower arm, wrist, hand */}
|
||||
<group
|
||||
ref={rightArmRef}
|
||||
position={[0.22, 0.98, 0]} // Shoulder position
|
||||
>
|
||||
{/* Upper arm segment */}
|
||||
<mesh position={[0, -0.18, 0]}>
|
||||
<capsuleGeometry args={[0.065, 0.28, 8, 16]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.4} />
|
||||
</mesh>
|
||||
|
||||
{/* Elbow joint */}
|
||||
<mesh position={[0, -0.34, 0]}>
|
||||
<sphereGeometry args={[0.07, 12, 12]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.4} />
|
||||
</mesh>
|
||||
|
||||
{/* Lower arm segment */}
|
||||
<mesh position={[0, -0.48, 0]}>
|
||||
<capsuleGeometry args={[0.06, 0.24, 8, 16]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.4} />
|
||||
</mesh>
|
||||
|
||||
{/* Wrist */}
|
||||
<mesh position={[0, -0.62, 0]}>
|
||||
<cylinderGeometry args={[0.055, 0.05, 0.08, 12]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.4} />
|
||||
</mesh>
|
||||
|
||||
{/* HAND - more realistic palm and fingers */}
|
||||
<group position={[0, -0.72, 0]}>
|
||||
{/* Palm */}
|
||||
<mesh>
|
||||
<boxGeometry args={[0.12, 0.1, 0.08]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.4} />
|
||||
</mesh>
|
||||
|
||||
{/* Fingers - 4 fingers */}
|
||||
<group>
|
||||
{/* Index finger */}
|
||||
<mesh position={[0.04, -0.08, 0.02]}>
|
||||
<capsuleGeometry args={[0.018, 0.12, 6, 12]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.4} />
|
||||
</mesh>
|
||||
{/* Middle finger */}
|
||||
<mesh position={[0, -0.09, 0.02]}>
|
||||
<capsuleGeometry args={[0.018, 0.13, 6, 12]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.4} />
|
||||
</mesh>
|
||||
{/* Ring finger */}
|
||||
<mesh position={[-0.04, -0.08, 0.02]}>
|
||||
<capsuleGeometry args={[0.018, 0.12, 6, 12]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.4} />
|
||||
</mesh>
|
||||
{/* Pinky */}
|
||||
<mesh position={[-0.07, -0.06, 0.02]}>
|
||||
<capsuleGeometry args={[0.015, 0.09, 6, 12]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.4} />
|
||||
</mesh>
|
||||
</group>
|
||||
|
||||
{/* Thumb */}
|
||||
<mesh position={[0.07, -0.03, 0.03]} rotation={[0, 0, 0.5]}>
|
||||
<capsuleGeometry args={[0.02, 0.08, 6, 12]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.4} />
|
||||
</mesh>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
{/* NECK */}
|
||||
<mesh position={[0, 1.08, 0]}>
|
||||
<cylinderGeometry args={[0.07, 0.08, 0.12, 16]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.4} />
|
||||
</mesh>
|
||||
|
||||
{/* HEAD GROUP */}
|
||||
<group position={[0, 1.35, 0]}>
|
||||
{/* Main head - slightly oval for human shape */}
|
||||
<mesh scale={[0.95, 1.05, 0.9]}>
|
||||
<sphereGeometry args={[0.28, 32, 32]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.3} />
|
||||
</mesh>
|
||||
|
||||
{/* EARS */}
|
||||
<group>
|
||||
{/* Left Ear */}
|
||||
<mesh position={[-0.26, 0, 0]} rotation={[0, 0, -0.2]}>
|
||||
<cylinderGeometry args={[0.06, 0.05, 0.12, 16]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.4} />
|
||||
</mesh>
|
||||
{/* Right Ear */}
|
||||
<mesh position={[0.26, 0, 0]} rotation={[0, 0, 0.2]}>
|
||||
<cylinderGeometry args={[0.06, 0.05, 0.12, 16]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.4} />
|
||||
</mesh>
|
||||
</group>
|
||||
|
||||
{/* HAIR - Better styled hair */}
|
||||
<group>
|
||||
{/* Top hair */}
|
||||
<mesh position={[0, 0.25, 0]} scale={[1, 0.6, 1]}>
|
||||
<sphereGeometry args={[0.26, 32, 32]} />
|
||||
<meshStandardMaterial color={hairColor} roughness={0.7} />
|
||||
</mesh>
|
||||
{/* Side hair left */}
|
||||
<mesh position={[-0.22, 0.15, 0]} scale={[0.4, 0.8, 0.6]}>
|
||||
<sphereGeometry args={[0.15, 16, 16]} />
|
||||
<meshStandardMaterial color={hairColor} roughness={0.7} />
|
||||
</mesh>
|
||||
{/* Side hair right */}
|
||||
<mesh position={[0.22, 0.15, 0]} scale={[0.4, 0.8, 0.6]}>
|
||||
<sphereGeometry args={[0.15, 16, 16]} />
|
||||
<meshStandardMaterial color={hairColor} roughness={0.7} />
|
||||
</mesh>
|
||||
{/* Front hair tuft */}
|
||||
<mesh position={[0, 0.28, 0.15]} rotation={[0.5, 0, 0]}>
|
||||
<capsuleGeometry args={[0.04, 0.15, 8, 16]} />
|
||||
<meshStandardMaterial color={hairColor} roughness={0.7} />
|
||||
</mesh>
|
||||
</group>
|
||||
|
||||
{/* FACE FEATURES */}
|
||||
<group position={[0, 0, 0.22]}>
|
||||
{/* EYEBROWS */}
|
||||
<mesh position={[-0.1, 0.12, 0]}>
|
||||
<capsuleGeometry args={[0.015, 0.08, 8, 16]} />
|
||||
<meshStandardMaterial color={hairColor} roughness={0.6} />
|
||||
</mesh>
|
||||
<mesh position={[0.1, 0.12, 0]}>
|
||||
<capsuleGeometry args={[0.015, 0.08, 8, 16]} />
|
||||
<meshStandardMaterial color={hairColor} roughness={0.6} />
|
||||
</mesh>
|
||||
|
||||
{/* EYES - Anime style */}
|
||||
{/* Left Eye */}
|
||||
<group position={[-0.1, 0.02, 0]}>
|
||||
{/* Eye white */}
|
||||
<mesh scale={[1, 1.3, 0.5]}>
|
||||
<sphereGeometry args={[0.07, 16, 16]} />
|
||||
<meshStandardMaterial color="white" roughness={0.2} />
|
||||
</mesh>
|
||||
{/* Iris */}
|
||||
<mesh position={[0, 0, 0.03]}>
|
||||
<sphereGeometry args={[0.045, 16, 16]} />
|
||||
<meshStandardMaterial color="#4B5563" roughness={0.1} />
|
||||
</mesh>
|
||||
{/* Pupil */}
|
||||
<mesh position={[0, 0, 0.05]}>
|
||||
<sphereGeometry args={[0.025, 16, 16]} />
|
||||
<meshStandardMaterial color="#1F2937" roughness={0} />
|
||||
</mesh>
|
||||
{/* Highlight */}
|
||||
<mesh position={[0.015, 0.015, 0.055]}>
|
||||
<sphereGeometry args={[0.012, 8, 8]} />
|
||||
<meshStandardMaterial color="white" roughness={0} />
|
||||
</mesh>
|
||||
</group>
|
||||
|
||||
{/* Right Eye */}
|
||||
<group position={[0.1, 0.02, 0]}>
|
||||
<mesh scale={[1, 1.3, 0.5]}>
|
||||
<sphereGeometry args={[0.07, 16, 16]} />
|
||||
<meshStandardMaterial color="white" roughness={0.2} />
|
||||
</mesh>
|
||||
<mesh position={[0, 0, 0.03]}>
|
||||
<sphereGeometry args={[0.045, 16, 16]} />
|
||||
<meshStandardMaterial color="#4B5563" roughness={0.1} />
|
||||
</mesh>
|
||||
<mesh position={[0, 0, 0.05]}>
|
||||
<sphereGeometry args={[0.025, 16, 16]} />
|
||||
<meshStandardMaterial color="#1F2937" roughness={0} />
|
||||
</mesh>
|
||||
<mesh position={[0.015, 0.015, 0.055]}>
|
||||
<sphereGeometry args={[0.012, 8, 8]} />
|
||||
<meshStandardMaterial color="white" roughness={0} />
|
||||
</mesh>
|
||||
</group>
|
||||
|
||||
{/* NOSE - Small and cute */}
|
||||
<mesh position={[0, -0.05, 0.03]}>
|
||||
<sphereGeometry args={[0.02, 8, 8]} />
|
||||
<meshStandardMaterial color={skinTone} roughness={0.4} />
|
||||
</mesh>
|
||||
|
||||
{/* MOUTH - Smile */}
|
||||
<mesh position={[0, -0.12, 0.01]} rotation={[0, 0, 0]}>
|
||||
<torusGeometry args={[0.06, 0.015, 8, 16, Math.PI]} />
|
||||
<meshStandardMaterial color="#BE123C" roughness={0.3} />
|
||||
</mesh>
|
||||
</group>
|
||||
</group>
|
||||
|
||||
{/* FLAG - Held by this character */}
|
||||
{holdsFlag && (
|
||||
<group position={[0.45, 1.2, 0.1]} rotation={[0, 0, -0.3]}>
|
||||
{/* Flag Pole */}
|
||||
<mesh position={[0, 1.2, 0]}>
|
||||
<cylinderGeometry args={[0.02, 0.02, 2.8, 12]} />
|
||||
<meshStandardMaterial color="#5D4037" roughness={0.6} />
|
||||
</mesh>
|
||||
|
||||
{/* Pole Top */}
|
||||
<mesh position={[0, 2.5, 0]}>
|
||||
<sphereGeometry args={[0.05, 12, 12]} />
|
||||
<meshStandardMaterial color="#FFD700" roughness={0.3} metalness={0.6} />
|
||||
</mesh>
|
||||
|
||||
{/* Flag */}
|
||||
<mesh ref={flagRef} position={[0.9, 1.8, 0]}>
|
||||
<planeGeometry args={[1.8, 0.9, 8, 8]} />
|
||||
<meshStandardMaterial
|
||||
map={flagTexture}
|
||||
side={THREE.DoubleSide}
|
||||
transparent
|
||||
/>
|
||||
</mesh>
|
||||
</group>
|
||||
)}
|
||||
|
||||
{/* GLOW EFFECT */}
|
||||
<mesh position={[0, 0.9, 0]}>
|
||||
<sphereGeometry args={[1.2, 32, 32]} />
|
||||
<meshBasicMaterial color={color} transparent opacity={0.06} />
|
||||
</mesh>
|
||||
</group>
|
||||
);
|
||||
}
|
||||
|
||||
interface CharactersProps {
|
||||
isCelebrating: boolean;
|
||||
}
|
||||
|
||||
export default function Characters({ isCelebrating }: CharactersProps) {
|
||||
return (
|
||||
<group>
|
||||
{/* Character 1 - Flipper - Left side, does figure-8 while flipping */}
|
||||
<Character
|
||||
color="#53B1FD"
|
||||
isCelebrating={isCelebrating}
|
||||
delay={200}
|
||||
type="flipper"
|
||||
hairColor="#1C1917"
|
||||
skinTone="#E8D5C4"
|
||||
index={0}
|
||||
/>
|
||||
|
||||
{/* Character 2 - Flag Bearer - CENTER, runs in circles waving flag */}
|
||||
<Character
|
||||
color="#2E90FA"
|
||||
isCelebrating={isCelebrating}
|
||||
delay={0}
|
||||
type="flag"
|
||||
hairColor="#4A3728"
|
||||
skinTone="#F5DEB3"
|
||||
holdsFlag={true}
|
||||
index={1}
|
||||
/>
|
||||
|
||||
{/* Character 3 - Dancer - Right side, large oval pattern with flips */}
|
||||
<Character
|
||||
color="#84CAFF"
|
||||
isCelebrating={isCelebrating}
|
||||
delay={400}
|
||||
type="dancer"
|
||||
hairColor="#3D2914"
|
||||
skinTone="#F5E6D3"
|
||||
index={2}
|
||||
/>
|
||||
</group>
|
||||
);
|
||||
}
|
||||
75
apps/fallback-ui/src/components/3d/Flag.tsx
Normal file
75
apps/fallback-ui/src/components/3d/Flag.tsx
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
import { useRef, useMemo } from 'react';
|
||||
import { useFrame } from '@react-three/fiber';
|
||||
import { TextureLoader, DoubleSide, Mesh } from 'three';
|
||||
|
||||
export default function Flag({ isCelebrating }: { isCelebrating: boolean }) {
|
||||
const flagRef = useRef<Mesh>(null);
|
||||
const poleRef = useRef<Mesh>(null);
|
||||
|
||||
// Create flag texture with text
|
||||
const texture = useMemo(() => {
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = 512;
|
||||
canvas.height = 256;
|
||||
const ctx = canvas.getContext('2d')!;
|
||||
|
||||
// Gradient background - Brand blue colors
|
||||
const gradient = ctx.createLinearGradient(0, 0, 512, 0);
|
||||
gradient.addColorStop(0, '#2E90FA');
|
||||
gradient.addColorStop(1, '#84CAFF');
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.fillRect(0, 0, 512, 256);
|
||||
|
||||
// Add text
|
||||
ctx.fillStyle = '#FFFFFF';
|
||||
ctx.font = 'bold 40px Arial';
|
||||
ctx.textAlign = 'center';
|
||||
ctx.textBaseline = 'middle';
|
||||
ctx.fillText('Freshyo for', 256, 100);
|
||||
ctx.fillText('mahabubnagar', 256, 160);
|
||||
|
||||
// Add decorative border
|
||||
ctx.strokeStyle = '#FFFFFF';
|
||||
ctx.lineWidth = 4;
|
||||
ctx.strokeRect(10, 10, 492, 236);
|
||||
|
||||
const texture = new TextureLoader().load(canvas.toDataURL());
|
||||
return texture;
|
||||
}, []);
|
||||
|
||||
useFrame((state) => {
|
||||
if (flagRef.current) {
|
||||
const time = state.clock.getElapsedTime();
|
||||
// Wave animation
|
||||
const waveIntensity = isCelebrating ? 0.3 : 0.1;
|
||||
flagRef.current.rotation.y = Math.sin(time * 3) * waveIntensity;
|
||||
flagRef.current.rotation.z = Math.sin(time * 2) * 0.05;
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<group position={[-1.5, 2.5, 0]}>
|
||||
{/* Flag Pole */}
|
||||
<mesh ref={poleRef} position={[0, 0, 0]}>
|
||||
<cylinderGeometry args={[0.05, 0.05, 3, 16]} />
|
||||
<meshStandardMaterial color="#8B4513" />
|
||||
</mesh>
|
||||
|
||||
{/* Flag */}
|
||||
<mesh ref={flagRef} position={[1.5, 1, 0]}>
|
||||
<planeGeometry args={[3, 1.5, 10, 10]} />
|
||||
<meshStandardMaterial
|
||||
map={texture}
|
||||
side={DoubleSide}
|
||||
transparent
|
||||
/>
|
||||
</mesh>
|
||||
|
||||
{/* Pole Top */}
|
||||
<mesh position={[0, 1.6, 0]}>
|
||||
<sphereGeometry args={[0.1, 16, 16]} />
|
||||
<meshStandardMaterial color="#53B1FD" emissive="#1570EF" emissiveIntensity={0.5} />
|
||||
</mesh>
|
||||
</group>
|
||||
);
|
||||
}
|
||||
183
apps/fallback-ui/src/components/3d/Scene.tsx
Normal file
183
apps/fallback-ui/src/components/3d/Scene.tsx
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
import { useRef, useEffect } from 'react';
|
||||
import { Canvas, useFrame, useThree } from '@react-three/fiber';
|
||||
import { OrbitControls, Stars, Float } from '@react-three/drei';
|
||||
import * as THREE from 'three';
|
||||
import Characters from './Characters';
|
||||
|
||||
// Warm gradient background
|
||||
function WarmBackground() {
|
||||
const { scene } = useThree();
|
||||
|
||||
useEffect(() => {
|
||||
// Create gradient texture
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = 512;
|
||||
canvas.height = 512;
|
||||
const ctx = canvas.getContext('2d')!;
|
||||
|
||||
const gradient = ctx.createLinearGradient(0, 0, 0, 512);
|
||||
gradient.addColorStop(0, '#FFE5D4');
|
||||
gradient.addColorStop(0.5, '#FFB4A2');
|
||||
gradient.addColorStop(1, '#FF8E72');
|
||||
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.fillRect(0, 0, 512, 512);
|
||||
|
||||
const texture = new THREE.TextureLoader().load(canvas.toDataURL());
|
||||
scene.background = texture;
|
||||
}, [scene]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Ground plane with warm color
|
||||
function Ground() {
|
||||
const meshRef = useRef<THREE.Mesh>(null);
|
||||
|
||||
useFrame((state) => {
|
||||
if (meshRef.current) {
|
||||
// Subtle ground animation
|
||||
meshRef.current.rotation.x = -Math.PI / 2;
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<mesh ref={meshRef} position={[0, -0.1, 0]} receiveShadow>
|
||||
<planeGeometry args={[20, 20, 32, 32]} />
|
||||
<meshStandardMaterial
|
||||
color="#F5FAFF"
|
||||
roughness={0.8}
|
||||
metalness={0.1}
|
||||
/>
|
||||
</mesh>
|
||||
);
|
||||
}
|
||||
|
||||
// Floating particles for atmosphere
|
||||
function FloatingParticles({ isCelebrating }: { isCelebrating: boolean }) {
|
||||
const points = useRef<THREE.Points>(null);
|
||||
const particleCount = isCelebrating ? 200 : 50;
|
||||
|
||||
const positions = new Float32Array(particleCount * 3);
|
||||
for (let i = 0; i < particleCount; i++) {
|
||||
positions[i * 3] = (Math.random() - 0.5) * 15;
|
||||
positions[i * 3 + 1] = Math.random() * 8;
|
||||
positions[i * 3 + 2] = (Math.random() - 0.5) * 15;
|
||||
}
|
||||
|
||||
useFrame((state) => {
|
||||
if (points.current) {
|
||||
points.current.rotation.y = state.clock.getElapsedTime() * 0.05;
|
||||
if (isCelebrating) {
|
||||
points.current.rotation.y = state.clock.getElapsedTime() * 0.2;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<points ref={points}>
|
||||
<bufferGeometry>
|
||||
<bufferAttribute
|
||||
attach="attributes-position"
|
||||
args={[positions, 3]}
|
||||
/>
|
||||
</bufferGeometry>
|
||||
<pointsMaterial
|
||||
size={0.1}
|
||||
color={isCelebrating ? "#53B1FD" : "#84CAFF"}
|
||||
transparent
|
||||
opacity={0.8}
|
||||
sizeAttenuation
|
||||
/>
|
||||
</points>
|
||||
);
|
||||
}
|
||||
|
||||
// Blue lighting setup
|
||||
function Lighting() {
|
||||
return (
|
||||
<>
|
||||
<ambientLight intensity={0.6} color="#D1E9FF" />
|
||||
<directionalLight
|
||||
position={[5, 10, 5]}
|
||||
intensity={1.2}
|
||||
color="#53B1FD"
|
||||
castShadow
|
||||
shadow-mapSize={[2048, 2048]}
|
||||
/>
|
||||
<pointLight position={[-5, 5, -5]} intensity={0.8} color="#84CAFF" />
|
||||
<pointLight position={[5, 3, 5]} intensity={0.6} color="#2E90FA" />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
// Camera animation
|
||||
function CameraController({ isCelebrating }: { isCelebrating: boolean }) {
|
||||
const { camera } = useThree();
|
||||
|
||||
useFrame((state) => {
|
||||
const time = state.clock.getElapsedTime();
|
||||
|
||||
if (isCelebrating) {
|
||||
// Dramatic camera movement during celebration
|
||||
camera.position.x = Math.sin(time * 0.5) * 2;
|
||||
camera.position.y = 3 + Math.sin(time * 0.3) * 0.5;
|
||||
camera.position.z = 8 + Math.cos(time * 0.5) * 1;
|
||||
} else {
|
||||
// Gentle orbiting before celebration
|
||||
camera.position.x = Math.sin(time * 0.2) * 4;
|
||||
camera.position.z = 8 + Math.cos(time * 0.2) * 2;
|
||||
camera.position.y = 3;
|
||||
}
|
||||
|
||||
camera.lookAt(0, 1, 0);
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
interface SceneProps {
|
||||
isCelebrating: boolean;
|
||||
}
|
||||
|
||||
export default function Scene({ isCelebrating }: SceneProps) {
|
||||
return (
|
||||
<div className="w-full h-screen">
|
||||
<Canvas
|
||||
shadows
|
||||
camera={{ position: [0, 3, 8], fov: 60 }}
|
||||
gl={{ antialias: true, alpha: true }}
|
||||
>
|
||||
<WarmBackground />
|
||||
<Lighting />
|
||||
<CameraController isCelebrating={isCelebrating} />
|
||||
|
||||
<Ground />
|
||||
<Characters isCelebrating={isCelebrating} />
|
||||
<FloatingParticles isCelebrating={isCelebrating} />
|
||||
|
||||
{/* Floating decorative elements */}
|
||||
<Float speed={2} rotationIntensity={0.5} floatIntensity={0.5}>
|
||||
<mesh position={[-3, 4, -2]}>
|
||||
<sphereGeometry args={[0.3, 16, 16]} />
|
||||
<meshStandardMaterial color="#84CAFF" emissive="#53B1FD" emissiveIntensity={0.3} />
|
||||
</mesh>
|
||||
</Float>
|
||||
|
||||
<Float speed={1.5} rotationIntensity={0.3} floatIntensity={0.3}>
|
||||
<mesh position={[3, 5, -3]}>
|
||||
<sphereGeometry args={[0.2, 16, 16]} />
|
||||
<meshStandardMaterial color="#53B1FD" emissive="#2E90FA" emissiveIntensity={0.3} />
|
||||
</mesh>
|
||||
</Float>
|
||||
|
||||
<Float speed={2.5} rotationIntensity={0.4} floatIntensity={0.4}>
|
||||
<mesh position={[2, 3, 2]}>
|
||||
<sphereGeometry args={[0.25, 16, 16]} />
|
||||
<meshStandardMaterial color="#2E90FA" emissive="#1570EF" emissiveIntensity={0.2} />
|
||||
</mesh>
|
||||
</Float>
|
||||
</Canvas>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -49,3 +49,46 @@
|
|||
@apply text-primary hover:text-primary/80;
|
||||
}
|
||||
}
|
||||
|
||||
/* Custom animations for inauguration */
|
||||
@keyframes float {
|
||||
0%, 100% {
|
||||
transform: translateY(0px);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-20px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes float-delayed {
|
||||
0%, 100% {
|
||||
transform: translateY(0px);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-15px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fade-in-up {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.animate-float {
|
||||
animation: float 3s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.animate-float-delayed {
|
||||
animation: float-delayed 4s ease-in-out infinite;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
|
||||
.animate-fade-in-up {
|
||||
animation: fade-in-up 0.5s ease-out forwards;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { UserHomeRoute } from './routes/user-home'
|
|||
import { SuperAdminRoute } from './routes/super-admin'
|
||||
import { CreateCouponRoute } from './routes/create-coupon'
|
||||
import { LocationMarkerRoute } from './routes/location-marker'
|
||||
import Inauguration from './routes/inauguration'
|
||||
import { AuthWrapper } from './components/AuthWrapper'
|
||||
import { SuperAdminGuard } from './components/SuperAdminGuard'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
|
@ -52,6 +53,16 @@ const loginRoute = new Route({
|
|||
)
|
||||
})
|
||||
|
||||
const inaugurationRoute = new Route({
|
||||
getParentRoute: () => rootRoute,
|
||||
path: '/inauguration',
|
||||
component: () => (
|
||||
<Suspense fallback={<p>Loading inauguration…</p>}>
|
||||
<Inauguration />
|
||||
</Suspense>
|
||||
)
|
||||
})
|
||||
|
||||
const userHomeRoute = new Route({
|
||||
getParentRoute: () => rootRoute,
|
||||
path: '/user-home',
|
||||
|
|
@ -107,7 +118,8 @@ const routeTree = rootRoute.addChildren([
|
|||
userHomeRoute,
|
||||
superAdminRoute,
|
||||
createCouponRoute,
|
||||
locationMarkerRoute
|
||||
locationMarkerRoute,
|
||||
inaugurationRoute
|
||||
])
|
||||
|
||||
export function createAppRouter() {
|
||||
|
|
|
|||
349
apps/fallback-ui/src/routes/inauguration.tsx
Normal file
349
apps/fallback-ui/src/routes/inauguration.tsx
Normal file
|
|
@ -0,0 +1,349 @@
|
|||
import { useState, useCallback } from 'react';
|
||||
import Scene from '../components/3d/Scene';
|
||||
import confetti from 'canvas-confetti';
|
||||
|
||||
export default function Inauguration() {
|
||||
const [isCelebrating, setIsCelebrating] = useState(false);
|
||||
const [showWelcome, setShowWelcome] = useState(false);
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
|
||||
const triggerConfetti = useCallback(() => {
|
||||
const duration = 5 * 1000;
|
||||
const animationEnd = Date.now() + duration;
|
||||
const defaults = { startVelocity: 30, spread: 360, ticks: 60, zIndex: 0 };
|
||||
|
||||
const randomInRange = (min: number, max: number) => Math.random() * (max - min) + min;
|
||||
|
||||
const interval: any = setInterval(function() {
|
||||
const timeLeft = animationEnd - Date.now();
|
||||
|
||||
if (timeLeft <= 0) {
|
||||
return clearInterval(interval);
|
||||
}
|
||||
|
||||
const particleCount = 50 * (timeLeft / duration);
|
||||
|
||||
const colors = ['#2E90FA', '#53B1FD', '#84CAFF', '#1570EF', '#175CD3'];
|
||||
|
||||
confetti({
|
||||
...defaults,
|
||||
particleCount,
|
||||
origin: { x: randomInRange(0.1, 0.3), y: Math.random() - 0.2 },
|
||||
colors: colors,
|
||||
shapes: ['circle', 'square'],
|
||||
scalar: randomInRange(0.8, 1.5)
|
||||
});
|
||||
confetti({
|
||||
...defaults,
|
||||
particleCount,
|
||||
origin: { x: randomInRange(0.7, 0.9), y: Math.random() - 0.2 },
|
||||
colors: colors,
|
||||
shapes: ['circle', 'square'],
|
||||
scalar: randomInRange(0.8, 1.5)
|
||||
});
|
||||
}, 250);
|
||||
}, []);
|
||||
|
||||
const handleKickstart = () => {
|
||||
setIsCelebrating(true);
|
||||
triggerConfetti();
|
||||
|
||||
setTimeout(() => {
|
||||
setShowWelcome(true);
|
||||
}, 2000);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="relative w-full h-screen overflow-hidden">
|
||||
{/* Animated Gradient Background */}
|
||||
<div
|
||||
className="absolute inset-0 animate-gradient-xy"
|
||||
style={{
|
||||
background: 'linear-gradient(135deg, #2E90FA 0%, #1570EF 25%, #53B1FD 50%, #84CAFF 75%, #2E90FA 100%)',
|
||||
backgroundSize: '400% 400%',
|
||||
animation: 'gradientShift 15s ease infinite'
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Animated Mesh Gradient Overlay */}
|
||||
<div className="absolute inset-0 opacity-60">
|
||||
<div
|
||||
className="absolute inset-0 animate-pulse"
|
||||
style={{
|
||||
background: 'radial-gradient(circle at 20% 80%, #84CAFF 0%, transparent 50%), radial-gradient(circle at 80% 20%, #53B1FD 0%, transparent 50%), radial-gradient(circle at 40% 40%, #2E90FA 0%, transparent 40%)',
|
||||
filter: 'blur(60px)'
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Floating Bubbles */}
|
||||
<div className="absolute inset-0 pointer-events-none overflow-hidden">
|
||||
{[...Array(20)].map((_, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="absolute rounded-full"
|
||||
style={{
|
||||
width: `${Math.random() * 100 + 50}px`,
|
||||
height: `${Math.random() * 100 + 50}px`,
|
||||
left: `${Math.random() * 100}%`,
|
||||
top: `${Math.random() * 100}%`,
|
||||
background: `radial-gradient(circle, rgba(255,255,255,0.3) 0%, transparent 70%)`,
|
||||
animation: `floatBubble ${Math.random() * 10 + 10}s ease-in-out infinite`,
|
||||
animationDelay: `${Math.random() * 5}s`,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* 3D Scene */}
|
||||
<div className="absolute inset-0">
|
||||
<Scene isCelebrating={isCelebrating} />
|
||||
</div>
|
||||
|
||||
{/* Main Content Container */}
|
||||
<div className="absolute inset-0 flex flex-col items-center justify-center pointer-events-none">
|
||||
|
||||
{/* Logo Section */}
|
||||
<div
|
||||
className={`text-center mb-8 transition-all duration-1000 ease-out ${showWelcome ? 'opacity-0 -translate-y-12' : 'opacity-100 translate-y-0'}`}
|
||||
>
|
||||
{/* Logo Container with Glassmorphism */}
|
||||
<div className="relative inline-block">
|
||||
{/* Glow Effect Behind Logo */}
|
||||
<div className="absolute -inset-4 bg-gradient-to-r from-[#2E90FA] to-[#84CAFF] rounded-3xl blur-2xl opacity-40 animate-pulse" />
|
||||
|
||||
{/* Logo Text */}
|
||||
<div className="relative">
|
||||
<h1 className="text-8xl font-black tracking-tight">
|
||||
<span
|
||||
className="bg-clip-text text-transparent animate-shimmer"
|
||||
style={{
|
||||
backgroundImage: 'linear-gradient(90deg, #FFFFFF 0%, #E0F2FE 25%, #FFFFFF 50%, #E0F2FE 75%, #FFFFFF 100%)',
|
||||
backgroundSize: '200% auto',
|
||||
textShadow: '0 0 40px rgba(46,144,250,0.5)',
|
||||
animation: 'shimmer 3s linear infinite'
|
||||
}}
|
||||
>
|
||||
FRESHYO
|
||||
</span>
|
||||
</h1>
|
||||
|
||||
{/* Tagline */}
|
||||
<p className="text-2xl font-light text-white/90 mt-3 tracking-widest uppercase">
|
||||
Freshness Delivered
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Center Content - CTA or Welcome Message */}
|
||||
<div className="relative z-10">
|
||||
{!showWelcome ? (
|
||||
/* CTA Button */
|
||||
<div
|
||||
className={`transition-all duration-700 ease-out ${isCelebrating ? 'opacity-0 scale-90' : 'opacity-100 scale-100'}`}
|
||||
onMouseEnter={() => setIsHovered(true)}
|
||||
onMouseLeave={() => setIsHovered(false)}
|
||||
>
|
||||
<button
|
||||
onClick={handleKickstart}
|
||||
className="pointer-events-auto group relative"
|
||||
>
|
||||
{/* Outer Glow Rings */}
|
||||
<div className="absolute -inset-8 rounded-full bg-gradient-to-r from-[#1570EF] via-[#53B1FD] to-[#1570EF] opacity-30 blur-2xl group-hover:opacity-50 group-hover:blur-3xl transition-all duration-500 animate-pulse" />
|
||||
|
||||
{/* Inner Glow Ring */}
|
||||
<div className="absolute -inset-4 rounded-full border-2 border-white/20 group-hover:border-white/40 transition-all duration-500" />
|
||||
|
||||
{/* Button Container */}
|
||||
<div className="relative overflow-hidden rounded-full bg-gradient-to-r from-[#1570EF] to-[#53B1FD] p-[2px]">
|
||||
<div className="relative rounded-full bg-gradient-to-r from-[#1570EF] to-[#53B1FD] px-12 py-6">
|
||||
{/* Animated Background on Hover */}
|
||||
<div
|
||||
className="absolute inset-0 bg-gradient-to-r from-[#2E90FA] via-[#53B1FD] to-[#2E90FA] opacity-0 group-hover:opacity-100 transition-opacity duration-500"
|
||||
style={{ backgroundSize: '200% auto' }}
|
||||
/>
|
||||
|
||||
{/* Button Content */}
|
||||
<div className="relative flex items-center gap-4">
|
||||
{/* Sparkle Icon */}
|
||||
<svg
|
||||
className={`w-8 h-8 text-white transition-transform duration-300 ${isHovered ? 'rotate-12 scale-110' : ''}`}
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
>
|
||||
<path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
|
||||
</svg>
|
||||
|
||||
<span className="text-3xl font-bold text-white tracking-wide">
|
||||
Launch Freshyo
|
||||
</span>
|
||||
|
||||
{/* Rocket Icon */}
|
||||
<svg
|
||||
className={`w-8 h-8 text-white transition-all duration-300 ${isHovered ? 'translate-x-1 -translate-y-1' : ''}`}
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15.59 14.37a6 6 0 01-5.84 7.38v-4.8m5.84-2.58a14.98 14.98 0 006.16-12.12A14.98 14.98 0 009.631 8.41m5.96 5.96a14.926 14.926 0 01-5.841 2.58m-.119-8.54a6 6 0 00-7.381 5.84h4.8m2.581-5.84a14.927 14.927 0 00-2.58 5.84m2.699 2.7c-.103.021-.207.041-.311.06a15.09 15.09 0 01-2.448-2.448 14.9 14.9 0 01.06-.312m-2.24 2.39a4.493 4.493 0 00-1.757 4.306 4.493 4.493 0 004.306-1.758M16 8l-6 6" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Floating Particles Around Button */}
|
||||
<div className="absolute -top-2 -right-2 w-4 h-4 bg-white/60 rounded-full animate-float-fast" />
|
||||
<div className="absolute -bottom-2 -left-2 w-3 h-3 bg-[#84CAFF] rounded-full animate-float-delayed-fast" />
|
||||
</button>
|
||||
|
||||
{/* Subtext under button */}
|
||||
<p className="text-white/60 text-sm mt-6 text-center font-medium tracking-wide">
|
||||
Click to celebrate our launch in Mahabubnagar
|
||||
</p>
|
||||
</div>
|
||||
) : (
|
||||
/* Welcome Message */
|
||||
<div className="text-center animate-fade-in-up">
|
||||
<div className="relative inline-block">
|
||||
{/* Background glow */}
|
||||
<div className="absolute -inset-8 bg-gradient-to-r from-[#2E90FA] to-[#84CAFF] rounded-full blur-3xl opacity-40" />
|
||||
|
||||
<div className="relative bg-white/10 backdrop-blur-lg rounded-3xl px-16 py-12 border border-white/20 shadow-2xl">
|
||||
{/* Success Icon */}
|
||||
<div className="w-20 h-20 mx-auto mb-6 rounded-full bg-gradient-to-r from-[#2E90FA] to-[#53B1FD] flex items-center justify-center shadow-lg">
|
||||
<svg className="w-10 h-10 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={3} d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<h2 className="text-5xl font-black text-white mb-4">
|
||||
Welcome to Freshyo!
|
||||
</h2>
|
||||
|
||||
<div className="flex items-center justify-center gap-2 text-2xl font-semibold text-white/90">
|
||||
<span>We're now live in</span>
|
||||
<span className="bg-clip-text text-transparent bg-gradient-to-r from-[#FFD700] to-[#FFA500] font-black">
|
||||
Mahabubnagar
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Decorative line */}
|
||||
<div className="mt-8 flex items-center justify-center gap-4">
|
||||
<div className="h-0.5 w-16 bg-gradient-to-r from-transparent to-white/40" />
|
||||
<div className="w-2 h-2 rounded-full bg-white/60" />
|
||||
<div className="h-0.5 w-16 bg-gradient-to-l from-transparent to-white/40" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Footer Info */}
|
||||
<div
|
||||
className={`absolute bottom-12 left-0 right-0 text-center transition-all duration-1000 ${showWelcome ? 'opacity-0 translate-y-8' : 'opacity-100 translate-y-0'}`}
|
||||
>
|
||||
<div className="inline-flex items-center gap-3 bg-white/10 backdrop-blur-sm rounded-full px-6 py-3 border border-white/10">
|
||||
<div className="w-2 h-2 rounded-full bg-green-400 animate-pulse" />
|
||||
<p className="text-white/80 text-sm font-medium">
|
||||
Bringing fresh groceries to your doorstep
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Side Decorative Elements */}
|
||||
<div className="absolute left-8 top-1/2 -translate-y-1/2 pointer-events-none">
|
||||
<div className="flex flex-col gap-4">
|
||||
{[...Array(3)].map((_, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="w-1 h-12 rounded-full bg-gradient-to-b from-white/40 to-transparent"
|
||||
style={{ animationDelay: `${i * 0.2}s` }}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="absolute right-8 top-1/2 -translate-y-1/2 pointer-events-none">
|
||||
<div className="flex flex-col gap-4">
|
||||
{[...Array(3)].map((_, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="w-1 h-12 rounded-full bg-gradient-to-b from-white/40 to-transparent"
|
||||
style={{ animationDelay: `${i * 0.2}s` }}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Custom Styles */}
|
||||
<style>{`
|
||||
@keyframes gradientShift {
|
||||
0% { background-position: 0% 50%; }
|
||||
50% { background-position: 100% 50%; }
|
||||
100% { background-position: 0% 50%; }
|
||||
}
|
||||
|
||||
@keyframes shimmer {
|
||||
0% { background-position: -200% center; }
|
||||
100% { background-position: 200% center; }
|
||||
}
|
||||
|
||||
@keyframes floatBubble {
|
||||
0%, 100% {
|
||||
transform: translateY(0) translateX(0) scale(1);
|
||||
opacity: 0.3;
|
||||
}
|
||||
25% {
|
||||
transform: translateY(-30px) translateX(10px) scale(1.1);
|
||||
opacity: 0.5;
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-20px) translateX(-10px) scale(0.9);
|
||||
opacity: 0.3;
|
||||
}
|
||||
75% {
|
||||
transform: translateY(-40px) translateX(5px) scale(1.05);
|
||||
opacity: 0.4;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes float-fast {
|
||||
0%, 100% { transform: translateY(0) translateX(0); }
|
||||
50% { transform: translateY(-10px) translateX(5px); }
|
||||
}
|
||||
|
||||
@keyframes float-delayed-fast {
|
||||
0%, 100% { transform: translateY(0) translateX(0); }
|
||||
50% { transform: translateY(8px) translateX(-5px); }
|
||||
}
|
||||
|
||||
.animate-float-fast {
|
||||
animation: float-fast 2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.animate-float-delayed-fast {
|
||||
animation: float-delayed-fast 2.5s ease-in-out infinite;
|
||||
animation-delay: 0.5s;
|
||||
}
|
||||
|
||||
.animate-fade-in-up {
|
||||
animation: fadeInUp 0.8s ease-out forwards;
|
||||
}
|
||||
|
||||
@keyframes fadeInUp {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(30px) scale(0.95);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
}
|
||||
}
|
||||
`}</style>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -130,8 +130,12 @@ const CheckoutAddressSelector: React.FC<AddressSelectorProps> = ({
|
|||
|
||||
<BottomDialog open={showAddAddress} onClose={() => setShowAddAddress(false)}>
|
||||
<AddressForm
|
||||
onSuccess={() => {
|
||||
onSuccess={(addressId) => {
|
||||
setShowAddAddress(false);
|
||||
// Auto-select the newly added address
|
||||
if (addressId) {
|
||||
onAddressSelect(addressId);
|
||||
}
|
||||
queryClient.invalidateQueries();
|
||||
}}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -258,8 +258,12 @@ const CheckoutPage: React.FC<CheckoutPageProps> = ({ isFlashDelivery = false })
|
|||
|
||||
<BottomDialog open={showAddAddress} onClose={() => setShowAddAddress(false)}>
|
||||
<AddressForm
|
||||
onSuccess={() => {
|
||||
onSuccess={(addressId) => {
|
||||
setShowAddAddress(false);
|
||||
// Auto-select the newly added address
|
||||
if (addressId) {
|
||||
setSelectedAddressId(addressId);
|
||||
}
|
||||
queryClient.invalidateQueries();
|
||||
}}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { tw, MyText, MyTouchableOpacity , Checkbox , MyTextInput , LoadingDialog
|
|||
import { trpc } from '../trpc-client';
|
||||
|
||||
interface AddressFormProps {
|
||||
onSuccess: () => void;
|
||||
onSuccess: (addressId?: number) => void;
|
||||
initialValues?: {
|
||||
id?: number;
|
||||
name: string;
|
||||
|
|
@ -38,9 +38,10 @@ const AddressForm: React.FC<AddressFormProps> = ({ onSuccess, initialValues, isE
|
|||
);
|
||||
|
||||
const createAddressMutation = trpc.user.address.createAddress.useMutation({
|
||||
onSuccess: () => {
|
||||
onSuccess: (data) => {
|
||||
setIsSubmitting(false);
|
||||
setTimeout(() => onSuccess(), 100);
|
||||
const addressId = data?.data?.id;
|
||||
setTimeout(() => onSuccess(addressId), 100);
|
||||
},
|
||||
onError: (error: any) => {
|
||||
setIsSubmitting(false);
|
||||
|
|
|
|||
559
package-lock.json
generated
559
package-lock.json
generated
|
|
@ -13,8 +13,12 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"@react-native/virtualized-lists": "^0.79.6",
|
||||
"@react-three/drei": "^10.7.7",
|
||||
"@react-three/fiber": "^9.5.0",
|
||||
"@types/three": "^0.182.0",
|
||||
"admin-ui": "^1.0.0",
|
||||
"backend": "^1.0.0",
|
||||
"canvas-confetti": "^1.9.4",
|
||||
"expo": "~53.0.22",
|
||||
"expo-auth-session": "~6.2.1",
|
||||
"expo-crypto": "~14.1.5",
|
||||
|
|
@ -22,11 +26,13 @@
|
|||
"node-cron": "^4.2.1",
|
||||
"react": "19.0.0",
|
||||
"react-native": "0.79.6",
|
||||
"three": "^0.182.0",
|
||||
"user-ui": "^1.0.0",
|
||||
"zustand": "^5.0.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@types/canvas-confetti": "^1.9.0",
|
||||
"@types/react": "~19.0.10",
|
||||
"@types/react-native-razorpay": "^2.2.6",
|
||||
"eslint": "^9.25.0",
|
||||
|
|
@ -2964,6 +2970,12 @@
|
|||
"@jridgewell/sourcemap-codec": "^1.4.10"
|
||||
}
|
||||
},
|
||||
"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/@drizzle-team/brocli": {
|
||||
"version": "0.10.2",
|
||||
"resolved": "https://registry.npmjs.org/@drizzle-team/brocli/-/brocli-0.10.2.tgz",
|
||||
|
|
@ -5350,6 +5362,24 @@
|
|||
"integrity": "sha512-gRa9gwYU3ECmQYv3lslts5hxuIa90veaEcxDYuu3QGOIAEM2mOZkVHp48ANJuu1CURtRdHKUBY5Lm1tHV+sD4g==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"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/@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/@msgpackr-extract/msgpackr-extract-darwin-arm64": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz",
|
||||
|
|
@ -6002,6 +6032,124 @@
|
|||
"nanoid": "^3.3.11"
|
||||
}
|
||||
},
|
||||
"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/@react-three/fiber/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/@react-three/fiber/node_modules/scheduler": {
|
||||
"version": "0.27.0",
|
||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz",
|
||||
"integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@redis/bloom": {
|
||||
"version": "5.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-5.10.0.tgz",
|
||||
|
|
@ -9660,6 +9808,12 @@
|
|||
"url": "https://opencollective.com/turf"
|
||||
}
|
||||
},
|
||||
"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",
|
||||
|
|
@ -9728,6 +9882,13 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/canvas-confetti": {
|
||||
"version": "1.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/canvas-confetti/-/canvas-confetti-1.9.0.tgz",
|
||||
"integrity": "sha512-aBGj/dULrimR1XDZLtG9JwxX1b4HPRF6CX9Yfwh3NvstZEm1ZL7RBnel4keCPSqs1ANRu1u2Aoz9R+VmtjYuTg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/connect": {
|
||||
"version": "3.4.38",
|
||||
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz",
|
||||
|
|
@ -9752,6 +9913,12 @@
|
|||
"integrity": "sha512-DauBl25PKZZ0WVJr42a6CNvI6efsdzofl9sajqZr2Gf5Gu733WkDdUGiPkUHXiUvYGzNNlFQde2wdZdfQPG+yw==",
|
||||
"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",
|
||||
|
|
@ -9925,6 +10092,12 @@
|
|||
"integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"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/pbf": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.5.tgz",
|
||||
|
|
@ -9984,6 +10157,15 @@
|
|||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"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/send": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz",
|
||||
|
|
@ -10009,6 +10191,12 @@
|
|||
"integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"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/strip-bom": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz",
|
||||
|
|
@ -10032,12 +10220,33 @@
|
|||
"@types/geojson": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/three": {
|
||||
"version": "0.182.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/three/-/three-0.182.0.tgz",
|
||||
"integrity": "sha512-WByN9V3Sbwbe2OkWuSGyoqQO8Du6yhYaXtXLoA5FkKTUJorZ+yOHBZ35zUUPQXlAKABZmbYp5oAqpA4RBjtJ/Q==",
|
||||
"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": "~0.22.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/validator": {
|
||||
"version": "13.15.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.15.10.tgz",
|
||||
"integrity": "sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==",
|
||||
"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/@types/yargs": {
|
||||
"version": "17.0.35",
|
||||
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz",
|
||||
|
|
@ -10691,6 +10900,24 @@
|
|||
"@urql/core": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"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-swc": {
|
||||
"version": "3.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.11.0.tgz",
|
||||
|
|
@ -10705,6 +10932,12 @@
|
|||
"vite": "^4 || ^5 || ^6 || ^7"
|
||||
}
|
||||
},
|
||||
"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/@xmldom/xmldom": {
|
||||
"version": "0.8.11",
|
||||
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.11.tgz",
|
||||
|
|
@ -11518,6 +11751,15 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/bidi-js": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz",
|
||||
"integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"require-from-string": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/big-integer": {
|
||||
"version": "1.6.52",
|
||||
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz",
|
||||
|
|
@ -11859,6 +12101,19 @@
|
|||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/camera-controls": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/camera-controls/-/camera-controls-3.1.0.tgz",
|
||||
"integrity": "sha512-w5oULNpijgTRH0ARFJJ0R5ct1nUM3R3WP7/b8A6j9uTGpRfnsypc/RBMPQV8JQDPayUe37p/TZZY1PcUr4czOQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=20.11.0",
|
||||
"npm": ">=10.8.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"three": ">=0.126.1"
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001760",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001760.tgz",
|
||||
|
|
@ -11879,6 +12134,16 @@
|
|||
],
|
||||
"license": "CC-BY-4.0"
|
||||
},
|
||||
"node_modules/canvas-confetti": {
|
||||
"version": "1.9.4",
|
||||
"resolved": "https://registry.npmjs.org/canvas-confetti/-/canvas-confetti-1.9.4.tgz",
|
||||
"integrity": "sha512-yxQbJkAVrFXWNbTUjPqjF7G+g6pDotOUHGbkZq2NELZUMDpiJ85rIEazVb8GTaAptNW2miJAXbs1BtioA251Pw==",
|
||||
"license": "ISC",
|
||||
"funding": {
|
||||
"type": "donate",
|
||||
"url": "https://www.paypal.me/kirilvatev"
|
||||
}
|
||||
},
|
||||
"node_modules/chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||
|
|
@ -12575,6 +12840,24 @@
|
|||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"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-fetch": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz",
|
||||
|
|
@ -12900,6 +13183,15 @@
|
|||
"npm": "1.2.8000 || >= 1.4.16"
|
||||
}
|
||||
},
|
||||
"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": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
|
||||
|
|
@ -13047,6 +13339,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/drizzle-kit": {
|
||||
"version": "0.31.8",
|
||||
"resolved": "https://registry.npmjs.org/drizzle-kit/-/drizzle-kit-0.31.8.tgz",
|
||||
|
|
@ -15307,6 +15605,12 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"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/file-entry-cache": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
|
||||
|
|
@ -15904,6 +16208,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/goober": {
|
||||
"version": "2.1.18",
|
||||
"resolved": "https://registry.npmjs.org/goober/-/goober-2.1.18.tgz",
|
||||
|
|
@ -16035,6 +16345,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/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",
|
||||
|
|
@ -16187,6 +16503,12 @@
|
|||
"node": ">=16.x"
|
||||
}
|
||||
},
|
||||
"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",
|
||||
|
|
@ -16954,6 +17276,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/jackspeak": {
|
||||
"version": "3.4.3",
|
||||
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
|
||||
|
|
@ -17430,6 +17764,15 @@
|
|||
"integrity": "sha512-Z3IhgVgrqO1S5xPYM3K5XwbkDasU67/Vys4heW+lfSBALcUZjeIIzI8zCLifY+OCzSq+fpDdywMDa7z+4srJPQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"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/lighthouse-logger": {
|
||||
"version": "1.4.2",
|
||||
"resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-1.4.2.tgz",
|
||||
|
|
@ -17899,6 +18242,16 @@
|
|||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"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/make-error": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||
|
|
@ -18034,6 +18387,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": "0.22.0",
|
||||
"resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.22.0.tgz",
|
||||
"integrity": "sha512-IebiK79sqIy+E4EgOr+CAw+Ke8hAspXKzBd0JdgEmPHiAwmvEj2S4h1rfvo+o/BnfEYd/jAOg5IeeIjzlzSnDg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/methods": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||
|
|
@ -19855,6 +20223,16 @@
|
|||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"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/prompts": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
|
||||
|
|
@ -20759,6 +21137,21 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"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/read-cache": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
||||
|
|
@ -21962,6 +22355,32 @@
|
|||
"integrity": "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==",
|
||||
"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",
|
||||
|
|
@ -22344,6 +22763,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/sweepline-intersections": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/sweepline-intersections/-/sweepline-intersections-1.5.0.tgz",
|
||||
|
|
@ -22566,6 +22994,50 @@
|
|||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/three": {
|
||||
"version": "0.182.0",
|
||||
"resolved": "https://registry.npmjs.org/three/-/three-0.182.0.tgz",
|
||||
"integrity": "sha512-GbHabT+Irv+ihI1/f5kIIsZ+Ef9Sl5A1Y7imvS5RQjWgtTPfPnZ43JmlYI7NtCRDK9zir20lQpfg8/9Yd02OvQ==",
|
||||
"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/three-stdlib/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/throat": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz",
|
||||
|
|
@ -22719,6 +23191,36 @@
|
|||
"tree-kill": "cli.js"
|
||||
}
|
||||
},
|
||||
"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.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
|
||||
|
|
@ -23443,6 +23945,43 @@
|
|||
"@esbuild/win32-x64": "0.27.1"
|
||||
}
|
||||
},
|
||||
"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/turbo": {
|
||||
"version": "2.6.3",
|
||||
"resolved": "https://registry.npmjs.org/turbo/-/turbo-2.6.3.tgz",
|
||||
|
|
@ -23935,6 +24474,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/utils-merge": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||
|
|
@ -24129,6 +24677,17 @@
|
|||
"defaults": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"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": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
],
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.25.2",
|
||||
"@types/canvas-confetti": "^1.9.0",
|
||||
"@types/react": "~19.0.10",
|
||||
"@types/react-native-razorpay": "^2.2.6",
|
||||
"eslint": "^9.25.0",
|
||||
|
|
@ -29,8 +30,12 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@react-native/virtualized-lists": "^0.79.6",
|
||||
"@react-three/drei": "^10.7.7",
|
||||
"@react-three/fiber": "^9.5.0",
|
||||
"@types/three": "^0.182.0",
|
||||
"admin-ui": "^1.0.0",
|
||||
"backend": "^1.0.0",
|
||||
"canvas-confetti": "^1.9.4",
|
||||
"expo": "~53.0.22",
|
||||
"expo-auth-session": "~6.2.1",
|
||||
"expo-crypto": "~14.1.5",
|
||||
|
|
@ -38,6 +43,7 @@
|
|||
"node-cron": "^4.2.1",
|
||||
"react": "19.0.0",
|
||||
"react-native": "0.79.6",
|
||||
"three": "^0.182.0",
|
||||
"user-ui": "^1.0.0",
|
||||
"zustand": "^5.0.9"
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue