@walkthru-earth/objex 1.3.1 → 1.4.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.
Files changed (184) hide show
  1. package/LICENSE +5 -0
  2. package/README.md +20 -12
  3. package/dist/components/browser/FileTreeSidebar.svelte +32 -17
  4. package/dist/components/layout/AboutSheet.svelte +5 -2
  5. package/dist/components/layout/ConnectionDialog.svelte +1 -1
  6. package/dist/components/layout/SettingsSheet.svelte +237 -0
  7. package/dist/components/layout/SettingsSheet.svelte.d.ts +6 -0
  8. package/dist/components/layout/Sidebar.svelte +73 -6
  9. package/dist/components/layout/Sidebar.svelte.d.ts +4 -1
  10. package/dist/components/layout/StatusBar.svelte +1 -1
  11. package/dist/components/layout/TabBar.svelte +2 -2
  12. package/dist/components/ui/context-menu/context-menu-radio-group.svelte.d.ts +1 -1
  13. package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte.d.ts +1 -1
  14. package/dist/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte.d.ts +1 -1
  15. package/dist/components/ui/input/input.svelte.d.ts +1 -1
  16. package/dist/components/ui/resizable/index.d.ts +1 -1
  17. package/dist/components/ui/resizable/index.js +2 -2
  18. package/dist/components/ui/slider/index.d.ts +3 -0
  19. package/dist/components/ui/slider/index.js +5 -0
  20. package/dist/components/ui/slider/range-slider.svelte +94 -0
  21. package/dist/components/ui/slider/range-slider.svelte.d.ts +21 -0
  22. package/dist/components/ui/slider/slider.svelte +83 -0
  23. package/dist/components/ui/slider/slider.svelte.d.ts +7 -0
  24. package/dist/components/viewers/ArchiveViewer.svelte +2 -2
  25. package/dist/components/viewers/CodeViewer.svelte +31 -22
  26. package/dist/components/viewers/CogControls.svelte +338 -184
  27. package/dist/components/viewers/CogControls.svelte.d.ts +33 -10
  28. package/dist/components/viewers/CogViewer.svelte +263 -112
  29. package/dist/components/viewers/CopcViewer.svelte +1 -1
  30. package/dist/components/viewers/FlatGeobufViewer.svelte +1 -1
  31. package/dist/components/viewers/GeoParquetMapViewer.svelte +6 -6
  32. package/dist/components/viewers/GeoParquetMapViewer.svelte.d.ts +1 -1
  33. package/dist/components/viewers/ImageViewer.svelte +2 -2
  34. package/dist/components/viewers/MarkdownViewer.svelte +12 -9
  35. package/dist/components/viewers/MediaViewer.svelte +2 -2
  36. package/dist/components/viewers/ModelViewer.svelte +1 -1
  37. package/dist/components/viewers/MultiCogViewer.svelte +467 -102
  38. package/dist/components/viewers/MultiCogViewer.svelte.d.ts +1 -1
  39. package/dist/components/viewers/NotebookViewer.svelte +6 -3
  40. package/dist/components/viewers/PdfViewer.svelte +2 -2
  41. package/dist/components/viewers/PmtilesViewer.svelte +3 -6
  42. package/dist/components/viewers/RawViewer.svelte +6 -3
  43. package/dist/components/viewers/StacMapViewer.svelte +1 -1
  44. package/dist/components/viewers/StacMosaicViewer.svelte +1760 -408
  45. package/dist/components/viewers/StacMosaicViewer.svelte.d.ts +1 -1
  46. package/dist/components/viewers/StacTabViewer.svelte +24 -13
  47. package/dist/components/viewers/StacTabViewer.svelte.d.ts +1 -1
  48. package/dist/components/viewers/TableGrid.svelte +4 -4
  49. package/dist/components/viewers/TableStatusBar.svelte +1 -1
  50. package/dist/components/viewers/TableToolbar.svelte +1 -1
  51. package/dist/components/viewers/TableViewer.svelte +25 -17
  52. package/dist/components/viewers/TableViewer.svelte.d.ts +1 -0
  53. package/dist/components/viewers/ViewerRouter.svelte +16 -8
  54. package/dist/components/viewers/ZarrMapViewer.svelte +11 -9
  55. package/dist/components/viewers/ZarrViewer.svelte +4 -4
  56. package/dist/components/viewers/cog/ChannelPicker.svelte +83 -0
  57. package/dist/components/viewers/cog/ChannelPicker.svelte.d.ts +13 -0
  58. package/dist/components/viewers/cog/PixelInspectorPanel.svelte +87 -0
  59. package/dist/components/viewers/cog/PixelInspectorPanel.svelte.d.ts +17 -0
  60. package/dist/components/viewers/cog/buildRgbLayer.d.ts +78 -0
  61. package/dist/components/viewers/cog/buildRgbLayer.js +176 -0
  62. package/dist/components/viewers/map/AttributeTable.svelte +1 -1
  63. package/dist/components/viewers/map/MapContainer.svelte +37 -11
  64. package/dist/components/viewers/pmtiles/PmtilesArchiveView.svelte +1 -1
  65. package/dist/components/viewers/pmtiles/PmtilesTileInspector.svelte +1 -1
  66. package/dist/components/viewers/stac/StacDatetimeBar.svelte +175 -0
  67. package/dist/components/viewers/stac/StacDatetimeBar.svelte.d.ts +10 -0
  68. package/dist/components/viewers/stac/StacFilterPanel.svelte +243 -0
  69. package/dist/components/viewers/stac/StacFilterPanel.svelte.d.ts +14 -0
  70. package/dist/components/viewers/stac/StacItemInspector.svelte +223 -0
  71. package/dist/components/viewers/stac/StacItemInspector.svelte.d.ts +10 -0
  72. package/dist/components/viewers/stac/StacItemStrip.svelte +228 -0
  73. package/dist/components/viewers/stac/StacItemStrip.svelte.d.ts +12 -0
  74. package/dist/file-icons/index.d.ts +1 -1
  75. package/dist/file-icons/index.js +1 -1
  76. package/dist/i18n/ar.js +110 -2
  77. package/dist/i18n/en.js +110 -2
  78. package/dist/index.d.ts +2 -28
  79. package/dist/index.js +7 -23
  80. package/dist/query/engine.d.ts +10 -0
  81. package/dist/query/source.js +1 -1
  82. package/dist/query/stac-source-factory.d.ts +65 -0
  83. package/dist/query/stac-source-factory.js +77 -0
  84. package/dist/query/stac-source-parquet.d.ts +135 -0
  85. package/dist/query/stac-source-parquet.js +465 -0
  86. package/dist/query/wasm.d.ts +8 -0
  87. package/dist/query/wasm.js +304 -2
  88. package/dist/storage/presign.js +1 -1
  89. package/dist/storage/providers.js +5 -5
  90. package/dist/stores/config.svelte.d.ts +15 -0
  91. package/dist/stores/config.svelte.js +46 -0
  92. package/dist/stores/connections.svelte.d.ts +2 -2
  93. package/dist/stores/connections.svelte.js +1 -2
  94. package/dist/stores/files.svelte.d.ts +1 -1
  95. package/dist/stores/files.svelte.js +1 -1
  96. package/dist/stores/query-history.svelte.js +1 -1
  97. package/dist/stores/settings.svelte.d.ts +16 -1
  98. package/dist/stores/settings.svelte.js +104 -48
  99. package/dist/stores/tabs.svelte.d.ts +3 -0
  100. package/dist/stores/tabs.svelte.js +17 -0
  101. package/dist/utils/cog-histogram.d.ts +121 -0
  102. package/dist/utils/cog-histogram.js +424 -0
  103. package/dist/utils/cog.d.ts +177 -20
  104. package/dist/utils/cog.js +361 -76
  105. package/dist/utils/colormap-sprite.d.ts +0 -9
  106. package/dist/utils/colormap-sprite.js +0 -21
  107. package/dist/utils/deck.d.ts +16 -12
  108. package/dist/utils/deck.js +10 -4
  109. package/dist/utils/pmtiles-tile.js +2 -2
  110. package/dist/utils/{url.d.ts → signed-url.d.ts} +15 -1
  111. package/dist/utils/{url.js → signed-url.js} +32 -10
  112. package/dist/utils/url-state.d.ts +36 -0
  113. package/dist/utils/url-state.js +72 -2
  114. package/dist/utils/zarr-tab.d.ts +1 -2
  115. package/dist/utils/zarr-tab.js +1 -2
  116. package/dist/utils/zarr.d.ts +0 -17
  117. package/dist/utils/zarr.js +1 -45
  118. package/package.json +55 -84
  119. package/dist/components/browser/Breadcrumb.svelte +0 -50
  120. package/dist/components/browser/Breadcrumb.svelte.d.ts +0 -7
  121. package/dist/components/browser/CreateFolderDialog.svelte +0 -98
  122. package/dist/components/browser/CreateFolderDialog.svelte.d.ts +0 -6
  123. package/dist/components/browser/DeleteConfirmDialog.svelte +0 -90
  124. package/dist/components/browser/DeleteConfirmDialog.svelte.d.ts +0 -8
  125. package/dist/components/browser/DropZone.svelte +0 -83
  126. package/dist/components/browser/DropZone.svelte.d.ts +0 -7
  127. package/dist/components/browser/FileBrowser.svelte +0 -252
  128. package/dist/components/browser/FileBrowser.svelte.d.ts +0 -3
  129. package/dist/components/browser/FileRow.svelte +0 -117
  130. package/dist/components/browser/FileRow.svelte.d.ts +0 -9
  131. package/dist/components/browser/RenameDialog.svelte +0 -101
  132. package/dist/components/browser/RenameDialog.svelte.d.ts +0 -8
  133. package/dist/components/browser/SearchBar.svelte +0 -40
  134. package/dist/components/browser/SearchBar.svelte.d.ts +0 -6
  135. package/dist/components/browser/UploadButton.svelte +0 -65
  136. package/dist/components/browser/UploadButton.svelte.d.ts +0 -3
  137. package/dist/query/stac-geoparquet.d.ts +0 -31
  138. package/dist/query/stac-geoparquet.js +0 -136
  139. package/dist/utils/clipboard.d.ts +0 -13
  140. package/dist/utils/clipboard.js +0 -38
  141. package/dist/utils/cloud-url.d.ts +0 -27
  142. package/dist/utils/cloud-url.js +0 -61
  143. package/dist/utils/cog-pure.d.ts +0 -25
  144. package/dist/utils/cog-pure.js +0 -35
  145. package/dist/utils/column-types.d.ts +0 -5
  146. package/dist/utils/column-types.js +0 -137
  147. package/dist/utils/connection-identity.d.ts +0 -51
  148. package/dist/utils/connection-identity.js +0 -97
  149. package/dist/utils/error.d.ts +0 -8
  150. package/dist/utils/error.js +0 -12
  151. package/dist/utils/evidence-context.d.ts +0 -22
  152. package/dist/utils/evidence-context.js +0 -56
  153. package/dist/utils/export.d.ts +0 -22
  154. package/dist/utils/export.js +0 -76
  155. package/dist/utils/file-sort.d.ts +0 -20
  156. package/dist/utils/file-sort.js +0 -41
  157. package/dist/utils/format.d.ts +0 -24
  158. package/dist/utils/format.js +0 -78
  159. package/dist/utils/geoarrow.d.ts +0 -32
  160. package/dist/utils/geoarrow.js +0 -672
  161. package/dist/utils/geometry-type.d.ts +0 -52
  162. package/dist/utils/geometry-type.js +0 -76
  163. package/dist/utils/hex.d.ts +0 -10
  164. package/dist/utils/hex.js +0 -27
  165. package/dist/utils/host-detection.d.ts +0 -23
  166. package/dist/utils/host-detection.js +0 -95
  167. package/dist/utils/local-storage.d.ts +0 -16
  168. package/dist/utils/local-storage.js +0 -37
  169. package/dist/utils/markdown-sql.d.ts +0 -30
  170. package/dist/utils/markdown-sql.js +0 -72
  171. package/dist/utils/notebook.d.ts +0 -59
  172. package/dist/utils/notebook.js +0 -211
  173. package/dist/utils/parquet-metadata.d.ts +0 -64
  174. package/dist/utils/parquet-metadata.js +0 -262
  175. package/dist/utils/stac-geoparquet.d.ts +0 -90
  176. package/dist/utils/stac-geoparquet.js +0 -223
  177. package/dist/utils/stac-hydrate.d.ts +0 -38
  178. package/dist/utils/stac-hydrate.js +0 -243
  179. package/dist/utils/stac.d.ts +0 -136
  180. package/dist/utils/stac.js +0 -176
  181. package/dist/utils/storage-url.d.ts +0 -90
  182. package/dist/utils/storage-url.js +0 -568
  183. package/dist/utils/wkb.d.ts +0 -43
  184. package/dist/utils/wkb.js +0 -359
