diff --git a/components.json b/components.json
new file mode 100644
index 00000000..63bdcbe8
--- /dev/null
+++ b/components.json
@@ -0,0 +1,17 @@
+{
+ "$schema": "https://ui.shadcn.com/schema.json",
+ "style": "new-york",
+ "rsc": false,
+ "tsx": true,
+ "tailwind": {
+ "config": "tailwind.config.js",
+ "css": "src/index.css",
+ "baseColor": "zinc",
+ "cssVariables": true,
+ "prefix": ""
+ },
+ "aliases": {
+ "components": "@/components",
+ "utils": "@/lib/utils"
+ }
+}
diff --git a/index.html b/index.html
index 4411938b..674c9e10 100644
--- a/index.html
+++ b/index.html
@@ -10,15 +10,13 @@
vizarr
+
-
+
-
diff --git a/package.json b/package.json
index c527dd7e..0b90edae 100644
--- a/package.json
+++ b/package.json
@@ -12,12 +12,18 @@
},
"dependencies": {
"@hms-dbmi/viv": "~0.17.2",
- "@material-ui/core": "^4.11.0",
- "@material-ui/icons": "^4.9.1",
- "@material-ui/styles": "^4.11.5",
- "@vivjs/types": "~0.17.0",
- "@zarrita/storage": "0.1.0",
- "deck.gl": "~9.0.0",
+ "@radix-ui/react-accordion": "^1.2.3",
+ "@radix-ui/react-icons": "^1.3.2",
+ "@radix-ui/react-popover": "^1.1.6",
+ "@radix-ui/react-select": "^2.1.6",
+ "@radix-ui/react-separator": "^1.1.2",
+ "@radix-ui/react-slider": "^1.2.3",
+ "@radix-ui/react-slot": "^1.1.2",
+ "@vivjs/types": "^0.17.2",
+ "@zarrita/storage": "^0.1.0",
+ "class-variance-authority": "^0.7.0",
+ "clsx": "^2.1.1",
+ "deck.gl": "~9.0.41",
"jotai": "^1.0.0",
"just-debounce-it": "^3.1.1",
"math.gl": "^4.1.0",
@@ -25,10 +31,13 @@
"quick-lru": "^7.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
- "zarrita": "0.5.0"
+ "tailwind-merge": "^3.0.2",
+ "tailwindcss": "^4.0.12",
+ "zarrita": "~0.5.0"
},
"devDependencies": {
"@biomejs/biome": "^1.9.4",
+ "@tailwindcss/vite": "^4.0.12",
"@types/node": "^22.13.5",
"@types/react": "^18.3.10",
"@types/react-dom": "^18.2.18",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index b373e04c..9cff5e29 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -16,27 +16,45 @@ importers:
'@hms-dbmi/viv':
specifier: ~0.17.2
version: 0.17.2(@deck.gl/core@9.0.41)(@deck.gl/geo-layers@9.0.41(@deck.gl/core@9.0.41)(@deck.gl/extensions@9.0.41(@deck.gl/core@9.0.41)(@luma.gl/core@9.0.28)(@luma.gl/engine@9.0.28(@luma.gl/core@9.0.28)))(@deck.gl/layers@9.0.41(@deck.gl/core@9.0.41)(@loaders.gl/core@4.3.3)(@luma.gl/core@9.0.28)(@luma.gl/engine@9.0.28(@luma.gl/core@9.0.28)))(@deck.gl/mesh-layers@9.0.41(@deck.gl/core@9.0.41)(@loaders.gl/core@4.3.3)(@luma.gl/core@9.0.28)(@luma.gl/engine@9.0.28(@luma.gl/core@9.0.28)))(@loaders.gl/core@4.3.3)(@luma.gl/core@9.0.28)(@luma.gl/engine@9.0.28(@luma.gl/core@9.0.28)))(@deck.gl/layers@9.0.41(@deck.gl/core@9.0.41)(@loaders.gl/core@4.3.3)(@luma.gl/core@9.0.28)(@luma.gl/engine@9.0.28(@luma.gl/core@9.0.28)))(@deck.gl/react@9.0.41(@deck.gl/core@9.0.41)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@luma.gl/constants@9.0.28)(@luma.gl/core@9.0.28)(@luma.gl/engine@9.0.28(@luma.gl/core@9.0.28))(@luma.gl/shadertools@9.0.28(@luma.gl/core@9.0.28))(@luma.gl/webgl@9.0.28(@luma.gl/core@9.0.28))(react@18.3.1)
- '@material-ui/core':
- specifier: ^4.11.0
- version: 4.12.4(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
- '@material-ui/icons':
- specifier: ^4.9.1
- version: 4.11.3(@material-ui/core@4.12.4(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
- '@material-ui/styles':
- specifier: ^4.11.5
- version: 4.11.5(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-accordion':
+ specifier: ^1.2.3
+ version: 1.2.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-icons':
+ specifier: ^1.3.2
+ version: 1.3.2(react@18.3.1)
+ '@radix-ui/react-popover':
+ specifier: ^1.1.6
+ version: 1.1.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-select':
+ specifier: ^2.1.6
+ version: 2.1.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-separator':
+ specifier: ^1.1.2
+ version: 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-slider':
+ specifier: ^1.2.3
+ version: 1.2.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-slot':
+ specifier: ^1.1.2
+ version: 1.1.2(@types/react@18.3.18)(react@18.3.1)
'@vivjs/types':
- specifier: ~0.17.0
+ specifier: ^0.17.2
version: 0.17.2
'@zarrita/storage':
- specifier: 0.1.0
+ specifier: ^0.1.0
version: 0.1.0
+ class-variance-authority:
+ specifier: ^0.7.0
+ version: 0.7.1
+ clsx:
+ specifier: ^2.1.1
+ version: 2.1.1
deck.gl:
- specifier: ~9.0.0
+ specifier: ~9.0.41
version: 9.0.41(@arcgis/core@4.32.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
jotai:
specifier: ^1.0.0
- version: 1.13.1(@babel/core@7.26.9)(@babel/template@7.26.9)(react@18.3.1)
+ version: 1.13.1(@babel/core@7.26.10)(@babel/template@7.26.9)(react@18.3.1)
just-debounce-it:
specifier: ^3.1.1
version: 3.2.0
@@ -55,13 +73,22 @@ importers:
react-dom:
specifier: ^18.2.0
version: 18.3.1(react@18.3.1)
+ tailwind-merge:
+ specifier: ^3.0.2
+ version: 3.0.2
+ tailwindcss:
+ specifier: ^4.0.12
+ version: 4.0.13
zarrita:
- specifier: 0.5.0
+ specifier: ~0.5.0
version: 0.5.0
devDependencies:
'@biomejs/biome':
specifier: ^1.9.4
version: 1.9.4
+ '@tailwindcss/vite':
+ specifier: ^4.0.12
+ version: 4.0.13(vite@6.2.1(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2))
'@types/node':
specifier: ^22.13.5
version: 22.13.10
@@ -73,13 +100,13 @@ importers:
version: 18.3.5(@types/react@18.3.18)
'@vitejs/plugin-react':
specifier: ^4.3.4
- version: 4.3.4(vite@6.2.1(@types/node@22.13.10))
+ version: 4.3.4(vite@6.2.1(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2))
typescript:
specifier: ^5.8.2
version: 5.8.2
vite:
specifier: ^6.2.0
- version: 6.2.1(@types/node@22.13.10)
+ version: 6.2.1(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)
packages:
@@ -107,12 +134,12 @@ packages:
resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==}
engines: {node: '>=6.9.0'}
- '@babel/core@7.26.9':
- resolution: {integrity: sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==}
+ '@babel/core@7.26.10':
+ resolution: {integrity: sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==}
engines: {node: '>=6.9.0'}
- '@babel/generator@7.26.9':
- resolution: {integrity: sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==}
+ '@babel/generator@7.26.10':
+ resolution: {integrity: sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==}
engines: {node: '>=6.9.0'}
'@babel/helper-compilation-targets@7.26.5':
@@ -145,12 +172,12 @@ packages:
resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==}
engines: {node: '>=6.9.0'}
- '@babel/helpers@7.26.9':
- resolution: {integrity: sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==}
+ '@babel/helpers@7.26.10':
+ resolution: {integrity: sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==}
engines: {node: '>=6.9.0'}
- '@babel/parser@7.26.9':
- resolution: {integrity: sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==}
+ '@babel/parser@7.26.10':
+ resolution: {integrity: sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==}
engines: {node: '>=6.0.0'}
hasBin: true
@@ -166,20 +193,16 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0-0
- '@babel/runtime@7.26.9':
- resolution: {integrity: sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==}
- engines: {node: '>=6.9.0'}
-
'@babel/template@7.26.9':
resolution: {integrity: sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==}
engines: {node: '>=6.9.0'}
- '@babel/traverse@7.26.9':
- resolution: {integrity: sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==}
+ '@babel/traverse@7.26.10':
+ resolution: {integrity: sha512-k8NuDrxr0WrPH5Aupqb2LCVURP/S0vBEn5mK6iH+GIYob66U5EtoZvcdudR2jQ4cmTwhEwW1DLB+Yyas9zjF6A==}
engines: {node: '>=6.9.0'}
- '@babel/types@7.26.9':
- resolution: {integrity: sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==}
+ '@babel/types@7.26.10':
+ resolution: {integrity: sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==}
engines: {node: '>=6.9.0'}
'@biomejs/biome@1.9.4':
@@ -326,9 +349,6 @@ packages:
peerDependencies:
'@deck.gl/core': ^9.0.0
- '@emotion/hash@0.8.0':
- resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==}
-
'@esbuild/aix-ppc64@0.25.1':
resolution: {integrity: sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==}
engines: {node: '>=18'}
@@ -496,6 +516,12 @@ packages:
'@floating-ui/dom@1.6.13':
resolution: {integrity: sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==}
+ '@floating-ui/react-dom@2.1.2':
+ resolution: {integrity: sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==}
+ peerDependencies:
+ react: '>=16.8.0'
+ react-dom: '>=16.8.0'
+
'@floating-ui/utils@0.2.9':
resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==}
@@ -675,68 +701,6 @@ packages:
'@mapbox/vector-tile@1.3.1':
resolution: {integrity: sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==}
- '@material-ui/core@4.12.4':
- resolution: {integrity: sha512-tr7xekNlM9LjA6pagJmL8QCgZXaubWUwkJnoYcMKd4gw/t4XiyvnTkjdGrUVicyB2BsdaAv1tvow45bPM4sSwQ==}
- engines: {node: '>=8.0.0'}
- deprecated: Material UI v4 doesn't receive active development since September 2021. See the guide https://mui.com/material-ui/migration/migration-v4/ to upgrade to v5.
- peerDependencies:
- '@types/react': ^16.8.6 || ^17.0.0
- react: ^16.8.0 || ^17.0.0
- react-dom: ^16.8.0 || ^17.0.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
-
- '@material-ui/icons@4.11.3':
- resolution: {integrity: sha512-IKHlyx6LDh8n19vzwH5RtHIOHl9Tu90aAAxcbWME6kp4dmvODM3UvOHJeMIDzUbd4muuJKHmlNoBN+mDY4XkBA==}
- engines: {node: '>=8.0.0'}
- peerDependencies:
- '@material-ui/core': ^4.0.0
- '@types/react': ^16.8.6 || ^17.0.0
- react: ^16.8.0 || ^17.0.0
- react-dom: ^16.8.0 || ^17.0.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
-
- '@material-ui/styles@4.11.5':
- resolution: {integrity: sha512-o/41ot5JJiUsIETME9wVLAJrmIWL3j0R0Bj2kCOLbSfqEkKf0fmaPt+5vtblUh5eXr2S+J/8J3DaCb10+CzPGA==}
- engines: {node: '>=8.0.0'}
- deprecated: Material UI v4 doesn't receive active development since September 2021. See the guide https://mui.com/material-ui/migration/migration-v4/ to upgrade to v5.
- peerDependencies:
- '@types/react': ^16.8.6 || ^17.0.0
- react: ^16.8.0 || ^17.0.0
- react-dom: ^16.8.0 || ^17.0.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
-
- '@material-ui/system@4.12.2':
- resolution: {integrity: sha512-6CSKu2MtmiJgcCGf6nBQpM8fLkuB9F55EKfbdTC80NND5wpTmKzwdhLYLH3zL4cLlK0gVaaltW7/wMuyTnN0Lw==}
- engines: {node: '>=8.0.0'}
- peerDependencies:
- '@types/react': ^16.8.6 || ^17.0.0
- react: ^16.8.0 || ^17.0.0
- react-dom: ^16.8.0 || ^17.0.0
- peerDependenciesMeta:
- '@types/react':
- optional: true
-
- '@material-ui/types@5.1.0':
- resolution: {integrity: sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A==}
- peerDependencies:
- '@types/react': '*'
- peerDependenciesMeta:
- '@types/react':
- optional: true
-
- '@material-ui/utils@4.11.3':
- resolution: {integrity: sha512-ZuQPV4rBK/V1j2dIkSSEcH5uT6AaHuKWFfotADHsC0wVL1NLd2WkFCm4ZZbX33iO4ydl6V0GPngKm8HZQ2oujg==}
- engines: {node: '>=8.0.0'}
- peerDependencies:
- react: ^16.8.0 || ^17.0.0
- react-dom: ^16.8.0 || ^17.0.0
-
'@math.gl/core@4.1.0':
resolution: {integrity: sha512-FrdHBCVG3QdrworwrUSzXIaK+/9OCRLscxI2OUy6sLOHyHgBMyfnEGs99/m3KNvs+95BsnQLWklVfpKfQzfwKA==}
@@ -779,6 +743,332 @@ packages:
'@probe.gl/stats@4.1.0':
resolution: {integrity: sha512-EI413MkWKBDVNIfLdqbeNSJTs7ToBz/KVGkwi3D+dQrSIkRI2IYbWGAU3xX+D6+CI4ls8ehxMhNpUVMaZggDvQ==}
+ '@radix-ui/number@1.1.0':
+ resolution: {integrity: sha512-V3gRzhVNU1ldS5XhAPTom1fOIo4ccrjjJgmE+LI2h/WaFpHmx0MQApT+KZHnx8abG6Avtfcz4WoEciMnpFT3HQ==}
+
+ '@radix-ui/primitive@1.1.1':
+ resolution: {integrity: sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==}
+
+ '@radix-ui/react-accordion@1.2.3':
+ resolution: {integrity: sha512-RIQ15mrcvqIkDARJeERSuXSry2N8uYnxkdDetpfmalT/+0ntOXLkFOsh9iwlAsCv+qcmhZjbdJogIm6WBa6c4A==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-arrow@1.1.2':
+ resolution: {integrity: sha512-G+KcpzXHq24iH0uGG/pF8LyzpFJYGD4RfLjCIBfGdSLXvjLHST31RUiRVrupIBMvIppMgSzQ6l66iAxl03tdlg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-collapsible@1.1.3':
+ resolution: {integrity: sha512-jFSerheto1X03MUC0g6R7LedNW9EEGWdg9W1+MlpkMLwGkgkbUXLPBH/KIuWKXUoeYRVY11llqbTBDzuLg7qrw==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-collection@1.1.2':
+ resolution: {integrity: sha512-9z54IEKRxIa9VityapoEYMuByaG42iSy1ZXlY2KcuLSEtq8x4987/N6m15ppoMffgZX72gER2uHe1D9Y6Unlcw==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-compose-refs@1.1.1':
+ resolution: {integrity: sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-context@1.1.1':
+ resolution: {integrity: sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-direction@1.1.0':
+ resolution: {integrity: sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-dismissable-layer@1.1.5':
+ resolution: {integrity: sha512-E4TywXY6UsXNRhFrECa5HAvE5/4BFcGyfTyK36gP+pAW1ed7UTK4vKwdr53gAJYwqbfCWC6ATvJa3J3R/9+Qrg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-focus-guards@1.1.1':
+ resolution: {integrity: sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-focus-scope@1.1.2':
+ resolution: {integrity: sha512-zxwE80FCU7lcXUGWkdt6XpTTCKPitG1XKOwViTxHVKIJhZl9MvIl2dVHeZENCWD9+EdWv05wlaEkRXUykU27RA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-icons@1.3.2':
+ resolution: {integrity: sha512-fyQIhGDhzfc9pK2kH6Pl9c4BDJGfMkPqkyIgYDthyNYoNg3wVhoJMMh19WS4Up/1KMPFVpNsT2q3WmXn2N1m6g==}
+ peerDependencies:
+ react: ^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc
+
+ '@radix-ui/react-id@1.1.0':
+ resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-popover@1.1.6':
+ resolution: {integrity: sha512-NQouW0x4/GnkFJ/pRqsIS3rM/k97VzKnVb2jB7Gq7VEGPy5g7uNV1ykySFt7eWSp3i2uSGFwaJcvIRJBAHmmFg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-popper@1.2.2':
+ resolution: {integrity: sha512-Rvqc3nOpwseCyj/rgjlJDYAgyfw7OC1tTkKn2ivhaMGcYt8FSBlahHOZak2i3QwkRXUXgGgzeEe2RuqeEHuHgA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-portal@1.1.4':
+ resolution: {integrity: sha512-sn2O9k1rPFYVyKd5LAJfo96JlSGVFpa1fS6UuBJfrZadudiw5tAmru+n1x7aMRQ84qDM71Zh1+SzK5QwU0tJfA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-presence@1.1.2':
+ resolution: {integrity: sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-primitive@2.0.2':
+ resolution: {integrity: sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-select@2.1.6':
+ resolution: {integrity: sha512-T6ajELxRvTuAMWH0YmRJ1qez+x4/7Nq7QIx7zJ0VK3qaEWdnWpNbEDnmWldG1zBDwqrLy5aLMUWcoGirVj5kMg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-separator@1.1.2':
+ resolution: {integrity: sha512-oZfHcaAp2Y6KFBX6I5P1u7CQoy4lheCGiYj+pGFrHy8E/VNRb5E39TkTr3JrV520csPBTZjkuKFdEsjS5EUNKQ==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-slider@1.2.3':
+ resolution: {integrity: sha512-nNrLAWLjGESnhqBqcCNW4w2nn7LxudyMzeB6VgdyAnFLC6kfQgnAjSL2v6UkQTnDctJBlxrmxfplWS4iYjdUTw==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-slot@1.1.2':
+ resolution: {integrity: sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-callback-ref@1.1.0':
+ resolution: {integrity: sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-controllable-state@1.1.0':
+ resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-escape-keydown@1.1.0':
+ resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-layout-effect@1.1.0':
+ resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-previous@1.1.0':
+ resolution: {integrity: sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-rect@1.1.0':
+ resolution: {integrity: sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-use-size@1.1.0':
+ resolution: {integrity: sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@radix-ui/react-visually-hidden@1.1.2':
+ resolution: {integrity: sha512-1SzA4ns2M1aRlvxErqhLHsBHoS5eI5UUcI2awAMgGUp4LoaoWOKYmvqDY2s/tltuPkh3Yk77YF/r3IRj+Amx4Q==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/rect@1.1.0':
+ resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==}
+
'@rollup/rollup-android-arm-eabi@4.35.0':
resolution: {integrity: sha512-uYQ2WfPaqz5QtVgMxfN6NpLD+no0MYHDBywl7itPYd3K5TjjSghNKmX8ic9S8NU8w81NVhJv/XojcHptRly7qQ==}
cpu: [arm]
@@ -874,6 +1164,84 @@ packages:
cpu: [x64]
os: [win32]
+ '@tailwindcss/node@4.0.13':
+ resolution: {integrity: sha512-P9TmtE9Vew0vv5FwyD4bsg/dHHsIsAuUXkenuGUc5gm8fYgaxpdoxIKngCyEMEQxyCKR8PQY5V5VrrKNOx7exg==}
+
+ '@tailwindcss/oxide-android-arm64@4.0.13':
+ resolution: {integrity: sha512-+9zmwaPQ8A9ycDcdb+hRkMn6NzsmZ4YJBsW5Xqq5EdOu9xlIgmuMuJauVzDPB5BSbIWfhPdZ+le8NeRZpl1coA==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [android]
+
+ '@tailwindcss/oxide-darwin-arm64@4.0.13':
+ resolution: {integrity: sha512-Bj1QGlEJSjs/205CIRfb5/jeveOqzJ4pFMdRxu0gyiYWxBRyxsExXqaD+7162wnLP/EDKh6S1MC9E/1GwEhLtA==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@tailwindcss/oxide-darwin-x64@4.0.13':
+ resolution: {integrity: sha512-lRTkxjTpMGXhLLM5GjZ0MtjPczMuhAo9j7PeSsaU6Imkm7W7RbrXfT8aP934kS7cBBV+HKN5U19Z0WWaORfb8Q==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@tailwindcss/oxide-freebsd-x64@4.0.13':
+ resolution: {integrity: sha512-p/YLyKhs+xFibVeAPlpMGDVMKgjChgzs12VnDFaaqRSJoOz+uJgRSKiir2tn50e7Nm4YYw35q/DRBwpDBNo1MQ==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@tailwindcss/oxide-linux-arm-gnueabihf@4.0.13':
+ resolution: {integrity: sha512-Ua/5ydE/QOTX8jHuc7M9ICWnaLi6K2MV/r+Ws2OppsOjy8tdlPbqYainJJ6Kl7ofm524K+4Fk9CQITPzeIESPw==}
+ engines: {node: '>= 10'}
+ cpu: [arm]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-arm64-gnu@4.0.13':
+ resolution: {integrity: sha512-/W1+Q6tBAVgZWh/bhfOHo4n7Ryh6E7zYj4bJd9SRbkPyLtRioyK3bi6RLuDj57sa7Amk/DeomSV9iycS0xqIPA==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-arm64-musl@4.0.13':
+ resolution: {integrity: sha512-GQj6TWevNxwsYw20FdT2r2d1f7uiRsF07iFvNYxPIvIyPEV74eZ0zgFEsAH1daK1OxPy+LXdZ4grV17P5tVzhQ==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-x64-gnu@4.0.13':
+ resolution: {integrity: sha512-sQRH09faifF9w9WS6TKDWr1oLi4hoPx0EIWXZHQK/jcjarDpXGQ2DbF0KnALJCwWBxOIP/1nrmU01fZwwMzY3g==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+
+ '@tailwindcss/oxide-linux-x64-musl@4.0.13':
+ resolution: {integrity: sha512-Or1N8DIF3tP+LsloJp+UXLTIMMHMUcWXFhJLCsM4T7MzFzxkeReewRWXfk5mk137cdqVeUEH/R50xAhY1mOkTQ==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [linux]
+
+ '@tailwindcss/oxide-win32-arm64-msvc@4.0.13':
+ resolution: {integrity: sha512-u2mQyqCFrr9vVTP6sfDRfGE6bhOX3/7rInehzxNhHX1HYRIx09H3sDdXzTxnZWKOjIg3qjFTCrYFUZckva5PIg==}
+ engines: {node: '>= 10'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@tailwindcss/oxide-win32-x64-msvc@4.0.13':
+ resolution: {integrity: sha512-sOEc4iCanp1Yqyeu9suQcEzfaUcHnqjBUgDg0ZXpjUMUwdSi37S1lu1RGoV1BYInvvGu3y3HHTmvsSfDhx2L8w==}
+ engines: {node: '>= 10'}
+ cpu: [x64]
+ os: [win32]
+
+ '@tailwindcss/oxide@4.0.13':
+ resolution: {integrity: sha512-pTH3Ex5zAWC9LbS+WsYAFmkXQW3NRjmvxkKJY3NP1x0KHBWjz0Q2uGtdGMJzsa0EwoZ7wq9RTbMH1UNPceCpWw==}
+ engines: {node: '>= 10'}
+
+ '@tailwindcss/vite@4.0.13':
+ resolution: {integrity: sha512-0XTd/NoVUAktIDaA4MdXhve0QWYh7WlZg20EHCuBFR80F8FhbVkRX+AY5cjbUP/IO2itHzt0iHc0iSE5kBUMhQ==}
+ peerDependencies:
+ vite: ^5.2.0 || ^6
+
'@turf/boolean-clockwise@5.1.5':
resolution: {integrity: sha512-FqbmEEOJ4rU4/2t7FKx0HUWmjFEVqR+NJrFP7ymGSjja2SQ7Q91nnBihGuT+yuHHl6ElMjQ3ttsB/eTmyCycxA==}
@@ -963,11 +1331,6 @@ packages:
peerDependencies:
'@types/react': ^18.0.0
- '@types/react-transition-group@4.4.12':
- resolution: {integrity: sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==}
- peerDependencies:
- '@types/react': '*'
-
'@types/react@18.3.18':
resolution: {integrity: sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==}
@@ -1077,6 +1440,10 @@ packages:
argparse@1.0.10:
resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
+ aria-hidden@1.2.4:
+ resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==}
+ engines: {node: '>=10'}
+
base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
@@ -1101,8 +1468,11 @@ packages:
charenc@0.0.2:
resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==}
- clsx@1.2.1:
- resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==}
+ class-variance-authority@0.7.1:
+ resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==}
+
+ clsx@2.1.1:
+ resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
engines: {node: '>=6'}
color-convert@2.0.1:
@@ -1143,15 +1513,9 @@ packages:
crypt@0.0.2:
resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==}
- css-vendor@2.0.8:
- resolution: {integrity: sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==}
-
cssfilter@0.0.10:
resolution: {integrity: sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==}
- csstype@2.6.21:
- resolution: {integrity: sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==}
-
csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
@@ -1220,8 +1584,12 @@ packages:
resolution: {integrity: sha512-3daSWyvZ/zwJvuMGlzG1O+Ow0YSadGfb3jsh9xoCutv2tWyB9dA4YvR9L9/fSdDZa2dByYQe+TqapSGUrjnkoA==}
engines: {node: '>=0.10.0'}
- dom-helpers@5.2.1:
- resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==}
+ detect-libc@2.0.3:
+ resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
+ engines: {node: '>=8'}
+
+ detect-node-es@1.1.0:
+ resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==}
draco3d@1.5.7:
resolution: {integrity: sha512-m6WCKt/erDXcw+70IJXnG7M3awwQPAsZvJGX5zY7beBqpELw6RDGkYVU0W43AFxye4pDZ5i2Lbyc/NNGqwjUVQ==}
@@ -1293,6 +1661,10 @@ packages:
resolution: {integrity: sha512-PT6uoF5a1+kbC3tHmZSUsLHBp2QJlHasxxxxPW47QIY1VBKpFB+FcDvX+MxER6UzgLQZ0xDzJ9s48B9JbOCTqA==}
engines: {node: '>=10.19'}
+ get-nonce@1.0.1:
+ resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==}
+ engines: {node: '>=6'}
+
gl-matrix@3.4.3:
resolution: {integrity: sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA==}
@@ -1311,12 +1683,6 @@ packages:
resolution: {integrity: sha512-tSQXBXS/MWQOn/RKckawJ61vvsDpCom87JgxiYdGwHdOa0ht0vzUWDlfioofFCRU0L+6NGDt6XzbgoJvZkMeRQ==}
engines: {node: '>=0.8.0'}
- hoist-non-react-statics@3.3.2:
- resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==}
-
- hyphenate-style-name@1.1.0:
- resolution: {integrity: sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==}
-
ieee754@1.2.1:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
@@ -1347,12 +1713,13 @@ packages:
is-error@2.2.2:
resolution: {integrity: sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==}
- is-in-browser@1.1.3:
- resolution: {integrity: sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g==}
-
isarray@1.0.0:
resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
+ jiti@2.4.2:
+ resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==}
+ hasBin: true
+
jotai@1.13.1:
resolution: {integrity: sha512-RUmH1S4vLsG3V6fbGlKzGJnLrDcC/HNb5gH2AeA9DzuJknoVxSGvvg8OBB7lke+gDc4oXmdVsaKn/xDUhWZ0vw==}
engines: {node: '>=12.20.0'}
@@ -1410,30 +1777,6 @@ packages:
engines: {node: '>=6'}
hasBin: true
- jss-plugin-camel-case@10.10.0:
- resolution: {integrity: sha512-z+HETfj5IYgFxh1wJnUAU8jByI48ED+v0fuTuhKrPR+pRBYS2EDwbusU8aFOpCdYhtRc9zhN+PJ7iNE8pAWyPw==}
-
- jss-plugin-default-unit@10.10.0:
- resolution: {integrity: sha512-SvpajxIECi4JDUbGLefvNckmI+c2VWmP43qnEy/0eiwzRUsafg5DVSIWSzZe4d2vFX1u9nRDP46WCFV/PXVBGQ==}
-
- jss-plugin-global@10.10.0:
- resolution: {integrity: sha512-icXEYbMufiNuWfuazLeN+BNJO16Ge88OcXU5ZDC2vLqElmMybA31Wi7lZ3lf+vgufRocvPj8443irhYRgWxP+A==}
-
- jss-plugin-nested@10.10.0:
- resolution: {integrity: sha512-9R4JHxxGgiZhurDo3q7LdIiDEgtA1bTGzAbhSPyIOWb7ZubrjQe8acwhEQ6OEKydzpl8XHMtTnEwHXCARLYqYA==}
-
- jss-plugin-props-sort@10.10.0:
- resolution: {integrity: sha512-5VNJvQJbnq/vRfje6uZLe/FyaOpzP/IH1LP+0fr88QamVrGJa0hpRRyAa0ea4U/3LcorJfBFVyC4yN2QC73lJg==}
-
- jss-plugin-rule-value-function@10.10.0:
- resolution: {integrity: sha512-uEFJFgaCtkXeIPgki8ICw3Y7VMkL9GEan6SqmT9tqpwM+/t+hxfMUdU4wQ0MtOiMNWhwnckBV0IebrKcZM9C0g==}
-
- jss-plugin-vendor-prefixer@10.10.0:
- resolution: {integrity: sha512-UY/41WumgjW8r1qMCO8l1ARg7NHnfRVWRhZ2E2m0DMYsr2DD91qIXLyNhiX83hHswR7Wm4D+oDYNC1zWCJWtqg==}
-
- jss@10.10.0:
- resolution: {integrity: sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==}
-
jszip@3.10.1:
resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==}
@@ -1449,6 +1792,70 @@ packages:
lie@3.3.0:
resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==}
+ lightningcss-darwin-arm64@1.29.2:
+ resolution: {integrity: sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [darwin]
+
+ lightningcss-darwin-x64@1.29.2:
+ resolution: {integrity: sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [darwin]
+
+ lightningcss-freebsd-x64@1.29.2:
+ resolution: {integrity: sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [freebsd]
+
+ lightningcss-linux-arm-gnueabihf@1.29.2:
+ resolution: {integrity: sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm]
+ os: [linux]
+
+ lightningcss-linux-arm64-gnu@1.29.2:
+ resolution: {integrity: sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ lightningcss-linux-arm64-musl@1.29.2:
+ resolution: {integrity: sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ lightningcss-linux-x64-gnu@1.29.2:
+ resolution: {integrity: sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [linux]
+
+ lightningcss-linux-x64-musl@1.29.2:
+ resolution: {integrity: sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [linux]
+
+ lightningcss-win32-arm64-msvc@1.29.2:
+ resolution: {integrity: sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [win32]
+
+ lightningcss-win32-x64-msvc@1.29.2:
+ resolution: {integrity: sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [win32]
+
+ lightningcss@1.29.2:
+ resolution: {integrity: sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==}
+ engines: {node: '>= 12.0.0'}
+
lit-element@4.1.1:
resolution: {integrity: sha512-HO9Tkkh34QkTeUmEdNYhMT8hzLid7YlMlATSi1q4q17HE5d9mrrEHJ/o8O2D0cMi182zK1F3v7x0PWFjrhXFew==}
@@ -1535,10 +1942,6 @@ packages:
numcodecs@0.3.2:
resolution: {integrity: sha512-6YSPnmZgg0P87jnNhi3s+FVLOcIn3y+1CTIgUulA3IdASzK9fJM87sUFkpyA+be9GibGRaST2wCgkD+6U+fWKw==}
- object-assign@4.1.1:
- resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
- engines: {node: '>=0.10.0'}
-
p-map@7.0.3:
resolution: {integrity: sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==}
engines: {node: '>=18'}
@@ -1570,9 +1973,6 @@ packages:
picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
- popper.js@1.16.1-lts:
- resolution: {integrity: sha512-Kjw8nKRl1m+VrSFCoVGPph93W/qrSO7ZkqPpTf7F4bk/sqcfWK019dWBUpE/fBOsOQY1dks/Bmcbfn1heM/IsA==}
-
postcss@8.5.3:
resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==}
engines: {node: ^10 || ^12 || >=14}
@@ -1583,9 +1983,6 @@ packages:
process-nextick-args@2.0.1:
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
- prop-types@15.8.1:
- resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
-
protocol-buffers-schema@3.6.0:
resolution: {integrity: sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==}
@@ -1609,21 +2006,39 @@ packages:
peerDependencies:
react: ^18.3.1
- react-is@16.13.1:
- resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
-
- react-is@17.0.2:
- resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
-
react-refresh@0.14.2:
resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==}
engines: {node: '>=0.10.0'}
- react-transition-group@4.4.5:
- resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==}
+ react-remove-scroll-bar@2.3.8:
+ resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ react-remove-scroll@2.6.3:
+ resolution: {integrity: sha512-pnAi91oOk8g8ABQKGF5/M9qxmmOPxaAnopyTHYfqYEwJhyFrbbBtHuSgtKEoH0jpcxx5o3hXqH1mNd9/Oi+8iQ==}
+ engines: {node: '>=10'}
peerDependencies:
- react: '>=16.6.0'
- react-dom: '>=16.6.0'
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ react-style-singleton@2.2.3:
+ resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
react@18.3.1:
resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==}
@@ -1635,9 +2050,6 @@ packages:
reference-spec-reader@0.2.0:
resolution: {integrity: sha512-q0mfCi5yZSSHXpCyxjgQeaORq3tvDsxDyzaadA/5+AbAUwRyRuuTh0aRQuE/vAOt/qzzxidJ5iDeu1cLHaNBlQ==}
- regenerator-runtime@0.14.1:
- resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==}
-
resolve-protobuf-schema@2.1.0:
resolution: {integrity: sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==}
@@ -1684,6 +2096,12 @@ packages:
tabbable@6.2.0:
resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==}
+ tailwind-merge@3.0.2:
+ resolution: {integrity: sha512-l7z+OYZ7mu3DTqrL88RiKrKIqO3NcpEO8V/Od04bNpvk0kiIFndGEoqfuzvj4yuhRkHKjRkII2z+KS2HfPcSxw==}
+
+ tailwindcss@4.0.13:
+ resolution: {integrity: sha512-gbvFrB0fOsTv/OugXWi2PtflJ4S6/ctu6Mmn3bCftmLY/6xRsQVEJPgIIpABwpZ52DpONkCA3bEj5b54MHxF2Q==}
+
tapable@2.2.1:
resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
engines: {node: '>=6'}
@@ -1700,9 +2118,6 @@ packages:
resolution: {integrity: sha512-AnkJYrbb7uPkDCEqGeVJiawZNiwVlSkkeX4jZg1gTEguClhyX+/Ezn07KB6DT29tG3UN418ldmS/W6KqGOTDjg==}
engines: {node: '>=18.12.0'}
- tiny-warning@1.0.3:
- resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==}
-
tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
@@ -1728,6 +2143,26 @@ packages:
peerDependencies:
browserslist: '>= 4.21.0'
+ use-callback-ref@1.3.3:
+ resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ use-sidecar@1.1.3:
+ resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ '@types/react': '*'
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
@@ -1855,18 +2290,18 @@ snapshots:
'@babel/compat-data@7.26.8': {}
- '@babel/core@7.26.9':
+ '@babel/core@7.26.10':
dependencies:
'@ampproject/remapping': 2.3.0
'@babel/code-frame': 7.26.2
- '@babel/generator': 7.26.9
+ '@babel/generator': 7.26.10
'@babel/helper-compilation-targets': 7.26.5
- '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.9)
- '@babel/helpers': 7.26.9
- '@babel/parser': 7.26.9
+ '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.10)
+ '@babel/helpers': 7.26.10
+ '@babel/parser': 7.26.10
'@babel/template': 7.26.9
- '@babel/traverse': 7.26.9
- '@babel/types': 7.26.9
+ '@babel/traverse': 7.26.10
+ '@babel/types': 7.26.10
convert-source-map: 2.0.0
debug: 4.4.0
gensync: 1.0.0-beta.2
@@ -1875,10 +2310,10 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@babel/generator@7.26.9':
+ '@babel/generator@7.26.10':
dependencies:
- '@babel/parser': 7.26.9
- '@babel/types': 7.26.9
+ '@babel/parser': 7.26.10
+ '@babel/types': 7.26.10
'@jridgewell/gen-mapping': 0.3.8
'@jridgewell/trace-mapping': 0.3.25
jsesc: 3.1.0
@@ -1893,17 +2328,17 @@ snapshots:
'@babel/helper-module-imports@7.25.9':
dependencies:
- '@babel/traverse': 7.26.9
- '@babel/types': 7.26.9
+ '@babel/traverse': 7.26.10
+ '@babel/types': 7.26.10
transitivePeerDependencies:
- supports-color
- '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.9)':
+ '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.10)':
dependencies:
- '@babel/core': 7.26.9
+ '@babel/core': 7.26.10
'@babel/helper-module-imports': 7.25.9
'@babel/helper-validator-identifier': 7.25.9
- '@babel/traverse': 7.26.9
+ '@babel/traverse': 7.26.10
transitivePeerDependencies:
- supports-color
@@ -1915,48 +2350,44 @@ snapshots:
'@babel/helper-validator-option@7.25.9': {}
- '@babel/helpers@7.26.9':
+ '@babel/helpers@7.26.10':
dependencies:
'@babel/template': 7.26.9
- '@babel/types': 7.26.9
+ '@babel/types': 7.26.10
- '@babel/parser@7.26.9':
+ '@babel/parser@7.26.10':
dependencies:
- '@babel/types': 7.26.9
+ '@babel/types': 7.26.10
- '@babel/plugin-transform-react-jsx-self@7.25.9(@babel/core@7.26.9)':
+ '@babel/plugin-transform-react-jsx-self@7.25.9(@babel/core@7.26.10)':
dependencies:
- '@babel/core': 7.26.9
+ '@babel/core': 7.26.10
'@babel/helper-plugin-utils': 7.26.5
- '@babel/plugin-transform-react-jsx-source@7.25.9(@babel/core@7.26.9)':
+ '@babel/plugin-transform-react-jsx-source@7.25.9(@babel/core@7.26.10)':
dependencies:
- '@babel/core': 7.26.9
+ '@babel/core': 7.26.10
'@babel/helper-plugin-utils': 7.26.5
- '@babel/runtime@7.26.9':
- dependencies:
- regenerator-runtime: 0.14.1
-
'@babel/template@7.26.9':
dependencies:
'@babel/code-frame': 7.26.2
- '@babel/parser': 7.26.9
- '@babel/types': 7.26.9
+ '@babel/parser': 7.26.10
+ '@babel/types': 7.26.10
- '@babel/traverse@7.26.9':
+ '@babel/traverse@7.26.10':
dependencies:
'@babel/code-frame': 7.26.2
- '@babel/generator': 7.26.9
- '@babel/parser': 7.26.9
+ '@babel/generator': 7.26.10
+ '@babel/parser': 7.26.10
'@babel/template': 7.26.9
- '@babel/types': 7.26.9
+ '@babel/types': 7.26.10
debug: 4.4.0
globals: 11.12.0
transitivePeerDependencies:
- supports-color
- '@babel/types@7.26.9':
+ '@babel/types@7.26.10':
dependencies:
'@babel/helper-string-parser': 7.25.9
'@babel/helper-validator-identifier': 7.25.9
@@ -2156,8 +2587,6 @@ snapshots:
'@deck.gl/core': 9.0.41
preact: 10.26.4
- '@emotion/hash@0.8.0': {}
-
'@esbuild/aix-ppc64@0.25.1':
optional: true
@@ -2268,6 +2697,12 @@ snapshots:
'@floating-ui/core': 1.6.9
'@floating-ui/utils': 0.2.9
+ '@floating-ui/react-dom@2.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ dependencies:
+ '@floating-ui/dom': 1.6.13
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+
'@floating-ui/utils@0.2.9': {}
'@hms-dbmi/viv@0.17.2(@deck.gl/core@9.0.41)(@deck.gl/geo-layers@9.0.41(@deck.gl/core@9.0.41)(@deck.gl/extensions@9.0.41(@deck.gl/core@9.0.41)(@luma.gl/core@9.0.28)(@luma.gl/engine@9.0.28(@luma.gl/core@9.0.28)))(@deck.gl/layers@9.0.41(@deck.gl/core@9.0.41)(@loaders.gl/core@4.3.3)(@luma.gl/core@9.0.28)(@luma.gl/engine@9.0.28(@luma.gl/core@9.0.28)))(@deck.gl/mesh-layers@9.0.41(@deck.gl/core@9.0.41)(@loaders.gl/core@4.3.3)(@luma.gl/core@9.0.28)(@luma.gl/engine@9.0.28(@luma.gl/core@9.0.28)))(@loaders.gl/core@4.3.3)(@luma.gl/core@9.0.28)(@luma.gl/engine@9.0.28(@luma.gl/core@9.0.28)))(@deck.gl/layers@9.0.41(@deck.gl/core@9.0.41)(@loaders.gl/core@4.3.3)(@luma.gl/core@9.0.28)(@luma.gl/engine@9.0.28(@luma.gl/core@9.0.28)))(@deck.gl/react@9.0.41(@deck.gl/core@9.0.41)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@luma.gl/constants@9.0.28)(@luma.gl/core@9.0.28)(@luma.gl/engine@9.0.28(@luma.gl/core@9.0.28))(@luma.gl/shadertools@9.0.28(@luma.gl/core@9.0.28))(@luma.gl/webgl@9.0.28(@luma.gl/core@9.0.28))(react@18.3.1)':
@@ -2521,169 +2956,403 @@ snapshots:
'@probe.gl/stats': 4.1.0
'@types/offscreencanvas': 2019.7.3
- '@luma.gl/engine@9.0.28(@luma.gl/core@9.0.28)':
+ '@luma.gl/engine@9.0.28(@luma.gl/core@9.0.28)':
+ dependencies:
+ '@luma.gl/core': 9.0.28
+ '@luma.gl/shadertools': 9.0.28(@luma.gl/core@9.0.28)
+ '@math.gl/core': 4.1.0
+ '@probe.gl/log': 4.1.0
+ '@probe.gl/stats': 4.1.0
+
+ '@luma.gl/gltf@9.0.28(@loaders.gl/core@4.3.3)(@luma.gl/core@9.0.28)(@luma.gl/engine@9.0.28(@luma.gl/core@9.0.28))':
+ dependencies:
+ '@loaders.gl/core': 4.3.3
+ '@loaders.gl/textures': 4.3.3(@loaders.gl/core@4.3.3)
+ '@luma.gl/core': 9.0.28
+ '@luma.gl/engine': 9.0.28(@luma.gl/core@9.0.28)
+ '@luma.gl/shadertools': 9.0.28(@luma.gl/core@9.0.28)
+ '@math.gl/core': 4.1.0
+
+ '@luma.gl/shadertools@9.0.28(@luma.gl/core@9.0.28)':
+ dependencies:
+ '@luma.gl/core': 9.0.28
+ '@math.gl/core': 4.1.0
+ '@math.gl/types': 4.1.0
+ wgsl_reflect: 1.2.0
+
+ '@luma.gl/webgl@9.0.28(@luma.gl/core@9.0.28)':
+ dependencies:
+ '@luma.gl/constants': 9.0.28
+ '@luma.gl/core': 9.0.28
+ '@probe.gl/env': 4.1.0
+
+ '@mapbox/martini@0.2.0': {}
+
+ '@mapbox/point-geometry@0.1.0': {}
+
+ '@mapbox/tile-cover@3.0.1':
+ dependencies:
+ tilebelt: 1.0.1
+
+ '@mapbox/tiny-sdf@2.0.6': {}
+
+ '@mapbox/vector-tile@1.3.1':
+ dependencies:
+ '@mapbox/point-geometry': 0.1.0
+
+ '@math.gl/core@4.1.0':
+ dependencies:
+ '@math.gl/types': 4.1.0
+
+ '@math.gl/culling@4.1.0':
+ dependencies:
+ '@math.gl/core': 4.1.0
+ '@math.gl/types': 4.1.0
+
+ '@math.gl/geospatial@4.1.0':
+ dependencies:
+ '@math.gl/core': 4.1.0
+ '@math.gl/types': 4.1.0
+
+ '@math.gl/polygon@4.1.0':
+ dependencies:
+ '@math.gl/core': 4.1.0
+
+ '@math.gl/sun@4.1.0': {}
+
+ '@math.gl/types@4.1.0': {}
+
+ '@math.gl/web-mercator@4.1.0':
+ dependencies:
+ '@math.gl/core': 4.1.0
+
+ '@open-wc/dedupe-mixin@1.4.0': {}
+
+ '@parse5/tools@0.3.0':
+ dependencies:
+ parse5: 7.2.1
+
+ '@petamoriken/float16@3.9.2': {}
+
+ '@polymer/polymer@3.5.2':
+ dependencies:
+ '@webcomponents/shadycss': 1.11.2
+
+ '@probe.gl/env@4.1.0': {}
+
+ '@probe.gl/log@4.1.0':
+ dependencies:
+ '@probe.gl/env': 4.1.0
+
+ '@probe.gl/stats@4.1.0': {}
+
+ '@radix-ui/number@1.1.0': {}
+
+ '@radix-ui/primitive@1.1.1': {}
+
+ '@radix-ui/react-accordion@1.2.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.1
+ '@radix-ui/react-collapsible': 1.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+ optionalDependencies:
+ '@types/react': 18.3.18
+ '@types/react-dom': 18.3.5(@types/react@18.3.18)
+
+ '@radix-ui/react-arrow@1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ dependencies:
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+ optionalDependencies:
+ '@types/react': 18.3.18
+ '@types/react-dom': 18.3.5(@types/react@18.3.18)
+
+ '@radix-ui/react-collapsible@1.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.1
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+ optionalDependencies:
+ '@types/react': 18.3.18
+ '@types/react-dom': 18.3.5(@types/react@18.3.18)
+
+ '@radix-ui/react-collection@1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
- '@luma.gl/core': 9.0.28
- '@luma.gl/shadertools': 9.0.28(@luma.gl/core@9.0.28)
- '@math.gl/core': 4.1.0
- '@probe.gl/log': 4.1.0
- '@probe.gl/stats': 4.1.0
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1)
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+ optionalDependencies:
+ '@types/react': 18.3.18
+ '@types/react-dom': 18.3.5(@types/react@18.3.18)
- '@luma.gl/gltf@9.0.28(@loaders.gl/core@4.3.3)(@luma.gl/core@9.0.28)(@luma.gl/engine@9.0.28(@luma.gl/core@9.0.28))':
+ '@radix-ui/react-compose-refs@1.1.1(@types/react@18.3.18)(react@18.3.1)':
dependencies:
- '@loaders.gl/core': 4.3.3
- '@loaders.gl/textures': 4.3.3(@loaders.gl/core@4.3.3)
- '@luma.gl/core': 9.0.28
- '@luma.gl/engine': 9.0.28(@luma.gl/core@9.0.28)
- '@luma.gl/shadertools': 9.0.28(@luma.gl/core@9.0.28)
- '@math.gl/core': 4.1.0
+ react: 18.3.1
+ optionalDependencies:
+ '@types/react': 18.3.18
- '@luma.gl/shadertools@9.0.28(@luma.gl/core@9.0.28)':
+ '@radix-ui/react-context@1.1.1(@types/react@18.3.18)(react@18.3.1)':
dependencies:
- '@luma.gl/core': 9.0.28
- '@math.gl/core': 4.1.0
- '@math.gl/types': 4.1.0
- wgsl_reflect: 1.2.0
+ react: 18.3.1
+ optionalDependencies:
+ '@types/react': 18.3.18
- '@luma.gl/webgl@9.0.28(@luma.gl/core@9.0.28)':
+ '@radix-ui/react-direction@1.1.0(@types/react@18.3.18)(react@18.3.1)':
dependencies:
- '@luma.gl/constants': 9.0.28
- '@luma.gl/core': 9.0.28
- '@probe.gl/env': 4.1.0
+ react: 18.3.1
+ optionalDependencies:
+ '@types/react': 18.3.18
- '@mapbox/martini@0.2.0': {}
+ '@radix-ui/react-dismissable-layer@1.1.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.1
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+ optionalDependencies:
+ '@types/react': 18.3.18
+ '@types/react-dom': 18.3.5(@types/react@18.3.18)
- '@mapbox/point-geometry@0.1.0': {}
+ '@radix-ui/react-focus-guards@1.1.1(@types/react@18.3.18)(react@18.3.1)':
+ dependencies:
+ react: 18.3.1
+ optionalDependencies:
+ '@types/react': 18.3.18
- '@mapbox/tile-cover@3.0.1':
+ '@radix-ui/react-focus-scope@1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
- tilebelt: 1.0.1
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+ optionalDependencies:
+ '@types/react': 18.3.18
+ '@types/react-dom': 18.3.5(@types/react@18.3.18)
- '@mapbox/tiny-sdf@2.0.6': {}
+ '@radix-ui/react-icons@1.3.2(react@18.3.1)':
+ dependencies:
+ react: 18.3.1
- '@mapbox/vector-tile@1.3.1':
+ '@radix-ui/react-id@1.1.0(@types/react@18.3.18)(react@18.3.1)':
dependencies:
- '@mapbox/point-geometry': 0.1.0
+ '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ react: 18.3.1
+ optionalDependencies:
+ '@types/react': 18.3.18
- '@material-ui/core@4.12.4(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
- dependencies:
- '@babel/runtime': 7.26.9
- '@material-ui/styles': 4.11.5(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
- '@material-ui/system': 4.12.2(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
- '@material-ui/types': 5.1.0(@types/react@18.3.18)
- '@material-ui/utils': 4.11.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
- '@types/react-transition-group': 4.4.12(@types/react@18.3.18)
- clsx: 1.2.1
- hoist-non-react-statics: 3.3.2
- popper.js: 1.16.1-lts
- prop-types: 15.8.1
+ '@radix-ui/react-popover@1.1.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.1
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ aria-hidden: 1.2.4
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+ react-remove-scroll: 2.6.3(@types/react@18.3.18)(react@18.3.1)
+ optionalDependencies:
+ '@types/react': 18.3.18
+ '@types/react-dom': 18.3.5(@types/react@18.3.18)
+
+ '@radix-ui/react-popper@1.2.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ dependencies:
+ '@floating-ui/react-dom': 2.1.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-arrow': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-use-rect': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/rect': 1.1.0
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
- react-is: 17.0.2
- react-transition-group: 4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
optionalDependencies:
'@types/react': 18.3.18
+ '@types/react-dom': 18.3.5(@types/react@18.3.18)
- '@material-ui/icons@4.11.3(@material-ui/core@4.12.4(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ '@radix-ui/react-portal@1.1.4(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.26.9
- '@material-ui/core': 4.12.4(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
optionalDependencies:
'@types/react': 18.3.18
+ '@types/react-dom': 18.3.5(@types/react@18.3.18)
- '@material-ui/styles@4.11.5(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
- dependencies:
- '@babel/runtime': 7.26.9
- '@emotion/hash': 0.8.0
- '@material-ui/types': 5.1.0(@types/react@18.3.18)
- '@material-ui/utils': 4.11.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
- clsx: 1.2.1
- csstype: 2.6.21
- hoist-non-react-statics: 3.3.2
- jss: 10.10.0
- jss-plugin-camel-case: 10.10.0
- jss-plugin-default-unit: 10.10.0
- jss-plugin-global: 10.10.0
- jss-plugin-nested: 10.10.0
- jss-plugin-props-sort: 10.10.0
- jss-plugin-rule-value-function: 10.10.0
- jss-plugin-vendor-prefixer: 10.10.0
- prop-types: 15.8.1
+ '@radix-ui/react-presence@1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ dependencies:
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
optionalDependencies:
'@types/react': 18.3.18
+ '@types/react-dom': 18.3.5(@types/react@18.3.18)
- '@material-ui/system@4.12.2(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ '@radix-ui/react-primitive@2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.26.9
- '@material-ui/utils': 4.11.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
- csstype: 2.6.21
- prop-types: 15.8.1
+ '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
optionalDependencies:
'@types/react': 18.3.18
-
- '@material-ui/types@5.1.0(@types/react@18.3.18)':
+ '@types/react-dom': 18.3.5(@types/react@18.3.18)
+
+ '@radix-ui/react-select@2.1.6(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ dependencies:
+ '@radix-ui/number': 1.1.0
+ '@radix-ui/primitive': 1.1.1
+ '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-dismissable-layer': 1.1.5(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-focus-scope': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-popper': 1.2.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-portal': 1.1.4(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-slot': 1.1.2(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-visually-hidden': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ aria-hidden: 1.2.4
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+ react-remove-scroll: 2.6.3(@types/react@18.3.18)(react@18.3.1)
optionalDependencies:
'@types/react': 18.3.18
+ '@types/react-dom': 18.3.5(@types/react@18.3.18)
- '@material-ui/utils@4.11.3(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ '@radix-ui/react-separator@1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
- '@babel/runtime': 7.26.9
- prop-types: 15.8.1
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+ optionalDependencies:
+ '@types/react': 18.3.18
+ '@types/react-dom': 18.3.5(@types/react@18.3.18)
+
+ '@radix-ui/react-slider@1.2.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
+ dependencies:
+ '@radix-ui/number': 1.1.0
+ '@radix-ui/primitive': 1.1.1
+ '@radix-ui/react-collection': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-direction': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-use-previous': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ '@radix-ui/react-use-size': 1.1.0(@types/react@18.3.18)(react@18.3.1)
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
- react-is: 17.0.2
+ optionalDependencies:
+ '@types/react': 18.3.18
+ '@types/react-dom': 18.3.5(@types/react@18.3.18)
- '@math.gl/core@4.1.0':
+ '@radix-ui/react-slot@1.1.2(@types/react@18.3.18)(react@18.3.1)':
dependencies:
- '@math.gl/types': 4.1.0
+ '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1)
+ react: 18.3.1
+ optionalDependencies:
+ '@types/react': 18.3.18
- '@math.gl/culling@4.1.0':
+ '@radix-ui/react-use-callback-ref@1.1.0(@types/react@18.3.18)(react@18.3.1)':
dependencies:
- '@math.gl/core': 4.1.0
- '@math.gl/types': 4.1.0
+ react: 18.3.1
+ optionalDependencies:
+ '@types/react': 18.3.18
- '@math.gl/geospatial@4.1.0':
+ '@radix-ui/react-use-controllable-state@1.1.0(@types/react@18.3.18)(react@18.3.1)':
dependencies:
- '@math.gl/core': 4.1.0
- '@math.gl/types': 4.1.0
+ '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ react: 18.3.1
+ optionalDependencies:
+ '@types/react': 18.3.18
- '@math.gl/polygon@4.1.0':
+ '@radix-ui/react-use-escape-keydown@1.1.0(@types/react@18.3.18)(react@18.3.1)':
dependencies:
- '@math.gl/core': 4.1.0
-
- '@math.gl/sun@4.1.0': {}
-
- '@math.gl/types@4.1.0': {}
+ '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ react: 18.3.1
+ optionalDependencies:
+ '@types/react': 18.3.18
- '@math.gl/web-mercator@4.1.0':
+ '@radix-ui/react-use-layout-effect@1.1.0(@types/react@18.3.18)(react@18.3.1)':
dependencies:
- '@math.gl/core': 4.1.0
-
- '@open-wc/dedupe-mixin@1.4.0': {}
+ react: 18.3.1
+ optionalDependencies:
+ '@types/react': 18.3.18
- '@parse5/tools@0.3.0':
+ '@radix-ui/react-use-previous@1.1.0(@types/react@18.3.18)(react@18.3.1)':
dependencies:
- parse5: 7.2.1
-
- '@petamoriken/float16@3.9.2': {}
+ react: 18.3.1
+ optionalDependencies:
+ '@types/react': 18.3.18
- '@polymer/polymer@3.5.2':
+ '@radix-ui/react-use-rect@1.1.0(@types/react@18.3.18)(react@18.3.1)':
dependencies:
- '@webcomponents/shadycss': 1.11.2
+ '@radix-ui/rect': 1.1.0
+ react: 18.3.1
+ optionalDependencies:
+ '@types/react': 18.3.18
- '@probe.gl/env@4.1.0': {}
+ '@radix-ui/react-use-size@1.1.0(@types/react@18.3.18)(react@18.3.1)':
+ dependencies:
+ '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1)
+ react: 18.3.1
+ optionalDependencies:
+ '@types/react': 18.3.18
- '@probe.gl/log@4.1.0':
+ '@radix-ui/react-visually-hidden@1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
dependencies:
- '@probe.gl/env': 4.1.0
+ '@radix-ui/react-primitive': 2.0.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
+ react: 18.3.1
+ react-dom: 18.3.1(react@18.3.1)
+ optionalDependencies:
+ '@types/react': 18.3.18
+ '@types/react-dom': 18.3.5(@types/react@18.3.18)
- '@probe.gl/stats@4.1.0': {}
+ '@radix-ui/rect@1.1.0': {}
'@rollup/rollup-android-arm-eabi@4.35.0':
optional: true
@@ -2742,6 +3411,67 @@ snapshots:
'@rollup/rollup-win32-x64-msvc@4.35.0':
optional: true
+ '@tailwindcss/node@4.0.13':
+ dependencies:
+ enhanced-resolve: 5.18.1
+ jiti: 2.4.2
+ tailwindcss: 4.0.13
+
+ '@tailwindcss/oxide-android-arm64@4.0.13':
+ optional: true
+
+ '@tailwindcss/oxide-darwin-arm64@4.0.13':
+ optional: true
+
+ '@tailwindcss/oxide-darwin-x64@4.0.13':
+ optional: true
+
+ '@tailwindcss/oxide-freebsd-x64@4.0.13':
+ optional: true
+
+ '@tailwindcss/oxide-linux-arm-gnueabihf@4.0.13':
+ optional: true
+
+ '@tailwindcss/oxide-linux-arm64-gnu@4.0.13':
+ optional: true
+
+ '@tailwindcss/oxide-linux-arm64-musl@4.0.13':
+ optional: true
+
+ '@tailwindcss/oxide-linux-x64-gnu@4.0.13':
+ optional: true
+
+ '@tailwindcss/oxide-linux-x64-musl@4.0.13':
+ optional: true
+
+ '@tailwindcss/oxide-win32-arm64-msvc@4.0.13':
+ optional: true
+
+ '@tailwindcss/oxide-win32-x64-msvc@4.0.13':
+ optional: true
+
+ '@tailwindcss/oxide@4.0.13':
+ optionalDependencies:
+ '@tailwindcss/oxide-android-arm64': 4.0.13
+ '@tailwindcss/oxide-darwin-arm64': 4.0.13
+ '@tailwindcss/oxide-darwin-x64': 4.0.13
+ '@tailwindcss/oxide-freebsd-x64': 4.0.13
+ '@tailwindcss/oxide-linux-arm-gnueabihf': 4.0.13
+ '@tailwindcss/oxide-linux-arm64-gnu': 4.0.13
+ '@tailwindcss/oxide-linux-arm64-musl': 4.0.13
+ '@tailwindcss/oxide-linux-x64-gnu': 4.0.13
+ '@tailwindcss/oxide-linux-x64-musl': 4.0.13
+ '@tailwindcss/oxide-win32-arm64-msvc': 4.0.13
+ '@tailwindcss/oxide-win32-x64-msvc': 4.0.13
+
+ '@tailwindcss/vite@4.0.13(vite@6.2.1(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2))':
+ dependencies:
+ '@tailwindcss/node': 4.0.13
+ '@tailwindcss/oxide': 4.0.13
+ lightningcss: 1.29.2
+ tailwindcss: 4.0.13
+ vite: 6.2.1(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)
+
'@turf/boolean-clockwise@5.1.5':
dependencies:
'@turf/helpers': 5.1.5
@@ -2771,24 +3501,24 @@ snapshots:
'@types/babel__core@7.20.5':
dependencies:
- '@babel/parser': 7.26.9
- '@babel/types': 7.26.9
+ '@babel/parser': 7.26.10
+ '@babel/types': 7.26.10
'@types/babel__generator': 7.6.8
'@types/babel__template': 7.4.4
'@types/babel__traverse': 7.20.6
'@types/babel__generator@7.6.8':
dependencies:
- '@babel/types': 7.26.9
+ '@babel/types': 7.26.10
'@types/babel__template@7.4.4':
dependencies:
- '@babel/parser': 7.26.9
- '@babel/types': 7.26.9
+ '@babel/parser': 7.26.10
+ '@babel/types': 7.26.10
'@types/babel__traverse@7.20.6':
dependencies:
- '@babel/types': 7.26.9
+ '@babel/types': 7.26.10
'@types/brotli@1.3.4':
dependencies:
@@ -2840,10 +3570,6 @@ snapshots:
dependencies:
'@types/react': 18.3.18
- '@types/react-transition-group@4.4.12(@types/react@18.3.18)':
- dependencies:
- '@types/react': 18.3.18
-
'@types/react@18.3.18':
dependencies:
'@types/prop-types': 15.7.14
@@ -2961,14 +3687,14 @@ snapshots:
dependencies:
'@vaadin/vaadin-development-mode-detector': 2.0.7
- '@vitejs/plugin-react@4.3.4(vite@6.2.1(@types/node@22.13.10))':
+ '@vitejs/plugin-react@4.3.4(vite@6.2.1(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2))':
dependencies:
- '@babel/core': 7.26.9
- '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.9)
- '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.9)
+ '@babel/core': 7.26.10
+ '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.10)
+ '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.10)
'@types/babel__core': 7.20.5
react-refresh: 0.14.2
- vite: 6.2.1(@types/node@22.13.10)
+ vite: 6.2.1(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2)
transitivePeerDependencies:
- supports-color
@@ -3059,6 +3785,10 @@ snapshots:
dependencies:
sprintf-js: 1.0.3
+ aria-hidden@1.2.4:
+ dependencies:
+ tslib: 2.8.1
+
base64-js@1.5.1:
optional: true
@@ -3084,7 +3814,11 @@ snapshots:
charenc@0.0.2: {}
- clsx@1.2.1: {}
+ class-variance-authority@0.7.1:
+ dependencies:
+ clsx: 2.1.1
+
+ clsx@2.1.1: {}
color-convert@2.0.1:
dependencies:
@@ -3121,15 +3855,8 @@ snapshots:
crypt@0.0.2: {}
- css-vendor@2.0.8:
- dependencies:
- '@babel/runtime': 7.26.9
- is-in-browser: 1.1.3
-
cssfilter@0.0.10: {}
- csstype@2.6.21: {}
-
csstype@3.1.3: {}
d3-array@3.2.4:
@@ -3197,10 +3924,9 @@ snapshots:
dependencies:
core-assert: 0.2.1
- dom-helpers@5.2.1:
- dependencies:
- '@babel/runtime': 7.26.9
- csstype: 3.1.3
+ detect-libc@2.0.3: {}
+
+ detect-node-es@1.1.0: {}
draco3d@1.5.7: {}
@@ -3288,6 +4014,8 @@ snapshots:
xml-utils: 1.10.1
zstddec: 0.1.0
+ get-nonce@1.0.1: {}
+
gl-matrix@3.4.3: {}
globals@11.12.0: {}
@@ -3298,12 +4026,6 @@ snapshots:
hammerjs@2.0.8: {}
- hoist-non-react-statics@3.3.2:
- dependencies:
- react-is: 16.13.1
-
- hyphenate-style-name@1.1.0: {}
-
ieee754@1.2.1: {}
image-size@0.7.5: {}
@@ -3324,15 +4046,15 @@ snapshots:
is-error@2.2.2: {}
- is-in-browser@1.1.3: {}
-
isarray@1.0.0: {}
- jotai@1.13.1(@babel/core@7.26.9)(@babel/template@7.26.9)(react@18.3.1):
+ jiti@2.4.2: {}
+
+ jotai@1.13.1(@babel/core@7.26.10)(@babel/template@7.26.9)(react@18.3.1):
dependencies:
react: 18.3.1
optionalDependencies:
- '@babel/core': 7.26.9
+ '@babel/core': 7.26.10
'@babel/template': 7.26.9
js-tokens@4.0.0: {}
@@ -3343,52 +4065,6 @@ snapshots:
json5@2.2.3: {}
- jss-plugin-camel-case@10.10.0:
- dependencies:
- '@babel/runtime': 7.26.9
- hyphenate-style-name: 1.1.0
- jss: 10.10.0
-
- jss-plugin-default-unit@10.10.0:
- dependencies:
- '@babel/runtime': 7.26.9
- jss: 10.10.0
-
- jss-plugin-global@10.10.0:
- dependencies:
- '@babel/runtime': 7.26.9
- jss: 10.10.0
-
- jss-plugin-nested@10.10.0:
- dependencies:
- '@babel/runtime': 7.26.9
- jss: 10.10.0
- tiny-warning: 1.0.3
-
- jss-plugin-props-sort@10.10.0:
- dependencies:
- '@babel/runtime': 7.26.9
- jss: 10.10.0
-
- jss-plugin-rule-value-function@10.10.0:
- dependencies:
- '@babel/runtime': 7.26.9
- jss: 10.10.0
- tiny-warning: 1.0.3
-
- jss-plugin-vendor-prefixer@10.10.0:
- dependencies:
- '@babel/runtime': 7.26.9
- css-vendor: 2.0.8
- jss: 10.10.0
-
- jss@10.10.0:
- dependencies:
- '@babel/runtime': 7.26.9
- csstype: 3.1.3
- is-in-browser: 1.1.3
- tiny-warning: 1.0.3
-
jszip@3.10.1:
dependencies:
lie: 3.3.0
@@ -3406,6 +4082,51 @@ snapshots:
dependencies:
immediate: 3.0.6
+ lightningcss-darwin-arm64@1.29.2:
+ optional: true
+
+ lightningcss-darwin-x64@1.29.2:
+ optional: true
+
+ lightningcss-freebsd-x64@1.29.2:
+ optional: true
+
+ lightningcss-linux-arm-gnueabihf@1.29.2:
+ optional: true
+
+ lightningcss-linux-arm64-gnu@1.29.2:
+ optional: true
+
+ lightningcss-linux-arm64-musl@1.29.2:
+ optional: true
+
+ lightningcss-linux-x64-gnu@1.29.2:
+ optional: true
+
+ lightningcss-linux-x64-musl@1.29.2:
+ optional: true
+
+ lightningcss-win32-arm64-msvc@1.29.2:
+ optional: true
+
+ lightningcss-win32-x64-msvc@1.29.2:
+ optional: true
+
+ lightningcss@1.29.2:
+ dependencies:
+ detect-libc: 2.0.3
+ optionalDependencies:
+ lightningcss-darwin-arm64: 1.29.2
+ lightningcss-darwin-x64: 1.29.2
+ lightningcss-freebsd-x64: 1.29.2
+ lightningcss-linux-arm-gnueabihf: 1.29.2
+ lightningcss-linux-arm64-gnu: 1.29.2
+ lightningcss-linux-arm64-musl: 1.29.2
+ lightningcss-linux-x64-gnu: 1.29.2
+ lightningcss-linux-x64-musl: 1.29.2
+ lightningcss-win32-arm64-msvc: 1.29.2
+ lightningcss-win32-x64-msvc: 1.29.2
+
lit-element@4.1.1:
dependencies:
'@lit-labs/ssr-dom-shim': 1.3.0
@@ -3488,8 +4209,6 @@ snapshots:
dependencies:
fflate: 0.8.2
- object-assign@4.1.1: {}
-
p-map@7.0.3: {}
p-queue@7.4.1:
@@ -3516,8 +4235,6 @@ snapshots:
picocolors@1.1.1: {}
- popper.js@1.16.1-lts: {}
-
postcss@8.5.3:
dependencies:
nanoid: 3.3.9
@@ -3528,12 +4245,6 @@ snapshots:
process-nextick-args@2.0.1: {}
- prop-types@15.8.1:
- dependencies:
- loose-envify: 1.4.0
- object-assign: 4.1.1
- react-is: 16.13.1
-
protocol-buffers-schema@3.6.0: {}
quadbin@0.2.0:
@@ -3552,20 +4263,34 @@ snapshots:
react: 18.3.1
scheduler: 0.23.2
- react-is@16.13.1: {}
+ react-refresh@0.14.2: {}
- react-is@17.0.2: {}
+ react-remove-scroll-bar@2.3.8(@types/react@18.3.18)(react@18.3.1):
+ dependencies:
+ react: 18.3.1
+ react-style-singleton: 2.2.3(@types/react@18.3.18)(react@18.3.1)
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 18.3.18
- react-refresh@0.14.2: {}
+ react-remove-scroll@2.6.3(@types/react@18.3.18)(react@18.3.1):
+ dependencies:
+ react: 18.3.1
+ react-remove-scroll-bar: 2.3.8(@types/react@18.3.18)(react@18.3.1)
+ react-style-singleton: 2.2.3(@types/react@18.3.18)(react@18.3.1)
+ tslib: 2.8.1
+ use-callback-ref: 1.3.3(@types/react@18.3.18)(react@18.3.1)
+ use-sidecar: 1.1.3(@types/react@18.3.18)(react@18.3.1)
+ optionalDependencies:
+ '@types/react': 18.3.18
- react-transition-group@4.4.5(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
+ react-style-singleton@2.2.3(@types/react@18.3.18)(react@18.3.1):
dependencies:
- '@babel/runtime': 7.26.9
- dom-helpers: 5.2.1
- loose-envify: 1.4.0
- prop-types: 15.8.1
+ get-nonce: 1.0.1
react: 18.3.1
- react-dom: 18.3.1(react@18.3.1)
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 18.3.18
react@18.3.1:
dependencies:
@@ -3583,8 +4308,6 @@ snapshots:
reference-spec-reader@0.2.0: {}
- regenerator-runtime@0.14.1: {}
-
resolve-protobuf-schema@2.1.0:
dependencies:
protocol-buffers-schema: 3.6.0
@@ -3644,6 +4367,10 @@ snapshots:
tabbable@6.2.0: {}
+ tailwind-merge@3.0.2: {}
+
+ tailwindcss@4.0.13: {}
+
tapable@2.2.1: {}
texture-compressor@1.0.2:
@@ -3655,8 +4382,6 @@ snapshots:
timezone-groups@0.10.4: {}
- tiny-warning@1.0.3: {}
-
tslib@2.8.1: {}
type-fest@4.37.0: {}
@@ -3675,11 +4400,26 @@ snapshots:
escalade: 3.2.0
picocolors: 1.1.1
+ use-callback-ref@1.3.3(@types/react@18.3.18)(react@18.3.1):
+ dependencies:
+ react: 18.3.1
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 18.3.18
+
+ use-sidecar@1.1.3(@types/react@18.3.18)(react@18.3.1):
+ dependencies:
+ detect-node-es: 1.1.0
+ react: 18.3.1
+ tslib: 2.8.1
+ optionalDependencies:
+ '@types/react': 18.3.18
+
util-deprecate@1.0.2: {}
uzip-module@1.0.3: {}
- vite@6.2.1(@types/node@22.13.10):
+ vite@6.2.1(@types/node@22.13.10)(jiti@2.4.2)(lightningcss@1.29.2):
dependencies:
esbuild: 0.25.1
postcss: 8.5.3
@@ -3687,6 +4427,8 @@ snapshots:
optionalDependencies:
'@types/node': 22.13.10
fsevents: 2.3.3
+ jiti: 2.4.2
+ lightningcss: 1.29.2
web-streams-polyfill@3.3.3: {}
diff --git a/src/components/LayerController/AcquisitionController.tsx b/src/components/LayerController/AcquisitionController.tsx
index d2f3c519..8cd53997 100644
--- a/src/components/LayerController/AcquisitionController.tsx
+++ b/src/components/LayerController/AcquisitionController.tsx
@@ -1,45 +1,32 @@
-import { Grid, NativeSelect } from "@material-ui/core";
+import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import React from "react";
-import type { ChangeEvent } from "react";
-import { useSourceData } from "../../hooks";
-
-function AcquisitionController() {
- const [sourceData] = useSourceData();
- const { acquisitionId, acquisitions } = sourceData;
-
- if (!acquisitions) {
- return null;
- }
-
- const handleSelectionChange = (event: ChangeEvent) => {
- let value = event.target.value;
- const url = new URL(window.location.href);
- if (value === "-1") {
- url.searchParams.delete("acquisition");
- } else {
- url.searchParams.set("acquisition", value);
- }
- window.location.href = decodeURIComponent(url.href);
- };
+function AcquisitionController(props: {
+ acquisitionId: string | number | undefined;
+ acquisitions: Array;
+}) {
+ const { acquisitionId, acquisitions } = props;
+ const id = acquisitionId ? String(acquisitionId) : undefined;
return (
- <>
-
-
-
- {acquisitions.map((acq) => {
- acq = acq as Ome.Acquisition;
- return (
-
- );
- })}
-
-
- >
+
);
}
diff --git a/src/components/LayerController/AddChannelButton.tsx b/src/components/LayerController/AddChannelButton.tsx
index f4801fc2..8d57c11b 100644
--- a/src/components/LayerController/AddChannelButton.tsx
+++ b/src/components/LayerController/AddChannelButton.tsx
@@ -1,36 +1,26 @@
-import { Divider, IconButton, NativeSelect, Paper, Popover, Typography } from "@material-ui/core";
-import { Add } from "@material-ui/icons";
-import React, { useState } from "react";
-import type { ChangeEvent, MouseEvent } from "react";
+import { PlusIcon } from "@radix-ui/react-icons";
+import * as React from "react";
-import { useLayerState, useSourceData } from "../../hooks";
-import { MAX_CHANNELS, calcDataRange, hexToRGB, resolveLoaderFromLayerProps } from "../../utils";
+import { Button } from "@/components/ui/button";
+import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
+import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
+import { Separator } from "@/components/ui/separator";
+import { useLayerState, useSourceData } from "@/hooks";
+import { MAX_CHANNELS, calcDataRange, hexToRGB, resolveLoaderFromLayerProps } from "@/utils";
function AddChannelButton() {
const [source, setSource] = useSourceData();
const [layer, setLayer] = useLayerState();
- const [anchorEl, setAnchorEl] = useState(null);
- const handleClick = (event: MouseEvent) => {
- setAnchorEl(event.currentTarget);
- };
-
- const handleClose = () => {
- setAnchorEl(null);
- };
-
- const handleChange = async (event: ChangeEvent) => {
- handleClose();
- const channelIndex = +event.target.value;
- const channelSelection = [...source.defaults.selection];
- if (source.channel_axis) {
- channelSelection[source.channel_axis] = channelIndex;
- }
+ const handleChange = async (channelIndex: number) => {
+ const channelSelection = source.channel_axis
+ ? source.defaults.selection.with(source.channel_axis, channelIndex)
+ : [...source.defaults.selection];
// cacluate contrast limits if missing from source;
let lim: [min: number, max: number];
if (source.contrast_limits[channelIndex]) {
- lim = source.contrast_limits[channelIndex] as [number, number];
+ lim = source.contrast_limits[channelIndex];
} else {
const loader = resolveLoaderFromLayerProps(layer.layerProps);
const lowres = Array.isArray(loader) ? loader[loader.length - 1] : loader;
@@ -42,15 +32,13 @@ function AddChannelButton() {
return { ...prev, contrast_limits: clims };
});
}
-
- setLayer((prev) => {
- const { layerProps } = prev;
+ setLayer(({ layerProps, ...rest }) => {
const selections = [...layerProps.selections, channelSelection];
const colors = [...layerProps.colors, hexToRGB(source.colors[channelIndex])];
const contrastLimits = [...layerProps.contrastLimitsRange, lim];
const channelsVisible = [...layerProps.channelsVisible, true];
return {
- ...prev,
+ ...rest,
layerProps: {
...layerProps,
selections,
@@ -63,59 +51,35 @@ function AddChannelButton() {
});
};
- const { names } = source;
- const open = Boolean(anchorEl);
- const id = open ? `layer-${source.id}-add-channel` : undefined;
return (
- <>
-
-
-
-
-
- selection:
-
-
-
- {names.map((name, i) => (
-
+
))}
-
-
-
- >
+
+
+
+
);
}
diff --git a/src/components/LayerController/AxisOptions.tsx b/src/components/LayerController/AxisOptions.tsx
index 94bb4d22..6e9d347d 100644
--- a/src/components/LayerController/AxisOptions.tsx
+++ b/src/components/LayerController/AxisOptions.tsx
@@ -1,94 +1,47 @@
-import { Divider, IconButton, Input, Paper, Popover, Typography } from "@material-ui/core";
-import { MoreHoriz } from "@material-ui/icons";
-import { withStyles } from "@material-ui/styles";
-import React, { useState } from "react";
-import type { ChangeEvent, MouseEvent } from "react";
-import { useLayerState, useSourceData } from "../../hooks";
+import { DotsHorizontalIcon } from "@radix-ui/react-icons";
+import * as React from "react";
-const DenseInput = withStyles({
- root: {
- width: "5.5em",
- fontSize: "0.7em",
- },
-})(Input);
+import { Button } from "@/components/ui/button";
+import { Input } from "@/components/ui/input";
+import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
+import { Separator } from "@/components/ui/separator";
+import { useLayerState } from "@/hooks";
-interface Props {
- axisIndex: number;
- max: number;
-}
-
-function AxisOptions({ axisIndex, max }: Props) {
- const [sourceData] = useSourceData();
+function AxisOptions(props: { axisIndex: number; max: number }) {
+ const { axisIndex, max } = props;
const [layer, setLayer] = useLayerState();
- const [anchorEl, setAnchorEl] = useState(null);
-
- const handleClick = (event: MouseEvent) => {
- setAnchorEl(event.currentTarget);
- };
-
- const handleClose = () => {
- setAnchorEl(null);
- };
-
- const handleIndexChange = (event: ChangeEvent) => {
- let value = +event.target.value;
- // Restrict value to valid range
- if (value < 0) value = 0;
- if (value > max) value = max;
-
- setLayer((prev) => {
- let layerProps = { ...prev.layerProps };
- // for each channel, update index
- layerProps.selections = layerProps.selections.map((ch) => {
- let new_ch = [...ch];
- new_ch[axisIndex] = value;
- return new_ch;
- });
-
- return { ...prev, layerProps };
- });
- };
-
- const open = Boolean(anchorEl);
- const id = open ? `${axisIndex}-index-${sourceData.id}-options` : undefined;
const value = layer.layerProps.selections[0] ? layer.layerProps.selections[0][axisIndex] : 1;
-
return (
- <>
-
-
-
-
-
- Index:
-
-
-
-
-
- >
+
+
+
+
+
+ index:
+
+ {
+ let value = +event.target.value;
+ // Restrict value to valid range
+ if (value < 0) value = 0;
+ if (value > max) value = max;
+ setLayer(({ layerProps, ...rest }) => ({
+ ...rest,
+ layerProps: {
+ ...layerProps,
+ selections: layerProps.selections.map((ch) => ch.with(axisIndex, value)),
+ },
+ }));
+ }}
+ type="number"
+ id="max"
+ />
+
+
);
}
diff --git a/src/components/LayerController/AxisSlider.tsx b/src/components/LayerController/AxisSlider.tsx
index fd538cb0..8d42dd44 100644
--- a/src/components/LayerController/AxisSlider.tsx
+++ b/src/components/LayerController/AxisSlider.tsx
@@ -1,35 +1,20 @@
-import { Divider, Grid, Typography } from "@material-ui/core";
-import { Slider } from "@material-ui/core";
-import { withStyles } from "@material-ui/styles";
+import { Slider } from "@/components/ui/slider";
+import { useLayerState, useSourceData } from "@/hooks";
import * as React from "react";
-import type { ChangeEvent } from "react";
-import { useLayerState, useSourceData } from "../../hooks";
-import DimensionOptions from "./AxisOptions";
-const DenseSlider = withStyles({
- root: {
- color: "white",
- padding: "10px 0px 5px 0px",
- marginRight: "5px",
- },
- active: {
- boxshadow: "0px 0px 0px 8px rgba(158, 158, 158, 0.16)",
- },
-})(Slider);
+import DimensionOptions from "./AxisOptions";
-interface Props {
- axisIndex: number;
- max: number;
+function capitalize(s: string) {
+ return s.charAt(0).toUpperCase() + s.slice(1);
}
-function AxisSlider({ axisIndex, max }: Props) {
- const [layer, setLayer] = useLayerState();
+function AxisSlider(props: { axisIndex: number; max: number }) {
+ const { axisIndex, max } = props;
const [sourceData] = useSourceData();
+ const [layer, setLayer] = useLayerState();
const { axis_labels } = sourceData;
- let axisLabel = axis_labels[axisIndex];
- if (axisLabel === "t" || axisLabel === "z") {
- axisLabel = axisLabel.toUpperCase();
- }
+ const axisLabel = capitalize(axis_labels[axisIndex]);
+
// state of the slider to update UI while dragging
const [value, setValue] = React.useState(0);
@@ -39,53 +24,37 @@ function AxisSlider({ axisIndex, max }: Props) {
setValue(layer.layerProps.selections[0] ? layer.layerProps.selections[0][axisIndex] : 1);
}, [layer.layerProps.selections, axisIndex]);
- const handleRelease = () => {
- setLayer((prev) => {
- let layerProps = { ...prev.layerProps };
- // for each channel, update index of this axis
- layerProps.selections = layerProps.selections.map((ch) => {
- let new_ch = [...ch];
- new_ch[axisIndex] = value;
- return new_ch;
- });
- return { ...prev, layerProps };
- });
- };
-
- const handleDrag = (_: ChangeEvent, value: number | number[]) => {
- setValue(value as number);
- };
+ let id = `axis-${axisIndex}-${sourceData.id}-slider`;
return (
- <>
-
-
-
-
-
- {axisLabel}: {value}/{max}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >
+
+
+
+
+
+
+ setValue(update)}
+ onValueCommit={([update]) => {
+ setLayer((prev) => {
+ let layerProps = { ...prev.layerProps };
+ // for each channel, update index of this axis
+ layerProps.selections = layerProps.selections.map((ch) => {
+ return ch.with(axisIndex, update);
+ });
+ return { ...prev, layerProps };
+ });
+ }}
+ min={0}
+ max={max}
+ step={1}
+ />
+
+
);
}
diff --git a/src/components/LayerController/AxisSliders.tsx b/src/components/LayerController/AxisSliders.tsx
deleted file mode 100644
index a2b558a7..00000000
--- a/src/components/LayerController/AxisSliders.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import { Divider, Grid } from "@material-ui/core";
-import React from "react";
-import { useSourceData } from "../../hooks";
-import AxisSlider from "./AxisSlider";
-
-function AxisSliders() {
- const [sourceData] = useSourceData();
- const { axis_labels, channel_axis, loader } = sourceData;
-
- const sliders = axis_labels
- .slice(0, -2) // ignore last two axes, [y,x]
- .map((name, i): [string, number, number] => [name, i, loader[0].shape[i]]) // capture the name, index, and size of non-yx dims
- .filter((d) => {
- if (d[1] === channel_axis) return false; // ignore channel_axis (for OME-Zarr channel_axis === 1)
- if (d[2] > 1) return true; // keep if size > 1
- return false; // otherwise ignore as well
- })
- .map(([name, i, size]) => );
-
- if (sliders.length === 0) return null;
- return (
- <>
- {sliders}
-
- >
- );
-}
-
-export default AxisSliders;
diff --git a/src/components/LayerController/ChannelController.tsx b/src/components/LayerController/ChannelController.tsx
index d81e7c0f..29639940 100644
--- a/src/components/LayerController/ChannelController.tsx
+++ b/src/components/LayerController/ChannelController.tsx
@@ -1,84 +1,74 @@
-import { Grid, IconButton, Slider, Typography } from "@material-ui/core";
-import { RadioButtonChecked, RadioButtonUnchecked } from "@material-ui/icons";
-import React from "react";
-import type { ChangeEvent } from "react";
-import { useLayerState, useSourceData } from "../../hooks";
+import * as React from "react";
+
+import { Slider } from "@/components/ui/slider";
+import { useLayerState, useSourceData } from "@/hooks";
import ChannelOptions from "./ChannelOptions";
-function ChannelController({ channelIndex }: { channelIndex: number }) {
+function ChannelController(props: { channelIndex: number }) {
+ const { channelIndex: i } = props;
const [sourceData] = useSourceData();
const [layer, setLayer] = useLayerState();
- const handleContrastChange = (_: ChangeEvent, v: number | number[]) => {
- setLayer((prev) => {
- const contrastLimits = [...prev.layerProps.contrastLimits];
- contrastLimits[channelIndex] = v as [number, number];
- return { ...prev, layerProps: { ...prev.layerProps, contrastLimits } };
- });
- };
-
- const handleVisibilityChange = () => {
- setLayer((prev) => {
- const channelsVisible = [...prev.layerProps.channelsVisible];
- channelsVisible[channelIndex] = !channelsVisible[channelIndex];
- return { ...prev, layerProps: { ...prev.layerProps, channelsVisible } };
- });
- };
-
- const lp = layer.layerProps;
-
- // Material slider tries to sort in place. Need to copy.
- const value = [...lp.contrastLimits[channelIndex]];
- const color = `rgb(${lp.colormap ? [255, 255, 255] : lp.colors[channelIndex]})`;
- const on = lp.channelsVisible[channelIndex];
- const [min, max] = lp.contrastLimitsRange[channelIndex];
+ const value = layer.layerProps.contrastLimits[i];
+ const color = `rgb(${layer.layerProps.colormap ? [255, 255, 255] : layer.layerProps.colors[i]})`;
+ const on = layer.layerProps.channelsVisible[i];
+ const [min, max] = layer.layerProps.contrastLimitsRange[i];
const { channel_axis, names } = sourceData;
- const selection = lp.selections[channelIndex];
- const nameIndex = Number.isInteger(channel_axis) ? selection[channel_axis as number] : 0;
+ const selection = layer.layerProps.selections[i];
+ const nameIndex = Number.isInteger(channel_axis) && channel_axis !== null ? selection[channel_axis] : 0;
const label = names[nameIndex];
+
return (
<>
-
-
-
-
- {label}
-
-
-
-
-
-
-
-
-
-
- {on ? : }
-
-
-
-
+ {label}
+
+
+
+
+
{
+ setLayer((prev) => ({
+ ...prev,
+ layerProps: {
+ ...prev.layerProps,
+ contrastLimits: prev.layerProps.contrastLimits.with(i, [...update]),
+ },
+ }));
+ }}
+ color={color}
+ min={min}
+ max={max}
+ step={0.01}
+ />
+
>
);
}
diff --git a/src/components/LayerController/ChannelOptions.tsx b/src/components/LayerController/ChannelOptions.tsx
index 288b7d99..2790d51d 100644
--- a/src/components/LayerController/ChannelOptions.tsx
+++ b/src/components/LayerController/ChannelOptions.tsx
@@ -1,184 +1,156 @@
-import { Divider, IconButton, Input, NativeSelect, Paper, Popover, Typography } from "@material-ui/core";
-import { MoreHoriz, Remove } from "@material-ui/icons";
-import { withStyles } from "@material-ui/styles";
-import React, { useState } from "react";
-import type { ChangeEvent, MouseEvent } from "react";
-import { useLayerState, useSourceData } from "../../hooks";
-import ColorPalette from "./ColorPalette";
-
-const DenseInput = withStyles({
- root: {
- width: "5.5em",
- fontSize: "0.7em",
- },
-})(Input);
-
-interface Props {
- channelIndex: number;
-}
-
-function ChannelOptions({ channelIndex }: Props) {
- const [sourceData] = useSourceData();
+import { Cross2Icon, DotsHorizontalIcon } from "@radix-ui/react-icons";
+import * as React from "react";
+
+import { Button } from "@/components/ui/button";
+import { Input } from "@/components/ui/input";
+import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
+import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
+import { Separator } from "@/components/ui/separator";
+import { useLayerState, useSourceData } from "@/hooks";
+import { assert, COLORS, clamp, hexToRGB } from "@/utils";
+
+const RGB_COLORS: [string, string][] = Object.entries(COLORS);
+
+function ChannelOptions(props: { channelIndex: number }) {
+ const { channelIndex: i } = props;
+ const [info] = useSourceData();
const [layer, setLayer] = useLayerState();
- const [anchorEl, setAnchorEl] = useState(null);
- const { channel_axis, names } = sourceData;
-
- const handleClick = (event: MouseEvent) => {
- setAnchorEl(event.currentTarget);
- };
-
- const handleClose = () => {
- setAnchorEl(null);
- };
-
- const handleColorChange = (rgb: [number, number, number]) => {
- setLayer((prev) => {
- const colors = [...prev.layerProps.colors];
- colors[channelIndex] = rgb;
- return { ...prev, layerProps: { ...prev.layerProps, colors } };
- });
- };
-
- const handleContrastLimitChange = (event: ChangeEvent) => {
- const targetId = event.target.id;
- let value = +event.target.value;
-
- // Only let positive values
- if (value < 0) value = 0;
-
- setLayer((prev) => {
- // Need to move sliders in if contrast limits are narrower
- const contrastLimitsRange = [...prev.layerProps.contrastLimitsRange];
- const contrastLimits = [...prev.layerProps.contrastLimits];
-
- const [cmin, cmax] = contrastLimitsRange[channelIndex];
- const [smin, smax] = contrastLimits[channelIndex];
-
- // Calculate climit update
- const [umin, umax] = targetId === "min" ? [value, cmax] : [cmin, value];
-
- // Update sliders if needed
- if (umin > smin) contrastLimits[channelIndex] = [umin, smax];
- if (umax < smax) contrastLimits[channelIndex] = [smin, umax];
-
- // Update channel constrast limits range
- contrastLimitsRange[channelIndex] = [umin, umax];
-
+ const { channel_axis, names } = info;
+ assert(channel_axis !== null, "channel_axis is null");
+
+ const handleContrastLimitChange = (unclamped: number, which: "min" | "max") => {
+ const value = clamp(unclamped, 0, Number.POSITIVE_INFINITY);
+ setLayer(({ layerProps, ...rest }) => {
+ const lims = layerProps.contrastLimitsRange[i];
+ const vals = layerProps.contrastLimits[i];
+ const [min, max] = which === "min" ? [value, lims[1]] : [lims[0], value];
return {
- ...prev,
- layerProps: { ...prev.layerProps, contrastLimits, contrastLimitsRange },
- };
- });
- };
-
- const handleRemove = () => {
- setLayer((prev) => {
- const { layerProps } = prev;
- const colors = [...layerProps.colors];
- const contrastLimits = [...layerProps.contrastLimits];
- const contrastLimitsRange = [...layerProps.contrastLimitsRange];
- const selections = [...layerProps.selections];
- const channelsVisible = [...layerProps.channelsVisible];
- colors.splice(channelIndex, 1);
- contrastLimits.splice(channelIndex, 1);
- contrastLimitsRange.splice(channelIndex, 1);
- selections.splice(channelIndex, 1);
- channelsVisible.splice(channelIndex, 1);
- return {
- ...prev,
+ ...rest,
layerProps: {
...layerProps,
- colors,
- selections,
- channelsVisible,
- contrastLimits,
- contrastLimitsRange,
+ contrastLimits: layerProps.contrastLimits.with(i, [
+ clamp(vals[0], min, Number.POSITIVE_INFINITY),
+ clamp(vals[1], 0, max),
+ ]),
+ contrastLimitsRange: layerProps.contrastLimitsRange.with(i, [min, max]),
},
};
});
};
- const handleSelectionChange = (event: ChangeEvent) => {
- setLayer((prev) => {
- const selections = [...prev.layerProps.selections];
- const channelSelection = [...selections[channelIndex]];
- if (Number.isInteger(channel_axis)) {
- channelSelection[channel_axis as number] = +event.target.value;
- selections[channelIndex] = channelSelection;
- }
- return { ...prev, layerProps: { ...prev.layerProps, selections } };
- });
+ const handleSelectionChange = (idx: number) => {
+ setLayer(({ layerProps, ...rest }) => ({
+ ...rest,
+ layerProps: {
+ ...layerProps,
+ selections: layerProps.selections.with(i, layerProps.selections[i].with(channel_axis, idx)),
+ },
+ }));
};
- const open = Boolean(anchorEl);
- const id = open ? `channel-${channelIndex}-${sourceData.name}-options` : undefined;
- const [min, max] = layer.layerProps.contrastLimitsRange[channelIndex];
+ const [min, max] = layer.layerProps.contrastLimitsRange[i];
return (
- <>
-
-
-
-
-
-
- remove:
-
-
-
-
-
- selection:
-
-
+
+
+
+
+
+ remove:
+
+
+
+ channel:
+
+
-
- contrast limits:
-
-
-
-
- color:
-
-
-
-
-
-
- >
+
+
+
+ contrast limits:
+
+ {
+ if (e.key !== "Enter") return;
+ const value = +e.currentTarget.value;
+ handleContrastLimitChange(value, "min");
+ }}
+ onBlur={(e) => handleContrastLimitChange(+e.currentTarget.value, "min")}
+ />
+ {
+ if (e.key !== "Enter") return;
+ const value = +e.currentTarget.value;
+ handleContrastLimitChange(value, "max");
+ }}
+ onBlur={(e) => handleContrastLimitChange(+e.currentTarget.value, "max")}
+ />
+
+ color:
+
+
+ {RGB_COLORS.map(([name, rgb]) => (
+
+
+
);
}
diff --git a/src/components/LayerController/ColorPalette.tsx b/src/components/LayerController/ColorPalette.tsx
deleted file mode 100644
index b9c77fe4..00000000
--- a/src/components/LayerController/ColorPalette.tsx
+++ /dev/null
@@ -1,40 +0,0 @@
-import { IconButton } from "@material-ui/core";
-import { Lens } from "@material-ui/icons";
-import { makeStyles } from "@material-ui/styles";
-import React from "react";
-import { COLORS, hexToRGB } from "../../utils";
-
-const useStyles = makeStyles(() => ({
- container: {
- display: "flex",
- justifyContent: "space-between",
- alignItems: "center",
- padding: "2px",
- },
- button: {
- padding: "3px",
- width: "16px",
- height: "16px",
- },
-}));
-
-const RGB_COLORS: [string, [number, number, number]][] = Object.entries(COLORS).map(([name, hex]) => [
- name,
- hexToRGB(hex),
-]);
-function ColorPalette({ handleChange }: { handleChange: (c: [number, number, number]) => void }) {
- const classes = useStyles();
- return (
-
- {RGB_COLORS.map(([name, rgb]) => {
- return (
- handleChange(rgb)}>
-
-
- );
- })}
-
- );
-}
-
-export default ColorPalette;
diff --git a/src/components/LayerController/Content.tsx b/src/components/LayerController/Content.tsx
deleted file mode 100644
index 787d6f0f..00000000
--- a/src/components/LayerController/Content.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-import { AccordionDetails, Divider, Grid, Typography } from "@material-ui/core";
-import { withStyles } from "@material-ui/styles";
-import React from "react";
-
-import AcquisitionController from "./AcquisitionController";
-import AddChannelButton from "./AddChannelButton";
-import AxisSliders from "./AxisSliders";
-import ChannelController from "./ChannelController";
-import Labels from "./Labels";
-import OpacitySlider from "./OpacitySlider";
-
-import { useLayerState } from "../../hooks";
-import { range } from "../../utils";
-
-const Details = withStyles({
- root: {
- padding: "2px 5px",
- borderLeft: "1px solid rgba(150, 150, 150, .2)",
- borderRight: "1px solid rgba(150, 150, 150, .2)",
- },
-})(AccordionDetails);
-
-function Content() {
- const [layer] = useLayerState();
- const nChannels = layer.layerProps.selections.length;
- return (
-
-
-
-
-
-
- opacity:
-
-
-
-
-
-
-
-
-
- channels:
-
-
-
-
-
-
-
- {range(nChannels).map((i) => (
-
- ))}
-
- {layer.labels?.length && (
- <>
-
- labels:
-
-
-
- {layer.labels.map((label, i) => (
-
- ))}
-
- >
- )}
-
-
- );
-}
-
-export default Content;
diff --git a/src/components/LayerController/Header.tsx b/src/components/LayerController/Header.tsx
deleted file mode 100644
index 07afe096..00000000
--- a/src/components/LayerController/Header.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import { AccordionSummary, Typography } from "@material-ui/core";
-import { withStyles } from "@material-ui/styles";
-import React from "react";
-import LayerVisibilityButton from "./LayerVisibilityButton";
-
-import { useSourceData } from "../../hooks";
-
-const DenseAccordionSummary = withStyles({
- root: {
- borderBottom: "1px solid rgba(150, 150, 150, .125)",
- backgroundColor: "rgba(150, 150, 150, 0.25)",
- display: "block",
- padding: "0 3px",
- height: 27,
- minHeight: 27,
- overflow: "hidden",
- transition: "none",
- "&$expanded": {
- minHeight: 27,
- },
- },
- content: {
- margin: 0,
- "&$expanded": {
- margin: 0,
- },
- },
- expanded: {},
-})(AccordionSummary);
-
-function Header({ name }: { name: string }) {
- const [sourceData] = useSourceData();
- const label = `layer-controller-${sourceData.id}`;
- return (
-
-
-
-
- {name}
-
-
-
- );
-}
-
-export default Header;
diff --git a/src/components/LayerController/Labels.tsx b/src/components/LayerController/Labels.tsx
index 81d6fe85..614d1c4e 100644
--- a/src/components/LayerController/Labels.tsx
+++ b/src/components/LayerController/Labels.tsx
@@ -1,16 +1,16 @@
-import { Grid, IconButton, Slider, Typography } from "@material-ui/core";
-import { RadioButtonChecked, RadioButtonUnchecked } from "@material-ui/icons";
import React from "react";
-import { useLayerState, useSourceData } from "../../hooks";
-import { assert } from "../../utils";
+import { Slider } from "@/components/ui/slider";
+
+import { useLayerState, useSourceData } from "@/hooks";
+import { assert } from "@/utils";
export default function Labels({ labelIndex }: { labelIndex: number }) {
const [source] = useSourceData();
const [layer, setLayer] = useLayerState();
assert(source.labels && layer.kind === "multiscale" && layer.labels, "Missing image labels");
- const handleOpacityChange = (_: unknown, value: number | number[]) => {
+ const handleOpacityChange = ([value]: Array) => {
setLayer((prev) => {
assert(prev.kind === "multiscale" && prev.labels, "Missing image labels");
return {
@@ -30,44 +30,44 @@ export default function Labels({ labelIndex }: { labelIndex: number }) {
const label = layer.labels[labelIndex];
return (
<>
-
-
-
- {name}
-
-
-
-
-
- {
- setLayer((prev) => {
- assert(prev.kind === "multiscale" && prev.labels, "Missing image labels");
- return {
- ...prev,
- labels: prev.labels.with(labelIndex, {
- ...prev.labels[labelIndex],
- on: !prev.labels[labelIndex].on,
- }),
- };
- });
+
+ {name}
+
+
+
+
+
>
);
}
diff --git a/src/components/LayerController/LayerVisibilityButton.tsx b/src/components/LayerController/LayerVisibilityButton.tsx
deleted file mode 100644
index 4db732d9..00000000
--- a/src/components/LayerController/LayerVisibilityButton.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-import { IconButton } from "@material-ui/core";
-import { Visibility, VisibilityOff } from "@material-ui/icons";
-import React from "react";
-import type { MouseEvent } from "react";
-import { useLayerState, useSourceData } from "../../hooks";
-
-function LayerVisibilityButton() {
- const [sourceData] = useSourceData();
- const [layer, setLayer] = useLayerState();
- const toggle = (event: MouseEvent) => {
- event.stopPropagation();
- setLayer((prev) => {
- const on = !prev.on;
- return { ...prev, on };
- });
- };
- return (
-
- {layer.on ? : }
-
- );
-}
-
-export default LayerVisibilityButton;
diff --git a/src/components/LayerController/OpacitySlider.tsx b/src/components/LayerController/OpacitySlider.tsx
deleted file mode 100644
index 2233b5e1..00000000
--- a/src/components/LayerController/OpacitySlider.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import { Slider } from "@material-ui/core";
-import { withStyles } from "@material-ui/styles";
-import React from "react";
-import type { ChangeEvent } from "react";
-import { useLayerState } from "../../hooks";
-
-const DenseSlider = withStyles({
- root: {
- color: "white",
- padding: "10px 0px 5px 0px",
- marginRight: "5px",
- },
- active: {
- boxshadow: "0px 0px 0px 8px rgba(158, 158, 158, 0.16)",
- },
-})(Slider);
-
-function OpacitySlider() {
- const [layer, setLayer] = useLayerState();
- const handleChange = (_: ChangeEvent, value: number | number[]) => {
- const opacity = value as number;
- setLayer((prev) => ({ ...prev, layerProps: { ...prev.layerProps, opacity } }));
- };
- return ;
-}
-
-export default OpacitySlider;
diff --git a/src/components/LayerController/index.tsx b/src/components/LayerController/index.tsx
index 8e13043e..2fe8dc51 100644
--- a/src/components/LayerController/index.tsx
+++ b/src/components/LayerController/index.tsx
@@ -1,41 +1,134 @@
-import MuiAccordion from "@material-ui/core/Accordion";
-import { withStyles } from "@material-ui/styles";
-import React from "react";
+import { EyeNoneIcon, EyeOpenIcon } from "@radix-ui/react-icons";
+import { useAtom } from "jotai";
-import { LayerStateContext, useSourceData } from "../../hooks";
-import { layerFamilyAtom } from "../../state";
-import Content from "./Content";
-import Header from "./Header";
+import AcquisitionSelect from "./AcquisitionController";
+import AddChannelButton from "./AddChannelButton";
+import AxisSlider from "./AxisSlider";
+import ChannelController from "./ChannelController";
+import Labels from "./Labels";
-const Accordion = withStyles({
- root: {
- borderBottom: "1px solid rgba(150, 150, 150, .2)",
- width: 200,
- boxshadow: "none",
- "&:not(:last-child)": {
- borderBottom: 0,
- },
- "&:before": {
- display: "none",
- },
- "&$expanded": {
- margin: 0,
- padding: 0,
- },
- },
- expanded: {
- padding: 1,
- },
-})(MuiAccordion);
+import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion";
+import { Separator } from "@/components/ui/separator";
+import { Slider } from "@/components/ui/slider";
+import { LayerStateContext, useSourceData } from "@/hooks";
+import { layerFamilyAtom } from "@/state";
+import { range } from "@/utils";
+
+/** Get the { name, idx, size } for each axis that is not the channel_axis and has size > 1 */
+function axisSliders(info: {
+ axis_labels: string[];
+ channel_axis: number | null;
+ loader: Array<{ shape: number[] }>;
+}): Array<{ name: string; idx: number; size: number }> {
+ const { axis_labels, channel_axis, loader } = info;
+ return axis_labels
+ .slice(0, -2) // ignore last two axes, [y,x]
+ .map((name, idx) => ({ name, idx, size: loader[0].shape[idx] }))
+ .filter(({ idx, size }) => {
+ // ignore channel_axis (for OME-Zarr channel_axis === 1)
+ if (idx === channel_axis) return false;
+ // keep if size > 1
+ return size > 1;
+ });
+}
function LayerController() {
- const [sourceInfo] = useSourceData();
- const layerAtom = layerFamilyAtom(sourceInfo);
+ const [info] = useSourceData();
+ const layerAtom = layerFamilyAtom(info);
+ const [layer, setLayer] = useAtom(layerAtom);
+ const { name = "" } = info;
+ const nChannels = layer.layerProps.selections.length;
return (
-
-
-
+
+
+
+
+
+ {name}
+
+
+
+ {(info.acquisitions?.length ?? 0) > 0 ? (
+ <>
+ {/* biome-ignore lint/style/noNonNullAssertion: Ok because we assert above */}
+
+
+ >
+ ) : null}
+
+
+ {
+ const [opacity] = update;
+ setLayer((prev) => ({ ...prev, layerProps: { ...prev.layerProps, opacity } }));
+ }}
+ min={0}
+ max={1}
+ step={0.01}
+ />
+
+
+ {axisSliders(info).map(({ name, idx, size }) => (
+
+ ))}
+
+
+
+
+ {range(nChannels).map((i) => (
+
+ ))}
+
+ {layer.labels?.length && (
+ <>
+
+ labels:
+
+
+
+ {layer.labels.map((label, i) => (
+
+ ))}
+
+ >
+ )}
+
+
);
diff --git a/src/components/Menu.tsx b/src/components/Menu.tsx
index fd6e84db..dd4122b0 100644
--- a/src/components/Menu.tsx
+++ b/src/components/Menu.tsx
@@ -1,6 +1,3 @@
-import { Grid, IconButton } from "@material-ui/core";
-import { Add, Remove } from "@material-ui/icons";
-import { makeStyles } from "@material-ui/styles";
import { useAtomValue } from "jotai";
import React, { useReducer } from "react";
@@ -8,46 +5,29 @@ import { SourceDataContext } from "../hooks";
import { sourceInfoAtomAtoms } from "../state";
import LayerController from "./LayerController";
-const useStyles = makeStyles({
- root: {
- zIndex: 1,
- position: "absolute",
- backgroundColor: "rgba(0, 0, 0, 0.7)",
- borderRadius: "5px",
- left: "5px",
- top: "5px",
- },
- scroll: {
- maxHeight: 500,
- overflowX: "hidden",
- overflowY: "scroll",
- "&::-webkit-scrollbar": {
- display: "none",
- background: "transparent",
- },
- scrollbarWidth: "none",
- flexDirection: "column",
- },
-});
+import { cn } from "@/lib/utils";
+import { MinusIcon, PlusIcon } from "@radix-ui/react-icons";
-function Menu(props: { open?: boolean }) {
- const sourceAtoms = useAtomValue(sourceInfoAtomAtoms);
- const [hidden, toggle] = useReducer((v) => !v, !(props.open ?? true));
- const classes = useStyles();
+function Menu({ open = true }: { open?: boolean }) {
+ const atoms = useAtomValue(sourceInfoAtomAtoms);
+ const [hidden, toggle] = useReducer((v) => !v, !open);
return (
-
-
-
- {hidden ? : }
-
-
- {sourceAtoms.map((sourceAtom) => (
-
-
-
- ))}
-
-
+
+
+
+ {atoms.map((sourceAtom) => (
+
+
+
+ ))}
+
);
}
diff --git a/src/components/ui/accordion.tsx b/src/components/ui/accordion.tsx
new file mode 100644
index 00000000..94c9f8aa
--- /dev/null
+++ b/src/components/ui/accordion.tsx
@@ -0,0 +1,51 @@
+import * as AccordionPrimitive from "@radix-ui/react-accordion";
+import { ChevronDownIcon } from "@radix-ui/react-icons";
+import * as React from "react";
+
+import { cn } from "@/lib/utils";
+
+const Accordion = AccordionPrimitive.Root;
+
+const AccordionItem = React.forwardRef<
+ React.ElementRef
,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+AccordionItem.displayName = "AccordionItem";
+
+const AccordionTrigger = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+ svg]:rotate-180",
+ className,
+ )}
+ {...props}
+ >
+ {children}
+
+
+
+));
+AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;
+
+const AccordionContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+ {children}
+
+));
+AccordionContent.displayName = AccordionPrimitive.Content.displayName;
+
+export { Accordion, AccordionItem, AccordionTrigger, AccordionContent };
diff --git a/src/components/ui/button.tsx b/src/components/ui/button.tsx
new file mode 100644
index 00000000..0187ec1f
--- /dev/null
+++ b/src/components/ui/button.tsx
@@ -0,0 +1,48 @@
+import { Slot } from "@radix-ui/react-slot";
+import { type VariantProps, cva } from "class-variance-authority";
+import * as React from "react";
+
+import { cn } from "@/lib/utils";
+
+const buttonVariants = cva(
+ "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
+ {
+ variants: {
+ variant: {
+ default: "bg-primary text-primary-foreground shadow hover:bg-primary/90",
+ destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
+ outline: "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
+ secondary: "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
+ ghost: "hover:bg-accent hover:text-accent-foreground",
+ link: "text-primary underline-offset-4 hover:underline",
+ },
+ size: {
+ default: "h-9 px-4 py-2",
+ sm: "h-8 rounded-md px-3 text-xs",
+ lg: "h-10 rounded-md px-8",
+ icon: "h-9 w-9",
+ "icon-sm": "h-6 w-6",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ size: "default",
+ },
+ },
+);
+
+export interface ButtonProps
+ extends React.ButtonHTMLAttributes,
+ VariantProps {
+ asChild?: boolean;
+}
+
+const Button = React.forwardRef(
+ ({ className, variant, size, asChild = false, ...props }, ref) => {
+ const Comp = asChild ? Slot : "button";
+ return ;
+ },
+);
+Button.displayName = "Button";
+
+export { Button, buttonVariants };
diff --git a/src/components/ui/card.tsx b/src/components/ui/card.tsx
new file mode 100644
index 00000000..ef73e8f1
--- /dev/null
+++ b/src/components/ui/card.tsx
@@ -0,0 +1,43 @@
+import * as React from "react";
+
+import { cn } from "@/lib/utils";
+
+const Card = React.forwardRef>(({ className, ...props }, ref) => (
+
+));
+Card.displayName = "Card";
+
+const CardHeader = React.forwardRef>(
+ ({ className, ...props }, ref) => (
+
+ ),
+);
+CardHeader.displayName = "CardHeader";
+
+const CardTitle = React.forwardRef>(
+ ({ className, ...props }, ref) => (
+
+ ),
+);
+CardTitle.displayName = "CardTitle";
+
+const CardDescription = React.forwardRef>(
+ ({ className, ...props }, ref) => (
+
+ ),
+);
+CardDescription.displayName = "CardDescription";
+
+const CardContent = React.forwardRef>(
+ ({ className, ...props }, ref) => ,
+);
+CardContent.displayName = "CardContent";
+
+const CardFooter = React.forwardRef>(
+ ({ className, ...props }, ref) => (
+
+ ),
+);
+CardFooter.displayName = "CardFooter";
+
+export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };
diff --git a/src/components/ui/input.tsx b/src/components/ui/input.tsx
new file mode 100644
index 00000000..d88afdf2
--- /dev/null
+++ b/src/components/ui/input.tsx
@@ -0,0 +1,22 @@
+import * as React from "react";
+
+import { cn } from "@/lib/utils";
+
+export interface InputProps extends React.InputHTMLAttributes {}
+
+const Input = React.forwardRef(({ className, type, ...props }, ref) => {
+ return (
+
+ );
+});
+Input.displayName = "Input";
+
+export { Input };
diff --git a/src/components/ui/popover.tsx b/src/components/ui/popover.tsx
new file mode 100644
index 00000000..ddca21e8
--- /dev/null
+++ b/src/components/ui/popover.tsx
@@ -0,0 +1,31 @@
+import * as PopoverPrimitive from "@radix-ui/react-popover";
+import * as React from "react";
+
+import { cn } from "@/lib/utils";
+
+const Popover = PopoverPrimitive.Root;
+
+const PopoverTrigger = PopoverPrimitive.Trigger;
+
+const PopoverAnchor = PopoverPrimitive.Anchor;
+
+const PopoverContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, align = "center", sideOffset = 4, ...props }, ref) => (
+
+
+
+));
+PopoverContent.displayName = PopoverPrimitive.Content.displayName;
+
+export { Popover, PopoverTrigger, PopoverContent, PopoverAnchor };
diff --git a/src/components/ui/select.tsx b/src/components/ui/select.tsx
new file mode 100644
index 00000000..c4980152
--- /dev/null
+++ b/src/components/ui/select.tsx
@@ -0,0 +1,142 @@
+import { CaretSortIcon, CheckIcon, ChevronDownIcon, ChevronUpIcon } from "@radix-ui/react-icons";
+import * as SelectPrimitive from "@radix-ui/react-select";
+import * as React from "react";
+
+import { cn } from "@/lib/utils";
+
+const Select = SelectPrimitive.Root;
+
+const SelectGroup = SelectPrimitive.Group;
+
+const SelectValue = SelectPrimitive.Value;
+
+const SelectTrigger = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+ span]:line-clamp-1",
+ className,
+ )}
+ {...props}
+ >
+ {children}
+
+
+
+
+));
+SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
+
+const SelectScrollUpButton = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+
+
+));
+SelectScrollUpButton.displayName = SelectPrimitive.ScrollUpButton.displayName;
+
+const SelectScrollDownButton = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+
+
+));
+SelectScrollDownButton.displayName = SelectPrimitive.ScrollDownButton.displayName;
+
+const SelectContent = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, position = "popper", ...props }, ref) => (
+
+
+
+
+ {children}
+
+
+
+
+));
+SelectContent.displayName = SelectPrimitive.Content.displayName;
+
+const SelectLabel = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+SelectLabel.displayName = SelectPrimitive.Label.displayName;
+
+const SelectItem = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, children, ...props }, ref) => (
+
+
+
+
+
+
+ {children}
+
+));
+SelectItem.displayName = SelectPrimitive.Item.displayName;
+
+const SelectSeparator = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, ...props }, ref) => (
+
+));
+SelectSeparator.displayName = SelectPrimitive.Separator.displayName;
+
+export {
+ Select,
+ SelectGroup,
+ SelectValue,
+ SelectTrigger,
+ SelectContent,
+ SelectLabel,
+ SelectItem,
+ SelectSeparator,
+ SelectScrollUpButton,
+ SelectScrollDownButton,
+};
diff --git a/src/components/ui/separator.tsx b/src/components/ui/separator.tsx
new file mode 100644
index 00000000..f90af383
--- /dev/null
+++ b/src/components/ui/separator.tsx
@@ -0,0 +1,20 @@
+import * as SeparatorPrimitive from "@radix-ui/react-separator";
+import * as React from "react";
+
+import { cn } from "@/lib/utils";
+
+const Separator = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, orientation = "horizontal", decorative = true, ...props }, ref) => (
+
+));
+Separator.displayName = SeparatorPrimitive.Root.displayName;
+
+export { Separator };
diff --git a/src/components/ui/slider.tsx b/src/components/ui/slider.tsx
new file mode 100644
index 00000000..aa57bece
--- /dev/null
+++ b/src/components/ui/slider.tsx
@@ -0,0 +1,34 @@
+import * as SliderPrimitive from "@radix-ui/react-slider";
+import * as React from "react";
+
+import { cn } from "@/lib/utils";
+
+const Slider = React.forwardRef<
+ React.ElementRef,
+ React.ComponentPropsWithoutRef
+>(({ className, color, ...props }, ref) => {
+ const initialValue = Array.isArray(props.value) ? props.value : [props.min, props.max];
+ return (
+
+
+
+
+ {initialValue.map((_, index) => (
+ // biome-ignore lint/suspicious/noArrayIndexKey: Ok because the array is static
+
+
+
+ ))}
+
+ );
+});
+Slider.displayName = SliderPrimitive.Root.displayName;
+
+export { Slider };
diff --git a/src/index.css b/src/index.css
new file mode 100644
index 00000000..a02a2cda
--- /dev/null
+++ b/src/index.css
@@ -0,0 +1,89 @@
+@import "tailwindcss";
+
+@layer base {
+ :root {
+ --background: 240 10% 3.9%;
+ --foreground: 0 0% 98%;
+ --card: 240 10% 3.9%;
+ --card-foreground: 0 0% 98%;
+ --popover: 240 10% 3.9%;
+ --popover-foreground: 0 0% 98%;
+ --primary: 0 0% 98%;
+ --primary-foreground: 240 5.9% 10%;
+ --secondary: 240 3.7% 15.9%;
+ --secondary-foreground: 0 0% 98%;
+ --muted: 240 3.7% 15.9%;
+ --muted-foreground: 240 5% 64.9%;
+ --accent: 240 3.7% 15.9%;
+ --accent-foreground: 0 0% 98%;
+ --destructive: 0 62.8% 30.6%;
+ --destructive-foreground: 0 0% 98%;
+ --border: 240 3.7% 15.9%;
+ --input: 240 3.7% 15.9%;
+ --ring: 240 4.9% 83.9%;
+ --chart-1: 220 70% 50%;
+ --chart-2: 160 60% 45%;
+ --chart-3: 30 80% 55%;
+ --chart-4: 280 65% 60%;
+ --chart-5: 340 75% 55%;
+ }
+}
+
+@theme {
+ --color-border: hsl(var(--border));
+ --color-input: hsl(var(--input));
+ --color-ring: hsl(var(--ring));
+ --color-background: hsl(var(--background));
+ --color-foreground: hsl(var(--foreground));
+
+ --color-primary: hsl(var(--primary));
+ --color-primary-foreground: hsl(var(--primary-foreground));
+
+ --color-secondary: hsl(var(--secondary));
+ --color-secondary-foreground: hsl(var(--secondary-foreground));
+
+ --color-destructive: hsl(var(--destructive));
+ --color-destructive-foreground: hsl(var(--destructive-foreground));
+
+ --color-muted: hsl(var(--muted));
+ --color-muted-foreground: hsl(var(--muted-foreground));
+
+ --color-accent: hsl(var(--accent));
+ --color-accent-foreground: hsl(var(--accent-foreground));
+
+ --color-popover: hsl(var(--popover));
+ --color-popover-foreground: hsl(var(--popover-foreground));
+
+ --color-card: hsl(var(--card));
+ --color-card-foreground: hsl(var(--card-foreground));
+
+ --radius-sm: calc(var(--radius) - 4px);
+ --radius-md: calc(var(--radius) - 2px);
+ --radius-lg: var(--radius);
+
+ --font-family-poppins: var(--font-poppins);
+ --font-family-inter: var(--font-inter);
+
+ --animate-accordion-down: accordion-down 0.2s ease-out;
+ --animate-accordion-up: accordion-up 0.2s ease-out;
+
+ @keyframes accordion-down {
+ from {
+ height: 0;
+ }
+
+ to {
+ height: var(--radix-accordion-content-height);
+ }
+ }
+
+ @keyframes accordion-up {
+ from {
+ height: var(--radix-accordion-content-height);
+ }
+
+ to {
+ height: "0";
+ }
+ }
+}
diff --git a/src/index.tsx b/src/index.tsx
index 4f9df005..54058568 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -1,7 +1,5 @@
-import { Link, Typography } from "@material-ui/core";
-import { ThemeProvider, makeStyles } from "@material-ui/styles";
-import { type PrimitiveAtom, Provider, atom } from "jotai";
-import { useAtomValue, useSetAtom } from "jotai";
+import { type PrimitiveAtom, Provider, atom, useAtomValue } from "jotai";
+import { useSetAtom } from "jotai";
import * as React from "react";
import ReactDOM from "react-dom/client";
@@ -9,6 +7,7 @@ import Menu from "./components/Menu";
import Viewer from "./components/Viewer";
import "./codecs/register";
import { ViewStateContext } from "./hooks";
+
import {
type ImageLayerConfig,
type ViewState,
@@ -17,11 +16,12 @@ import {
sourceErrorAtom,
viewStateAtom,
} from "./state";
-import theme from "./theme";
import { defer, typedEmitter } from "./utils";
export { version } from "../package.json";
+import "./index.css";
+
type Events = {
viewStateChange: ViewState;
};
@@ -35,23 +35,14 @@ export interface VizarrViewer {
destroy(): void;
}
-const useStyles = makeStyles({
- errorContainer: {
- position: "fixed",
- top: 0,
- bottom: 0,
- left: 0,
- right: 0,
- color: "#fff",
- display: "flex",
- alignItems: "center",
- textAlign: "center",
- justifyContent: "center",
- fontSize: "120%",
- },
-});
-
export function createViewer(element: HTMLElement, options: { menuOpen?: boolean } = {}): Promise {
+ const shadowRoot = element.attachShadow({ mode: "open" });
+ const link = Object.assign(document.createElement("link"), {
+ rel: "stylesheet",
+ href: new URL(/* @vite-ignore */ "index.css", import.meta.url).href,
+ });
+ shadowRoot.appendChild(link);
+
const ref = React.createRef();
const emitter = typedEmitter();
const viewStateAtomWithEffect: PrimitiveAtom = atom(
@@ -88,7 +79,6 @@ export function createViewer(element: HTMLElement, options: { menuOpen?: boolean
resolve(ref.current);
}
}, []);
- const classes = useStyles();
return (
<>
{sourceError === null && redirectObj === null && (
@@ -98,30 +88,26 @@ export function createViewer(element: HTMLElement, options: { menuOpen?: boolean
)}
{sourceError !== null && (
-
+
{`Error: server replied with "${sourceError}" when loading the resource`}
)}
{redirectObj !== null && (
-
-
+
)}
>
);
}
- let root = ReactDOM.createRoot(element);
+ let root = ReactDOM.createRoot(shadowRoot);
root.render(
-
-
-
-
-
-
- ,
+
+
+ ,
);
return promise;
}
diff --git a/src/lib/utils.ts b/src/lib/utils.ts
new file mode 100644
index 00000000..365058ce
--- /dev/null
+++ b/src/lib/utils.ts
@@ -0,0 +1,6 @@
+import { type ClassValue, clsx } from "clsx";
+import { twMerge } from "tailwind-merge";
+
+export function cn(...inputs: ClassValue[]) {
+ return twMerge(clsx(inputs));
+}
diff --git a/src/theme.ts b/src/theme.ts
deleted file mode 100644
index 632ef1ce..00000000
--- a/src/theme.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-import grey from "@material-ui/core/colors/grey";
-import { createTheme } from "@material-ui/core/styles";
-
-export default createTheme({
- palette: {
- type: "dark",
- primary: grey,
- secondary: grey,
- },
- props: {
- MuiButton: {
- size: "small",
- },
- MuiButtonBase: {
- disableRipple: true,
- },
- MuiFilledInput: {
- margin: "dense",
- },
- MuiFormControl: {
- margin: "dense",
- },
- MuiFormHelperText: {
- margin: "dense",
- },
- MuiIconButton: {
- size: "small",
- },
- MuiInputBase: {
- margin: "dense",
- },
- MuiInputLabel: {
- margin: "dense",
- },
- MuiOutlinedInput: {
- margin: "dense",
- },
- },
- overrides: {
- MuiSlider: {
- thumb: {
- "&:focus, &:hover": {
- boxShadow: "none",
- },
- height: 11,
- width: 5,
- borderRadius: "15%",
- marginLeft: -1,
- },
- },
- MuiInput: {
- underline: {
- "&&&&:hover:before": {
- borderBottom: "1px solid #fff",
- },
- },
- },
- MuiPaper: {
- root: {
- backgroundColor: "rgba(0, 0, 0, 0.8)",
- },
- },
- MuiSvgIcon: {
- root: {
- width: "0.7em",
- height: "0.7em",
- },
- },
- },
-});
diff --git a/src/utils.ts b/src/utils.ts
index fb517195..8b1bd018 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -24,6 +24,8 @@ export const RGB = [COLORS.red, COLORS.green, COLORS.blue];
export const CYMRGB = Object.values(COLORS).slice(0, -2);
export const OME_VALIDATOR_URL = "https://ome.github.io/ome-ngff-validator/";
+export { clamp } from "math.gl";
+
async function normalizeStore(source: string | zarr.Readable): Promise> {
if (typeof source === "string") {
let store: zarr.Readable;
diff --git a/tsconfig.json b/tsconfig.json
index 62b84831..c6ce8edf 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -9,6 +9,10 @@
"forceConsistentCasingInFileNames": true,
"verbatimModuleSyntax": true,
"jsx": "preserve",
+ "baseUrl": ".",
+ "paths": {
+ "@/*": ["./src/*"]
+ },
"types": ["vite/client"]
}
}
diff --git a/vite.config.js b/vite.config.js
index 409e82ec..0af56b77 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -1,5 +1,6 @@
import * as path from "node:path";
+import tailwindcss from "@tailwindcss/vite";
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";
@@ -7,26 +8,35 @@ import { defineConfig } from "vite";
* Writes a new entry point that exports contents of an existing chunk.
* @param {string} entryPointName - Name of the new entry point
* @param {RegExp} chunkName - Name of the existing chunk
+ * @return {import("vite").Plugin}
*/
function writeEntryPoint(entryPointName, chunkName) {
+ const jsFile = `${entryPointName}.js`;
+ const cssFile = `${entryPointName}.css`;
return {
name: "write-entry-point",
async generateBundle(_, bundle) {
- const chunk = Object.keys(bundle).find((key) => key.match(chunkName));
- if (!chunk) {
+ const chunk = Object.values(bundle).find((key) => key.type === "chunk" && key.fileName.match(chunkName));
+ const styles = Object.values(bundle).find((key) => key.type === "asset" && key.fileName.match(chunkName));
+ if (!chunk || !styles) {
throw new Error(`Could not find chunk matching ${chunkName}`);
}
- bundle[entryPointName] = {
- fileName: entryPointName,
+ bundle[jsFile] = {
+ fileName: jsFile,
type: "chunk",
- code: `export * from './${chunk}';`,
+ code: `export * from './${chunk.fileName}';`,
+ };
+ bundle[cssFile] = {
+ fileName: cssFile,
+ type: "asset",
+ source: styles.source,
};
},
};
}
export default defineConfig({
- plugins: [react(), writeEntryPoint("index.js", /^vizarr-/)],
+ plugins: [react(), tailwindcss(), writeEntryPoint("index", /^vizarr-/)],
base: process.env.VIZARR_PREFIX || "./",
publicDir: path.resolve(__dirname, "assets"),
build: {
@@ -36,11 +46,16 @@ export default defineConfig({
output: {
minifyInternalExports: false,
manualChunks: {
- vizarr: [path.resolve(__dirname, "src/index.tsx")],
+ vizarr: [path.resolve(__dirname, "./src/index.tsx")],
},
},
},
},
+ resolve: {
+ alias: {
+ "@": path.resolve(__dirname, "./src"),
+ },
+ },
server: {
open: `?source=${process.env.VIZARR_DATA || "https://uk1s3.embassy.ebi.ac.uk/idr/zarr/v0.1/6001253.zarr"}`,
},