From 5a0575ae7cfb7f2a3759d9878e369b9a97871116 Mon Sep 17 00:00:00 2001 From: alrocar Date: Tue, 25 Feb 2025 10:46:36 +0100 Subject: [PATCH 01/12] add sidebar buttons --- dashboard/log-analyzer/package-lock.json | 1809 ++++++++++++++++- dashboard/log-analyzer/package.json | 8 +- .../animations/SplashCursor/SplashCursor.tsx | 1546 ++++++++++++++ .../src/components/layout/Sidebar.tsx | 84 +- 4 files changed, 3425 insertions(+), 22 deletions(-) create mode 100644 dashboard/log-analyzer/src/components/animations/SplashCursor/SplashCursor.tsx diff --git a/dashboard/log-analyzer/package-lock.json b/dashboard/log-analyzer/package-lock.json index 9bb598c..bcea378 100644 --- a/dashboard/log-analyzer/package-lock.json +++ b/dashboard/log-analyzer/package-lock.json @@ -17,6 +17,9 @@ "@radix-ui/react-separator": "^1.1.1", "@radix-ui/react-slot": "^1.1.1", "@radix-ui/react-tooltip": "^1.1.8", + "@react-three/drei": "^9.122.0", + "@react-three/fiber": "^8.18.0", + "@react-three/rapier": "^1.5.0", "@tinybirdco/charts": "^0.2.4", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", @@ -24,11 +27,13 @@ "echarts": "^5.6.0", "echarts-for-react": "^3.0.2", "lucide-react": "^0.474.0", + "meshline": "^3.3.1", "next": "15.1.6", "react": "^18.2.0", "react-dom": "^18.2.0", "tailwind-merge": "^3.0.1", "tailwindcss-animate": "^1.0.7", + "three": "^0.167.1", "use-debounce": "^10.0.4", "zod": "^3.24.1" }, @@ -41,7 +46,8 @@ "eslint-config-next": "15.1.6", "postcss": "^8", "tailwindcss": "^3.4.1", - "typescript": "^5" + "typescript": "^5", + "url-loader": "^4.1.1" } }, "node_modules/@alloc/quick-lru": { @@ -56,6 +62,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@babel/runtime": { + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.9.tgz", + "integrity": "sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==", + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@chronark/zod-bird": { "version": "0.3.10", "resolved": "https://registry.npmjs.org/@chronark/zod-bird/-/zod-bird-0.3.10.tgz", @@ -65,6 +83,12 @@ "zod": "^3.22.4" } }, + "node_modules/@dimforge/rapier3d-compat": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/@dimforge/rapier3d-compat/-/rapier3d-compat-0.14.0.tgz", + "integrity": "sha512-/uHrUzS+CRQ+NQrrJCEDUkhwHlNsAAexbNXgbN9sHY+GwR+SFFAFrxRr8Llf5/AJZzqiLANdQIfJ63Cw4gJVqw==", + "license": "Apache-2.0" + }, "node_modules/@emnapi/runtime": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz", @@ -717,6 +741,18 @@ "node": ">=6.0.0" } }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", @@ -733,6 +769,24 @@ "@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/@monogrid/gainmap-js": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@monogrid/gainmap-js/-/gainmap-js-3.1.0.tgz", + "integrity": "sha512-Obb0/gEd/HReTlg8ttaYk+0m62gQJmCblMOjHSMHRrBP2zdfKMHLCRbh/6ex9fSUJMKdjjIEiohwkbGD3wj2Nw==", + "license": "MIT", + "dependencies": { + "promise-worker-transferable": "^1.0.4" + }, + "peerDependencies": { + "three": ">= 0.159.0" + } + }, "node_modules/@next/env": { "version": "15.1.6", "resolved": "https://registry.npmjs.org/@next/env/-/env-15.1.6.tgz", @@ -1775,6 +1829,210 @@ "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==", "license": "MIT" }, + "node_modules/@react-spring/animated": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.5.tgz", + "integrity": "sha512-Tqrwz7pIlsSDITzxoLS3n/v/YCUHQdOIKtOJf4yL6kYVSDTSmVK1LI1Q3M/uu2Sx4X3pIWF3xLUhlsA6SPNTNg==", + "license": "MIT", + "dependencies": { + "@react-spring/shared": "~9.7.5", + "@react-spring/types": "~9.7.5" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/core": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.5.tgz", + "integrity": "sha512-rmEqcxRcu7dWh7MnCcMXLvrf6/SDlSokLaLTxiPlAYi11nN3B5oiCUAblO72o+9z/87j2uzxa2Inm8UbLjXA+w==", + "license": "MIT", + "dependencies": { + "@react-spring/animated": "~9.7.5", + "@react-spring/shared": "~9.7.5", + "@react-spring/types": "~9.7.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/react-spring/donate" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/rafz": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.7.5.tgz", + "integrity": "sha512-5ZenDQMC48wjUzPAm1EtwQ5Ot3bLIAwwqP2w2owG5KoNdNHpEJV263nGhCeKKmuA3vG2zLLOdu3or6kuDjA6Aw==", + "license": "MIT" + }, + "node_modules/@react-spring/shared": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.5.tgz", + "integrity": "sha512-wdtoJrhUeeyD/PP/zo+np2s1Z820Ohr/BbuVYv+3dVLW7WctoiN7std8rISoYoHpUXtbkpesSKuPIw/6U1w1Pw==", + "license": "MIT", + "dependencies": { + "@react-spring/rafz": "~9.7.5", + "@react-spring/types": "~9.7.5" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@react-spring/three": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/@react-spring/three/-/three-9.7.5.tgz", + "integrity": "sha512-RxIsCoQfUqOS3POmhVHa1wdWS0wyHAUway73uRLp3GAL5U2iYVNdnzQsep6M2NZ994BlW8TcKuMtQHUqOsy6WA==", + "license": "MIT", + "dependencies": { + "@react-spring/animated": "~9.7.5", + "@react-spring/core": "~9.7.5", + "@react-spring/shared": "~9.7.5", + "@react-spring/types": "~9.7.5" + }, + "peerDependencies": { + "@react-three/fiber": ">=6.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "three": ">=0.126" + } + }, + "node_modules/@react-spring/types": { + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.5.tgz", + "integrity": "sha512-HVj7LrZ4ReHWBimBvu2SKND3cDVUPWKLqRTmWe/fNY6o1owGOX0cAHbdPDTMelgBlVbrTKrre6lFkhqGZErK/g==", + "license": "MIT" + }, + "node_modules/@react-three/drei": { + "version": "9.122.0", + "resolved": "https://registry.npmjs.org/@react-three/drei/-/drei-9.122.0.tgz", + "integrity": "sha512-SEO/F/rBCTjlLez7WAlpys+iGe9hty4rNgjZvgkQeXFSiwqD4Hbk/wNHMAbdd8vprO2Aj81mihv4dF5bC7D0CA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mediapipe/tasks-vision": "0.10.17", + "@monogrid/gainmap-js": "^3.0.6", + "@react-spring/three": "~9.7.5", + "@use-gesture/react": "^10.3.1", + "camera-controls": "^2.9.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", + "react-composer": "^5.0.3", + "stats-gl": "^2.2.8", + "stats.js": "^0.17.0", + "suspend-react": "^0.1.3", + "three-mesh-bvh": "^0.7.8", + "three-stdlib": "^2.35.6", + "troika-three-text": "^0.52.0", + "tunnel-rat": "^0.1.2", + "utility-types": "^3.11.0", + "zustand": "^5.0.1" + }, + "peerDependencies": { + "@react-three/fiber": "^8", + "react": "^18", + "react-dom": "^18", + "three": ">=0.137" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/@react-three/fiber": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-8.18.0.tgz", + "integrity": "sha512-FYZZqD0UUHUswKz3LQl2Z7H24AhD14XGTsIRw3SJaXUxyfVMi+1yiZGmqTcPt/CkPpdU7rrxqcyQ1zJE5DjvIQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.17.8", + "@types/react-reconciler": "^0.26.7", + "@types/webxr": "*", + "base64-js": "^1.5.1", + "buffer": "^6.0.3", + "its-fine": "^1.0.6", + "react-reconciler": "^0.27.0", + "react-use-measure": "^2.1.7", + "scheduler": "^0.21.0", + "suspend-react": "^0.1.3", + "zustand": "^3.7.1" + }, + "peerDependencies": { + "expo": ">=43.0", + "expo-asset": ">=8.4", + "expo-file-system": ">=11.0", + "expo-gl": ">=11.0", + "react": ">=18 <19", + "react-dom": ">=18 <19", + "react-native": ">=0.64", + "three": ">=0.133" + }, + "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/scheduler": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", + "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/@react-three/fiber/node_modules/zustand": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.7.2.tgz", + "integrity": "sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==", + "license": "MIT", + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + } + } + }, + "node_modules/@react-three/rapier": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@react-three/rapier/-/rapier-1.5.0.tgz", + "integrity": "sha512-gylk2KyCer9EoymFyTyc+g2IqyAq4mTbZgaHoSJi6gHoXlJsC2LVeN4jedvegvjUsXPExdE60wHjCPa+DS4iXw==", + "dependencies": { + "@dimforge/rapier3d-compat": "0.14.0", + "suspend-react": "^0.1.3", + "three-stdlib": "^2.29.4" + }, + "peerDependencies": { + "@react-three/fiber": ">=8.9.0", + "react": ">=18.0.0", + "three": ">=0.139.0" + } + }, "node_modules/@rtsao/scc": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", @@ -1818,6 +2076,42 @@ "react-dom": ">=16.6.0" } }, + "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/@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/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", @@ -1849,11 +2143,16 @@ "undici-types": "~6.19.2" } }, + "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.0.8", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.8.tgz", "integrity": "sha512-9P/o1IGdfmQxrujGbIMDyYaaCykhLKc0NGCtYcECNUr9UAaDe4gwvV9bR6tvd5Br1SG0j+PBpbKr2UYY8CwqSw==", - "devOptional": true, "license": "MIT", "dependencies": { "csstype": "^3.0.2" @@ -1869,6 +2168,41 @@ "@types/react": "^19.0.0" } }, + "node_modules/@types/react-reconciler": { + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.26.7.tgz", + "integrity": "sha512-mBDYl8x+oyPX/VBb3E638N0B7xG+SPk/EAMcVPeexqus/5aTpTphQi0curhhshOqRrc9t6OPoJfEUkbymse/lQ==", + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/stats.js": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.3.tgz", + "integrity": "sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ==", + "license": "MIT" + }, + "node_modules/@types/three": { + "version": "0.173.0", + "resolved": "https://registry.npmjs.org/@types/three/-/three-0.173.0.tgz", + "integrity": "sha512-KtNjfI/CRB6JVKIVeZM1R3GYDX2wkoV2itNcQu2j4d7qkhjGOuB+s2oF6jl9mztycDLGMtrAnJQYxInC8Bb20A==", + "license": "MIT", + "dependencies": { + "@tweenjs/tween.js": "~23.1.3", + "@types/stats.js": "*", + "@types/webxr": "*", + "@webgpu/types": "*", + "fflate": "~0.8.2", + "meshoptimizer": "~0.18.1" + } + }, + "node_modules/@types/webxr": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.21.tgz", + "integrity": "sha512-geZIAtLzjGmgY2JUi6VxXdCrTb99A7yP49lxLr2Nm/uIK0PkkxcEi4OGhoGDO4pxCf3JwGz2GiJL2Ej4K2bKaA==", + "license": "MIT" + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.23.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.23.0.tgz", @@ -2105,6 +2439,222 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "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/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webgpu/types": { + "version": "0.1.54", + "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.54.tgz", + "integrity": "sha512-81oaalC8LFrXjhsczomEQ0u3jG+TqE6V9QHLA8GNZq/Rnot0KDugu3LhSYSlie8tSdooAN1Hov05asrUUp9qgg==", + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true, + "license": "BSD-3-Clause", + "peer": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true, + "license": "Apache-2.0", + "peer": true + }, "node_modules/acorn": { "version": "8.14.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", @@ -2145,6 +2695,61 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, "node_modules/ansi-regex": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", @@ -2442,19 +3047,58 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/brace-expansion": { + "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/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.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", @@ -2477,6 +3121,72 @@ "node": ">=8" } }, + "node_modules/browserslist": { + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "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/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -2557,6 +3267,15 @@ "node": ">= 6" } }, + "node_modules/camera-controls": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/camera-controls/-/camera-controls-2.10.0.tgz", + "integrity": "sha512-vBQ5Daxv4KRsn07U/VqkPxoqD8U+S++0oq5NLf4HevMuh/BDta3rg49e/P564AMzFPBePQeXDKOkiIezRgyDwg==", + "license": "MIT", + "peerDependencies": { + "three": ">=0.126.1" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001697", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001697.tgz", @@ -2630,6 +3349,17 @@ "node": ">= 6" } }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.0" + } + }, "node_modules/class-variance-authority": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz", @@ -2716,6 +3446,24 @@ "dev": true, "license": "MIT" }, + "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", @@ -2746,7 +3494,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "devOptional": true, "license": "MIT" }, "node_modules/damerau-levenshtein": { @@ -2890,6 +3637,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.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", @@ -2931,6 +3687,12 @@ "node": ">=0.10.0" } }, + "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", @@ -2982,12 +3744,30 @@ "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", "license": "0BSD" }, + "node_modules/electron-to-chromium": { + "version": "1.5.103", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.103.tgz", + "integrity": "sha512-P6+XzIkfndgsrjROJWfSvVEgNHtPgbhVyTkwLjUM2HU/h7pZRORgaTlHqfAikqxKmdJMLW8fftrdGWbd/Ds0FA==", + "dev": true, + "license": "ISC", + "peer": true + }, "node_modules/emoji-regex": { "version": "9.2.2", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "license": "MIT" }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/enhanced-resolve": { "version": "5.18.1", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", @@ -3116,6 +3896,14 @@ "node": ">= 0.4" } }, + "node_modules/es-module-lexer": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", + "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", @@ -3173,6 +3961,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -3642,6 +4441,17 @@ "node": ">=0.10.0" } }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.8.x" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -3692,6 +4502,24 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause", + "peer": true + }, "node_modules/fastq": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz", @@ -3701,6 +4529,12 @@ "reusify": "^1.0.4" } }, + "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", @@ -3961,6 +4795,14 @@ "node": ">=10.13.0" } }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true + }, "node_modules/glob/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -4015,6 +4857,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", @@ -4135,6 +4983,32 @@ "node": ">= 0.4" } }, + "node_modules/hls.js": { + "version": "1.5.20", + "resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.5.20.tgz", + "integrity": "sha512-uu0VXUK52JhihhnN/MVVo1lvqNNuhoxkonqgO3IpjvQiGpJBdIXMGkofjQb/j9zvV7a1SW8U9g1FslWx/1HOiQ==", + "license": "Apache-2.0" + }, + "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", @@ -4145,6 +5019,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", @@ -4454,6 +5334,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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/is-regex": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", @@ -4630,6 +5516,27 @@ "node": ">= 0.4" } }, + "node_modules/its-fine": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/its-fine/-/its-fine-1.2.5.tgz", + "integrity": "sha512-fXtDA0X0t0eBYAGLVM5YsgJGsJ5jEmqZEPrGbzdf5awjv0xE7nqv3TVnvtUF060Tkes15DbDAKW/I48vsb6SyA==", + "license": "MIT", + "dependencies": { + "@types/react-reconciler": "^0.28.0" + }, + "peerDependencies": { + "react": ">=18.0" + } + }, + "node_modules/its-fine/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/jackspeak": { "version": "3.4.3", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", @@ -4645,6 +5552,39 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "node_modules/jiti": { "version": "1.21.7", "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", @@ -4680,6 +5620,14 @@ "dev": true, "license": "MIT" }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -4767,6 +5715,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/lilconfig": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", @@ -4785,6 +5742,45 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "license": "MIT" }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/loader-utils/node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -4835,6 +5831,16 @@ "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, + "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/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -4845,6 +5851,14 @@ "node": ">= 0.4" } }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -4854,6 +5868,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.18.1", + "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.18.1.tgz", + "integrity": "sha512-ZhoIoL7TNV4s5B6+rx5mC//fw8/POGyNxS/DZyCJeiZ12ScLfVwRE/GfsxwiTkMYYD5DmK2/JXnEVXqL4rF+Sw==", + "license": "MIT" + }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -4867,7 +5896,30 @@ "node": ">=8.6" } }, - "node_modules/minimatch": { + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", @@ -4942,6 +5994,14 @@ "dev": true, "license": "MIT" }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/next": { "version": "15.1.6", "resolved": "https://registry.npmjs.org/next/-/next-15.1.6.tgz", @@ -5024,6 +6084,14 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -5480,6 +6548,12 @@ "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "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/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -5490,11 +6564,20 @@ "node": ">= 0.8.0" } }, + "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/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dev": true, "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", @@ -5532,6 +6615,17 @@ ], "license": "MIT" }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, "node_modules/react": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", @@ -5544,6 +6638,18 @@ "node": ">=0.10.0" } }, + "node_modules/react-composer": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/react-composer/-/react-composer-5.0.3.tgz", + "integrity": "sha512-1uWd07EME6XZvMfapwZmc7NgCZqDemcvicRi3wMJzXsQLvZ3L7fTHVyPy1bZdnWXM4iPjYuNE+uJ41MLKeTtnA==", + "license": "MIT", + "dependencies": { + "prop-types": "^15.6.0" + }, + "peerDependencies": { + "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/react-dom": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", @@ -5561,9 +6667,33 @@ "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true, "license": "MIT" }, + "node_modules/react-reconciler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.27.0.tgz", + "integrity": "sha512-HmMDKciQjYmBRGuuhIaKA1ba/7a+UsM5FzOZsMO2JYHt9Jh8reCb7j1eDC95NOyUlKM9KRyvdx0flBuDvYSBoA==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.21.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "react": "^18.0.0" + } + }, + "node_modules/react-reconciler/node_modules/scheduler": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", + "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, "node_modules/react-remove-scroll": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.6.3.tgz", @@ -5633,6 +6763,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/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -5677,6 +6822,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" + }, "node_modules/regexp.prototype.flags": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", @@ -5698,6 +6849,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve": { "version": "1.22.10", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", @@ -5791,6 +6951,28 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "peer": true + }, "node_modules/safe-push-apply": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", @@ -5835,6 +7017,25 @@ "loose-envify": "^1.1.0" } }, + "node_modules/schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, "node_modules/semver": { "version": "7.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", @@ -5848,6 +7049,17 @@ "node": ">=10" } }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, "node_modules/set-function-length": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", @@ -6061,6 +7273,17 @@ "resolved": "https://registry.npmjs.org/size-sensor/-/size-sensor-1.0.2.tgz", "integrity": "sha512-2NCmWxY7A9pYKGXNBfteo4hy14gWu47rg5692peVMst6lQLPKrVjhY+UTEsPI5ceFRJSl3gVgMYaUi/hKuaiKw==" }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -6070,6 +7293,18 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, "node_modules/stable-hash": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.4.tgz", @@ -6077,6 +7312,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/streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", @@ -6387,6 +7648,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/swr": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/swr/-/swr-2.3.1.tgz", @@ -6494,6 +7764,131 @@ "node": ">=6" } }, + "node_modules/terser": { + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz", + "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.11", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.11.tgz", + "integrity": "sha512-RVCsMfuD0+cTt3EwX8hSl2Ks56EbFHWmhluwcqoPKtBnfjiT6olaq7PRIRfhyU8nnC2MrnDrBLfrD/RGE+cVXQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", + "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/thenify": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", @@ -6515,6 +7910,45 @@ "node": ">=0.8" } }, + "node_modules/three": { + "version": "0.167.1", + "resolved": "https://registry.npmjs.org/three/-/three-0.167.1.tgz", + "integrity": "sha512-gYTLJA/UQip6J/tJvl91YYqlZF47+D/kxiWrbTon35ZHlXEN0VOo+Qke2walF1/x92v55H6enomymg4Dak52kw==", + "license": "MIT" + }, + "node_modules/three-mesh-bvh": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/three-mesh-bvh/-/three-mesh-bvh-0.7.8.tgz", + "integrity": "sha512-BGEZTOIC14U0XIRw3tO4jY7IjP7n7v24nv9JXS1CyeVRWOCkcOMhRnmENUjuV39gktAw4Ofhr0OvIAiTspQrrw==", + "deprecated": "Deprecated due to three.js version incompatibility. Please use v0.8.0, instead.", + "license": "MIT", + "peerDependencies": { + "three": ">= 0.151.0" + } + }, + "node_modules/three-stdlib": { + "version": "2.35.14", + "resolved": "https://registry.npmjs.org/three-stdlib/-/three-stdlib-2.35.14.tgz", + "integrity": "sha512-kpCaEg59M9usFTgHC+YZNKvx7nMoLI2zQxZBV8pjoNW6vNZmGyXpaLBL09A2oLCsS3KepgMFkOuk6lRoebTNvA==", + "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/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -6527,6 +7961,36 @@ "node": ">=8.0" } }, + "node_modules/troika-three-text": { + "version": "0.52.3", + "resolved": "https://registry.npmjs.org/troika-three-text/-/troika-three-text-0.52.3.tgz", + "integrity": "sha512-jLhiwgV8kEkwWjvK12f2fHVpbOC75p7SgPQ0cgcz+IMtN5Bdyg4EuFdwuTOVu9ga8UeYdKBpzd1AxviyixtYTQ==", + "license": "MIT", + "dependencies": { + "bidi-js": "^1.0.2", + "troika-three-utils": "^0.52.0", + "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.0", + "resolved": "https://registry.npmjs.org/troika-three-utils/-/troika-three-utils-0.52.0.tgz", + "integrity": "sha512-00oxqIIehtEKInOTQekgyknBuRUj1POfOUE2q1OmL+Xlpp4gIu+S0oA0schTyXsDS4d9DkR04iqCdD40rF5R6w==", + "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.0.1", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz", @@ -6565,6 +8029,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.6", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.6.tgz", + "integrity": "sha512-ibr/n1hBzLLj5Y+yUcU7dYw8p6WnIVzdJbnX+1YpaScvZVF2ziugqHs+LAmHw4lWO9c/zRj+K1ncgWDQuthEdQ==", + "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/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -6696,6 +8197,38 @@ "dev": true, "license": "MIT" }, + "node_modules/update-browserslist-db": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", + "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -6706,6 +8239,34 @@ "punycode": "^2.1.0" } }, + "node_modules/url-loader": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", + "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "mime-types": "^2.1.27", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "file-loader": "*", + "webpack": "^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "file-loader": { + "optional": true + } + } + }, "node_modules/use-callback-ref": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz", @@ -6776,6 +8337,187 @@ "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/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "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/webpack": { + "version": "5.98.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.98.0.tgz", + "integrity": "sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.11", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/webpack/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "peer": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz", + "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -7025,6 +8767,35 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz", "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", "license": "0BSD" + }, + "node_modules/zustand": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.3.tgz", + "integrity": "sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==", + "license": "MIT", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } } } } diff --git a/dashboard/log-analyzer/package.json b/dashboard/log-analyzer/package.json index 662cd23..4965ec0 100644 --- a/dashboard/log-analyzer/package.json +++ b/dashboard/log-analyzer/package.json @@ -18,6 +18,9 @@ "@radix-ui/react-separator": "^1.1.1", "@radix-ui/react-slot": "^1.1.1", "@radix-ui/react-tooltip": "^1.1.8", + "@react-three/drei": "^9.122.0", + "@react-three/fiber": "^8.18.0", + "@react-three/rapier": "^1.5.0", "@tinybirdco/charts": "^0.2.4", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", @@ -25,11 +28,13 @@ "echarts": "^5.6.0", "echarts-for-react": "^3.0.2", "lucide-react": "^0.474.0", + "meshline": "^3.3.1", "next": "15.1.6", "react": "^18.2.0", "react-dom": "^18.2.0", "tailwind-merge": "^3.0.1", "tailwindcss-animate": "^1.0.7", + "three": "^0.167.1", "use-debounce": "^10.0.4", "zod": "^3.24.1" }, @@ -42,6 +47,7 @@ "eslint-config-next": "15.1.6", "postcss": "^8", "tailwindcss": "^3.4.1", - "typescript": "^5" + "typescript": "^5", + "url-loader": "^4.1.1" } } diff --git a/dashboard/log-analyzer/src/components/animations/SplashCursor/SplashCursor.tsx b/dashboard/log-analyzer/src/components/animations/SplashCursor/SplashCursor.tsx new file mode 100644 index 0000000..202eef5 --- /dev/null +++ b/dashboard/log-analyzer/src/components/animations/SplashCursor/SplashCursor.tsx @@ -0,0 +1,1546 @@ +"use client"; +import React, { useEffect, useRef } from "react"; + +interface ColorRGB { + r: number; + g: number; + b: number; +} + +interface SplashCursorProps { + SIM_RESOLUTION?: number; + DYE_RESOLUTION?: number; + CAPTURE_RESOLUTION?: number; + DENSITY_DISSIPATION?: number; + VELOCITY_DISSIPATION?: number; + PRESSURE?: number; + PRESSURE_ITERATIONS?: number; + CURL?: number; + SPLAT_RADIUS?: number; + SPLAT_FORCE?: number; + SHADING?: boolean; + COLOR_UPDATE_SPEED?: number; + BACK_COLOR?: ColorRGB; + TRANSPARENT?: boolean; +} + +interface Pointer { + id: number; + texcoordX: number; + texcoordY: number; + prevTexcoordX: number; + prevTexcoordY: number; + deltaX: number; + deltaY: number; + down: boolean; + moved: boolean; + color: ColorRGB; +} + +function pointerPrototype(): Pointer { + return { + id: -1, + texcoordX: 0, + texcoordY: 0, + prevTexcoordX: 0, + prevTexcoordY: 0, + deltaX: 0, + deltaY: 0, + down: false, + moved: false, + color: { r: 0, g: 0, b: 0 }, + }; +} + +export default function SplashCursor({ + SIM_RESOLUTION = 128, + DYE_RESOLUTION = 1440, + CAPTURE_RESOLUTION = 512, + DENSITY_DISSIPATION = 3.5, + VELOCITY_DISSIPATION = 2, + PRESSURE = 0.1, + PRESSURE_ITERATIONS = 20, + CURL = 3, + SPLAT_RADIUS = 0.2, + SPLAT_FORCE = 6000, + SHADING = true, + COLOR_UPDATE_SPEED = 10, + BACK_COLOR = { r: 0.5, g: 0, b: 0 }, + TRANSPARENT = true +}: SplashCursorProps) { + const canvasRef = useRef(null); + + useEffect(() => { + const canvas = canvasRef.current; + if (!canvas) return; // Guard canvas early + + // Pointer and config setup + let pointers: Pointer[] = [pointerPrototype()]; + + // All these are guaranteed numbers due to destructuring defaults + // So we cast them to remove TS warnings: + let config = { + SIM_RESOLUTION: SIM_RESOLUTION!, + DYE_RESOLUTION: DYE_RESOLUTION!, + CAPTURE_RESOLUTION: CAPTURE_RESOLUTION!, + DENSITY_DISSIPATION: DENSITY_DISSIPATION!, + VELOCITY_DISSIPATION: VELOCITY_DISSIPATION!, + PRESSURE: PRESSURE!, + PRESSURE_ITERATIONS: PRESSURE_ITERATIONS!, + CURL: CURL!, + SPLAT_RADIUS: SPLAT_RADIUS!, + SPLAT_FORCE: SPLAT_FORCE!, + SHADING, + COLOR_UPDATE_SPEED: COLOR_UPDATE_SPEED!, + PAUSED: false, + BACK_COLOR, + TRANSPARENT, + }; + + // Get WebGL context (WebGL1 or WebGL2) + const { gl, ext } = getWebGLContext(canvas); + if (!gl || !ext) return; + + // If no linear filtering, reduce resolution + if (!ext.supportLinearFiltering) { + config.DYE_RESOLUTION = 256; + config.SHADING = false; + } + + function getWebGLContext(canvas: HTMLCanvasElement) { + const params = { + alpha: true, + depth: false, + stencil: false, + antialias: false, + preserveDrawingBuffer: false, + }; + + let gl = canvas.getContext( + "webgl2", + params + ) as WebGL2RenderingContext | null; + + if (!gl) { + gl = (canvas.getContext("webgl", params) || + canvas.getContext( + "experimental-webgl", + params + )) as WebGL2RenderingContext | null; + } + + if (!gl) { + throw new Error("Unable to initialize WebGL."); + } + + const isWebGL2 = "drawBuffers" in gl; + + let supportLinearFiltering = false; + let halfFloat = null; + + if (isWebGL2) { + // For WebGL2 + (gl as WebGL2RenderingContext).getExtension("EXT_color_buffer_float"); + supportLinearFiltering = !!(gl as WebGL2RenderingContext).getExtension( + "OES_texture_float_linear" + ); + } else { + // For WebGL1 + halfFloat = gl.getExtension("OES_texture_half_float"); + supportLinearFiltering = !!gl.getExtension( + "OES_texture_half_float_linear" + ); + } + + gl.clearColor(0, 0, 0, 1); + + const halfFloatTexType = isWebGL2 + ? (gl as WebGL2RenderingContext).HALF_FLOAT + : (halfFloat && (halfFloat as any).HALF_FLOAT_OES) || 0; + + let formatRGBA: any; + let formatRG: any; + let formatR: any; + + if (isWebGL2) { + formatRGBA = getSupportedFormat( + gl, + (gl as WebGL2RenderingContext).RGBA16F, + gl.RGBA, + halfFloatTexType + ); + formatRG = getSupportedFormat( + gl, + (gl as WebGL2RenderingContext).RG16F, + (gl as WebGL2RenderingContext).RG, + halfFloatTexType + ); + formatR = getSupportedFormat( + gl, + (gl as WebGL2RenderingContext).R16F, + (gl as WebGL2RenderingContext).RED, + halfFloatTexType + ); + } else { + formatRGBA = getSupportedFormat(gl, gl.RGBA, gl.RGBA, halfFloatTexType); + formatRG = getSupportedFormat(gl, gl.RGBA, gl.RGBA, halfFloatTexType); + formatR = getSupportedFormat(gl, gl.RGBA, gl.RGBA, halfFloatTexType); + } + + return { + gl, + ext: { + formatRGBA, + formatRG, + formatR, + halfFloatTexType, + supportLinearFiltering, + }, + }; + } + + function getSupportedFormat( + gl: WebGLRenderingContext | WebGL2RenderingContext, + internalFormat: number, + format: number, + type: number + ): { internalFormat: number; format: number } | null { + if (!supportRenderTextureFormat(gl, internalFormat, format, type)) { + // For WebGL2 fallback: + if ("drawBuffers" in gl) { + const gl2 = gl as WebGL2RenderingContext; + switch (internalFormat) { + case gl2.R16F: + return getSupportedFormat(gl2, gl2.RG16F, gl2.RG, type); + case gl2.RG16F: + return getSupportedFormat(gl2, gl2.RGBA16F, gl2.RGBA, type); + default: + return null; + } + } + return null; + } + return { internalFormat, format }; + } + + function supportRenderTextureFormat( + gl: WebGLRenderingContext | WebGL2RenderingContext, + internalFormat: number, + format: number, + type: number + ) { + const texture = gl.createTexture(); + if (!texture) return false; + + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texImage2D( + gl.TEXTURE_2D, + 0, + internalFormat, + 4, + 4, + 0, + format, + type, + null + ); + + const fbo = gl.createFramebuffer(); + if (!fbo) return false; + + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); + gl.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + gl.TEXTURE_2D, + texture, + 0 + ); + const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER); + return status === gl.FRAMEBUFFER_COMPLETE; + } + + function hashCode(s: string) { + if (!s.length) return 0; + let hash = 0; + for (let i = 0; i < s.length; i++) { + hash = (hash << 5) - hash + s.charCodeAt(i); + hash |= 0; + } + return hash; + } + + function addKeywords(source: string, keywords: string[] | null) { + if (!keywords) return source; + let keywordsString = ""; + for (const keyword of keywords) { + keywordsString += `#define ${keyword}\n`; + } + return keywordsString + source; + } + + function compileShader( + type: number, + source: string, + keywords: string[] | null = null + ): WebGLShader | null { + const shaderSource = addKeywords(source, keywords); + const shader = gl.createShader(type); + if (!shader) return null; + gl.shaderSource(shader, shaderSource); + gl.compileShader(shader); + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + console.trace(gl.getShaderInfoLog(shader)); + } + return shader; + } + + function createProgram( + vertexShader: WebGLShader | null, + fragmentShader: WebGLShader | null + ): WebGLProgram | null { + if (!vertexShader || !fragmentShader) return null; + const program = gl.createProgram(); + if (!program) return null; + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragmentShader); + gl.linkProgram(program); + if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { + console.trace(gl.getProgramInfoLog(program)); + } + return program; + } + + function getUniforms(program: WebGLProgram) { + let uniforms: Record = {}; + const uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); + for (let i = 0; i < uniformCount; i++) { + const uniformInfo = gl.getActiveUniform(program, i); + if (uniformInfo) { + uniforms[uniformInfo.name] = gl.getUniformLocation( + program, + uniformInfo.name + ); + } + } + return uniforms; + } + + class Program { + program: WebGLProgram | null; + uniforms: Record; + + constructor( + vertexShader: WebGLShader | null, + fragmentShader: WebGLShader | null + ) { + this.program = createProgram(vertexShader, fragmentShader); + this.uniforms = this.program ? getUniforms(this.program) : {}; + } + + bind() { + if (this.program) gl.useProgram(this.program); + } + } + + class Material { + vertexShader: WebGLShader | null; + fragmentShaderSource: string; + programs: Record; + activeProgram: WebGLProgram | null; + uniforms: Record; + + constructor( + vertexShader: WebGLShader | null, + fragmentShaderSource: string + ) { + this.vertexShader = vertexShader; + this.fragmentShaderSource = fragmentShaderSource; + this.programs = {}; + this.activeProgram = null; + this.uniforms = {}; + } + + setKeywords(keywords: string[]) { + let hash = 0; + for (const kw of keywords) { + hash += hashCode(kw); + } + let program = this.programs[hash]; + if (program == null) { + const fragmentShader = compileShader( + gl.FRAGMENT_SHADER, + this.fragmentShaderSource, + keywords + ); + program = createProgram(this.vertexShader, fragmentShader); + this.programs[hash] = program; + } + if (program === this.activeProgram) return; + if (program) { + this.uniforms = getUniforms(program); + } + this.activeProgram = program; + } + + bind() { + if (this.activeProgram) { + gl.useProgram(this.activeProgram); + } + } + } + + // -------------------- Shaders -------------------- + const baseVertexShader = compileShader( + gl.VERTEX_SHADER, + ` + precision highp float; + attribute vec2 aPosition; + varying vec2 vUv; + varying vec2 vL; + varying vec2 vR; + varying vec2 vT; + varying vec2 vB; + uniform vec2 texelSize; + + void main () { + vUv = aPosition * 0.5 + 0.5; + vL = vUv - vec2(texelSize.x, 0.0); + vR = vUv + vec2(texelSize.x, 0.0); + vT = vUv + vec2(0.0, texelSize.y); + vB = vUv - vec2(0.0, texelSize.y); + gl_Position = vec4(aPosition, 0.0, 1.0); + } + ` + ); + + const copyShader = compileShader( + gl.FRAGMENT_SHADER, + ` + precision mediump float; + precision mediump sampler2D; + varying highp vec2 vUv; + uniform sampler2D uTexture; + + void main () { + gl_FragColor = texture2D(uTexture, vUv); + } + ` + ); + + const clearShader = compileShader( + gl.FRAGMENT_SHADER, + ` + precision mediump float; + precision mediump sampler2D; + varying highp vec2 vUv; + uniform sampler2D uTexture; + uniform float value; + + void main () { + gl_FragColor = value * texture2D(uTexture, vUv); + } + ` + ); + + const displayShaderSource = ` + precision highp float; + precision highp sampler2D; + varying vec2 vUv; + varying vec2 vL; + varying vec2 vR; + varying vec2 vT; + varying vec2 vB; + uniform sampler2D uTexture; + uniform sampler2D uDithering; + uniform vec2 ditherScale; + uniform vec2 texelSize; + + vec3 linearToGamma (vec3 color) { + color = max(color, vec3(0)); + return max(1.055 * pow(color, vec3(0.416666667)) - 0.055, vec3(0)); + } + + void main () { + vec3 c = texture2D(uTexture, vUv).rgb; + #ifdef SHADING + vec3 lc = texture2D(uTexture, vL).rgb; + vec3 rc = texture2D(uTexture, vR).rgb; + vec3 tc = texture2D(uTexture, vT).rgb; + vec3 bc = texture2D(uTexture, vB).rgb; + + float dx = length(rc) - length(lc); + float dy = length(tc) - length(bc); + + vec3 n = normalize(vec3(dx, dy, length(texelSize))); + vec3 l = vec3(0.0, 0.0, 1.0); + + float diffuse = clamp(dot(n, l) + 0.7, 0.7, 1.0); + c *= diffuse; + #endif + + float a = max(c.r, max(c.g, c.b)); + gl_FragColor = vec4(c, a); + } + `; + + const splatShader = compileShader( + gl.FRAGMENT_SHADER, + ` + precision highp float; + precision highp sampler2D; + varying vec2 vUv; + uniform sampler2D uTarget; + uniform float aspectRatio; + uniform vec3 color; + uniform vec2 point; + uniform float radius; + + void main () { + vec2 p = vUv - point.xy; + p.x *= aspectRatio; + vec3 splat = exp(-dot(p, p) / radius) * color; + vec3 base = texture2D(uTarget, vUv).xyz; + gl_FragColor = vec4(base + splat, 1.0); + } + ` + ); + + const advectionShader = compileShader( + gl.FRAGMENT_SHADER, + ` + precision highp float; + precision highp sampler2D; + varying vec2 vUv; + uniform sampler2D uVelocity; + uniform sampler2D uSource; + uniform vec2 texelSize; + uniform vec2 dyeTexelSize; + uniform float dt; + uniform float dissipation; + + vec4 bilerp (sampler2D sam, vec2 uv, vec2 tsize) { + vec2 st = uv / tsize - 0.5; + vec2 iuv = floor(st); + vec2 fuv = fract(st); + + vec4 a = texture2D(sam, (iuv + vec2(0.5, 0.5)) * tsize); + vec4 b = texture2D(sam, (iuv + vec2(1.5, 0.5)) * tsize); + vec4 c = texture2D(sam, (iuv + vec2(0.5, 1.5)) * tsize); + vec4 d = texture2D(sam, (iuv + vec2(1.5, 1.5)) * tsize); + + return mix(mix(a, b, fuv.x), mix(c, d, fuv.x), fuv.y); + } + + void main () { + #ifdef MANUAL_FILTERING + vec2 coord = vUv - dt * bilerp(uVelocity, vUv, texelSize).xy * texelSize; + vec4 result = bilerp(uSource, coord, dyeTexelSize); + #else + vec2 coord = vUv - dt * texture2D(uVelocity, vUv).xy * texelSize; + vec4 result = texture2D(uSource, coord); + #endif + float decay = 1.0 + dissipation * dt; + gl_FragColor = result / decay; + } + `, + ext.supportLinearFiltering ? null : ["MANUAL_FILTERING"] + ); + + const divergenceShader = compileShader( + gl.FRAGMENT_SHADER, + ` + precision mediump float; + precision mediump sampler2D; + varying highp vec2 vUv; + varying highp vec2 vL; + varying highp vec2 vR; + varying highp vec2 vT; + varying highp vec2 vB; + uniform sampler2D uVelocity; + + void main () { + float L = texture2D(uVelocity, vL).x; + float R = texture2D(uVelocity, vR).x; + float T = texture2D(uVelocity, vT).y; + float B = texture2D(uVelocity, vB).y; + + vec2 C = texture2D(uVelocity, vUv).xy; + if (vL.x < 0.0) { L = -C.x; } + if (vR.x > 1.0) { R = -C.x; } + if (vT.y > 1.0) { T = -C.y; } + if (vB.y < 0.0) { B = -C.y; } + + float div = 0.5 * (R - L + T - B); + gl_FragColor = vec4(div, 0.0, 0.0, 1.0); + } + ` + ); + + const curlShader = compileShader( + gl.FRAGMENT_SHADER, + ` + precision mediump float; + precision mediump sampler2D; + varying highp vec2 vUv; + varying highp vec2 vL; + varying highp vec2 vR; + varying highp vec2 vT; + varying highp vec2 vB; + uniform sampler2D uVelocity; + + void main () { + float L = texture2D(uVelocity, vL).y; + float R = texture2D(uVelocity, vR).y; + float T = texture2D(uVelocity, vT).x; + float B = texture2D(uVelocity, vB).x; + float vorticity = R - L - T + B; + gl_FragColor = vec4(0.5 * vorticity, 0.0, 0.0, 1.0); + } + ` + ); + + const vorticityShader = compileShader( + gl.FRAGMENT_SHADER, + ` + precision highp float; + precision highp sampler2D; + varying vec2 vUv; + varying vec2 vL; + varying vec2 vR; + varying vec2 vT; + varying vec2 vB; + uniform sampler2D uVelocity; + uniform sampler2D uCurl; + uniform float curl; + uniform float dt; + + void main () { + float L = texture2D(uCurl, vL).x; + float R = texture2D(uCurl, vR).x; + float T = texture2D(uCurl, vT).x; + float B = texture2D(uCurl, vB).x; + float C = texture2D(uCurl, vUv).x; + + vec2 force = 0.5 * vec2(abs(T) - abs(B), abs(R) - abs(L)); + force /= length(force) + 0.0001; + force *= curl * C; + force.y *= -1.0; + + vec2 velocity = texture2D(uVelocity, vUv).xy; + velocity += force * dt; + velocity = min(max(velocity, -1000.0), 1000.0); + gl_FragColor = vec4(velocity, 0.0, 1.0); + } + ` + ); + + const pressureShader = compileShader( + gl.FRAGMENT_SHADER, + ` + precision mediump float; + precision mediump sampler2D; + varying highp vec2 vUv; + varying highp vec2 vL; + varying highp vec2 vR; + varying highp vec2 vT; + varying highp vec2 vB; + uniform sampler2D uPressure; + uniform sampler2D uDivergence; + + void main () { + float L = texture2D(uPressure, vL).x; + float R = texture2D(uPressure, vR).x; + float T = texture2D(uPressure, vT).x; + float B = texture2D(uPressure, vB).x; + float C = texture2D(uPressure, vUv).x; + float divergence = texture2D(uDivergence, vUv).x; + float pressure = (L + R + B + T - divergence) * 0.25; + gl_FragColor = vec4(pressure, 0.0, 0.0, 1.0); + } + ` + ); + + const gradientSubtractShader = compileShader( + gl.FRAGMENT_SHADER, + ` + precision mediump float; + precision mediump sampler2D; + varying highp vec2 vUv; + varying highp vec2 vL; + varying highp vec2 vR; + varying highp vec2 vT; + varying highp vec2 vB; + uniform sampler2D uPressure; + uniform sampler2D uVelocity; + + void main () { + float L = texture2D(uPressure, vL).x; + float R = texture2D(uPressure, vR).x; + float T = texture2D(uPressure, vT).x; + float B = texture2D(uPressure, vB).x; + vec2 velocity = texture2D(uVelocity, vUv).xy; + velocity.xy -= vec2(R - L, T - B); + gl_FragColor = vec4(velocity, 0.0, 1.0); + } + ` + ); + + // -------------------- Fullscreen Triangles -------------------- + const blit = (() => { + const buffer = gl.createBuffer()!; + gl.bindBuffer(gl.ARRAY_BUFFER, buffer); + gl.bufferData( + gl.ARRAY_BUFFER, + new Float32Array([-1, -1, -1, 1, 1, 1, 1, -1]), + gl.STATIC_DRAW + ); + const elemBuffer = gl.createBuffer()!; + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elemBuffer); + gl.bufferData( + gl.ELEMENT_ARRAY_BUFFER, + new Uint16Array([0, 1, 2, 0, 2, 3]), + gl.STATIC_DRAW + ); + gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0); + gl.enableVertexAttribArray(0); + + return (target: FBO | null, doClear = false) => { + if (!gl) return; + if (!target) { + gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + } else { + gl.viewport(0, 0, target.width, target.height); + gl.bindFramebuffer(gl.FRAMEBUFFER, target.fbo); + } + if (doClear) { + gl.clearColor(0, 0, 0, 1); + gl.clear(gl.COLOR_BUFFER_BIT); + } + gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0); + }; + })(); + + // Types for Framebuffers + interface FBO { + texture: WebGLTexture; + fbo: WebGLFramebuffer; + width: number; + height: number; + texelSizeX: number; + texelSizeY: number; + attach: (id: number) => number; + } + + interface DoubleFBO { + width: number; + height: number; + texelSizeX: number; + texelSizeY: number; + read: FBO; + write: FBO; + swap: () => void; + } + + // FBO variables + let dye: DoubleFBO; + let velocity: DoubleFBO; + let divergence: FBO; + let curl: FBO; + let pressure: DoubleFBO; + + // WebGL Programs + const copyProgram = new Program(baseVertexShader, copyShader); + const clearProgram = new Program(baseVertexShader, clearShader); + const splatProgram = new Program(baseVertexShader, splatShader); + const advectionProgram = new Program(baseVertexShader, advectionShader); + const divergenceProgram = new Program(baseVertexShader, divergenceShader); + const curlProgram = new Program(baseVertexShader, curlShader); + const vorticityProgram = new Program(baseVertexShader, vorticityShader); + const pressureProgram = new Program(baseVertexShader, pressureShader); + const gradienSubtractProgram = new Program( + baseVertexShader, + gradientSubtractShader + ); + const displayMaterial = new Material(baseVertexShader, displayShaderSource); + + // -------------------- FBO creation -------------------- + function createFBO( + w: number, + h: number, + internalFormat: number, + format: number, + type: number, + param: number + ): FBO { + gl.activeTexture(gl.TEXTURE0); + const texture = gl.createTexture()!; + gl.bindTexture(gl.TEXTURE_2D, texture); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, param); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, param); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texImage2D( + gl.TEXTURE_2D, + 0, + internalFormat, + w, + h, + 0, + format, + type, + null + ); + const fbo = gl.createFramebuffer()!; + gl.bindFramebuffer(gl.FRAMEBUFFER, fbo); + gl.framebufferTexture2D( + gl.FRAMEBUFFER, + gl.COLOR_ATTACHMENT0, + gl.TEXTURE_2D, + texture, + 0 + ); + gl.viewport(0, 0, w, h); + gl.clear(gl.COLOR_BUFFER_BIT); + + const texelSizeX = 1 / w; + const texelSizeY = 1 / h; + + return { + texture, + fbo, + width: w, + height: h, + texelSizeX, + texelSizeY, + attach(id: number) { + gl.activeTexture(gl.TEXTURE0 + id); + gl.bindTexture(gl.TEXTURE_2D, texture); + return id; + }, + }; + } + + function createDoubleFBO( + w: number, + h: number, + internalFormat: number, + format: number, + type: number, + param: number + ): DoubleFBO { + const fbo1 = createFBO(w, h, internalFormat, format, type, param); + const fbo2 = createFBO(w, h, internalFormat, format, type, param); + return { + width: w, + height: h, + texelSizeX: fbo1.texelSizeX, + texelSizeY: fbo1.texelSizeY, + read: fbo1, + write: fbo2, + swap() { + const tmp = this.read; + this.read = this.write; + this.write = tmp; + }, + }; + } + + function resizeFBO( + target: FBO, + w: number, + h: number, + internalFormat: number, + format: number, + type: number, + param: number + ) { + const newFBO = createFBO(w, h, internalFormat, format, type, param); + copyProgram.bind(); + if (copyProgram.uniforms.uTexture) + gl.uniform1i(copyProgram.uniforms.uTexture, target.attach(0)); + blit(newFBO, false); + return newFBO; + } + + function resizeDoubleFBO( + target: DoubleFBO, + w: number, + h: number, + internalFormat: number, + format: number, + type: number, + param: number + ) { + if (target.width === w && target.height === h) return target; + target.read = resizeFBO( + target.read, + w, + h, + internalFormat, + format, + type, + param + ); + target.write = createFBO(w, h, internalFormat, format, type, param); + target.width = w; + target.height = h; + target.texelSizeX = 1 / w; + target.texelSizeY = 1 / h; + return target; + } + + function initFramebuffers() { + const simRes = getResolution(config.SIM_RESOLUTION!); + const dyeRes = getResolution(config.DYE_RESOLUTION!); + + const texType = ext.halfFloatTexType; + const rgba = ext.formatRGBA; + const rg = ext.formatRG; + const r = ext.formatR; + const filtering = ext.supportLinearFiltering ? gl.LINEAR : gl.NEAREST; + gl.disable(gl.BLEND); + + if (!dye) { + dye = createDoubleFBO( + dyeRes.width, + dyeRes.height, + rgba.internalFormat, + rgba.format, + texType, + filtering + ); + } else { + dye = resizeDoubleFBO( + dye, + dyeRes.width, + dyeRes.height, + rgba.internalFormat, + rgba.format, + texType, + filtering + ); + } + + if (!velocity) { + velocity = createDoubleFBO( + simRes.width, + simRes.height, + rg.internalFormat, + rg.format, + texType, + filtering + ); + } else { + velocity = resizeDoubleFBO( + velocity, + simRes.width, + simRes.height, + rg.internalFormat, + rg.format, + texType, + filtering + ); + } + + divergence = createFBO( + simRes.width, + simRes.height, + r.internalFormat, + r.format, + texType, + gl.NEAREST + ); + curl = createFBO( + simRes.width, + simRes.height, + r.internalFormat, + r.format, + texType, + gl.NEAREST + ); + pressure = createDoubleFBO( + simRes.width, + simRes.height, + r.internalFormat, + r.format, + texType, + gl.NEAREST + ); + } + + function updateKeywords() { + const displayKeywords: string[] = []; + if (config.SHADING) displayKeywords.push("SHADING"); + displayMaterial.setKeywords(displayKeywords); + } + + function getResolution(resolution: number) { + const w = gl.drawingBufferWidth; + const h = gl.drawingBufferHeight; + const aspectRatio = w / h; + let aspect = aspectRatio < 1 ? 1 / aspectRatio : aspectRatio; + const min = Math.round(resolution); + const max = Math.round(resolution * aspect); + if (w > h) { + return { width: max, height: min }; + } + return { width: min, height: max }; + } + + function scaleByPixelRatio(input: number) { + const pixelRatio = window.devicePixelRatio || 1; + return Math.floor(input * pixelRatio); + } + + // -------------------- Simulation Setup -------------------- + updateKeywords(); + initFramebuffers(); + + let lastUpdateTime = Date.now(); + let colorUpdateTimer = 0.0; + + function updateFrame() { + const dt = calcDeltaTime(); + if (resizeCanvas()) initFramebuffers(); + updateColors(dt); + applyInputs(); + step(dt); + render(null); + requestAnimationFrame(updateFrame); + } + + function calcDeltaTime() { + const now = Date.now(); + let dt = (now - lastUpdateTime) / 1000; + dt = Math.min(dt, 0.016666); + lastUpdateTime = now; + return dt; + } + + function resizeCanvas() { + const width = scaleByPixelRatio(canvas!.clientWidth); + const height = scaleByPixelRatio(canvas!.clientHeight); + if (canvas!.width !== width || canvas!.height !== height) { + canvas!.width = width; + canvas!.height = height; + return true; + } + return false; + } + + function updateColors(dt: number) { + colorUpdateTimer += dt * config.COLOR_UPDATE_SPEED; + if (colorUpdateTimer >= 1) { + colorUpdateTimer = wrap(colorUpdateTimer, 0, 1); + pointers.forEach((p) => { + p.color = generateColor(); + }); + } + } + + function applyInputs() { + for (const p of pointers) { + if (p.moved) { + p.moved = false; + splatPointer(p); + } + } + } + + function step(dt: number) { + gl.disable(gl.BLEND); + + // Curl + curlProgram.bind(); + if (curlProgram.uniforms.texelSize) { + gl.uniform2f( + curlProgram.uniforms.texelSize, + velocity.texelSizeX, + velocity.texelSizeY + ); + } + if (curlProgram.uniforms.uVelocity) { + gl.uniform1i(curlProgram.uniforms.uVelocity, velocity.read.attach(0)); + } + blit(curl); + + // Vorticity + vorticityProgram.bind(); + if (vorticityProgram.uniforms.texelSize) { + gl.uniform2f( + vorticityProgram.uniforms.texelSize, + velocity.texelSizeX, + velocity.texelSizeY + ); + } + if (vorticityProgram.uniforms.uVelocity) { + gl.uniform1i( + vorticityProgram.uniforms.uVelocity, + velocity.read.attach(0) + ); + } + if (vorticityProgram.uniforms.uCurl) { + gl.uniform1i(vorticityProgram.uniforms.uCurl, curl.attach(1)); + } + if (vorticityProgram.uniforms.curl) { + gl.uniform1f(vorticityProgram.uniforms.curl, config.CURL); + } + if (vorticityProgram.uniforms.dt) { + gl.uniform1f(vorticityProgram.uniforms.dt, dt); + } + blit(velocity.write); + velocity.swap(); + + // Divergence + divergenceProgram.bind(); + if (divergenceProgram.uniforms.texelSize) { + gl.uniform2f( + divergenceProgram.uniforms.texelSize, + velocity.texelSizeX, + velocity.texelSizeY + ); + } + if (divergenceProgram.uniforms.uVelocity) { + gl.uniform1i( + divergenceProgram.uniforms.uVelocity, + velocity.read.attach(0) + ); + } + blit(divergence); + + // Clear pressure + clearProgram.bind(); + if (clearProgram.uniforms.uTexture) { + gl.uniform1i(clearProgram.uniforms.uTexture, pressure.read.attach(0)); + } + if (clearProgram.uniforms.value) { + gl.uniform1f(clearProgram.uniforms.value, config.PRESSURE); + } + blit(pressure.write); + pressure.swap(); + + // Pressure + pressureProgram.bind(); + if (pressureProgram.uniforms.texelSize) { + gl.uniform2f( + pressureProgram.uniforms.texelSize, + velocity.texelSizeX, + velocity.texelSizeY + ); + } + if (pressureProgram.uniforms.uDivergence) { + gl.uniform1i( + pressureProgram.uniforms.uDivergence, + divergence.attach(0) + ); + } + for (let i = 0; i < config.PRESSURE_ITERATIONS; i++) { + if (pressureProgram.uniforms.uPressure) { + gl.uniform1i( + pressureProgram.uniforms.uPressure, + pressure.read.attach(1) + ); + } + blit(pressure.write); + pressure.swap(); + } + + // Gradient Subtract + gradienSubtractProgram.bind(); + if (gradienSubtractProgram.uniforms.texelSize) { + gl.uniform2f( + gradienSubtractProgram.uniforms.texelSize, + velocity.texelSizeX, + velocity.texelSizeY + ); + } + if (gradienSubtractProgram.uniforms.uPressure) { + gl.uniform1i( + gradienSubtractProgram.uniforms.uPressure, + pressure.read.attach(0) + ); + } + if (gradienSubtractProgram.uniforms.uVelocity) { + gl.uniform1i( + gradienSubtractProgram.uniforms.uVelocity, + velocity.read.attach(1) + ); + } + blit(velocity.write); + velocity.swap(); + + // Advection - velocity + advectionProgram.bind(); + if (advectionProgram.uniforms.texelSize) { + gl.uniform2f( + advectionProgram.uniforms.texelSize, + velocity.texelSizeX, + velocity.texelSizeY + ); + } + if ( + !ext.supportLinearFiltering && + advectionProgram.uniforms.dyeTexelSize + ) { + gl.uniform2f( + advectionProgram.uniforms.dyeTexelSize, + velocity.texelSizeX, + velocity.texelSizeY + ); + } + const velocityId = velocity.read.attach(0); + if (advectionProgram.uniforms.uVelocity) { + gl.uniform1i(advectionProgram.uniforms.uVelocity, velocityId); + } + if (advectionProgram.uniforms.uSource) { + gl.uniform1i(advectionProgram.uniforms.uSource, velocityId); + } + if (advectionProgram.uniforms.dt) { + gl.uniform1f(advectionProgram.uniforms.dt, dt); + } + if (advectionProgram.uniforms.dissipation) { + gl.uniform1f( + advectionProgram.uniforms.dissipation, + config.VELOCITY_DISSIPATION + ); + } + blit(velocity.write); + velocity.swap(); + + // Advection - dye + if ( + !ext.supportLinearFiltering && + advectionProgram.uniforms.dyeTexelSize + ) { + gl.uniform2f( + advectionProgram.uniforms.dyeTexelSize, + dye.texelSizeX, + dye.texelSizeY + ); + } + if (advectionProgram.uniforms.uVelocity) { + gl.uniform1i( + advectionProgram.uniforms.uVelocity, + velocity.read.attach(0) + ); + } + if (advectionProgram.uniforms.uSource) { + gl.uniform1i(advectionProgram.uniforms.uSource, dye.read.attach(1)); + } + if (advectionProgram.uniforms.dissipation) { + gl.uniform1f( + advectionProgram.uniforms.dissipation, + config.DENSITY_DISSIPATION + ); + } + blit(dye.write); + dye.swap(); + } + + function render(target: FBO | null) { + gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + gl.enable(gl.BLEND); + drawDisplay(target); + } + + function drawDisplay(target: FBO | null) { + const width = target ? target.width : gl.drawingBufferWidth; + const height = target ? target.height : gl.drawingBufferHeight; + displayMaterial.bind(); + if (config.SHADING && displayMaterial.uniforms.texelSize) { + gl.uniform2f(displayMaterial.uniforms.texelSize, 1 / width, 1 / height); + } + if (displayMaterial.uniforms.uTexture) { + gl.uniform1i(displayMaterial.uniforms.uTexture, dye.read.attach(0)); + } + blit(target, false); + } + + // -------------------- Interaction -------------------- + function splatPointer(pointer: Pointer) { + const dx = pointer.deltaX * config.SPLAT_FORCE; + const dy = pointer.deltaY * config.SPLAT_FORCE; + splat(pointer.texcoordX, pointer.texcoordY, dx, dy, pointer.color); + } + + function clickSplat(pointer: Pointer) { + const color = generateColor(); + color.r *= 10; + color.g *= 10; + color.b *= 10; + const dx = 10 * (Math.random() - 0.5); + const dy = 30 * (Math.random() - 0.5); + splat(pointer.texcoordX, pointer.texcoordY, dx, dy, color); + } + + function splat( + x: number, + y: number, + dx: number, + dy: number, + color: ColorRGB + ) { + splatProgram.bind(); + if (splatProgram.uniforms.uTarget) { + gl.uniform1i(splatProgram.uniforms.uTarget, velocity.read.attach(0)); + } + if (splatProgram.uniforms.aspectRatio) { + gl.uniform1f( + splatProgram.uniforms.aspectRatio, + canvas!.width / canvas!.height + ); + } + if (splatProgram.uniforms.point) { + gl.uniform2f(splatProgram.uniforms.point, x, y); + } + if (splatProgram.uniforms.color) { + gl.uniform3f(splatProgram.uniforms.color, dx, dy, 0); + } + if (splatProgram.uniforms.radius) { + gl.uniform1f( + splatProgram.uniforms.radius, + correctRadius(config.SPLAT_RADIUS / 100)! + ); + } + blit(velocity.write); + velocity.swap(); + + if (splatProgram.uniforms.uTarget) { + gl.uniform1i(splatProgram.uniforms.uTarget, dye.read.attach(0)); + } + if (splatProgram.uniforms.color) { + gl.uniform3f(splatProgram.uniforms.color, color.r, color.g, color.b); + } + blit(dye.write); + dye.swap(); + } + + function correctRadius(radius: number) { + // Use non-null assertion (canvas can't be null here) + const aspectRatio = canvas!.width / canvas!.height; + if (aspectRatio > 1) radius *= aspectRatio; + return radius; + } + + function updatePointerDownData( + pointer: Pointer, + id: number, + posX: number, + posY: number + ) { + pointer.id = id; + pointer.down = true; + pointer.moved = false; + pointer.texcoordX = posX / canvas!.width; + pointer.texcoordY = 1 - posY / canvas!.height; + pointer.prevTexcoordX = pointer.texcoordX; + pointer.prevTexcoordY = pointer.texcoordY; + pointer.deltaX = 0; + pointer.deltaY = 0; + pointer.color = generateColor(); + } + + function updatePointerMoveData( + pointer: Pointer, + posX: number, + posY: number, + color: ColorRGB + ) { + pointer.prevTexcoordX = pointer.texcoordX; + pointer.prevTexcoordY = pointer.texcoordY; + pointer.texcoordX = posX / canvas!.width; + pointer.texcoordY = 1 - posY / canvas!.height; + pointer.deltaX = correctDeltaX( + pointer.texcoordX - pointer.prevTexcoordX + )!; + pointer.deltaY = correctDeltaY( + pointer.texcoordY - pointer.prevTexcoordY + )!; + pointer.moved = + Math.abs(pointer.deltaX) > 0 || Math.abs(pointer.deltaY) > 0; + pointer.color = color; + } + + function updatePointerUpData(pointer: Pointer) { + pointer.down = false; + } + + function correctDeltaX(delta: number) { + const aspectRatio = canvas!.width / canvas!.height; + if (aspectRatio < 1) delta *= aspectRatio; + return delta; + } + + function correctDeltaY(delta: number) { + const aspectRatio = canvas!.width / canvas!.height; + if (aspectRatio > 1) delta /= aspectRatio; + return delta; + } + + function generateColor(): ColorRGB { + const c = HSVtoRGB(Math.random(), 1.0, 1.0); + c.r *= 0.15; + c.g *= 0.15; + c.b *= 0.15; + return c; + } + + function HSVtoRGB(h: number, s: number, v: number): ColorRGB { + let r = 0, + g = 0, + b = 0; + const i = Math.floor(h * 6); + const f = h * 6 - i; + const p = v * (1 - s); + const q = v * (1 - f * s); + const t = v * (1 - (1 - f) * s); + + switch (i % 6) { + case 0: + r = v; + g = t; + b = p; + break; + case 1: + r = q; + g = v; + b = p; + break; + case 2: + r = p; + g = v; + b = t; + break; + case 3: + r = p; + g = q; + b = v; + break; + case 4: + r = t; + g = p; + b = v; + break; + case 5: + r = v; + g = p; + b = q; + break; + } + return { r, g, b }; + } + + function wrap(value: number, min: number, max: number) { + const range = max - min; + if (range === 0) return min; + return ((value - min) % range) + min; + } + + // -------------------- Event Listeners -------------------- + window.addEventListener("mousedown", (e) => { + const pointer = pointers[0]; + const posX = scaleByPixelRatio(e.clientX); + const posY = scaleByPixelRatio(e.clientY); + updatePointerDownData(pointer, -1, posX, posY); + clickSplat(pointer); + }); + + // Start rendering on first mouse move + function handleFirstMouseMove(e: MouseEvent) { + const pointer = pointers[0]; + const posX = scaleByPixelRatio(e.clientX); + const posY = scaleByPixelRatio(e.clientY); + const color = generateColor(); + updateFrame(); + updatePointerMoveData(pointer, posX, posY, color); + document.body.removeEventListener("mousemove", handleFirstMouseMove); + } + document.body.addEventListener("mousemove", handleFirstMouseMove); + + window.addEventListener("mousemove", (e) => { + const pointer = pointers[0]; + const posX = scaleByPixelRatio(e.clientX); + const posY = scaleByPixelRatio(e.clientY); + const color = pointer.color; + updatePointerMoveData(pointer, posX, posY, color); + }); + + // Start rendering on first touch + function handleFirstTouchStart(e: TouchEvent) { + const touches = e.targetTouches; + const pointer = pointers[0]; + for (let i = 0; i < touches.length; i++) { + const posX = scaleByPixelRatio(touches[i].clientX); + const posY = scaleByPixelRatio(touches[i].clientY); + updateFrame(); + updatePointerDownData(pointer, touches[i].identifier, posX, posY); + } + document.body.removeEventListener("touchstart", handleFirstTouchStart); + } + document.body.addEventListener("touchstart", handleFirstTouchStart); + + window.addEventListener( + "touchstart", + (e) => { + const touches = e.targetTouches; + const pointer = pointers[0]; + for (let i = 0; i < touches.length; i++) { + const posX = scaleByPixelRatio(touches[i].clientX); + const posY = scaleByPixelRatio(touches[i].clientY); + updatePointerDownData(pointer, touches[i].identifier, posX, posY); + } + }, + false + ); + + window.addEventListener( + "touchmove", + (e) => { + const touches = e.targetTouches; + const pointer = pointers[0]; + for (let i = 0; i < touches.length; i++) { + const posX = scaleByPixelRatio(touches[i].clientX); + const posY = scaleByPixelRatio(touches[i].clientY); + updatePointerMoveData(pointer, posX, posY, pointer.color); + } + }, + false + ); + + window.addEventListener("touchend", (e) => { + const touches = e.changedTouches; + const pointer = pointers[0]; + for (let i = 0; i < touches.length; i++) { + updatePointerUpData(pointer); + } + }); + // ------------------------------------------------------------ + }, [ + SIM_RESOLUTION, + DYE_RESOLUTION, + CAPTURE_RESOLUTION, + DENSITY_DISSIPATION, + VELOCITY_DISSIPATION, + PRESSURE, + PRESSURE_ITERATIONS, + CURL, + SPLAT_RADIUS, + SPLAT_FORCE, + SHADING, + COLOR_UPDATE_SPEED, + BACK_COLOR, + TRANSPARENT, + ]); + + return ( +
+ +
+ ); +} diff --git a/dashboard/log-analyzer/src/components/layout/Sidebar.tsx b/dashboard/log-analyzer/src/components/layout/Sidebar.tsx index ce94c9c..785e012 100644 --- a/dashboard/log-analyzer/src/components/layout/Sidebar.tsx +++ b/dashboard/log-analyzer/src/components/layout/Sidebar.tsx @@ -6,10 +6,12 @@ import { useRouter, useSearchParams, usePathname } from "next/navigation"; import { Button } from "@/components/ui/button"; import { cn } from "@/lib/utils"; import { CollapseIcon, ExpandIcon } from "@/components/icons"; +import SplashCursor from '@/components/animations/SplashCursor/SplashCursor' export default function Sidebar() { const [isCollapsed, setIsCollapsed] = useState(false); const [refreshTrigger, setRefreshTrigger] = useState(false); + const [showSplashCursor, setShowSplashCursor] = useState(false); const router = useRouter(); const pathname = usePathname(); const searchParams = useSearchParams(); @@ -24,6 +26,30 @@ export default function Sidebar() { return () => window.removeEventListener('refresh-filters', handleRefresh); }, []); + // Add Konami code detection + useEffect(() => { + const konamiCode = ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight', 'b', 'a']; + let konamiIndex = 0; + + const handleKeydown = (e: KeyboardEvent) => { + const key = e.key.toLowerCase(); + const requiredKey = konamiCode[konamiIndex].toLowerCase(); + + if (key === requiredKey) { + konamiIndex++; + if (konamiIndex === konamiCode.length) { + setShowSplashCursor(true); + konamiIndex = 0; + } + } else { + konamiIndex = 0; + } + }; + + window.addEventListener('keydown', handleKeydown); + return () => window.removeEventListener('keydown', handleKeydown); + }, []); + // Update URL with new filters const createFilterHandler = useCallback((filterName: string) => { return (selected: string[]) => { @@ -47,10 +73,23 @@ export default function Sidebar() { setIsCollapsed(true); }; + const handleProductHunt = () => { + window.open('https://www.producthunt.com/posts/log-analyzer', '_blank'); + }; + + const handleGitHub = () => { + window.open('https://github.com/tinybirdco/logs-explorer-template/fork', '_blank'); + }; + + const handleShowHN = () => { + window.open('https://news.ycombinator.com/item?id=yourpostid', '_blank'); + }; + return ( From 1399ec3a856593d0c9984e49ae2880c36020e4ad Mon Sep 17 00:00:00 2001 From: alrocar Date: Tue, 25 Feb 2025 11:53:29 +0100 Subject: [PATCH 02/12] linter --- .../animations/SplashCursor/SplashCursor.tsx | 12 ++++++++---- .../log-analyzer/src/components/layout/Sidebar.tsx | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/dashboard/log-analyzer/src/components/animations/SplashCursor/SplashCursor.tsx b/dashboard/log-analyzer/src/components/animations/SplashCursor/SplashCursor.tsx index 202eef5..9507352 100644 --- a/dashboard/log-analyzer/src/components/animations/SplashCursor/SplashCursor.tsx +++ b/dashboard/log-analyzer/src/components/animations/SplashCursor/SplashCursor.tsx @@ -75,11 +75,11 @@ export default function SplashCursor({ if (!canvas) return; // Guard canvas early // Pointer and config setup - let pointers: Pointer[] = [pointerPrototype()]; + const pointers: Pointer[] = [pointerPrototype()]; // All these are guaranteed numbers due to destructuring defaults // So we cast them to remove TS warnings: - let config = { + const config = { SIM_RESOLUTION: SIM_RESOLUTION!, DYE_RESOLUTION: DYE_RESOLUTION!, CAPTURE_RESOLUTION: CAPTURE_RESOLUTION!, @@ -156,10 +156,14 @@ export default function SplashCursor({ const halfFloatTexType = isWebGL2 ? (gl as WebGL2RenderingContext).HALF_FLOAT + // eslint-disable-next-line @typescript-eslint/no-explicit-any : (halfFloat && (halfFloat as any).HALF_FLOAT_OES) || 0; + // eslint-disable-next-line @typescript-eslint/no-explicit-any let formatRGBA: any; + // eslint-disable-next-line @typescript-eslint/no-explicit-any let formatRG: any; + // eslint-disable-next-line @typescript-eslint/no-explicit-any let formatR: any; if (isWebGL2) { @@ -316,7 +320,7 @@ export default function SplashCursor({ } function getUniforms(program: WebGLProgram) { - let uniforms: Record = {}; + const uniforms: Record = {}; const uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); for (let i = 0; i < uniformCount; i++) { const uniformInfo = gl.getActiveUniform(program, i); @@ -984,7 +988,7 @@ export default function SplashCursor({ const w = gl.drawingBufferWidth; const h = gl.drawingBufferHeight; const aspectRatio = w / h; - let aspect = aspectRatio < 1 ? 1 / aspectRatio : aspectRatio; + const aspect = aspectRatio < 1 ? 1 / aspectRatio : aspectRatio; const min = Math.round(resolution); const max = Math.round(resolution * aspect); if (w > h) { diff --git a/dashboard/log-analyzer/src/components/layout/Sidebar.tsx b/dashboard/log-analyzer/src/components/layout/Sidebar.tsx index 785e012..36140ab 100644 --- a/dashboard/log-analyzer/src/components/layout/Sidebar.tsx +++ b/dashboard/log-analyzer/src/components/layout/Sidebar.tsx @@ -199,7 +199,7 @@ export default function Sidebar() { className="block w-full" > Fork on GitHub From 96952260575cd2c7b99bc5c461bfa365cb96479e Mon Sep 17 00:00:00 2001 From: alrocar Date: Tue, 25 Feb 2025 12:10:41 +0100 Subject: [PATCH 03/12] update --- dashboard/log-analyzer/src/components/layout/Sidebar.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dashboard/log-analyzer/src/components/layout/Sidebar.tsx b/dashboard/log-analyzer/src/components/layout/Sidebar.tsx index 36140ab..f910efa 100644 --- a/dashboard/log-analyzer/src/components/layout/Sidebar.tsx +++ b/dashboard/log-analyzer/src/components/layout/Sidebar.tsx @@ -74,7 +74,7 @@ export default function Sidebar() { }; const handleProductHunt = () => { - window.open('https://www.producthunt.com/posts/log-analyzer', '_blank'); + window.open('https://www.producthunt.com/posts/habitgo', '_blank'); }; const handleGitHub = () => { @@ -178,7 +178,7 @@ export default function Sidebar() { {/* Updated bottom section */}
Date: Tue, 25 Feb 2025 12:48:49 +0100 Subject: [PATCH 04/12] fix --- .../animations/SplashCursor/SplashCursor.tsx | 4 ++-- .../src/components/layout/Sidebar.tsx | 17 ++++++++++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/dashboard/log-analyzer/src/components/animations/SplashCursor/SplashCursor.tsx b/dashboard/log-analyzer/src/components/animations/SplashCursor/SplashCursor.tsx index 9507352..aeffe11 100644 --- a/dashboard/log-analyzer/src/components/animations/SplashCursor/SplashCursor.tsx +++ b/dashboard/log-analyzer/src/components/animations/SplashCursor/SplashCursor.tsx @@ -56,12 +56,12 @@ export default function SplashCursor({ SIM_RESOLUTION = 128, DYE_RESOLUTION = 1440, CAPTURE_RESOLUTION = 512, - DENSITY_DISSIPATION = 3.5, + DENSITY_DISSIPATION = 1.5, VELOCITY_DISSIPATION = 2, PRESSURE = 0.1, PRESSURE_ITERATIONS = 20, CURL = 3, - SPLAT_RADIUS = 0.2, + SPLAT_RADIUS = 0.5, SPLAT_FORCE = 6000, SHADING = true, COLOR_UPDATE_SPEED = 10, diff --git a/dashboard/log-analyzer/src/components/layout/Sidebar.tsx b/dashboard/log-analyzer/src/components/layout/Sidebar.tsx index f910efa..b6ef961 100644 --- a/dashboard/log-analyzer/src/components/layout/Sidebar.tsx +++ b/dashboard/log-analyzer/src/components/layout/Sidebar.tsx @@ -26,7 +26,7 @@ export default function Sidebar() { return () => window.removeEventListener('refresh-filters', handleRefresh); }, []); - // Add Konami code detection + // Keep the Konami code effect useEffect(() => { const konamiCode = ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight', 'b', 'a']; let konamiIndex = 0; @@ -73,8 +73,15 @@ export default function Sidebar() { setIsCollapsed(true); }; + const handleSocialClick = (callback: () => void) => { + return () => { + setShowSplashCursor(true); + callback(); + }; + }; + const handleProductHunt = () => { - window.open('https://www.producthunt.com/posts/habitgo', '_blank'); + window.open('https://www.producthunt.com/posts/log-analyzer?utm_source=badge-featured', '_blank'); }; const handleGitHub = () => { @@ -181,7 +188,7 @@ export default function Sidebar() { href="https://www.producthunt.com/posts/habitgo?utm_source=badge-featured" target="_blank" rel="noopener noreferrer" - onClick={handleProductHunt} + onClick={handleSocialClick(handleProductHunt)} className="block w-full" > Show HN From ddee49765818d135bac399b4477cc02bc238cdf5 Mon Sep 17 00:00:00 2001 From: alrocar Date: Tue, 25 Feb 2025 12:58:11 +0100 Subject: [PATCH 05/12] fix --- dashboard/log-analyzer/src/components/layout/Sidebar.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dashboard/log-analyzer/src/components/layout/Sidebar.tsx b/dashboard/log-analyzer/src/components/layout/Sidebar.tsx index b6ef961..351fcf1 100644 --- a/dashboard/log-analyzer/src/components/layout/Sidebar.tsx +++ b/dashboard/log-analyzer/src/components/layout/Sidebar.tsx @@ -212,7 +212,7 @@ export default function Sidebar() { /> - Show HN - + */}
)} From 2560d58ae26ec4e14bfdd44a56672b0c60c97e0e Mon Sep 17 00:00:00 2001 From: alrocar Date: Tue, 25 Feb 2025 13:01:38 +0100 Subject: [PATCH 06/12] fix --- dashboard/log-analyzer/src/components/layout/Sidebar.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dashboard/log-analyzer/src/components/layout/Sidebar.tsx b/dashboard/log-analyzer/src/components/layout/Sidebar.tsx index 351fcf1..f1adce0 100644 --- a/dashboard/log-analyzer/src/components/layout/Sidebar.tsx +++ b/dashboard/log-analyzer/src/components/layout/Sidebar.tsx @@ -88,9 +88,9 @@ export default function Sidebar() { window.open('https://github.com/tinybirdco/logs-explorer-template/fork', '_blank'); }; - const handleShowHN = () => { - window.open('https://news.ycombinator.com/item?id=yourpostid', '_blank'); - }; + // const handleShowHN = () => { + // window.open('https://news.ycombinator.com/item?id=yourpostid', '_blank'); + // }; return (