@@ -0,0 +1,228 @@
1
+ <script lang="ts">
2
+ import type { StacItemView } from '@walkthru-earth/objex-utils';
3
+ import { formatDate } from '@walkthru-earth/objex-utils';
4
+ import { onDestroy, untrack } from 'svelte';
5
+ import { t } from '../../../i18n/index.svelte.js';
6
+
7
+ /**
8
+ * Bottom-anchored, horizontally-scrolling strip of STAC items. Each card
9
+ * shows a thumbnail (when available), the id, datetime, and cloud cover.
10
+ * Hovering a card highlights the matching footprint via `onHover`,
11
+ * clicking selects/pins it via `onSelect`.
12
+ *
13
+ * Thumbnails are presigned via the parent's `presign` callback (the same
14
+ * helper the mosaic uses) so private buckets work without a duplicate
15
+ * cache. Errors are swallowed quietly, a missing thumbnail is just an
16
+ * empty box, never a console flood.
17
+ *
18
+ * Layout choice: the strip is `position: absolute` instead of part of the
19
+ * MapContainer's flow because both the inspector (right slide-over) and
20
+ * the existing pixel inspector (`bottom-2 left-2`) need to coexist with
21
+ * it on the same map surface. `bottom-12` leaves room above the pixel
22
+ * inspector overlay.
23
+ */
24
+ let {
25
+ views,
26
+ hoveredId,
27
+ selectedId,
28
+ presign,
29
+ onHover,
30
+ onSelect
31
+ }: {
32
+ views: readonly StacItemView[];
33
+ hoveredId: string | null;
34
+ selectedId: string | null;
35
+ presign: (href: string) => Promise<string>;
36
+ onHover: (id: string | null) => void;
37
+ onSelect: (id: string | null) => void;
38
+ } = $props();
39
+
40
+ // Resolved thumbnail URLs, keyed by item id. Held as a Map in $state.raw
41
+ // so per-resolve writes are O(1) instead of the O(n) object-spread the
42
+ // previous `{...thumbs, [id]: url}` did (which accumulated to O(n²) over a
43
+ // viewport of 1000+ items, per the project's $state.raw rule for large
44
+ // collections). Reactivity is triggered by bumping `thumbsTick`; readers
45
+ // in the template subscribe to that tick + read `thumbs.get(id)`.
46
+ const thumbs = new Map<string, string | null>();
47
+ let thumbsTick = $state(0);
48
+ const inflight = new Set<string>();
49
+ // Mirror of the current `views[].id` set. The .then() handler for each
50
+ // presign checks against this so a presign that settles AFTER its item
51
+ // scrolled out of the viewport does not re-insert a stale entry into
52
+ // `thumbs` (which the cleanup $effect just removed). Mutated by the
53
+ // cleanup effect, read by load handlers.
54
+ let liveIds = new Set<string>();
55
+
56
+ function loadThumbnail(view: StacItemView): void {
57
+ if (!view.thumbnailHref) return;
58
+ if (thumbs.has(view.id)) return;
59
+ if (inflight.has(view.id)) return;
60
+ inflight.add(view.id);
61
+ presign(view.thumbnailHref)
62
+ .then((url) => {
63
+ if (!liveIds.has(view.id)) return;
64
+ thumbs.set(view.id, url);
65
+ thumbsTick++;
66
+ })
67
+ .catch(() => {
68
+ if (!liveIds.has(view.id)) return;
69
+ thumbs.set(view.id, null);
70
+ thumbsTick++;
71
+ })
72
+ .finally(() => {
73
+ inflight.delete(view.id);
74
+ });
75
+ }
76
+
77
+ // Eagerly kick presigning for every view as soon as it appears. `presign`
78
+ // is local crypto (SigV4 query-string sign or HTTPS pass-through), not a
79
+ // network call, so resolving all thumbnails up-front is cheap. Each
80
+ // resulting `<img>` carries `loading="lazy"`, so the actual GET is still
81
+ // deferred to scroll-into-view by the browser. The previous mouseenter /
82
+ // focus trigger never fired on touch devices and required the user to
83
+ // hover every card individually on desktop.
84
+ $effect(() => {
85
+ for (const view of views) loadThumbnail(view);
86
+ });
87
+
88
+ // Drop thumbs for items no longer in the views list. Without this, panning
89
+ // across a STAC API would grow `thumbs` forever as the user discovers new
90
+ // regions, and the cache would dominate memory before any other leak.
91
+ $effect(() => {
92
+ const ids = new Set(views.map((v) => v.id));
93
+ liveIds = ids;
94
+ untrack(() => {
95
+ let mutated = false;
96
+ for (const id of thumbs.keys()) {
97
+ if (!ids.has(id)) {
98
+ thumbs.delete(id);
99
+ mutated = true;
100
+ }
101
+ }
102
+ if (mutated) thumbsTick++;
103
+ });
104
+ });
105
+
106
+ // Scroll the selected card into view when selection comes from outside
107
+ // (footprint click). Only fires when the id changes, not on every render.
108
+ let scrollContainer: HTMLDivElement | null = $state(null);
109
+ let lastScrolled: string | null = null;
110
+ $effect(() => {
111
+ if (!selectedId || selectedId === lastScrolled) return;
112
+ if (!scrollContainer) return;
113
+ const el = scrollContainer.querySelector(`[data-item-id="${CSS.escape(selectedId)}"]`);
114
+ if (el && 'scrollIntoView' in el) {
115
+ (el as HTMLElement).scrollIntoView({ behavior: 'smooth', block: 'nearest', inline: 'center' });
116
+ lastScrolled = selectedId;
117
+ }
118
+ });
119
+
120
+ onDestroy(() => {
121
+ thumbs.clear();
122
+ inflight.clear();
123
+ liveIds = new Set();
124
+ });
125
+
126
+ function formatItemDate(iso: string | null): string {
127
+ if (!iso) return '';
128
+ const t = Date.parse(iso);
129
+ return Number.isFinite(t) ? formatDate(t) : iso;
130
+ }
131
+
132
+ /**
133
+ * Template reader for the thumbs Map. Reading `thumbsTick` first registers
134
+ * a Svelte reactive dependency on the tick counter, so any tick bump
135
+ * (resolve / failure / cleanup) re-evaluates this call site without us
136
+ * having to wrap the entire Map in a reactive Proxy via `$state(Map)`.
137
+ * Returns the same tri-state the template branches on:
138
+ * string → resolved URL, render `<img>`
139
+ * null → presign failed, render "no thumbnail" placeholder
140
+ * undefined → still in flight (or has no thumbnailHref), render "loading"
141
+ */
142
+ function thumbFor(id: string): string | null | undefined {
143
+ void thumbsTick;
144
+ return thumbs.get(id);
145
+ }
146
+ </script>
147
+
148
+ <div
149
+ class="pointer-events-auto rounded-md bg-card/90 shadow-lg backdrop-blur-sm"
150
+ >
151
+ <div class="flex items-center justify-between border-b border-border px-2 py-1 text-xs text-muted-foreground sm:text-[10px]">
152
+ <span class="tabular-nums">{t('stac.stripCount', { count: views.length })}</span>
153
+ {#if selectedId}
154
+ <button
155
+ class="inline-flex min-h-8 items-center rounded px-2 py-1 text-xs hover:bg-accent hover:text-accent-foreground sm:min-h-0 sm:px-1.5 sm:py-0.5 sm:text-[10px]"
156
+ style="touch-action: manipulation;"
157
+ onclick={() => onSelect(null)}
158
+ >
159
+ {t('stac.clearSelection')}
160
+ </button>
161
+ {/if}
162
+ </div>
163
+ <div
164
+ bind:this={scrollContainer}
165
+ role="list"
166
+ class="flex snap-x snap-mandatory gap-1.5 overflow-x-auto overscroll-x-contain px-2 py-1.5"
167
+ style="-webkit-overflow-scrolling: touch;"
168
+ onmouseleave={() => onHover(null)}
169
+ >
170
+ {#each views as view (view.id)}
171
+ {@const thumb = thumbFor(view.id)}
172
+ <button
173
+ type="button"
174
+ data-item-id={view.id}
175
+ class="group relative flex w-24 shrink-0 snap-start flex-col gap-1 overflow-hidden rounded border bg-background text-left transition-colors sm:w-32"
176
+ class:border-border={view.id !== hoveredId && view.id !== selectedId}
177
+ class:border-white={view.id === hoveredId && view.id !== selectedId}
178
+ class:border-amber-400={view.id === selectedId}
179
+ class:ring-1={view.id === selectedId}
180
+ class:ring-amber-400={view.id === selectedId}
181
+ onmouseenter={() => onHover(view.id)}
182
+ onfocus={() => onHover(view.id)}
183
+ onclick={() => onSelect(view.id)}
184
+ >
185
+ <div class="relative aspect-square w-full bg-muted">
186
+ {#if thumb}
187
+ <img
188
+ src={thumb}
189
+ alt=""
190
+ loading="lazy"
191
+ decoding="async"
192
+ fetchpriority="low"
193
+ class="h-full w-full object-cover"
194
+ onerror={() => {
195
+ thumbs.set(view.id, null);
196
+ thumbsTick++;
197
+ }}
198
+ />
199
+ {:else if thumb === null}
200
+ <div class="flex h-full w-full items-center justify-center text-[9px] text-muted-foreground">
201
+ {t('stac.thumbNone')}
202
+ </div>
203
+ {:else if view.thumbnailHref}
204
+ <div class="flex h-full w-full items-center justify-center text-[9px] text-muted-foreground">
205
+ {t('stac.thumbLoading')}
206
+ </div>
207
+ {:else}
208
+ <div class="flex h-full w-full items-center justify-center text-[9px] text-muted-foreground">
209
+ {t('stac.thumbNone')}
210
+ </div>
211
+ {/if}
212
+ {#if view.cloudCover != null}
213
+ <span
214
+ class="absolute right-0.5 top-0.5 rounded bg-black/60 px-1 text-[9px] tabular-nums text-white"
215
+ title={t('stac.cloudCover')}
216
+ >
217
+ {Math.round(view.cloudCover)}%
218
+ </span>
219
+ {/if}
220
+ </div>
221
+ <div class="px-1.5 pb-1 text-[10px] leading-tight">
222
+ <div class="truncate font-medium" title={view.id}>{view.id}</div>
223
+ <div class="truncate text-muted-foreground">{formatItemDate(view.datetime)}</div>
224
+ </div>
225
+ </button>
226
+ {/each}
227
+ </div>
228
+ </div>
@@ -0,0 +1,12 @@
1
+ import type { StacItemView } from '@walkthru-earth/objex-utils';
2
+ type $$ComponentProps = {
3
+ views: readonly StacItemView[];
4
+ hoveredId: string | null;
5
+ selectedId: string | null;
6
+ presign: (href: string) => Promise<string>;
7
+ onHover: (id: string | null) => void;
8
+ onSelect: (id: string | null) => void;
9
+ };
10
+ declare const StacItemStrip: import("svelte").Component<$$ComponentProps, {}, "">;
11
+ type StacItemStrip = ReturnType<typeof StacItemStrip>;
12
+ export default StacItemStrip;
@@ -4,7 +4,7 @@
4
4
  * Single source of truth for extension → icon, color, label, category,
5
5
  * viewer, DuckDB read function, MIME type, and queryability.
6
6
  *
7
- * Used by: FileRow, FileTreeSidebar, ViewerRouter, TableViewer, WasmQueryEngine, etc.
7
+ * Used by: FileTreeSidebar, ViewerRouter, TableViewer, WasmQueryEngine, etc.
8
8
  */
9
9
  export type FileCategory = 'data' | 'geo' | 'code' | 'document' | 'config' | 'image' | 'video' | 'audio' | 'archive' | 'database' | '3d' | 'other';
10
10
  export type ViewerKind = 'table' | 'image' | 'video' | 'audio' | 'markdown' | 'code' | 'cog' | 'pmtiles' | 'flatgeobuf' | 'pdf' | '3d' | 'archive' | 'database' | 'zarr' | 'copc' | 'notebook' | 'raw';
@@ -4,7 +4,7 @@
4
4
  * Single source of truth for extension → icon, color, label, category,
5
5
  * viewer, DuckDB read function, MIME type, and queryability.
6
6
  *
7
- * Used by: FileRow, FileTreeSidebar, ViewerRouter, TableViewer, WasmQueryEngine, etc.
7
+ * Used by: FileTreeSidebar, ViewerRouter, TableViewer, WasmQueryEngine, etc.
8
8
  */
9
9
  // ---------------------------------------------------------------------------
10
10
  // Defaults
package/dist/i18n/ar.js CHANGED
@@ -53,6 +53,26 @@ export const ar = {
53
53
  'theme.dark': 'داكن',
54
54
  'theme.system': 'النظام',
55
55
  'theme.tooltip': 'وضع {mode}',
56
+ // Settings
57
+ 'settings.title': 'الإعدادات',
58
+ 'settings.tooltip': 'الإعدادات',
59
+ 'settings.appearance': 'المظهر',
60
+ 'settings.language': 'اللغة',
61
+ 'settings.data': 'البيانات',
62
+ 'settings.interface': 'الواجهة',
63
+ 'settings.map': 'الخريطة',
64
+ 'settings.basemapAuto': 'تلقائي (حسب السمة)',
65
+ 'settings.rowLimit': 'حد الصفوف الافتراضي',
66
+ 'settings.rowLimitHelp': 'عدد الصفوف المحملة لكل صفحة في عارض الجدول.',
67
+ 'settings.mosaicLimit': 'حد عناصر STAC',
68
+ 'settings.mosaicLimitHelp': 'أقصى عدد لعناصر STAC المحملة في الفسيفساء.',
69
+ 'settings.showConnectionRail': 'شريط الاتصالات الجانبي',
70
+ 'settings.showFileTree': 'شجرة الملفات',
71
+ 'settings.lockedByLink': 'يتم التحكم به عبر معامل الرابط',
72
+ 'settings.copyConfig': 'نسخ إعدادات JSON',
73
+ 'settings.copied': 'تم النسخ',
74
+ 'settings.reset': 'إعادة الضبط الافتراضي',
75
+ 'settings.customConfig': 'تم تحميل إعدادات مخصصة',
56
76
  // Safe Lock
57
77
  'safeLock.enabledAria': 'قفل الأمان مفعّل (قراءة فقط)',
58
78
  'safeLock.disabledAria': 'قفل الأمان معطّل (الكتابة مسموحة)',
@@ -73,6 +93,10 @@ export const ar = {
73
93
  'fileTree.filterPlaceholder': 'تصفية الملفات...',
74
94
  'fileTree.noMatch': 'لا توجد ملفات مطابقة',
75
95
  'fileTree.emptyBucket': 'حاوية فارغة',
96
+ 'fileTree.corsError': 'تعذّر عرض محتوى هذه الحاوية',
97
+ 'fileTree.corsHint': 'استجاب الخادم لكنه لم يُرسل ترويسات CORS، فحجب المتصفح الاستجابة. هذا إعداد يتحكم به مالك الحاوية ولا يمكن تغييره من هنا. تحتاج الحاوية إلى سياسة CORS تسمح بهذا المصدر، أو الوصول عبر وسيط.',
98
+ 'fileTree.loadError': 'تعذّر تحميل هذه الحاوية',
99
+ 'fileTree.loadErrorHint': 'تحقق من إعدادات الاتصال والشبكة، وتأكد من صحة اسم الحاوية والمنطقة.',
76
100
  'fileTree.expandDir': 'توسيع المجلد',
77
101
  'fileTree.copyHttpUrl': 'نسخ رابط HTTPS',
78
102
  'fileTree.copyNativeUri': 'نسخ رابط {scheme}',
@@ -386,14 +410,21 @@ export const ar = {
386
410
  'mapInfo.size': 'الحجم',
387
411
  'mapInfo.bands': 'النطاقات',
388
412
  'map.mosaicEmpty': 'كتالوج STAC لا يحتوي على عناصر بها أصول COG.',
413
+ 'map.mosaicEmptyViewport': 'لا توجد عناصر في نطاق الخريطة الحالي. حرّك أو ابتعد، أو ارفع حد العناصر.',
389
414
  'map.mosaicNoAssets': 'لا تحتوي عناصر STAC على عنوان URL صالح لأصل COG.',
390
415
  'map.multiCogMissingBands': 'عنصر STAC هذا ينقصه نطاقات الأحمر والأخضر والأزرق اللازمة للتركيب.',
416
+ 'map.multiCogMosaicHeavy': 'فسيفساء متعددة الأصول مع عدد كبير من العناصر، قد يتأثر الأداء',
391
417
  'map.multiCogPreset.label': 'الإعداد المسبق',
392
418
  'map.multiCogPreset.trueColor': 'ألوان طبيعية',
393
419
  'map.multiCogPreset.falseColorIR': 'أشعة تحت حمراء كاذبة اللون',
394
420
  'map.multiCogPreset.swir': 'الأشعة تحت الحمراء قصيرة الموجة',
395
421
  'map.multiCogPreset.vegetation': 'الغطاء النباتي',
396
422
  'map.multiCogPreset.agriculture': 'الزراعة',
423
+ 'map.multiCogPreset.custom': 'مخصص',
424
+ 'map.multiCogBands': 'النطاقات',
425
+ 'map.multiCogBandsTooltip': 'اختر النطاق المُسند إلى كل قناة إخراج',
426
+ 'map.multiCogChannelNone': '(بدون)',
427
+ 'map.mosaicAsset': 'الأصل',
397
428
  // تبديل عرض STAC (StacTabViewer)
398
429
  'stac.viewMosaic': 'خريطة',
399
430
  'stac.viewMultiCog': 'خريطة (نطاقات)',
@@ -408,16 +439,93 @@ export const ar = {
408
439
  'stac.mosaicSourcesOther': 'فسيفساء، {count} مصادر',
409
440
  'stac.mosaicInfo': 'معلومات الفسيفساء',
410
441
  'stac.mosaicSourcesLabel': 'المصادر',
442
+ 'stac.explainHeading': 'تحليل',
443
+ 'stac.explainItems': 'العناصر، {visible} ظاهر / {total} إجمالي',
444
+ 'stac.explainAssets': 'أصول مميزة، {count}',
445
+ 'stac.explainOverlap': 'تداخل في المركز، {count} عناصر',
446
+ 'stac.explainBytes': 'تقدير بايت البلاطة لكل عنصر، {bytes}',
447
+ 'stac.explainTimeSpan': 'الفترة، من {start} إلى {end}',
448
+ 'stac.viewportMode': 'منطقة الخريطة',
449
+ 'stac.timeRange': 'الوقت',
450
+ 'stac.timeLatest': 'الأحدث',
451
+ 'stac.time7d': 'آخر 7 أيام',
452
+ 'stac.time30d': 'آخر 30 يومًا',
453
+ 'stac.time90d': 'آخر 90 يومًا',
454
+ 'stac.time1y': 'آخر سنة',
455
+ 'stac.timeAll': 'كل الوقت',
456
+ 'stac.refresh': 'تحديث',
457
+ 'stac.filters': 'المرشحات',
458
+ 'stac.itemLimit': 'حد العناصر',
459
+ 'stac.itemLimitHint': 'الحد الأقصى لعدد العناصر التي يتم جلبها لكل عرض. القيم الأعلى تكشف عن مصادر أكثر لكنها تبطئ التحميل.',
460
+ 'stac.capReached': 'تم بلوغ الحد {limit}. ارفع الحد لجلب المزيد.',
461
+ 'stac.lastRefresh': 'آخر تحديث، منذ {seconds} ثانية',
462
+ 'stac.stageIdle': 'في وضع الانتظار',
463
+ 'stac.stageClassify': 'تصنيف STAC',
464
+ 'stac.stageFetch': 'جلب العناصر',
465
+ 'stac.stageIndex': 'فهرسة المساحات',
466
+ 'stac.stageRender': 'رسم البلاطات',
467
+ 'stac.stageEmpty': 'لا توجد عناصر في العرض',
468
+ 'stac.stageError': 'خطأ',
469
+ 'stac.stageSuperseded': 'تم استبدال الجلب السابق بتحريك جديد',
470
+ 'stac.smokeWarning': 'فشل اختبار التخزين، {reason}',
471
+ 'stac.smokeWarningHint': 'تعذّر الوصول إلى أحد ملفات COG التمثيلية. تحقّق من بيانات الاعتماد للاتصال، أو CORS للحاوية، أو من صحة عنوان الأصل.',
472
+ 'stac.modeViewportApi': 'الوضع، تحديث عند التحريك، STAC API',
473
+ 'stac.modeViewportParquet': 'الوضع، تحديث عند التحريك، stac-geoparquet',
474
+ 'stac.modeStatic': 'الوضع، كتالوج ثابت (جلب لمرة واحدة، قص محلي حسب النطاق)',
475
+ 'stac.footprints': 'البصمات',
476
+ 'stac.footprintsHint': 'إظهار حدود كل عنصر محمّل',
477
+ 'stac.strip': 'الشريط',
478
+ 'stac.stripCount': '{count} عنصر',
479
+ 'stac.clearSelection': 'مسح التحديد',
480
+ 'stac.thumbLoading': 'جارٍ التحميل…',
481
+ 'stac.thumbNone': 'لا توجد معاينة',
482
+ 'stac.cloudCover': 'الغطاء السحابي',
483
+ 'stac.datetime': 'التاريخ والوقت',
484
+ 'stac.endDatetime': 'تاريخ النهاية',
485
+ 'stac.gsd': 'دقة العينة الأرضية',
486
+ 'stac.platform': 'المنصة',
487
+ 'stac.constellation': 'الكوكبة',
488
+ 'stac.instruments': 'الأجهزة',
489
+ 'stac.epsg': 'النظام المرجعي',
490
+ 'stac.assets': 'الأصول ({count})',
491
+ 'stac.assetOpen': 'فتح',
492
+ 'stac.flyTo': 'الانتقال',
493
+ 'stac.filterDatetime': 'تصفية حسب التاريخ',
494
+ 'stac.granularityLabel': 'المدرج التكراري، فواصل {granularity}',
495
+ 'stac.granularity.day': 'يوم',
496
+ 'stac.granularity.week': 'أسبوع',
497
+ 'stac.granularity.month': 'شهر',
498
+ 'stac.granularity.year': 'سنة',
499
+ 'stac.facetTotal': '{count} محمَّل',
500
+ 'stac.facetNoneAvailable': 'لا توجد حقول قابلة للتصفية في هذه البيانات.',
501
+ 'stac.resetFilters': 'إعادة',
502
+ 'stac.filtersActive': 'فلاتر نشطة',
503
+ 'stac.collection': 'المجموعة',
504
+ 'stac.assetRoles': 'أدوار الأصول',
505
+ 'stac.copyId': 'نسخ المعرف',
506
+ 'stac.copyJson': 'نسخ JSON',
507
+ 'stac.copied': 'تم النسخ',
508
+ 'stac.close': 'إغلاق',
509
+ 'stac.showRaw': 'عرض JSON الخام',
510
+ 'stac.hideRaw': 'إخفاء JSON الخام',
411
511
  // COG Controls
412
512
  'cog.style': 'النمط',
513
+ 'cog.asset': 'الأصل',
413
514
  'cog.band': 'النطاق',
414
515
  'cog.singleBand': 'نطاق واحد',
415
516
  'cog.colorRamp': 'تدرج الألوان',
416
517
  'cog.colorRampSearch': 'بحث في التدرجات…',
417
518
  'cog.pixelValue': 'قيمة البكسل',
418
519
  'cog.reading': 'قراءة البكسل...',
419
- 'cog.rescale': 'إعادة القياس',
420
- 'cog.rescaleReset': 'إعادة تعيين',
520
+ 'cog.rescale.label': 'إعادة القياس',
521
+ 'cog.rescale.reset': 'إعادة تعيين',
522
+ 'cog.nodata.label': 'بيانات مفقودة',
523
+ 'cog.nodata.auto': 'تلقائي',
524
+ 'cog.nodata.value': 'قيمة',
525
+ 'cog.nodata.off': 'إيقاف',
526
+ 'cog.nodata.autoHint': 'من الملف: {value}',
527
+ 'cog.nodata.autoNone': 'لا يوجد وسم GDAL_NODATA',
528
+ 'cog.nodata.valuePlaceholder': 'مثال: -9999',
421
529
  // PMTiles Viewer
422
530
  'pmtiles.mapView': 'خريطة',
423
531
  'pmtiles.archiveView': 'الأرشيف',
package/dist/i18n/en.js CHANGED
@@ -53,6 +53,26 @@ export const en = {
53
53
  'theme.dark': 'Dark',
54
54
  'theme.system': 'System',
55
55
  'theme.tooltip': '{mode} mode',
56
+ // Settings
57
+ 'settings.title': 'Settings',
58
+ 'settings.tooltip': 'Settings',
59
+ 'settings.appearance': 'Appearance',
60
+ 'settings.language': 'Language',
61
+ 'settings.data': 'Data',
62
+ 'settings.interface': 'Interface',
63
+ 'settings.map': 'Map',
64
+ 'settings.basemapAuto': 'Auto (match theme)',
65
+ 'settings.rowLimit': 'Default row limit',
66
+ 'settings.rowLimitHelp': 'Rows loaded per page in the table viewer.',
67
+ 'settings.mosaicLimit': 'STAC item limit',
68
+ 'settings.mosaicLimitHelp': 'Maximum STAC items loaded into a mosaic.',
69
+ 'settings.showConnectionRail': 'Connection sidebar',
70
+ 'settings.showFileTree': 'File tree',
71
+ 'settings.lockedByLink': 'Controlled by a link parameter',
72
+ 'settings.copyConfig': 'Copy config JSON',
73
+ 'settings.copied': 'Copied',
74
+ 'settings.reset': 'Reset to defaults',
75
+ 'settings.customConfig': 'Custom config loaded',
56
76
  // Safe Lock
57
77
  'safeLock.enabledAria': 'Safe lock enabled (read-only)',
58
78
  'safeLock.disabledAria': 'Safe lock disabled (writes allowed)',
@@ -73,6 +93,10 @@ export const en = {
73
93
  'fileTree.filterPlaceholder': 'Filter files...',
74
94
  'fileTree.noMatch': 'No matching files',
75
95
  'fileTree.emptyBucket': 'Empty bucket',
96
+ 'fileTree.corsError': "Can't list this bucket",
97
+ 'fileTree.corsHint': 'The server replied but sent no CORS headers, so the browser blocked the response. This is set by the bucket owner and cannot be changed here. The bucket needs a CORS policy that allows this origin, or access through a proxy.',
98
+ 'fileTree.loadError': "Couldn't load this bucket",
99
+ 'fileTree.loadErrorHint': 'Check the connection settings and your network, and confirm the bucket name and region are correct.',
76
100
  'fileTree.expandDir': 'Expand directory',
77
101
  'fileTree.copyHttpUrl': 'Copy HTTPS URL',
78
102
  'fileTree.copyNativeUri': 'Copy {scheme} URI',
@@ -386,14 +410,21 @@ export const en = {
386
410
  'mapInfo.size': 'Size',
387
411
  'mapInfo.bands': 'Bands',
388
412
  'map.mosaicEmpty': 'STAC catalog has no items with COG assets.',
413
+ 'map.mosaicEmptyViewport': 'No items in the current map view. Pan or zoom out, or raise the item cap.',
389
414
  'map.mosaicNoAssets': 'None of the STAC items expose a usable COG asset URL.',
390
415
  'map.multiCogMissingBands': 'This STAC item is missing the red/green/blue bands required for a composite.',
416
+ 'map.multiCogMosaicHeavy': 'Multi-asset mosaic with many items, performance may degrade',
391
417
  'map.multiCogPreset.label': 'Preset',
392
418
  'map.multiCogPreset.trueColor': 'True Color',
393
419
  'map.multiCogPreset.falseColorIR': 'False-Color IR',
394
420
  'map.multiCogPreset.swir': 'SWIR',
395
421
  'map.multiCogPreset.vegetation': 'Vegetation',
396
422
  'map.multiCogPreset.agriculture': 'Agriculture',
423
+ 'map.multiCogPreset.custom': 'Custom',
424
+ 'map.multiCogBands': 'Bands',
425
+ 'map.multiCogBandsTooltip': 'Pick which STAC asset feeds each output channel',
426
+ 'map.multiCogChannelNone': '(none)',
427
+ 'map.mosaicAsset': 'Asset',
397
428
  // STAC tab toggle (StacTabViewer)
398
429
  'stac.viewMosaic': 'Map',
399
430
  'stac.viewMultiCog': 'Map (Bands)',
@@ -408,16 +439,93 @@ export const en = {
408
439
  'stac.mosaicSourcesOther': 'Mosaic, {count} sources',
409
440
  'stac.mosaicInfo': 'Mosaic info',
410
441
  'stac.mosaicSourcesLabel': 'Sources',
442
+ 'stac.explainHeading': 'Explain',
443
+ 'stac.explainItems': 'Items, {visible} visible / {total} total',
444
+ 'stac.explainAssets': 'Distinct assets, {count}',
445
+ 'stac.explainOverlap': 'Center overlap, {count} items',
446
+ 'stac.explainBytes': 'Est tile bytes per item, {bytes}',
447
+ 'stac.explainTimeSpan': 'Time span, {start} to {end}',
448
+ 'stac.viewportMode': 'Map area',
449
+ 'stac.timeRange': 'Time',
450
+ 'stac.timeLatest': 'Latest',
451
+ 'stac.time7d': 'Last 7 days',
452
+ 'stac.time30d': 'Last 30 days',
453
+ 'stac.time90d': 'Last 90 days',
454
+ 'stac.time1y': 'Last year',
455
+ 'stac.timeAll': 'All time',
456
+ 'stac.refresh': 'Refresh',
457
+ 'stac.filters': 'Filters',
458
+ 'stac.itemLimit': 'Item cap',
459
+ 'stac.itemLimitHint': 'Maximum items to fetch per viewport. Higher values reveal more sources but slow loading.',
460
+ 'stac.capReached': 'Cap of {limit} items reached. Raise the cap to fetch more.',
461
+ 'stac.lastRefresh': 'Last refresh, {seconds}s ago',
462
+ 'stac.stageIdle': 'Idle',
463
+ 'stac.stageClassify': 'Classifying STAC',
464
+ 'stac.stageFetch': 'Fetching items',
465
+ 'stac.stageIndex': 'Indexing footprints',
466
+ 'stac.stageRender': 'Rendering tiles',
467
+ 'stac.stageEmpty': 'No items in view',
468
+ 'stac.stageError': 'Error',
469
+ 'stac.stageSuperseded': 'Previous fetch superseded by new pan',
470
+ 'stac.smokeWarning': 'Storage probe failed, {reason}',
471
+ 'stac.smokeWarningHint': 'A representative COG could not be reached. Check connection credentials, bucket CORS, or whether the asset href resolves.',
472
+ 'stac.modeViewportApi': 'Mode, viewport refresh on pan, STAC API',
473
+ 'stac.modeViewportParquet': 'Mode, viewport refresh on pan, stac-geoparquet',
474
+ 'stac.modeStatic': 'Mode, static catalog (one-shot fetch, client-side bbox clipping)',
475
+ 'stac.footprints': 'Footprints',
476
+ 'stac.footprintsHint': 'Toggle bbox outlines for every loaded item',
477
+ 'stac.strip': 'Strip',
478
+ 'stac.stripCount': '{count} items',
479
+ 'stac.clearSelection': 'Clear selection',
480
+ 'stac.thumbLoading': 'Loading…',
481
+ 'stac.thumbNone': 'No preview',
482
+ 'stac.cloudCover': 'Cloud cover',
483
+ 'stac.datetime': 'Datetime',
484
+ 'stac.endDatetime': 'End datetime',
485
+ 'stac.gsd': 'GSD',
486
+ 'stac.platform': 'Platform',
487
+ 'stac.constellation': 'Constellation',
488
+ 'stac.instruments': 'Instruments',
489
+ 'stac.epsg': 'CRS',
490
+ 'stac.assets': 'Assets ({count})',
491
+ 'stac.assetOpen': 'Open',
492
+ 'stac.flyTo': 'Fly to',
493
+ 'stac.filterDatetime': 'Filter by datetime',
494
+ 'stac.granularityLabel': 'Histogram, {granularity} buckets',
495
+ 'stac.granularity.day': 'day',
496
+ 'stac.granularity.week': 'week',
497
+ 'stac.granularity.month': 'month',
498
+ 'stac.granularity.year': 'year',
499
+ 'stac.facetTotal': '{count} loaded',
500
+ 'stac.facetNoneAvailable': 'No filterable fields detected for this dataset.',
501
+ 'stac.resetFilters': 'Reset',
502
+ 'stac.filtersActive': 'Filters active',
503
+ 'stac.collection': 'Collection',
504
+ 'stac.assetRoles': 'Asset roles',
505
+ 'stac.copyId': 'Copy id',
506
+ 'stac.copyJson': 'Copy JSON',
507
+ 'stac.copied': 'Copied',
508
+ 'stac.close': 'Close',
509
+ 'stac.showRaw': 'Show raw JSON',
510
+ 'stac.hideRaw': 'Hide raw JSON',
411
511
  // COG Controls
412
512
  'cog.style': 'Style',
513
+ 'cog.asset': 'Asset',
413
514
  'cog.band': 'Band',
414
515
  'cog.singleBand': 'Single',
415
516
  'cog.colorRamp': 'Color ramp',
416
517
  'cog.colorRampSearch': 'Search ramps…',
417
518
  'cog.pixelValue': 'Pixel Value',
418
519
  'cog.reading': 'Reading pixel...',
419
- 'cog.rescale': 'Rescale',
420
- 'cog.rescaleReset': 'Reset',
520
+ 'cog.rescale.label': 'Rescale',
521
+ 'cog.rescale.reset': 'Reset',
522
+ 'cog.nodata.label': 'No-data',
523
+ 'cog.nodata.auto': 'Auto',
524
+ 'cog.nodata.value': 'Value',
525
+ 'cog.nodata.off': 'Off',
526
+ 'cog.nodata.autoHint': 'from file: {value}',
527
+ 'cog.nodata.autoNone': 'no GDAL_NODATA tag',
528
+ 'cog.nodata.valuePlaceholder': 'e.g. -9999',
421
529
  // PMTiles Viewer
422
530
  'pmtiles.mapView': 'Map',
423
531
  'pmtiles.archiveView': 'Archive',
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export type { ChannelComposite, ChannelRef, CogAsset, CogInfo, ConnectionIdentityInput, DatetimeFacet, Defaults, EnumFacet, EnumFacetField, Facet, FacetSet, FacetSort, FacetState, GeoArrowGeomType, GeoArrowResult, GeoBounds, GeoColumnMeta, GeoParquetMeta, GeoType, HexRow, NumericFacet, NumericFacetField, ParquetFileMetadata, ParsedGeometry, ParsedMarkdownDocument, ParsedStorageUrl, PresetDef, SortConfig, SortDirection, SortField, SqlBlock, StacApiCapabilities, StacBboxStruct, StacGeoparquetRow, StacGeoparquetSchemaColumn, StacItemView, StacNativeQuery, StacRowToItemOptions, StacSource, StacSourceBatch, StacSourceCapabilities, StacSourceKind, StacSourceRequest, StorageExtensionVersion, StorageHints, StorageProvider, ToNativeQueryOptions, TypeCategory } from '@walkthru-earth/objex-utils';
2
+ export { allChannelsBand0, applyFacets, applyPreset, applyStorageHintsToConnection, availablePresets, buildDataTypeLabel, buildFacets, buildGeoArrowTables, clampBounds, classifyType, compositeFromUrl, compositeToUrl, connectionIdentityKey, copyToClipboard, DATETIME_HISTOGRAM_BINS, describeParseResult, detectStorageExtensionVersion, emptyFacetState, emptyPushdown, emptyStorageHints, escapeCsvField, extractBounds, extractCogAssets, extractEpsgFromGeoMeta, extractGeometryTypes, extractItemView, extractStorageHints, findGeoColumn, findGeoColumnFromRows, flattenStacBbox, formatDate, formatFileSize, formatValue, generateHexDump, getFileExtension, getNativeScheme, handleLoadError, hasActiveFilters, interpolateTemplates, isAbortError, isSameConnectionIdentity, isSingleAssetComposite, isStacGeoparquetSchema, jsonReplacerBigInt, loadFromStorage, looksLikeUrl, markSqlBlocks, normalizeEndpoint, normalizeGeomType, normalizeProvider, PRESETS, parseMarkdownDocument, parseStorageUrl, parseWKB, persistToStorage, pickNaturalColorComposite, pickStacPrimaryAsset, presetMatchesComposite, readParquetMetadata, residualState, resolveCloudUrl, resolveStacAssetHref, SF_LABELS, STAC_GEOPARQUET_REQUIRED_COLUMNS, safeClamp, safeDecodeURIComponent, serializeToCsv, serializeToJson, sniffApiCapabilities, sortFileEntries, sortViews, stacRowToItem, syntheticSelfAsset, toBinary, toCql2Filter, toggleSortField, toNativeQuery, typeBadgeClass, typeColor, typeLabel, wireCodeCopyButtons } from '@walkthru-earth/objex-utils';
1
3
  export { COPY_FEEDBACK_MS, DEFAULT_TARGET_CRS, DUCKDB_INIT_TIMEOUT_MS, LAYER_HUE_MULTIPLIER, MAX_QUERY_HISTORY_ENTRIES, SQL_PREVIEW_LENGTH, STORAGE_KEYS, VIEWER_DIR_EXTENSIONS, WGS84_CODES } from './constants.js';
2
4
  export type { DuckDbReadFn, FileCategory, FileTypeInfo, ViewerKind } from './file-icons/index.js';
3
5
  export { buildDuckDbSource, getDuckDbReadFn, getFileTypeInfo, getMimeType, getViewerKind, isCloudNativeFormat, isQueryable } from './file-icons/index.js';
@@ -8,31 +10,3 @@ export type { ProviderDef, ProviderId, ProviderRegion } from './storage/provider
8
10
  export { buildEndpointFromTemplate, buildProviderBaseUrl, getProvider, isGcsProvider, PROVIDER_IDS, PROVIDERS } from './storage/providers.js';
9
11
  export { UrlAdapter } from './storage/url-adapter.js';
10
12
  export type { Connection, ConnectionConfig, FileEntry, Tab, Theme, WriteResult } from './types.js';
11
- export { copyToClipboard, wireCodeCopyButtons } from './utils/clipboard.js';
12
- export { getNativeScheme, resolveCloudUrl, safeDecodeURIComponent } from './utils/cloud-url.js';
13
- export type { CogInfo, GeoBounds } from './utils/cog.js';
14
- export { buildDataTypeLabel, clampBounds, SF_LABELS, safeClamp } from './utils/cog.js';
15
- export type { TypeCategory } from './utils/column-types.js';
16
- export { classifyType, typeBadgeClass, typeColor, typeLabel } from './utils/column-types.js';
17
- export type { ConnectionIdentityInput } from './utils/connection-identity.js';
18
- export { connectionIdentityKey, isSameConnectionIdentity, normalizeEndpoint, normalizeProvider } from './utils/connection-identity.js';
19
- export { handleLoadError } from './utils/error.js';
20
- export { escapeCsvField, serializeToCsv, serializeToJson } from './utils/export.js';
21
- export type { SortConfig, SortDirection, SortField } from './utils/file-sort.js';
22
- export { sortFileEntries, toggleSortField } from './utils/file-sort.js';
23
- export { formatDate, formatFileSize, formatValue, getFileExtension, jsonReplacerBigInt } from './utils/format.js';
24
- export type { GeoArrowGeomType, GeoArrowResult } from './utils/geoarrow.js';
25
- export { buildGeoArrowTables, normalizeGeomType } from './utils/geoarrow.js';
26
- export type { HexRow } from './utils/hex.js';
27
- export { generateHexDump } from './utils/hex.js';
28
- export { loadFromStorage, persistToStorage } from './utils/local-storage.js';
29
- export type { ParsedMarkdownDocument, SqlBlock } from './utils/markdown-sql.js';
30
- export { interpolateTemplates, markSqlBlocks, parseMarkdownDocument } from './utils/markdown-sql.js';
31
- export type { GeoColumnMeta, GeoParquetMeta, ParquetFileMetadata } from './utils/parquet-metadata.js';
32
- export { extractBounds, extractEpsgFromGeoMeta, extractGeometryTypes, readParquetMetadata } from './utils/parquet-metadata.js';
33
- export type { StacBboxStruct, StacGeoparquetRow, StacGeoparquetSchemaColumn, StacRowToItemOptions } from './utils/stac-geoparquet.js';
34
- export { flattenStacBbox, isStacGeoparquetSchema, pickStacPrimaryAsset, resolveStacAssetHref, STAC_GEOPARQUET_REQUIRED_COLUMNS, stacRowToItem } from './utils/stac-geoparquet.js';
35
- export type { Defaults, ParsedStorageUrl, StorageProvider } from './utils/storage-url.js';
36
- export { describeParseResult, looksLikeUrl, parseStorageUrl } from './utils/storage-url.js';
37
- export type { GeoType, ParsedGeometry } from './utils/wkb.js';
38
- export { findGeoColumn, findGeoColumnFromRows, parseWKB, toBinary } from './utils/wkb.js';