@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.
Files changed (367) hide show
  1. package/LICENSE +396 -0
  2. package/README.md +114 -0
  3. package/dist/assets/favicon.svg +17 -0
  4. package/dist/components/CLAUDE.md +44 -0
  5. package/dist/components/browser/Breadcrumb.svelte +50 -0
  6. package/dist/components/browser/Breadcrumb.svelte.d.ts +7 -0
  7. package/dist/components/browser/CreateFolderDialog.svelte +98 -0
  8. package/dist/components/browser/CreateFolderDialog.svelte.d.ts +6 -0
  9. package/dist/components/browser/DeleteConfirmDialog.svelte +90 -0
  10. package/dist/components/browser/DeleteConfirmDialog.svelte.d.ts +8 -0
  11. package/dist/components/browser/DropZone.svelte +83 -0
  12. package/dist/components/browser/DropZone.svelte.d.ts +7 -0
  13. package/dist/components/browser/FileBrowser.svelte +229 -0
  14. package/dist/components/browser/FileBrowser.svelte.d.ts +3 -0
  15. package/dist/components/browser/FileRow.svelte +112 -0
  16. package/dist/components/browser/FileRow.svelte.d.ts +9 -0
  17. package/dist/components/browser/FileTreeSidebar.svelte +559 -0
  18. package/dist/components/browser/FileTreeSidebar.svelte.d.ts +8 -0
  19. package/dist/components/browser/RenameDialog.svelte +101 -0
  20. package/dist/components/browser/RenameDialog.svelte.d.ts +8 -0
  21. package/dist/components/browser/SearchBar.svelte +40 -0
  22. package/dist/components/browser/SearchBar.svelte.d.ts +6 -0
  23. package/dist/components/browser/UploadButton.svelte +65 -0
  24. package/dist/components/browser/UploadButton.svelte.d.ts +3 -0
  25. package/dist/components/editor/CodeMirrorEditor.svelte +404 -0
  26. package/dist/components/editor/CodeMirrorEditor.svelte.d.ts +12 -0
  27. package/dist/components/editor/MilkdownEditor.svelte +98 -0
  28. package/dist/components/editor/MilkdownEditor.svelte.d.ts +9 -0
  29. package/dist/components/editor/SqlEditor.svelte +173 -0
  30. package/dist/components/editor/SqlEditor.svelte.d.ts +7 -0
  31. package/dist/components/editor/SqlResultBlock.svelte +199 -0
  32. package/dist/components/editor/SqlResultBlock.svelte.d.ts +9 -0
  33. package/dist/components/layout/ConnectionDialog.svelte +439 -0
  34. package/dist/components/layout/ConnectionDialog.svelte.d.ts +9 -0
  35. package/dist/components/layout/LocaleToggle.svelte +32 -0
  36. package/dist/components/layout/LocaleToggle.svelte.d.ts +3 -0
  37. package/dist/components/layout/SafeLockToggle.svelte +37 -0
  38. package/dist/components/layout/SafeLockToggle.svelte.d.ts +18 -0
  39. package/dist/components/layout/Sidebar.svelte +314 -0
  40. package/dist/components/layout/Sidebar.svelte.d.ts +3 -0
  41. package/dist/components/layout/StatusBar.svelte +73 -0
  42. package/dist/components/layout/StatusBar.svelte.d.ts +3 -0
  43. package/dist/components/layout/TabBar.svelte +102 -0
  44. package/dist/components/layout/TabBar.svelte.d.ts +7 -0
  45. package/dist/components/layout/ThemeToggle.svelte +52 -0
  46. package/dist/components/layout/ThemeToggle.svelte.d.ts +3 -0
  47. package/dist/components/ui/badge/badge.svelte +49 -0
  48. package/dist/components/ui/badge/badge.svelte.d.ts +32 -0
  49. package/dist/components/ui/badge/index.d.ts +1 -0
  50. package/dist/components/ui/badge/index.js +1 -0
  51. package/dist/components/ui/button/button.svelte +82 -0
  52. package/dist/components/ui/button/button.svelte.d.ts +64 -0
  53. package/dist/components/ui/button/index.d.ts +2 -0
  54. package/dist/components/ui/button/index.js +4 -0
  55. package/dist/components/ui/context-menu/context-menu-checkbox-item.svelte +40 -0
  56. package/dist/components/ui/context-menu/context-menu-checkbox-item.svelte.d.ts +9 -0
  57. package/dist/components/ui/context-menu/context-menu-content.svelte +28 -0
  58. package/dist/components/ui/context-menu/context-menu-content.svelte.d.ts +10 -0
  59. package/dist/components/ui/context-menu/context-menu-group-heading.svelte +21 -0
  60. package/dist/components/ui/context-menu/context-menu-group-heading.svelte.d.ts +7 -0
  61. package/dist/components/ui/context-menu/context-menu-group.svelte +7 -0
  62. package/dist/components/ui/context-menu/context-menu-group.svelte.d.ts +4 -0
  63. package/dist/components/ui/context-menu/context-menu-item.svelte +27 -0
  64. package/dist/components/ui/context-menu/context-menu-item.svelte.d.ts +8 -0
  65. package/dist/components/ui/context-menu/context-menu-label.svelte +24 -0
  66. package/dist/components/ui/context-menu/context-menu-label.svelte.d.ts +8 -0
  67. package/dist/components/ui/context-menu/context-menu-portal.svelte +7 -0
  68. package/dist/components/ui/context-menu/context-menu-portal.svelte.d.ts +3 -0
  69. package/dist/components/ui/context-menu/context-menu-radio-group.svelte +16 -0
  70. package/dist/components/ui/context-menu/context-menu-radio-group.svelte.d.ts +4 -0
  71. package/dist/components/ui/context-menu/context-menu-radio-item.svelte +33 -0
  72. package/dist/components/ui/context-menu/context-menu-radio-item.svelte.d.ts +4 -0
  73. package/dist/components/ui/context-menu/context-menu-separator.svelte +17 -0
  74. package/dist/components/ui/context-menu/context-menu-separator.svelte.d.ts +4 -0
  75. package/dist/components/ui/context-menu/context-menu-shortcut.svelte +20 -0
  76. package/dist/components/ui/context-menu/context-menu-shortcut.svelte.d.ts +5 -0
  77. package/dist/components/ui/context-menu/context-menu-sub-content.svelte +20 -0
  78. package/dist/components/ui/context-menu/context-menu-sub-content.svelte.d.ts +4 -0
  79. package/dist/components/ui/context-menu/context-menu-sub-trigger.svelte +29 -0
  80. package/dist/components/ui/context-menu/context-menu-sub-trigger.svelte.d.ts +8 -0
  81. package/dist/components/ui/context-menu/context-menu-sub.svelte +7 -0
  82. package/dist/components/ui/context-menu/context-menu-sub.svelte.d.ts +3 -0
  83. package/dist/components/ui/context-menu/context-menu-trigger.svelte +7 -0
  84. package/dist/components/ui/context-menu/context-menu-trigger.svelte.d.ts +4 -0
  85. package/dist/components/ui/context-menu/context-menu.svelte +7 -0
  86. package/dist/components/ui/context-menu/context-menu.svelte.d.ts +3 -0
  87. package/dist/components/ui/context-menu/index.d.ts +17 -0
  88. package/dist/components/ui/context-menu/index.js +19 -0
  89. package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte +16 -0
  90. package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte.d.ts +4 -0
  91. package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte +43 -0
  92. package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte.d.ts +9 -0
  93. package/dist/components/ui/dropdown-menu/dropdown-menu-content.svelte +29 -0
  94. package/dist/components/ui/dropdown-menu/dropdown-menu-content.svelte.d.ts +10 -0
  95. package/dist/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte +22 -0
  96. package/dist/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte.d.ts +8 -0
  97. package/dist/components/ui/dropdown-menu/dropdown-menu-group.svelte +7 -0
  98. package/dist/components/ui/dropdown-menu/dropdown-menu-group.svelte.d.ts +4 -0
  99. package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte +27 -0
  100. package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte.d.ts +8 -0
  101. package/dist/components/ui/dropdown-menu/dropdown-menu-label.svelte +24 -0
  102. package/dist/components/ui/dropdown-menu/dropdown-menu-label.svelte.d.ts +8 -0
  103. package/dist/components/ui/dropdown-menu/dropdown-menu-portal.svelte +7 -0
  104. package/dist/components/ui/dropdown-menu/dropdown-menu-portal.svelte.d.ts +3 -0
  105. package/dist/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte +16 -0
  106. package/dist/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte.d.ts +4 -0
  107. package/dist/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte +33 -0
  108. package/dist/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte.d.ts +4 -0
  109. package/dist/components/ui/dropdown-menu/dropdown-menu-separator.svelte +17 -0
  110. package/dist/components/ui/dropdown-menu/dropdown-menu-separator.svelte.d.ts +4 -0
  111. package/dist/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte +20 -0
  112. package/dist/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte.d.ts +5 -0
  113. package/dist/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte +20 -0
  114. package/dist/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte.d.ts +4 -0
  115. package/dist/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte +29 -0
  116. package/dist/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte.d.ts +7 -0
  117. package/dist/components/ui/dropdown-menu/dropdown-menu-sub.svelte +7 -0
  118. package/dist/components/ui/dropdown-menu/dropdown-menu-sub.svelte.d.ts +3 -0
  119. package/dist/components/ui/dropdown-menu/dropdown-menu-trigger.svelte +7 -0
  120. package/dist/components/ui/dropdown-menu/dropdown-menu-trigger.svelte.d.ts +4 -0
  121. package/dist/components/ui/dropdown-menu/dropdown-menu.svelte +7 -0
  122. package/dist/components/ui/dropdown-menu/dropdown-menu.svelte.d.ts +3 -0
  123. package/dist/components/ui/dropdown-menu/index.d.ts +18 -0
  124. package/dist/components/ui/dropdown-menu/index.js +18 -0
  125. package/dist/components/ui/input/index.d.ts +2 -0
  126. package/dist/components/ui/input/index.js +4 -0
  127. package/dist/components/ui/input/input.svelte +52 -0
  128. package/dist/components/ui/input/input.svelte.d.ts +13 -0
  129. package/dist/components/ui/resizable/index.d.ts +4 -0
  130. package/dist/components/ui/resizable/index.js +6 -0
  131. package/dist/components/ui/resizable/resizable-handle.svelte +30 -0
  132. package/dist/components/ui/resizable/resizable-handle.svelte.d.ts +8 -0
  133. package/dist/components/ui/resizable/resizable-pane-group.svelte +20 -0
  134. package/dist/components/ui/resizable/resizable-pane-group.svelte.d.ts +7 -0
  135. package/dist/components/ui/scroll-area/index.d.ts +3 -0
  136. package/dist/components/ui/scroll-area/index.js +5 -0
  137. package/dist/components/ui/scroll-area/scroll-area-scrollbar.svelte +31 -0
  138. package/dist/components/ui/scroll-area/scroll-area-scrollbar.svelte.d.ts +4 -0
  139. package/dist/components/ui/scroll-area/scroll-area.svelte +47 -0
  140. package/dist/components/ui/scroll-area/scroll-area.svelte.d.ts +11 -0
  141. package/dist/components/ui/separator/index.d.ts +2 -0
  142. package/dist/components/ui/separator/index.js +4 -0
  143. package/dist/components/ui/separator/separator.svelte +21 -0
  144. package/dist/components/ui/separator/separator.svelte.d.ts +4 -0
  145. package/dist/components/ui/sheet/index.d.ts +11 -0
  146. package/dist/components/ui/sheet/index.js +13 -0
  147. package/dist/components/ui/sheet/sheet-close.svelte +7 -0
  148. package/dist/components/ui/sheet/sheet-close.svelte.d.ts +4 -0
  149. package/dist/components/ui/sheet/sheet-content.svelte +62 -0
  150. package/dist/components/ui/sheet/sheet-content.svelte.d.ts +37 -0
  151. package/dist/components/ui/sheet/sheet-description.svelte +17 -0
  152. package/dist/components/ui/sheet/sheet-description.svelte.d.ts +4 -0
  153. package/dist/components/ui/sheet/sheet-footer.svelte +20 -0
  154. package/dist/components/ui/sheet/sheet-footer.svelte.d.ts +5 -0
  155. package/dist/components/ui/sheet/sheet-header.svelte +20 -0
  156. package/dist/components/ui/sheet/sheet-header.svelte.d.ts +5 -0
  157. package/dist/components/ui/sheet/sheet-overlay.svelte +20 -0
  158. package/dist/components/ui/sheet/sheet-overlay.svelte.d.ts +4 -0
  159. package/dist/components/ui/sheet/sheet-portal.svelte +7 -0
  160. package/dist/components/ui/sheet/sheet-portal.svelte.d.ts +3 -0
  161. package/dist/components/ui/sheet/sheet-title.svelte +13 -0
  162. package/dist/components/ui/sheet/sheet-title.svelte.d.ts +4 -0
  163. package/dist/components/ui/sheet/sheet-trigger.svelte +7 -0
  164. package/dist/components/ui/sheet/sheet-trigger.svelte.d.ts +4 -0
  165. package/dist/components/ui/sheet/sheet.svelte +7 -0
  166. package/dist/components/ui/sheet/sheet.svelte.d.ts +3 -0
  167. package/dist/components/ui/switch/index.d.ts +2 -0
  168. package/dist/components/ui/switch/index.js +4 -0
  169. package/dist/components/ui/switch/switch.svelte +28 -0
  170. package/dist/components/ui/switch/switch.svelte.d.ts +8 -0
  171. package/dist/components/ui/tabs/index.d.ts +5 -0
  172. package/dist/components/ui/tabs/index.js +7 -0
  173. package/dist/components/ui/tabs/tabs-content.svelte +17 -0
  174. package/dist/components/ui/tabs/tabs-content.svelte.d.ts +4 -0
  175. package/dist/components/ui/tabs/tabs-list.svelte +16 -0
  176. package/dist/components/ui/tabs/tabs-list.svelte.d.ts +4 -0
  177. package/dist/components/ui/tabs/tabs-trigger.svelte +20 -0
  178. package/dist/components/ui/tabs/tabs-trigger.svelte.d.ts +4 -0
  179. package/dist/components/ui/tabs/tabs.svelte +19 -0
  180. package/dist/components/ui/tabs/tabs.svelte.d.ts +4 -0
  181. package/dist/components/ui/tooltip/index.d.ts +6 -0
  182. package/dist/components/ui/tooltip/index.js +8 -0
  183. package/dist/components/ui/tooltip/tooltip-content.svelte +52 -0
  184. package/dist/components/ui/tooltip/tooltip-content.svelte.d.ts +11 -0
  185. package/dist/components/ui/tooltip/tooltip-portal.svelte +7 -0
  186. package/dist/components/ui/tooltip/tooltip-portal.svelte.d.ts +4 -0
  187. package/dist/components/ui/tooltip/tooltip-provider.svelte +7 -0
  188. package/dist/components/ui/tooltip/tooltip-provider.svelte.d.ts +4 -0
  189. package/dist/components/ui/tooltip/tooltip-trigger.svelte +7 -0
  190. package/dist/components/ui/tooltip/tooltip-trigger.svelte.d.ts +4 -0
  191. package/dist/components/ui/tooltip/tooltip.svelte +7 -0
  192. package/dist/components/ui/tooltip/tooltip.svelte.d.ts +4 -0
  193. package/dist/components/viewers/ArchiveViewer.svelte +586 -0
  194. package/dist/components/viewers/ArchiveViewer.svelte.d.ts +7 -0
  195. package/dist/components/viewers/CLAUDE.md +60 -0
  196. package/dist/components/viewers/CodeViewer.svelte +553 -0
  197. package/dist/components/viewers/CodeViewer.svelte.d.ts +7 -0
  198. package/dist/components/viewers/CogViewer.svelte +1345 -0
  199. package/dist/components/viewers/CogViewer.svelte.d.ts +7 -0
  200. package/dist/components/viewers/CopcViewer.svelte +25 -0
  201. package/dist/components/viewers/CopcViewer.svelte.d.ts +7 -0
  202. package/dist/components/viewers/DatabaseViewer.svelte +169 -0
  203. package/dist/components/viewers/DatabaseViewer.svelte.d.ts +7 -0
  204. package/dist/components/viewers/FileInfo.svelte +174 -0
  205. package/dist/components/viewers/FileInfo.svelte.d.ts +10 -0
  206. package/dist/components/viewers/FlatGeobufViewer.svelte +755 -0
  207. package/dist/components/viewers/FlatGeobufViewer.svelte.d.ts +7 -0
  208. package/dist/components/viewers/GeoParquetMapViewer.svelte +278 -0
  209. package/dist/components/viewers/GeoParquetMapViewer.svelte.d.ts +17 -0
  210. package/dist/components/viewers/ImageViewer.svelte +233 -0
  211. package/dist/components/viewers/ImageViewer.svelte.d.ts +7 -0
  212. package/dist/components/viewers/LoadProgress.svelte +93 -0
  213. package/dist/components/viewers/LoadProgress.svelte.d.ts +15 -0
  214. package/dist/components/viewers/MapViewer.svelte +234 -0
  215. package/dist/components/viewers/MapViewer.svelte.d.ts +7 -0
  216. package/dist/components/viewers/MarkdownViewer.svelte +478 -0
  217. package/dist/components/viewers/MarkdownViewer.svelte.d.ts +7 -0
  218. package/dist/components/viewers/MediaViewer.svelte +121 -0
  219. package/dist/components/viewers/MediaViewer.svelte.d.ts +7 -0
  220. package/dist/components/viewers/ModelViewer.svelte +164 -0
  221. package/dist/components/viewers/ModelViewer.svelte.d.ts +7 -0
  222. package/dist/components/viewers/NotebookViewer.svelte +389 -0
  223. package/dist/components/viewers/NotebookViewer.svelte.d.ts +7 -0
  224. package/dist/components/viewers/PdfViewer.svelte +278 -0
  225. package/dist/components/viewers/PdfViewer.svelte.d.ts +7 -0
  226. package/dist/components/viewers/PmtilesViewer.svelte +191 -0
  227. package/dist/components/viewers/PmtilesViewer.svelte.d.ts +7 -0
  228. package/dist/components/viewers/QueryHistoryPanel.svelte +159 -0
  229. package/dist/components/viewers/QueryHistoryPanel.svelte.d.ts +8 -0
  230. package/dist/components/viewers/RawViewer.svelte +117 -0
  231. package/dist/components/viewers/RawViewer.svelte.d.ts +7 -0
  232. package/dist/components/viewers/StacMapViewer.svelte +20 -0
  233. package/dist/components/viewers/StacMapViewer.svelte.d.ts +7 -0
  234. package/dist/components/viewers/StyleEditorOverlay.svelte +27 -0
  235. package/dist/components/viewers/StyleEditorOverlay.svelte.d.ts +7 -0
  236. package/dist/components/viewers/TableGrid.svelte +355 -0
  237. package/dist/components/viewers/TableGrid.svelte.d.ts +12 -0
  238. package/dist/components/viewers/TableStatusBar.svelte +92 -0
  239. package/dist/components/viewers/TableStatusBar.svelte.d.ts +11 -0
  240. package/dist/components/viewers/TableToolbar.svelte +382 -0
  241. package/dist/components/viewers/TableToolbar.svelte.d.ts +25 -0
  242. package/dist/components/viewers/TableViewer.svelte +923 -0
  243. package/dist/components/viewers/TableViewer.svelte.d.ts +7 -0
  244. package/dist/components/viewers/ViewerRouter.svelte +70 -0
  245. package/dist/components/viewers/ViewerRouter.svelte.d.ts +7 -0
  246. package/dist/components/viewers/ZarrMapViewer.svelte +288 -0
  247. package/dist/components/viewers/ZarrMapViewer.svelte.d.ts +17 -0
  248. package/dist/components/viewers/ZarrViewer.svelte +256 -0
  249. package/dist/components/viewers/ZarrViewer.svelte.d.ts +7 -0
  250. package/dist/components/viewers/map/AttributeTable.svelte +52 -0
  251. package/dist/components/viewers/map/AttributeTable.svelte.d.ts +8 -0
  252. package/dist/components/viewers/map/MapContainer.svelte +158 -0
  253. package/dist/components/viewers/map/MapContainer.svelte.d.ts +12 -0
  254. package/dist/components/viewers/pmtiles/PmtilesArchiveView.svelte +389 -0
  255. package/dist/components/viewers/pmtiles/PmtilesArchiveView.svelte.d.ts +10 -0
  256. package/dist/components/viewers/pmtiles/PmtilesMapView.svelte +332 -0
  257. package/dist/components/viewers/pmtiles/PmtilesMapView.svelte.d.ts +11 -0
  258. package/dist/components/viewers/pmtiles/PmtilesTileInspector.svelte +373 -0
  259. package/dist/components/viewers/pmtiles/PmtilesTileInspector.svelte.d.ts +12 -0
  260. package/dist/components/viewers/pmtiles/SvgTileRenderer.svelte +112 -0
  261. package/dist/components/viewers/pmtiles/SvgTileRenderer.svelte.d.ts +10 -0
  262. package/dist/file-icons/CLAUDE.md +21 -0
  263. package/dist/file-icons/FileTypeIcon.svelte +74 -0
  264. package/dist/file-icons/FileTypeIcon.svelte.d.ts +9 -0
  265. package/dist/file-icons/index.d.ts +56 -0
  266. package/dist/file-icons/index.js +1070 -0
  267. package/dist/i18n/CLAUDE.md +19 -0
  268. package/dist/i18n/ar.d.ts +1 -0
  269. package/dist/i18n/ar.js +404 -0
  270. package/dist/i18n/en.d.ts +1 -0
  271. package/dist/i18n/en.js +404 -0
  272. package/dist/i18n/index.svelte.d.ts +9 -0
  273. package/dist/i18n/index.svelte.js +27 -0
  274. package/dist/index.d.ts +20 -0
  275. package/dist/index.js +13 -0
  276. package/dist/query/CLAUDE.md +22 -0
  277. package/dist/query/engine.d.ts +56 -0
  278. package/dist/query/engine.js +6 -0
  279. package/dist/query/index.d.ts +4 -0
  280. package/dist/query/index.js +19 -0
  281. package/dist/query/wasm.d.ts +20 -0
  282. package/dist/query/wasm.js +890 -0
  283. package/dist/storage/CLAUDE.md +23 -0
  284. package/dist/storage/adapter.d.ts +21 -0
  285. package/dist/storage/adapter.js +1 -0
  286. package/dist/storage/browser-azure.d.ts +25 -0
  287. package/dist/storage/browser-azure.js +271 -0
  288. package/dist/storage/browser-cloud.d.ts +32 -0
  289. package/dist/storage/browser-cloud.js +293 -0
  290. package/dist/storage/index.d.ts +11 -0
  291. package/dist/storage/index.js +37 -0
  292. package/dist/storage/url-adapter.d.ts +19 -0
  293. package/dist/storage/url-adapter.js +51 -0
  294. package/dist/stores/CLAUDE.md +29 -0
  295. package/dist/stores/browser.svelte.d.ts +28 -0
  296. package/dist/stores/browser.svelte.js +160 -0
  297. package/dist/stores/connections.svelte.d.ts +56 -0
  298. package/dist/stores/connections.svelte.js +272 -0
  299. package/dist/stores/credentials.svelte.d.ts +56 -0
  300. package/dist/stores/credentials.svelte.js +79 -0
  301. package/dist/stores/files.svelte.d.ts +20 -0
  302. package/dist/stores/files.svelte.js +76 -0
  303. package/dist/stores/query-history.svelte.d.ts +16 -0
  304. package/dist/stores/query-history.svelte.js +57 -0
  305. package/dist/stores/safelock.svelte.d.ts +8 -0
  306. package/dist/stores/safelock.svelte.js +52 -0
  307. package/dist/stores/settings.svelte.d.ts +11 -0
  308. package/dist/stores/settings.svelte.js +101 -0
  309. package/dist/stores/tab-resources.svelte.d.ts +25 -0
  310. package/dist/stores/tab-resources.svelte.js +61 -0
  311. package/dist/stores/tabs.svelte.d.ts +17 -0
  312. package/dist/stores/tabs.svelte.js +110 -0
  313. package/dist/types/notebookjs.d.ts +14 -0
  314. package/dist/types.d.ts +47 -0
  315. package/dist/types.js +1 -0
  316. package/dist/utils/CLAUDE.md +54 -0
  317. package/dist/utils/analytics.d.ts +10 -0
  318. package/dist/utils/analytics.js +38 -0
  319. package/dist/utils/archive.d.ts +70 -0
  320. package/dist/utils/archive.js +333 -0
  321. package/dist/utils/column-types.d.ts +5 -0
  322. package/dist/utils/column-types.js +137 -0
  323. package/dist/utils/deck.d.ts +98 -0
  324. package/dist/utils/deck.js +208 -0
  325. package/dist/utils/evidence-context.d.ts +22 -0
  326. package/dist/utils/evidence-context.js +56 -0
  327. package/dist/utils/export.d.ts +2 -0
  328. package/dist/utils/export.js +51 -0
  329. package/dist/utils/format.d.ts +14 -0
  330. package/dist/utils/format.js +56 -0
  331. package/dist/utils/geoarrow.d.ts +32 -0
  332. package/dist/utils/geoarrow.js +672 -0
  333. package/dist/utils/hex.d.ts +10 -0
  334. package/dist/utils/hex.js +27 -0
  335. package/dist/utils/host-detection.d.ts +23 -0
  336. package/dist/utils/host-detection.js +289 -0
  337. package/dist/utils/map-selection.d.ts +12 -0
  338. package/dist/utils/map-selection.js +45 -0
  339. package/dist/utils/markdown-sql.d.ts +30 -0
  340. package/dist/utils/markdown-sql.js +73 -0
  341. package/dist/utils/markdown.d.ts +18 -0
  342. package/dist/utils/markdown.js +146 -0
  343. package/dist/utils/model3d.d.ts +13 -0
  344. package/dist/utils/model3d.js +62 -0
  345. package/dist/utils/parquet-metadata.d.ts +58 -0
  346. package/dist/utils/parquet-metadata.js +228 -0
  347. package/dist/utils/pdf.d.ts +8 -0
  348. package/dist/utils/pdf.js +28 -0
  349. package/dist/utils/pmtiles-tile.d.ts +38 -0
  350. package/dist/utils/pmtiles-tile.js +64 -0
  351. package/dist/utils/pmtiles.d.ts +46 -0
  352. package/dist/utils/pmtiles.js +135 -0
  353. package/dist/utils/shiki.d.ts +8 -0
  354. package/dist/utils/shiki.js +98 -0
  355. package/dist/utils/storage-url.d.ts +64 -0
  356. package/dist/utils/storage-url.js +374 -0
  357. package/dist/utils/url-state.d.ts +40 -0
  358. package/dist/utils/url-state.js +113 -0
  359. package/dist/utils/url.d.ts +27 -0
  360. package/dist/utils/url.js +115 -0
  361. package/dist/utils/wkb.d.ts +43 -0
  362. package/dist/utils/wkb.js +345 -0
  363. package/dist/utils/zarr.d.ts +39 -0
  364. package/dist/utils/zarr.js +204 -0
  365. package/dist/utils.d.ts +12 -0
  366. package/dist/utils.js +5 -0
  367. package/package.json +203 -0
