@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,314 @@
1
+ <script lang="ts">
2
+ import CloudIcon from '@lucide/svelte/icons/cloud';
3
+ import DatabaseIcon from '@lucide/svelte/icons/database';
4
+ import GlobeIcon from '@lucide/svelte/icons/globe';
5
+ import PencilIcon from '@lucide/svelte/icons/pencil';
6
+ import PlusIcon from '@lucide/svelte/icons/plus';
7
+ import TrashIcon from '@lucide/svelte/icons/trash-2';
8
+ import {
9
+ ContextMenu,
10
+ ContextMenuContent,
11
+ ContextMenuItem,
12
+ ContextMenuSeparator,
13
+ ContextMenuTrigger
14
+ } from '../ui/context-menu/index.js';
15
+ import { Separator } from '../ui/separator/index.js';
16
+ import {
17
+ Tooltip,
18
+ TooltipContent,
19
+ TooltipProvider,
20
+ TooltipTrigger
21
+ } from '../ui/tooltip/index.js';
22
+ import { t } from '../../i18n/index.svelte.js';
23
+ import { browser } from '../../stores/browser.svelte.js';
24
+ import { connections } from '../../stores/connections.svelte.js';
25
+ import { credentialStore, loadFromNative } from '../../stores/credentials.svelte.js';
26
+ import { tabs } from '../../stores/tabs.svelte.js';
27
+ import type { Connection } from '../../types.js';
28
+ import { type DetectedHost, detectHostBucket } from '../../utils/host-detection.js';
29
+ import { parseStorageUrl } from '../../utils/storage-url.js';
30
+ import { clearUrlState, syncUrlParam } from '../../utils/url-state.js';
31
+ import ConnectionDialog from './ConnectionDialog.svelte';
32
+ import LocaleToggle from './LocaleToggle.svelte';
33
+ import ThemeToggle from './ThemeToggle.svelte';
34
+
35
+ let dialogOpen = $state(false);
36
+ let editingConnection = $state<Connection | null>(null);
37
+ let detectedHost = $state<DetectedHost | null>(null);
38
+ let autoConnecting = $state(false);
39
+
40
+ $effect(() => {
41
+ connections.load().then(async () => {
42
+ await handleAutoDetection();
43
+ // On first visit (no connections, no URL params), load the demo bucket
44
+ if (connections.items.length === 0 && !new URL(window.location.href).searchParams.has('url')) {
45
+ await loadDemoConnection();
46
+ }
47
+ });
48
+ });
49
+
50
+ // Allow other components to request opening the new-connection dialog
51
+ $effect(() => {
52
+ if (connections.dialogRequested) {
53
+ connections.clearDialogRequest();
54
+ handleAddConnection();
55
+ }
56
+ });
57
+
58
+ async function handleAutoDetection() {
59
+ // Direct file URLs (e.g. ?url=https://...file.parquet) are opened eagerly
60
+ // in +page.svelte so they work on mobile. Skip if tab already exists.
61
+ const url = new URL(window.location.href);
62
+ const rawUrl = url.searchParams.get('url');
63
+ if (rawUrl && tabs.items.some((t) => t.id === `url:${rawUrl}`)) {
64
+ return;
65
+ }
66
+
67
+ const detected = detectHostBucket();
68
+ if (!detected) return;
69
+
70
+ const hasUrlParam = url.searchParams.has('url');
71
+
72
+ if (hasUrlParam) {
73
+ // Auto-connect immediately for ?url= param (zero-friction)
74
+ autoConnecting = true;
75
+ try {
76
+ const connId = await connections.saveHostConnection(detected);
77
+ const conn = connections.getById(connId);
78
+ if (!conn) return;
79
+
80
+ if (!(await ensureCredentials(conn))) return;
81
+
82
+ const parsed = parseStorageUrl(url.searchParams.get('url')!);
83
+ const prefixParam = parsed.prefix;
84
+
85
+ if (prefixParam && !prefixParam.endsWith('/')) {
86
+ // It's a file — browse to its parent folder and open it
87
+ const parentPrefix = prefixParam.includes('/') ? prefixParam.replace(/\/[^/]*$/, '/') : '';
88
+ browser.browse(conn, parentPrefix || undefined);
89
+ const fileName = prefixParam.split('/').pop() || prefixParam;
90
+ const ext = fileName.includes('.') ? fileName.split('.').pop()!.toLowerCase() : '';
91
+ const tabId = `${conn.id}:${prefixParam}`;
92
+ tabs.open({
93
+ id: tabId,
94
+ name: fileName,
95
+ path: prefixParam,
96
+ source: 'remote',
97
+ connectionId: conn.id,
98
+ extension: ext
99
+ });
100
+ // Fire-and-forget: fetch file size via HEAD request
101
+ fetch(url.searchParams.get('url')!, { method: 'HEAD' })
102
+ .then((res) => {
103
+ const cl = res.headers.get('content-length');
104
+ if (cl) tabs.update(tabId, { size: Number(cl) });
105
+ })
106
+ .catch(() => {});
107
+ } else if (prefixParam) {
108
+ // It's a directory prefix
109
+ browser.browse(conn, prefixParam);
110
+ } else {
111
+ browser.browse(conn);
112
+ }
113
+ syncUrlParam(conn, prefixParam || undefined);
114
+ } finally {
115
+ autoConnecting = false;
116
+ }
117
+ } else {
118
+ // Show indicator for hostname-detected bucket
119
+ detectedHost = detected;
120
+ }
121
+ }
122
+
123
+ async function loadDemoConnection() {
124
+ const id = await connections.save({
125
+ name: 'Source Cooperative',
126
+ provider: 's3',
127
+ endpoint: '',
128
+ bucket: 'us-west-2.opendata.source.coop',
129
+ region: 'us-west-2',
130
+ anonymous: true
131
+ });
132
+ if (!id) return;
133
+ const conn = connections.getById(id);
134
+ if (conn) {
135
+ browser.browse(conn);
136
+ syncUrlParam(conn);
137
+ }
138
+ }
139
+
140
+ async function handleConnectDetected() {
141
+ if (!detectedHost || autoConnecting) return;
142
+ autoConnecting = true;
143
+ try {
144
+ const connId = await connections.saveHostConnection(detectedHost);
145
+ const conn = connections.getById(connId);
146
+ if (conn) {
147
+ if (!(await ensureCredentials(conn))) return;
148
+ browser.browse(conn);
149
+ syncUrlParam(conn);
150
+ }
151
+ detectedHost = null;
152
+ } finally {
153
+ autoConnecting = false;
154
+ }
155
+ }
156
+
157
+ function handleAddConnection() {
158
+ editingConnection = null;
159
+ dialogOpen = true;
160
+ }
161
+
162
+ function handleEditConnection(connection: Connection) {
163
+ editingConnection = connection;
164
+ dialogOpen = true;
165
+ }
166
+
167
+ async function handleDeleteConnection(connection: Connection) {
168
+ if (!confirm(t('sidebar.deleteConfirm', { name: connection.name }))) return;
169
+ await connections.remove(connection.id);
170
+ if (browser.activeConnection?.id === connection.id) {
171
+ browser.clear();
172
+ clearUrlState();
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Ensure credentials are available for a non-anonymous connection.
178
+ * Tries the browser password manager first, then opens the dialog.
179
+ * Returns true if credentials are ready, false if the dialog was opened.
180
+ */
181
+ async function ensureCredentials(connection: Connection): Promise<boolean> {
182
+ if (connection.anonymous) return true;
183
+ if (credentialStore.has(connection.id)) return true;
184
+
185
+ // Try restoring from browser password manager
186
+ const native = await loadFromNative(connection.id);
187
+ if (native) {
188
+ credentialStore.set(connection.id, native);
189
+ return true;
190
+ }
191
+
192
+ // No credentials — open the dialog so the user can re-enter them
193
+ editingConnection = connection;
194
+ dialogOpen = true;
195
+
196
+ return false;
197
+ }
198
+
199
+ async function handleBrowseConnection(connection: Connection) {
200
+ // Skip if this connection is already being browsed — avoids clearing entries
201
+ // and re-fetching, which causes DOM churn that can close the mobile Sheet.
202
+ if (browser.activeConnection?.id === connection.id) return;
203
+ if (!(await ensureCredentials(connection))) return;
204
+ browser.browse(connection);
205
+ syncUrlParam(connection);
206
+ }
207
+ </script>
208
+
209
+ <TooltipProvider>
210
+ <div class="flex h-full w-12 flex-col items-center bg-sidebar py-2">
211
+ <!-- App icon -->
212
+ <div class="mb-2 flex size-8 items-center justify-center">
213
+ <DatabaseIcon class="size-5 text-sidebar-primary" />
214
+ </div>
215
+
216
+ <Separator class="mx-2 mb-2" />
217
+
218
+ <!-- Connections -->
219
+ <div class="flex flex-1 flex-col items-center gap-1 overflow-auto">
220
+ <!-- Detected host indicator -->
221
+ {#if detectedHost}
222
+ <Tooltip>
223
+ <TooltipTrigger>
224
+ <button
225
+ class="group relative flex size-8 items-center justify-center rounded-lg border border-dashed border-primary/50 text-primary transition-colors hover:bg-primary/10"
226
+ class:animate-pulse={!autoConnecting}
227
+ onclick={handleConnectDetected}
228
+ disabled={autoConnecting}
229
+ >
230
+ <GlobeIcon class="size-4" />
231
+ </button>
232
+ </TooltipTrigger>
233
+ <TooltipContent side="right">
234
+ {t('sidebar.browseDetected', { name: detectedHost.bucket })}
235
+ </TooltipContent>
236
+ </Tooltip>
237
+ {/if}
238
+
239
+ {#each connections.items as connection (connection.id)}
240
+ {@const isActive = browser.activeConnection?.id === connection.id}
241
+ <ContextMenu>
242
+ <ContextMenuTrigger>
243
+ <Tooltip>
244
+ <TooltipTrigger>
245
+ <button
246
+ class="group relative flex size-8 items-center justify-center rounded-lg transition-colors {isActive ? 'bg-accent text-accent-foreground' : 'text-muted-foreground hover:bg-accent/50 hover:text-foreground'}"
247
+ onclick={() => handleBrowseConnection(connection)}
248
+ >
249
+ <CloudIcon class="size-4" />
250
+ {#if isActive}
251
+ <div class="absolute left-0 top-1/2 h-4 w-0.5 -translate-y-1/2 rounded-r bg-primary"></div>
252
+ {/if}
253
+ </button>
254
+ </TooltipTrigger>
255
+ <TooltipContent side="right">
256
+ {connection.name}
257
+ </TooltipContent>
258
+ </Tooltip>
259
+ </ContextMenuTrigger>
260
+ <ContextMenuContent class="w-40">
261
+ <ContextMenuItem onclick={() => handleEditConnection(connection)}>
262
+ <PencilIcon class="me-2 size-3.5" />
263
+ {t('sidebar.edit')}
264
+ </ContextMenuItem>
265
+ <ContextMenuSeparator />
266
+ <ContextMenuItem
267
+ class="text-destructive data-[highlighted]:text-destructive"
268
+ onclick={() => handleDeleteConnection(connection)}
269
+ >
270
+ <TrashIcon class="me-2 size-3.5" />
271
+ {t('sidebar.delete')}
272
+ </ContextMenuItem>
273
+ </ContextMenuContent>
274
+ </ContextMenu>
275
+ {/each}
276
+
277
+ <!-- Add connection button -->
278
+ <Tooltip>
279
+ <TooltipTrigger>
280
+ <button
281
+ class="flex size-8 items-center justify-center rounded-lg border border-dashed border-muted-foreground/30 text-muted-foreground transition-colors hover:border-foreground/50 hover:text-foreground"
282
+ onclick={handleAddConnection}
283
+ >
284
+ <PlusIcon class="size-4" />
285
+ </button>
286
+ </TooltipTrigger>
287
+ <TooltipContent side="right">{t('sidebar.addConnection')}</TooltipContent>
288
+ </Tooltip>
289
+ </div>
290
+
291
+ <!-- Bottom actions -->
292
+ <div class="mt-auto flex flex-col items-center gap-1 pt-2">
293
+ <LocaleToggle />
294
+ <ThemeToggle />
295
+ </div>
296
+ </div>
297
+ </TooltipProvider>
298
+
299
+ <ConnectionDialog
300
+ bind:open={dialogOpen}
301
+ editConnection={editingConnection}
302
+ onSaved={() => {
303
+ connections.reload();
304
+ // If we opened the dialog for a credential re-entry, auto-browse after save
305
+ if (editingConnection) {
306
+ const conn = connections.getById(editingConnection.id);
307
+ if (conn && credentialStore.has(conn.id)) {
308
+ browser.browse(conn);
309
+ syncUrlParam(conn);
310
+ }
311
+ }
312
+ handleAutoDetection();
313
+ }}
314
+ />
@@ -0,0 +1,3 @@
1
+ declare const Sidebar: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type Sidebar = ReturnType<typeof Sidebar>;
3
+ export default Sidebar;
@@ -0,0 +1,73 @@
1
+ <script lang="ts">
2
+ import CloudIcon from '@lucide/svelte/icons/cloud';
3
+ import FileTextIcon from '@lucide/svelte/icons/file-text';
4
+ import FolderIcon from '@lucide/svelte/icons/folder';
5
+ import GlobeIcon from '@lucide/svelte/icons/globe';
6
+ import InfoIcon from '@lucide/svelte/icons/info';
7
+ import { Separator } from '../ui/separator/index.js';
8
+ import { getFileTypeInfo } from '../../file-icons/index.js';
9
+ import { t } from '../../i18n/index.svelte.js';
10
+ import { browser } from '../../stores/browser.svelte.js';
11
+ import { files } from '../../stores/files.svelte.js';
12
+ import { tabs } from '../../stores/tabs.svelte.js';
13
+ import { formatFileSize } from '../../utils/format.js';
14
+ import SafeLockToggle from './SafeLockToggle.svelte';
15
+
16
+ let isBrowsingRemote = $derived(browser.activeConnection !== null);
17
+
18
+ let displayPath = $derived(isBrowsingRemote ? browser.currentPrefix : files.currentPath);
19
+ let displayCount = $derived(isBrowsingRemote ? browser.entries.length : files.entries.length);
20
+
21
+ let activeTab = $derived(tabs.active);
22
+ let activeFileInfo = $derived(activeTab ? getFileTypeInfo(activeTab.extension) : null);
23
+ </script>
24
+
25
+ <div
26
+ class="flex h-7 shrink-0 items-center gap-1 border-t bg-muted/40 px-3 text-[11px] text-muted-foreground"
27
+ >
28
+ <!-- Connection / path context -->
29
+ {#if isBrowsingRemote && browser.activeConnection}
30
+ <CloudIcon class="size-3 shrink-0" />
31
+ <span class="max-w-[200px] truncate" title={browser.activeConnection.name}>
32
+ {browser.activeConnection.name}
33
+ </span>
34
+ {#if displayPath}
35
+ <span class="text-muted-foreground/50">/</span>
36
+ <span class="max-w-[200px] truncate" title={displayPath}>{displayPath}</span>
37
+ {/if}
38
+ <Separator orientation="vertical" class="mx-1.5 h-3.5" />
39
+ {:else if displayPath}
40
+ <FolderIcon class="size-3 shrink-0" />
41
+ <span class="max-w-[300px] truncate" title={displayPath}>{displayPath}</span>
42
+ <Separator orientation="vertical" class="mx-1.5 h-3.5" />
43
+ {/if}
44
+
45
+ <!-- Entry count -->
46
+ {#if displayCount > 0}
47
+ <FileTextIcon class="size-3 shrink-0" />
48
+ <span>{displayCount} {displayCount === 1 ? t('statusBar.item') : t('statusBar.items')}</span>
49
+ <Separator orientation="vertical" class="mx-1.5 h-3.5" />
50
+ {/if}
51
+
52
+ <!-- Active file info -->
53
+ {#if activeTab && activeFileInfo}
54
+ <InfoIcon class="size-3 shrink-0" />
55
+ <span>{activeFileInfo.label}</span>
56
+ {#if activeTab.size}
57
+ <span class="text-muted-foreground/50">·</span>
58
+ <span>{formatFileSize(activeTab.size)}</span>
59
+ {/if}
60
+ <Separator orientation="vertical" class="mx-1.5 h-3.5" />
61
+ {/if}
62
+
63
+ <!-- Spacer -->
64
+ <div class="flex-1"></div>
65
+
66
+ <!-- Safe lock toggle -->
67
+ <SafeLockToggle />
68
+ <Separator orientation="vertical" class="mx-1.5 h-3.5" />
69
+
70
+ <!-- Mode indicator -->
71
+ <GlobeIcon class="size-3 shrink-0" />
72
+ <span>{t('statusBar.web')}</span>
73
+ </div>
@@ -0,0 +1,3 @@
1
+ declare const StatusBar: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type StatusBar = ReturnType<typeof StatusBar>;
3
+ export default StatusBar;
@@ -0,0 +1,102 @@
1
+ <script lang="ts">
2
+ import DatabaseIcon from '@lucide/svelte/icons/database';
3
+ import FileTextIcon from '@lucide/svelte/icons/file-text';
4
+ import XIcon from '@lucide/svelte/icons/x';
5
+ import type { Snippet } from 'svelte';
6
+ import { Button } from '../ui/button/index.js';
7
+ import * as ContextMenu from '../ui/context-menu/index.js';
8
+ import { ScrollArea } from '../ui/scroll-area/index.js';
9
+ import { t } from '../../i18n/index.svelte.js';
10
+ import { tabs } from '../../stores/tabs.svelte.js';
11
+ import { buildHttpsUrl, buildStorageUrl } from '../../utils/url.js';
12
+
13
+ let { leading }: { leading?: Snippet } = $props();
14
+
15
+ let copiedType = $state<string | null>(null);
16
+
17
+ function getTabIcon(tab: { connectionId?: string }) {
18
+ if (tab.connectionId) return DatabaseIcon;
19
+ return FileTextIcon;
20
+ }
21
+
22
+ function handleClose(event: MouseEvent, id: string) {
23
+ event.stopPropagation();
24
+ tabs.close(id);
25
+ }
26
+
27
+ async function handleCopy(type: 'https' | 's3', tab: (typeof tabs.items)[0]) {
28
+ const url = type === 'https' ? buildHttpsUrl(tab) : buildStorageUrl(tab);
29
+ if (!url) return;
30
+ try {
31
+ await navigator.clipboard.writeText(url);
32
+ copiedType = `${type}-${tab.id}`;
33
+ setTimeout(() => (copiedType = null), 2000);
34
+ } catch {
35
+ // clipboard API may fail in some contexts
36
+ }
37
+ }
38
+ </script>
39
+
40
+ {#if tabs.items.length > 0 || leading}
41
+ <div class="flex h-9 shrink-0 items-center border-b bg-muted/30">
42
+ {#if leading}
43
+ <div class="flex items-center ps-1">
44
+ {@render leading()}
45
+ </div>
46
+ {/if}
47
+ <ScrollArea orientation="horizontal" class="w-full">
48
+ <div class="flex h-9 items-center">
49
+ {#each tabs.items as tab (tab.id)}
50
+ {@const TabIcon = getTabIcon(tab)}
51
+ {@const isActive = tabs.active?.id === tab.id}
52
+ <ContextMenu.Root>
53
+ <ContextMenu.Trigger>
54
+ <button
55
+ class="group relative flex h-9 shrink-0 items-center gap-1.5 border-e px-3 text-sm transition-colors
56
+ {isActive
57
+ ? 'bg-background text-foreground'
58
+ : 'text-muted-foreground hover:bg-background/50 hover:text-foreground'}"
59
+ onclick={() => tabs.setActive(tab.id)}
60
+ >
61
+ <TabIcon class="size-3.5 shrink-0" />
62
+ <span class="max-w-[120px] truncate">{tab.name}</span>
63
+ <Button
64
+ variant="ghost"
65
+ size="icon-sm"
66
+ class="ms-1 size-5 opacity-0 transition-opacity group-hover:opacity-100
67
+ {isActive ? 'opacity-60' : ''}"
68
+ onclick={(e: MouseEvent) => handleClose(e, tab.id)}
69
+ aria-label={t('tabBar.closeTab', { name: tab.name })}
70
+ >
71
+ <XIcon class="size-3" />
72
+ </Button>
73
+ {#if isActive}
74
+ <div class="absolute bottom-0 left-0 right-0 h-0.5 bg-primary"></div>
75
+ {/if}
76
+ </button>
77
+ </ContextMenu.Trigger>
78
+ <ContextMenu.Content class="w-52">
79
+ <ContextMenu.Item onclick={() => handleCopy('https', tab)}>
80
+ {copiedType === `https-${tab.id}` ? t('tabBar.copied') : t('tabBar.copyHttps')}
81
+ </ContextMenu.Item>
82
+ {#if tab.source === 'remote'}
83
+ <ContextMenu.Item onclick={() => handleCopy('s3', tab)}>
84
+ {copiedType === `s3-${tab.id}` ? t('tabBar.copied') : t('tabBar.copyStorage')}
85
+ </ContextMenu.Item>
86
+ {/if}
87
+ <ContextMenu.Separator />
88
+ <ContextMenu.Item onclick={() => tabs.close(tab.id)}>
89
+ {t('tabBar.closeTab', { name: '' }).trim()}
90
+ </ContextMenu.Item>
91
+ {#if tabs.items.length > 1}
92
+ <ContextMenu.Item onclick={() => tabs.closeOthers(tab.id)}>
93
+ {t('tabBar.closeOtherTabs')}
94
+ </ContextMenu.Item>
95
+ {/if}
96
+ </ContextMenu.Content>
97
+ </ContextMenu.Root>
98
+ {/each}
99
+ </div>
100
+ </ScrollArea>
101
+ </div>
102
+ {/if}
@@ -0,0 +1,7 @@
1
+ import type { Snippet } from 'svelte';
2
+ type $$ComponentProps = {
3
+ leading?: Snippet;
4
+ };
5
+ declare const TabBar: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type TabBar = ReturnType<typeof TabBar>;
7
+ export default TabBar;
@@ -0,0 +1,52 @@
1
+ <script lang="ts">
2
+ import MonitorIcon from '@lucide/svelte/icons/monitor';
3
+ import MoonIcon from '@lucide/svelte/icons/moon';
4
+ import SunIcon from '@lucide/svelte/icons/sun';
5
+ import { Button } from '../ui/button/index.js';
6
+ import {
7
+ Tooltip,
8
+ TooltipContent,
9
+ TooltipProvider,
10
+ TooltipTrigger
11
+ } from '../ui/tooltip/index.js';
12
+ import { t } from '../../i18n/index.svelte.js';
13
+ import { settings } from '../../stores/settings.svelte.js';
14
+
15
+ const icons = {
16
+ light: SunIcon,
17
+ dark: MoonIcon,
18
+ system: MonitorIcon
19
+ } as const;
20
+
21
+ const cycle: Record<string, 'light' | 'dark' | 'system'> = {
22
+ light: 'dark',
23
+ dark: 'system',
24
+ system: 'light'
25
+ };
26
+
27
+ function toggle() {
28
+ settings.setTheme(cycle[settings.theme]);
29
+ }
30
+
31
+ let CurrentIcon = $derived(icons[settings.theme]);
32
+ let label = $derived(t(`theme.${settings.theme}`));
33
+ </script>
34
+
35
+ <Tooltip>
36
+ <TooltipTrigger onclick={toggle}>
37
+ {#snippet child({ props })}
38
+ <Button
39
+ {...props}
40
+ variant="ghost"
41
+ size="icon-sm"
42
+ class="rounded-lg text-muted-foreground hover:text-foreground"
43
+ aria-label={t('theme.tooltip', { mode: label })}
44
+ >
45
+ <CurrentIcon class="size-4" />
46
+ </Button>
47
+ {/snippet}
48
+ </TooltipTrigger>
49
+ <TooltipContent side="right">
50
+ {t('theme.tooltip', { mode: label })}
51
+ </TooltipContent>
52
+ </Tooltip>
@@ -0,0 +1,3 @@
1
+ declare const ThemeToggle: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type ThemeToggle = ReturnType<typeof ThemeToggle>;
3
+ export default ThemeToggle;
@@ -0,0 +1,49 @@
1
+ <script lang="ts" module>
2
+ import { tv, type VariantProps } from 'tailwind-variants';
3
+
4
+ export const badgeVariants = tv({
5
+ base: 'focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] [&>svg]:pointer-events-none [&>svg]:size-3',
6
+ variants: {
7
+ variant: {
8
+ default: 'bg-primary text-primary-foreground [a&]:hover:bg-primary/90 border-transparent',
9
+ secondary:
10
+ 'bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90 border-transparent',
11
+ destructive:
12
+ 'bg-destructive [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/70 border-transparent text-white',
13
+ outline: 'text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground'
14
+ }
15
+ },
16
+ defaultVariants: {
17
+ variant: 'default'
18
+ }
19
+ });
20
+
21
+ export type BadgeVariant = VariantProps<typeof badgeVariants>['variant'];
22
+ </script>
23
+
24
+ <script lang="ts">
25
+ import type { HTMLAnchorAttributes } from "svelte/elements";
26
+ import { cn, type WithElementRef } from "../../../utils.js";
27
+
28
+ let {
29
+ ref = $bindable(null),
30
+ href,
31
+ class: className,
32
+ variant = "default",
33
+ children,
34
+ ...restProps
35
+ }: WithElementRef<HTMLAnchorAttributes> & {
36
+ variant?: BadgeVariant;
37
+ } = $props();
38
+ </script>
39
+
40
+ <svelte:element
41
+ this={href ? "a" : "span"}
42
+ bind:this={ref}
43
+ data-slot="badge"
44
+ {href}
45
+ class={cn(badgeVariants({ variant }), className)}
46
+ {...restProps}
47
+ >
48
+ {@render children?.()}
49
+ </svelte:element>
@@ -0,0 +1,32 @@
1
+ import { type VariantProps } from 'tailwind-variants';
2
+ export declare const badgeVariants: import("tailwind-variants").TVReturnType<{
3
+ variant: {
4
+ default: string;
5
+ secondary: string;
6
+ destructive: string;
7
+ outline: string;
8
+ };
9
+ }, undefined, "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] [&>svg]:pointer-events-none [&>svg]:size-3", {
10
+ variant: {
11
+ default: string;
12
+ secondary: string;
13
+ destructive: string;
14
+ outline: string;
15
+ };
16
+ }, undefined, import("tailwind-variants").TVReturnType<{
17
+ variant: {
18
+ default: string;
19
+ secondary: string;
20
+ destructive: string;
21
+ outline: string;
22
+ };
23
+ }, undefined, "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] [&>svg]:pointer-events-none [&>svg]:size-3", unknown, unknown, undefined>>;
24
+ export type BadgeVariant = VariantProps<typeof badgeVariants>['variant'];
25
+ import type { HTMLAnchorAttributes } from "svelte/elements";
26
+ import { type WithElementRef } from "../../../utils.js";
27
+ type $$ComponentProps = WithElementRef<HTMLAnchorAttributes> & {
28
+ variant?: BadgeVariant;
29
+ };
30
+ declare const Badge: import("svelte").Component<$$ComponentProps, {}, "ref">;
31
+ type Badge = ReturnType<typeof Badge>;
32
+ export default Badge;
@@ -0,0 +1 @@
1
+ export { type BadgeVariant, badgeVariants, default as Badge } from './badge.svelte';
@@ -0,0 +1 @@
1
+ export { badgeVariants, default as Badge } from './badge.svelte';