@hiai-gg/docsmint 0.3.7 → 0.3.9

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 (210) hide show
  1. package/backend/src/lib/logger.ts +45 -15
  2. package/dist/backend/index.js +238 -150
  3. package/dist/client.d.ts +11 -0
  4. package/dist/client.js +9 -0
  5. package/dist/frontend/CategoryDialog-CxVyaBV5.js +611 -0
  6. package/dist/frontend/ConfirmDialog-NFGXRa3E.js +214 -0
  7. package/dist/frontend/CreateSnapshotDialog-BDgFTeFn.js +216 -0
  8. package/dist/frontend/DatePicker-BZRBluzF.js +256 -0
  9. package/dist/frontend/DeleteDialog-CvAr2WPu.js +174 -0
  10. package/dist/frontend/FolderNode-C6FJv99G.js +298 -0
  11. package/dist/frontend/FolderTreeSelector-CyB8y2Sm.js +103 -0
  12. package/dist/frontend/HiaiDocsExtensionProvider-DHWLzRUu.js +11 -0
  13. package/dist/frontend/Icon-CooFj4Ee.js +64 -0
  14. package/dist/frontend/SettingsDialog-BHh68rTB.js +1016 -0
  15. package/dist/frontend/ShareDialog-BUOkYSlw.js +165 -0
  16. package/dist/frontend/Sidebar-Cu3JrKDC.js +2021 -0
  17. package/dist/frontend/TagCreateDialog-B9YZBNHi.js +260 -0
  18. package/dist/frontend/api/settings.js +1 -1
  19. package/dist/frontend/app-shell.d.ts +8 -0
  20. package/dist/frontend/app-shell.js +291 -0
  21. package/dist/frontend/{bundle-mjs-CP6Owz-8.js → bundle-mjs-DllmqUxV.js} +583 -568
  22. package/dist/frontend/camera-iKXDOOWT.js +29 -0
  23. package/dist/frontend/check-D-UuvBuh.js +25 -0
  24. package/dist/frontend/chevron-down-CiPtYyFh.js +25 -0
  25. package/dist/frontend/circle-check-tSPE1V6t.js +29 -0
  26. package/dist/frontend/clock-DJHbHZb8.js +29 -0
  27. package/dist/frontend/components/category-dialog.js +1 -1
  28. package/dist/frontend/components/create-snapshot-dialog.js +1 -1
  29. package/dist/frontend/components/delete-dialog.js +1 -1
  30. package/dist/frontend/components/editor/document-editor.js +1367 -1356
  31. package/dist/frontend/components/editor/document-title.js +25 -25
  32. package/dist/frontend/components/editor/markdown-toggle.js +45 -45
  33. package/dist/frontend/components/folder-node.js +1 -1
  34. package/dist/frontend/components/folder-tree-selector.js +1 -1
  35. package/dist/frontend/components/save-as-dialog.js +169 -151
  36. package/dist/frontend/components/settings.js +1 -1
  37. package/dist/frontend/components/share-dialog.js +1 -1
  38. package/dist/frontend/components/sidebar.js +2 -2013
  39. package/dist/frontend/components/tag-create-dialog.js +1 -1
  40. package/dist/frontend/components/version-history.js +188 -187
  41. package/dist/frontend/confirm-dialog-C4jTRbiS.js +250 -0
  42. package/dist/frontend/copy-GppwRMjX.js +32 -0
  43. package/dist/frontend/dashboard.js +1187 -1155
  44. package/dist/frontend/dialog-Bevp9mmM.js +213 -0
  45. package/dist/frontend/{loader-circle-Bk-WFz9g.js → dist-C3857Spp.js} +93 -92
  46. package/dist/frontend/doc-tabs.js +2 -2
  47. package/dist/frontend/dropdown-menu-CRSby3e9.js +530 -0
  48. package/dist/frontend/extension.js +2 -11
  49. package/dist/frontend/{floating-layer-anchor-C51M4l6v.js → floating-layer-anchor-BDs7vO-M.js} +1414 -1412
  50. package/dist/frontend/folder-DeWhnD7O.js +45 -0
  51. package/dist/frontend/folder-refresh.js +1 -1
  52. package/dist/frontend/frontend.css +1 -1
  53. package/dist/frontend/i18n.js +2 -2
  54. package/dist/frontend/input-BWlOML_m.js +23 -0
  55. package/dist/frontend/keyboard.js +1 -1
  56. package/dist/frontend/{keyboard.svelte-D7H8DihC.js → keyboard.svelte-CApmX0vl.js} +53 -53
  57. package/dist/frontend/label-C2HfJNQ2.js +30 -0
  58. package/dist/frontend/{messages-BpYaLbzE.js → messages-C5Q890i2.js} +8 -8
  59. package/dist/frontend/rotate-ccw-B4Q7brmV.js +25 -0
  60. package/dist/frontend/search.js +673 -647
  61. package/dist/frontend/select-value-GXwx90Pr.js +1446 -0
  62. package/dist/frontend/{settings-blyobazp.js → settings-DSrUl4hW.js} +9 -9
  63. package/dist/frontend/shared-document.js +94 -94
  64. package/dist/frontend/subfolders-refresh-store.svelte-B2dKVmgz.js +65 -0
  65. package/dist/frontend/tag-HxRazVN_.js +54 -0
  66. package/dist/frontend/tag-store.svelte-CqrUXo0o.js +29 -0
  67. package/dist/frontend/textarea-DOAE-h42.js +23 -0
  68. package/dist/frontend/theme.js +1 -1
  69. package/dist/frontend/theme.svelte-DKfCy12k.js +49 -0
  70. package/dist/frontend/{utils-D8kmM3ub.js → utils-BPDRytUU.js} +2 -3
  71. package/dist/frontend/{utils-C0OW2678.js → utils-DrfHTcei.js} +2 -3
  72. package/dist/frontend/utils.js +1 -1
  73. package/dist/frontend/x-CzBsnJ2x.js +25 -0
  74. package/dist/frontend-ssr/api/attachments.js +2 -0
  75. package/dist/frontend-ssr/api/categories.js +2 -0
  76. package/dist/frontend-ssr/api/documents.js +2 -0
  77. package/dist/frontend-ssr/api/folders.js +2 -0
  78. package/dist/frontend-ssr/api/settings.js +2 -0
  79. package/dist/frontend-ssr/api/share.js +2 -0
  80. package/dist/frontend-ssr/api/tags.js +2 -0
  81. package/dist/frontend-ssr/app-shell.js +294 -0
  82. package/dist/frontend-ssr/assets/CategoryDialog-BcGW8-Kf.js +584 -0
  83. package/dist/frontend-ssr/assets/ConfirmDialog-DjMFKc0V.js +420 -0
  84. package/dist/frontend-ssr/assets/CreateSnapshotDialog-1bROJ-Rn.js +214 -0
  85. package/dist/frontend-ssr/assets/DatePicker-B1ML8OVz.js +312 -0
  86. package/dist/frontend-ssr/assets/DeleteDialog-tBYaP0L3.js +154 -0
  87. package/dist/frontend-ssr/assets/FolderNode-BZ0Q2QUS.js +171 -0
  88. package/dist/frontend-ssr/assets/FolderTreeSelector-DZNZ2oI6.js +147 -0
  89. package/dist/frontend-ssr/assets/HiaiDocsExtensionProvider-DAM-lX4R.js +13 -0
  90. package/dist/frontend-ssr/assets/Icon-B0Zqppjo.js +231 -0
  91. package/dist/frontend-ssr/assets/SettingsDialog-B8L_YqNA.js +1107 -0
  92. package/dist/frontend-ssr/assets/ShareDialog-vMvJLRfn.js +54 -0
  93. package/dist/frontend-ssr/assets/Sidebar-EHuUAx3W.js +2033 -0
  94. package/dist/frontend-ssr/assets/TagCreateDialog-B0DPEfmQ.js +264 -0
  95. package/dist/frontend-ssr/assets/api-keys-DFqX39MT.js +35 -0
  96. package/dist/frontend-ssr/assets/attachments-CWBxE3Vz.js +85 -0
  97. package/dist/frontend-ssr/assets/auth-client-x26kqY8Z.js +1286 -0
  98. package/dist/frontend-ssr/assets/camera-CdxscTw-.js +84 -0
  99. package/dist/frontend-ssr/assets/categories-AOqgcsn4.js +75 -0
  100. package/dist/frontend-ssr/assets/chevron-down-CSSNGNh_.js +80 -0
  101. package/dist/frontend-ssr/assets/chevron-right-B4p7Sk6X.js +80 -0
  102. package/dist/frontend-ssr/assets/circle-check-CI1v4vYh.js +84 -0
  103. package/dist/frontend-ssr/assets/client-DZMkDkDn.js +129 -0
  104. package/dist/frontend-ssr/assets/clipboard-CXOaoz2W.js +30 -0
  105. package/dist/frontend-ssr/assets/clock-IL-eX2di.js +84 -0
  106. package/dist/frontend-ssr/assets/confirm-dialog-BCthVwUY.js +429 -0
  107. package/dist/frontend-ssr/assets/context-jz1GGEUi.js +45 -0
  108. package/dist/frontend-ssr/assets/copy-CjV57nGQ.js +87 -0
  109. package/dist/frontend-ssr/assets/db-CnxeO66n.js +65 -0
  110. package/dist/frontend-ssr/assets/dialog-BOV1u6zP.js +157 -0
  111. package/dist/frontend-ssr/assets/dndzone-DMvTO_Jz.js +2114 -0
  112. package/dist/frontend-ssr/assets/document-drop-coordinator-CEaYACsC.js +109 -0
  113. package/dist/frontend-ssr/assets/documents-BnOTRdTY.js +108 -0
  114. package/dist/frontend-ssr/assets/dropdown-menu-Bj5rbqbB.js +555 -0
  115. package/dist/frontend-ssr/assets/editorExtensions-DUzwndMy.js +186 -0
  116. package/dist/frontend-ssr/assets/floating-layer-anchor-CYIE8Oj6.js +6114 -0
  117. package/dist/frontend-ssr/assets/folder-DChhG7qN.js +80 -0
  118. package/dist/frontend-ssr/assets/folders-CTfbS24J.js +127 -0
  119. package/dist/frontend-ssr/assets/identity-B3uHoDtf.js +99 -0
  120. package/dist/frontend-ssr/assets/input-DezGsU3y.js +19 -0
  121. package/dist/frontend-ssr/assets/keyboard.svelte-BgF47N3L.js +174 -0
  122. package/dist/frontend-ssr/assets/label-Bj8-TfFN.js +21 -0
  123. package/dist/frontend-ssr/assets/loader-circle-DZsrZ-er.js +80 -0
  124. package/dist/frontend-ssr/assets/markdown-CjqvGi5W.js +20 -0
  125. package/dist/frontend-ssr/assets/messages-CvqpZNJe.js +11125 -0
  126. package/dist/frontend-ssr/assets/resolve-BqHozBXl.js +32 -0
  127. package/dist/frontend-ssr/assets/rotate-ccw-BlgWwaiq.js +80 -0
  128. package/dist/frontend-ssr/assets/select-value-6Lk0ToYd.js +1526 -0
  129. package/dist/frontend-ssr/assets/settings-Bk5Hk9Vq.js +64 -0
  130. package/dist/frontend-ssr/assets/share-BTBJelxA.js +30 -0
  131. package/dist/frontend-ssr/assets/subfolders-refresh-store.svelte-DAh4gT16.js +77 -0
  132. package/dist/frontend-ssr/assets/tag-GZEuGWk1.js +166 -0
  133. package/dist/frontend-ssr/assets/tag-store.svelte-DPodKj6Z.js +21 -0
  134. package/dist/frontend-ssr/assets/tags-BId2wdYd.js +49 -0
  135. package/dist/frontend-ssr/assets/textarea-Dev-qSEc.js +21 -0
  136. package/dist/frontend-ssr/assets/theme.svelte-Co0-ssaD.js +67 -0
  137. package/dist/frontend-ssr/assets/utils-DtlPPXpJ.js +9 -0
  138. package/dist/frontend-ssr/assets/utils-DvZnctjz.js +23 -0
  139. package/dist/frontend-ssr/collaboration.js +39 -0
  140. package/dist/frontend-ssr/components/category-dialog.js +2 -0
  141. package/dist/frontend-ssr/components/create-snapshot-dialog.js +2 -0
  142. package/dist/frontend-ssr/components/delete-dialog.js +2 -0
  143. package/dist/frontend-ssr/components/editor/document-editor.js +2499 -0
  144. package/dist/frontend-ssr/components/editor/document-title.js +11 -0
  145. package/dist/frontend-ssr/components/editor/docx-serializer.js +186 -0
  146. package/dist/frontend-ssr/components/editor/extensions.js +2 -0
  147. package/dist/frontend-ssr/components/editor/markdown-toggle.js +20 -0
  148. package/dist/frontend-ssr/components/editor/markdown.js +2 -0
  149. package/dist/frontend-ssr/components/folder-node.js +2 -0
  150. package/dist/frontend-ssr/components/folder-tree-selector.js +2 -0
  151. package/dist/frontend-ssr/components/save-as-dialog.js +280 -0
  152. package/dist/frontend-ssr/components/settings.js +2 -0
  153. package/dist/frontend-ssr/components/share-dialog.js +2 -0
  154. package/dist/frontend-ssr/components/sidebar.js +2 -0
  155. package/dist/frontend-ssr/components/tag-create-dialog.js +2 -0
  156. package/dist/frontend-ssr/components/version-history.js +370 -0
  157. package/dist/frontend-ssr/dashboard.js +2542 -0
  158. package/dist/frontend-ssr/doc-tabs.js +23 -0
  159. package/dist/frontend-ssr/document-drop-coordinator.js +2 -0
  160. package/dist/frontend-ssr/extension.js +2 -0
  161. package/dist/frontend-ssr/folder-refresh.js +2 -0
  162. package/dist/frontend-ssr/i18n.js +10 -0
  163. package/dist/frontend-ssr/keyboard.js +2 -0
  164. package/dist/frontend-ssr/offline/identity.js +2 -0
  165. package/dist/frontend-ssr/search.js +332 -0
  166. package/dist/frontend-ssr/shared-document.js +273 -0
  167. package/dist/frontend-ssr/theme.js +9 -0
  168. package/dist/frontend-ssr/types.js +1 -0
  169. package/dist/frontend-ssr/utils/clipboard.js +2 -0
  170. package/dist/frontend-ssr/utils/dndzone.js +2 -0
  171. package/dist/frontend-ssr/utils.js +2 -0
  172. package/package.json +28 -1
  173. package/packages/cli/src/index.ts +1 -1
  174. package/packages/db/src/schema.ts +3 -0
  175. package/packages/mcp-server/src/index.ts +1 -1
  176. package/dist/frontend/CategoryDialog--rIE7FrH.js +0 -580
  177. package/dist/frontend/ConfirmDialog-Cpzyb55f.js +0 -212
  178. package/dist/frontend/CreateSnapshotDialog-CmkV-n2A.js +0 -216
  179. package/dist/frontend/DatePicker-Byynca7V.js +0 -257
  180. package/dist/frontend/DeleteDialog-ap6nOywZ.js +0 -174
  181. package/dist/frontend/FolderDialog-DmN_trV0.js +0 -247
  182. package/dist/frontend/FolderNode-C4B8a2fd.js +0 -317
  183. package/dist/frontend/FolderTreeSelector-D6ijiZTA.js +0 -100
  184. package/dist/frontend/Icon-DtNo0N1U.js +0 -64
  185. package/dist/frontend/SettingsDialog-2kTaTXAs.js +0 -992
  186. package/dist/frontend/ShareDialog-BBDGNF5n.js +0 -165
  187. package/dist/frontend/TagCreateDialog-DiLZnJo4.js +0 -258
  188. package/dist/frontend/camera-B7dAOd4s.js +0 -28
  189. package/dist/frontend/check-CDwRlG9T.js +0 -24
  190. package/dist/frontend/chevron-down-B7ZrjUmT.js +0 -24
  191. package/dist/frontend/circle-check-CDqeMB2d.js +0 -28
  192. package/dist/frontend/client-Bc5Fzx40.js +0 -2785
  193. package/dist/frontend/clock-Ck5Sn-Zl.js +0 -28
  194. package/dist/frontend/clsx-nmtDPO_P.js +0 -16
  195. package/dist/frontend/copy-CMAA6GP0.js +0 -31
  196. package/dist/frontend/dialog-BDkiG42a.js +0 -213
  197. package/dist/frontend/disclose-version-5I57E3LD.js +0 -3
  198. package/dist/frontend/ellipsis-vertical-BBuPldbW.js +0 -519
  199. package/dist/frontend/folder-TQjKY4yn.js +0 -44
  200. package/dist/frontend/index-client-jobkrWVL.js +0 -86
  201. package/dist/frontend/input-CBI6p4Xl.js +0 -23
  202. package/dist/frontend/label-C-GkhEp4.js +0 -30
  203. package/dist/frontend/rotate-ccw-CleZtJ5D.js +0 -24
  204. package/dist/frontend/select-value-CvrWRkXW.js +0 -1436
  205. package/dist/frontend/subfolders-refresh-store.svelte-BsheoQma.js +0 -65
  206. package/dist/frontend/tag-Dx3SmucJ.js +0 -53
  207. package/dist/frontend/tag-store.svelte-CIaF4sdZ.js +0 -29
  208. package/dist/frontend/textarea-Dfp78XlL.js +0 -23
  209. package/dist/frontend/theme.svelte-CROg1Hi5.js +0 -49
  210. package/dist/frontend/x-DaTdeDXv.js +0 -24