@@ -0,0 +1,7 @@
1
+ import type { Tab } from '../../types';
2
+ type $$ComponentProps = {
3
+ tab: Tab;
4
+ };
5
+ declare const FlatGeobufViewer: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type FlatGeobufViewer = ReturnType<typeof FlatGeobufViewer>;
7
+ export default FlatGeobufViewer;
@@ -0,0 +1,278 @@
1
+ <script lang="ts">
2
+ import LocateIcon from '@lucide/svelte/icons/locate';
3
+ import type maplibregl from 'maplibre-gl';
4
+ import { onDestroy } from 'svelte';
5
+ import { t } from '../../i18n/index.svelte.js';
6
+ import type { MapQueryResult, SchemaField } from '../../query/engine';
7
+ import { settings } from '../../stores/settings.svelte.js';
8
+ import { tabResources } from '../../stores/tab-resources.svelte.js';
9
+ import type { Tab } from '../../types';
10
+ import {
11
+ buildSelectionLayer,
12
+ createGeoArrowLayers,
13
+ createGeoArrowOverlay,
14
+ hoverCursor,
15
+ loadGeoArrowModules
16
+ } from '../../utils/deck.js';
17
+ import {
18
+ buildGeoArrowTables,
19
+ type GeoArrowGeomType,
20
+ type GeoArrowResult
21
+ } from '../../utils/geoarrow.js';
22
+ import { parseWKB } from '../../utils/wkb.js';
23
+ import LoadProgress, { type ProgressEntry } from './LoadProgress.svelte';
24
+ import AttributeTable from './map/AttributeTable.svelte';
25
+ import MapContainer from './map/MapContainer.svelte';
26
+
27
+ let {
28
+ tab,
29
+ schema,
30
+ mapData = null,
31
+ sourceCrs = null,
32
+ knownGeomType = undefined,
33
+ metadataBounds = null,
34
+ isCustomQuery = false,
35
+ progressEntries = []
36
+ }: {
37
+ tab: Tab;
38
+ schema: SchemaField[];
39
+ mapData?: MapQueryResult | null;
40
+ sourceCrs?: string | null;
41
+ knownGeomType?: GeoArrowGeomType;
42
+ metadataBounds?: [number, number, number, number] | null;
43
+ isCustomQuery?: boolean;
44
+ progressEntries?: ProgressEntry[];
45
+ } = $props();
46
+
47
+ let loading = $state(true);
48
+ let error = $state<string | null>(null);
49
+ let featureCount = $state(0);
50
+ let selectedFeature = $state<Record<string, any> | null>(null);
51
+ let showAttributes = $state(false);
52
+ let bounds = $state<[number, number, number, number] | undefined>();
53
+
54
+ let firstFeatureCoord = $state<[number, number] | null>(null);
55
+
56
+ let loadGen = 0;
57
+
58
+ let geoArrowState: {
59
+ modules: Record<string, any>;
60
+ geoArrowResults: GeoArrowResult[];
61
+ } | null = null;
62
+ let overlayRef: any = null;
63
+ let dataLayersRef: any[] = [];
64
+ let mapRef: maplibregl.Map | null = null;
65
+ let wkbArraysRef: Uint8Array[] = [];
66
+
67
+ /** Drill into nested coordinate arrays to find the first [lng, lat] pair. */
68
+ function extractFirstCoord(coords: any): [number, number] | null {
69
+ if (!Array.isArray(coords) || coords.length === 0) return null;
70
+ if (typeof coords[0] === 'number') return [coords[0] as number, coords[1] as number];
71
+ return extractFirstCoord(coords[0]);
72
+ }
73
+
74
+ function flyToFirstFeature() {
75
+ if (!mapRef || !firstFeatureCoord) return;
76
+ mapRef.flyTo({ center: firstFeatureCoord, zoom: 14 });
77
+ }
78
+
79
+ // mapData is read synchronously in loadGeoData (before any await),
80
+ // so Svelte 5 tracks it as a dependency. The effect re-fires when
81
+ // mapData changes — on initial load, pagination, sort, page size change.
82
+ $effect(() => {
83
+ if (!tab || schema.length === 0) return;
84
+ loadGeoData();
85
+ });
86
+
87
+ function cleanup() {
88
+ if (overlayRef && mapRef) {
89
+ try {
90
+ mapRef.removeControl(overlayRef);
91
+ } catch {
92
+ /* already removed */
93
+ }
94
+ }
95
+ overlayRef = null;
96
+ mapRef = null;
97
+ geoArrowState = null;
98
+ wkbArraysRef = [];
99
+ }
100
+
101
+ $effect(() => {
102
+ const id = tab.id;
103
+ const unregister = tabResources.register(id, cleanup);
104
+ return unregister;
105
+ });
106
+ onDestroy(cleanup);
107
+
108
+ async function loadGeoData() {
109
+ const gen = ++loadGen;
110
+ error = null;
111
+
112
+ // Always use preloaded map data from TableViewer's unified query.
113
+ // No independent fetch — avoids duplicate DuckDB queries.
114
+ // The $effect re-fires when mapData changes (tracked read below).
115
+ if (!mapData || mapData.rowCount === 0) {
116
+ loading = true;
117
+ return; // Wait — effect will re-fire when mapData arrives
118
+ }
119
+
120
+ try {
121
+ const result = mapData;
122
+
123
+ const modules = await loadGeoArrowModules();
124
+ if (gen !== loadGen) return;
125
+
126
+ // Keep WKB ref for selection highlight (no copy — same typed arrays)
127
+ wkbArraysRef = result.wkbArrays;
128
+
129
+ // Convert WKB → GeoArrow Arrow Tables (zero-copy direct binary read)
130
+ // Skip knownGeomType for custom queries — the user's SQL may return
131
+ // different geometry types or join different tables.
132
+ const effectiveGeomType = isCustomQuery ? undefined : knownGeomType;
133
+ const geoArrowResults = buildGeoArrowTables(
134
+ result.wkbArrays,
135
+ result.attributes,
136
+ effectiveGeomType
137
+ );
138
+
139
+ if (geoArrowResults.length === 0) {
140
+ console.warn('[GeoMap] Empty geoArrow results:', {
141
+ wkbCount: result.wkbArrays.length,
142
+ effectiveGeomType,
143
+ gen
144
+ });
145
+ error = t('map.noData');
146
+ loading = false;
147
+ return;
148
+ }
149
+
150
+ geoArrowState = { modules, geoArrowResults };
151
+ featureCount = geoArrowResults.reduce((sum, r) => sum + r.table.numRows, 0);
152
+ // Use metadata bounds if available (no client-side computation needed)
153
+ bounds = metadataBounds ?? geoArrowResults[0].bounds;
154
+
155
+ // Extract first feature coordinate for fly-to
156
+ if (result.wkbArrays.length > 0) {
157
+ const parsed = parseWKB(result.wkbArrays[0]);
158
+ if (parsed) firstFeatureCoord = extractFirstCoord(parsed.coordinates);
159
+ }
160
+
161
+ // If map is already alive, update overlay in-place (no remount)
162
+ if (overlayRef && mapRef) {
163
+ const newLayers = createGeoArrowLayers(modules, {
164
+ layerId: 'geoarrow-data',
165
+ geoArrowResults,
166
+ onHover: hoverCursor(mapRef),
167
+ onClick: handleFeatureClick
168
+ });
169
+ dataLayersRef = newLayers;
170
+ overlayRef.setProps({ layers: newLayers });
171
+ }
172
+
173
+ loading = false;
174
+ } catch (err) {
175
+ if (gen !== loadGen) return;
176
+ error = err instanceof Error ? err.message : String(err);
177
+ loading = false;
178
+ }
179
+ }
180
+
181
+ function handleFeatureClick(props: Record<string, any>, sourceIndex: number) {
182
+ selectedFeature = props;
183
+ showAttributes = true;
184
+ // Reconstruct GeoJSON Feature from WKB for selection highlight
185
+ if (!geoArrowState || !overlayRef) return;
186
+ const GeoJsonLayer = geoArrowState.modules.GeoJsonLayer;
187
+ const wkb = wkbArraysRef[sourceIndex];
188
+ if (wkb) {
189
+ const geom = parseWKB(wkb);
190
+ if (geom) {
191
+ const selLayer = buildSelectionLayer(GeoJsonLayer, {
192
+ type: 'Feature',
193
+ geometry: geom as GeoJSON.Geometry,
194
+ properties: {}
195
+ });
196
+ if (selLayer) {
197
+ overlayRef.setProps({ layers: [...dataLayersRef, selLayer] });
198
+ }
199
+ }
200
+ }
201
+ }
202
+
203
+ function onMapReady(map: maplibregl.Map) {
204
+ if (!geoArrowState) return;
205
+ mapRef = map;
206
+
207
+ const { modules, geoArrowResults } = geoArrowState;
208
+
209
+ const { overlay, layers: dataLayers } = createGeoArrowOverlay(modules, {
210
+ layerId: 'geoarrow-data',
211
+ geoArrowResults,
212
+ onHover: hoverCursor(map),
213
+ onClick: handleFeatureClick
214
+ });
215
+
216
+ dataLayersRef = dataLayers;
217
+ overlayRef = overlay;
218
+
219
+ map.addControl(overlay as any);
220
+ }
221
+ </script>
222
+
223
+ <div class="relative flex h-full overflow-hidden">
224
+ {#if loading}
225
+ <LoadProgress stage={t('map.loadingGeometry')} entries={progressEntries} />
226
+ {:else if error}
227
+ <div class="flex flex-1 items-center justify-center">
228
+ <p class="text-sm text-red-400">{error}</p>
229
+ </div>
230
+ {:else}
231
+ <div class="flex-1">
232
+ <MapContainer {onMapReady} {bounds} />
233
+ </div>
234
+
235
+ <!-- Floating feature count badge + fly-to -->
236
+ {#if featureCount > 0}
237
+ <div
238
+ class="absolute left-2 top-2 z-10 flex items-center gap-1"
239
+ >
240
+ <div
241
+ class="pointer-events-none rounded bg-card/80 px-2 py-1 text-xs text-card-foreground backdrop-blur-sm"
242
+ >
243
+ {featureCount.toLocaleString()} features{#if !isCustomQuery && featureCount >= settings.featureLimit}
244
+ <span class="text-amber-300">(limit)</span>{/if}
245
+ </div>
246
+ {#if firstFeatureCoord}
247
+ <button
248
+ class="rounded bg-card/80 p-1.5 text-card-foreground backdrop-blur-sm hover:bg-card"
249
+ onclick={flyToFirstFeature}
250
+ title={t('map.flyToFirst')}
251
+ >
252
+ <LocateIcon class="size-3.5" />
253
+ </button>
254
+ {/if}
255
+ </div>
256
+ {/if}
257
+
258
+ <!-- Floating button group -->
259
+ {#if selectedFeature}
260
+ <div class="absolute right-2 top-2 z-10 flex gap-1">
261
+ <button
262
+ class="rounded bg-card/80 px-2 py-1 text-xs text-card-foreground backdrop-blur-sm hover:bg-card"
263
+ class:ring-1={showAttributes}
264
+ class:ring-primary={showAttributes}
265
+ onclick={() => (showAttributes = !showAttributes)}
266
+ >
267
+ {t('map.attributes')}
268
+ </button>
269
+ </div>
270
+ {/if}
271
+
272
+ <AttributeTable
273
+ feature={selectedFeature}
274
+ visible={showAttributes}
275
+ onClose={() => (showAttributes = false)}
276
+ />
277
+ {/if}
278
+ </div>
@@ -0,0 +1,17 @@
1
+ import type { MapQueryResult, SchemaField } from '../../query/engine';
2
+ import type { Tab } from '../../types';
3
+ import { type GeoArrowGeomType } from '../../utils/geoarrow.js';
4
+ import { type ProgressEntry } from './LoadProgress.svelte';
5
+ type $$ComponentProps = {
6
+ tab: Tab;
7
+ schema: SchemaField[];
8
+ mapData?: MapQueryResult | null;
9
+ sourceCrs?: string | null;
10
+ knownGeomType?: GeoArrowGeomType;
11
+ metadataBounds?: [number, number, number, number] | null;
12
+ isCustomQuery?: boolean;
13
+ progressEntries?: ProgressEntry[];
14
+ };
15
+ declare const GeoParquetMapViewer: import("svelte").Component<$$ComponentProps, {}, "">;
16
+ type GeoParquetMapViewer = ReturnType<typeof GeoParquetMapViewer>;
17
+ export default GeoParquetMapViewer;
@@ -0,0 +1,233 @@
1
+ <script lang="ts">
2
+ import EllipsisVerticalIcon from '@lucide/svelte/icons/ellipsis-vertical';
3
+ import MaximizeIcon from '@lucide/svelte/icons/maximize';
4
+ import MinusIcon from '@lucide/svelte/icons/minus';
5
+ import PlusIcon from '@lucide/svelte/icons/plus';
6
+ import RotateCwIcon from '@lucide/svelte/icons/rotate-cw';
7
+ import ScanIcon from '@lucide/svelte/icons/scan';
8
+ import { onDestroy } from 'svelte';
9
+ import { Badge } from '../ui/badge/index.js';
10
+ import { Button } from '../ui/button/index.js';
11
+ import * as DropdownMenu from '../ui/dropdown-menu/index.js';
12
+ import { t } from '../../i18n/index.svelte.js';
13
+ import { getAdapter } from '../../storage/index.js';
14
+ import { tabResources } from '../../stores/tab-resources.svelte.js';
15
+ import type { Tab } from '../../types';
16
+ import { buildHttpsUrl, canStreamDirectly } from '../../utils/url.js';
17
+
18
+ const mimeMap: Record<string, string> = {
19
+ png: 'image/png',
20
+ jpg: 'image/jpeg',
21
+ jpeg: 'image/jpeg',
22
+ gif: 'image/gif',
23
+ webp: 'image/webp',
24
+ avif: 'image/avif',
25
+ svg: 'image/svg+xml',
26
+ bmp: 'image/bmp',
27
+ ico: 'image/x-icon'
28
+ };
29
+
30
+ let { tab }: { tab: Tab } = $props();
31
+
32
+ let abortController: AbortController | null = null;
33
+ let imgSrc = $state<string | null>(null);
34
+ let blobUrl = $state<string | null>(null);
35
+ let loading = $state(true);
36
+ let error = $state<string | null>(null);
37
+ let scale = $state(1);
38
+ let rotation = $state(0);
39
+ let panX = $state(0);
40
+ let panY = $state(0);
41
+ let dragging = $state(false);
42
+ let lastX = 0;
43
+ let lastY = 0;
44
+ let wrapperEl: HTMLDivElement | undefined = $state();
45
+
46
+ $effect(() => {
47
+ if (!tab) return;
48
+ loadImage();
49
+ });
50
+
51
+ async function loadImage() {
52
+ loading = true;
53
+ error = null;
54
+ cleanup();
55
+ abortController = new AbortController();
56
+ const { signal } = abortController;
57
+ resetView();
58
+
59
+ try {
60
+ if (canStreamDirectly(tab)) {
61
+ // Direct URL — browser streams natively (no CORS needed for <img>)
62
+ imgSrc = buildHttpsUrl(tab);
63
+ } else {
64
+ // Authenticated S3 — download via storage adapter
65
+ const adapter = getAdapter(tab.source, tab.connectionId);
66
+ const data = await adapter.read(tab.path, undefined, undefined, signal);
67
+ const ext = tab.extension.toLowerCase();
68
+ const blob = new Blob([data as unknown as BlobPart], {
69
+ type: mimeMap[ext] || 'application/octet-stream'
70
+ });
71
+ blobUrl = URL.createObjectURL(blob);
72
+ imgSrc = blobUrl;
73
+ }
74
+ } catch (err) {
75
+ if (err instanceof DOMException && err.name === 'AbortError') return;
76
+ error = err instanceof Error ? err.message : String(err);
77
+ } finally {
78
+ loading = false;
79
+ }
80
+ }
81
+
82
+ function resetView() {
83
+ scale = 1;
84
+ rotation = 0;
85
+ panX = 0;
86
+ panY = 0;
87
+ }
88
+
89
+ function zoomIn() {
90
+ scale = Math.min(scale * 1.4, 20);
91
+ }
92
+
93
+ function zoomOut() {
94
+ scale = Math.max(scale / 1.4, 0.1);
95
+ }
96
+
97
+ function fitView() {
98
+ resetView();
99
+ }
100
+
101
+ function rotate() {
102
+ rotation = (rotation + 90) % 360;
103
+ }
104
+
105
+ function fullscreen() {
106
+ wrapperEl?.requestFullscreen?.();
107
+ }
108
+
109
+ function handleWheel(e: WheelEvent) {
110
+ e.preventDefault();
111
+ const factor = e.deltaY > 0 ? 0.9 : 1.1;
112
+ scale = Math.max(0.1, Math.min(20, scale * factor));
113
+ }
114
+
115
+ function handlePointerDown(e: PointerEvent) {
116
+ if (e.button !== 0) return;
117
+ dragging = true;
118
+ lastX = e.clientX;
119
+ lastY = e.clientY;
120
+ (e.currentTarget as HTMLElement).setPointerCapture(e.pointerId);
121
+ }
122
+
123
+ function handlePointerMove(e: PointerEvent) {
124
+ if (!dragging) return;
125
+ panX += e.clientX - lastX;
126
+ panY += e.clientY - lastY;
127
+ lastX = e.clientX;
128
+ lastY = e.clientY;
129
+ }
130
+
131
+ function handlePointerUp() {
132
+ dragging = false;
133
+ }
134
+
135
+ function handleDblClick() {
136
+ if (scale !== 1 || panX !== 0 || panY !== 0) {
137
+ resetView();
138
+ } else {
139
+ scale = 2;
140
+ }
141
+ }
142
+
143
+ function cleanup() {
144
+ abortController?.abort();
145
+ abortController = null;
146
+ if (blobUrl) {
147
+ URL.revokeObjectURL(blobUrl);
148
+ blobUrl = null;
149
+ }
150
+ imgSrc = null;
151
+ }
152
+
153
+ $effect(() => {
154
+ const id = tab.id;
155
+ const unregister = tabResources.register(id, cleanup);
156
+ return unregister;
157
+ });
158
+ onDestroy(cleanup);
159
+ </script>
160
+
161
+ <div class="flex h-full flex-col">
162
+ <div
163
+ 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"
164
+ >
165
+ <span class="truncate max-w-[120px] text-sm font-medium text-zinc-700 sm:max-w-none dark:text-zinc-300">{tab.name}</span>
166
+ <Badge variant="secondary">{tab.extension.toUpperCase()}</Badge>
167
+
168
+ <div class="ms-auto flex items-center gap-1">
169
+ <!-- Desktop controls -->
170
+ <div class="hidden items-center gap-1 sm:flex">
171
+ <Button variant="ghost" size="sm" class="h-7 px-1.5" onclick={zoomIn} title={t('image.zoomIn')}>
172
+ <PlusIcon class="size-3.5" />
173
+ </Button>
174
+ <Button variant="ghost" size="sm" class="h-7 px-1.5" onclick={zoomOut} title={t('image.zoomOut')}>
175
+ <MinusIcon class="size-3.5" />
176
+ </Button>
177
+ <Button variant="ghost" size="sm" class="h-7 px-1.5" onclick={fitView} title={t('image.fit')}>
178
+ <ScanIcon class="size-3.5" />
179
+ </Button>
180
+ <Button variant="ghost" size="sm" class="h-7 px-1.5" onclick={rotate} title={t('image.rotate')}>
181
+ <RotateCwIcon class="size-3.5" />
182
+ </Button>
183
+ <Button variant="ghost" size="sm" class="h-7 px-1.5" onclick={fullscreen} title={t('image.fullscreen')}>
184
+ <MaximizeIcon class="size-3.5" />
185
+ </Button>
186
+ </div>
187
+
188
+ <!-- Mobile overflow menu -->
189
+ <div class="flex sm:hidden">
190
+ <DropdownMenu.Root>
191
+ <DropdownMenu.Trigger class="rounded p-1 text-zinc-400 hover:bg-zinc-100 dark:hover:bg-zinc-800">
192
+ <EllipsisVerticalIcon class="size-4" />
193
+ </DropdownMenu.Trigger>
194
+ <DropdownMenu.Content align="end" class="w-40">
195
+ <DropdownMenu.Item onclick={zoomIn}>{t('image.zoomIn')}</DropdownMenu.Item>
196
+ <DropdownMenu.Item onclick={zoomOut}>{t('image.zoomOut')}</DropdownMenu.Item>
197
+ <DropdownMenu.Item onclick={fitView}>{t('image.fit')}</DropdownMenu.Item>
198
+ <DropdownMenu.Item onclick={rotate}>{t('image.rotate')}</DropdownMenu.Item>
199
+ <DropdownMenu.Item onclick={fullscreen}>{t('image.fullscreen')}</DropdownMenu.Item>
200
+ </DropdownMenu.Content>
201
+ </DropdownMenu.Root>
202
+ </div>
203
+ </div>
204
+ </div>
205
+
206
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
207
+ <div
208
+ bind:this={wrapperEl}
209
+ class="relative flex flex-1 items-center justify-center overflow-hidden bg-zinc-100 dark:bg-zinc-900"
210
+ class:cursor-grab={scale > 1 && !dragging}
211
+ class:cursor-grabbing={dragging}
212
+ onwheel={handleWheel}
213
+ ondblclick={handleDblClick}
214
+ >
215
+ {#if loading}
216
+ <p class="text-sm text-zinc-400">{t('image.loading')}</p>
217
+ {:else if error}
218
+ <p class="text-sm text-red-400">{error}</p>
219
+ {:else if imgSrc}
220
+ <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
221
+ <img
222
+ src={imgSrc}
223
+ alt={tab.name}
224
+ class="max-h-full max-w-full select-none"
225
+ style="transform: translate({panX}px, {panY}px) scale({scale}) rotate({rotation}deg); transition: {dragging ? 'none' : 'transform 0.15s ease-out'};"
226
+ draggable="false"
227
+ onpointerdown={handlePointerDown}
228
+ onpointermove={handlePointerMove}
229
+ onpointerup={handlePointerUp}
230
+ />
231
+ {/if}
232
+ </div>
233
+ </div>
@@ -0,0 +1,7 @@
1
+ import type { Tab } from '../../types';
2
+ type $$ComponentProps = {
3
+ tab: Tab;
4
+ };
5
+ declare const ImageViewer: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type ImageViewer = ReturnType<typeof ImageViewer>;
7
+ export default ImageViewer;
@@ -0,0 +1,93 @@
1
+ <script lang="ts">
2
+ import CheckCircleIcon from '@lucide/svelte/icons/circle-check';
3
+ import Loader2Icon from '@lucide/svelte/icons/loader-2';
4
+ import XCircleIcon from '@lucide/svelte/icons/x-circle';
5
+ import { t } from '../../i18n/index.svelte.js';
6
+
7
+ export type ProgressEntry = {
8
+ label: string;
9
+ value: string;
10
+ detail?: string;
11
+ };
12
+
13
+ let {
14
+ stage = '',
15
+ entries = [],
16
+ onCancel,
17
+ onForceCancel,
18
+ forceCancelVisible = false
19
+ }: {
20
+ stage?: string;
21
+ entries?: ProgressEntry[];
22
+ onCancel?: () => void;
23
+ onForceCancel?: () => void;
24
+ forceCancelVisible?: boolean;
25
+ } = $props();
26
+ </script>
27
+
28
+ <div class="flex flex-1 flex-col items-center justify-center gap-4 px-4">
29
+ <!-- Active step -->
30
+ <div class="flex items-center gap-2 text-center">
31
+ <Loader2Icon class="size-4 shrink-0 animate-spin text-primary" />
32
+ <p class="text-sm text-zinc-500 dark:text-zinc-400">{stage || t('table.loading')}</p>
33
+ </div>
34
+
35
+ <!-- Discovered metadata -->
36
+ {#if entries.length > 0}
37
+ <div
38
+ class="w-full max-w-md rounded-lg border border-zinc-200/60 bg-zinc-50/80 px-3 py-2.5 sm:px-4 sm:py-3 dark:border-zinc-800/60 dark:bg-zinc-900/50"
39
+ >
40
+ <div class="flex flex-col gap-1.5">
41
+ {#each entries as entry}
42
+ <div class="flex items-start gap-1.5 sm:gap-2">
43
+ <CheckCircleIcon class="mt-0.5 size-3 shrink-0 text-green-500/80" />
44
+ <span
45
+ class="w-14 shrink-0 text-[11px] leading-4 text-zinc-400 sm:w-[4.5rem] sm:text-xs dark:text-zinc-500"
46
+ >
47
+ {entry.label}
48
+ </span>
49
+ <div class="min-w-0 flex-1">
50
+ <span class="break-all text-[11px] font-medium leading-4 text-zinc-600 sm:text-xs dark:text-zinc-300">
51
+ {entry.value}
52
+ </span>
53
+ {#if entry.detail}
54
+ <p
55
+ class="mt-0.5 truncate font-mono text-[10px] leading-tight text-zinc-400 dark:text-zinc-500"
56
+ >
57
+ {entry.detail}
58
+ </p>
59
+ {/if}
60
+ </div>
61
+ </div>
62
+ {/each}
63
+ </div>
64
+ </div>
65
+ {/if}
66
+
67
+ <!-- Cancel -->
68
+ {#if onCancel}
69
+ <div class="flex flex-col items-center gap-2">
70
+ <button
71
+ class="flex items-center gap-1 rounded border border-zinc-300 px-3 py-1 text-xs text-zinc-500 hover:bg-zinc-100 dark:border-zinc-700 dark:text-zinc-400 dark:hover:bg-zinc-800"
72
+ onclick={onCancel}
73
+ >
74
+ <XCircleIcon class="size-3" />
75
+ {t('table.cancel')}
76
+ </button>
77
+ {#if forceCancelVisible && onForceCancel}
78
+ <div class="flex flex-col items-center gap-1">
79
+ <button
80
+ class="flex items-center gap-1 rounded border border-red-400 bg-red-50 px-3 py-1 text-xs text-red-600 hover:bg-red-100 dark:border-red-700 dark:bg-red-950 dark:text-red-400 dark:hover:bg-red-900"
81
+ onclick={onForceCancel}
82
+ >
83
+ <XCircleIcon class="size-3" />
84
+ {t('table.forceStop')}
85
+ </button>
86
+ <p class="max-w-xs text-center text-[10px] text-zinc-400 dark:text-zinc-500">
87
+ {t('table.forceStopWarning')}
88
+ </p>
89
+ </div>
90
+ {/if}
91
+ </div>
92
+ {/if}
93
+ </div>
@@ -0,0 +1,15 @@
1
+ export type ProgressEntry = {
2
+ label: string;
3
+ value: string;
4
+ detail?: string;
5
+ };
6
+ type $$ComponentProps = {
7
+ stage?: string;
8
+ entries?: ProgressEntry[];
9
+ onCancel?: () => void;
10
+ onForceCancel?: () => void;
11
+ forceCancelVisible?: boolean;
12
+ };
13
+ declare const LoadProgress: import("svelte").Component<$$ComponentProps, {}, "">;
14
+ type LoadProgress = ReturnType<typeof LoadProgress>;
15
+ export default LoadProgress;