@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,10 @@
1
+ export interface HexRow {
2
+ offset: string;
3
+ hex: string[];
4
+ ascii: string;
5
+ }
6
+ /**
7
+ * Generates a hex dump from binary data.
8
+ * Returns rows of offset | hex bytes | ASCII representation.
9
+ */
10
+ export declare function generateHexDump(data: Uint8Array, bytesPerRow?: number): HexRow[];
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Generates a hex dump from binary data.
3
+ * Returns rows of offset | hex bytes | ASCII representation.
4
+ */
5
+ export function generateHexDump(data, bytesPerRow = 16) {
6
+ const rows = [];
7
+ for (let i = 0; i < data.length; i += bytesPerRow) {
8
+ const slice = data.slice(i, i + bytesPerRow);
9
+ const offset = i.toString(16).padStart(8, '0');
10
+ const hex = [];
11
+ for (let j = 0; j < bytesPerRow; j++) {
12
+ if (j < slice.length) {
13
+ hex.push(slice[j].toString(16).padStart(2, '0'));
14
+ }
15
+ else {
16
+ hex.push(' ');
17
+ }
18
+ }
19
+ let ascii = '';
20
+ for (let j = 0; j < slice.length; j++) {
21
+ const byte = slice[j];
22
+ ascii += byte >= 0x20 && byte <= 0x7e ? String.fromCharCode(byte) : '.';
23
+ }
24
+ rows.push({ offset, hex, ascii });
25
+ }
26
+ return rows;
27
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Auto-detect hosting bucket from URL search params and window.location.
3
+ *
4
+ * Detection priority:
5
+ * 1. `?url=<storage-url>` query parameter (highest priority)
6
+ * 2. `window.location.hostname` pattern matching (fallback)
7
+ *
8
+ * Also extracts `rootPrefix` when the app is hosted inside a subfolder.
9
+ */
10
+ import type { StorageProvider } from './storage-url.js';
11
+ export interface DetectedHost {
12
+ provider: StorageProvider;
13
+ bucket: string;
14
+ region: string;
15
+ endpoint: string;
16
+ rootPrefix: string;
17
+ bucketUrl: string;
18
+ }
19
+ /**
20
+ * Detect hosting bucket from current URL.
21
+ * Returns null when no hosting bucket can be determined.
22
+ */
23
+ export declare function detectHostBucket(): DetectedHost | null;
@@ -0,0 +1,289 @@
1
+ /**
2
+ * Auto-detect hosting bucket from URL search params and window.location.
3
+ *
4
+ * Detection priority:
5
+ * 1. `?url=<storage-url>` query parameter (highest priority)
6
+ * 2. `window.location.hostname` pattern matching (fallback)
7
+ *
8
+ * Also extracts `rootPrefix` when the app is hosted inside a subfolder.
9
+ */
10
+ import { parseStorageUrl } from './storage-url.js';
11
+ /**
12
+ * Extract root prefix from pathname.
13
+ * When hosted at `/subfolder/index.html` or `/subfolder/`, returns `subfolder/`.
14
+ */
15
+ function extractRootPrefix(pathname) {
16
+ // Strip trailing filename (index.html, etc.)
17
+ let clean = pathname.replace(/\/[^/]*\.[^/]*$/, '/');
18
+ // Remove leading slash
19
+ clean = clean.replace(/^\//, '');
20
+ // Empty or just '/' means no prefix
21
+ if (!clean || clean === '/')
22
+ return '';
23
+ // Ensure trailing slash
24
+ if (!clean.endsWith('/'))
25
+ clean += '/';
26
+ return clean;
27
+ }
28
+ /**
29
+ * Build a normalized API endpoint URL for a detected provider.
30
+ */
31
+ function buildBucketUrl(provider, endpoint, bucket) {
32
+ if (endpoint) {
33
+ return `${endpoint.replace(/\/$/, '')}/${bucket}`;
34
+ }
35
+ switch (provider) {
36
+ case 'gcs':
37
+ return `https://storage.googleapis.com/${bucket}`;
38
+ case 'azure':
39
+ return `${endpoint}/${bucket}`;
40
+ case 'storj':
41
+ return `https://gateway.storjshare.io/${bucket}`;
42
+ default:
43
+ return `https://s3.us-east-1.amazonaws.com/${bucket}`;
44
+ }
45
+ }
46
+ /**
47
+ * Detect hosting bucket from current URL.
48
+ * Returns null when no hosting bucket can be determined.
49
+ */
50
+ export function detectHostBucket() {
51
+ if (typeof window === 'undefined')
52
+ return null;
53
+ const url = new URL(window.location.href);
54
+ const host = url.hostname;
55
+ // --- Priority 1: ?url= query parameter ---
56
+ const urlParam = url.searchParams.get('url');
57
+ if (urlParam) {
58
+ const parsed = parseStorageUrl(urlParam);
59
+ if (parsed.bucket) {
60
+ return {
61
+ provider: parsed.provider === 'unknown' ? 's3' : parsed.provider,
62
+ bucket: parsed.bucket,
63
+ region: parsed.region,
64
+ endpoint: parsed.endpoint,
65
+ rootPrefix: '',
66
+ bucketUrl: buildBucketUrl(parsed.provider, parsed.endpoint, parsed.bucket)
67
+ };
68
+ }
69
+ }
70
+ // --- Priority 2: Hostname pattern matching ---
71
+ const pathname = url.pathname;
72
+ // AWS S3 virtual-hosted: <bucket>.s3.<region>.amazonaws.com
73
+ const awsVhost = host.match(/^(.+)\.s3[.-]([a-z0-9-]+)\.amazonaws\.com$/);
74
+ if (awsVhost) {
75
+ return {
76
+ provider: 's3',
77
+ bucket: awsVhost[1],
78
+ region: awsVhost[2],
79
+ endpoint: '',
80
+ rootPrefix: extractRootPrefix(pathname),
81
+ bucketUrl: `https://s3.${awsVhost[2]}.amazonaws.com/${awsVhost[1]}`
82
+ };
83
+ }
84
+ // AWS S3 website hosting: <bucket>.s3-website-<region>.amazonaws.com or <bucket>.s3-website.<region>.amazonaws.com
85
+ const awsWebsite = host.match(/^(.+)\.s3-website[.-]([a-z0-9-]+)\.amazonaws\.com$/);
86
+ if (awsWebsite) {
87
+ return {
88
+ provider: 's3',
89
+ bucket: awsWebsite[1],
90
+ region: awsWebsite[2],
91
+ endpoint: '',
92
+ rootPrefix: extractRootPrefix(pathname),
93
+ bucketUrl: `https://s3.${awsWebsite[2]}.amazonaws.com/${awsWebsite[1]}`
94
+ };
95
+ }
96
+ // AWS S3 path-style: s3.<region>.amazonaws.com/<bucket>
97
+ const awsPath = host.match(/^s3[.-]([a-z0-9-]+)\.amazonaws\.com$/);
98
+ if (awsPath) {
99
+ const parts = pathname.replace(/^\//, '').split('/').filter(Boolean);
100
+ if (parts.length > 0) {
101
+ return {
102
+ provider: 's3',
103
+ bucket: parts[0],
104
+ region: awsPath[1],
105
+ endpoint: '',
106
+ rootPrefix: parts.length > 1 ? extractRootPrefix(`/${parts.slice(1).join('/')}`) : '',
107
+ bucketUrl: `https://s3.${awsPath[1]}.amazonaws.com/${parts[0]}`
108
+ };
109
+ }
110
+ }
111
+ // GCS: storage.googleapis.com/<bucket>
112
+ if (host === 'storage.googleapis.com') {
113
+ const parts = pathname.replace(/^\//, '').split('/').filter(Boolean);
114
+ if (parts.length > 0) {
115
+ return {
116
+ provider: 'gcs',
117
+ bucket: parts[0],
118
+ region: 'us',
119
+ endpoint: '',
120
+ rootPrefix: parts.length > 1 ? extractRootPrefix(`/${parts.slice(1).join('/')}`) : '',
121
+ bucketUrl: `https://storage.googleapis.com/${parts[0]}`
122
+ };
123
+ }
124
+ }
125
+ // GCS virtual-hosted: <bucket>.storage.googleapis.com
126
+ const gcsVhost = host.match(/^(.+)\.storage\.googleapis\.com$/);
127
+ if (gcsVhost) {
128
+ return {
129
+ provider: 'gcs',
130
+ bucket: gcsVhost[1],
131
+ region: 'us',
132
+ endpoint: '',
133
+ rootPrefix: extractRootPrefix(pathname),
134
+ bucketUrl: `https://storage.googleapis.com/${gcsVhost[1]}`
135
+ };
136
+ }
137
+ // Azure Static Website: <account>.z<N>.web.core.windows.net
138
+ const azureWeb = host.match(/^([a-z0-9]+)\.z\d+\.web\.core\.windows\.net$/);
139
+ if (azureWeb) {
140
+ return {
141
+ provider: 'azure',
142
+ bucket: '$web',
143
+ region: '',
144
+ endpoint: `https://${azureWeb[1]}.blob.core.windows.net`,
145
+ rootPrefix: extractRootPrefix(pathname),
146
+ bucketUrl: `https://${azureWeb[1]}.blob.core.windows.net/$web`
147
+ };
148
+ }
149
+ // Azure Blob: <account>.blob.core.windows.net/<container>
150
+ const azureBlob = host.match(/^([a-z0-9]+)\.blob\.core\.windows\.net$/);
151
+ if (azureBlob) {
152
+ const parts = pathname.replace(/^\//, '').split('/').filter(Boolean);
153
+ if (parts.length > 0) {
154
+ return {
155
+ provider: 'azure',
156
+ bucket: parts[0],
157
+ region: '',
158
+ endpoint: `https://${host}`,
159
+ rootPrefix: parts.length > 1 ? extractRootPrefix(`/${parts.slice(1).join('/')}`) : '',
160
+ bucketUrl: `https://${host}/${parts[0]}`
161
+ };
162
+ }
163
+ }
164
+ // R2 public: pub-<id>.r2.dev
165
+ const r2Public = host.match(/^(pub-[a-z0-9]+)\.r2\.dev$/);
166
+ if (r2Public) {
167
+ const parts = pathname.replace(/^\//, '').split('/').filter(Boolean);
168
+ return {
169
+ provider: 'r2',
170
+ bucket: parts[0] || r2Public[1],
171
+ region: 'auto',
172
+ endpoint: `https://${host}`,
173
+ rootPrefix: parts.length > 1 ? extractRootPrefix(`/${parts.slice(1).join('/')}`) : '',
174
+ bucketUrl: `https://${host}`
175
+ };
176
+ }
177
+ // DigitalOcean Spaces: <bucket>.<region>.digitaloceanspaces.com
178
+ const doSpaces = host.match(/^(.+)\.([a-z0-9-]+)\.digitaloceanspaces\.com$/);
179
+ if (doSpaces) {
180
+ return {
181
+ provider: 's3',
182
+ bucket: doSpaces[1],
183
+ region: doSpaces[2],
184
+ endpoint: `https://${doSpaces[2]}.digitaloceanspaces.com`,
185
+ rootPrefix: extractRootPrefix(pathname),
186
+ bucketUrl: `https://${doSpaces[2]}.digitaloceanspaces.com/${doSpaces[1]}`
187
+ };
188
+ }
189
+ // DigitalOcean Spaces CDN: <bucket>.<region>.cdn.digitaloceanspaces.com
190
+ const doCdn = host.match(/^(.+)\.([a-z0-9-]+)\.cdn\.digitaloceanspaces\.com$/);
191
+ if (doCdn) {
192
+ return {
193
+ provider: 's3',
194
+ bucket: doCdn[1],
195
+ region: doCdn[2],
196
+ endpoint: `https://${doCdn[2]}.digitaloceanspaces.com`,
197
+ rootPrefix: extractRootPrefix(pathname),
198
+ bucketUrl: `https://${doCdn[2]}.digitaloceanspaces.com/${doCdn[1]}`
199
+ };
200
+ }
201
+ // Wasabi: s3.<region>.wasabisys.com/<bucket>
202
+ const wasabi = host.match(/^s3\.([a-z0-9-]+)\.wasabisys\.com$/);
203
+ if (wasabi) {
204
+ const parts = pathname.replace(/^\//, '').split('/').filter(Boolean);
205
+ if (parts.length > 0) {
206
+ return {
207
+ provider: 's3',
208
+ bucket: parts[0],
209
+ region: wasabi[1],
210
+ endpoint: `https://${host}`,
211
+ rootPrefix: parts.length > 1 ? extractRootPrefix(`/${parts.slice(1).join('/')}`) : '',
212
+ bucketUrl: `https://${host}/${parts[0]}`
213
+ };
214
+ }
215
+ }
216
+ // B2 S3: <bucket>.s3.<region>.backblazeb2.com
217
+ const b2s3 = host.match(/^(.+)\.s3\.([a-z0-9-]+)\.backblazeb2\.com$/);
218
+ if (b2s3) {
219
+ return {
220
+ provider: 's3',
221
+ bucket: b2s3[1],
222
+ region: b2s3[2],
223
+ endpoint: `https://s3.${b2s3[2]}.backblazeb2.com`,
224
+ rootPrefix: extractRootPrefix(pathname),
225
+ bucketUrl: `https://s3.${b2s3[2]}.backblazeb2.com/${b2s3[1]}`
226
+ };
227
+ }
228
+ // IBM COS: <bucket>.s3-web.<region>.cloud-object-storage.appdomain.cloud
229
+ const ibmCos = host.match(/^(.+)\.s3-web\.([a-z0-9-]+)\.cloud-object-storage\.appdomain\.cloud$/);
230
+ if (ibmCos) {
231
+ return {
232
+ provider: 's3',
233
+ bucket: ibmCos[1],
234
+ region: ibmCos[2],
235
+ endpoint: `https://s3.${ibmCos[2]}.cloud-object-storage.appdomain.cloud`,
236
+ rootPrefix: extractRootPrefix(pathname),
237
+ bucketUrl: `https://s3.${ibmCos[2]}.cloud-object-storage.appdomain.cloud/${ibmCos[1]}`
238
+ };
239
+ }
240
+ // Storj S3 gateway: gateway.storjshare.io/<bucket> (or gateway.<region>.storjshare.io)
241
+ const storjGateway = host.match(/^gateway\.(?:([a-z0-9]+)\.)?storjshare\.io$/);
242
+ if (storjGateway) {
243
+ const parts = pathname.replace(/^\//, '').split('/').filter(Boolean);
244
+ if (parts.length > 0) {
245
+ return {
246
+ provider: 'storj',
247
+ bucket: parts[0],
248
+ region: storjGateway[1] || 'us1',
249
+ endpoint: `${url.protocol}//${url.host}`,
250
+ rootPrefix: parts.length > 1 ? extractRootPrefix(`/${parts.slice(1).join('/')}`) : '',
251
+ bucketUrl: `${url.protocol}//${url.host}/${parts[0]}`
252
+ };
253
+ }
254
+ }
255
+ // Storj linksharing: link.storjshare.io/raw/<access>/<bucket>/...
256
+ const storjLink = host.match(/^link\.(?:([a-z0-9]+)\.)?storjshare\.io$/);
257
+ if (storjLink) {
258
+ const parts = pathname.replace(/^\//, '').split('/').filter(Boolean);
259
+ if (parts.length >= 3 && (parts[0] === 'raw' || parts[0] === 's')) {
260
+ return {
261
+ provider: 'storj',
262
+ bucket: parts[2],
263
+ region: storjLink[1] || 'us1',
264
+ endpoint: `${url.protocol}//${url.host}/${parts[0]}/${parts[1]}`,
265
+ rootPrefix: parts.length > 3 ? extractRootPrefix(`/${parts.slice(3).join('/')}`) : '',
266
+ bucketUrl: `${url.protocol}//${url.host}/${parts[0]}/${parts[1]}/${parts[2]}`
267
+ };
268
+ }
269
+ }
270
+ // MinIO / localhost / private IPs
271
+ const isLocal = host === 'localhost' ||
272
+ host === '127.0.0.1' ||
273
+ host.startsWith('192.168.') ||
274
+ host.startsWith('10.');
275
+ if (isLocal) {
276
+ const parts = pathname.replace(/^\//, '').split('/').filter(Boolean);
277
+ if (parts.length > 0) {
278
+ return {
279
+ provider: 'minio',
280
+ bucket: parts[0],
281
+ region: 'us-east-1',
282
+ endpoint: `${url.protocol}//${url.host}`,
283
+ rootPrefix: parts.length > 1 ? extractRootPrefix(`/${parts.slice(1).join('/')}`) : '',
284
+ bucketUrl: `${url.protocol}//${url.host}/${parts[0]}`
285
+ };
286
+ }
287
+ }
288
+ return null;
289
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Shared selection highlight for all map viewers.
3
+ *
4
+ * Adds a MapLibre GeoJSON source + yellow outline layers that render
5
+ * on top of any data layer (deck.gl or native MapLibre).
6
+ * Works because every viewer uses MapLibre as its base map.
7
+ */
8
+ import type maplibregl from 'maplibre-gl';
9
+ /** Add an empty GeoJSON source + outline layers to the map. Call once in onMapReady. */
10
+ export declare function setupSelectionLayer(map: maplibregl.Map): void;
11
+ /** Set or clear the selected feature. Pass null to clear. */
12
+ export declare function updateSelection(map: maplibregl.Map, feature: GeoJSON.Feature | null): void;
@@ -0,0 +1,45 @@
1
+ const SOURCE_ID = 'selection-highlight';
2
+ const SELECTION_COLOR = '#ffc800'; // QGIS-style yellow
3
+ /** Add an empty GeoJSON source + outline layers to the map. Call once in onMapReady. */
4
+ export function setupSelectionLayer(map) {
5
+ if (map.getSource(SOURCE_ID))
6
+ return; // idempotent
7
+ map.addSource(SOURCE_ID, {
8
+ type: 'geojson',
9
+ data: { type: 'FeatureCollection', features: [] }
10
+ });
11
+ // Polygon / line outline
12
+ map.addLayer({
13
+ id: 'selection-outline',
14
+ type: 'line',
15
+ source: SOURCE_ID,
16
+ paint: {
17
+ 'line-color': SELECTION_COLOR,
18
+ 'line-width': 3,
19
+ 'line-opacity': 1
20
+ }
21
+ });
22
+ // Point halo
23
+ map.addLayer({
24
+ id: 'selection-point',
25
+ type: 'circle',
26
+ source: SOURCE_ID,
27
+ filter: ['==', '$type', 'Point'],
28
+ paint: {
29
+ 'circle-radius': 10,
30
+ 'circle-color': 'transparent',
31
+ 'circle-stroke-color': SELECTION_COLOR,
32
+ 'circle-stroke-width': 3
33
+ }
34
+ });
35
+ }
36
+ /** Set or clear the selected feature. Pass null to clear. */
37
+ export function updateSelection(map, feature) {
38
+ const source = map.getSource(SOURCE_ID);
39
+ if (!source)
40
+ return;
41
+ source.setData({
42
+ type: 'FeatureCollection',
43
+ features: feature ? [feature] : []
44
+ });
45
+ }
@@ -0,0 +1,30 @@
1
+ export interface SqlBlock {
2
+ name: string;
3
+ sql: string;
4
+ startLine: number;
5
+ endLine: number;
6
+ }
7
+ export interface ParsedMarkdownDocument {
8
+ frontmatter: Record<string, any>;
9
+ content: string;
10
+ sqlBlocks: SqlBlock[];
11
+ }
12
+ /**
13
+ * Parse a markdown document with YAML frontmatter and SQL code blocks.
14
+ *
15
+ * Evidence-compatible syntax:
16
+ * ```sql query_name
17
+ * SELECT * FROM table
18
+ * ```
19
+ */
20
+ export declare function parseMarkdownDocument(markdown: string): ParsedMarkdownDocument;
21
+ /**
22
+ * Interpolate template variables in markdown text.
23
+ * Supports {queryName.rows[0].columnName} syntax.
24
+ */
25
+ export declare function interpolateTemplates(text: string, queryResults: Map<string, Record<string, any>[]>): string;
26
+ /**
27
+ * Replace SQL blocks in markdown content with placeholder markers
28
+ * that can be replaced with rendered components.
29
+ */
30
+ export declare function markSqlBlocks(content: string): string;
@@ -0,0 +1,73 @@
1
+ import YAML from 'yaml';
2
+ /**
3
+ * Parse a markdown document with YAML frontmatter and SQL code blocks.
4
+ *
5
+ * Evidence-compatible syntax:
6
+ * ```sql query_name
7
+ * SELECT * FROM table
8
+ * ```
9
+ */
10
+ export function parseMarkdownDocument(markdown) {
11
+ let frontmatter = {};
12
+ let content = markdown;
13
+ // Extract YAML frontmatter
14
+ const fmMatch = markdown.match(/^---\n([\s\S]*?)\n---\n/);
15
+ if (fmMatch) {
16
+ try {
17
+ frontmatter = YAML.parse(fmMatch[1]) || {};
18
+ }
19
+ catch {
20
+ // Invalid YAML — ignore
21
+ }
22
+ content = markdown.slice(fmMatch[0].length);
23
+ }
24
+ // Extract SQL blocks
25
+ const sqlBlocks = [];
26
+ const lines = content.split('\n');
27
+ let i = 0;
28
+ while (i < lines.length) {
29
+ const line = lines[i];
30
+ const match = line.match(/^```sql\s+(\w[\w-]*)\s*$/);
31
+ if (match) {
32
+ const name = match[1];
33
+ const startLine = i;
34
+ const sqlLines = [];
35
+ i++;
36
+ while (i < lines.length && lines[i] !== '```') {
37
+ sqlLines.push(lines[i]);
38
+ i++;
39
+ }
40
+ sqlBlocks.push({
41
+ name,
42
+ sql: sqlLines.join('\n'),
43
+ startLine,
44
+ endLine: i
45
+ });
46
+ }
47
+ i++;
48
+ }
49
+ return { frontmatter, content, sqlBlocks };
50
+ }
51
+ /**
52
+ * Interpolate template variables in markdown text.
53
+ * Supports {queryName.rows[0].columnName} syntax.
54
+ */
55
+ export function interpolateTemplates(text, queryResults) {
56
+ return text.replace(/\{(\w+)\.rows\[(\d+)\]\.(\w+)\}/g, (match, queryName, rowIdx, colName) => {
57
+ const rows = queryResults.get(queryName);
58
+ if (!rows)
59
+ return match;
60
+ const row = rows[parseInt(rowIdx, 10)];
61
+ if (!row)
62
+ return match;
63
+ const value = row[colName];
64
+ return value !== undefined ? String(value) : match;
65
+ });
66
+ }
67
+ /**
68
+ * Replace SQL blocks in markdown content with placeholder markers
69
+ * that can be replaced with rendered components.
70
+ */
71
+ export function markSqlBlocks(content) {
72
+ return content.replace(/```sql\s+(\w[\w-]*)\s*\n([\s\S]*?)```/g, (_, name) => `<div data-sql-block="${name}"></div>`);
73
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Renders markdown to HTML with GFM support.
3
+ * Code blocks use reversed Shiki theme (dark on light, light on dark)
4
+ * and include a copy button.
5
+ */
6
+ export declare function renderMarkdown(markdown: string): Promise<string>;
7
+ /**
8
+ * Detect whether text is primarily RTL by sampling the first 1000 characters.
9
+ */
10
+ export declare function detectRTL(text: string): boolean;
11
+ /**
12
+ * Post-process rendered HTML for RTL/LTR direction.
13
+ * Uses DOM-based approach for reliable mixed content handling.
14
+ * Code blocks always get LTR. In RTL docs, individual block elements
15
+ * get direction based on their content language.
16
+ * Western digits (0-9) are LTR, Arabic-Indic digits (٠-٩) are RTL.
17
+ */
18
+ export declare function processDirection(html: string, isRTL: boolean): string;
@@ -0,0 +1,146 @@
1
+ import { Marked } from 'marked';
2
+ import { extensionToShikiLang, highlightCodeReversed } from './shiki';
3
+ let markedInstance = null;
4
+ function getMarked() {
5
+ if (markedInstance)
6
+ return markedInstance;
7
+ markedInstance = new Marked({
8
+ async: true,
9
+ gfm: true,
10
+ breaks: false
11
+ });
12
+ markedInstance.use({
13
+ renderer: {
14
+ code({ text, lang }) {
15
+ const escaped = text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
16
+ if (lang === 'mermaid') {
17
+ return `<div class="mermaid">${escaped}</div>`;
18
+ }
19
+ return `<pre class="shiki-pending" data-lang="${lang || ''}" data-code="${encodeURIComponent(text)}"><code>${escaped}</code></pre>`;
20
+ }
21
+ }
22
+ });
23
+ return markedInstance;
24
+ }
25
+ /**
26
+ * Renders markdown to HTML with GFM support.
27
+ * Code blocks use reversed Shiki theme (dark on light, light on dark)
28
+ * and include a copy button.
29
+ */
30
+ export async function renderMarkdown(markdown) {
31
+ const marked = getMarked();
32
+ let html = await marked.parse(markdown);
33
+ // Post-process: highlight code blocks with Shiki (reversed theme)
34
+ const codeBlockRegex = /<pre class="shiki-pending" data-lang="([^"]*)" data-code="([^"]*)"><code>[\s\S]*?<\/code><\/pre>/g;
35
+ const matches = [...html.matchAll(codeBlockRegex)];
36
+ for (const match of matches) {
37
+ const lang = match[1];
38
+ const code = decodeURIComponent(match[2]);
39
+ const shikiLang = lang ? (extensionToShikiLang(`.${lang}`) ?? lang) : undefined;
40
+ try {
41
+ const highlighted = await highlightCodeReversed(code, shikiLang);
42
+ // Wrap in a container with copy button
43
+ const langLabel = lang ? `<span class="code-lang">${lang}</span>` : '';
44
+ const copyBtn = `<button class="code-copy-btn" data-code="${encodeURIComponent(code)}" title="Copy">${langLabel}<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg></button>`;
45
+ const wrapped = `<div class="code-block-wrapper">${copyBtn}${highlighted}</div>`;
46
+ html = html.replace(match[0], wrapped);
47
+ }
48
+ catch {
49
+ // If highlighting fails, keep the escaped version
50
+ }
51
+ }
52
+ return html;
53
+ }
54
+ // RTL unicode ranges: Arabic, Hebrew, Arabic Supplement, Arabic Extended
55
+ const RTL_CHAR_REGEX = /[\u0590-\u05FF\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF\uFB50-\uFDFF\uFE70-\uFEFF]/;
56
+ // Arabic-Indic digits: ٠١٢٣٤٥٦٧٨٩ and Extended Arabic-Indic: ۰۱۲۳۴۵۶۷۸۹
57
+ const ARABIC_DIGIT_REGEX = /[\u0660-\u0669\u06F0-\u06F9]/;
58
+ // Western digits
59
+ const WESTERN_DIGIT_REGEX = /[0-9]/;
60
+ /**
61
+ * Detect whether text is primarily RTL by sampling the first 1000 characters.
62
+ */
63
+ export function detectRTL(text) {
64
+ const sample = text.slice(0, 1000);
65
+ let rtlCount = 0;
66
+ for (const char of sample) {
67
+ if (RTL_CHAR_REGEX.test(char))
68
+ rtlCount++;
69
+ }
70
+ return rtlCount > 5;
71
+ }
72
+ /**
73
+ * Determine if a text segment should be LTR.
74
+ * - Text with Latin first strong char and more Latin than Arabic → LTR
75
+ * - Text with only Western digits (0-9) and no Arabic chars → LTR
76
+ * - Text with Arabic-Indic digits (٠-٩) → RTL
77
+ * - Text with Arabic first strong char → RTL
78
+ */
79
+ function shouldBeLTR(text) {
80
+ if (!text)
81
+ return false;
82
+ // Find the first strong directional character (Arabic or Latin)
83
+ const match = text.match(/[\u0600-\u06FFa-zA-Z]/);
84
+ if (match) {
85
+ // Has strong directional characters
86
+ if (/[a-zA-Z]/.test(match[0])) {
87
+ // First strong char is Latin — confirm with count
88
+ const arabicCount = (text.match(/[\u0600-\u06FF]/g) || []).length;
89
+ const englishCount = (text.match(/[a-zA-Z]/g) || []).length;
90
+ return englishCount > arabicCount;
91
+ }
92
+ // First strong char is Arabic → RTL
93
+ return false;
94
+ }
95
+ // No strong directional chars — check digits
96
+ const hasWesternDigits = WESTERN_DIGIT_REGEX.test(text);
97
+ const hasArabicDigits = ARABIC_DIGIT_REGEX.test(text);
98
+ if (hasArabicDigits)
99
+ return false; // Arabic-Indic digits → RTL
100
+ if (hasWesternDigits)
101
+ return true; // Western digits → LTR
102
+ // No directional content at all — inherit parent direction
103
+ return false;
104
+ }
105
+ /**
106
+ * Post-process rendered HTML for RTL/LTR direction.
107
+ * Uses DOM-based approach for reliable mixed content handling.
108
+ * Code blocks always get LTR. In RTL docs, individual block elements
109
+ * get direction based on their content language.
110
+ * Western digits (0-9) are LTR, Arabic-Indic digits (٠-٩) are RTL.
111
+ */
112
+ export function processDirection(html, isRTL) {
113
+ if (typeof document === 'undefined')
114
+ return html;
115
+ if (!isRTL)
116
+ return html;
117
+ const container = document.createElement('div');
118
+ container.innerHTML = html;
119
+ // Code blocks are always LTR
120
+ for (const el of container.querySelectorAll('pre, code')) {
121
+ el.style.direction = 'ltr';
122
+ el.style.textAlign = 'left';
123
+ }
124
+ // Process each block element for mixed content
125
+ for (const el of container.querySelectorAll('p, li, h1, h2, h3, h4, h5, h6, td, th')) {
126
+ const text = el.textContent || '';
127
+ if (shouldBeLTR(text)) {
128
+ el.style.direction = 'ltr';
129
+ el.style.textAlign = 'left';
130
+ // For lists in RTL context with LTR content, swap padding
131
+ if (el.tagName === 'LI') {
132
+ const parent = el.parentElement;
133
+ if (parent && (parent.tagName === 'UL' || parent.tagName === 'OL')) {
134
+ parent.style.paddingLeft = '2em';
135
+ parent.style.paddingRight = '0';
136
+ }
137
+ }
138
+ }
139
+ else {
140
+ // Explicitly set RTL direction on Arabic content
141
+ el.style.direction = 'rtl';
142
+ el.style.textAlign = 'right';
143
+ }
144
+ }
145
+ return container.innerHTML;
146
+ }