@walkthru-earth/objex 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +396 -0
- package/README.md +114 -0
- package/dist/assets/favicon.svg +17 -0
- package/dist/components/CLAUDE.md +44 -0
- package/dist/components/browser/Breadcrumb.svelte +50 -0
- package/dist/components/browser/Breadcrumb.svelte.d.ts +7 -0
- package/dist/components/browser/CreateFolderDialog.svelte +98 -0
- package/dist/components/browser/CreateFolderDialog.svelte.d.ts +6 -0
- package/dist/components/browser/DeleteConfirmDialog.svelte +90 -0
- package/dist/components/browser/DeleteConfirmDialog.svelte.d.ts +8 -0
- package/dist/components/browser/DropZone.svelte +83 -0
- package/dist/components/browser/DropZone.svelte.d.ts +7 -0
- package/dist/components/browser/FileBrowser.svelte +229 -0
- package/dist/components/browser/FileBrowser.svelte.d.ts +3 -0
- package/dist/components/browser/FileRow.svelte +112 -0
- package/dist/components/browser/FileRow.svelte.d.ts +9 -0
- package/dist/components/browser/FileTreeSidebar.svelte +559 -0
- package/dist/components/browser/FileTreeSidebar.svelte.d.ts +8 -0
- package/dist/components/browser/RenameDialog.svelte +101 -0
- package/dist/components/browser/RenameDialog.svelte.d.ts +8 -0
- package/dist/components/browser/SearchBar.svelte +40 -0
- package/dist/components/browser/SearchBar.svelte.d.ts +6 -0
- package/dist/components/browser/UploadButton.svelte +65 -0
- package/dist/components/browser/UploadButton.svelte.d.ts +3 -0
- package/dist/components/editor/CodeMirrorEditor.svelte +404 -0
- package/dist/components/editor/CodeMirrorEditor.svelte.d.ts +12 -0
- package/dist/components/editor/MilkdownEditor.svelte +98 -0
- package/dist/components/editor/MilkdownEditor.svelte.d.ts +9 -0
- package/dist/components/editor/SqlEditor.svelte +173 -0
- package/dist/components/editor/SqlEditor.svelte.d.ts +7 -0
- package/dist/components/editor/SqlResultBlock.svelte +199 -0
- package/dist/components/editor/SqlResultBlock.svelte.d.ts +9 -0
- package/dist/components/layout/ConnectionDialog.svelte +439 -0
- package/dist/components/layout/ConnectionDialog.svelte.d.ts +9 -0
- package/dist/components/layout/LocaleToggle.svelte +32 -0
- package/dist/components/layout/LocaleToggle.svelte.d.ts +3 -0
- package/dist/components/layout/SafeLockToggle.svelte +37 -0
- package/dist/components/layout/SafeLockToggle.svelte.d.ts +18 -0
- package/dist/components/layout/Sidebar.svelte +314 -0
- package/dist/components/layout/Sidebar.svelte.d.ts +3 -0
- package/dist/components/layout/StatusBar.svelte +73 -0
- package/dist/components/layout/StatusBar.svelte.d.ts +3 -0
- package/dist/components/layout/TabBar.svelte +102 -0
- package/dist/components/layout/TabBar.svelte.d.ts +7 -0
- package/dist/components/layout/ThemeToggle.svelte +52 -0
- package/dist/components/layout/ThemeToggle.svelte.d.ts +3 -0
- package/dist/components/ui/badge/badge.svelte +49 -0
- package/dist/components/ui/badge/badge.svelte.d.ts +32 -0
- package/dist/components/ui/badge/index.d.ts +1 -0
- package/dist/components/ui/badge/index.js +1 -0
- package/dist/components/ui/button/button.svelte +82 -0
- package/dist/components/ui/button/button.svelte.d.ts +64 -0
- package/dist/components/ui/button/index.d.ts +2 -0
- package/dist/components/ui/button/index.js +4 -0
- package/dist/components/ui/context-menu/context-menu-checkbox-item.svelte +40 -0
- package/dist/components/ui/context-menu/context-menu-checkbox-item.svelte.d.ts +9 -0
- package/dist/components/ui/context-menu/context-menu-content.svelte +28 -0
- package/dist/components/ui/context-menu/context-menu-content.svelte.d.ts +10 -0
- package/dist/components/ui/context-menu/context-menu-group-heading.svelte +21 -0
- package/dist/components/ui/context-menu/context-menu-group-heading.svelte.d.ts +7 -0
- package/dist/components/ui/context-menu/context-menu-group.svelte +7 -0
- package/dist/components/ui/context-menu/context-menu-group.svelte.d.ts +4 -0
- package/dist/components/ui/context-menu/context-menu-item.svelte +27 -0
- package/dist/components/ui/context-menu/context-menu-item.svelte.d.ts +8 -0
- package/dist/components/ui/context-menu/context-menu-label.svelte +24 -0
- package/dist/components/ui/context-menu/context-menu-label.svelte.d.ts +8 -0
- package/dist/components/ui/context-menu/context-menu-portal.svelte +7 -0
- package/dist/components/ui/context-menu/context-menu-portal.svelte.d.ts +3 -0
- package/dist/components/ui/context-menu/context-menu-radio-group.svelte +16 -0
- package/dist/components/ui/context-menu/context-menu-radio-group.svelte.d.ts +4 -0
- package/dist/components/ui/context-menu/context-menu-radio-item.svelte +33 -0
- package/dist/components/ui/context-menu/context-menu-radio-item.svelte.d.ts +4 -0
- package/dist/components/ui/context-menu/context-menu-separator.svelte +17 -0
- package/dist/components/ui/context-menu/context-menu-separator.svelte.d.ts +4 -0
- package/dist/components/ui/context-menu/context-menu-shortcut.svelte +20 -0
- package/dist/components/ui/context-menu/context-menu-shortcut.svelte.d.ts +5 -0
- package/dist/components/ui/context-menu/context-menu-sub-content.svelte +20 -0
- package/dist/components/ui/context-menu/context-menu-sub-content.svelte.d.ts +4 -0
- package/dist/components/ui/context-menu/context-menu-sub-trigger.svelte +29 -0
- package/dist/components/ui/context-menu/context-menu-sub-trigger.svelte.d.ts +8 -0
- package/dist/components/ui/context-menu/context-menu-sub.svelte +7 -0
- package/dist/components/ui/context-menu/context-menu-sub.svelte.d.ts +3 -0
- package/dist/components/ui/context-menu/context-menu-trigger.svelte +7 -0
- package/dist/components/ui/context-menu/context-menu-trigger.svelte.d.ts +4 -0
- package/dist/components/ui/context-menu/context-menu.svelte +7 -0
- package/dist/components/ui/context-menu/context-menu.svelte.d.ts +3 -0
- package/dist/components/ui/context-menu/index.d.ts +17 -0
- package/dist/components/ui/context-menu/index.js +19 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte +16 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte.d.ts +4 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte +43 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte.d.ts +9 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-content.svelte +29 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-content.svelte.d.ts +10 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte +22 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte.d.ts +8 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-group.svelte +7 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-group.svelte.d.ts +4 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte +27 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte.d.ts +8 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-label.svelte +24 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-label.svelte.d.ts +8 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-portal.svelte +7 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-portal.svelte.d.ts +3 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte +16 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte.d.ts +4 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte +33 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte.d.ts +4 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-separator.svelte +17 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-separator.svelte.d.ts +4 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte +20 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte.d.ts +5 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte +20 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte.d.ts +4 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte +29 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte.d.ts +7 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-sub.svelte +7 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-sub.svelte.d.ts +3 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-trigger.svelte +7 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-trigger.svelte.d.ts +4 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu.svelte +7 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu.svelte.d.ts +3 -0
- package/dist/components/ui/dropdown-menu/index.d.ts +18 -0
- package/dist/components/ui/dropdown-menu/index.js +18 -0
- package/dist/components/ui/input/index.d.ts +2 -0
- package/dist/components/ui/input/index.js +4 -0
- package/dist/components/ui/input/input.svelte +52 -0
- package/dist/components/ui/input/input.svelte.d.ts +13 -0
- package/dist/components/ui/resizable/index.d.ts +4 -0
- package/dist/components/ui/resizable/index.js +6 -0
- package/dist/components/ui/resizable/resizable-handle.svelte +30 -0
- package/dist/components/ui/resizable/resizable-handle.svelte.d.ts +8 -0
- package/dist/components/ui/resizable/resizable-pane-group.svelte +20 -0
- package/dist/components/ui/resizable/resizable-pane-group.svelte.d.ts +7 -0
- package/dist/components/ui/scroll-area/index.d.ts +3 -0
- package/dist/components/ui/scroll-area/index.js +5 -0
- package/dist/components/ui/scroll-area/scroll-area-scrollbar.svelte +31 -0
- package/dist/components/ui/scroll-area/scroll-area-scrollbar.svelte.d.ts +4 -0
- package/dist/components/ui/scroll-area/scroll-area.svelte +47 -0
- package/dist/components/ui/scroll-area/scroll-area.svelte.d.ts +11 -0
- package/dist/components/ui/separator/index.d.ts +2 -0
- package/dist/components/ui/separator/index.js +4 -0
- package/dist/components/ui/separator/separator.svelte +21 -0
- package/dist/components/ui/separator/separator.svelte.d.ts +4 -0
- package/dist/components/ui/sheet/index.d.ts +11 -0
- package/dist/components/ui/sheet/index.js +13 -0
- package/dist/components/ui/sheet/sheet-close.svelte +7 -0
- package/dist/components/ui/sheet/sheet-close.svelte.d.ts +4 -0
- package/dist/components/ui/sheet/sheet-content.svelte +62 -0
- package/dist/components/ui/sheet/sheet-content.svelte.d.ts +37 -0
- package/dist/components/ui/sheet/sheet-description.svelte +17 -0
- package/dist/components/ui/sheet/sheet-description.svelte.d.ts +4 -0
- package/dist/components/ui/sheet/sheet-footer.svelte +20 -0
- package/dist/components/ui/sheet/sheet-footer.svelte.d.ts +5 -0
- package/dist/components/ui/sheet/sheet-header.svelte +20 -0
- package/dist/components/ui/sheet/sheet-header.svelte.d.ts +5 -0
- package/dist/components/ui/sheet/sheet-overlay.svelte +20 -0
- package/dist/components/ui/sheet/sheet-overlay.svelte.d.ts +4 -0
- package/dist/components/ui/sheet/sheet-portal.svelte +7 -0
- package/dist/components/ui/sheet/sheet-portal.svelte.d.ts +3 -0
- package/dist/components/ui/sheet/sheet-title.svelte +13 -0
- package/dist/components/ui/sheet/sheet-title.svelte.d.ts +4 -0
- package/dist/components/ui/sheet/sheet-trigger.svelte +7 -0
- package/dist/components/ui/sheet/sheet-trigger.svelte.d.ts +4 -0
- package/dist/components/ui/sheet/sheet.svelte +7 -0
- package/dist/components/ui/sheet/sheet.svelte.d.ts +3 -0
- package/dist/components/ui/switch/index.d.ts +2 -0
- package/dist/components/ui/switch/index.js +4 -0
- package/dist/components/ui/switch/switch.svelte +28 -0
- package/dist/components/ui/switch/switch.svelte.d.ts +8 -0
- package/dist/components/ui/tabs/index.d.ts +5 -0
- package/dist/components/ui/tabs/index.js +7 -0
- package/dist/components/ui/tabs/tabs-content.svelte +17 -0
- package/dist/components/ui/tabs/tabs-content.svelte.d.ts +4 -0
- package/dist/components/ui/tabs/tabs-list.svelte +16 -0
- package/dist/components/ui/tabs/tabs-list.svelte.d.ts +4 -0
- package/dist/components/ui/tabs/tabs-trigger.svelte +20 -0
- package/dist/components/ui/tabs/tabs-trigger.svelte.d.ts +4 -0
- package/dist/components/ui/tabs/tabs.svelte +19 -0
- package/dist/components/ui/tabs/tabs.svelte.d.ts +4 -0
- package/dist/components/ui/tooltip/index.d.ts +6 -0
- package/dist/components/ui/tooltip/index.js +8 -0
- package/dist/components/ui/tooltip/tooltip-content.svelte +52 -0
- package/dist/components/ui/tooltip/tooltip-content.svelte.d.ts +11 -0
- package/dist/components/ui/tooltip/tooltip-portal.svelte +7 -0
- package/dist/components/ui/tooltip/tooltip-portal.svelte.d.ts +4 -0
- package/dist/components/ui/tooltip/tooltip-provider.svelte +7 -0
- package/dist/components/ui/tooltip/tooltip-provider.svelte.d.ts +4 -0
- package/dist/components/ui/tooltip/tooltip-trigger.svelte +7 -0
- package/dist/components/ui/tooltip/tooltip-trigger.svelte.d.ts +4 -0
- package/dist/components/ui/tooltip/tooltip.svelte +7 -0
- package/dist/components/ui/tooltip/tooltip.svelte.d.ts +4 -0
- package/dist/components/viewers/ArchiveViewer.svelte +586 -0
- package/dist/components/viewers/ArchiveViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/CLAUDE.md +60 -0
- package/dist/components/viewers/CodeViewer.svelte +553 -0
- package/dist/components/viewers/CodeViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/CogViewer.svelte +1345 -0
- package/dist/components/viewers/CogViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/CopcViewer.svelte +25 -0
- package/dist/components/viewers/CopcViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/DatabaseViewer.svelte +169 -0
- package/dist/components/viewers/DatabaseViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/FileInfo.svelte +174 -0
- package/dist/components/viewers/FileInfo.svelte.d.ts +10 -0
- package/dist/components/viewers/FlatGeobufViewer.svelte +755 -0
- package/dist/components/viewers/FlatGeobufViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/GeoParquetMapViewer.svelte +278 -0
- package/dist/components/viewers/GeoParquetMapViewer.svelte.d.ts +17 -0
- package/dist/components/viewers/ImageViewer.svelte +233 -0
- package/dist/components/viewers/ImageViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/LoadProgress.svelte +93 -0
- package/dist/components/viewers/LoadProgress.svelte.d.ts +15 -0
- package/dist/components/viewers/MapViewer.svelte +234 -0
- package/dist/components/viewers/MapViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/MarkdownViewer.svelte +478 -0
- package/dist/components/viewers/MarkdownViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/MediaViewer.svelte +121 -0
- package/dist/components/viewers/MediaViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/ModelViewer.svelte +164 -0
- package/dist/components/viewers/ModelViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/NotebookViewer.svelte +389 -0
- package/dist/components/viewers/NotebookViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/PdfViewer.svelte +278 -0
- package/dist/components/viewers/PdfViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/PmtilesViewer.svelte +191 -0
- package/dist/components/viewers/PmtilesViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/QueryHistoryPanel.svelte +159 -0
- package/dist/components/viewers/QueryHistoryPanel.svelte.d.ts +8 -0
- package/dist/components/viewers/RawViewer.svelte +117 -0
- package/dist/components/viewers/RawViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/StacMapViewer.svelte +20 -0
- package/dist/components/viewers/StacMapViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/StyleEditorOverlay.svelte +27 -0
- package/dist/components/viewers/StyleEditorOverlay.svelte.d.ts +7 -0
- package/dist/components/viewers/TableGrid.svelte +355 -0
- package/dist/components/viewers/TableGrid.svelte.d.ts +12 -0
- package/dist/components/viewers/TableStatusBar.svelte +92 -0
- package/dist/components/viewers/TableStatusBar.svelte.d.ts +11 -0
- package/dist/components/viewers/TableToolbar.svelte +382 -0
- package/dist/components/viewers/TableToolbar.svelte.d.ts +25 -0
- package/dist/components/viewers/TableViewer.svelte +923 -0
- package/dist/components/viewers/TableViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/ViewerRouter.svelte +70 -0
- package/dist/components/viewers/ViewerRouter.svelte.d.ts +7 -0
- package/dist/components/viewers/ZarrMapViewer.svelte +288 -0
- package/dist/components/viewers/ZarrMapViewer.svelte.d.ts +17 -0
- package/dist/components/viewers/ZarrViewer.svelte +256 -0
- package/dist/components/viewers/ZarrViewer.svelte.d.ts +7 -0
- package/dist/components/viewers/map/AttributeTable.svelte +52 -0
- package/dist/components/viewers/map/AttributeTable.svelte.d.ts +8 -0
- package/dist/components/viewers/map/MapContainer.svelte +158 -0
- package/dist/components/viewers/map/MapContainer.svelte.d.ts +12 -0
- package/dist/components/viewers/pmtiles/PmtilesArchiveView.svelte +389 -0
- package/dist/components/viewers/pmtiles/PmtilesArchiveView.svelte.d.ts +10 -0
- package/dist/components/viewers/pmtiles/PmtilesMapView.svelte +332 -0
- package/dist/components/viewers/pmtiles/PmtilesMapView.svelte.d.ts +11 -0
- package/dist/components/viewers/pmtiles/PmtilesTileInspector.svelte +373 -0
- package/dist/components/viewers/pmtiles/PmtilesTileInspector.svelte.d.ts +12 -0
- package/dist/components/viewers/pmtiles/SvgTileRenderer.svelte +112 -0
- package/dist/components/viewers/pmtiles/SvgTileRenderer.svelte.d.ts +10 -0
- package/dist/file-icons/CLAUDE.md +21 -0
- package/dist/file-icons/FileTypeIcon.svelte +74 -0
- package/dist/file-icons/FileTypeIcon.svelte.d.ts +9 -0
- package/dist/file-icons/index.d.ts +56 -0
- package/dist/file-icons/index.js +1070 -0
- package/dist/i18n/CLAUDE.md +19 -0
- package/dist/i18n/ar.d.ts +1 -0
- package/dist/i18n/ar.js +404 -0
- package/dist/i18n/en.d.ts +1 -0
- package/dist/i18n/en.js +404 -0
- package/dist/i18n/index.svelte.d.ts +9 -0
- package/dist/i18n/index.svelte.js +27 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +13 -0
- package/dist/query/CLAUDE.md +22 -0
- package/dist/query/engine.d.ts +56 -0
- package/dist/query/engine.js +6 -0
- package/dist/query/index.d.ts +4 -0
- package/dist/query/index.js +19 -0
- package/dist/query/wasm.d.ts +20 -0
- package/dist/query/wasm.js +890 -0
- package/dist/storage/CLAUDE.md +23 -0
- package/dist/storage/adapter.d.ts +21 -0
- package/dist/storage/adapter.js +1 -0
- package/dist/storage/browser-azure.d.ts +25 -0
- package/dist/storage/browser-azure.js +271 -0
- package/dist/storage/browser-cloud.d.ts +32 -0
- package/dist/storage/browser-cloud.js +293 -0
- package/dist/storage/index.d.ts +11 -0
- package/dist/storage/index.js +37 -0
- package/dist/storage/url-adapter.d.ts +19 -0
- package/dist/storage/url-adapter.js +51 -0
- package/dist/stores/CLAUDE.md +29 -0
- package/dist/stores/browser.svelte.d.ts +28 -0
- package/dist/stores/browser.svelte.js +160 -0
- package/dist/stores/connections.svelte.d.ts +56 -0
- package/dist/stores/connections.svelte.js +272 -0
- package/dist/stores/credentials.svelte.d.ts +56 -0
- package/dist/stores/credentials.svelte.js +79 -0
- package/dist/stores/files.svelte.d.ts +20 -0
- package/dist/stores/files.svelte.js +76 -0
- package/dist/stores/query-history.svelte.d.ts +16 -0
- package/dist/stores/query-history.svelte.js +57 -0
- package/dist/stores/safelock.svelte.d.ts +8 -0
- package/dist/stores/safelock.svelte.js +52 -0
- package/dist/stores/settings.svelte.d.ts +11 -0
- package/dist/stores/settings.svelte.js +101 -0
- package/dist/stores/tab-resources.svelte.d.ts +25 -0
- package/dist/stores/tab-resources.svelte.js +61 -0
- package/dist/stores/tabs.svelte.d.ts +17 -0
- package/dist/stores/tabs.svelte.js +110 -0
- package/dist/types/notebookjs.d.ts +14 -0
- package/dist/types.d.ts +47 -0
- package/dist/types.js +1 -0
- package/dist/utils/CLAUDE.md +54 -0
- package/dist/utils/analytics.d.ts +10 -0
- package/dist/utils/analytics.js +38 -0
- package/dist/utils/archive.d.ts +70 -0
- package/dist/utils/archive.js +333 -0
- package/dist/utils/column-types.d.ts +5 -0
- package/dist/utils/column-types.js +137 -0
- package/dist/utils/deck.d.ts +98 -0
- package/dist/utils/deck.js +208 -0
- package/dist/utils/evidence-context.d.ts +22 -0
- package/dist/utils/evidence-context.js +56 -0
- package/dist/utils/export.d.ts +2 -0
- package/dist/utils/export.js +51 -0
- package/dist/utils/format.d.ts +14 -0
- package/dist/utils/format.js +56 -0
- package/dist/utils/geoarrow.d.ts +32 -0
- package/dist/utils/geoarrow.js +672 -0
- package/dist/utils/hex.d.ts +10 -0
- package/dist/utils/hex.js +27 -0
- package/dist/utils/host-detection.d.ts +23 -0
- package/dist/utils/host-detection.js +289 -0
- package/dist/utils/map-selection.d.ts +12 -0
- package/dist/utils/map-selection.js +45 -0
- package/dist/utils/markdown-sql.d.ts +30 -0
- package/dist/utils/markdown-sql.js +73 -0
- package/dist/utils/markdown.d.ts +18 -0
- package/dist/utils/markdown.js +146 -0
- package/dist/utils/model3d.d.ts +13 -0
- package/dist/utils/model3d.js +62 -0
- package/dist/utils/parquet-metadata.d.ts +58 -0
- package/dist/utils/parquet-metadata.js +228 -0
- package/dist/utils/pdf.d.ts +8 -0
- package/dist/utils/pdf.js +28 -0
- package/dist/utils/pmtiles-tile.d.ts +38 -0
- package/dist/utils/pmtiles-tile.js +64 -0
- package/dist/utils/pmtiles.d.ts +46 -0
- package/dist/utils/pmtiles.js +135 -0
- package/dist/utils/shiki.d.ts +8 -0
- package/dist/utils/shiki.js +98 -0
- package/dist/utils/storage-url.d.ts +64 -0
- package/dist/utils/storage-url.js +374 -0
- package/dist/utils/url-state.d.ts +40 -0
- package/dist/utils/url-state.js +113 -0
- package/dist/utils/url.d.ts +27 -0
- package/dist/utils/url.js +115 -0
- package/dist/utils/wkb.d.ts +43 -0
- package/dist/utils/wkb.js +345 -0
- package/dist/utils/zarr.d.ts +39 -0
- package/dist/utils/zarr.js +204 -0
- package/dist/utils.d.ts +12 -0
- package/dist/utils.js +5 -0
- package/package.json +203 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { getViewerKind } from '../../file-icons/index.js';
|
|
3
|
+
import type { Tab } from '../../types';
|
|
4
|
+
import CodeViewer from './CodeViewer.svelte';
|
|
5
|
+
import ImageViewer from './ImageViewer.svelte';
|
|
6
|
+
import MediaViewer from './MediaViewer.svelte';
|
|
7
|
+
import RawViewer from './RawViewer.svelte';
|
|
8
|
+
import TableViewer from './TableViewer.svelte';
|
|
9
|
+
|
|
10
|
+
let { tab }: { tab: Tab } = $props();
|
|
11
|
+
|
|
12
|
+
const ext = $derived(tab?.extension ?? '');
|
|
13
|
+
const viewerKind = $derived(getViewerKind(ext));
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
{#if viewerKind === 'table'}
|
|
17
|
+
<TableViewer {tab} />
|
|
18
|
+
{:else if viewerKind === 'image'}
|
|
19
|
+
<ImageViewer {tab} />
|
|
20
|
+
{:else if viewerKind === 'video' || viewerKind === 'audio'}
|
|
21
|
+
<MediaViewer {tab} />
|
|
22
|
+
{:else if viewerKind === 'markdown'}
|
|
23
|
+
{#await import('./MarkdownViewer.svelte') then { default: MarkdownViewer }}
|
|
24
|
+
<MarkdownViewer {tab} />
|
|
25
|
+
{/await}
|
|
26
|
+
{:else if viewerKind === 'code'}
|
|
27
|
+
<CodeViewer {tab} />
|
|
28
|
+
{:else if viewerKind === 'cog'}
|
|
29
|
+
{#await import('./CogViewer.svelte') then { default: CogViewer }}
|
|
30
|
+
<CogViewer {tab} />
|
|
31
|
+
{/await}
|
|
32
|
+
{:else if viewerKind === 'pmtiles'}
|
|
33
|
+
{#await import('./PmtilesViewer.svelte') then { default: PmtilesViewer }}
|
|
34
|
+
<PmtilesViewer {tab} />
|
|
35
|
+
{/await}
|
|
36
|
+
{:else if viewerKind === 'flatgeobuf'}
|
|
37
|
+
{#await import('./FlatGeobufViewer.svelte') then { default: FlatGeobufViewer }}
|
|
38
|
+
<FlatGeobufViewer {tab} />
|
|
39
|
+
{/await}
|
|
40
|
+
{:else if viewerKind === 'pdf'}
|
|
41
|
+
{#await import('./PdfViewer.svelte') then { default: PdfViewer }}
|
|
42
|
+
<PdfViewer {tab} />
|
|
43
|
+
{/await}
|
|
44
|
+
{:else if viewerKind === '3d'}
|
|
45
|
+
{#await import('./ModelViewer.svelte') then { default: ModelViewer }}
|
|
46
|
+
<ModelViewer {tab} />
|
|
47
|
+
{/await}
|
|
48
|
+
{:else if viewerKind === 'archive'}
|
|
49
|
+
{#await import('./ArchiveViewer.svelte') then { default: ArchiveViewer }}
|
|
50
|
+
<ArchiveViewer {tab} />
|
|
51
|
+
{/await}
|
|
52
|
+
{:else if viewerKind === 'database'}
|
|
53
|
+
{#await import('./DatabaseViewer.svelte') then { default: DatabaseViewer }}
|
|
54
|
+
<DatabaseViewer {tab} />
|
|
55
|
+
{/await}
|
|
56
|
+
{:else if viewerKind === 'zarr'}
|
|
57
|
+
{#await import('./ZarrViewer.svelte') then { default: ZarrViewer }}
|
|
58
|
+
<ZarrViewer {tab} />
|
|
59
|
+
{/await}
|
|
60
|
+
{:else if viewerKind === 'copc'}
|
|
61
|
+
{#await import('./CopcViewer.svelte') then { default: CopcViewer }}
|
|
62
|
+
<CopcViewer {tab} />
|
|
63
|
+
{/await}
|
|
64
|
+
{:else if viewerKind === 'notebook'}
|
|
65
|
+
{#await import('./NotebookViewer.svelte') then { default: NotebookViewer }}
|
|
66
|
+
<NotebookViewer {tab} />
|
|
67
|
+
{/await}
|
|
68
|
+
{:else}
|
|
69
|
+
<RawViewer {tab} />
|
|
70
|
+
{/if}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type maplibregl from 'maplibre-gl';
|
|
3
|
+
import { onDestroy, untrack } from 'svelte';
|
|
4
|
+
import { t } from '../../i18n/index.svelte.js';
|
|
5
|
+
import { tabResources } from '../../stores/tab-resources.svelte.js';
|
|
6
|
+
import type { Tab } from '../../types';
|
|
7
|
+
import { buildHttpsUrl } from '../../utils/url.js';
|
|
8
|
+
import MapContainer from './map/MapContainer.svelte';
|
|
9
|
+
|
|
10
|
+
interface ZarrVarMeta {
|
|
11
|
+
name: string;
|
|
12
|
+
shape: number[];
|
|
13
|
+
dtype: string;
|
|
14
|
+
dims: string[];
|
|
15
|
+
attributes: Record<string, any>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let {
|
|
19
|
+
tab,
|
|
20
|
+
variables,
|
|
21
|
+
spatialRefAttrs,
|
|
22
|
+
zarrVersion = null
|
|
23
|
+
}: {
|
|
24
|
+
tab: Tab;
|
|
25
|
+
variables: ZarrVarMeta[];
|
|
26
|
+
spatialRefAttrs: Record<string, any> | null;
|
|
27
|
+
zarrVersion?: number | null;
|
|
28
|
+
} = $props();
|
|
29
|
+
|
|
30
|
+
let loading = $state(true);
|
|
31
|
+
let error = $state<string | null>(null);
|
|
32
|
+
let selectedVar = $state('');
|
|
33
|
+
let zarrLayer: any = null;
|
|
34
|
+
let mapRef: maplibregl.Map | null = null;
|
|
35
|
+
|
|
36
|
+
// Extract proj4 from spatial_ref if available
|
|
37
|
+
const proj4String = $derived(extractProj4(spatialRefAttrs));
|
|
38
|
+
|
|
39
|
+
// Initialize selectedVar from variables prop
|
|
40
|
+
$effect(() => {
|
|
41
|
+
if (!selectedVar && variables.length > 0) {
|
|
42
|
+
selectedVar = variables[0].name;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Identify non-spatial selector dimensions for the selected variable
|
|
47
|
+
const selectedMeta = $derived(variables.find((v) => v.name === selectedVar));
|
|
48
|
+
const selectorDims = $derived(getSelectorDims(selectedMeta));
|
|
49
|
+
|
|
50
|
+
// Dimension slider state
|
|
51
|
+
let selectorValues = $state<Record<string, number>>({});
|
|
52
|
+
|
|
53
|
+
// Default colormap (viridis-ish)
|
|
54
|
+
const colormap = [
|
|
55
|
+
[68, 1, 84],
|
|
56
|
+
[72, 35, 116],
|
|
57
|
+
[64, 67, 135],
|
|
58
|
+
[52, 94, 141],
|
|
59
|
+
[33, 145, 140],
|
|
60
|
+
[94, 201, 98],
|
|
61
|
+
[253, 231, 37]
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
function extractProj4(attrs: Record<string, any> | null): string | null {
|
|
65
|
+
if (!attrs) return null;
|
|
66
|
+
// Try common attribute names for proj4 strings
|
|
67
|
+
return (
|
|
68
|
+
attrs.proj4_params ||
|
|
69
|
+
attrs.proj4text ||
|
|
70
|
+
attrs.proj4 ||
|
|
71
|
+
buildProj4FromCrsWkt(attrs.crs_wkt) ||
|
|
72
|
+
null
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Try to build a proj4 string from crs_wkt for Lambert Conformal Conic */
|
|
77
|
+
function buildProj4FromCrsWkt(crsWkt: string | undefined): string | null {
|
|
78
|
+
if (!crsWkt) return null;
|
|
79
|
+
try {
|
|
80
|
+
const lcc = crsWkt.includes('Lambert_Conformal_Conic');
|
|
81
|
+
if (!lcc) return null;
|
|
82
|
+
|
|
83
|
+
const getParam = (name: string) => {
|
|
84
|
+
const m = crsWkt.match(new RegExp(`PARAMETER\\["${name}",([^\\]]+)\\]`));
|
|
85
|
+
return m ? parseFloat(m[1]) : null;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const lat0 = getParam('latitude_of_origin');
|
|
89
|
+
const lon0 = getParam('central_meridian');
|
|
90
|
+
const lat1 = getParam('standard_parallel_1');
|
|
91
|
+
const lat2 = getParam('standard_parallel_2');
|
|
92
|
+
const x0 = getParam('false_easting') ?? 0;
|
|
93
|
+
const y0 = getParam('false_northing') ?? 0;
|
|
94
|
+
|
|
95
|
+
// Extract sphere radius
|
|
96
|
+
const sphereMatch = crsWkt.match(/SPHEROID\["[^"]*",([^,]+)/);
|
|
97
|
+
const R = sphereMatch ? parseFloat(sphereMatch[1]) : 6371229;
|
|
98
|
+
|
|
99
|
+
if (lat0 == null || lon0 == null || lat1 == null || lat2 == null) return null;
|
|
100
|
+
|
|
101
|
+
return `+proj=lcc +lat_1=${lat1} +lat_2=${lat2} +lat_0=${lat0} +lon_0=${lon0} +x_0=${x0} +y_0=${y0} +R=${R} +units=m +no_defs`;
|
|
102
|
+
} catch {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function getSelectorDims(meta: ZarrVarMeta | undefined): { name: string; size: number }[] {
|
|
108
|
+
if (!meta) return [];
|
|
109
|
+
const spatialNames = ['x', 'y', 'lat', 'lon', 'latitude', 'longitude'];
|
|
110
|
+
const dims: { name: string; size: number }[] = [];
|
|
111
|
+
for (let i = 0; i < meta.dims.length; i++) {
|
|
112
|
+
const d = meta.dims[i];
|
|
113
|
+
if (!spatialNames.includes(d.toLowerCase())) {
|
|
114
|
+
dims.push({ name: d, size: meta.shape[i] });
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return dims;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Initialize selector values when variable changes
|
|
121
|
+
$effect(() => {
|
|
122
|
+
const dims = selectorDims;
|
|
123
|
+
const prev = untrack(() => selectorValues);
|
|
124
|
+
const newVals: Record<string, number> = {};
|
|
125
|
+
for (const d of dims) {
|
|
126
|
+
newVals[d.name] = prev[d.name] ?? 0;
|
|
127
|
+
}
|
|
128
|
+
selectorValues = newVals;
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
async function onMapReady(map: maplibregl.Map) {
|
|
132
|
+
mapRef = map;
|
|
133
|
+
await addZarrLayer(map);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async function addZarrLayer(map: maplibregl.Map) {
|
|
137
|
+
loading = true;
|
|
138
|
+
error = null;
|
|
139
|
+
|
|
140
|
+
try {
|
|
141
|
+
// Remove existing layer
|
|
142
|
+
if (zarrLayer && map.getLayer(zarrLayer.id)) {
|
|
143
|
+
map.removeLayer(zarrLayer.id);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const { ZarrLayer } = await import('@carbonplan/zarr-layer');
|
|
147
|
+
|
|
148
|
+
const storeUrl = buildStoreUrl();
|
|
149
|
+
const selector: Record<string, any> = {};
|
|
150
|
+
for (const [dim, val] of Object.entries(selectorValues)) {
|
|
151
|
+
selector[dim] = { selected: val, type: 'index' };
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const opts: any = {
|
|
155
|
+
id: 'zarr-data',
|
|
156
|
+
source: storeUrl,
|
|
157
|
+
variable: selectedVar,
|
|
158
|
+
colormap,
|
|
159
|
+
clim: [0, 1], // placeholder — adjusted after loading
|
|
160
|
+
opacity: 0.85,
|
|
161
|
+
selector,
|
|
162
|
+
version: zarrVersion,
|
|
163
|
+
onLoadingStateChange: (state: any) => {
|
|
164
|
+
if (state.error) {
|
|
165
|
+
error = state.error.message;
|
|
166
|
+
}
|
|
167
|
+
loading = state.loading;
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
// Add projection info if available
|
|
172
|
+
if (proj4String) {
|
|
173
|
+
opts.proj4 = proj4String;
|
|
174
|
+
opts.spatialDimensions = { lat: 'y', lon: 'x' };
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
zarrLayer = new ZarrLayer(opts);
|
|
178
|
+
map.addLayer(zarrLayer);
|
|
179
|
+
} catch (err) {
|
|
180
|
+
error = err instanceof Error ? err.message : String(err);
|
|
181
|
+
loading = false;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function buildStoreUrl(): string {
|
|
186
|
+
const url = buildHttpsUrl(tab);
|
|
187
|
+
// Strip zarr.json suffix and trailing slashes
|
|
188
|
+
return url.replace(/\/zarr\.json$/, '').replace(/\/+$/, '');
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Re-render when selector changes
|
|
192
|
+
async function updateSelector() {
|
|
193
|
+
if (!zarrLayer) return;
|
|
194
|
+
const selector: Record<string, any> = {};
|
|
195
|
+
for (const [dim, val] of Object.entries(selectorValues)) {
|
|
196
|
+
selector[dim] = { selected: val, type: 'index' };
|
|
197
|
+
}
|
|
198
|
+
try {
|
|
199
|
+
await zarrLayer.setSelector(selector);
|
|
200
|
+
} catch (err) {
|
|
201
|
+
error = err instanceof Error ? err.message : String(err);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Re-render when variable changes
|
|
206
|
+
async function changeVariable() {
|
|
207
|
+
if (!mapRef) return;
|
|
208
|
+
await addZarrLayer(mapRef);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function cleanup() {
|
|
212
|
+
try {
|
|
213
|
+
if (zarrLayer && mapRef?.getLayer('zarr-data')) {
|
|
214
|
+
mapRef.removeLayer('zarr-data');
|
|
215
|
+
}
|
|
216
|
+
} catch {
|
|
217
|
+
// map may already be destroyed
|
|
218
|
+
}
|
|
219
|
+
zarrLayer = null;
|
|
220
|
+
mapRef = null;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
$effect(() => {
|
|
224
|
+
const id = tab.id;
|
|
225
|
+
const unregister = tabResources.register(id, cleanup);
|
|
226
|
+
return unregister;
|
|
227
|
+
});
|
|
228
|
+
onDestroy(cleanup);
|
|
229
|
+
</script>
|
|
230
|
+
|
|
231
|
+
<div class="flex h-full w-full flex-col overflow-hidden">
|
|
232
|
+
<!-- Controls bar -->
|
|
233
|
+
<div
|
|
234
|
+
class="flex items-center gap-2 border-b border-zinc-200 px-3 py-1.5 dark:border-zinc-800"
|
|
235
|
+
>
|
|
236
|
+
<label class="flex items-center gap-1 text-xs text-zinc-400">
|
|
237
|
+
{t('map.variable')}
|
|
238
|
+
<select
|
|
239
|
+
class="rounded border border-zinc-300 bg-white px-1.5 py-0.5 text-xs text-zinc-700 dark:border-zinc-700 dark:bg-zinc-900 dark:text-zinc-300"
|
|
240
|
+
bind:value={selectedVar}
|
|
241
|
+
onchange={changeVariable}
|
|
242
|
+
>
|
|
243
|
+
{#each variables as v}
|
|
244
|
+
<option value={v.name}>{v.name}</option>
|
|
245
|
+
{/each}
|
|
246
|
+
</select>
|
|
247
|
+
</label>
|
|
248
|
+
|
|
249
|
+
{#each selectorDims as dim}
|
|
250
|
+
<label class="flex items-center gap-1 text-xs text-zinc-400">
|
|
251
|
+
{dim.name}:
|
|
252
|
+
<input
|
|
253
|
+
type="range"
|
|
254
|
+
min="0"
|
|
255
|
+
max={dim.size - 1}
|
|
256
|
+
bind:value={selectorValues[dim.name]}
|
|
257
|
+
onchange={updateSelector}
|
|
258
|
+
class="h-1 w-16"
|
|
259
|
+
/>
|
|
260
|
+
<span class="w-6 text-end text-zinc-500">{selectorValues[dim.name] ?? 0}</span>
|
|
261
|
+
</label>
|
|
262
|
+
{/each}
|
|
263
|
+
|
|
264
|
+
{#if selectedMeta}
|
|
265
|
+
<span class="ms-auto text-xs text-zinc-400">
|
|
266
|
+
{selectedMeta.dtype} [{selectedMeta.shape.join(', ')}]
|
|
267
|
+
</span>
|
|
268
|
+
{/if}
|
|
269
|
+
</div>
|
|
270
|
+
|
|
271
|
+
<!-- Map -->
|
|
272
|
+
<div class="relative min-h-0 flex-1">
|
|
273
|
+
{#if error && !loading}
|
|
274
|
+
<div class="flex h-full items-center justify-center">
|
|
275
|
+
<p class="max-w-md text-center text-sm text-red-400">{error}</p>
|
|
276
|
+
</div>
|
|
277
|
+
{:else}
|
|
278
|
+
<MapContainer {onMapReady} bounds={[-130, 20, -60, 55]} />
|
|
279
|
+
{#if loading}
|
|
280
|
+
<div
|
|
281
|
+
class="pointer-events-none absolute left-2 top-2 z-10 rounded bg-card/80 px-2 py-1 text-xs text-card-foreground backdrop-blur-sm"
|
|
282
|
+
>
|
|
283
|
+
{t('map.loadingZarr')}
|
|
284
|
+
</div>
|
|
285
|
+
{/if}
|
|
286
|
+
{/if}
|
|
287
|
+
</div>
|
|
288
|
+
</div>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Tab } from '../../types';
|
|
2
|
+
interface ZarrVarMeta {
|
|
3
|
+
name: string;
|
|
4
|
+
shape: number[];
|
|
5
|
+
dtype: string;
|
|
6
|
+
dims: string[];
|
|
7
|
+
attributes: Record<string, any>;
|
|
8
|
+
}
|
|
9
|
+
type $$ComponentProps = {
|
|
10
|
+
tab: Tab;
|
|
11
|
+
variables: ZarrVarMeta[];
|
|
12
|
+
spatialRefAttrs: Record<string, any> | null;
|
|
13
|
+
zarrVersion?: number | null;
|
|
14
|
+
};
|
|
15
|
+
declare const ZarrMapViewer: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
16
|
+
type ZarrMapViewer = ReturnType<typeof ZarrMapViewer>;
|
|
17
|
+
export default ZarrMapViewer;
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { untrack } from 'svelte';
|
|
3
|
+
import { Badge } from '../ui/badge/index.js';
|
|
4
|
+
import { Button } from '../ui/button/index.js';
|
|
5
|
+
import { t } from '../../i18n/index.svelte.js';
|
|
6
|
+
import type { Tab } from '../../types';
|
|
7
|
+
import { buildHttpsUrl } from '../../utils/url.js';
|
|
8
|
+
import { getUrlView, updateUrlView } from '../../utils/url-state.js';
|
|
9
|
+
import {
|
|
10
|
+
fetchConsolidated,
|
|
11
|
+
formatShape,
|
|
12
|
+
probeWithZarrita,
|
|
13
|
+
type VarMeta,
|
|
14
|
+
type ZarrMetadata
|
|
15
|
+
} from '../../utils/zarr.js';
|
|
16
|
+
|
|
17
|
+
let { tab }: { tab: Tab } = $props();
|
|
18
|
+
|
|
19
|
+
let loading = $state(true);
|
|
20
|
+
let error = $state<string | null>(null);
|
|
21
|
+
const urlView = getUrlView();
|
|
22
|
+
let viewMode = $state<'inspect' | 'map'>(urlView === 'map' ? 'map' : 'inspect');
|
|
23
|
+
|
|
24
|
+
let storeAttrs = $state<Record<string, any>>({});
|
|
25
|
+
let variables = $state<VarMeta[]>([]);
|
|
26
|
+
let coordVars = $state<VarMeta[]>([]);
|
|
27
|
+
let spatialRefAttrs = $state<Record<string, any> | null>(null);
|
|
28
|
+
let selectedNode = $state<VarMeta | null>(null);
|
|
29
|
+
let zarrVersion = $state<number | null>(null);
|
|
30
|
+
|
|
31
|
+
const mapVars = $derived(variables.filter((v) => v.shape.length >= 2));
|
|
32
|
+
const hasMapVars = $derived(mapVars.length > 0);
|
|
33
|
+
|
|
34
|
+
// Reset view mode when tab changes (component reuse across zarr-type tabs)
|
|
35
|
+
let prevTabId = '';
|
|
36
|
+
$effect(() => {
|
|
37
|
+
const id = tab.id;
|
|
38
|
+
if (prevTabId && prevTabId !== id) {
|
|
39
|
+
viewMode = 'inspect';
|
|
40
|
+
updateUrlView('');
|
|
41
|
+
}
|
|
42
|
+
prevTabId = id;
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
$effect(() => {
|
|
46
|
+
if (!tab) return;
|
|
47
|
+
const _tabId = tab.id;
|
|
48
|
+
untrack(() => {
|
|
49
|
+
loadZarrMetadata();
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
function setViewMode(mode: 'inspect' | 'map') {
|
|
54
|
+
viewMode = mode;
|
|
55
|
+
updateUrlView(viewMode);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function loadZarrMetadata() {
|
|
59
|
+
loading = true;
|
|
60
|
+
error = null;
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
const url = buildHttpsUrl(tab)
|
|
64
|
+
.replace(/\/zarr\.json$/, '')
|
|
65
|
+
.replace(/\/+$/, '');
|
|
66
|
+
|
|
67
|
+
let meta: ZarrMetadata | null = await fetchConsolidated(url);
|
|
68
|
+
|
|
69
|
+
if (!meta) {
|
|
70
|
+
meta = await probeWithZarrita(url, tab.name.replace(/\.(zarr|zr3)$/, ''));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (meta) {
|
|
74
|
+
storeAttrs = meta.storeAttrs;
|
|
75
|
+
variables = meta.variables;
|
|
76
|
+
coordVars = meta.coords;
|
|
77
|
+
spatialRefAttrs = meta.spatialRefAttrs;
|
|
78
|
+
zarrVersion = meta.zarrVersion;
|
|
79
|
+
}
|
|
80
|
+
} catch (err) {
|
|
81
|
+
error = err instanceof Error ? err.message : String(err);
|
|
82
|
+
} finally {
|
|
83
|
+
loading = false;
|
|
84
|
+
updateUrlView(viewMode);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
</script>
|
|
88
|
+
|
|
89
|
+
<div class="flex h-full flex-col">
|
|
90
|
+
<!-- Toolbar -->
|
|
91
|
+
<div
|
|
92
|
+
class="flex items-center gap-1 border-b border-zinc-200 px-2 py-1.5 sm:gap-2 sm:px-4 dark:border-zinc-800"
|
|
93
|
+
>
|
|
94
|
+
<span class="truncate max-w-[120px] text-sm font-medium text-zinc-700 sm:max-w-none dark:text-zinc-300">{tab.name}</span>
|
|
95
|
+
<Badge variant="secondary" class="bg-purple-100 text-purple-600 dark:bg-purple-900 dark:text-purple-300">{t('zarr.badge')}</Badge>
|
|
96
|
+
|
|
97
|
+
{#if variables.length > 0}
|
|
98
|
+
<span class="hidden text-xs text-zinc-400 sm:inline">{variables.length} {t('zarr.variables')}</span>
|
|
99
|
+
{/if}
|
|
100
|
+
|
|
101
|
+
<div class="ms-auto flex items-center gap-1">
|
|
102
|
+
<Button
|
|
103
|
+
variant={viewMode === 'inspect' ? 'secondary' : 'ghost'}
|
|
104
|
+
size="sm"
|
|
105
|
+
class="h-7 px-2 text-xs"
|
|
106
|
+
onclick={() => setViewMode('inspect')}
|
|
107
|
+
>
|
|
108
|
+
{t('zarr.inspect')}
|
|
109
|
+
</Button>
|
|
110
|
+
{#if hasMapVars}
|
|
111
|
+
<Button
|
|
112
|
+
variant={viewMode === 'map' ? 'secondary' : 'ghost'}
|
|
113
|
+
size="sm"
|
|
114
|
+
class="h-7 px-2 text-xs"
|
|
115
|
+
onclick={() => setViewMode('map')}
|
|
116
|
+
>
|
|
117
|
+
{t('zarr.map')}
|
|
118
|
+
</Button>
|
|
119
|
+
{/if}
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
|
|
123
|
+
<!-- Content -->
|
|
124
|
+
<div class="flex min-h-0 flex-1 overflow-hidden">
|
|
125
|
+
{#if loading}
|
|
126
|
+
<div class="flex flex-1 items-center justify-center">
|
|
127
|
+
<p class="text-sm text-zinc-400">{t('zarr.loading')}</p>
|
|
128
|
+
</div>
|
|
129
|
+
{:else if error}
|
|
130
|
+
<div class="flex flex-1 items-center justify-center">
|
|
131
|
+
<p class="max-w-md text-center text-sm text-red-400">{error}</p>
|
|
132
|
+
</div>
|
|
133
|
+
{:else if viewMode === 'map' && hasMapVars}
|
|
134
|
+
{#key viewMode}
|
|
135
|
+
{#await import('./ZarrMapViewer.svelte') then ZarrMapViewer}
|
|
136
|
+
<ZarrMapViewer.default {tab} variables={mapVars} {spatialRefAttrs} {zarrVersion} />
|
|
137
|
+
{/await}
|
|
138
|
+
{/key}
|
|
139
|
+
{:else}
|
|
140
|
+
<!-- Inspect mode -->
|
|
141
|
+
<div class="flex flex-1 overflow-hidden">
|
|
142
|
+
<!-- Variable list sidebar -->
|
|
143
|
+
<div
|
|
144
|
+
class="w-64 shrink-0 overflow-auto border-e border-zinc-200 bg-zinc-50 dark:border-zinc-800 dark:bg-zinc-900"
|
|
145
|
+
>
|
|
146
|
+
{#if Object.keys(storeAttrs).length > 0}
|
|
147
|
+
<div class="border-b border-zinc-200 px-3 py-2 dark:border-zinc-800">
|
|
148
|
+
<button
|
|
149
|
+
class="w-full text-start text-xs font-medium text-zinc-500 hover:text-zinc-700 dark:text-zinc-400 dark:hover:text-zinc-200"
|
|
150
|
+
onclick={() => (selectedNode = null)}
|
|
151
|
+
>
|
|
152
|
+
Store Attributes
|
|
153
|
+
</button>
|
|
154
|
+
</div>
|
|
155
|
+
{/if}
|
|
156
|
+
|
|
157
|
+
{#if variables.length > 0}
|
|
158
|
+
<div class="border-b border-zinc-200 px-3 py-2 dark:border-zinc-800">
|
|
159
|
+
<h3 class="text-xs font-medium text-zinc-400">Data Variables ({variables.length})</h3>
|
|
160
|
+
</div>
|
|
161
|
+
{#each variables as v}
|
|
162
|
+
<button
|
|
163
|
+
class="flex w-full items-center gap-2 px-3 py-1.5 text-start text-xs hover:bg-zinc-100 dark:hover:bg-zinc-800"
|
|
164
|
+
class:bg-blue-50={selectedNode?.name === v.name}
|
|
165
|
+
class:dark:bg-blue-950={selectedNode?.name === v.name}
|
|
166
|
+
onclick={() => (selectedNode = v)}
|
|
167
|
+
>
|
|
168
|
+
<span class="font-medium text-zinc-700 dark:text-zinc-300">{v.name}</span>
|
|
169
|
+
<span class="ms-auto text-zinc-400">{v.dtype}</span>
|
|
170
|
+
</button>
|
|
171
|
+
{/each}
|
|
172
|
+
{/if}
|
|
173
|
+
|
|
174
|
+
{#if coordVars.length > 0}
|
|
175
|
+
<div class="border-b border-zinc-200 px-3 py-2 dark:border-zinc-800">
|
|
176
|
+
<h3 class="text-xs font-medium text-zinc-400">Coordinates ({coordVars.length})</h3>
|
|
177
|
+
</div>
|
|
178
|
+
{#each coordVars as v}
|
|
179
|
+
<button
|
|
180
|
+
class="flex w-full items-center gap-2 px-3 py-1.5 text-start text-xs hover:bg-zinc-100 dark:hover:bg-zinc-800"
|
|
181
|
+
class:bg-blue-50={selectedNode?.name === v.name}
|
|
182
|
+
class:dark:bg-blue-950={selectedNode?.name === v.name}
|
|
183
|
+
onclick={() => (selectedNode = v)}
|
|
184
|
+
>
|
|
185
|
+
<span class="text-zinc-500 dark:text-zinc-400">{v.name}</span>
|
|
186
|
+
<span class="ms-auto text-zinc-400">{v.dtype}</span>
|
|
187
|
+
</button>
|
|
188
|
+
{/each}
|
|
189
|
+
{/if}
|
|
190
|
+
</div>
|
|
191
|
+
|
|
192
|
+
<!-- Detail panel -->
|
|
193
|
+
<div class="flex-1 overflow-auto p-4">
|
|
194
|
+
{#if selectedNode}
|
|
195
|
+
<h2 class="mb-3 text-sm font-semibold text-zinc-700 dark:text-zinc-200">
|
|
196
|
+
{selectedNode.name}
|
|
197
|
+
</h2>
|
|
198
|
+
<dl class="space-y-2 text-xs">
|
|
199
|
+
<dt class="font-medium text-zinc-500 dark:text-zinc-400">Shape</dt>
|
|
200
|
+
<dd class="font-mono text-zinc-700 dark:text-zinc-300">{formatShape(selectedNode.shape)}</dd>
|
|
201
|
+
|
|
202
|
+
{#if selectedNode.dims.length > 0}
|
|
203
|
+
<dt class="font-medium text-zinc-500 dark:text-zinc-400">Dimensions</dt>
|
|
204
|
+
<dd class="font-mono text-zinc-700 dark:text-zinc-300">
|
|
205
|
+
({selectedNode.dims.join(', ')})
|
|
206
|
+
</dd>
|
|
207
|
+
{/if}
|
|
208
|
+
|
|
209
|
+
<dt class="font-medium text-zinc-500 dark:text-zinc-400">Data Type</dt>
|
|
210
|
+
<dd class="font-mono text-zinc-700 dark:text-zinc-300">{selectedNode.dtype}</dd>
|
|
211
|
+
|
|
212
|
+
{#if selectedNode.chunks.length > 0}
|
|
213
|
+
<dt class="font-medium text-zinc-500 dark:text-zinc-400">Chunks</dt>
|
|
214
|
+
<dd class="font-mono text-zinc-700 dark:text-zinc-300">[{selectedNode.chunks.join(', ')}]</dd>
|
|
215
|
+
{/if}
|
|
216
|
+
|
|
217
|
+
{#if Object.keys(selectedNode.attributes).length > 0}
|
|
218
|
+
<dt class="mt-3 font-medium text-zinc-500 dark:text-zinc-400">Attributes</dt>
|
|
219
|
+
<dd>
|
|
220
|
+
<div class="mt-1 rounded border border-zinc-200 bg-zinc-100 p-2 dark:border-zinc-700 dark:bg-zinc-800">
|
|
221
|
+
{#each Object.entries(selectedNode.attributes) as [key, value]}
|
|
222
|
+
<div class="flex gap-2 py-0.5">
|
|
223
|
+
<span class="shrink-0 font-medium text-zinc-500 dark:text-zinc-400">{key}:</span>
|
|
224
|
+
<span class="break-all text-zinc-700 dark:text-zinc-300">
|
|
225
|
+
{typeof value === 'string' ? value : JSON.stringify(value)}
|
|
226
|
+
</span>
|
|
227
|
+
</div>
|
|
228
|
+
{/each}
|
|
229
|
+
</div>
|
|
230
|
+
</dd>
|
|
231
|
+
{/if}
|
|
232
|
+
</dl>
|
|
233
|
+
{:else if Object.keys(storeAttrs).length > 0}
|
|
234
|
+
<h2 class="mb-3 text-sm font-semibold text-zinc-700 dark:text-zinc-200">
|
|
235
|
+
Store Attributes
|
|
236
|
+
</h2>
|
|
237
|
+
<div class="rounded border border-zinc-200 bg-zinc-100 p-2 text-xs dark:border-zinc-700 dark:bg-zinc-800">
|
|
238
|
+
{#each Object.entries(storeAttrs) as [key, value]}
|
|
239
|
+
<div class="flex gap-2 py-0.5">
|
|
240
|
+
<span class="shrink-0 font-medium text-zinc-500 dark:text-zinc-400">{key}:</span>
|
|
241
|
+
<span class="break-all text-zinc-700 dark:text-zinc-300">
|
|
242
|
+
{typeof value === 'string' ? value : JSON.stringify(value)}
|
|
243
|
+
</span>
|
|
244
|
+
</div>
|
|
245
|
+
{/each}
|
|
246
|
+
</div>
|
|
247
|
+
{:else}
|
|
248
|
+
<div class="flex h-full items-center justify-center">
|
|
249
|
+
<p class="text-sm text-zinc-400">Select a variable from the list</p>
|
|
250
|
+
</div>
|
|
251
|
+
{/if}
|
|
252
|
+
</div>
|
|
253
|
+
</div>
|
|
254
|
+
{/if}
|
|
255
|
+
</div>
|
|
256
|
+
</div>
|