@@ -0,0 +1,2033 @@
1
+ import { $n as search_placeholder, Ar as doc_delete_success_description, Dr as doc_delete, E as sidebar_powered_by, Ln as settings_title, Lr as dashboard_new_document, Mr as doc_delete_confirm, Or as doc_share, Pr as doc_title_label, S as categories_new, _n as action_save, _t as tags_load_error, an as sidebar_recent, d as sidebar_uncategorized, er as search_title, fr as folders_name_placeholder, gn as action_cancel, gr as folders_delete_title, hn as action_delete, in as sidebar_folders, jr as doc_delete_success, kr as doc_tags, ln as action_loading, mn as action_edit, mr as folders_delete_success, nr as tags_delete_description, or as tags_new, pr as folders_delete_success_description, rr as tags_delete_title, tr as tags_add, un as action_go_to, vr as folders_rename, vt as action_copy_content, xr as folders_new, yn as error_generic, yt as editor_more_options, zr as dashboard_title } from "./messages-CvqpZNJe.js";
2
+ import { t as Icon } from "./Icon-B0Zqppjo.js";
3
+ import { i as Check, n as Plus, r as File_text, t as FolderDialog } from "./confirm-dialog-BCthVwUY.js";
4
+ import { t as Chevron_down } from "./chevron-down-CSSNGNh_.js";
5
+ import { t as Chevron_right } from "./chevron-right-B4p7Sk6X.js";
6
+ import { t as Clock } from "./clock-IL-eX2di.js";
7
+ import { t as Copy } from "./copy-CjV57nGQ.js";
8
+ import { t as Folder } from "./folder-DChhG7qN.js";
9
+ import { t as SettingsDialog } from "./SettingsDialog-B8L_YqNA.js";
10
+ import { n as Search, t as Tag } from "./tag-GZEuGWk1.js";
11
+ import { a as Dropdown_menu, i as Dropdown_menu_content, o as Ellipsis_vertical, r as Dropdown_menu_item, t as Dropdown_menu_trigger } from "./dropdown-menu-Bj5rbqbB.js";
12
+ import { t as Loader_circle } from "./loader-circle-DZsrZ-er.js";
13
+ import { t as cn } from "./utils-DvZnctjz.js";
14
+ import { a as Dialog, i as Dialog_description, n as Dialog_header, o as Button, r as Dialog_footer, t as Dialog_title } from "./dialog-BOV1u6zP.js";
15
+ import { t as Input } from "./input-DezGsU3y.js";
16
+ import { t as Label } from "./label-Bj8-TfFN.js";
17
+ import { n as apiFetch } from "./client-DZMkDkDn.js";
18
+ import { i as listCategories, r as deleteCategory } from "./categories-AOqgcsn4.js";
19
+ import { t as getFrontendExtensions } from "./context-jz1GGEUi.js";
20
+ import { t as resolveExtensions } from "./resolve-BqHozBXl.js";
21
+ import { n as SHADOW_ITEM_MARKER_PROPERTY_NAME } from "./dndzone-DMvTO_Jz.js";
22
+ import { c as updateDocument, r as deleteDocument, s as listDocuments, t as clearDocumentsCache } from "./documents-BnOTRdTY.js";
23
+ import { c as updateFolder, r as deleteFolder, s as listFolders, t as createFolder } from "./folders-CTfbS24J.js";
24
+ import { t as DeleteDialog } from "./DeleteDialog-tBYaP0L3.js";
25
+ import { t as ShareDialog } from "./ShareDialog-vMvJLRfn.js";
26
+ import { t as CategoryDialog } from "./CategoryDialog-BcGW8-Kf.js";
27
+ import { n as createDocumentPlacementWriter, t as createDocumentDropCoordinator } from "./document-drop-coordinator-CEaYACsC.js";
28
+ import { a as getFolderFromRegistry, c as getPendingDocumentPlacement, f as registerDocument, n as bumpSubfoldersRefresh, p as registerFolder, r as getDocumentFromRegistry, t as acknowledgeDocumentPlacement, u as publishDocumentPlacement } from "./subfolders-refresh-store.svelte-DAh4gT16.js";
29
+ import { t as FolderNode } from "./FolderNode-BZ0Q2QUS.js";
30
+ import { i as setSelectedTag, n as refreshDocs, r as refreshTags, t as getSelectedTag } from "./tag-store.svelte-DPodKj6Z.js";
31
+ import { t as ConfirmDialog } from "./ConfirmDialog-DjMFKc0V.js";
32
+ import { i as deleteTag, o as listTags } from "./tags-BId2wdYd.js";
33
+ import { t as TagCreateDialog } from "./TagCreateDialog-B0DPEfmQ.js";
34
+ import * as $ from "svelte/internal/server";
35
+ import { onDestroy, onMount } from "svelte";
36
+ import { goto } from "$app/navigation";
37
+ import { page } from "$app/state";
38
+ import "svelte/animate";
39
+ //#region ../node_modules/.bun/lucide-svelte@1.0.1+ff5f301bb2db9a0d/node_modules/lucide-svelte/dist/icons/panel-left-close.svelte
40
+ function Panel_left_close($$renderer, $$props) {
41
+ const $$sanitized_props = $.sanitize_props($$props);
42
+ /**
43
+ * @license lucide-svelte v1.0.1 - ISC
44
+ *
45
+ * ISC License
46
+ *
47
+ * Copyright (c) 2026 Lucide Icons and Contributors
48
+ *
49
+ * Permission to use, copy, modify, and/or distribute this software for any
50
+ * purpose with or without fee is hereby granted, provided that the above
51
+ * copyright notice and this permission notice appear in all copies.
52
+ *
53
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
54
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
55
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
56
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
57
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
58
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
59
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
60
+ *
61
+ * ---
62
+ *
63
+ * The following Lucide icons are derived from the Feather project:
64
+ *
65
+ * airplay, alert-circle, alert-octagon, alert-triangle, aperture, arrow-down-circle, arrow-down-left, arrow-down-right, arrow-down, arrow-left-circle, arrow-left, arrow-right-circle, arrow-right, arrow-up-circle, arrow-up-left, arrow-up-right, arrow-up, at-sign, calendar, cast, check, chevron-down, chevron-left, chevron-right, chevron-up, chevrons-down, chevrons-left, chevrons-right, chevrons-up, circle, clipboard, clock, code, columns, command, compass, corner-down-left, corner-down-right, corner-left-down, corner-left-up, corner-right-down, corner-right-up, corner-up-left, corner-up-right, crosshair, database, divide-circle, divide-square, dollar-sign, download, external-link, feather, frown, hash, headphones, help-circle, info, italic, key, layout, life-buoy, link-2, link, loader, lock, log-in, log-out, maximize, meh, minimize, minimize-2, minus-circle, minus-square, minus, monitor, moon, more-horizontal, more-vertical, move, music, navigation-2, navigation, octagon, pause-circle, percent, plus-circle, plus-square, plus, power, radio, rss, search, server, share, shopping-bag, sidebar, smartphone, smile, square, table-2, tablet, target, terminal, trash-2, trash, triangle, tv, type, upload, x-circle, x-octagon, x-square, x, zoom-in, zoom-out
66
+ *
67
+ * The MIT License (MIT) (for the icons listed above)
68
+ *
69
+ * Copyright (c) 2013-present Cole Bemis
70
+ *
71
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
72
+ * of this software and associated documentation files (the "Software"), to deal
73
+ * in the Software without restriction, including without limitation the rights
74
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
75
+ * copies of the Software, and to permit persons to whom the Software is
76
+ * furnished to do so, subject to the following conditions:
77
+ *
78
+ * The above copyright notice and this permission notice shall be included in all
79
+ * copies or substantial portions of the Software.
80
+ *
81
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
82
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
83
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
84
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
85
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
86
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
87
+ * SOFTWARE.
88
+ *
89
+ */
90
+ Icon($$renderer, $.spread_props([
91
+ { name: "panel-left-close" },
92
+ $$sanitized_props,
93
+ {
94
+ /**
95
+ * @component @name PanelLeftClose
96
+ * @description Lucide SVG icon component, renders SVG Element with children.
97
+ *
98
+ * @preview ![img](data:image/svg+xml;base64,PHN2ZyAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogIHdpZHRoPSIyNCIKICBoZWlnaHQ9IjI0IgogIHZpZXdCb3g9IjAgMCAyNCAyNCIKICBmaWxsPSJub25lIgogIHN0cm9rZT0iIzAwMCIgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6ICNmZmY7IGJvcmRlci1yYWRpdXM6IDJweCIKICBzdHJva2Utd2lkdGg9IjIiCiAgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIgogIHN0cm9rZS1saW5lam9pbj0icm91bmQiCj4KICA8cmVjdCB3aWR0aD0iMTgiIGhlaWdodD0iMTgiIHg9IjMiIHk9IjMiIHJ4PSIyIiAvPgogIDxwYXRoIGQ9Ik05IDN2MTgiIC8+CiAgPHBhdGggZD0ibTE2IDE1LTMtMyAzLTMiIC8+Cjwvc3ZnPgo=) - https://lucide.dev/icons/panel-left-close
99
+ * @see https://lucide.dev/guide/packages/lucide-svelte - Documentation
100
+ *
101
+ * @param {Object} props - Lucide icons props and any valid SVG attribute
102
+ * @returns {FunctionalComponent} Svelte component
103
+ *
104
+ */
105
+ iconNode: [
106
+ ["rect", {
107
+ "width": "18",
108
+ "height": "18",
109
+ "x": "3",
110
+ "y": "3",
111
+ "rx": "2"
112
+ }],
113
+ ["path", { "d": "M9 3v18" }],
114
+ ["path", { "d": "m16 15-3-3 3-3" }]
115
+ ],
116
+ children: ($$renderer) => {
117
+ $$renderer.push(`<!--[-->`);
118
+ $.slot($$renderer, $$props, "default", {}, null);
119
+ $$renderer.push(`<!--]-->`);
120
+ },
121
+ $$slots: { default: true }
122
+ }
123
+ ]));
124
+ }
125
+ //#endregion
126
+ //#region ../node_modules/.bun/lucide-svelte@1.0.1+ff5f301bb2db9a0d/node_modules/lucide-svelte/dist/icons/panel-left-open.svelte
127
+ function Panel_left_open($$renderer, $$props) {
128
+ const $$sanitized_props = $.sanitize_props($$props);
129
+ /**
130
+ * @license lucide-svelte v1.0.1 - ISC
131
+ *
132
+ * ISC License
133
+ *
134
+ * Copyright (c) 2026 Lucide Icons and Contributors
135
+ *
136
+ * Permission to use, copy, modify, and/or distribute this software for any
137
+ * purpose with or without fee is hereby granted, provided that the above
138
+ * copyright notice and this permission notice appear in all copies.
139
+ *
140
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
141
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
142
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
143
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
144
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
145
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
146
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
147
+ *
148
+ * ---
149
+ *
150
+ * The following Lucide icons are derived from the Feather project:
151
+ *
152
+ * airplay, alert-circle, alert-octagon, alert-triangle, aperture, arrow-down-circle, arrow-down-left, arrow-down-right, arrow-down, arrow-left-circle, arrow-left, arrow-right-circle, arrow-right, arrow-up-circle, arrow-up-left, arrow-up-right, arrow-up, at-sign, calendar, cast, check, chevron-down, chevron-left, chevron-right, chevron-up, chevrons-down, chevrons-left, chevrons-right, chevrons-up, circle, clipboard, clock, code, columns, command, compass, corner-down-left, corner-down-right, corner-left-down, corner-left-up, corner-right-down, corner-right-up, corner-up-left, corner-up-right, crosshair, database, divide-circle, divide-square, dollar-sign, download, external-link, feather, frown, hash, headphones, help-circle, info, italic, key, layout, life-buoy, link-2, link, loader, lock, log-in, log-out, maximize, meh, minimize, minimize-2, minus-circle, minus-square, minus, monitor, moon, more-horizontal, more-vertical, move, music, navigation-2, navigation, octagon, pause-circle, percent, plus-circle, plus-square, plus, power, radio, rss, search, server, share, shopping-bag, sidebar, smartphone, smile, square, table-2, tablet, target, terminal, trash-2, trash, triangle, tv, type, upload, x-circle, x-octagon, x-square, x, zoom-in, zoom-out
153
+ *
154
+ * The MIT License (MIT) (for the icons listed above)
155
+ *
156
+ * Copyright (c) 2013-present Cole Bemis
157
+ *
158
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
159
+ * of this software and associated documentation files (the "Software"), to deal
160
+ * in the Software without restriction, including without limitation the rights
161
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
162
+ * copies of the Software, and to permit persons to whom the Software is
163
+ * furnished to do so, subject to the following conditions:
164
+ *
165
+ * The above copyright notice and this permission notice shall be included in all
166
+ * copies or substantial portions of the Software.
167
+ *
168
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
169
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
170
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
171
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
172
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
173
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
174
+ * SOFTWARE.
175
+ *
176
+ */
177
+ Icon($$renderer, $.spread_props([
178
+ { name: "panel-left-open" },
179
+ $$sanitized_props,
180
+ {
181
+ /**
182
+ * @component @name PanelLeftOpen
183
+ * @description Lucide SVG icon component, renders SVG Element with children.
184
+ *
185
+ * @preview ![img](data:image/svg+xml;base64,PHN2ZyAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogIHdpZHRoPSIyNCIKICBoZWlnaHQ9IjI0IgogIHZpZXdCb3g9IjAgMCAyNCAyNCIKICBmaWxsPSJub25lIgogIHN0cm9rZT0iIzAwMCIgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6ICNmZmY7IGJvcmRlci1yYWRpdXM6IDJweCIKICBzdHJva2Utd2lkdGg9IjIiCiAgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIgogIHN0cm9rZS1saW5lam9pbj0icm91bmQiCj4KICA8cmVjdCB3aWR0aD0iMTgiIGhlaWdodD0iMTgiIHg9IjMiIHk9IjMiIHJ4PSIyIiAvPgogIDxwYXRoIGQ9Ik05IDN2MTgiIC8+CiAgPHBhdGggZD0ibTE0IDkgMyAzLTMgMyIgLz4KPC9zdmc+Cg==) - https://lucide.dev/icons/panel-left-open
186
+ * @see https://lucide.dev/guide/packages/lucide-svelte - Documentation
187
+ *
188
+ * @param {Object} props - Lucide icons props and any valid SVG attribute
189
+ * @returns {FunctionalComponent} Svelte component
190
+ *
191
+ */
192
+ iconNode: [
193
+ ["rect", {
194
+ "width": "18",
195
+ "height": "18",
196
+ "x": "3",
197
+ "y": "3",
198
+ "rx": "2"
199
+ }],
200
+ ["path", { "d": "M9 3v18" }],
201
+ ["path", { "d": "m14 9 3 3-3 3" }]
202
+ ],
203
+ children: ($$renderer) => {
204
+ $$renderer.push(`<!--[-->`);
205
+ $.slot($$renderer, $$props, "default", {}, null);
206
+ $$renderer.push(`<!--]-->`);
207
+ },
208
+ $$slots: { default: true }
209
+ }
210
+ ]));
211
+ }
212
+ //#endregion
213
+ //#region ../node_modules/.bun/lucide-svelte@1.0.1+ff5f301bb2db9a0d/node_modules/lucide-svelte/dist/icons/settings.svelte
214
+ function Settings($$renderer, $$props) {
215
+ const $$sanitized_props = $.sanitize_props($$props);
216
+ /**
217
+ * @license lucide-svelte v1.0.1 - ISC
218
+ *
219
+ * ISC License
220
+ *
221
+ * Copyright (c) 2026 Lucide Icons and Contributors
222
+ *
223
+ * Permission to use, copy, modify, and/or distribute this software for any
224
+ * purpose with or without fee is hereby granted, provided that the above
225
+ * copyright notice and this permission notice appear in all copies.
226
+ *
227
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
228
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
229
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
230
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
231
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
232
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
233
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
234
+ *
235
+ * ---
236
+ *
237
+ * The following Lucide icons are derived from the Feather project:
238
+ *
239
+ * airplay, alert-circle, alert-octagon, alert-triangle, aperture, arrow-down-circle, arrow-down-left, arrow-down-right, arrow-down, arrow-left-circle, arrow-left, arrow-right-circle, arrow-right, arrow-up-circle, arrow-up-left, arrow-up-right, arrow-up, at-sign, calendar, cast, check, chevron-down, chevron-left, chevron-right, chevron-up, chevrons-down, chevrons-left, chevrons-right, chevrons-up, circle, clipboard, clock, code, columns, command, compass, corner-down-left, corner-down-right, corner-left-down, corner-left-up, corner-right-down, corner-right-up, corner-up-left, corner-up-right, crosshair, database, divide-circle, divide-square, dollar-sign, download, external-link, feather, frown, hash, headphones, help-circle, info, italic, key, layout, life-buoy, link-2, link, loader, lock, log-in, log-out, maximize, meh, minimize, minimize-2, minus-circle, minus-square, minus, monitor, moon, more-horizontal, more-vertical, move, music, navigation-2, navigation, octagon, pause-circle, percent, plus-circle, plus-square, plus, power, radio, rss, search, server, share, shopping-bag, sidebar, smartphone, smile, square, table-2, tablet, target, terminal, trash-2, trash, triangle, tv, type, upload, x-circle, x-octagon, x-square, x, zoom-in, zoom-out
240
+ *
241
+ * The MIT License (MIT) (for the icons listed above)
242
+ *
243
+ * Copyright (c) 2013-present Cole Bemis
244
+ *
245
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
246
+ * of this software and associated documentation files (the "Software"), to deal
247
+ * in the Software without restriction, including without limitation the rights
248
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
249
+ * copies of the Software, and to permit persons to whom the Software is
250
+ * furnished to do so, subject to the following conditions:
251
+ *
252
+ * The above copyright notice and this permission notice shall be included in all
253
+ * copies or substantial portions of the Software.
254
+ *
255
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
256
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
257
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
258
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
259
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
260
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
261
+ * SOFTWARE.
262
+ *
263
+ */
264
+ Icon($$renderer, $.spread_props([
265
+ { name: "settings" },
266
+ $$sanitized_props,
267
+ {
268
+ /**
269
+ * @component @name Settings
270
+ * @description Lucide SVG icon component, renders SVG Element with children.
271
+ *
272
+ * @preview ![img](data:image/svg+xml;base64,PHN2ZyAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogIHdpZHRoPSIyNCIKICBoZWlnaHQ9IjI0IgogIHZpZXdCb3g9IjAgMCAyNCAyNCIKICBmaWxsPSJub25lIgogIHN0cm9rZT0iIzAwMCIgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6ICNmZmY7IGJvcmRlci1yYWRpdXM6IDJweCIKICBzdHJva2Utd2lkdGg9IjIiCiAgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIgogIHN0cm9rZS1saW5lam9pbj0icm91bmQiCj4KICA8cGF0aCBkPSJNOS42NzEgNC4xMzZhMi4zNCAyLjM0IDAgMCAxIDQuNjU5IDAgMi4zNCAyLjM0IDAgMCAwIDMuMzE5IDEuOTE1IDIuMzQgMi4zNCAwIDAgMSAyLjMzIDQuMDMzIDIuMzQgMi4zNCAwIDAgMCAwIDMuODMxIDIuMzQgMi4zNCAwIDAgMS0yLjMzIDQuMDMzIDIuMzQgMi4zNCAwIDAgMC0zLjMxOSAxLjkxNSAyLjM0IDIuMzQgMCAwIDEtNC42NTkgMCAyLjM0IDIuMzQgMCAwIDAtMy4zMi0xLjkxNSAyLjM0IDIuMzQgMCAwIDEtMi4zMy00LjAzMyAyLjM0IDIuMzQgMCAwIDAgMC0zLjgzMUEyLjM0IDIuMzQgMCAwIDEgNi4zNSA2LjA1MWEyLjM0IDIuMzQgMCAwIDAgMy4zMTktMS45MTUiIC8+CiAgPGNpcmNsZSBjeD0iMTIiIGN5PSIxMiIgcj0iMyIgLz4KPC9zdmc+Cg==) - https://lucide.dev/icons/settings
273
+ * @see https://lucide.dev/guide/packages/lucide-svelte - Documentation
274
+ *
275
+ * @param {Object} props - Lucide icons props and any valid SVG attribute
276
+ * @returns {FunctionalComponent} Svelte component
277
+ *
278
+ */
279
+ iconNode: [["path", { "d": "M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915" }], ["circle", {
280
+ "cx": "12",
281
+ "cy": "12",
282
+ "r": "3"
283
+ }]],
284
+ children: ($$renderer) => {
285
+ $$renderer.push(`<!--[-->`);
286
+ $.slot($$renderer, $$props, "default", {}, null);
287
+ $$renderer.push(`<!--]-->`);
288
+ },
289
+ $$slots: { default: true }
290
+ }
291
+ ]));
292
+ }
293
+ //#endregion
294
+ //#region src/lib/components/SearchBar.svelte
295
+ function SearchBar($$renderer, $$props) {
296
+ $$renderer.component(($$renderer) => {
297
+ const { class: className } = $$props;
298
+ let query = "";
299
+ $$renderer.push(`<div${$.attr_class($.clsx(cn("relative", className)))}>`);
300
+ Search($$renderer, { class: "pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground" });
301
+ $$renderer.push(`<!----> <input type="text"${$.attr("value", query)}${$.attr("placeholder", search_placeholder())}${$.attr_class($.clsx(cn("flex h-9 w-full rounded-md border border-input bg-transparent pl-9 py-1 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring", "pr-3")))}/> `);
302
+ $$renderer.push("<!--[-1-->");
303
+ $$renderer.push(`<!--]--></div>`);
304
+ });
305
+ }
306
+ //#endregion
307
+ //#region src/lib/components/sidebar/FolderTree.svelte
308
+ function docRowInner($$renderer, doc) {
309
+ $$renderer.push(`<a${$.attr("href", `/docs/${doc.id}`)} data-sveltekit-noscroll=""${$.attr_class($.clsx(cn("flex w-full min-w-0 items-center gap-1.5 rounded-md px-2 py-1 text-sm transition-colors hover:bg-accent hover:text-accent-foreground", page.params.id === doc.id && "bg-accent text-accent-foreground font-medium")))}><span class="w-3.5 shrink-0"></span> `);
310
+ File_text($$renderer, { class: "size-4 shrink-0 text-muted-foreground" });
311
+ $$renderer.push(`<!----> <span class="min-w-0 truncate">${$.escape(doc.title)}</span></a>`);
312
+ }
313
+ function FolderTree($$renderer, $$props) {
314
+ $$renderer.component(($$renderer) => {
315
+ /**
316
+ * Identifies where a doc dndzone lives in the tree. Every doc zone
317
+ * (folder content, category root-doc bucket, Uncategorized root)
318
+ * carries one of these so the persist handler knows what to do with
319
+ * a drop:
320
+ * - `{ kind: "folder", id }` → drop inside folder `id`. The doc
321
+ * inherits the folder's `categoryId` (or `null` if the folder
322
+ * has none).
323
+ * - `{ kind: "category", id }` → drop on the category's root-doc
324
+ * bucket. The doc loses its `folderId` and gains `categoryId = id`.
325
+ * - `{ kind: "root" }` → Uncategorized root zone. The doc
326
+ * is detached from any folder AND any category.
327
+ */
328
+ const FLIP_MS = 200;
329
+ const DOCUMENT_FLIP_MS = 80;
330
+ const FOLDER_EXPAND_DELAY_MS = 400;
331
+ const INITIAL_FETCH_DELAY_MS = 500;
332
+ let folders = [];
333
+ let categories = [];
334
+ let documents = [];
335
+ let expandedFolderIds = /* @__PURE__ */ new Set();
336
+ let expandedCategoryIds = /* @__PURE__ */ new Set();
337
+ let uncategorizedExpanded = true;
338
+ let loadError = null;
339
+ let dndError = null;
340
+ let dndErrorTimer = null;
341
+ function setDndError(msg) {
342
+ dndError = msg;
343
+ if (dndErrorTimer) {
344
+ clearTimeout(dndErrorTimer);
345
+ dndErrorTimer = null;
346
+ }
347
+ if (msg !== null) dndErrorTimer = setTimeout(() => {
348
+ dndError = null;
349
+ dndErrorTimer = null;
350
+ }, 5e3);
351
+ }
352
+ let dragDisabled = false;
353
+ let isDraggingGlobal = false;
354
+ let isDraggingFolder = false;
355
+ let isDraggingDoc = false;
356
+ let draggedDocId = null;
357
+ let documentDragGeneration = 0;
358
+ Promise.resolve();
359
+ let rootItems = [];
360
+ let folderDocsMap = {};
361
+ let categoryRootDocsMap = {};
362
+ let bucketFoldersMap = {};
363
+ let orderedBuckets = [];
364
+ let showNewFolderDialog = false;
365
+ let newFolderParentId = null;
366
+ let newFolderCategoryId = null;
367
+ let showRenameDialog = false;
368
+ let renameTarget = null;
369
+ let renameValue = "";
370
+ let renameError = null;
371
+ let renameSubmitting = false;
372
+ let showDeleteDialog = false;
373
+ let deleteTarget = null;
374
+ let showShareDialog = false;
375
+ let shareDocumentId = "";
376
+ let shareFolderId = "";
377
+ let shareDocumentTitle = "";
378
+ let shareFolderName = "";
379
+ let shareCategoryId = "";
380
+ let shareCategoryName = "";
381
+ let showCategoryDialog = false;
382
+ let categoryDialogMode = "create";
383
+ let selectedCategory = null;
384
+ let categoryBusy = false;
385
+ let expandTimer = null;
386
+ let pendingExpandFolderId = null;
387
+ let categoryExpandTimer = null;
388
+ let copiedDocId = null;
389
+ let copyLoadingDocId = null;
390
+ function clearExpandTimer() {
391
+ if (expandTimer !== null) {
392
+ clearTimeout(expandTimer);
393
+ expandTimer = null;
394
+ }
395
+ pendingExpandFolderId = null;
396
+ }
397
+ function scheduleFolderExpand(folderId) {
398
+ clearExpandTimer();
399
+ if (expandedFolderIds.has(folderId)) return;
400
+ pendingExpandFolderId = folderId;
401
+ expandTimer = setTimeout(() => {
402
+ if (pendingExpandFolderId === folderId && !expandedFolderIds.has(folderId)) {
403
+ const next = new Set(expandedFolderIds);
404
+ next.add(folderId);
405
+ expandedFolderIds = next;
406
+ }
407
+ expandTimer = null;
408
+ pendingExpandFolderId = null;
409
+ }, FOLDER_EXPAND_DELAY_MS);
410
+ }
411
+ function sanitizeItems(raw) {
412
+ if (!Array.isArray(raw)) return [];
413
+ return raw.filter((item) => item !== null && typeof item === "object" && typeof item.id === "string");
414
+ }
415
+ function buildZoneState(docs) {
416
+ const root = [];
417
+ const byCategory = {};
418
+ const byFolder = {};
419
+ for (const doc of docs) if (doc.folderId) {
420
+ const list = byFolder[doc.folderId] ?? [];
421
+ list.push(doc);
422
+ byFolder[doc.folderId] = list;
423
+ } else if (doc.categoryId) {
424
+ const list = byCategory[doc.categoryId] ?? [];
425
+ list.push(doc);
426
+ byCategory[doc.categoryId] = list;
427
+ } else root.push(doc);
428
+ return {
429
+ root,
430
+ byCategory,
431
+ byFolder
432
+ };
433
+ }
434
+ function resyncZonesFromDocuments() {
435
+ const { root, byCategory, byFolder } = buildZoneState(documents);
436
+ rootItems = root;
437
+ categoryRootDocsMap = byCategory;
438
+ folderDocsMap = byFolder;
439
+ }
440
+ function resyncBucketFolders() {
441
+ const byCategory = /* @__PURE__ */ new Map();
442
+ for (const cat of categories) byCategory.set(cat.id, []);
443
+ const uncategorized = [];
444
+ for (const folder of folders) if (folder.categoryId && byCategory.has(folder.categoryId)) byCategory.get(folder.categoryId)?.push(folder);
445
+ else uncategorized.push(folder);
446
+ const next = {};
447
+ for (const cat of categories) next[cat.id] = byCategory.get(cat.id) ?? [];
448
+ next[UNCATEGORIZED_KEY] = uncategorized;
449
+ bucketFoldersMap = next;
450
+ }
451
+ async function loadFolders() {
452
+ try {
453
+ folders = ((await listFolders(null))[0]?.children ?? []).map((f) => {
454
+ registerFolder(f.id, f.parentId ?? null, f.categoryId ?? null, f.order ?? 0);
455
+ return {
456
+ id: f.id,
457
+ name: f.name,
458
+ categoryId: f.categoryId ?? null,
459
+ parentId: f.parentId,
460
+ order: f.order ?? 0
461
+ };
462
+ });
463
+ loadError = null;
464
+ } catch (e) {
465
+ console.error("FolderTree: failed to load folders", e);
466
+ loadError = "Failed to load folders";
467
+ }
468
+ }
469
+ async function loadCategories() {
470
+ try {
471
+ const loaded = await listCategories();
472
+ const ids = /* @__PURE__ */ new Set();
473
+ for (const category of loaded) {
474
+ if (ids.has(category.id)) throw new Error(`Categories response contains duplicate id: ${category.id}`);
475
+ ids.add(category.id);
476
+ }
477
+ categories = loaded;
478
+ } catch (e) {
479
+ console.error("FolderTree: failed to load categories", e);
480
+ }
481
+ }
482
+ let documentsLoadGeneration = 0;
483
+ async function loadDocuments() {
484
+ const generation = ++documentsLoadGeneration;
485
+ try {
486
+ const tag = getSelectedTag();
487
+ const res = await listDocuments({
488
+ limit: 100,
489
+ ...tag ? { tag } : {}
490
+ });
491
+ if (generation !== documentsLoadGeneration) return;
492
+ documents = res.items.map((doc) => getPendingDocumentPlacement(doc.id) ? {
493
+ ...doc,
494
+ folderId: getPendingDocumentPlacement(doc.id)?.folderId ?? null,
495
+ categoryId: getPendingDocumentPlacement(doc.id)?.categoryId ?? null
496
+ } : doc);
497
+ documents.forEach((d) => {
498
+ d.id, d.title, d.categoryId, d.folderId, Object.keys(d);
499
+ registerDocument(d.id, d.folderId ?? null, d.categoryId ?? null);
500
+ });
501
+ resyncZonesFromDocuments();
502
+ } catch (e) {
503
+ console.error("FolderTree: failed to load documents", e);
504
+ loadError = "Failed to load documents";
505
+ }
506
+ }
507
+ async function refresh() {
508
+ clearDocumentsCache();
509
+ await Promise.all([
510
+ loadFolders(),
511
+ loadCategories(),
512
+ loadDocuments()
513
+ ]);
514
+ }
515
+ function rollbackDocumentPlacement(documentId, placement) {
516
+ documentsLoadGeneration++;
517
+ registerDocument(documentId, placement.folderId, placement.categoryId);
518
+ documents = documents.map((doc) => doc.id === documentId ? {
519
+ ...doc,
520
+ ...placement
521
+ } : doc);
522
+ resyncZonesFromDocuments();
523
+ }
524
+ const writeDocumentPlacement = createDocumentPlacementWriter({
525
+ patch: (documentId, placement) => updateDocument(documentId, placement),
526
+ optimistic: (documentId, placement) => publishDocumentPlacement(documentId, placement.folderId, placement.categoryId),
527
+ acknowledge: acknowledgeDocumentPlacement,
528
+ rollback: rollbackDocumentPlacement,
529
+ onError: (error) => {
530
+ console.error("FolderTree: document move failed", error);
531
+ setDndError(error instanceof Error ? error.message : "Move failed");
532
+ }
533
+ });
534
+ function persistDocumentPlacement(documentId, placement) {
535
+ const original = getDocumentFromRegistry(documentId);
536
+ if (!original) return;
537
+ if (original.folderId === placement.folderId && original.categoryId === placement.categoryId) return;
538
+ writeDocumentPlacement(documentId, placement, original).catch(() => void 0);
539
+ }
540
+ const documentDropCoordinator = createDocumentDropCoordinator({ persist: persistDocumentPlacement });
541
+ onMount(() => {
542
+ const timer = setTimeout(() => {
543
+ refresh();
544
+ }, INITIAL_FETCH_DELAY_MS);
545
+ return () => clearTimeout(timer);
546
+ });
547
+ onDestroy(() => {
548
+ documentDropCoordinator.cancel();
549
+ if (dndErrorTimer) {
550
+ clearTimeout(dndErrorTimer);
551
+ dndErrorTimer = null;
552
+ }
553
+ if (expandTimer) {
554
+ clearTimeout(expandTimer);
555
+ expandTimer = null;
556
+ }
557
+ if (categoryExpandTimer) {
558
+ clearTimeout(categoryExpandTimer);
559
+ categoryExpandTimer = null;
560
+ }
561
+ });
562
+ /**
563
+ * Public reload entry point. Exposed so other components (dashboard
564
+ * after import, RecentDocs after rename/delete, etc.) can request an
565
+ * immediate refresh without going through the shared nonce store —
566
+ * keeps the burst of initial fetches under control.
567
+ */
568
+ async function refreshFolderTree() {
569
+ await refresh();
570
+ }
571
+ function toggleFolder(id) {
572
+ const wasExpanded = expandedFolderIds.has(id);
573
+ const next = new Set(expandedFolderIds);
574
+ if (wasExpanded) next.delete(id);
575
+ else next.add(id);
576
+ expandedFolderIds = next;
577
+ dragDisabled = true;
578
+ if (typeof window !== "undefined") window.setTimeout(() => {
579
+ dragDisabled = false;
580
+ }, 250);
581
+ }
582
+ function openNewFolderInCategory(categoryId) {
583
+ newFolderParentId = null;
584
+ newFolderCategoryId = categoryId;
585
+ showNewFolderDialog = true;
586
+ }
587
+ function openNewSubfolder(parentId) {
588
+ newFolderParentId = parentId;
589
+ newFolderCategoryId = null;
590
+ showNewFolderDialog = true;
591
+ }
592
+ async function handleCreateFolder(name) {
593
+ const parentId = newFolderParentId;
594
+ const createdFolder = await createFolder({
595
+ name,
596
+ parentId,
597
+ categoryId: newFolderCategoryId
598
+ });
599
+ await loadFolders();
600
+ if (parentId) {
601
+ expandedFolderIds = new Set(expandedFolderIds).add(parentId);
602
+ bumpSubfoldersRefresh(parentId);
603
+ }
604
+ return createdFolder;
605
+ }
606
+ function setZoneItems(zone, next) {
607
+ if (zone.kind === "root") {
608
+ rootItems = next;
609
+ return;
610
+ }
611
+ if (zone.kind === "category") {
612
+ categoryRootDocsMap = {
613
+ ...categoryRootDocsMap,
614
+ [zone.id]: next
615
+ };
616
+ return;
617
+ }
618
+ folderDocsMap = {
619
+ ...folderDocsMap,
620
+ [zone.id]: next
621
+ };
622
+ }
623
+ function handleConsider(zone) {
624
+ return (e) => {
625
+ e.stopPropagation();
626
+ const startsNewDrag = !isDraggingDoc;
627
+ isDraggingGlobal = true;
628
+ isDraggingDoc = true;
629
+ if (e.detail.info?.id) {
630
+ draggedDocId = e.detail.info.id;
631
+ if (startsNewDrag) documentDropCoordinator.begin(e.detail.info.id, ++documentDragGeneration);
632
+ }
633
+ setZoneItems(zone, sanitizeItems(e.detail.items));
634
+ clearExpandTimer();
635
+ };
636
+ }
637
+ function handleFinalize(zone) {
638
+ return (e) => {
639
+ e.stopPropagation();
640
+ setZoneItems(zone, sanitizeItems(e.detail.items));
641
+ clearExpandTimer();
642
+ const isSourceZone = e.detail.info?.trigger === "droppedIntoAnother";
643
+ e.detail.info?.trigger;
644
+ const finalizedDocumentId = e.detail.info?.id ?? draggedDocId;
645
+ if (!isSourceZone && finalizedDocumentId) documentDropCoordinator.zone(finalizedDocumentId, placementForZone(zone));
646
+ if (finalizedDocumentId) documentDropCoordinator.end(finalizedDocumentId, documentDragGeneration);
647
+ isDraggingGlobal = false;
648
+ isDraggingDoc = false;
649
+ if (typeof window !== "undefined") window.setTimeout(() => {
650
+ if (draggedDocId === finalizedDocumentId) draggedDocId = null;
651
+ }, 0);
652
+ else draggedDocId = null;
653
+ };
654
+ }
655
+ function placementForZone(zone) {
656
+ return {
657
+ folderId: zone.kind === "folder" ? zone.id : null,
658
+ categoryId: zone.kind === "category" ? zone.id : zone.kind === "root" ? null : getFolderFromRegistry(zone.id)?.categoryId ?? null
659
+ };
660
+ }
661
+ function handleDropOnFolder(e, folderId) {
662
+ const documentId = draggedDocId ?? documentDropCoordinator.pendingId(documentDragGeneration);
663
+ if (!documentId) return;
664
+ e.preventDefault();
665
+ e.stopPropagation();
666
+ const targetCategoryId = getFolderFromRegistry(folderId)?.categoryId ?? null;
667
+ const original = getDocumentFromRegistry(documentId);
668
+ if (!original) return;
669
+ if (original.folderId !== folderId) documentDropCoordinator.header(documentId, {
670
+ folderId,
671
+ categoryId: targetCategoryId
672
+ });
673
+ draggedDocId = null;
674
+ }
675
+ const PARENT_ZONE_PREFIX = "parent:";
676
+ function handleFolderConsider(zoneKey) {
677
+ return (e) => {
678
+ e.stopPropagation();
679
+ isDraggingGlobal = true;
680
+ isDraggingFolder = true;
681
+ const next = sanitizeFolderItems(e.detail.items);
682
+ if (!zoneKey.startsWith(PARENT_ZONE_PREFIX)) bucketFoldersMap = {
683
+ ...bucketFoldersMap,
684
+ [zoneKey]: next
685
+ };
686
+ };
687
+ }
688
+ function handleFolderFinalize(zoneKey) {
689
+ return (e) => {
690
+ e.stopPropagation();
691
+ const next = sanitizeFolderItems(e.detail.items);
692
+ const isSourceZone = e.detail.info?.trigger === "droppedIntoAnother";
693
+ if (!zoneKey.startsWith(PARENT_ZONE_PREFIX)) bucketFoldersMap = {
694
+ ...bucketFoldersMap,
695
+ [zoneKey]: next
696
+ };
697
+ isDraggingGlobal = false;
698
+ isDraggingFolder = false;
699
+ if (!isSourceZone) persistFolderChanges(zoneKey, next);
700
+ };
701
+ }
702
+ function handleNestedFolderConsider(parentId) {
703
+ return handleFolderConsider(`${PARENT_ZONE_PREFIX}${parentId}`);
704
+ }
705
+ function handleNestedFolderFinalize(parentId) {
706
+ return handleFolderFinalize(`${PARENT_ZONE_PREFIX}${parentId}`);
707
+ }
708
+ function sanitizeFolderItems(raw) {
709
+ if (!Array.isArray(raw)) return [];
710
+ return raw.filter((item) => item !== null && typeof item === "object" && typeof item.id === "string");
711
+ }
712
+ function computeBlockedAncestors(targetParentId) {
713
+ const blocked = /* @__PURE__ */ new Set();
714
+ if (!targetParentId) return blocked;
715
+ let currentId = targetParentId;
716
+ while (currentId && !blocked.has(currentId)) {
717
+ blocked.add(currentId);
718
+ currentId = getFolderFromRegistry(currentId)?.parentId ?? null;
719
+ }
720
+ return blocked;
721
+ }
722
+ async function persistFolderChanges(zoneKey, zoneItems) {
723
+ const isParentZone = zoneKey.startsWith(PARENT_ZONE_PREFIX);
724
+ const targetCategoryId = isParentZone ? null : zoneKey === UNCATEGORIZED_KEY ? null : zoneKey;
725
+ const targetParentId = isParentZone ? zoneKey.slice(7) || null : null;
726
+ const updatesMap = /* @__PURE__ */ new Map();
727
+ const blocked = isParentZone ? computeBlockedAncestors(targetParentId) : /* @__PURE__ */ new Set();
728
+ if (isParentZone) for (const folder of zoneItems) {
729
+ if (blocked.has(folder.id)) continue;
730
+ const original = getFolderFromRegistry(folder.id);
731
+ if (!original) continue;
732
+ if (original.parentId !== targetParentId) {
733
+ updatesMap.set(folder.id, {
734
+ folderId: folder.id,
735
+ parentId: targetParentId
736
+ });
737
+ registerFolder(folder.id, targetParentId, original.categoryId, original.order);
738
+ }
739
+ }
740
+ else for (const folder of zoneItems) {
741
+ const original = getFolderFromRegistry(folder.id);
742
+ if (!original) continue;
743
+ const categoryChanged = original.categoryId !== targetCategoryId;
744
+ const parentChanged = original.parentId !== null;
745
+ if (categoryChanged || parentChanged) {
746
+ const payload = { folderId: folder.id };
747
+ if (categoryChanged) payload.categoryId = targetCategoryId;
748
+ if (parentChanged) payload.parentId = null;
749
+ updatesMap.set(folder.id, payload);
750
+ registerFolder(folder.id, null, targetCategoryId, original.order);
751
+ }
752
+ }
753
+ zoneItems.forEach((folder, index) => {
754
+ if (isParentZone && blocked.has(folder.id)) return;
755
+ const original = getFolderFromRegistry(folder.id);
756
+ if (!original) return;
757
+ const orderChanged = original.order !== index;
758
+ const existingUpdate = updatesMap.get(folder.id);
759
+ if (existingUpdate) {
760
+ existingUpdate.order = index;
761
+ registerFolder(folder.id, existingUpdate.parentId !== void 0 ? existingUpdate.parentId : original.parentId, existingUpdate.categoryId !== void 0 ? existingUpdate.categoryId : original.categoryId, index);
762
+ } else if (orderChanged) {
763
+ updatesMap.set(folder.id, {
764
+ folderId: folder.id,
765
+ order: index
766
+ });
767
+ registerFolder(folder.id, original.parentId, original.categoryId, index);
768
+ }
769
+ });
770
+ const updates = Array.from(updatesMap.values());
771
+ const affectedParents = /* @__PURE__ */ new Set();
772
+ if (isParentZone) {
773
+ if (targetParentId) affectedParents.add(targetParentId);
774
+ for (const folder of zoneItems) {
775
+ const originalParent = folder.parentId ?? null;
776
+ if (originalParent !== null && originalParent !== targetParentId) affectedParents.add(originalParent);
777
+ }
778
+ }
779
+ if (updates.length === 0) return;
780
+ try {
781
+ await Promise.all(updates.map((u) => {
782
+ const { folderId, ...patchBody } = u;
783
+ return updateFolder(folderId, patchBody);
784
+ }));
785
+ await refresh();
786
+ resyncBucketFolders();
787
+ for (const folderId of affectedParents) bumpSubfoldersRefresh(folderId);
788
+ } catch (err) {
789
+ console.error("FolderTree: folder DnD persist failed", err);
790
+ setDndError(err instanceof Error ? `Move failed: ${err.message}` : "Move failed: unknown error");
791
+ }
792
+ }
793
+ function startRename(kind, id, name) {
794
+ renameTarget = {
795
+ kind,
796
+ id,
797
+ name
798
+ };
799
+ renameValue = name;
800
+ renameError = null;
801
+ showRenameDialog = true;
802
+ }
803
+ function closeRenameDialog() {
804
+ showRenameDialog = false;
805
+ renameTarget = null;
806
+ renameValue = "";
807
+ renameError = null;
808
+ renameSubmitting = false;
809
+ }
810
+ async function submitRename(e) {
811
+ e?.preventDefault();
812
+ const target = renameTarget;
813
+ if (!target) return;
814
+ const trimmed = renameValue.trim();
815
+ if (trimmed.length === 0) {
816
+ renameError = "Name is required";
817
+ return;
818
+ }
819
+ renameSubmitting = true;
820
+ try {
821
+ if (target.kind === "folder") await updateFolder(target.id, { name: trimmed });
822
+ else await updateDocument(target.id, { title: trimmed });
823
+ closeRenameDialog();
824
+ await refresh();
825
+ refreshDocs();
826
+ } catch (err) {
827
+ console.error("FolderTree: rename failed", err);
828
+ renameError = err instanceof Error ? err.message : error_generic();
829
+ } finally {
830
+ renameSubmitting = false;
831
+ }
832
+ }
833
+ function startDelete(kind, id, name) {
834
+ deleteTarget = {
835
+ kind,
836
+ id,
837
+ name
838
+ };
839
+ showDeleteDialog = true;
840
+ }
841
+ function openShareDialogForDocument(id, title) {
842
+ shareDocumentId = id;
843
+ shareFolderId = "";
844
+ shareCategoryId = "";
845
+ shareDocumentTitle = title;
846
+ shareFolderName = "";
847
+ shareCategoryName = "";
848
+ showShareDialog = true;
849
+ }
850
+ function openShareDialogForFolder(id, name) {
851
+ shareFolderId = id;
852
+ shareDocumentId = "";
853
+ shareCategoryId = "";
854
+ shareFolderName = name;
855
+ shareDocumentTitle = "";
856
+ shareCategoryName = "";
857
+ showShareDialog = true;
858
+ }
859
+ function openShareDialogForCategory(id, name) {
860
+ shareCategoryId = id;
861
+ shareDocumentId = "";
862
+ shareFolderId = "";
863
+ shareCategoryName = name;
864
+ shareDocumentTitle = "";
865
+ shareFolderName = "";
866
+ showShareDialog = true;
867
+ }
868
+ function cancelDelete() {
869
+ showDeleteDialog = false;
870
+ deleteTarget = null;
871
+ }
872
+ async function confirmDelete() {
873
+ const target = deleteTarget;
874
+ if (!target) return;
875
+ if (target.kind === "folder") await deleteFolder(target.id);
876
+ else await deleteDocument(target.id);
877
+ await refresh();
878
+ refreshDocs();
879
+ }
880
+ function openEditCategoryDialog(category) {
881
+ categoryDialogMode = "edit";
882
+ selectedCategory = category;
883
+ showCategoryDialog = true;
884
+ }
885
+ function openDeleteCategoryDialog(category) {
886
+ categoryDialogMode = "delete";
887
+ selectedCategory = category;
888
+ showCategoryDialog = true;
889
+ }
890
+ function closeCategoryDialog() {
891
+ if (categoryBusy) return;
892
+ showCategoryDialog = false;
893
+ selectedCategory = null;
894
+ categoryBusy = false;
895
+ }
896
+ async function handleCategorySave(payload) {
897
+ categoryBusy = true;
898
+ try {
899
+ const body = {
900
+ name: payload.name,
901
+ apiMode: payload.apiMode,
902
+ apiPermissionRead: payload.apiPermissionRead,
903
+ apiPermissionEdit: payload.apiPermissionEdit,
904
+ apiPermissionWrite: payload.apiPermissionWrite
905
+ };
906
+ let savedCategory;
907
+ if (categoryDialogMode === "edit" && selectedCategory) savedCategory = await apiFetch(`/api/categories/${encodeURIComponent(selectedCategory.id)}`, {
908
+ method: "PATCH",
909
+ body
910
+ });
911
+ else savedCategory = await apiFetch("/api/categories", {
912
+ method: "POST",
913
+ body
914
+ });
915
+ await refresh();
916
+ return savedCategory;
917
+ } finally {
918
+ categoryBusy = false;
919
+ }
920
+ }
921
+ async function handleCategoryDelete() {
922
+ if (!selectedCategory) return;
923
+ categoryBusy = true;
924
+ try {
925
+ await deleteCategory(selectedCategory.id);
926
+ await refresh();
927
+ } finally {
928
+ categoryBusy = false;
929
+ }
930
+ }
931
+ const UNCATEGORIZED_KEY = "__uncategorized__";
932
+ const categoryBuckets = $.derived(() => orderedBuckets.filter((b) => b.id !== UNCATEGORIZED_KEY && b.category !== null));
933
+ const uncatBucket = $.derived(() => orderedBuckets.find((b) => b.id === UNCATEGORIZED_KEY) ?? null);
934
+ $.derived(() => {
935
+ const byCategory = /* @__PURE__ */ new Map();
936
+ for (const cat of categories) byCategory.set(cat.id, []);
937
+ const uncategorized = [];
938
+ for (const folder of folders) if (folder.categoryId && byCategory.has(folder.categoryId)) byCategory.get(folder.categoryId)?.push(folder);
939
+ else uncategorized.push(folder);
940
+ const items = [];
941
+ for (const cat of categories) items.push({
942
+ id: cat.id,
943
+ category: cat,
944
+ folders: byCategory.get(cat.id) ?? []
945
+ });
946
+ items.push({
947
+ id: UNCATEGORIZED_KEY,
948
+ category: null,
949
+ folders: uncategorized
950
+ });
951
+ return items;
952
+ });
953
+ function docMenu($$renderer, doc) {
954
+ Dropdown_menu($$renderer, {
955
+ children: ($$renderer) => {
956
+ {
957
+ function child($$renderer, { props }) {
958
+ $$renderer.push(`<button${$.attributes({
959
+ ...props,
960
+ type: "button",
961
+ class: "inline-flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground opacity-0 transition-opacity hover:bg-accent hover:text-accent-foreground group-hover/doc:opacity-100 focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
962
+ "aria-label": editor_more_options(),
963
+ title: editor_more_options()
964
+ })}>`);
965
+ Ellipsis_vertical($$renderer, { class: "size-3.5" });
966
+ $$renderer.push(`<!----></button>`);
967
+ }
968
+ Dropdown_menu_trigger($$renderer, {
969
+ child,
970
+ $$slots: { child: true }
971
+ });
972
+ }
973
+ $$renderer.push(`<!----> `);
974
+ Dropdown_menu_content($$renderer, {
975
+ align: "end",
976
+ children: ($$renderer) => {
977
+ Dropdown_menu_item($$renderer, {
978
+ onSelect: () => startRename("doc", doc.id, doc.title),
979
+ children: ($$renderer) => {
980
+ $$renderer.push(`<!---->${$.escape(folders_rename())}`);
981
+ },
982
+ $$slots: { default: true }
983
+ });
984
+ $$renderer.push(`<!----> `);
985
+ Dropdown_menu_item($$renderer, {
986
+ onSelect: () => openShareDialogForDocument(doc.id, doc.title),
987
+ children: ($$renderer) => {
988
+ $$renderer.push(`<!---->${$.escape(doc_share())}`);
989
+ },
990
+ $$slots: { default: true }
991
+ });
992
+ $$renderer.push(`<!----> `);
993
+ Dropdown_menu_item($$renderer, {
994
+ class: "text-destructive focus:text-destructive",
995
+ onSelect: () => startDelete("doc", doc.id, doc.title),
996
+ children: ($$renderer) => {
997
+ $$renderer.push(`<!---->${$.escape(action_delete())}`);
998
+ },
999
+ $$slots: { default: true }
1000
+ });
1001
+ $$renderer.push(`<!---->`);
1002
+ },
1003
+ $$slots: { default: true }
1004
+ });
1005
+ $$renderer.push(`<!---->`);
1006
+ },
1007
+ $$slots: { default: true }
1008
+ });
1009
+ }
1010
+ function copyButton($$renderer, doc) {
1011
+ $$renderer.push(`<button type="button"${$.attr_class(`inline-flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground opacity-0 transition-opacity hover:bg-accent hover:text-accent-foreground group-hover/doc:opacity-100 focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ${copiedDocId === doc.id || copyLoadingDocId === doc.id ? "opacity-100" : ""}`)}${$.attr("aria-label", action_copy_content())}${$.attr("title", action_copy_content())}${$.attr("disabled", copyLoadingDocId === doc.id, true)}>`);
1012
+ if (copyLoadingDocId === doc.id) {
1013
+ $$renderer.push("<!--[0-->");
1014
+ Loader_circle($$renderer, { class: "size-3.5 animate-spin" });
1015
+ } else if (copiedDocId === doc.id) {
1016
+ $$renderer.push("<!--[1-->");
1017
+ Check($$renderer, { class: "size-3.5" });
1018
+ } else {
1019
+ $$renderer.push("<!--[-1-->");
1020
+ Copy($$renderer, { class: "size-3.5" });
1021
+ }
1022
+ $$renderer.push(`<!--]--></button>`);
1023
+ }
1024
+ function folderBlock($$renderer, folder) {
1025
+ FolderNode($$renderer, {
1026
+ folder,
1027
+ expandedFolderIds,
1028
+ onToggleFolder: toggleFolder,
1029
+ onRename: (id, name) => startRename("folder", id, name),
1030
+ onDelete: (id, name) => startDelete("folder", id, name),
1031
+ onCreateSubfolder: openNewSubfolder,
1032
+ onShare: openShareDialogForFolder,
1033
+ dragDisabled,
1034
+ isDraggingGlobal,
1035
+ isDraggingFolder,
1036
+ isDraggingDoc,
1037
+ draggedDocId,
1038
+ onScheduleFolderExpand: scheduleFolderExpand,
1039
+ onClearExpandTimer: clearExpandTimer,
1040
+ onConsiderDocs: handleConsider,
1041
+ onFinalizeDocs: handleFinalize,
1042
+ onConsiderSubfolders: handleNestedFolderConsider,
1043
+ onFinalizeSubfolders: handleNestedFolderFinalize,
1044
+ onDropOnFolder: handleDropOnFolder,
1045
+ folderDocsMap,
1046
+ folderFlipDurationMs: FLIP_MS,
1047
+ documentFlipDurationMs: DOCUMENT_FLIP_MS,
1048
+ docRowInner,
1049
+ copyButton,
1050
+ docMenu
1051
+ });
1052
+ }
1053
+ let $$settled = true;
1054
+ let $$inner_renderer;
1055
+ function $$render_inner($$renderer) {
1056
+ $$renderer.push(`<div class="space-y-1"><div class="mb-2 flex items-center justify-between gap-1"><a href="/" class="block flex-1 px-2 text-xs font-medium uppercase tracking-wider text-muted-foreground transition-colors hover:text-foreground"${$.attr("title", dashboard_title())}>${$.escape(sidebar_folders())}</a> <button type="button" class="inline-flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"${$.attr("aria-label", categories_new())}${$.attr("title", categories_new())}>`);
1057
+ Plus($$renderer, { class: "size-3.5" });
1058
+ $$renderer.push(`<!----></button></div> `);
1059
+ if (loadError) {
1060
+ $$renderer.push("<!--[0-->");
1061
+ $$renderer.push(`<p class="px-2 text-xs text-destructive">${$.escape(loadError)}</p>`);
1062
+ } else $$renderer.push("<!--[-1-->");
1063
+ $$renderer.push(`<!--]--> `);
1064
+ if (dndError) {
1065
+ $$renderer.push("<!--[0-->");
1066
+ $$renderer.push(`<p class="px-2 text-xs text-destructive">${$.escape(dndError)}</p>`);
1067
+ } else $$renderer.push("<!--[-1-->");
1068
+ $$renderer.push(`<!--]--> <div class="min-h-[8px] space-y-1"><!--[-->`);
1069
+ const each_array = $.ensure_array_like(categoryBuckets());
1070
+ for (let $$index_2 = 0, $$length = each_array.length; $$index_2 < $$length; $$index_2++) {
1071
+ let bucket = each_array[$$index_2];
1072
+ const isBucketExpanded = expandedCategoryIds.has(bucket.id);
1073
+ $$renderer.push(`<div class="group/bucket"${$.attr("data-is-dnd-shadow-item-hint", bucket[SHADOW_ITEM_MARKER_PROPERTY_NAME])}><div class="flex w-full min-w-0 items-center gap-0.5"><button type="button"${$.attr("aria-expanded", isBucketExpanded)}${$.attr_class($.clsx(cn("flex min-w-0 flex-1 items-center gap-1.5 rounded-md px-2 py-1.5 text-xs font-medium uppercase tracking-wider text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground", draggedDocId && "hover:bg-accent/40 border border-dashed border-primary/30")))}>`);
1074
+ if (isBucketExpanded) {
1075
+ $$renderer.push("<!--[0-->");
1076
+ Chevron_down($$renderer, { class: "size-3.5 shrink-0" });
1077
+ } else {
1078
+ $$renderer.push("<!--[-1-->");
1079
+ Chevron_right($$renderer, { class: "size-3.5 shrink-0" });
1080
+ }
1081
+ $$renderer.push(`<!--]--> <span class="min-w-0 truncate">${$.escape(bucket.category.name)}</span></button> `);
1082
+ Dropdown_menu($$renderer, {
1083
+ children: ($$renderer) => {
1084
+ {
1085
+ function child($$renderer, { props }) {
1086
+ $$renderer.push(`<button${$.attributes({
1087
+ ...props,
1088
+ type: "button",
1089
+ class: "inline-flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground opacity-0 transition-opacity hover:bg-accent hover:text-accent-foreground group-hover/bucket:opacity-100 focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1090
+ "aria-label": editor_more_options(),
1091
+ title: editor_more_options()
1092
+ })}>`);
1093
+ Ellipsis_vertical($$renderer, { class: "size-3.5" });
1094
+ $$renderer.push(`<!----></button>`);
1095
+ }
1096
+ Dropdown_menu_trigger($$renderer, {
1097
+ child,
1098
+ $$slots: { child: true }
1099
+ });
1100
+ }
1101
+ $$renderer.push(`<!----> `);
1102
+ Dropdown_menu_content($$renderer, {
1103
+ align: "end",
1104
+ children: ($$renderer) => {
1105
+ Dropdown_menu_item($$renderer, {
1106
+ onSelect: () => goto(`/?category=${bucket.category.id}`),
1107
+ children: ($$renderer) => {
1108
+ $$renderer.push(`<!---->${$.escape(action_go_to())}`);
1109
+ },
1110
+ $$slots: { default: true }
1111
+ });
1112
+ $$renderer.push(`<!----> `);
1113
+ Dropdown_menu_item($$renderer, {
1114
+ onSelect: () => goto(`/docs/new?category=${bucket.category.id}`),
1115
+ children: ($$renderer) => {
1116
+ $$renderer.push(`<!---->${$.escape(dashboard_new_document())}`);
1117
+ },
1118
+ $$slots: { default: true }
1119
+ });
1120
+ $$renderer.push(`<!----> `);
1121
+ Dropdown_menu_item($$renderer, {
1122
+ onSelect: () => openNewFolderInCategory(bucket.category.id),
1123
+ children: ($$renderer) => {
1124
+ $$renderer.push(`<!---->${$.escape(folders_new())}`);
1125
+ },
1126
+ $$slots: { default: true }
1127
+ });
1128
+ $$renderer.push(`<!----> `);
1129
+ Dropdown_menu_item($$renderer, {
1130
+ onSelect: () => openShareDialogForCategory(bucket.category.id, bucket.category.name),
1131
+ children: ($$renderer) => {
1132
+ $$renderer.push(`<!---->${$.escape(doc_share())}`);
1133
+ },
1134
+ $$slots: { default: true }
1135
+ });
1136
+ $$renderer.push(`<!----> `);
1137
+ Dropdown_menu_item($$renderer, {
1138
+ onSelect: () => openEditCategoryDialog(bucket.category),
1139
+ children: ($$renderer) => {
1140
+ $$renderer.push(`<!---->${$.escape(action_edit())}`);
1141
+ },
1142
+ $$slots: { default: true }
1143
+ });
1144
+ $$renderer.push(`<!----> `);
1145
+ Dropdown_menu_item($$renderer, {
1146
+ class: "text-destructive focus:text-destructive",
1147
+ onSelect: () => openDeleteCategoryDialog(bucket.category),
1148
+ children: ($$renderer) => {
1149
+ $$renderer.push(`<!---->${$.escape(action_delete())}`);
1150
+ },
1151
+ $$slots: { default: true }
1152
+ });
1153
+ $$renderer.push(`<!---->`);
1154
+ },
1155
+ $$slots: { default: true }
1156
+ });
1157
+ $$renderer.push(`<!---->`);
1158
+ },
1159
+ $$slots: { default: true }
1160
+ });
1161
+ $$renderer.push(`<!----></div> `);
1162
+ if (isBucketExpanded) {
1163
+ $$renderer.push("<!--[0-->");
1164
+ const zoneItems = bucketFoldersMap[bucket.id] ?? [];
1165
+ const rootDocs = categoryRootDocsMap[bucket.id] ?? [];
1166
+ $$renderer.push(`<div class="ml-0.5 space-y-0.5 border-l border-border pl-0.5"><div${$.attr_class($.clsx(cn("min-h-[8px] space-y-0.5 transition-all duration-150", isDraggingFolder && zoneItems.length === 0 && "min-h-[36px] bg-accent/20 rounded border border-dashed border-muted-foreground/20")))}><!--[-->`);
1167
+ const each_array_1 = $.ensure_array_like(zoneItems);
1168
+ for (let $$index = 0, $$length = each_array_1.length; $$index < $$length; $$index++) {
1169
+ let folder = each_array_1[$$index];
1170
+ $$renderer.push(`<div>`);
1171
+ folderBlock($$renderer, folder);
1172
+ $$renderer.push(`<!----></div>`);
1173
+ }
1174
+ $$renderer.push(`<!--]--></div> <div${$.attr_class($.clsx(cn("min-h-[8px] space-y-0.5 transition-all duration-150", isDraggingDoc && rootDocs.length === 0 && "min-h-[36px] bg-accent/20 rounded border border-dashed border-muted-foreground/20")))}><!--[-->`);
1175
+ const each_array_2 = $.ensure_array_like(rootDocs);
1176
+ for (let $$index_1 = 0, $$length = each_array_2.length; $$index_1 < $$length; $$index_1++) {
1177
+ let doc = each_array_2[$$index_1];
1178
+ $$renderer.push(`<div class="group/doc flex w-full min-w-0 items-center gap-1">`);
1179
+ docRowInner($$renderer, doc);
1180
+ $$renderer.push(`<!----> `);
1181
+ copyButton($$renderer, doc);
1182
+ $$renderer.push(`<!----> `);
1183
+ docMenu($$renderer, doc);
1184
+ $$renderer.push(`<!----></div>`);
1185
+ }
1186
+ $$renderer.push(`<!--]--></div></div>`);
1187
+ } else $$renderer.push("<!--[-1-->");
1188
+ $$renderer.push(`<!--]--></div>`);
1189
+ }
1190
+ $$renderer.push(`<!--]--></div> `);
1191
+ if (uncatBucket()) {
1192
+ $$renderer.push("<!--[0-->");
1193
+ $$renderer.push(`<div class="group/bucket"><div class="flex w-full min-w-0 items-center gap-0.5"><button type="button"${$.attr("aria-expanded", uncategorizedExpanded)}${$.attr_class($.clsx(cn("flex min-w-0 flex-1 items-center gap-1.5 rounded-md px-2 py-1.5 text-xs font-medium uppercase tracking-wider text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground", draggedDocId && "hover:bg-accent/40 border border-dashed border-primary/30")))}>`);
1194
+ $$renderer.push("<!--[0-->");
1195
+ Chevron_down($$renderer, { class: "size-3.5 shrink-0" });
1196
+ $$renderer.push(`<!--]--> <span class="min-w-0 truncate">${$.escape(sidebar_uncategorized())}</span></button></div> `);
1197
+ {
1198
+ $$renderer.push("<!--[0-->");
1199
+ const zoneItems = bucketFoldersMap[UNCATEGORIZED_KEY] ?? [];
1200
+ $$renderer.push(`<div class="ml-0.5 space-y-0.5 border-l border-border pl-0.5"><div${$.attr_class($.clsx(cn("min-h-[8px] space-y-0.5 transition-all duration-150", isDraggingFolder && zoneItems.length === 0 && "min-h-[36px] bg-accent/20 rounded border border-dashed border-muted-foreground/20")))}><!--[-->`);
1201
+ const each_array_3 = $.ensure_array_like(zoneItems);
1202
+ for (let $$index_3 = 0, $$length = each_array_3.length; $$index_3 < $$length; $$index_3++) {
1203
+ let folder = each_array_3[$$index_3];
1204
+ $$renderer.push(`<div>`);
1205
+ folderBlock($$renderer, folder);
1206
+ $$renderer.push(`<!----></div>`);
1207
+ }
1208
+ $$renderer.push(`<!--]--></div> <div${$.attr_class($.clsx(cn("min-h-[8px] space-y-0.5 transition-all duration-150", isDraggingDoc && rootItems.length === 0 && "min-h-[36px] bg-accent/20 rounded border border-dashed border-muted-foreground/20")))}><!--[-->`);
1209
+ const each_array_4 = $.ensure_array_like(rootItems);
1210
+ for (let $$index_4 = 0, $$length = each_array_4.length; $$index_4 < $$length; $$index_4++) {
1211
+ let doc = each_array_4[$$index_4];
1212
+ $$renderer.push(`<div class="group/doc flex w-full min-w-0 items-center gap-1">`);
1213
+ docRowInner($$renderer, doc);
1214
+ $$renderer.push(`<!----> `);
1215
+ copyButton($$renderer, doc);
1216
+ $$renderer.push(`<!----> `);
1217
+ docMenu($$renderer, doc);
1218
+ $$renderer.push(`<!----></div>`);
1219
+ }
1220
+ $$renderer.push(`<!--]--></div></div>`);
1221
+ }
1222
+ $$renderer.push(`<!--]--></div>`);
1223
+ } else $$renderer.push("<!--[-1-->");
1224
+ $$renderer.push(`<!--]--> <button type="button" class="flex w-full items-center gap-1.5 rounded-md px-2 py-1.5 text-sm text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground">`);
1225
+ Plus($$renderer, { class: "size-3.5" });
1226
+ $$renderer.push(`<!----> <span>${$.escape(folders_new())}</span></button></div> `);
1227
+ FolderDialog($$renderer, {
1228
+ mode: "create",
1229
+ onSave: handleCreateFolder,
1230
+ closeOnSave: false,
1231
+ get open() {
1232
+ return showNewFolderDialog;
1233
+ },
1234
+ set open($$value) {
1235
+ showNewFolderDialog = $$value;
1236
+ $$settled = false;
1237
+ }
1238
+ });
1239
+ $$renderer.push(`<!----> `);
1240
+ Dialog($$renderer, {
1241
+ onOpenChange: (next) => {
1242
+ if (!next) closeRenameDialog();
1243
+ },
1244
+ get open() {
1245
+ return showRenameDialog;
1246
+ },
1247
+ set open($$value) {
1248
+ showRenameDialog = $$value;
1249
+ $$settled = false;
1250
+ },
1251
+ children: ($$renderer) => {
1252
+ Dialog_header($$renderer, {
1253
+ children: ($$renderer) => {
1254
+ Dialog_title($$renderer, {
1255
+ children: ($$renderer) => {
1256
+ $$renderer.push(`<!---->${$.escape(folders_rename())}`);
1257
+ },
1258
+ $$slots: { default: true }
1259
+ });
1260
+ $$renderer.push(`<!----> `);
1261
+ Dialog_description($$renderer, {
1262
+ children: ($$renderer) => {
1263
+ $$renderer.push(`<!---->${$.escape(renameTarget?.kind === "folder" ? folders_name_placeholder() : doc_title_label())}`);
1264
+ },
1265
+ $$slots: { default: true }
1266
+ });
1267
+ $$renderer.push(`<!---->`);
1268
+ },
1269
+ $$slots: { default: true }
1270
+ });
1271
+ $$renderer.push(`<!----> <form class="space-y-4"><div class="space-y-2">`);
1272
+ Label($$renderer, {
1273
+ for: "rename-input",
1274
+ children: ($$renderer) => {
1275
+ $$renderer.push(`<!---->${$.escape(renameTarget?.kind === "folder" ? folders_name_placeholder() : doc_title_label())}`);
1276
+ },
1277
+ $$slots: { default: true }
1278
+ });
1279
+ $$renderer.push(`<!----> `);
1280
+ Input($$renderer, {
1281
+ id: "rename-input",
1282
+ name: "name",
1283
+ type: "text",
1284
+ maxlength: 255,
1285
+ required: true,
1286
+ disabled: renameSubmitting,
1287
+ "aria-invalid": renameError ? "true" : void 0,
1288
+ "aria-describedby": renameError ? "rename-input-error" : void 0,
1289
+ autocomplete: "off",
1290
+ get value() {
1291
+ return renameValue;
1292
+ },
1293
+ set value($$value) {
1294
+ renameValue = $$value;
1295
+ $$settled = false;
1296
+ }
1297
+ });
1298
+ $$renderer.push(`<!----> `);
1299
+ if (renameError) {
1300
+ $$renderer.push("<!--[0-->");
1301
+ $$renderer.push(`<p id="rename-input-error" class="text-xs text-destructive" role="alert">${$.escape(renameError)}</p>`);
1302
+ } else $$renderer.push("<!--[-1-->");
1303
+ $$renderer.push(`<!--]--></div></form> `);
1304
+ Dialog_footer($$renderer, {
1305
+ children: ($$renderer) => {
1306
+ Button($$renderer, {
1307
+ variant: "outline",
1308
+ type: "button",
1309
+ onclick: closeRenameDialog,
1310
+ disabled: renameSubmitting,
1311
+ children: ($$renderer) => {
1312
+ $$renderer.push(`<!---->${$.escape(action_cancel())}`);
1313
+ },
1314
+ $$slots: { default: true }
1315
+ });
1316
+ $$renderer.push(`<!----> `);
1317
+ Button($$renderer, {
1318
+ type: "submit",
1319
+ onclick: submitRename,
1320
+ disabled: renameSubmitting || renameValue.trim().length === 0,
1321
+ children: ($$renderer) => {
1322
+ $$renderer.push(`<!---->${$.escape(renameSubmitting ? action_loading() : action_save())}`);
1323
+ },
1324
+ $$slots: { default: true }
1325
+ });
1326
+ $$renderer.push(`<!---->`);
1327
+ },
1328
+ $$slots: { default: true }
1329
+ });
1330
+ $$renderer.push(`<!---->`);
1331
+ },
1332
+ $$slots: { default: true }
1333
+ });
1334
+ $$renderer.push(`<!----> `);
1335
+ DeleteDialog($$renderer, {
1336
+ targetName: deleteTarget?.name ?? "",
1337
+ title: deleteTarget?.kind === "folder" ? folders_delete_title() : doc_delete(),
1338
+ description: deleteTarget?.kind === "folder" ? "Its documents will be moved to the root and will not be deleted." : doc_delete_confirm(),
1339
+ successTitle: deleteTarget?.kind === "folder" ? folders_delete_success() : doc_delete_success(),
1340
+ successDescription: deleteTarget?.kind === "folder" ? folders_delete_success_description() : doc_delete_success_description(),
1341
+ confirmLabel: action_delete(),
1342
+ cancelLabel: action_cancel(),
1343
+ onConfirm: confirmDelete,
1344
+ onCancel: cancelDelete,
1345
+ get open() {
1346
+ return showDeleteDialog;
1347
+ },
1348
+ set open($$value) {
1349
+ showDeleteDialog = $$value;
1350
+ $$settled = false;
1351
+ }
1352
+ });
1353
+ $$renderer.push(`<!----> `);
1354
+ CategoryDialog($$renderer, {
1355
+ mode: categoryDialogMode,
1356
+ category: selectedCategory ?? void 0,
1357
+ onSave: handleCategorySave,
1358
+ onDelete: handleCategoryDelete,
1359
+ onClose: closeCategoryDialog,
1360
+ get open() {
1361
+ return showCategoryDialog;
1362
+ },
1363
+ set open($$value) {
1364
+ showCategoryDialog = $$value;
1365
+ $$settled = false;
1366
+ }
1367
+ });
1368
+ $$renderer.push(`<!----> `);
1369
+ ShareDialog($$renderer, {
1370
+ documentId: shareDocumentId,
1371
+ documentTitle: shareDocumentTitle,
1372
+ folderId: shareFolderId,
1373
+ folderName: shareFolderName,
1374
+ categoryId: shareCategoryId,
1375
+ categoryName: shareCategoryName,
1376
+ get open() {
1377
+ return showShareDialog;
1378
+ },
1379
+ set open($$value) {
1380
+ showShareDialog = $$value;
1381
+ $$settled = false;
1382
+ }
1383
+ });
1384
+ $$renderer.push(`<!---->`);
1385
+ }
1386
+ do {
1387
+ $$settled = true;
1388
+ $$inner_renderer = $$renderer.copy();
1389
+ $$render_inner($$inner_renderer);
1390
+ } while (!$$settled);
1391
+ $$renderer.subsume($$inner_renderer);
1392
+ $.bind_props($$props, { refreshFolderTree });
1393
+ });
1394
+ }
1395
+ //#endregion
1396
+ //#region src/lib/components/sidebar/RecentDocs.svelte
1397
+ function RecentDocs($$renderer, $$props) {
1398
+ $$renderer.component(($$renderer) => {
1399
+ let recentDocs = [];
1400
+ let activeId = null;
1401
+ let loadError = null;
1402
+ let copiedDocId = null;
1403
+ let copyLoadingDocId = null;
1404
+ let copyTimer = null;
1405
+ let showRenameDialog = false;
1406
+ let renameTarget = null;
1407
+ let renameValue = "";
1408
+ let renameError = null;
1409
+ let renameSubmitting = false;
1410
+ let showDeleteDialog = false;
1411
+ let deleteTarget = null;
1412
+ let deleteBusy = false;
1413
+ async function fetchRecentDocs() {
1414
+ try {
1415
+ const tag = getSelectedTag();
1416
+ recentDocs = (await listDocuments({
1417
+ limit: 6,
1418
+ ...tag ? { tag } : {}
1419
+ })).items;
1420
+ loadError = null;
1421
+ } catch (e) {
1422
+ console.error("RecentDocs: failed to load recent documents", e);
1423
+ loadError = "Failed to load recent documents";
1424
+ }
1425
+ }
1426
+ onMount(() => {
1427
+ fetchRecentDocs();
1428
+ });
1429
+ /**
1430
+ * Public reload entry point. Exposed so other components (dashboard
1431
+ * after import, FolderTree after rename/delete, etc.) can request an
1432
+ * immediate refresh without going through the shared nonce store —
1433
+ * keeps the burst of initial fetches under control.
1434
+ */
1435
+ async function refreshRecentDocs() {
1436
+ await fetchRecentDocs();
1437
+ }
1438
+ onDestroy(() => {
1439
+ if (copyTimer) {
1440
+ clearTimeout(copyTimer);
1441
+ copyTimer = null;
1442
+ }
1443
+ });
1444
+ function startRename(id, title) {
1445
+ renameTarget = {
1446
+ id,
1447
+ title
1448
+ };
1449
+ renameValue = title;
1450
+ renameError = null;
1451
+ showRenameDialog = true;
1452
+ }
1453
+ function closeRenameDialog() {
1454
+ showRenameDialog = false;
1455
+ renameTarget = null;
1456
+ renameValue = "";
1457
+ renameError = null;
1458
+ renameSubmitting = false;
1459
+ }
1460
+ async function submitRename(e) {
1461
+ e?.preventDefault();
1462
+ const target = renameTarget;
1463
+ if (!target) return;
1464
+ const trimmed = renameValue.trim();
1465
+ if (trimmed.length === 0) {
1466
+ renameError = "Name is required";
1467
+ return;
1468
+ }
1469
+ renameSubmitting = true;
1470
+ try {
1471
+ await updateDocument(target.id, { title: trimmed });
1472
+ closeRenameDialog();
1473
+ await fetchRecentDocs();
1474
+ refreshDocs();
1475
+ } catch (err) {
1476
+ console.error("RecentDocs: rename failed", err);
1477
+ renameError = err instanceof Error ? err.message : error_generic();
1478
+ } finally {
1479
+ renameSubmitting = false;
1480
+ }
1481
+ }
1482
+ function startDelete(id, title) {
1483
+ deleteTarget = {
1484
+ id,
1485
+ title
1486
+ };
1487
+ showDeleteDialog = true;
1488
+ }
1489
+ function cancelDelete() {
1490
+ showDeleteDialog = false;
1491
+ deleteTarget = null;
1492
+ deleteBusy = false;
1493
+ }
1494
+ async function confirmDelete() {
1495
+ const target = deleteTarget;
1496
+ if (!target || deleteBusy) return;
1497
+ deleteBusy = true;
1498
+ try {
1499
+ await deleteDocument(target.id);
1500
+ cancelDelete();
1501
+ await fetchRecentDocs();
1502
+ refreshDocs();
1503
+ } catch (err) {
1504
+ console.error("RecentDocs: delete failed", err);
1505
+ loadError = err instanceof Error ? err.message : error_generic();
1506
+ deleteBusy = false;
1507
+ }
1508
+ }
1509
+ let $$settled = true;
1510
+ let $$inner_renderer;
1511
+ function $$render_inner($$renderer) {
1512
+ $$renderer.push(`<div class="space-y-1"><h3 class="mb-2 px-2 text-xs font-medium uppercase tracking-wider text-muted-foreground">${$.escape(sidebar_recent())}</h3> `);
1513
+ if (loadError) {
1514
+ $$renderer.push("<!--[0-->");
1515
+ $$renderer.push(`<p class="px-2 text-xs text-destructive">${$.escape(loadError)}</p>`);
1516
+ } else $$renderer.push("<!--[-1-->");
1517
+ $$renderer.push(`<!--]--> <!--[-->`);
1518
+ const each_array = $.ensure_array_like(recentDocs);
1519
+ for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
1520
+ let doc = each_array[$$index];
1521
+ $$renderer.push(`<div class="group/doc flex min-w-0 items-center gap-1"><a${$.attr("href", `/docs/${doc.id}`)}${$.attr_class($.clsx(cn("flex min-w-0 flex-1 items-center gap-2 rounded-md px-2 py-1.5 text-sm transition-colors hover:bg-accent hover:text-accent-foreground", activeId === doc.id && "bg-accent text-accent-foreground")))}>`);
1522
+ File_text($$renderer, { class: "size-4 shrink-0 text-muted-foreground" });
1523
+ $$renderer.push(`<!----> <div class="min-w-0 flex-1"><p class="truncate min-w-0">${$.escape(doc.title)}</p> <p class="text-xs text-muted-foreground">${$.escape(doc.updatedAt)}</p></div></a> <button type="button"${$.attr_class(`inline-flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground opacity-0 transition-opacity hover:bg-accent hover:text-accent-foreground group-hover/doc:opacity-100 focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring ${copiedDocId === doc.id || copyLoadingDocId === doc.id ? "opacity-100" : ""}`)}${$.attr("aria-label", action_copy_content())}${$.attr("title", action_copy_content())}${$.attr("disabled", copyLoadingDocId === doc.id, true)}>`);
1524
+ if (copyLoadingDocId === doc.id) {
1525
+ $$renderer.push("<!--[0-->");
1526
+ Loader_circle($$renderer, { class: "size-3.5 animate-spin" });
1527
+ } else if (copiedDocId === doc.id) {
1528
+ $$renderer.push("<!--[1-->");
1529
+ Check($$renderer, { class: "size-3.5" });
1530
+ } else {
1531
+ $$renderer.push("<!--[-1-->");
1532
+ Copy($$renderer, { class: "size-3.5" });
1533
+ }
1534
+ $$renderer.push(`<!--]--></button> `);
1535
+ Dropdown_menu($$renderer, {
1536
+ children: ($$renderer) => {
1537
+ {
1538
+ function child($$renderer, { props }) {
1539
+ $$renderer.push(`<button${$.attributes({
1540
+ ...props,
1541
+ type: "button",
1542
+ class: "inline-flex size-6 shrink-0 items-center justify-center rounded-md text-muted-foreground opacity-0 transition-opacity hover:bg-accent hover:text-accent-foreground group-hover/doc:opacity-100 focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1543
+ "aria-label": editor_more_options(),
1544
+ title: editor_more_options()
1545
+ })}>`);
1546
+ Ellipsis_vertical($$renderer, { class: "size-3.5" });
1547
+ $$renderer.push(`<!----></button>`);
1548
+ }
1549
+ Dropdown_menu_trigger($$renderer, {
1550
+ child,
1551
+ $$slots: { child: true }
1552
+ });
1553
+ }
1554
+ $$renderer.push(`<!----> `);
1555
+ Dropdown_menu_content($$renderer, {
1556
+ align: "end",
1557
+ children: ($$renderer) => {
1558
+ Dropdown_menu_item($$renderer, {
1559
+ onSelect: () => startRename(doc.id, doc.title),
1560
+ children: ($$renderer) => {
1561
+ $$renderer.push(`<!---->${$.escape(folders_rename())}`);
1562
+ },
1563
+ $$slots: { default: true }
1564
+ });
1565
+ $$renderer.push(`<!----> `);
1566
+ Dropdown_menu_item($$renderer, {
1567
+ class: "text-destructive focus:text-destructive",
1568
+ onSelect: () => startDelete(doc.id, doc.title),
1569
+ children: ($$renderer) => {
1570
+ $$renderer.push(`<!---->${$.escape(action_delete())}`);
1571
+ },
1572
+ $$slots: { default: true }
1573
+ });
1574
+ $$renderer.push(`<!---->`);
1575
+ },
1576
+ $$slots: { default: true }
1577
+ });
1578
+ $$renderer.push(`<!---->`);
1579
+ },
1580
+ $$slots: { default: true }
1581
+ });
1582
+ $$renderer.push(`<!----></div>`);
1583
+ }
1584
+ $$renderer.push(`<!--]--></div> `);
1585
+ Dialog($$renderer, {
1586
+ onOpenChange: (next) => {
1587
+ if (!next) closeRenameDialog();
1588
+ },
1589
+ get open() {
1590
+ return showRenameDialog;
1591
+ },
1592
+ set open($$value) {
1593
+ showRenameDialog = $$value;
1594
+ $$settled = false;
1595
+ },
1596
+ children: ($$renderer) => {
1597
+ Dialog_header($$renderer, {
1598
+ children: ($$renderer) => {
1599
+ Dialog_title($$renderer, {
1600
+ children: ($$renderer) => {
1601
+ $$renderer.push(`<!---->${$.escape(folders_rename())}`);
1602
+ },
1603
+ $$slots: { default: true }
1604
+ });
1605
+ $$renderer.push(`<!----> `);
1606
+ Dialog_description($$renderer, {
1607
+ children: ($$renderer) => {
1608
+ $$renderer.push(`<!---->${$.escape(doc_title_label())}`);
1609
+ },
1610
+ $$slots: { default: true }
1611
+ });
1612
+ $$renderer.push(`<!---->`);
1613
+ },
1614
+ $$slots: { default: true }
1615
+ });
1616
+ $$renderer.push(`<!----> <form class="space-y-4"><div class="space-y-2">`);
1617
+ Label($$renderer, {
1618
+ for: "recent-rename-input",
1619
+ children: ($$renderer) => {
1620
+ $$renderer.push(`<!---->${$.escape(doc_title_label())}`);
1621
+ },
1622
+ $$slots: { default: true }
1623
+ });
1624
+ $$renderer.push(`<!----> `);
1625
+ Input($$renderer, {
1626
+ id: "recent-rename-input",
1627
+ name: "name",
1628
+ type: "text",
1629
+ maxlength: 255,
1630
+ required: true,
1631
+ disabled: renameSubmitting,
1632
+ "aria-invalid": renameError ? "true" : void 0,
1633
+ "aria-describedby": renameError ? "recent-rename-input-error" : void 0,
1634
+ autocomplete: "off",
1635
+ get value() {
1636
+ return renameValue;
1637
+ },
1638
+ set value($$value) {
1639
+ renameValue = $$value;
1640
+ $$settled = false;
1641
+ }
1642
+ });
1643
+ $$renderer.push(`<!----> `);
1644
+ if (renameError) {
1645
+ $$renderer.push("<!--[0-->");
1646
+ $$renderer.push(`<p id="recent-rename-input-error" class="text-xs text-destructive" role="alert">${$.escape(renameError)}</p>`);
1647
+ } else $$renderer.push("<!--[-1-->");
1648
+ $$renderer.push(`<!--]--></div></form> `);
1649
+ Dialog_footer($$renderer, {
1650
+ children: ($$renderer) => {
1651
+ Button($$renderer, {
1652
+ variant: "outline",
1653
+ type: "button",
1654
+ onclick: closeRenameDialog,
1655
+ disabled: renameSubmitting,
1656
+ children: ($$renderer) => {
1657
+ $$renderer.push(`<!---->${$.escape(action_cancel())}`);
1658
+ },
1659
+ $$slots: { default: true }
1660
+ });
1661
+ $$renderer.push(`<!----> `);
1662
+ Button($$renderer, {
1663
+ type: "submit",
1664
+ onclick: submitRename,
1665
+ disabled: renameSubmitting || renameValue.trim().length === 0,
1666
+ children: ($$renderer) => {
1667
+ $$renderer.push(`<!---->${$.escape(renameSubmitting ? action_loading() : action_save())}`);
1668
+ },
1669
+ $$slots: { default: true }
1670
+ });
1671
+ $$renderer.push(`<!---->`);
1672
+ },
1673
+ $$slots: { default: true }
1674
+ });
1675
+ $$renderer.push(`<!---->`);
1676
+ },
1677
+ $$slots: { default: true }
1678
+ });
1679
+ $$renderer.push(`<!----> `);
1680
+ ConfirmDialog($$renderer, {
1681
+ title: doc_delete(),
1682
+ description: doc_delete_confirm(),
1683
+ confirmLabel: action_delete(),
1684
+ cancelLabel: action_cancel(),
1685
+ variant: "destructive",
1686
+ busy: deleteBusy,
1687
+ onConfirm: confirmDelete,
1688
+ onCancel: cancelDelete,
1689
+ get open() {
1690
+ return showDeleteDialog;
1691
+ },
1692
+ set open($$value) {
1693
+ showDeleteDialog = $$value;
1694
+ $$settled = false;
1695
+ }
1696
+ });
1697
+ $$renderer.push(`<!---->`);
1698
+ }
1699
+ do {
1700
+ $$settled = true;
1701
+ $$inner_renderer = $$renderer.copy();
1702
+ $$render_inner($$inner_renderer);
1703
+ } while (!$$settled);
1704
+ $$renderer.subsume($$inner_renderer);
1705
+ $.bind_props($$props, { refreshRecentDocs });
1706
+ });
1707
+ }
1708
+ //#endregion
1709
+ //#region src/lib/components/sidebar/TagList.svelte
1710
+ function TagList($$renderer, $$props) {
1711
+ $$renderer.component(($$renderer) => {
1712
+ let tags = [];
1713
+ let loadError = null;
1714
+ let showCreateDialog = false;
1715
+ let editTarget = null;
1716
+ let showDeleteDialog = false;
1717
+ let deleteTarget = null;
1718
+ let busy = false;
1719
+ async function refresh() {
1720
+ try {
1721
+ tags = await listTags();
1722
+ } catch (e) {
1723
+ console.error("TagList: failed to load tags", e);
1724
+ loadError = tags_load_error();
1725
+ }
1726
+ }
1727
+ onMount(() => {
1728
+ refresh();
1729
+ });
1730
+ function handleCreated(created) {
1731
+ tags = [...tags, created];
1732
+ refreshTags();
1733
+ refresh();
1734
+ }
1735
+ function handleUpdated(updated) {
1736
+ tags = tags.map((t) => t.id === updated.id ? updated : t);
1737
+ refreshTags();
1738
+ }
1739
+ function startEdit(t) {
1740
+ editTarget = t;
1741
+ showCreateDialog = true;
1742
+ }
1743
+ function handleDialogClose() {
1744
+ editTarget = null;
1745
+ }
1746
+ function startDelete(t) {
1747
+ deleteTarget = t;
1748
+ showDeleteDialog = true;
1749
+ }
1750
+ function cancelDelete() {
1751
+ showDeleteDialog = false;
1752
+ deleteTarget = null;
1753
+ }
1754
+ async function confirmDelete() {
1755
+ const t = deleteTarget;
1756
+ if (!t || busy) return;
1757
+ busy = true;
1758
+ try {
1759
+ await deleteTag(t.id);
1760
+ tags = tags.filter((tag) => tag.id !== t.id);
1761
+ if (getSelectedTag() === t.id) setSelectedTag(null);
1762
+ showDeleteDialog = false;
1763
+ deleteTarget = null;
1764
+ refreshTags();
1765
+ } catch (e) {
1766
+ console.error("TagList: deleteTag failed", e);
1767
+ loadError = error_generic();
1768
+ } finally {
1769
+ busy = false;
1770
+ }
1771
+ }
1772
+ let $$settled = true;
1773
+ let $$inner_renderer;
1774
+ function $$render_inner($$renderer) {
1775
+ $$renderer.push(`<div class="space-y-1"><h3 class="mb-2 px-2 text-xs font-medium uppercase tracking-wider text-muted-foreground">${$.escape(doc_tags())}</h3> `);
1776
+ if (loadError) {
1777
+ $$renderer.push("<!--[0-->");
1778
+ $$renderer.push(`<p class="px-2 text-xs text-destructive">${$.escape(loadError)}</p>`);
1779
+ } else $$renderer.push("<!--[-1-->");
1780
+ $$renderer.push(`<!--]--> <div class="flex flex-wrap gap-1 px-2"><!--[-->`);
1781
+ const each_array = $.ensure_array_like(tags);
1782
+ for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
1783
+ let tag = each_array[$$index];
1784
+ $$renderer.push(`<div${$.attr_class($.clsx(cn("group/tag relative inline-flex items-center rounded-full transition-colors", getSelectedTag() === tag.id ? "bg-primary text-primary-foreground" : "bg-secondary text-secondary-foreground hover:bg-secondary/80")))}><button type="button" class="inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium"${$.attr("aria-pressed", getSelectedTag() === tag.id)}><span class="size-2.5 shrink-0 rounded-full"${$.attr_style(`background-color: ${$.stringify(tag.color || "#888888")}`)}></span> ${$.escape(tag.name)}</button> `);
1785
+ Dropdown_menu($$renderer, {
1786
+ children: ($$renderer) => {
1787
+ {
1788
+ function child($$renderer, { props }) {
1789
+ $$renderer.push(`<button${$.attributes({
1790
+ ...props,
1791
+ type: "button",
1792
+ class: $.clsx(cn("hidden size-5 items-center justify-center rounded-full hover:bg-black/10 focus-visible:inline-flex group-hover/tag:inline-flex mr-0.5 data-[state=open]:inline-flex", getSelectedTag() === tag.id && "inline-flex")),
1793
+ "aria-label": editor_more_options(),
1794
+ title: editor_more_options(),
1795
+ disabled: busy
1796
+ })}>`);
1797
+ if (busy) {
1798
+ $$renderer.push("<!--[0-->");
1799
+ Loader_circle($$renderer, { class: "size-3 animate-spin" });
1800
+ } else {
1801
+ $$renderer.push("<!--[-1-->");
1802
+ Ellipsis_vertical($$renderer, { class: "size-3" });
1803
+ }
1804
+ $$renderer.push(`<!--]--></button>`);
1805
+ }
1806
+ Dropdown_menu_trigger($$renderer, {
1807
+ child,
1808
+ $$slots: { child: true }
1809
+ });
1810
+ }
1811
+ $$renderer.push(`<!----> `);
1812
+ Dropdown_menu_content($$renderer, {
1813
+ align: "start",
1814
+ children: ($$renderer) => {
1815
+ Dropdown_menu_item($$renderer, {
1816
+ onSelect: () => startEdit(tag),
1817
+ children: ($$renderer) => {
1818
+ $$renderer.push(`<!---->${$.escape(action_edit())}`);
1819
+ },
1820
+ $$slots: { default: true }
1821
+ });
1822
+ $$renderer.push(`<!----> `);
1823
+ Dropdown_menu_item($$renderer, {
1824
+ class: "text-destructive focus:text-destructive",
1825
+ onSelect: () => startDelete(tag),
1826
+ children: ($$renderer) => {
1827
+ $$renderer.push(`<!---->${$.escape(action_delete())}`);
1828
+ },
1829
+ $$slots: { default: true }
1830
+ });
1831
+ $$renderer.push(`<!---->`);
1832
+ },
1833
+ $$slots: { default: true }
1834
+ });
1835
+ $$renderer.push(`<!---->`);
1836
+ },
1837
+ $$slots: { default: true }
1838
+ });
1839
+ $$renderer.push(`<!----></div>`);
1840
+ }
1841
+ $$renderer.push(`<!--]--> <button type="button" class="inline-flex items-center gap-0.5 rounded-full px-2 py-0.5 text-xs text-muted-foreground transition-colors hover:bg-secondary hover:text-secondary-foreground"${$.attr("aria-label", tags_new())}>`);
1842
+ Plus($$renderer, { class: "size-3" });
1843
+ $$renderer.push(`<!----> ${$.escape(tags_add())}</button></div></div> `);
1844
+ TagCreateDialog($$renderer, {
1845
+ mode: editTarget ? "edit" : "create",
1846
+ tag: editTarget,
1847
+ onCreated: handleCreated,
1848
+ onUpdated: handleUpdated,
1849
+ onClose: handleDialogClose,
1850
+ get open() {
1851
+ return showCreateDialog;
1852
+ },
1853
+ set open($$value) {
1854
+ showCreateDialog = $$value;
1855
+ $$settled = false;
1856
+ }
1857
+ });
1858
+ $$renderer.push(`<!----> `);
1859
+ ConfirmDialog($$renderer, {
1860
+ title: tags_delete_title(),
1861
+ description: tags_delete_description(),
1862
+ confirmLabel: action_delete(),
1863
+ cancelLabel: action_cancel(),
1864
+ variant: "destructive",
1865
+ busy,
1866
+ onConfirm: confirmDelete,
1867
+ onCancel: cancelDelete,
1868
+ get open() {
1869
+ return showDeleteDialog;
1870
+ },
1871
+ set open($$value) {
1872
+ showDeleteDialog = $$value;
1873
+ $$settled = false;
1874
+ }
1875
+ });
1876
+ $$renderer.push(`<!---->`);
1877
+ }
1878
+ do {
1879
+ $$settled = true;
1880
+ $$inner_renderer = $$renderer.copy();
1881
+ $$render_inner($$inner_renderer);
1882
+ } while (!$$settled);
1883
+ $$renderer.subsume($$inner_renderer);
1884
+ });
1885
+ }
1886
+ //#endregion
1887
+ //#region src/lib/components/sidebar/Sidebar.svelte
1888
+ function Sidebar($$renderer, $$props) {
1889
+ $$renderer.component(($$renderer) => {
1890
+ let { mobile = false, mobileOpen = false, element = null } = $$props;
1891
+ let collapsed = false;
1892
+ let showSettings = false;
1893
+ const isCollapsed = $.derived(() => !mobile && collapsed);
1894
+ let width = 256;
1895
+ let isResizing = false;
1896
+ const frontendExtensions = getFrontendExtensions();
1897
+ const navigationExtensions = $.derived(() => resolveExtensions(frontendExtensions.navigation, { pathname: page.url.pathname }));
1898
+ let $$settled = true;
1899
+ let $$inner_renderer;
1900
+ function $$render_inner($$renderer) {
1901
+ $$renderer.push(`<aside${$.attr("id", mobile ? "mobile-navigation" : void 0)}${$.attr("role", mobile && mobileOpen ? "dialog" : void 0)}${$.attr("aria-modal", mobile && mobileOpen ? "true" : void 0)}${$.attr("aria-label", mobile ? "Navigation" : void 0)}${$.attr("aria-hidden", mobile && !mobileOpen ? "true" : void 0)} tabindex="-1"${$.attr("inert", mobile && !mobileOpen, true)}${$.attr_class($.clsx(cn("flex flex-col border-r border-border bg-card", mobile && "fixed inset-y-0 left-0 z-50 h-full w-[80%] max-w-[320px] shadow-xl transition-transform duration-300 ease-out", mobile && (mobileOpen ? "translate-x-0" : "-translate-x-full"), !mobile && "relative h-screen", !mobile && "transition-[width] duration-200")))}${$.attr_style(mobile ? "padding-top: env(safe-area-inset-top);" : isCollapsed() ? "width: 48px;" : `width: ${width}px;`)}>`);
1902
+ if (!mobile && !isCollapsed()) {
1903
+ $$renderer.push("<!--[0-->");
1904
+ $$renderer.push(`<div role="separator" tabindex="-1"${$.attr_class($.clsx(cn("absolute right-0 top-0 z-40 h-full w-1 cursor-col-resize hover:bg-primary/50 transition-colors", isResizing)))}></div>`);
1905
+ } else $$renderer.push("<!--[-1-->");
1906
+ $$renderer.push(`<!--]--> `);
1907
+ if (!mobile) {
1908
+ $$renderer.push("<!--[0-->");
1909
+ $$renderer.push(`<button class="absolute -right-3 top-4 z-40 flex size-6 items-center justify-center rounded-full border border-border bg-background shadow-sm hover:bg-accent">`);
1910
+ if (isCollapsed()) {
1911
+ $$renderer.push("<!--[0-->");
1912
+ Panel_left_open($$renderer, { class: "size-3.5" });
1913
+ } else {
1914
+ $$renderer.push("<!--[-1-->");
1915
+ Panel_left_close($$renderer, { class: "size-3.5" });
1916
+ }
1917
+ $$renderer.push(`<!--]--></button>`);
1918
+ } else $$renderer.push("<!--[-1-->");
1919
+ $$renderer.push(`<!--]--> `);
1920
+ if (!isCollapsed()) {
1921
+ $$renderer.push("<!--[0-->");
1922
+ $$renderer.push(`<div class="flex flex-1 flex-col gap-4 overflow-y-auto p-3">`);
1923
+ SearchBar($$renderer, { class: "mr-5" });
1924
+ $$renderer.push(`<!----> `);
1925
+ $$renderer.push("<!--[0-->");
1926
+ FolderTree($$renderer, {});
1927
+ $$renderer.push(`<!----> <div class="h-px bg-border"></div>`);
1928
+ $$renderer.push(`<!--]--> `);
1929
+ $$renderer.push("<!--[0-->");
1930
+ RecentDocs($$renderer, {});
1931
+ $$renderer.push(`<!----> <div class="h-px bg-border"></div>`);
1932
+ $$renderer.push(`<!--]--> `);
1933
+ $$renderer.push("<!--[0-->");
1934
+ TagList($$renderer, {});
1935
+ $$renderer.push(`<!--]--> `);
1936
+ if (navigationExtensions().length > 0) {
1937
+ $$renderer.push("<!--[0-->");
1938
+ $$renderer.push(`<div class="h-px bg-border"></div> <nav class="space-y-1" aria-label="Product navigation"><!--[-->`);
1939
+ const each_array = $.ensure_array_like(navigationExtensions());
1940
+ for (let $$index = 0, $$length = each_array.length; $$index < $$length; $$index++) {
1941
+ let extension = each_array[$$index];
1942
+ const Icon = extension.icon;
1943
+ $$renderer.push(`<a${$.attr("href", extension.href ?? "#")}${$.attr("aria-disabled", extension.disabled)} class="flex items-center gap-2 rounded-md px-2 py-1.5 text-sm text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground aria-disabled:pointer-events-none aria-disabled:opacity-50">`);
1944
+ if (Icon) {
1945
+ $$renderer.push("<!--[0-->");
1946
+ if (Icon) {
1947
+ $$renderer.push("<!--[-->");
1948
+ Icon($$renderer, { class: "size-4" });
1949
+ $$renderer.push("<!--]-->");
1950
+ } else {
1951
+ $$renderer.push("<!--[!-->");
1952
+ $$renderer.push("<!--]-->");
1953
+ }
1954
+ } else $$renderer.push("<!--[-1-->");
1955
+ $$renderer.push(`<!--]--> <span class="min-w-0 flex-1 truncate">${$.escape(extension.label)}</span> `);
1956
+ if (extension.badge !== void 0) {
1957
+ $$renderer.push("<!--[0-->");
1958
+ $$renderer.push(`<span class="rounded bg-muted px-1.5 py-0.5 text-xs">${$.escape(extension.badge)}</span>`);
1959
+ } else $$renderer.push("<!--[-1-->");
1960
+ $$renderer.push(`<!--]--></a>`);
1961
+ }
1962
+ $$renderer.push(`<!--]--></nav>`);
1963
+ } else $$renderer.push("<!--[-1-->");
1964
+ $$renderer.push(`<!--]--></div>`);
1965
+ } else {
1966
+ $$renderer.push("<!--[-1-->");
1967
+ $$renderer.push(`<div class="flex flex-1 flex-col items-center gap-1 pt-14"><button class="flex size-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground"${$.attr("title", sidebar_folders())}${$.attr("aria-label", sidebar_folders())}>`);
1968
+ Folder($$renderer, { class: "size-4" });
1969
+ $$renderer.push(`<!----></button> <button class="flex size-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground"${$.attr("title", search_title())}${$.attr("aria-label", search_title())}>`);
1970
+ Search($$renderer, { class: "size-4" });
1971
+ $$renderer.push(`<!----></button> <button class="flex size-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground"${$.attr("title", sidebar_recent())}${$.attr("aria-label", sidebar_recent())}>`);
1972
+ Clock($$renderer, { class: "size-4" });
1973
+ $$renderer.push(`<!----></button> <button class="flex size-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground"${$.attr("title", doc_tags())}${$.attr("aria-label", doc_tags())}>`);
1974
+ Tag($$renderer, { class: "size-4" });
1975
+ $$renderer.push(`<!----></button> <!--[-->`);
1976
+ const each_array_1 = $.ensure_array_like(navigationExtensions());
1977
+ for (let $$index_1 = 0, $$length = each_array_1.length; $$index_1 < $$length; $$index_1++) {
1978
+ let extension = each_array_1[$$index_1];
1979
+ const Icon = extension.icon;
1980
+ $$renderer.push(`<a${$.attr("href", extension.href ?? "#")}${$.attr("aria-disabled", extension.disabled)} class="flex size-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground aria-disabled:pointer-events-none aria-disabled:opacity-50"${$.attr("title", extension.label)}${$.attr("aria-label", extension.label)}>`);
1981
+ if (Icon) {
1982
+ $$renderer.push("<!--[0-->");
1983
+ if (Icon) {
1984
+ $$renderer.push("<!--[-->");
1985
+ Icon($$renderer, { class: "size-4" });
1986
+ $$renderer.push("<!--]-->");
1987
+ } else {
1988
+ $$renderer.push("<!--[!-->");
1989
+ $$renderer.push("<!--]-->");
1990
+ }
1991
+ } else {
1992
+ $$renderer.push("<!--[-1-->");
1993
+ $$renderer.push(`<span class="text-xs">${$.escape(extension.label.slice(0, 1))}</span>`);
1994
+ }
1995
+ $$renderer.push(`<!--]--></a>`);
1996
+ }
1997
+ $$renderer.push(`<!--]--></div>`);
1998
+ }
1999
+ $$renderer.push(`<!--]--> <div class="border-t border-border p-2">`);
2000
+ if (isCollapsed()) {
2001
+ $$renderer.push("<!--[0-->");
2002
+ $$renderer.push(`<div class="flex flex-col items-center gap-2"><button type="button" class="flex size-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground"${$.attr("title", settings_title())}${$.attr("aria-label", settings_title())}>`);
2003
+ Settings($$renderer, { class: "size-4" });
2004
+ $$renderer.push(`<!----></button> <a href="https://docsmint.com" target="_blank" rel="noopener noreferrer" class="flex size-8 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-foreground"${$.attr("title", sidebar_powered_by())}${$.attr("aria-label", sidebar_powered_by())}><img src="/favicon.ico" alt="DocsMint" class="size-5 object-contain dark:hidden"/> <img src="/favicon_white.ico" alt="" aria-hidden="true" class="hidden size-5 object-contain dark:block"/></a></div>`);
2005
+ } else {
2006
+ $$renderer.push("<!--[-1-->");
2007
+ $$renderer.push(`<div class="flex items-center justify-between"><a href="https://docsmint.com" target="_blank" rel="noopener noreferrer" class="text-xs text-muted-foreground hover:text-foreground transition-colors"${$.attr("title", sidebar_powered_by())}>${$.escape(sidebar_powered_by())}</a> <button type="button" class="flex size-7 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground"${$.attr("title", settings_title())}${$.attr("aria-label", settings_title())}>`);
2008
+ Settings($$renderer, { class: "size-4" });
2009
+ $$renderer.push(`<!----></button></div>`);
2010
+ }
2011
+ $$renderer.push(`<!--]--></div></aside> `);
2012
+ SettingsDialog($$renderer, {
2013
+ get open() {
2014
+ return showSettings;
2015
+ },
2016
+ set open($$value) {
2017
+ showSettings = $$value;
2018
+ $$settled = false;
2019
+ }
2020
+ });
2021
+ $$renderer.push(`<!---->`);
2022
+ }
2023
+ do {
2024
+ $$settled = true;
2025
+ $$inner_renderer = $$renderer.copy();
2026
+ $$render_inner($$inner_renderer);
2027
+ } while (!$$settled);
2028
+ $$renderer.subsume($$inner_renderer);
2029
+ $.bind_props($$props, { element });
2030
+ });
2031
+ }
2032
+ //#endregion
2033
+ export { Sidebar as t };