@arbidocs/blocks 0.5.119 → 0.5.121

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 (463) hide show
  1. package/dist/ClippingMediaViewer-B6WG7Q64.cjs +156 -0
  2. package/dist/ClippingMediaViewer-B6WG7Q64.cjs.map +1 -0
  3. package/dist/ClippingPdfViewer-6GCVTV3V.cjs +79 -0
  4. package/dist/ClippingPdfViewer-6GCVTV3V.cjs.map +1 -0
  5. package/dist/{ConnectedCallDock-WER7R222.cjs → ConnectedCallDock-DC5V5OUJ.cjs} +25 -23
  6. package/dist/ConnectedCallDock-DC5V5OUJ.cjs.map +1 -0
  7. package/dist/{ConnectedCallRoom-T7OBQTYP.cjs → ConnectedCallRoom-FQLXWTFB.cjs} +18 -16
  8. package/dist/{ConnectedCallRoom-T7OBQTYP.cjs.map → ConnectedCallRoom-FQLXWTFB.cjs.map} +1 -1
  9. package/dist/{ConnectedNativeDocxComparison-546ILGLW.cjs → ConnectedNativeDocxComparison-4Q5S7VLD.cjs} +17 -17
  10. package/dist/{ConnectedNativeDocxComparison-546ILGLW.cjs.map → ConnectedNativeDocxComparison-4Q5S7VLD.cjs.map} +1 -1
  11. package/dist/ConnectedPresentation-4HLDZDWV.cjs +183 -0
  12. package/dist/ConnectedPresentation-4HLDZDWV.cjs.map +1 -0
  13. package/dist/{ConnectedProductionSetDialog-LHB4VQWC.cjs → ConnectedProductionSetDialog-4EAY6KAZ.cjs} +3 -3
  14. package/dist/{ConnectedProductionSetDialog-LHB4VQWC.cjs.map → ConnectedProductionSetDialog-4EAY6KAZ.cjs.map} +1 -1
  15. package/dist/ConnectedSlidesTab-7QDE2CZD.cjs +234 -0
  16. package/dist/ConnectedSlidesTab-7QDE2CZD.cjs.map +1 -0
  17. package/dist/{ConnectedStreamedWordArtifact-S2ZFZLZQ.cjs → ConnectedStreamedWordArtifact-FFOQJBOI.cjs} +17 -17
  18. package/dist/{ConnectedStreamedWordArtifact-S2ZFZLZQ.cjs.map → ConnectedStreamedWordArtifact-FFOQJBOI.cjs.map} +1 -1
  19. package/dist/{DocumentReviewCard-ZSBZBGFK.cjs → DocumentReviewCard-SNWVEZ7S.cjs} +19 -18
  20. package/dist/DocumentReviewCard-SNWVEZ7S.cjs.map +1 -0
  21. package/dist/{FilesViewerDialog-6UKR5WEF.cjs → FilesViewerDialog-IZI63FOV.cjs} +54 -47
  22. package/dist/FilesViewerDialog-IZI63FOV.cjs.map +1 -0
  23. package/dist/{GridViewImpl-ZMJJWTOM.cjs → GridViewImpl-LTYET77Q.cjs} +3 -3
  24. package/dist/GridViewImpl-LTYET77Q.cjs.map +1 -0
  25. package/dist/{WorkspaceTableView-J3C6VH4T.cjs → WorkspaceTableView-TEIRB6VJ.cjs} +11 -10
  26. package/dist/WorkspaceTableView-TEIRB6VJ.cjs.map +1 -0
  27. package/dist/agents/index.cjs +297 -297
  28. package/dist/agents/tasks/ConversationListView.js +10 -2
  29. package/dist/agents/tasks/ConversationListView.js.map +2 -2
  30. package/dist/agents/tasks/TaskTable.js +5 -4
  31. package/dist/agents/tasks/TaskTable.js.map +2 -2
  32. package/dist/agents/tasks/WorkflowsTable.js +4 -5
  33. package/dist/agents/tasks/WorkflowsTable.js.map +2 -2
  34. package/dist/agents/tasks/taskColumns.js +1 -1
  35. package/dist/agents/tasks/taskColumns.js.map +1 -1
  36. package/dist/agents/tasks/taskTableLabels.js +1 -1
  37. package/dist/agents/tasks/taskTableLabels.js.map +1 -1
  38. package/dist/agents/tasks/workflowTableLabels.js +1 -1
  39. package/dist/agents/tasks/workflowTableLabels.js.map +1 -1
  40. package/dist/{ai-IM4A23YT.cjs → ai-KBYNRNZ6.cjs} +28 -26
  41. package/dist/ai-KBYNRNZ6.cjs.map +1 -0
  42. package/dist/calls/connected/CallControls.d.ts +2 -0
  43. package/dist/calls/connected/CallControls.js +71 -9
  44. package/dist/calls/connected/CallControls.js.map +2 -2
  45. package/dist/calls/connected/ShareDocumentDialog.d.ts +14 -0
  46. package/dist/calls/connected/ShareDocumentDialog.js +77 -0
  47. package/dist/calls/connected/ShareDocumentDialog.js.map +7 -0
  48. package/dist/calls/index.cjs +121 -121
  49. package/dist/chat/index.cjs +9 -8
  50. package/dist/{chunk-T23UTIRI.cjs → chunk-2PZT3J34.cjs} +6 -6
  51. package/dist/{chunk-T23UTIRI.cjs.map → chunk-2PZT3J34.cjs.map} +1 -1
  52. package/dist/{chunk-SGYSDABK.cjs → chunk-2W5E62EY.cjs} +6 -6
  53. package/dist/{chunk-SGYSDABK.cjs.map → chunk-2W5E62EY.cjs.map} +1 -1
  54. package/dist/{chunk-TDO5UWXF.cjs → chunk-3SCNXNHI.cjs} +5 -5
  55. package/dist/{chunk-TDO5UWXF.cjs.map → chunk-3SCNXNHI.cjs.map} +1 -1
  56. package/dist/{chunk-KTQOGT2L.cjs → chunk-474GPLCM.cjs} +7 -7
  57. package/dist/{chunk-KTQOGT2L.cjs.map → chunk-474GPLCM.cjs.map} +1 -1
  58. package/dist/{chunk-TP5PGWIO.cjs → chunk-4IOYQLKG.cjs} +3 -3
  59. package/dist/{chunk-TP5PGWIO.cjs.map → chunk-4IOYQLKG.cjs.map} +1 -1
  60. package/dist/{chunk-NY3YUCOW.cjs → chunk-4NPCDS2X.cjs} +3 -3
  61. package/dist/{chunk-NY3YUCOW.cjs.map → chunk-4NPCDS2X.cjs.map} +1 -1
  62. package/dist/{chunk-CPG7II4E.cjs → chunk-4RBQ44RY.cjs} +28 -28
  63. package/dist/chunk-4RBQ44RY.cjs.map +1 -0
  64. package/dist/{chunk-BQ5RIWWT.cjs → chunk-4VZZWYEC.cjs} +3 -3
  65. package/dist/{chunk-BQ5RIWWT.cjs.map → chunk-4VZZWYEC.cjs.map} +1 -1
  66. package/dist/{chunk-Y24V6HPR.cjs → chunk-52KGMAO5.cjs} +15 -15
  67. package/dist/{chunk-Y24V6HPR.cjs.map → chunk-52KGMAO5.cjs.map} +1 -1
  68. package/dist/{chunk-HB2O4THB.cjs → chunk-5534FYXP.cjs} +4 -4
  69. package/dist/{chunk-HB2O4THB.cjs.map → chunk-5534FYXP.cjs.map} +1 -1
  70. package/dist/chunk-5GCCUXMT.cjs +63 -0
  71. package/dist/chunk-5GCCUXMT.cjs.map +1 -0
  72. package/dist/chunk-5LTIZ44D.cjs +95 -0
  73. package/dist/chunk-5LTIZ44D.cjs.map +1 -0
  74. package/dist/{chunk-YGXOKB5Z.cjs → chunk-734NPQNR.cjs} +4 -4
  75. package/dist/{chunk-YGXOKB5Z.cjs.map → chunk-734NPQNR.cjs.map} +1 -1
  76. package/dist/{chunk-SB4M3ITT.cjs → chunk-7VUJGHMY.cjs} +444 -100
  77. package/dist/chunk-7VUJGHMY.cjs.map +1 -0
  78. package/dist/chunk-AFQTQC7A.cjs +35 -0
  79. package/dist/chunk-AFQTQC7A.cjs.map +1 -0
  80. package/dist/{chunk-XKVPSOKP.cjs → chunk-AY6EZSZB.cjs} +4 -4
  81. package/dist/{chunk-XKVPSOKP.cjs.map → chunk-AY6EZSZB.cjs.map} +1 -1
  82. package/dist/{chunk-TT4IF52H.cjs → chunk-BVAT4EVC.cjs} +40 -41
  83. package/dist/chunk-BVAT4EVC.cjs.map +1 -0
  84. package/dist/{chunk-VGCTYTEW.cjs → chunk-C2OICDMI.cjs} +10 -10
  85. package/dist/{chunk-VGCTYTEW.cjs.map → chunk-C2OICDMI.cjs.map} +1 -1
  86. package/dist/{chunk-CPR6EHG7.cjs → chunk-DR2AH7JL.cjs} +179 -55
  87. package/dist/chunk-DR2AH7JL.cjs.map +1 -0
  88. package/dist/{chunk-NJCK6V6U.cjs → chunk-EATIFPKP.cjs} +4 -60
  89. package/dist/chunk-EATIFPKP.cjs.map +1 -0
  90. package/dist/{chunk-B3LZITVF.cjs → chunk-EHP6OH5D.cjs} +11 -451
  91. package/dist/chunk-EHP6OH5D.cjs.map +1 -0
  92. package/dist/{chunk-DDIW4HLU.cjs → chunk-ENGL7P3I.cjs} +46 -37
  93. package/dist/chunk-ENGL7P3I.cjs.map +1 -0
  94. package/dist/{chunk-QHOHDNBU.cjs → chunk-FKFQCK3C.cjs} +4 -4
  95. package/dist/{chunk-QHOHDNBU.cjs.map → chunk-FKFQCK3C.cjs.map} +1 -1
  96. package/dist/{chunk-6UTKM5AB.cjs → chunk-GKVE5JGB.cjs} +76 -76
  97. package/dist/chunk-GKVE5JGB.cjs.map +1 -0
  98. package/dist/{chunk-B2HNNG25.cjs → chunk-GPX5VC57.cjs} +50 -50
  99. package/dist/{chunk-B2HNNG25.cjs.map → chunk-GPX5VC57.cjs.map} +1 -1
  100. package/dist/{chunk-WAV762GP.cjs → chunk-GQXPNIRE.cjs} +6 -6
  101. package/dist/{chunk-WAV762GP.cjs.map → chunk-GQXPNIRE.cjs.map} +1 -1
  102. package/dist/chunk-GX2EBMJW.cjs +133 -0
  103. package/dist/chunk-GX2EBMJW.cjs.map +1 -0
  104. package/dist/{chunk-7OPOPYV6.cjs → chunk-H5OLHP2U.cjs} +3 -3
  105. package/dist/{chunk-7OPOPYV6.cjs.map → chunk-H5OLHP2U.cjs.map} +1 -1
  106. package/dist/chunk-HYUKPHCT.cjs +66 -0
  107. package/dist/chunk-HYUKPHCT.cjs.map +1 -0
  108. package/dist/{chunk-NNUK5ZM7.cjs → chunk-JQLWKNJO.cjs} +29 -27
  109. package/dist/chunk-JQLWKNJO.cjs.map +1 -0
  110. package/dist/{chunk-OEREKAAP.cjs → chunk-JZEYHDWJ.cjs} +75 -75
  111. package/dist/{chunk-OEREKAAP.cjs.map → chunk-JZEYHDWJ.cjs.map} +1 -1
  112. package/dist/{chunk-PGJYD67F.cjs → chunk-KNGZZC4O.cjs} +7 -6
  113. package/dist/chunk-KNGZZC4O.cjs.map +1 -0
  114. package/dist/{chunk-NIE3N6OM.cjs → chunk-KP5AITQ4.cjs} +10 -10
  115. package/dist/{chunk-NIE3N6OM.cjs.map → chunk-KP5AITQ4.cjs.map} +1 -1
  116. package/dist/{chunk-YYPZOEED.cjs → chunk-LHWOKOMP.cjs} +23 -2
  117. package/dist/chunk-LHWOKOMP.cjs.map +1 -0
  118. package/dist/{chunk-57NHXEU2.cjs → chunk-MXBXZXXQ.cjs} +5 -5
  119. package/dist/{chunk-57NHXEU2.cjs.map → chunk-MXBXZXXQ.cjs.map} +1 -1
  120. package/dist/{chunk-WXUU3COI.cjs → chunk-MZ2KZXNU.cjs} +3 -3
  121. package/dist/{chunk-WXUU3COI.cjs.map → chunk-MZ2KZXNU.cjs.map} +1 -1
  122. package/dist/chunk-NAJN32MF.cjs +154 -0
  123. package/dist/chunk-NAJN32MF.cjs.map +1 -0
  124. package/dist/{chunk-557MJ4IH.cjs → chunk-NLOETJCB.cjs} +17 -154
  125. package/dist/chunk-NLOETJCB.cjs.map +1 -0
  126. package/dist/{chunk-4XJEHKVZ.cjs → chunk-PIYYBPHH.cjs} +4 -4
  127. package/dist/{chunk-4XJEHKVZ.cjs.map → chunk-PIYYBPHH.cjs.map} +1 -1
  128. package/dist/chunk-Q3XJUXID.cjs +4774 -0
  129. package/dist/chunk-Q3XJUXID.cjs.map +1 -0
  130. package/dist/{chunk-325GVZE6.cjs → chunk-Q6DQGGP4.cjs} +3 -3
  131. package/dist/{chunk-325GVZE6.cjs.map → chunk-Q6DQGGP4.cjs.map} +1 -1
  132. package/dist/chunk-QFXILJMJ.cjs +458 -0
  133. package/dist/chunk-QFXILJMJ.cjs.map +1 -0
  134. package/dist/{chunk-R7CJEIA5.cjs → chunk-RYVZDFVO.cjs} +8 -9
  135. package/dist/chunk-RYVZDFVO.cjs.map +1 -0
  136. package/dist/{chunk-VLCY46K6.cjs → chunk-TG2GM7WJ.cjs} +4 -3
  137. package/dist/chunk-TG2GM7WJ.cjs.map +1 -0
  138. package/dist/{chunk-EOG6OT5I.cjs → chunk-TXP2N3DC.cjs} +4 -4
  139. package/dist/{chunk-EOG6OT5I.cjs.map → chunk-TXP2N3DC.cjs.map} +1 -1
  140. package/dist/{chunk-KXIRVKCJ.cjs → chunk-UUENH4BJ.cjs} +3 -3
  141. package/dist/{chunk-KXIRVKCJ.cjs.map → chunk-UUENH4BJ.cjs.map} +1 -1
  142. package/dist/chunk-VJ5ZLRBD.cjs +27 -0
  143. package/dist/chunk-VJ5ZLRBD.cjs.map +1 -0
  144. package/dist/{chunk-P77YTTJ3.cjs → chunk-W6B3RYTX.cjs} +4 -4
  145. package/dist/{chunk-P77YTTJ3.cjs.map → chunk-W6B3RYTX.cjs.map} +1 -1
  146. package/dist/chunk-WOOOMTTA.cjs +19 -0
  147. package/dist/chunk-WOOOMTTA.cjs.map +1 -0
  148. package/dist/{chunk-ZPPMAL5P.cjs → chunk-WQMR3O2D.cjs} +6 -10
  149. package/dist/chunk-WQMR3O2D.cjs.map +1 -0
  150. package/dist/{chunk-CJYWHUZR.cjs → chunk-XCKHOXRP.cjs} +4 -4
  151. package/dist/{chunk-CJYWHUZR.cjs.map → chunk-XCKHOXRP.cjs.map} +1 -1
  152. package/dist/{chunk-6WMMZLEV.cjs → chunk-XJEXFEWG.cjs} +2 -27
  153. package/dist/chunk-XJEXFEWG.cjs.map +1 -0
  154. package/dist/chunk-XK4TVJKD.cjs +73 -0
  155. package/dist/chunk-XK4TVJKD.cjs.map +1 -0
  156. package/dist/chunk-XTR26TNE.cjs +1358 -0
  157. package/dist/chunk-XTR26TNE.cjs.map +1 -0
  158. package/dist/{chunk-E7TE2WVT.cjs → chunk-ZVEW3JBT.cjs} +3 -3
  159. package/dist/{chunk-E7TE2WVT.cjs.map → chunk-ZVEW3JBT.cjs.map} +1 -1
  160. package/dist/collaboration/index.cjs +73 -73
  161. package/dist/collaboration/sharing/ShareControl.js +10 -2
  162. package/dist/collaboration/sharing/ShareControl.js.map +2 -2
  163. package/dist/components/SharedCell.d.ts +2 -4
  164. package/dist/components/SharedCell.js +4 -8
  165. package/dist/components/SharedCell.js.map +2 -2
  166. package/dist/components/ZoomSlider.d.ts +25 -0
  167. package/dist/components/ZoomSlider.js +59 -0
  168. package/dist/components/ZoomSlider.js.map +7 -0
  169. package/dist/connect/docx.cjs +20 -20
  170. package/dist/connect/index.cjs +1210 -1264
  171. package/dist/connect/index.cjs.map +1 -1
  172. package/dist/connect/viewer.cjs +42 -36
  173. package/dist/connection/ai.d.ts +1 -1
  174. package/dist/connection/facts/factPageColumns.js +3 -9
  175. package/dist/connection/facts/factPageColumns.js.map +2 -2
  176. package/dist/connection/files/ConnectedNewFileMenu.d.ts +2 -1
  177. package/dist/connection/files/ConnectedNewFileMenu.js +9 -3
  178. package/dist/connection/files/ConnectedNewFileMenu.js.map +2 -2
  179. package/dist/connection/files/explorer/ConnectedFilesExplorer.js +1 -1
  180. package/dist/connection/files/explorer/ConnectedFilesExplorer.js.map +2 -2
  181. package/dist/connection/files/explorer/FileTiles.js +1 -1
  182. package/dist/connection/files/explorer/FileTiles.js.map +2 -2
  183. package/dist/connection/files/fields/documentField.js +1 -1
  184. package/dist/connection/files/fields/documentField.js.map +2 -2
  185. package/dist/connection/files/grid/cells.js +1 -3
  186. package/dist/connection/files/grid/cells.js.map +2 -2
  187. package/dist/connection/files/grid/documentColumns.js +4 -3
  188. package/dist/connection/files/grid/documentColumns.js.map +2 -2
  189. package/dist/connection/files/page/DocumentsFilterBarActions.js +17 -28
  190. package/dist/connection/files/page/DocumentsFilterBarActions.js.map +2 -2
  191. package/dist/connection/mail/useMailboxDefaults.js +1 -1
  192. package/dist/connection/mail/useMailboxDefaults.js.map +2 -2
  193. package/dist/connection/panels/useSessionPanelMode.js +3 -2
  194. package/dist/connection/panels/useSessionPanelMode.js.map +2 -2
  195. package/dist/connection/presentation/ClippingMediaViewer.d.ts +12 -0
  196. package/dist/connection/presentation/ClippingMediaViewer.js +153 -0
  197. package/dist/connection/presentation/ClippingMediaViewer.js.map +7 -0
  198. package/dist/connection/presentation/ClippingPdfViewer.d.ts +22 -0
  199. package/dist/connection/presentation/ClippingPdfViewer.js +75 -0
  200. package/dist/connection/presentation/ClippingPdfViewer.js.map +7 -0
  201. package/dist/connection/presentation/ConnectedPresentation.d.ts +12 -0
  202. package/dist/connection/presentation/ConnectedPresentation.js +100 -0
  203. package/dist/connection/presentation/ConnectedPresentation.js.map +7 -0
  204. package/dist/connection/presentation/ConnectedSlidesTab.d.ts +20 -0
  205. package/dist/connection/presentation/ConnectedSlidesTab.js +220 -0
  206. package/dist/connection/presentation/ConnectedSlidesTab.js.map +7 -0
  207. package/dist/connection/presentation/CropClipDialog.d.ts +11 -0
  208. package/dist/connection/presentation/CropClipDialog.js +86 -0
  209. package/dist/connection/presentation/CropClipDialog.js.map +7 -0
  210. package/dist/connection/presentation/GenerateTile.d.ts +4 -0
  211. package/dist/connection/presentation/GenerateTile.js +24 -0
  212. package/dist/connection/presentation/GenerateTile.js.map +7 -0
  213. package/dist/connection/presentation/LabelColumnMenu.d.ts +8 -0
  214. package/dist/connection/presentation/LabelColumnMenu.js +38 -0
  215. package/dist/connection/presentation/LabelColumnMenu.js.map +7 -0
  216. package/dist/connection/presentation/PresentationDialogs.d.ts +39 -0
  217. package/dist/connection/presentation/PresentationDialogs.js +295 -0
  218. package/dist/connection/presentation/PresentationDialogs.js.map +7 -0
  219. package/dist/connection/presentation/PresentationFileCard.d.ts +10 -0
  220. package/dist/connection/presentation/PresentationFileCard.js +35 -0
  221. package/dist/connection/presentation/PresentationFileCard.js.map +7 -0
  222. package/dist/connection/presentation/PresentationPill.d.ts +8 -0
  223. package/dist/connection/presentation/PresentationPill.js +44 -0
  224. package/dist/connection/presentation/PresentationPill.js.map +7 -0
  225. package/dist/connection/presentation/PresentationSlot.d.ts +7 -0
  226. package/dist/connection/presentation/PresentationSlot.js +35 -0
  227. package/dist/connection/presentation/PresentationSlot.js.map +7 -0
  228. package/dist/connection/presentation/requests.d.ts +16 -0
  229. package/dist/connection/presentation/requests.js +20 -0
  230. package/dist/connection/presentation/requests.js.map +7 -0
  231. package/dist/connection/presentation/useImageGeneration.d.ts +11 -0
  232. package/dist/connection/presentation/useImageGeneration.js +66 -0
  233. package/dist/connection/presentation/useImageGeneration.js.map +7 -0
  234. package/dist/connection/presentation/useLabelColumns.d.ts +15 -0
  235. package/dist/connection/presentation/useLabelColumns.js +33 -0
  236. package/dist/connection/presentation/useLabelColumns.js.map +7 -0
  237. package/dist/connection/presentation/usePresentationController.d.ts +15 -0
  238. package/dist/connection/presentation/usePresentationController.js +118 -0
  239. package/dist/connection/presentation/usePresentationController.js.map +7 -0
  240. package/dist/connection/presentation/usePresentationFiles.d.ts +44 -0
  241. package/dist/connection/presentation/usePresentationFiles.js +307 -0
  242. package/dist/connection/presentation/usePresentationFiles.js.map +7 -0
  243. package/dist/connection/presentation/useViewerClipping.d.ts +14 -0
  244. package/dist/connection/presentation/useViewerClipping.js +18 -0
  245. package/dist/connection/presentation/useViewerClipping.js.map +7 -0
  246. package/dist/connection/sharing/WorkspaceMembersList.d.ts +4 -0
  247. package/dist/connection/sharing/WorkspaceMembersList.js +34 -0
  248. package/dist/connection/sharing/WorkspaceMembersList.js.map +7 -0
  249. package/dist/connection/shell/ConnectedAppShell.js +9 -1
  250. package/dist/connection/shell/ConnectedAppShell.js.map +2 -2
  251. package/dist/connection/viewer/CleanViewControl.d.ts +8 -0
  252. package/dist/connection/viewer/CleanViewControl.js +76 -0
  253. package/dist/connection/viewer/CleanViewControl.js.map +7 -0
  254. package/dist/connection/viewer/ConnectedDocumentViewer.js +31 -31
  255. package/dist/connection/viewer/ConnectedDocumentViewer.js.map +2 -2
  256. package/dist/connection/viewer/ViewerCropModal.d.ts +5 -0
  257. package/dist/connection/viewer/ViewerCropModal.js +22 -0
  258. package/dist/connection/viewer/ViewerCropModal.js.map +7 -0
  259. package/dist/connection/viewer/ViewerPdfPane.d.ts +3 -1
  260. package/dist/connection/viewer/ViewerPdfPane.js +57 -2
  261. package/dist/connection/viewer/ViewerPdfPane.js.map +2 -2
  262. package/dist/connection/viewer/drafts.js +6 -4
  263. package/dist/connection/viewer/drafts.js.map +2 -2
  264. package/dist/connection/viewer/pdf/PdfPassageHighlights.d.ts +12 -0
  265. package/dist/connection/viewer/pdf/PdfPassageHighlights.js +36 -0
  266. package/dist/connection/viewer/pdf/PdfPassageHighlights.js.map +7 -0
  267. package/dist/connection/viewer/pdf/passageHighlights.d.ts +26 -0
  268. package/dist/connection/viewer/pdf/passageHighlights.js +40 -0
  269. package/dist/connection/viewer/pdf/passageHighlights.js.map +7 -0
  270. package/dist/connection/viewer/pdf/usePdfPassageHighlights.d.ts +9 -0
  271. package/dist/connection/viewer/pdf/usePdfPassageHighlights.js +47 -0
  272. package/dist/connection/viewer/pdf/usePdfPassageHighlights.js.map +7 -0
  273. package/dist/connection/viewer/shareDocument.d.ts +11 -0
  274. package/dist/connection/viewer/shareDocument.js +11 -0
  275. package/dist/connection/viewer/shareDocument.js.map +7 -0
  276. package/dist/connection/viewer/slidesTabChunk.d.ts +2 -0
  277. package/dist/connection/viewer/slidesTabChunk.js +9 -0
  278. package/dist/connection/viewer/slidesTabChunk.js.map +7 -0
  279. package/dist/connection/viewer/useCleanView.d.ts +14 -0
  280. package/dist/connection/viewer/useCleanView.js +29 -0
  281. package/dist/connection/viewer/useCleanView.js.map +7 -0
  282. package/dist/connection/viewer/useViewedDocument.d.ts +1 -0
  283. package/dist/connection/viewer/useViewedDocument.js +9 -1
  284. package/dist/connection/viewer/useViewedDocument.js.map +2 -2
  285. package/dist/connection/viewer/useViewerTabs.js +18 -4
  286. package/dist/connection/viewer/useViewerTabs.js.map +2 -2
  287. package/dist/connection/workflows/ConnectedWorkflowStart.d.ts +14 -2
  288. package/dist/connection/workflows/ConnectedWorkflowStart.js +5 -2
  289. package/dist/connection/workflows/ConnectedWorkflowStart.js.map +2 -2
  290. package/dist/connection/workflows/workflowsPageLabels.js +1 -1
  291. package/dist/connection/workflows/workflowsPageLabels.js.map +1 -1
  292. package/dist/dashboards/index.cjs +1 -1
  293. package/dist/databases/index.cjs +49 -49
  294. package/dist/document-tools/DocumentToolButtons.d.ts +2 -0
  295. package/dist/document-tools/DocumentToolButtons.js +22 -1
  296. package/dist/document-tools/DocumentToolButtons.js.map +2 -2
  297. package/dist/document-tools/index.cjs +16 -12
  298. package/dist/document-tools/index.d.ts +1 -1
  299. package/dist/document-tools/index.js +2 -0
  300. package/dist/document-tools/index.js.map +2 -2
  301. package/dist/embed/index.cjs +43 -41
  302. package/dist/facts/factColumns.js +3 -3
  303. package/dist/facts/factColumns.js.map +1 -1
  304. package/dist/facts/index.cjs +42 -42
  305. package/dist/files/GridViewImpl.js +1 -1
  306. package/dist/files/GridViewImpl.js.map +2 -2
  307. package/dist/files/HtmlViewerParts.js +7 -15
  308. package/dist/files/HtmlViewerParts.js.map +2 -2
  309. package/dist/files/ViewerChrome.d.ts +5 -1
  310. package/dist/files/ViewerChrome.js +16 -6
  311. package/dist/files/ViewerChrome.js.map +2 -2
  312. package/dist/files/index.cjs +226 -226
  313. package/dist/files/navigator/DocumentSearchList.js +1 -1
  314. package/dist/files/navigator/DocumentSearchList.js.map +2 -2
  315. package/dist/index.cjs +1668 -1666
  316. package/dist/index.cjs.map +1 -1
  317. package/dist/presentation/BoxActionBar.d.ts +11 -0
  318. package/dist/presentation/BoxActionBar.js +182 -0
  319. package/dist/presentation/BoxActionBar.js.map +7 -0
  320. package/dist/presentation/ClipActionBar.d.ts +26 -0
  321. package/dist/presentation/ClipActionBar.js +103 -0
  322. package/dist/presentation/ClipActionBar.js.map +7 -0
  323. package/dist/presentation/ClipCaptureOverlay.d.ts +14 -0
  324. package/dist/presentation/ClipCaptureOverlay.js +69 -0
  325. package/dist/presentation/ClipCaptureOverlay.js.map +7 -0
  326. package/dist/presentation/ClipImage.d.ts +21 -0
  327. package/dist/presentation/ClipImage.js +119 -0
  328. package/dist/presentation/ClipImage.js.map +7 -0
  329. package/dist/presentation/ClipTray.d.ts +11 -0
  330. package/dist/presentation/ClipTray.js +152 -0
  331. package/dist/presentation/ClipTray.js.map +7 -0
  332. package/dist/presentation/ClipViewControls.d.ts +11 -0
  333. package/dist/presentation/ClipViewControls.js +142 -0
  334. package/dist/presentation/ClipViewControls.js.map +7 -0
  335. package/dist/presentation/DesignMenu.d.ts +8 -0
  336. package/dist/presentation/DesignMenu.js +199 -0
  337. package/dist/presentation/DesignMenu.js.map +7 -0
  338. package/dist/presentation/LayoutMenu.d.ts +17 -0
  339. package/dist/presentation/LayoutMenu.js +122 -0
  340. package/dist/presentation/LayoutMenu.js.map +7 -0
  341. package/dist/presentation/MediaClip.d.ts +15 -0
  342. package/dist/presentation/MediaClip.js +67 -0
  343. package/dist/presentation/MediaClip.js.map +7 -0
  344. package/dist/presentation/Notice.d.ts +6 -0
  345. package/dist/presentation/Notice.js +43 -0
  346. package/dist/presentation/Notice.js.map +7 -0
  347. package/dist/presentation/PresentationStage.d.ts +32 -0
  348. package/dist/presentation/PresentationStage.js +232 -0
  349. package/dist/presentation/PresentationStage.js.map +7 -0
  350. package/dist/presentation/PresenterView.d.ts +16 -0
  351. package/dist/presentation/PresenterView.js +69 -0
  352. package/dist/presentation/PresenterView.js.map +7 -0
  353. package/dist/presentation/SlideDecor.d.ts +25 -0
  354. package/dist/presentation/SlideDecor.js +189 -0
  355. package/dist/presentation/SlideDecor.js.map +7 -0
  356. package/dist/presentation/SlidesEditor.d.ts +25 -0
  357. package/dist/presentation/SlidesEditor.js +359 -0
  358. package/dist/presentation/SlidesEditor.js.map +7 -0
  359. package/dist/presentation/StageBox.d.ts +30 -0
  360. package/dist/presentation/StageBox.js +281 -0
  361. package/dist/presentation/StageBox.js.map +7 -0
  362. package/dist/presentation/StageItem.d.ts +37 -0
  363. package/dist/presentation/StageItem.js +211 -0
  364. package/dist/presentation/StageItem.js.map +7 -0
  365. package/dist/presentation/box-style.d.ts +6 -0
  366. package/dist/presentation/box-style.js +19 -0
  367. package/dist/presentation/box-style.js.map +7 -0
  368. package/dist/presentation/boxes.d.ts +105 -0
  369. package/dist/presentation/boxes.js +103 -0
  370. package/dist/presentation/boxes.js.map +7 -0
  371. package/dist/presentation/draw-boxes.d.ts +8 -0
  372. package/dist/presentation/draw-boxes.js +130 -0
  373. package/dist/presentation/draw-boxes.js.map +7 -0
  374. package/dist/presentation/export-boxes.d.ts +10 -0
  375. package/dist/presentation/export-boxes.js +74 -0
  376. package/dist/presentation/export-boxes.js.map +7 -0
  377. package/dist/presentation/export-pptx.d.ts +16 -0
  378. package/dist/presentation/export-pptx.js +194 -0
  379. package/dist/presentation/export-pptx.js.map +7 -0
  380. package/dist/presentation/import-pptx.d.ts +35 -0
  381. package/dist/presentation/import-pptx.js +659 -0
  382. package/dist/presentation/import-pptx.js.map +7 -0
  383. package/dist/presentation/merge-outside-edits.d.ts +12 -0
  384. package/dist/presentation/merge-outside-edits.js +35 -0
  385. package/dist/presentation/merge-outside-edits.js.map +7 -0
  386. package/dist/presentation/model.d.ts +201 -0
  387. package/dist/presentation/model.js +271 -0
  388. package/dist/presentation/model.js.map +7 -0
  389. package/dist/presentation/panel-id.d.ts +34 -0
  390. package/dist/presentation/panel-id.js +24 -0
  391. package/dist/presentation/panel-id.js.map +7 -0
  392. package/dist/presentation/persistence.d.ts +121 -0
  393. package/dist/presentation/persistence.js +141 -0
  394. package/dist/presentation/persistence.js.map +7 -0
  395. package/dist/presentation/pptx-data.d.ts +22 -0
  396. package/dist/presentation/pptx-data.js +83 -0
  397. package/dist/presentation/pptx-data.js.map +7 -0
  398. package/dist/presentation/pptx-xml.d.ts +90 -0
  399. package/dist/presentation/pptx-xml.js +333 -0
  400. package/dist/presentation/pptx-xml.js.map +7 -0
  401. package/dist/presentation/render-slides.d.ts +58 -0
  402. package/dist/presentation/render-slides.js +309 -0
  403. package/dist/presentation/render-slides.js.map +7 -0
  404. package/dist/presentation/saved-boxes.d.ts +11 -0
  405. package/dist/presentation/saved-boxes.js +80 -0
  406. package/dist/presentation/saved-boxes.js.map +7 -0
  407. package/dist/presentation/slide-layout.d.ts +54 -0
  408. package/dist/presentation/slide-layout.js +117 -0
  409. package/dist/presentation/slide-layout.js.map +7 -0
  410. package/dist/presentation/stage-videos.d.ts +5 -0
  411. package/dist/presentation/stage-videos.js +19 -0
  412. package/dist/presentation/stage-videos.js.map +7 -0
  413. package/dist/presentation/store.d.ts +203 -0
  414. package/dist/presentation/store.js +429 -0
  415. package/dist/presentation/store.js.map +7 -0
  416. package/dist/presentation/theme.d.ts +102 -0
  417. package/dist/presentation/theme.js +276 -0
  418. package/dist/presentation/theme.js.map +7 -0
  419. package/dist/presentation/useClipDrag.d.ts +26 -0
  420. package/dist/presentation/useClipDrag.js +65 -0
  421. package/dist/presentation/useClipDrag.js.map +7 -0
  422. package/dist/presentation/useObjectUrl.d.ts +6 -0
  423. package/dist/presentation/useObjectUrl.js +15 -0
  424. package/dist/presentation/useObjectUrl.js.map +7 -0
  425. package/dist/presentation/usePresenterKeys.d.ts +13 -0
  426. package/dist/presentation/usePresenterKeys.js +62 -0
  427. package/dist/presentation/usePresenterKeys.js.map +7 -0
  428. package/dist/settings/index.cjs +151 -150
  429. package/dist/shell/PanelPortal.js +1 -0
  430. package/dist/shell/PanelPortal.js.map +2 -2
  431. package/dist/shell/index.cjs +112 -110
  432. package/dist/shell/panel-windows.d.ts +2 -0
  433. package/dist/shell/panel-windows.js +7 -2
  434. package/dist/shell/panel-windows.js.map +2 -2
  435. package/dist/studio/index.cjs +28 -26
  436. package/dist/studio/index.cjs.map +1 -1
  437. package/dist/styles.css +1 -1
  438. package/dist/workflow-canvas/index.cjs +58 -57
  439. package/dist/workflow-canvas/index.cjs.map +1 -1
  440. package/node_modules/@arbidocs/coedit/package.json +1 -1
  441. package/package.json +6 -5
  442. package/dist/ConnectedCallDock-WER7R222.cjs.map +0 -1
  443. package/dist/DocumentReviewCard-ZSBZBGFK.cjs.map +0 -1
  444. package/dist/FilesViewerDialog-6UKR5WEF.cjs.map +0 -1
  445. package/dist/GridViewImpl-ZMJJWTOM.cjs.map +0 -1
  446. package/dist/WorkspaceTableView-J3C6VH4T.cjs.map +0 -1
  447. package/dist/ai-IM4A23YT.cjs.map +0 -1
  448. package/dist/chunk-557MJ4IH.cjs.map +0 -1
  449. package/dist/chunk-6UTKM5AB.cjs.map +0 -1
  450. package/dist/chunk-6WMMZLEV.cjs.map +0 -1
  451. package/dist/chunk-B3LZITVF.cjs.map +0 -1
  452. package/dist/chunk-CPG7II4E.cjs.map +0 -1
  453. package/dist/chunk-CPR6EHG7.cjs.map +0 -1
  454. package/dist/chunk-DDIW4HLU.cjs.map +0 -1
  455. package/dist/chunk-NJCK6V6U.cjs.map +0 -1
  456. package/dist/chunk-NNUK5ZM7.cjs.map +0 -1
  457. package/dist/chunk-PGJYD67F.cjs.map +0 -1
  458. package/dist/chunk-R7CJEIA5.cjs.map +0 -1
  459. package/dist/chunk-SB4M3ITT.cjs.map +0 -1
  460. package/dist/chunk-TT4IF52H.cjs.map +0 -1
  461. package/dist/chunk-VLCY46K6.cjs.map +0 -1
  462. package/dist/chunk-YYPZOEED.cjs.map +0 -1
  463. package/dist/chunk-ZPPMAL5P.cjs.map +0 -1
@@ -1,22 +1,26 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunkSB4M3ITT_cjs = require('../chunk-SB4M3ITT.cjs');
4
+ var chunk7VUJGHMY_cjs = require('../chunk-7VUJGHMY.cjs');
5
+ require('../chunk-5LTIZ44D.cjs');
6
+ require('../chunk-XTR26TNE.cjs');
5
7
  require('../chunk-4CIVQWAX.cjs');
6
8
  var chunkPL7HUTM3_cjs = require('../chunk-PL7HUTM3.cjs');
7
- require('../chunk-YGXOKB5Z.cjs');
8
- require('../chunk-KXIRVKCJ.cjs');
9
- require('../chunk-TT4IF52H.cjs');
10
- require('../chunk-NJCK6V6U.cjs');
11
- require('../chunk-NNUK5ZM7.cjs');
9
+ require('../chunk-VJ5ZLRBD.cjs');
10
+ require('../chunk-734NPQNR.cjs');
11
+ require('../chunk-UUENH4BJ.cjs');
12
+ require('../chunk-BVAT4EVC.cjs');
13
+ require('../chunk-EATIFPKP.cjs');
14
+ require('../chunk-HYUKPHCT.cjs');
15
+ require('../chunk-JQLWKNJO.cjs');
12
16
  require('../chunk-223D4727.cjs');
13
17
  require('../chunk-SNUBQMIS.cjs');
14
- require('../chunk-VGCTYTEW.cjs');
18
+ require('../chunk-C2OICDMI.cjs');
15
19
  require('../chunk-4ONPEVTP.cjs');
16
20
  require('../chunk-V3KLUWQQ.cjs');
17
21
  require('../chunk-P5AQYC4D.cjs');
18
- require('../chunk-WAV762GP.cjs');
19
- require('../chunk-YYPZOEED.cjs');
22
+ require('../chunk-GQXPNIRE.cjs');
23
+ require('../chunk-LHWOKOMP.cjs');
20
24
  require('../chunk-GNZAH6UI.cjs');
21
25
  require('../chunk-JH6JTI76.cjs');
22
26
  require('../chunk-QQMMCXBP.cjs');
@@ -24,32 +28,45 @@ require('../chunk-DTMBAFIL.cjs');
24
28
  require('../chunk-ZESMRGDV.cjs');
25
29
  require('../chunk-VCEX7COE.cjs');
26
30
  require('../chunk-34HQO4ZQ.cjs');
27
- require('../chunk-B3LZITVF.cjs');
31
+ require('../chunk-CT3SLXB7.cjs');
32
+ require('../chunk-EHP6OH5D.cjs');
33
+ require('../chunk-QFXILJMJ.cjs');
28
34
  require('../chunk-MZZ3SBQL.cjs');
29
- require('../chunk-NY3YUCOW.cjs');
30
- require('../chunk-325GVZE6.cjs');
31
- require('../chunk-ZPPMAL5P.cjs');
35
+ require('../chunk-4NPCDS2X.cjs');
36
+ require('../chunk-Q6DQGGP4.cjs');
37
+ require('../chunk-WQMR3O2D.cjs');
32
38
  require('../chunk-ORELHENJ.cjs');
33
39
  require('../chunk-NWNVWO6L.cjs');
34
40
  require('../chunk-SK6HQ46Q.cjs');
35
- require('../chunk-MNIQDXM6.cjs');
36
- require('../chunk-E3Y7RI3J.cjs');
37
- require('../chunk-VLCY46K6.cjs');
41
+ require('../chunk-TG2GM7WJ.cjs');
42
+ require('../chunk-DEXUL3T6.cjs');
43
+ require('../chunk-AFQTQC7A.cjs');
44
+ require('../chunk-XJEXFEWG.cjs');
45
+ require('../chunk-Z2XZ2D4N.cjs');
46
+ require('../chunk-YZSQ7F5K.cjs');
47
+ require('../chunk-MCXS6X37.cjs');
48
+ require('../chunk-KQF7POTG.cjs');
38
49
  require('../chunk-VKH3BEZE.cjs');
50
+ require('../chunk-75BNMCUX.cjs');
39
51
  require('../chunk-OEJQFPWO.cjs');
40
52
  require('../chunk-OYXWQTHF.cjs');
41
53
  require('../chunk-S237ORM3.cjs');
42
54
  require('../chunk-II2OEXHW.cjs');
43
- require('../chunk-R7CJEIA5.cjs');
55
+ require('../chunk-FX3K6LNZ.cjs');
56
+ require('../chunk-RYVZDFVO.cjs');
44
57
  require('../chunk-3YEXZX4H.cjs');
45
58
  require('../chunk-4PA6VCCR.cjs');
46
- require('../chunk-WXUU3COI.cjs');
59
+ require('../chunk-MZ2KZXNU.cjs');
47
60
  require('../chunk-AHDJXIUB.cjs');
61
+ require('../chunk-YVCOQHCE.cjs');
48
62
  require('../chunk-RL2HI6NP.cjs');
49
63
  require('../chunk-6UZC4XVV.cjs');
50
- require('../chunk-YVCOQHCE.cjs');
64
+ require('../chunk-QGVOT7E4.cjs');
65
+ require('../chunk-QRAQZTJE.cjs');
66
+ require('../chunk-UDSHVNU3.cjs');
51
67
  require('../chunk-JV5TVUOU.cjs');
52
- require('../chunk-E7TE2WVT.cjs');
68
+ require('../chunk-IPSHAMO2.cjs');
69
+ require('../chunk-ZVEW3JBT.cjs');
53
70
  require('../chunk-EG7EJFUE.cjs');
54
71
  require('../chunk-VG24E4JJ.cjs');
55
72
  require('../chunk-U2FFG2B3.cjs');
@@ -60,32 +77,21 @@ require('../chunk-HQDR43JC.cjs');
60
77
  require('../chunk-JR2YSBD5.cjs');
61
78
  require('../chunk-3YZKDCWY.cjs');
62
79
  require('../chunk-SJSGSHIT.cjs');
63
- require('../chunk-ZW6FPIFC.cjs');
64
- require('../chunk-CT3SLXB7.cjs');
65
- require('../chunk-DEXUL3T6.cjs');
66
- require('../chunk-6WMMZLEV.cjs');
67
- require('../chunk-Z2XZ2D4N.cjs');
68
- require('../chunk-YZSQ7F5K.cjs');
69
- require('../chunk-MCXS6X37.cjs');
70
- require('../chunk-KQF7POTG.cjs');
71
- require('../chunk-75BNMCUX.cjs');
72
- require('../chunk-FX3K6LNZ.cjs');
73
- require('../chunk-QGVOT7E4.cjs');
74
- require('../chunk-QRAQZTJE.cjs');
75
- require('../chunk-UDSHVNU3.cjs');
76
- require('../chunk-IPSHAMO2.cjs');
77
80
  require('../chunk-PPCATBOY.cjs');
81
+ require('../chunk-ZW6FPIFC.cjs');
82
+ require('../chunk-LJJJ6CYH.cjs');
83
+ require('../chunk-MNIQDXM6.cjs');
84
+ require('../chunk-E3Y7RI3J.cjs');
78
85
  require('../chunk-TKHCIHE2.cjs');
79
86
  require('../chunk-JDFBEGQO.cjs');
80
87
  require('../chunk-ULWRNGGE.cjs');
81
- require('../chunk-LJJJ6CYH.cjs');
82
88
  require('../chunk-PLIF5CUV.cjs');
83
89
 
84
90
 
85
91
 
86
92
  Object.defineProperty(exports, "ConnectedDocumentViewer", {
87
93
  enumerable: true,
88
- get: function () { return chunkSB4M3ITT_cjs.ConnectedDocumentViewer; }
94
+ get: function () { return chunk7VUJGHMY_cjs.ConnectedDocumentViewer; }
89
95
  });
90
96
  Object.defineProperty(exports, "ConnectedDocumentToolsProvider", {
91
97
  enumerable: true,
@@ -21,7 +21,7 @@ export declare function useConnectedAiTask(): {
21
21
  type: "arbi.artifact";
22
22
  doc_ext_id: string;
23
23
  title: string;
24
- mode: "markdown" | "html" | "text" | "react" | "image";
24
+ mode: "markdown" | "html" | "text" | "react" | "image" | "presentation";
25
25
  content: string;
26
26
  file_type: string;
27
27
  is_complete: boolean;
@@ -1,11 +1,6 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
- import {
4
- UserEntity,
5
- VerifiedToggle,
6
- VisibilityToggle,
7
- formatFriendlyDate
8
- } from "@arbidocs/react/ui";
3
+ import { UserEntity, VerifiedToggle, formatFriendlyDate, SharingEntity } from "@arbidocs/react/ui";
9
4
  import { Quote } from "lucide-react";
10
5
  import { memo, useEffect, useState } from "react";
11
6
  import {
@@ -111,13 +106,12 @@ function createFactPageColumns({
111
106
  }
112
107
  ),
113
108
  renderShared: (fact, params) => /* @__PURE__ */ jsx(
114
- VisibilityToggle,
109
+ SharingEntity,
115
110
  {
116
- items: { shared: fact.shared },
111
+ shared: fact.shared,
117
112
  onToggle: () => onToggleShared(fact),
118
113
  disabled: params.context?.canChangeSharing?.(fact) === false,
119
114
  disabledTooltip: "Only the creator can change who can see this",
120
- showLabel: false,
121
115
  tooltipActive: "Shared with this workspace \u2014 click to make private to you & your agents",
122
116
  tooltipInactive: "Private to you & your agents \u2014 click to share with this workspace",
123
117
  "data-testid": `facts-grid-shared-${fact.external_id}`
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/connection/facts/factPageColumns.tsx"],
4
- "sourcesContent": ["/**\n * The Facts page's grid columns: the blocks Facts columns bound to the page \u2014 toggles, creator\n * avatar, label picker and row actions come from the page via the grid `context` (so the column\n * defs are built once and never rebuilt), and the callbacks own the mutations. A column header\n * keeps its filter button on screen (`FactHeader`).\n */\nimport {\n UserEntity,\n VerifiedToggle,\n VisibilityToggle,\n formatFriendlyDate,\n} from '@arbidocs/react/ui'\nimport type { ColDef, ICellRendererParams, IHeaderParams } from 'ag-grid-community'\nimport { Quote } from 'lucide-react'\nimport { memo, useEffect, useState, type ReactNode } from 'react'\nimport {\n DEFAULT_FACT_COLUMN_LABELS,\n createFactColumns,\n sourceDocCount,\n} from '../../facts/factColumns'\nimport { FactRowActions } from '../../facts/FactRowActions'\nimport { FilterButton } from '../../files/grid/FilterButton'\nimport type { Fact } from './types'\n\n/** A fact's creator, as the page knows them. */\nexport interface FactCreator {\n external_id: string\n given_name?: string | null\n family_name?: string | null\n email?: string | null\n picture?: string | null\n}\n\n/** Resolves a creator's external id to the user. */\nexport type LookupUser = (externalId: string | null | undefined) => FactCreator | null\n\ninterface FactGridContext {\n lookupUser?: LookupUser\n /** The host's own creator avatar. */\n renderUser?: (user: FactCreator | null) => ReactNode\n renderFactTags?: (fact: Fact, rowHeight?: number) => ReactNode\n openEdit?: (fact: Fact) => void\n removeFact?: (fact: Fact) => void\n /** Who may change who can see a fact: its creator or a workspace owner. */\n canChangeSharing?: (fact: Fact) => boolean\n /** Who may reword a fact (it replaces the note): its creator or a workspace owner. */\n canRewrite?: (fact: Fact) => boolean\n /** Whether the fact is in the current chat (read live: the column defs are built once). */\n isInChat?: (fact: Fact) => boolean\n}\n\ninterface FactColumnCallbacks {\n /** Add the fact to the current chat, or take it out (absent: no chat, no In chat column). */\n onToggleInChat?: (fact: Fact) => void\n /** Whether the fact is in the current chat. */\n isInChat?: (fact: Fact) => boolean\n onToggleConfirmed: (fact: Fact) => void\n onToggleShared: (fact: Fact) => void\n}\n\n/** The Sources count opens the fact (as a double-click does), where its passages are listed. */\nfunction renderSourcesCell(params: ICellRendererParams<Fact>): ReactNode {\n const fact = params.data\n const count = sourceDocCount(fact)\n if (!fact || count === 0) return <span className=\"text-muted-foreground/40\">\u2014</span>\n return (\n <button\n type=\"button\"\n onClick={() => (params.context as FactGridContext | undefined)?.openEdit?.(fact)}\n title={DEFAULT_FACT_COLUMN_LABELS.sourcedFrom(count)}\n data-testid={`facts-grid-sources-${fact.external_id}`}\n className=\"inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground\"\n >\n <Quote className=\"size-3 opacity-70\" />\n {count}\n </button>\n )\n}\n\n/** Column header with a PERSISTENT filter button, as the document grid uses.\n *\n * AG Grid's built-in button only appears on header hover, which is invisible on\n * a touchscreen and easy to miss anywhere else. Rendering FilterButton\n * ourselves keeps the control on screen and matches every other grid.\n *\n * A custom header also has to wire sorting itself. This mirrors the tag column\n * header exactly (createTagColumn): the whole header is the click target and\n * the direction shows via AG Grid's own `ag-icon` sort indicator \u2014 so a\n * sortable column here (e.g. Dates) sorts and LOOKS identical to the standard\n * columns, rather than with a bespoke control.\n */\nconst FactHeader = memo(function FactHeader({\n params,\n colId,\n}: {\n params: IHeaderParams\n colId: string\n}) {\n const [sort, setSort] = useState<'asc' | 'desc' | null | undefined>(params.column.getSort())\n\n useEffect(() => {\n const updateSort = () => setSort(params.column.getSort())\n updateSort()\n params.column.addEventListener('sortChanged', updateSort)\n return () => params.column.removeEventListener('sortChanged', updateSort)\n }, [params.column])\n\n return (\n <div\n className={`flex h-full w-full items-center gap-2 px-2 ${\n params.enableSorting ? 'cursor-pointer' : ''\n }`}\n onClick={(e) => {\n if (params.enableSorting) params.progressSort(e.shiftKey)\n }}\n >\n {/* FilterButton carries AG Grid's `.ag-header-icon` class, which the theme\n gives `order: 1`; order-2 keeps the label to its right. */}\n <FilterButton params={params} colId={colId} />\n <span className=\"order-2 min-w-0 flex-1 truncate\">{params.displayName}</span>\n {/* AG Grid's own sort-indicator markup (container + asc/desc icons toggled\n via `ag-hidden`), so the theme styles it byte-for-byte like the default\n header on the standard columns. */}\n <span className=\"ag-sort-indicator-container order-2 flex-shrink-0\" aria-hidden=\"true\">\n <span\n className={`ag-sort-indicator-icon ag-sort-ascending-icon ${\n sort === 'asc' ? '' : 'ag-hidden'\n }`}\n >\n <span className=\"ag-icon ag-icon-asc\" role=\"presentation\" />\n </span>\n <span\n className={`ag-sort-indicator-icon ag-sort-descending-icon ${\n sort === 'desc' ? '' : 'ag-hidden'\n }`}\n >\n <span className=\"ag-icon ag-icon-desc\" role=\"presentation\" />\n </span>\n </span>\n </div>\n )\n})\n\nexport function createFactPageColumns({\n onToggleInChat,\n isInChat,\n onToggleConfirmed,\n onToggleShared,\n}: FactColumnCallbacks): ColDef<Fact>[] {\n const columns = createFactColumns<Fact>({\n onToggleInChat,\n isInChat,\n renderHeader: (params, colId) => <FactHeader params={params} colId={colId} />,\n renderRowActions: (fact, params) => {\n const ctx = params.context as FactGridContext | undefined\n return (\n <FactRowActions\n onEdit={() => ctx?.openEdit?.(fact)}\n canEdit={ctx?.canRewrite?.(fact) !== false}\n onDelete={() => ctx?.removeFact?.(fact)}\n />\n )\n },\n // Pass the row height so the labels clamp to the rows that fully fit.\n renderLabels: (fact, params) =>\n (params.context as FactGridContext | undefined)?.renderFactTags?.(\n fact,\n params.node.rowHeight ?? 52\n ) ?? null,\n renderVerified: (fact) => (\n <VerifiedToggle\n verified={fact.confirmed}\n onToggle={() => onToggleConfirmed(fact)}\n showLabel={false}\n data-testid={`facts-grid-confirmed-${fact.external_id}`}\n />\n ),\n renderShared: (fact, params) => (\n <VisibilityToggle\n items={{ shared: fact.shared }}\n onToggle={() => onToggleShared(fact)}\n disabled={\n (params.context as FactGridContext | undefined)?.canChangeSharing?.(fact) === false\n }\n disabledTooltip=\"Only the creator can change who can see this\"\n showLabel={false}\n tooltipActive=\"Shared with this workspace \u2014 click to make private to you & your agents\"\n tooltipInactive=\"Private to you & your agents \u2014 click to share with this workspace\"\n data-testid={`facts-grid-shared-${fact.external_id}`}\n />\n ),\n // Users are read from the grid context, not captured in the closure: the column defs are\n // built once, and a stale lookup would render every creator as unknown.\n renderCreator: (fact, params) => {\n const ctx = params.context as FactGridContext | undefined\n const user = ctx?.lookupUser?.(fact.created_by_ext_id) ?? null\n if (ctx?.renderUser) return ctx.renderUser(user)\n return (\n <UserEntity\n size=\"sm\"\n variant=\"icon\"\n displayName={\n user\n ? [user.given_name, user.family_name].filter(Boolean).join(' ') || user.email || ''\n : undefined\n }\n initials={\n user\n ? [user.given_name, user.family_name]\n .filter(Boolean)\n .map((n) => (n as string)[0]?.toUpperCase())\n .join('')\n .slice(0, 2)\n : undefined\n }\n picture={user?.picture}\n />\n )\n },\n getCreatorName: (params) => {\n const creator = (params.context as FactGridContext | undefined)?.lookupUser?.(\n params.data?.created_by_ext_id\n )\n if (!creator) return ''\n return (\n [creator.given_name, creator.family_name].filter(Boolean).join(' ') || creator.email || ''\n )\n },\n formatDate: formatFriendlyDate,\n })\n return dateBeforeFact(\n columns.map((col) => {\n if (col.colId === 'sources') return { ...col, cellRenderer: renderSourcesCell }\n // The list arrives newest-created first, which reads as a jumbled chronology: open by date.\n if (col.colId === 'date') return { ...col, sort: 'asc', comparator: compareDatesUndatedLast }\n return col\n })\n )\n}\n\n/**\n * Orders the date-only values (null when undated) so undated facts come after the dated ones,\n * instead of AG Grid's default of listing nulls first. Descending, the grid reverses this, so\n * undated facts lead; the ascending chronology is the one that opens on them otherwise.\n */\nfunction compareDatesUndatedLast(a: string | null, b: string | null): number {\n if (!a && !b) return 0\n if (!a) return 1\n if (!b) return -1\n if (a === b) return 0\n return a < b ? -1 : 1\n}\n\n/**\n * Dates read before the fact, as a chronology does (date, fact, source), so the date sits beside\n * the text instead of past Labels and Verified, where a narrow table pushes it out of view.\n */\nfunction dateBeforeFact(columns: ColDef<Fact>[]): ColDef<Fact>[] {\n const date = columns.find((c) => c.colId === 'date')\n const rest = columns.filter((c) => c.colId !== 'date')\n const textAt = rest.findIndex((c) => c.colId === 'text')\n if (!date || textAt === -1) return columns\n return [...rest.slice(0, textAt), date, ...rest.slice(textAt)]\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * The Facts page's grid columns: the blocks Facts columns bound to the page \u2014 toggles, creator\n * avatar, label picker and row actions come from the page via the grid `context` (so the column\n * defs are built once and never rebuilt), and the callbacks own the mutations. A column header\n * keeps its filter button on screen (`FactHeader`).\n */\nimport { UserEntity, VerifiedToggle, formatFriendlyDate, SharingEntity } from '@arbidocs/react/ui'\nimport type { ColDef, ICellRendererParams, IHeaderParams } from 'ag-grid-community'\nimport { Quote } from 'lucide-react'\nimport { memo, useEffect, useState, type ReactNode } from 'react'\nimport {\n DEFAULT_FACT_COLUMN_LABELS,\n createFactColumns,\n sourceDocCount,\n} from '../../facts/factColumns'\nimport { FactRowActions } from '../../facts/FactRowActions'\nimport { FilterButton } from '../../files/grid/FilterButton'\nimport type { Fact } from './types'\n\n/** A fact's creator, as the page knows them. */\nexport interface FactCreator {\n external_id: string\n given_name?: string | null\n family_name?: string | null\n email?: string | null\n picture?: string | null\n}\n\n/** Resolves a creator's external id to the user. */\nexport type LookupUser = (externalId: string | null | undefined) => FactCreator | null\n\ninterface FactGridContext {\n lookupUser?: LookupUser\n /** The host's own creator avatar. */\n renderUser?: (user: FactCreator | null) => ReactNode\n renderFactTags?: (fact: Fact, rowHeight?: number) => ReactNode\n openEdit?: (fact: Fact) => void\n removeFact?: (fact: Fact) => void\n /** Who may change who can see a fact: its creator or a workspace owner. */\n canChangeSharing?: (fact: Fact) => boolean\n /** Who may reword a fact (it replaces the note): its creator or a workspace owner. */\n canRewrite?: (fact: Fact) => boolean\n /** Whether the fact is in the current chat (read live: the column defs are built once). */\n isInChat?: (fact: Fact) => boolean\n}\n\ninterface FactColumnCallbacks {\n /** Add the fact to the current chat, or take it out (absent: no chat, no In chat column). */\n onToggleInChat?: (fact: Fact) => void\n /** Whether the fact is in the current chat. */\n isInChat?: (fact: Fact) => boolean\n onToggleConfirmed: (fact: Fact) => void\n onToggleShared: (fact: Fact) => void\n}\n\n/** The Sources count opens the fact (as a double-click does), where its passages are listed. */\nfunction renderSourcesCell(params: ICellRendererParams<Fact>): ReactNode {\n const fact = params.data\n const count = sourceDocCount(fact)\n if (!fact || count === 0) return <span className=\"text-muted-foreground/40\">\u2014</span>\n return (\n <button\n type=\"button\"\n onClick={() => (params.context as FactGridContext | undefined)?.openEdit?.(fact)}\n title={DEFAULT_FACT_COLUMN_LABELS.sourcedFrom(count)}\n data-testid={`facts-grid-sources-${fact.external_id}`}\n className=\"inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground\"\n >\n <Quote className=\"size-3 opacity-70\" />\n {count}\n </button>\n )\n}\n\n/** Column header with a PERSISTENT filter button, as the document grid uses.\n *\n * AG Grid's built-in button only appears on header hover, which is invisible on\n * a touchscreen and easy to miss anywhere else. Rendering FilterButton\n * ourselves keeps the control on screen and matches every other grid.\n *\n * A custom header also has to wire sorting itself. This mirrors the tag column\n * header exactly (createTagColumn): the whole header is the click target and\n * the direction shows via AG Grid's own `ag-icon` sort indicator \u2014 so a\n * sortable column here (e.g. Dates) sorts and LOOKS identical to the standard\n * columns, rather than with a bespoke control.\n */\nconst FactHeader = memo(function FactHeader({\n params,\n colId,\n}: {\n params: IHeaderParams\n colId: string\n}) {\n const [sort, setSort] = useState<'asc' | 'desc' | null | undefined>(params.column.getSort())\n\n useEffect(() => {\n const updateSort = () => setSort(params.column.getSort())\n updateSort()\n params.column.addEventListener('sortChanged', updateSort)\n return () => params.column.removeEventListener('sortChanged', updateSort)\n }, [params.column])\n\n return (\n <div\n className={`flex h-full w-full items-center gap-2 px-2 ${\n params.enableSorting ? 'cursor-pointer' : ''\n }`}\n onClick={(e) => {\n if (params.enableSorting) params.progressSort(e.shiftKey)\n }}\n >\n {/* FilterButton carries AG Grid's `.ag-header-icon` class, which the theme\n gives `order: 1`; order-2 keeps the label to its right. */}\n <FilterButton params={params} colId={colId} />\n <span className=\"order-2 min-w-0 flex-1 truncate\">{params.displayName}</span>\n {/* AG Grid's own sort-indicator markup (container + asc/desc icons toggled\n via `ag-hidden`), so the theme styles it byte-for-byte like the default\n header on the standard columns. */}\n <span className=\"ag-sort-indicator-container order-2 flex-shrink-0\" aria-hidden=\"true\">\n <span\n className={`ag-sort-indicator-icon ag-sort-ascending-icon ${\n sort === 'asc' ? '' : 'ag-hidden'\n }`}\n >\n <span className=\"ag-icon ag-icon-asc\" role=\"presentation\" />\n </span>\n <span\n className={`ag-sort-indicator-icon ag-sort-descending-icon ${\n sort === 'desc' ? '' : 'ag-hidden'\n }`}\n >\n <span className=\"ag-icon ag-icon-desc\" role=\"presentation\" />\n </span>\n </span>\n </div>\n )\n})\n\nexport function createFactPageColumns({\n onToggleInChat,\n isInChat,\n onToggleConfirmed,\n onToggleShared,\n}: FactColumnCallbacks): ColDef<Fact>[] {\n const columns = createFactColumns<Fact>({\n onToggleInChat,\n isInChat,\n renderHeader: (params, colId) => <FactHeader params={params} colId={colId} />,\n renderRowActions: (fact, params) => {\n const ctx = params.context as FactGridContext | undefined\n return (\n <FactRowActions\n onEdit={() => ctx?.openEdit?.(fact)}\n canEdit={ctx?.canRewrite?.(fact) !== false}\n onDelete={() => ctx?.removeFact?.(fact)}\n />\n )\n },\n // Pass the row height so the labels clamp to the rows that fully fit.\n renderLabels: (fact, params) =>\n (params.context as FactGridContext | undefined)?.renderFactTags?.(\n fact,\n params.node.rowHeight ?? 52\n ) ?? null,\n renderVerified: (fact) => (\n <VerifiedToggle\n verified={fact.confirmed}\n onToggle={() => onToggleConfirmed(fact)}\n showLabel={false}\n data-testid={`facts-grid-confirmed-${fact.external_id}`}\n />\n ),\n renderShared: (fact, params) => (\n <SharingEntity\n shared={fact.shared}\n onToggle={() => onToggleShared(fact)}\n disabled={\n (params.context as FactGridContext | undefined)?.canChangeSharing?.(fact) === false\n }\n disabledTooltip=\"Only the creator can change who can see this\"\n tooltipActive=\"Shared with this workspace \u2014 click to make private to you & your agents\"\n tooltipInactive=\"Private to you & your agents \u2014 click to share with this workspace\"\n data-testid={`facts-grid-shared-${fact.external_id}`}\n />\n ),\n // Users are read from the grid context, not captured in the closure: the column defs are\n // built once, and a stale lookup would render every creator as unknown.\n renderCreator: (fact, params) => {\n const ctx = params.context as FactGridContext | undefined\n const user = ctx?.lookupUser?.(fact.created_by_ext_id) ?? null\n if (ctx?.renderUser) return ctx.renderUser(user)\n return (\n <UserEntity\n size=\"sm\"\n variant=\"icon\"\n displayName={\n user\n ? [user.given_name, user.family_name].filter(Boolean).join(' ') || user.email || ''\n : undefined\n }\n initials={\n user\n ? [user.given_name, user.family_name]\n .filter(Boolean)\n .map((n) => (n as string)[0]?.toUpperCase())\n .join('')\n .slice(0, 2)\n : undefined\n }\n picture={user?.picture}\n />\n )\n },\n getCreatorName: (params) => {\n const creator = (params.context as FactGridContext | undefined)?.lookupUser?.(\n params.data?.created_by_ext_id\n )\n if (!creator) return ''\n return (\n [creator.given_name, creator.family_name].filter(Boolean).join(' ') || creator.email || ''\n )\n },\n formatDate: formatFriendlyDate,\n })\n return dateBeforeFact(\n columns.map((col) => {\n if (col.colId === 'sources') return { ...col, cellRenderer: renderSourcesCell }\n // The list arrives newest-created first, which reads as a jumbled chronology: open by date.\n if (col.colId === 'date') return { ...col, sort: 'asc', comparator: compareDatesUndatedLast }\n return col\n })\n )\n}\n\n/**\n * Orders the date-only values (null when undated) so undated facts come after the dated ones,\n * instead of AG Grid's default of listing nulls first. Descending, the grid reverses this, so\n * undated facts lead; the ascending chronology is the one that opens on them otherwise.\n */\nfunction compareDatesUndatedLast(a: string | null, b: string | null): number {\n if (!a && !b) return 0\n if (!a) return 1\n if (!b) return -1\n if (a === b) return 0\n return a < b ? -1 : 1\n}\n\n/**\n * Dates read before the fact, as a chronology does (date, fact, source), so the date sits beside\n * the text instead of past Labels and Verified, where a narrow table pushes it out of view.\n */\nfunction dateBeforeFact(columns: ColDef<Fact>[]): ColDef<Fact>[] {\n const date = columns.find((c) => c.colId === 'date')\n const rest = columns.filter((c) => c.colId !== 'date')\n const textAt = rest.findIndex((c) => c.colId === 'text')\n if (!date || textAt === -1) return columns\n return [...rest.slice(0, textAt), date, ...rest.slice(textAt)]\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["FactHeader"]
7
7
  }
@@ -1,5 +1,6 @@
1
1
  /**
2
- * The "Create a file" menu: Doc, Voice, Photo or Video. A plain menu of one-click actions
2
+ * The "Create a file" menu: Doc, Voice, Photo, Video or Presentation. A plain menu of one-click
3
+ * actions
3
4
  * (`ActionMenuDialog`): the pick starts a draft of that kind in the session
4
5
  * (`startDraftDocument`, which shows it in the viewer) and lands on Files, where the user sees it.
5
6
  * The viewer's draft-kind dropdown still lets them change their mind.
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { jsx } from "react/jsx-runtime";
3
- import { Camera, FilePlus2, FileText, Mic, Video } from "lucide-react";
3
+ import { Camera, FilePlus2, FileText, Mic, Presentation, Video } from "lucide-react";
4
4
  import { useArbiSessionStore } from "@arbidocs/react";
5
5
  import { ActionMenuDialog } from "../../home/ActionMenuDialog.js";
6
6
  const ITEMS = [
@@ -17,7 +17,13 @@ const ITEMS = [
17
17
  description: "Take a picture",
18
18
  icon: /* @__PURE__ */ jsx(Camera, { className: "size-7" })
19
19
  },
20
- { id: "video", label: "Video", description: "Record video", icon: /* @__PURE__ */ jsx(Video, { className: "size-7" }) }
20
+ { id: "video", label: "Video", description: "Record video", icon: /* @__PURE__ */ jsx(Video, { className: "size-7" }) },
21
+ {
22
+ id: "presentation",
23
+ label: "Presentation",
24
+ description: "Show parts of documents",
25
+ icon: /* @__PURE__ */ jsx(Presentation, { className: "size-7" })
26
+ }
21
27
  ];
22
28
  function ConnectedNewFileMenu({ open, onOpenChange }) {
23
29
  const session = useArbiSessionStore();
@@ -33,7 +39,7 @@ function ConnectedNewFileMenu({ open, onOpenChange }) {
33
39
  onOpenChange,
34
40
  icon: /* @__PURE__ */ jsx(FilePlus2, { className: "size-5" }),
35
41
  title: "Create a file",
36
- description: "Pick what to start \u2014 write a doc, or record a voice note, photo or video.",
42
+ description: "Pick what to start \u2014 write a doc, record a voice note, photo or video, or build a presentation.",
37
43
  items: ITEMS,
38
44
  onPick: pick,
39
45
  testId: "new-file-menu",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/connection/files/ConnectedNewFileMenu.tsx"],
4
- "sourcesContent": ["/**\n * The \"Create a file\" menu: Doc, Voice, Photo or Video. A plain menu of one-click actions\n * (`ActionMenuDialog`): the pick starts a draft of that kind in the session\n * (`startDraftDocument`, which shows it in the viewer) and lands on Files, where the user sees it.\n * The viewer's draft-kind dropdown still lets them change their mind.\n */\n\nimport { Camera, FilePlus2, FileText, Mic, Video } from 'lucide-react'\nimport { useArbiSessionStore, type ArbiDraftKind } from '@arbidocs/react'\nimport { ActionMenuDialog, type ActionMenuItem } from '../../home/ActionMenuDialog'\n\nconst ITEMS: ActionMenuItem[] = [\n {\n id: 'text',\n label: 'Doc',\n description: 'Write or paste text',\n icon: <FileText className=\"size-7\" />,\n },\n { id: 'audio', label: 'Voice', description: 'Record audio', icon: <Mic className=\"size-7\" /> },\n {\n id: 'photo',\n label: 'Photo',\n description: 'Take a picture',\n icon: <Camera className=\"size-7\" />,\n },\n { id: 'video', label: 'Video', description: 'Record video', icon: <Video className=\"size-7\" /> },\n]\n\nexport interface ConnectedNewFileMenuProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n}\n\nexport function ConnectedNewFileMenu({ open, onOpenChange }: ConnectedNewFileMenuProps) {\n const session = useArbiSessionStore()\n const pick = (id: string) => {\n session.startDraftDocument(id as ArbiDraftKind)\n onOpenChange(false)\n session.setPage('documents')\n }\n return (\n <ActionMenuDialog\n open={open}\n onOpenChange={onOpenChange}\n icon={<FilePlus2 className=\"size-5\" />}\n title=\"Create a file\"\n description=\"Pick what to start \u2014 write a doc, or record a voice note, photo or video.\"\n items={ITEMS}\n onPick={pick}\n testId=\"new-file-menu\"\n itemTestId=\"new-file-item\"\n />\n )\n}\n"],
5
- "mappings": ";AAgBU;AATV,SAAS,QAAQ,WAAW,UAAU,KAAK,aAAa;AACxD,SAAS,2BAA+C;AACxD,SAAS,wBAA6C;AAEtD,MAAM,QAA0B;AAAA,EAC9B;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM,oBAAC,YAAS,WAAU,UAAS;AAAA,EACrC;AAAA,EACA,EAAE,IAAI,SAAS,OAAO,SAAS,aAAa,gBAAgB,MAAM,oBAAC,OAAI,WAAU,UAAS,EAAG;AAAA,EAC7F;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM,oBAAC,UAAO,WAAU,UAAS;AAAA,EACnC;AAAA,EACA,EAAE,IAAI,SAAS,OAAO,SAAS,aAAa,gBAAgB,MAAM,oBAAC,SAAM,WAAU,UAAS,EAAG;AACjG;AAOO,SAAS,qBAAqB,EAAE,MAAM,aAAa,GAA8B;AACtF,QAAM,UAAU,oBAAoB;AACpC,QAAM,OAAO,CAAC,OAAe;AAC3B,YAAQ,mBAAmB,EAAmB;AAC9C,iBAAa,KAAK;AAClB,YAAQ,QAAQ,WAAW;AAAA,EAC7B;AACA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,MAAM,oBAAC,aAAU,WAAU,UAAS;AAAA,MACpC,OAAM;AAAA,MACN,aAAY;AAAA,MACZ,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,QAAO;AAAA,MACP,YAAW;AAAA;AAAA,EACb;AAEJ;",
4
+ "sourcesContent": ["/**\n * The \"Create a file\" menu: Doc, Voice, Photo, Video or Presentation. A plain menu of one-click\n * actions\n * (`ActionMenuDialog`): the pick starts a draft of that kind in the session\n * (`startDraftDocument`, which shows it in the viewer) and lands on Files, where the user sees it.\n * The viewer's draft-kind dropdown still lets them change their mind.\n */\n\nimport { Camera, FilePlus2, FileText, Mic, Presentation, Video } from 'lucide-react'\nimport { useArbiSessionStore, type ArbiDraftKind } from '@arbidocs/react'\nimport { ActionMenuDialog, type ActionMenuItem } from '../../home/ActionMenuDialog'\n\nconst ITEMS: ActionMenuItem[] = [\n {\n id: 'text',\n label: 'Doc',\n description: 'Write or paste text',\n icon: <FileText className=\"size-7\" />,\n },\n { id: 'audio', label: 'Voice', description: 'Record audio', icon: <Mic className=\"size-7\" /> },\n {\n id: 'photo',\n label: 'Photo',\n description: 'Take a picture',\n icon: <Camera className=\"size-7\" />,\n },\n { id: 'video', label: 'Video', description: 'Record video', icon: <Video className=\"size-7\" /> },\n {\n id: 'presentation',\n label: 'Presentation',\n description: 'Show parts of documents',\n icon: <Presentation className=\"size-7\" />,\n },\n]\n\nexport interface ConnectedNewFileMenuProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n}\n\nexport function ConnectedNewFileMenu({ open, onOpenChange }: ConnectedNewFileMenuProps) {\n const session = useArbiSessionStore()\n const pick = (id: string) => {\n session.startDraftDocument(id as ArbiDraftKind)\n onOpenChange(false)\n session.setPage('documents')\n }\n return (\n <ActionMenuDialog\n open={open}\n onOpenChange={onOpenChange}\n icon={<FilePlus2 className=\"size-5\" />}\n title=\"Create a file\"\n description=\"Pick what to start \u2014 write a doc, record a voice note, photo or video, or build a presentation.\"\n items={ITEMS}\n onPick={pick}\n testId=\"new-file-menu\"\n itemTestId=\"new-file-item\"\n />\n )\n}\n"],
5
+ "mappings": ";AAiBU;AATV,SAAS,QAAQ,WAAW,UAAU,KAAK,cAAc,aAAa;AACtE,SAAS,2BAA+C;AACxD,SAAS,wBAA6C;AAEtD,MAAM,QAA0B;AAAA,EAC9B;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM,oBAAC,YAAS,WAAU,UAAS;AAAA,EACrC;AAAA,EACA,EAAE,IAAI,SAAS,OAAO,SAAS,aAAa,gBAAgB,MAAM,oBAAC,OAAI,WAAU,UAAS,EAAG;AAAA,EAC7F;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM,oBAAC,UAAO,WAAU,UAAS;AAAA,EACnC;AAAA,EACA,EAAE,IAAI,SAAS,OAAO,SAAS,aAAa,gBAAgB,MAAM,oBAAC,SAAM,WAAU,UAAS,EAAG;AAAA,EAC/F;AAAA,IACE,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,MAAM,oBAAC,gBAAa,WAAU,UAAS;AAAA,EACzC;AACF;AAOO,SAAS,qBAAqB,EAAE,MAAM,aAAa,GAA8B;AACtF,QAAM,UAAU,oBAAoB;AACpC,QAAM,OAAO,CAAC,OAAe;AAC3B,YAAQ,mBAAmB,EAAmB;AAC9C,iBAAa,KAAK;AAClB,YAAQ,QAAQ,WAAW;AAAA,EAC7B;AACA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,MAAM,oBAAC,aAAU,WAAU,UAAS;AAAA,MACpC,OAAM;AAAA,MACN,aAAY;AAAA,MACZ,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,QAAO;AAAA,MACP,YAAW;AAAA;AAAA,EACb;AAEJ;",
6
6
  "names": []
7
7
  }
@@ -770,7 +770,7 @@ const ConnectedFilesExplorer = forwardRef(function ConnectedFilesExplorer2({
770
770
  );
771
771
  });
772
772
  function DragPreview({ doc, count }) {
773
- const Icon = getFileTypeIcon(doc.file_name, { mime: doc.file_type });
773
+ const Icon = getFileTypeIcon(doc.file_name, { mime: doc.file_type, folder: doc.folder });
774
774
  return /* @__PURE__ */ jsx(
775
775
  ExplorerDragPreview,
776
776
  {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/connection/files/explorer/ConnectedFilesExplorer.tsx"],
4
- "sourcesContent": ["/**\n * The workspace's files as a file explorer (OneDrive / Drive style), bound to the session: folders\n * come from each document's `folder` path; renames, moves and deletes are written through\n * `@arbidocs/react`.\n *\n * - Breadcrumb navigation is the host's (`folderPath` / `onFolderPathChange`): it may keep the\n * folder in a filter, the URL or state.\n * - A virtualised tile grid that scales to thousands of documents, sized by `tileSize`.\n * - OS-style selection: click, \u2318/Ctrl-click, shift-range, the hover checkbox and a marquee.\n * - Drag files onto a folder tile to move them; drop OS files on the view to upload.\n *\n * Selection is the host's (`selectedIds` / `onSelectionChange`), so its bulk actions act on it.\n */\n\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react'\nimport {\n DndContext,\n DragOverlay,\n MouseSensor,\n TouchSensor,\n pointerWithin,\n rectIntersection,\n useSensor,\n useSensors,\n type CollisionDetection,\n type DragEndEvent,\n type DragStartEvent,\n} from '@dnd-kit/core'\nimport { useVirtualizer } from '@tanstack/react-virtual'\nimport {\n useDeleteDocuments,\n useDocumentHostActions,\n useDocumentThumbnails,\n useDownloadDocuments,\n useRenameFolder,\n useTags,\n useUpdateDocuments,\n useWorkspaces,\n} from '@arbidocs/react'\nimport { getDocumentTitle, getFileTypeIcon } from '@arbidocs/react/ui'\nimport {\n ExplorerDragPreview,\n ExplorerDropOverlay,\n ExplorerEmpty,\n ExplorerFrame,\n ExplorerMarquee,\n ExplorerScroller,\n ExplorerStage,\n} from '../../../files/ExplorerSurface'\nimport { ExplorerLoadingTiles } from '../../../files/Explorer'\nimport {\n buildExplorerEntries,\n collectFolderDocs,\n getExplorerDisplayName,\n joinFolderPath,\n searchExplorerDocuments,\n type ExplorerEntry,\n type ExplorerFolder,\n type ExplorerSort,\n} from '../../../files/folders'\nimport { canDeleteDocument, type WorkspaceMemberRole } from '../../../files/permissions'\nimport {\n RECENTLY_DELETED_HINT,\n RECENTLY_DELETED_HINT_PLURAL,\n} from '../../../files/recently-deleted'\nimport { useBlocksEnvironment } from '../../../provider/environment'\nimport { useConnectedWorkspace } from '../../ConnectionProvider'\nimport { useConnectedWorkspaceRole } from '../../ConnectedWorkflowsTable'\nimport { useFilesStore, usePendingFolders } from '../store'\nimport {\n FileTile,\n FolderTile,\n type ExplorerDensity,\n type FileTileDocument,\n type FileTileUser,\n} from './FileTiles'\n\n// Both densities are thumbnail grids, differing only in tile size. Row heights include the gap so\n// the virtualiser's estimate matches the rendered slot exactly.\nconst GRID_GAP = 12\n// The scroller's horizontal padding (px-4 each side).\nconst SCROLL_PADDING_X = 32\n// A portrait page (height / width), so cover-page thumbnails read.\nconst PAGE_ASPECT = 1.3\n/** The zoom slider's bounds: the target tile width in px (smaller: more tiles per row). */\nexport const TILE_MIN = 88\nexport const TILE_MAX = 232\nexport const TILE_DEFAULT = 200\n// Narrower tiles use the compact styling.\nconst COMPACT_BELOW = 132\nconst NO_DOCUMENTS: FileTileDocument[] = []\n\nexport interface ConnectedFilesExplorerHandle {\n /** Add a placeholder folder here and start naming it. */\n triggerNewFolder: () => void\n /** Scroll the tile of `docId` into view, when it is displayed. */\n scrollToDocument: (docId: string) => void\n}\n\nexport interface ConnectedFilesExplorerProps {\n documents: FileTileDocument[]\n isLoading: boolean\n /** The viewer may add, rename and move files here. */\n canUpload: boolean\n selectedIds: string[]\n onSelectionChange: (ids: string[]) => void\n onOpenDocument: (docId: string) => void\n onUploadFiles: (files: File[], folder?: string | null) => void\n /** The open folder (empty: the workspace root). */\n folderPath: readonly string[]\n onFolderPathChange: (path: string[]) => void\n /** A search across every folder (absent or empty: the open folder is listed). */\n search?: string\n sort: ExplorerSort\n sortReversed: boolean\n /** The target tile width in px (`TILE_MIN`..`TILE_MAX`). */\n tileSize: number\n /** The ids of the files displayed, in display order (a navigator steps the same list). */\n onOrderedFilesChange?: (docIds: string[]) => void\n /** Move the selected files: the host opens its folder picker. Absent: not offered. */\n onMoveSelected?: () => void\n /** Move a folder with its structure: the host opens its folder picker. */\n onFolderMove?: (folder: ExplorerFolder) => void\n /** Open a document in the host's review view. Absent: not offered. */\n onOpenInReview?: (docId: string) => void\n /** Shown instead of the explorer while the workspace has no documents and the viewer may add. */\n emptyWorkspace?: ReactNode\n}\n\n/** The workspace's name (the download archive is named after it), members and the viewer's role. */\nfunction useFilesWorkspace() {\n const { workspaceId, userId, live } = useConnectedWorkspace()\n const { members, role } = useConnectedWorkspaceRole()\n const { data: workspaces } = useWorkspaces({ enabled: live })\n const workspaceName = workspaces?.find((w) => w.external_id === workspaceId)?.name\n return {\n workspaceId: workspaceId ?? '',\n workspaceName,\n userId,\n role: (role ?? null) as WorkspaceMemberRole | null,\n members,\n }\n}\n\nexport const ConnectedFilesExplorer = forwardRef<\n ConnectedFilesExplorerHandle,\n ConnectedFilesExplorerProps\n>(function ConnectedFilesExplorer(\n {\n documents,\n isLoading,\n canUpload,\n selectedIds,\n onSelectionChange,\n onOrderedFilesChange,\n onOpenDocument,\n onUploadFiles,\n folderPath,\n onFolderPathChange,\n search = '',\n sort,\n sortReversed,\n tileSize,\n onMoveSelected,\n onFolderMove,\n onOpenInReview,\n emptyWorkspace,\n },\n ref\n) {\n const { confirm, notify } = useBlocksEnvironment()\n const currentPath = folderPath as string[]\n const density: ExplorerDensity = tileSize < COMPACT_BELOW ? 'list' : 'grid'\n const [containerWidth, setContainerWidth] = useState(0)\n const [activeDragId, setActiveDragId] = useState<string | null>(null)\n const [isFileDragOver, setIsFileDragOver] = useState(false)\n const [renamingId, setRenamingId] = useState<string | null>(null)\n\n const scrollRef = useRef<HTMLDivElement | null>(null)\n const anchorRef = useRef<string | null>(null)\n const dragIdsRef = useRef<string[]>([])\n const fileDragDepth = useRef(0)\n // The marquee is drawn by mutating this overlay's style (one paint per frame), so dragging the\n // lasso never re-renders the grid; the selection is computed once, on release.\n const marqueeOverlayRef = useRef<HTMLDivElement | null>(null)\n // The marquee gesture: its origin, whether it adds to the selection, and that selection.\n const marqueeRef = useRef<{ x: number; y: number; additive: boolean; base: string[] } | null>(\n null\n )\n // A background drag crossed the start threshold: the click that follows must not clear.\n const didMarqueeRef = useRef(false)\n\n const updateDocument = useUpdateDocuments()\n const deleteDocuments = useDeleteDocuments()\n const renameFolder = useRenameFolder()\n const { workspaceId: wsId, workspaceName, userId, role, members } = useFilesWorkspace()\n const { downloadDocuments, downloadDocument } = useDownloadDocuments({ workspaceName })\n const { data: workspaceTags } = useTags()\n const hostActions = useDocumentHostActions()\n\n // Member and label lookups for the hover card, memoised so they keep the tiles memoised.\n const userById = useMemo(() => {\n const map = new Map<string, FileTileUser>()\n for (const member of members) map.set(member.user.external_id, member.user)\n return map\n }, [members])\n const tagNameById = useMemo(() => {\n const map = new Map<string, string>()\n for (const tag of workspaceTags ?? []) map.set(tag.external_id, tag.name)\n return map\n }, [workspaceTags])\n\n // Placeholder (empty) folders of this workspace.\n const pendingFolders = usePendingFolders(wsId)\n const addPendingFolder = useFilesStore((state) => state.addPendingFolder)\n const removePendingFolder = useFilesStore((state) => state.removePendingFolder)\n // The placeholder folder being named inline (its full path).\n const [editingFolderPath, setEditingFolderPath] = useState<string | null>(null)\n\n const isSearching = search.trim().length > 0\n\n // The selection for handlers that run outside the render that produced it (drag, keys).\n const selectedSet = useMemo(() => new Set(selectedIds), [selectedIds])\n const selectedIdsRef = useRef(selectedIds)\n selectedIdsRef.current = selectedIds\n\n // The open folder's entries, or a flat search result.\n const { folders, files } = useMemo(() => {\n const result = isSearching\n ? {\n folders: [] as ExplorerFolder[],\n files: searchExplorerDocuments(documents, search, sort),\n }\n : buildExplorerEntries(documents, currentPath, sort, [...pendingFolders])\n if (sortReversed) result.files = [...result.files].reverse()\n return result\n }, [documents, currentPath, sort, isSearching, search, sortReversed, pendingFolders])\n\n const entries: ExplorerEntry<FileTileDocument>[] = useMemo(\n () => [...folders, ...files.map((doc) => ({ kind: 'file' as const, doc }))],\n [folders, files]\n )\n const orderedFileIds = useMemo(() => files.map((d) => d.external_id), [files])\n // Each folder's documents (everything beneath it), and whether the selection holds all or some of\n // them: its checkbox and selected styling. Keyed by the joined path.\n const folderDocs = useMemo(() => {\n const map = new Map<string, FileTileDocument[]>()\n for (const f of folders) map.set(f.path.join('/'), collectFolderDocs(documents, f.path))\n return map\n }, [folders, documents])\n const folderSelection = useMemo(() => {\n const map = new Map<string, { all: boolean; some: boolean }>()\n for (const [key, docs] of folderDocs) {\n const sel = docs.reduce((n, d) => (selectedSet.has(d.external_id) ? n + 1 : n), 0)\n map.set(key, { all: docs.length > 0 && sel === docs.length, some: sel > 0 })\n }\n return map\n }, [folderDocs, selectedSet])\n\n // Columns from the measured width, each tile a portrait page so the thumbnail is legible.\n const contentWidth = Math.max(0, containerWidth - SCROLL_PADDING_X)\n const columnCount = Math.max(\n 1,\n Math.floor((contentWidth + GRID_GAP) / (tileSize + GRID_GAP)) || 1\n )\n const colWidth =\n contentWidth > 0 ? (contentWidth - (columnCount - 1) * GRID_GAP) / columnCount : tileSize\n const tileHeight = Math.max(120, Math.round(colWidth * PAGE_ASPECT))\n const rowHeight = tileHeight + GRID_GAP\n const rowCount = Math.ceil(entries.length / columnCount)\n\n const rowVirtualizer = useVirtualizer({\n count: rowCount,\n getScrollElement: () => scrollRef.current,\n estimateSize: () => rowHeight,\n overscan: 3,\n })\n\n // The displayed files (on-screen rows plus overscan): the thumbnail loader fetches only these.\n const virtualRows = rowVirtualizer.getVirtualItems()\n const firstRow = virtualRows.length > 0 ? virtualRows[0].index : 0\n const lastRow = virtualRows.length > 0 ? virtualRows[virtualRows.length - 1].index : -1\n const visibleFileIds = useMemo(() => {\n const ids: string[] = []\n for (let r = firstRow; r <= lastRow; r++) {\n const start = r * columnCount\n for (let c = 0; c < columnCount; c++) {\n const entry = entries[start + c]\n if (entry?.kind === 'file') ids.push(entry.doc.external_id)\n }\n }\n return ids\n }, [firstRow, lastRow, columnCount, entries])\n const thumbnailsById = useDocumentThumbnails(visibleFileIds)\n\n useEffect(() => {\n rowVirtualizer.measure()\n }, [rowVirtualizer, columnCount, rowHeight, entries.length])\n\n // The empty workspace shows the host's dropzone instead of the scroller, so the first upload\n // mounts the scroller fresh: the width measurement re-runs on this flag (else the grid stays on\n // the loading tiles until a reload).\n const isWholeWorkspaceEmpty =\n !isLoading && documents.length === 0 && canUpload && emptyWorkspace !== undefined\n\n // The width is measured before paint (a first frame at width 0 would flash one stretched column)\n // and rounded and deduplicated, so sub-pixel resize noise does not re-run the tile maths.\n useLayoutEffect(() => {\n const el = scrollRef.current\n if (!el) return\n const apply = () => {\n const next = Math.round(el.clientWidth)\n setContainerWidth((prev) => (prev === next ? prev : next))\n }\n apply()\n const ro = new ResizeObserver(apply)\n ro.observe(el)\n return () => ro.disconnect()\n }, [isWholeWorkspaceEmpty])\n\n // A new listing scrolls to the top and drops the range anchor.\n useEffect(() => {\n anchorRef.current = null\n if (scrollRef.current) scrollRef.current.scrollTop = 0\n }, [currentPath, search])\n\n // ---- Marquee selection: a drag from empty space selects, on release, every tile it touches;\n // \u2318/Ctrl/Shift at the start adds to the selection. Clamped to the scroller.\n useEffect(() => {\n const MARQUEE_THRESHOLD = 5\n let rafId = 0\n let cur: { left: number; top: number; right: number; bottom: number } | null = null\n\n const paint = () => {\n rafId = 0\n const el = marqueeOverlayRef.current\n if (!el || !cur) return\n el.style.display = 'block'\n el.style.left = `${cur.left}px`\n el.style.top = `${cur.top}px`\n el.style.width = `${cur.right - cur.left}px`\n el.style.height = `${cur.bottom - cur.top}px`\n }\n\n const onMove = (e: PointerEvent) => {\n const m = marqueeRef.current\n if (!m) return\n if (\n !didMarqueeRef.current &&\n Math.hypot(e.clientX - m.x, e.clientY - m.y) < MARQUEE_THRESHOLD\n )\n return\n didMarqueeRef.current = true\n const b = scrollRef.current?.getBoundingClientRect()\n const px = b ? Math.max(b.left, Math.min(e.clientX, b.right)) : e.clientX\n const py = b ? Math.max(b.top, Math.min(e.clientY, b.bottom)) : e.clientY\n cur = {\n left: Math.min(m.x, px),\n top: Math.min(m.y, py),\n right: Math.max(m.x, px),\n bottom: Math.max(m.y, py),\n }\n if (!rafId) rafId = requestAnimationFrame(paint)\n }\n\n const onUp = () => {\n const m = marqueeRef.current\n if (!m) return\n marqueeRef.current = null\n if (rafId) cancelAnimationFrame(rafId)\n rafId = 0\n const el = marqueeOverlayRef.current\n if (el) el.style.display = 'none'\n if (!didMarqueeRef.current || !cur) return\n const box = cur\n const hit: string[] = []\n scrollRef.current?.querySelectorAll('[data-doc-id]').forEach((node) => {\n const r = node.getBoundingClientRect()\n if (r.left < box.right && r.right > box.left && r.top < box.bottom && r.bottom > box.top) {\n const id = node.getAttribute('data-doc-id')\n if (id) hit.push(id)\n }\n })\n onSelectionChange(m.additive ? Array.from(new Set([...m.base, ...hit])) : hit)\n }\n\n window.addEventListener('pointermove', onMove)\n window.addEventListener('pointerup', onUp)\n return () => {\n window.removeEventListener('pointermove', onMove)\n window.removeEventListener('pointerup', onUp)\n if (rafId) cancelAnimationFrame(rafId)\n }\n }, [onSelectionChange])\n\n const handleScrollPointerDown = useCallback((e: React.PointerEvent) => {\n if (e.button !== 0) return\n const el = e.target as HTMLElement\n if (\n el.closest(\n '[data-testid=\"explorer-file\"],[data-testid=\"explorer-folder\"],button,input,select,a,[role=\"button\"]'\n )\n ) {\n return\n }\n const additive = e.shiftKey || e.metaKey || e.ctrlKey\n marqueeRef.current = {\n x: e.clientX,\n y: e.clientY,\n additive,\n base: additive ? selectedIdsRef.current : [],\n }\n didMarqueeRef.current = false\n }, [])\n\n // ---- Navigation\n\n const openFolder = useCallback(\n (folder: ExplorerFolder) => onFolderPathChange(folder.path),\n [onFolderPathChange]\n )\n\n // ---- Placeholder (empty) folders\n\n const handleNewFolder = useCallback(() => {\n if (!wsId) return\n const siblings = new Set(folders.map((f) => f.name.toLowerCase()))\n const base = 'New folder'\n let name = base\n let i = 2\n while (siblings.has(name.toLowerCase())) name = `${base} ${i++}`\n const path = joinFolderPath([...currentPath, name])\n if (!path) return\n addPendingFolder(wsId, path)\n setEditingFolderPath(path)\n }, [wsId, folders, currentPath, addPendingFolder])\n\n // Publish the displayed order only when the ids differ: `documents` is a new array on most\n // renders, and handing each new identity to the host's state would loop.\n const lastOrderedRef = useRef<string[]>([])\n useEffect(() => {\n const prev = lastOrderedRef.current\n if (prev.length === orderedFileIds.length && prev.every((id, i) => id === orderedFileIds[i])) {\n return\n }\n lastOrderedRef.current = orderedFileIds\n onOrderedFilesChange?.(orderedFileIds)\n }, [onOrderedFilesChange, orderedFileIds])\n\n const scrollToDocument = useCallback(\n (docId: string) => {\n const index = entries.findIndex((e) => e.kind === 'file' && e.doc.external_id === docId)\n if (index < 0) return\n rowVirtualizer.scrollToIndex(Math.floor(index / columnCount), { align: 'center' })\n },\n [entries, columnCount, rowVirtualizer]\n )\n\n useImperativeHandle(ref, () => ({ triggerNewFolder: handleNewFolder, scrollToDocument }), [\n handleNewFolder,\n scrollToDocument,\n ])\n\n const commitFolderName = useCallback(\n async (folder: ExplorerFolder, rawName: string) => {\n setEditingFolderPath(null)\n const name = rawName.trim()\n if (!wsId || !name || name === folder.name) return\n const siblings = new Set(folders.filter((f) => f !== folder).map((f) => f.name.toLowerCase()))\n if (siblings.has(name.toLowerCase())) {\n notify(`A folder named \"${name}\" already exists here.`, 'error')\n return\n }\n const oldPath = joinFolderPath(folder.path)\n const newPrefix = [...folder.path.slice(0, -1), name]\n const newPath = joinFolderPath(newPrefix)\n\n // Every document beneath the folder moves under the new name, the subtree with it.\n const docs = collectFolderDocs(documents, folder.path)\n try {\n if ((await renameFolder(docs, folder.path, newPrefix)) > 0) {\n notify(`Renamed folder to \"${name}\"`, 'success')\n }\n } catch {\n notify('Failed to rename folder. Please try again.', 'error')\n return\n }\n if (oldPath) removePendingFolder(wsId, oldPath)\n if (docs.length === 0 && newPath) addPendingFolder(wsId, newPath)\n },\n [wsId, folders, documents, renameFolder, notify, addPendingFolder, removePendingFolder]\n )\n\n const cancelFolderName = useCallback(() => setEditingFolderPath(null), [])\n\n // ---- Selection\n\n const clearSelection = useCallback(() => {\n if (selectedIdsRef.current.length > 0) onSelectionChange([])\n anchorRef.current = null\n }, [onSelectionChange])\n\n const handleSelect = useCallback(\n (doc: FileTileDocument, e: React.MouseEvent) => {\n const id = doc.external_id\n // Shift: the range from the anchor, which stays put so further shift-clicks re-extend it.\n if (e.shiftKey) {\n const from = anchorRef.current ?? id\n const a = orderedFileIds.indexOf(from)\n const b = orderedFileIds.indexOf(id)\n if (a !== -1 && b !== -1) {\n anchorRef.current = from\n const [lo, hi] = a < b ? [a, b] : [b, a]\n onSelectionChange(orderedFileIds.slice(lo, hi + 1))\n return\n }\n }\n // \u2318/Ctrl: toggle this file, keeping the rest; it becomes the anchor.\n if (e.metaKey || e.ctrlKey) {\n onSelectionChange(\n selectedSet.has(id) ? selectedIds.filter((s) => s !== id) : [...selectedIds, id]\n )\n anchorRef.current = id\n return\n }\n onSelectionChange([id])\n anchorRef.current = id\n },\n [onSelectionChange, orderedFileIds, selectedIds, selectedSet]\n )\n\n const handleToggle = useCallback(\n (doc: FileTileDocument, e: React.MouseEvent) => {\n e.stopPropagation()\n const id = doc.external_id\n onSelectionChange(\n selectedSet.has(id) ? selectedIds.filter((s) => s !== id) : [...selectedIds, id]\n )\n anchorRef.current = id\n },\n [onSelectionChange, selectedIds, selectedSet]\n )\n\n // A folder toggles every document inside it: a folder is shorthand for \"everything in it\".\n const handleToggleFolder = useCallback(\n (folder: ExplorerFolder, e: React.MouseEvent) => {\n e.stopPropagation()\n const ids = collectFolderDocs(documents, folder.path).map((d) => d.external_id)\n if (ids.length === 0) return\n if (ids.every((id) => selectedSet.has(id))) {\n const remove = new Set(ids)\n onSelectionChange(selectedIds.filter((id) => !remove.has(id)))\n } else {\n onSelectionChange(Array.from(new Set([...selectedIds, ...ids])))\n }\n anchorRef.current = null\n },\n [documents, onSelectionChange, selectedIds, selectedSet]\n )\n\n const handleOpenFile = useCallback(\n (doc: FileTileDocument) => onOpenDocument(doc.external_id),\n [onOpenDocument]\n )\n const handleOpenInReview = useMemo(\n () => (onOpenInReview ? (doc: FileTileDocument) => onOpenInReview(doc.external_id) : undefined),\n [onOpenInReview]\n )\n\n // ---- Rename (inline; the document's title)\n\n const startRename = useCallback((doc: FileTileDocument) => setRenamingId(doc.external_id), [])\n const cancelRename = useCallback(() => setRenamingId(null), [])\n const commitRename = useCallback(\n async (doc: FileTileDocument, name: string) => {\n setRenamingId(null)\n try {\n await updateDocument.mutateAsync({\n documents: [\n { external_id: doc.external_id, doc_metadata: { ...doc.doc_metadata, title: name } },\n ],\n })\n notify(`Renamed to \"${name}\"`, 'success')\n } catch {\n notify('Failed to rename. Please try again.', 'error')\n }\n },\n [updateDocument, notify]\n )\n\n // F2 renames the one selected file.\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== 'F2' || renamingId) return\n const target = e.target as HTMLElement | null\n if (target && /^(input|textarea|select)$/i.test(target.tagName)) return\n if (selectedIdsRef.current.length === 1) setRenamingId(selectedIdsRef.current[0])\n }\n window.addEventListener('keydown', onKey)\n return () => window.removeEventListener('keydown', onKey)\n }, [renamingId])\n\n // ---- A file's menu\n\n const handleDownload = useCallback(\n (doc: FileTileDocument) => void downloadDocument(doc),\n [downloadDocument]\n )\n\n // \"Move to\u2026\" acts on the selection: select just this file first.\n const handleMove = useMemo(\n () =>\n onMoveSelected\n ? (doc: FileTileDocument) => {\n onSelectionChange([doc.external_id])\n onMoveSelected()\n }\n : undefined,\n [onSelectionChange, onMoveSelected]\n )\n\n const handleDelete = useCallback(\n async (doc: FileTileDocument) => {\n const name = getExplorerDisplayName(doc)\n const confirmed = await confirm({\n message: `Delete \"${name}\"? ${RECENTLY_DELETED_HINT}`,\n title: 'Delete file',\n })\n if (!confirmed) return\n try {\n await deleteDocuments.mutateAsync([doc.external_id])\n onSelectionChange(selectedIdsRef.current.filter((id) => id !== doc.external_id))\n notify(`Deleted \"${name}\"`, 'success')\n } catch {\n notify('Failed to delete. Please try again.', 'error')\n }\n },\n [confirm, deleteDocuments, onSelectionChange, notify]\n )\n\n // ---- A folder's menu: each acts on everything the folder holds.\n\n const startFolderRename = useCallback(\n (folder: ExplorerFolder) => setEditingFolderPath(folder.path.join('/')),\n []\n )\n\n const handleFolderDownload = useCallback(\n (folder: ExplorerFolder) => {\n const docs = collectFolderDocs(documents, folder.path)\n if (docs.length > 0) void downloadDocuments(docs)\n },\n [documents, downloadDocuments]\n )\n\n const handleFolderMove = useMemo(() => {\n if (onFolderMove) return onFolderMove\n if (!onMoveSelected) return undefined\n // A flat move (the structure is not kept).\n return (folder: ExplorerFolder) => {\n const ids = collectFolderDocs(documents, folder.path).map((d) => d.external_id)\n if (ids.length === 0) return\n onSelectionChange(ids)\n onMoveSelected()\n }\n }, [documents, onFolderMove, onMoveSelected, onSelectionChange])\n\n const handleFolderDelete = useCallback(\n async (folder: ExplorerFolder) => {\n const docs = collectFolderDocs(documents, folder.path)\n // An empty placeholder: drop it (nothing to delete).\n if (docs.length === 0) {\n const path = joinFolderPath(folder.path)\n if (wsId && path) removePendingFolder(wsId, path)\n return\n }\n const confirmed = await confirm({\n message: `Delete folder \"${folder.name}\" and its ${docs.length} item${docs.length === 1 ? '' : 's'}? ${RECENTLY_DELETED_HINT_PLURAL}`,\n title: 'Delete folder',\n })\n if (!confirmed) return\n try {\n const ids = docs.map((d) => d.external_id)\n await deleteDocuments.mutateAsync(ids)\n const removed = new Set(ids)\n onSelectionChange(selectedIdsRef.current.filter((id) => !removed.has(id)))\n notify(`Deleted folder \"${folder.name}\"`, 'success')\n } catch {\n notify('Failed to delete folder. Please try again.', 'error')\n }\n },\n [confirm, documents, deleteDocuments, onSelectionChange, removePendingFolder, wsId, notify]\n )\n\n // Deleting a folder deletes every file inside: offered only when the viewer may delete them all.\n const canDeleteFolder = useCallback(\n (folder: ExplorerFolder) =>\n canUpload &&\n collectFolderDocs(documents, folder.path).every((doc) =>\n canDeleteDocument(doc, userId, role)\n ),\n [canUpload, documents, userId, role]\n )\n\n const handleBackgroundClick = useCallback(\n (e: React.MouseEvent) => {\n // The click that ends a marquee keeps its selection.\n if (didMarqueeRef.current) {\n didMarqueeRef.current = false\n return\n }\n if (!(e.target as HTMLElement).closest('[data-testid^=\"explorer-\"]')) clearSelection()\n },\n [clearSelection]\n )\n\n // ---- Moving: drag onto a folder\n\n const moveDocs = useCallback(\n async (ids: string[], folder: string | null) => {\n if (ids.length === 0) return\n try {\n await updateDocument.mutateAsync({\n documents: ids.map((external_id) => ({ external_id, folder })),\n })\n // The moved files left this view: a stale selection must not ride into the next drag.\n clearSelection()\n notify(\n `Moved ${ids.length} item${ids.length === 1 ? '' : 's'} to \"${folder ?? 'Home'}\"`,\n 'success'\n )\n } catch {\n notify('Failed to move. Please try again.', 'error')\n }\n },\n [updateDocument, clearSelection, notify]\n )\n\n // Mouse + touch sensors, not the pointer sensor: its pointer capture swallows the move events on\n // some setups, so the drop target is never found.\n const sensors = useSensors(\n useSensor(MouseSensor, { activationConstraint: { distance: 6 } }),\n useSensor(TouchSensor, { activationConstraint: { delay: 150, tolerance: 8 } })\n )\n\n // The folder under the pointer; else (between tiles, a folder's edge) the one the dragged tile\n // overlaps most, so a drop near a folder still moves the files.\n const collisionDetection = useCallback<CollisionDetection>((args) => {\n const hits = pointerWithin(args)\n return hits.length > 0 ? hits : rectIntersection(args)\n }, [])\n\n const handleDragStart = useCallback(\n (event: DragStartEvent) => {\n const docId = event.active.data.current?.docId as string | undefined\n if (!docId) return\n setActiveDragId(docId)\n if (!selectedIdsRef.current.includes(docId)) {\n onSelectionChange([docId])\n dragIdsRef.current = [docId]\n } else {\n dragIdsRef.current = selectedIdsRef.current\n }\n },\n [onSelectionChange]\n )\n\n const handleDragEnd = useCallback(\n (event: DragEndEvent) => {\n setActiveDragId(null)\n const data = event.over?.data.current as { type?: string; path?: string[] } | undefined\n if (data?.type === 'folder' && data.path) {\n const targetFolder = joinFolderPath(data.path)\n // Files already in the target stay put.\n const moving = dragIdsRef.current.filter((id) => {\n const doc = documents.find((d) => d.external_id === id)\n return doc && (doc.folder ?? null) !== targetFolder\n })\n void moveDocs(moving, targetFolder)\n }\n },\n [documents, moveDocs]\n )\n\n // ---- Drop to upload (OS files)\n\n const handleNativeDragOver = useCallback(\n (e: React.DragEvent) => {\n if (!canUpload) return\n if (e.dataTransfer.types.includes('Files')) {\n e.preventDefault()\n e.dataTransfer.dropEffect = 'copy'\n }\n },\n [canUpload]\n )\n\n const handleNativeDragEnter = useCallback(\n (e: React.DragEvent) => {\n if (!canUpload || !e.dataTransfer.types.includes('Files')) return\n fileDragDepth.current += 1\n setIsFileDragOver(true)\n },\n [canUpload]\n )\n\n const handleNativeDragLeave = useCallback(() => {\n fileDragDepth.current = Math.max(0, fileDragDepth.current - 1)\n if (fileDragDepth.current === 0) setIsFileDragOver(false)\n }, [])\n\n const handleNativeDrop = useCallback(\n (e: React.DragEvent) => {\n fileDragDepth.current = 0\n setIsFileDragOver(false)\n if (!canUpload) return\n const dropped = Array.from(e.dataTransfer.files ?? [])\n if (dropped.length > 0) {\n e.preventDefault()\n onUploadFiles(dropped, joinFolderPath(currentPath))\n }\n },\n [canUpload, currentPath, onUploadFiles]\n )\n\n // ---- Render\n\n const activeDoc = activeDragId ? documents.find((d) => d.external_id === activeDragId) : null\n const dragCount = dragIdsRef.current.length || 1\n\n if (isWholeWorkspaceEmpty) return <>{emptyWorkspace}</>\n\n return (\n <DndContext\n sensors={sensors}\n collisionDetection={collisionDetection}\n onDragStart={handleDragStart}\n onDragEnd={handleDragEnd}\n onDragCancel={() => setActiveDragId(null)}\n >\n <ExplorerFrame data-testid=\"documents-explorer\">\n <ExplorerStage>\n <ExplorerScroller\n ref={scrollRef}\n onClick={handleBackgroundClick}\n onPointerDown={handleScrollPointerDown}\n onDragEnter={handleNativeDragEnter}\n onDragOver={handleNativeDragOver}\n onDragLeave={handleNativeDragLeave}\n onDrop={handleNativeDrop}\n data-testid=\"explorer-scroll\"\n >\n {isLoading && documents.length === 0 ? (\n <ExplorerLoadingTiles />\n ) : entries.length === 0 ? (\n <ExplorerEmpty\n title={isSearching ? `No files match \"${search.trim()}\"` : 'This folder is empty'}\n description={\n isSearching\n ? 'Try a different search.'\n : canUpload\n ? 'Drop files here or use Upload to add documents.'\n : 'No documents here yet.'\n }\n />\n ) : containerWidth === 0 ? (\n // Not measured yet: rendering now would flash one stretched column.\n <ExplorerLoadingTiles />\n ) : (\n <div\n style={{\n height: rowVirtualizer.getTotalSize(),\n position: 'relative',\n width: '100%',\n }}\n >\n {virtualRows.map((virtualRow) => {\n const start = virtualRow.index * columnCount\n const rowEntries = entries.slice(start, start + columnCount)\n return (\n <div\n key={virtualRow.key}\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n height: tileHeight,\n transform: `translateY(${virtualRow.start}px)`,\n display: 'grid',\n gridTemplateColumns: `repeat(${columnCount}, minmax(0, 1fr))`,\n columnGap: GRID_GAP,\n }}\n >\n {rowEntries.map((entry) => {\n if (entry.kind === 'folder') {\n const key = entry.path.join('/')\n return (\n <FolderTile\n key={`folder:${key}`}\n folder={entry}\n density={density}\n editing={editingFolderPath === key}\n selected={folderSelection.get(key)?.all}\n partiallySelected={folderSelection.get(key)?.some}\n documents={folderDocs.get(key) ?? NO_DOCUMENTS}\n onOpen={openFolder}\n onToggleSelect={handleToggleFolder}\n onCommitName={commitFolderName}\n onCancelName={cancelFolderName}\n onStartRename={canUpload ? startFolderRename : undefined}\n onDownload={handleFolderDownload}\n onMove={canUpload ? handleFolderMove : undefined}\n onDelete={canDeleteFolder(entry) ? handleFolderDelete : undefined}\n actions={hostActions}\n />\n )\n }\n const doc = entry.doc\n return (\n <FileTile\n key={doc.external_id}\n doc={doc}\n density={density}\n selected={selectedSet.has(doc.external_id)}\n dragging={activeDragId === doc.external_id}\n dndActive={activeDragId !== null}\n renaming={renamingId === doc.external_id}\n canDelete={canDeleteDocument(doc, userId, role)}\n thumbnailUrl={thumbnailsById.get(doc.external_id)}\n modifiedBy={userById.get(\n doc.updated_by_ext_id ?? doc.created_by_ext_id\n )}\n tagNameById={tagNameById}\n onSelect={handleSelect}\n onToggle={handleToggle}\n onOpen={handleOpenFile}\n onReview={handleOpenInReview}\n onStartRename={startRename}\n onCommitRename={commitRename}\n onCancelRename={cancelRename}\n onDownload={handleDownload}\n onMove={canUpload ? handleMove : undefined}\n onDelete={handleDelete}\n actions={hostActions}\n />\n )\n })}\n </div>\n )\n })}\n </div>\n )}\n </ExplorerScroller>\n\n {/* The marquee: always mounted, drawn by mutating its style during a drag. */}\n <ExplorerMarquee ref={marqueeOverlayRef} data-testid=\"explorer-marquee\" />\n\n {isFileDragOver && (\n <ExplorerDropOverlay\n label={`Drop to upload${\n currentPath.length > 0 ? ` to \"${currentPath[currentPath.length - 1]}\"` : ''\n }`}\n />\n )}\n </ExplorerStage>\n </ExplorerFrame>\n\n <DragOverlay dropAnimation={null}>\n {activeDoc ? <DragPreview doc={activeDoc} count={dragCount} /> : null}\n </DragOverlay>\n </DndContext>\n )\n})\n\n/** The preview under the cursor while files are dragged. */\nfunction DragPreview({ doc, count }: { doc: FileTileDocument; count: number }) {\n const Icon = getFileTypeIcon(doc.file_name, { mime: doc.file_type })\n return (\n <ExplorerDragPreview\n icon={<Icon size={20} />}\n title={getDocumentTitle(doc, doc.file_name ?? 'Untitled')}\n count={count}\n />\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * The workspace's files as a file explorer (OneDrive / Drive style), bound to the session: folders\n * come from each document's `folder` path; renames, moves and deletes are written through\n * `@arbidocs/react`.\n *\n * - Breadcrumb navigation is the host's (`folderPath` / `onFolderPathChange`): it may keep the\n * folder in a filter, the URL or state.\n * - A virtualised tile grid that scales to thousands of documents, sized by `tileSize`.\n * - OS-style selection: click, \u2318/Ctrl-click, shift-range, the hover checkbox and a marquee.\n * - Drag files onto a folder tile to move them; drop OS files on the view to upload.\n *\n * Selection is the host's (`selectedIds` / `onSelectionChange`), so its bulk actions act on it.\n */\n\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react'\nimport {\n DndContext,\n DragOverlay,\n MouseSensor,\n TouchSensor,\n pointerWithin,\n rectIntersection,\n useSensor,\n useSensors,\n type CollisionDetection,\n type DragEndEvent,\n type DragStartEvent,\n} from '@dnd-kit/core'\nimport { useVirtualizer } from '@tanstack/react-virtual'\nimport {\n useDeleteDocuments,\n useDocumentHostActions,\n useDocumentThumbnails,\n useDownloadDocuments,\n useRenameFolder,\n useTags,\n useUpdateDocuments,\n useWorkspaces,\n} from '@arbidocs/react'\nimport { getDocumentTitle, getFileTypeIcon } from '@arbidocs/react/ui'\nimport {\n ExplorerDragPreview,\n ExplorerDropOverlay,\n ExplorerEmpty,\n ExplorerFrame,\n ExplorerMarquee,\n ExplorerScroller,\n ExplorerStage,\n} from '../../../files/ExplorerSurface'\nimport { ExplorerLoadingTiles } from '../../../files/Explorer'\nimport {\n buildExplorerEntries,\n collectFolderDocs,\n getExplorerDisplayName,\n joinFolderPath,\n searchExplorerDocuments,\n type ExplorerEntry,\n type ExplorerFolder,\n type ExplorerSort,\n} from '../../../files/folders'\nimport { canDeleteDocument, type WorkspaceMemberRole } from '../../../files/permissions'\nimport {\n RECENTLY_DELETED_HINT,\n RECENTLY_DELETED_HINT_PLURAL,\n} from '../../../files/recently-deleted'\nimport { useBlocksEnvironment } from '../../../provider/environment'\nimport { useConnectedWorkspace } from '../../ConnectionProvider'\nimport { useConnectedWorkspaceRole } from '../../ConnectedWorkflowsTable'\nimport { useFilesStore, usePendingFolders } from '../store'\nimport {\n FileTile,\n FolderTile,\n type ExplorerDensity,\n type FileTileDocument,\n type FileTileUser,\n} from './FileTiles'\n\n// Both densities are thumbnail grids, differing only in tile size. Row heights include the gap so\n// the virtualiser's estimate matches the rendered slot exactly.\nconst GRID_GAP = 12\n// The scroller's horizontal padding (px-4 each side).\nconst SCROLL_PADDING_X = 32\n// A portrait page (height / width), so cover-page thumbnails read.\nconst PAGE_ASPECT = 1.3\n/** The zoom slider's bounds: the target tile width in px (smaller: more tiles per row). */\nexport const TILE_MIN = 88\nexport const TILE_MAX = 232\nexport const TILE_DEFAULT = 200\n// Narrower tiles use the compact styling.\nconst COMPACT_BELOW = 132\nconst NO_DOCUMENTS: FileTileDocument[] = []\n\nexport interface ConnectedFilesExplorerHandle {\n /** Add a placeholder folder here and start naming it. */\n triggerNewFolder: () => void\n /** Scroll the tile of `docId` into view, when it is displayed. */\n scrollToDocument: (docId: string) => void\n}\n\nexport interface ConnectedFilesExplorerProps {\n documents: FileTileDocument[]\n isLoading: boolean\n /** The viewer may add, rename and move files here. */\n canUpload: boolean\n selectedIds: string[]\n onSelectionChange: (ids: string[]) => void\n onOpenDocument: (docId: string) => void\n onUploadFiles: (files: File[], folder?: string | null) => void\n /** The open folder (empty: the workspace root). */\n folderPath: readonly string[]\n onFolderPathChange: (path: string[]) => void\n /** A search across every folder (absent or empty: the open folder is listed). */\n search?: string\n sort: ExplorerSort\n sortReversed: boolean\n /** The target tile width in px (`TILE_MIN`..`TILE_MAX`). */\n tileSize: number\n /** The ids of the files displayed, in display order (a navigator steps the same list). */\n onOrderedFilesChange?: (docIds: string[]) => void\n /** Move the selected files: the host opens its folder picker. Absent: not offered. */\n onMoveSelected?: () => void\n /** Move a folder with its structure: the host opens its folder picker. */\n onFolderMove?: (folder: ExplorerFolder) => void\n /** Open a document in the host's review view. Absent: not offered. */\n onOpenInReview?: (docId: string) => void\n /** Shown instead of the explorer while the workspace has no documents and the viewer may add. */\n emptyWorkspace?: ReactNode\n}\n\n/** The workspace's name (the download archive is named after it), members and the viewer's role. */\nfunction useFilesWorkspace() {\n const { workspaceId, userId, live } = useConnectedWorkspace()\n const { members, role } = useConnectedWorkspaceRole()\n const { data: workspaces } = useWorkspaces({ enabled: live })\n const workspaceName = workspaces?.find((w) => w.external_id === workspaceId)?.name\n return {\n workspaceId: workspaceId ?? '',\n workspaceName,\n userId,\n role: (role ?? null) as WorkspaceMemberRole | null,\n members,\n }\n}\n\nexport const ConnectedFilesExplorer = forwardRef<\n ConnectedFilesExplorerHandle,\n ConnectedFilesExplorerProps\n>(function ConnectedFilesExplorer(\n {\n documents,\n isLoading,\n canUpload,\n selectedIds,\n onSelectionChange,\n onOrderedFilesChange,\n onOpenDocument,\n onUploadFiles,\n folderPath,\n onFolderPathChange,\n search = '',\n sort,\n sortReversed,\n tileSize,\n onMoveSelected,\n onFolderMove,\n onOpenInReview,\n emptyWorkspace,\n },\n ref\n) {\n const { confirm, notify } = useBlocksEnvironment()\n const currentPath = folderPath as string[]\n const density: ExplorerDensity = tileSize < COMPACT_BELOW ? 'list' : 'grid'\n const [containerWidth, setContainerWidth] = useState(0)\n const [activeDragId, setActiveDragId] = useState<string | null>(null)\n const [isFileDragOver, setIsFileDragOver] = useState(false)\n const [renamingId, setRenamingId] = useState<string | null>(null)\n\n const scrollRef = useRef<HTMLDivElement | null>(null)\n const anchorRef = useRef<string | null>(null)\n const dragIdsRef = useRef<string[]>([])\n const fileDragDepth = useRef(0)\n // The marquee is drawn by mutating this overlay's style (one paint per frame), so dragging the\n // lasso never re-renders the grid; the selection is computed once, on release.\n const marqueeOverlayRef = useRef<HTMLDivElement | null>(null)\n // The marquee gesture: its origin, whether it adds to the selection, and that selection.\n const marqueeRef = useRef<{ x: number; y: number; additive: boolean; base: string[] } | null>(\n null\n )\n // A background drag crossed the start threshold: the click that follows must not clear.\n const didMarqueeRef = useRef(false)\n\n const updateDocument = useUpdateDocuments()\n const deleteDocuments = useDeleteDocuments()\n const renameFolder = useRenameFolder()\n const { workspaceId: wsId, workspaceName, userId, role, members } = useFilesWorkspace()\n const { downloadDocuments, downloadDocument } = useDownloadDocuments({ workspaceName })\n const { data: workspaceTags } = useTags()\n const hostActions = useDocumentHostActions()\n\n // Member and label lookups for the hover card, memoised so they keep the tiles memoised.\n const userById = useMemo(() => {\n const map = new Map<string, FileTileUser>()\n for (const member of members) map.set(member.user.external_id, member.user)\n return map\n }, [members])\n const tagNameById = useMemo(() => {\n const map = new Map<string, string>()\n for (const tag of workspaceTags ?? []) map.set(tag.external_id, tag.name)\n return map\n }, [workspaceTags])\n\n // Placeholder (empty) folders of this workspace.\n const pendingFolders = usePendingFolders(wsId)\n const addPendingFolder = useFilesStore((state) => state.addPendingFolder)\n const removePendingFolder = useFilesStore((state) => state.removePendingFolder)\n // The placeholder folder being named inline (its full path).\n const [editingFolderPath, setEditingFolderPath] = useState<string | null>(null)\n\n const isSearching = search.trim().length > 0\n\n // The selection for handlers that run outside the render that produced it (drag, keys).\n const selectedSet = useMemo(() => new Set(selectedIds), [selectedIds])\n const selectedIdsRef = useRef(selectedIds)\n selectedIdsRef.current = selectedIds\n\n // The open folder's entries, or a flat search result.\n const { folders, files } = useMemo(() => {\n const result = isSearching\n ? {\n folders: [] as ExplorerFolder[],\n files: searchExplorerDocuments(documents, search, sort),\n }\n : buildExplorerEntries(documents, currentPath, sort, [...pendingFolders])\n if (sortReversed) result.files = [...result.files].reverse()\n return result\n }, [documents, currentPath, sort, isSearching, search, sortReversed, pendingFolders])\n\n const entries: ExplorerEntry<FileTileDocument>[] = useMemo(\n () => [...folders, ...files.map((doc) => ({ kind: 'file' as const, doc }))],\n [folders, files]\n )\n const orderedFileIds = useMemo(() => files.map((d) => d.external_id), [files])\n // Each folder's documents (everything beneath it), and whether the selection holds all or some of\n // them: its checkbox and selected styling. Keyed by the joined path.\n const folderDocs = useMemo(() => {\n const map = new Map<string, FileTileDocument[]>()\n for (const f of folders) map.set(f.path.join('/'), collectFolderDocs(documents, f.path))\n return map\n }, [folders, documents])\n const folderSelection = useMemo(() => {\n const map = new Map<string, { all: boolean; some: boolean }>()\n for (const [key, docs] of folderDocs) {\n const sel = docs.reduce((n, d) => (selectedSet.has(d.external_id) ? n + 1 : n), 0)\n map.set(key, { all: docs.length > 0 && sel === docs.length, some: sel > 0 })\n }\n return map\n }, [folderDocs, selectedSet])\n\n // Columns from the measured width, each tile a portrait page so the thumbnail is legible.\n const contentWidth = Math.max(0, containerWidth - SCROLL_PADDING_X)\n const columnCount = Math.max(\n 1,\n Math.floor((contentWidth + GRID_GAP) / (tileSize + GRID_GAP)) || 1\n )\n const colWidth =\n contentWidth > 0 ? (contentWidth - (columnCount - 1) * GRID_GAP) / columnCount : tileSize\n const tileHeight = Math.max(120, Math.round(colWidth * PAGE_ASPECT))\n const rowHeight = tileHeight + GRID_GAP\n const rowCount = Math.ceil(entries.length / columnCount)\n\n const rowVirtualizer = useVirtualizer({\n count: rowCount,\n getScrollElement: () => scrollRef.current,\n estimateSize: () => rowHeight,\n overscan: 3,\n })\n\n // The displayed files (on-screen rows plus overscan): the thumbnail loader fetches only these.\n const virtualRows = rowVirtualizer.getVirtualItems()\n const firstRow = virtualRows.length > 0 ? virtualRows[0].index : 0\n const lastRow = virtualRows.length > 0 ? virtualRows[virtualRows.length - 1].index : -1\n const visibleFileIds = useMemo(() => {\n const ids: string[] = []\n for (let r = firstRow; r <= lastRow; r++) {\n const start = r * columnCount\n for (let c = 0; c < columnCount; c++) {\n const entry = entries[start + c]\n if (entry?.kind === 'file') ids.push(entry.doc.external_id)\n }\n }\n return ids\n }, [firstRow, lastRow, columnCount, entries])\n const thumbnailsById = useDocumentThumbnails(visibleFileIds)\n\n useEffect(() => {\n rowVirtualizer.measure()\n }, [rowVirtualizer, columnCount, rowHeight, entries.length])\n\n // The empty workspace shows the host's dropzone instead of the scroller, so the first upload\n // mounts the scroller fresh: the width measurement re-runs on this flag (else the grid stays on\n // the loading tiles until a reload).\n const isWholeWorkspaceEmpty =\n !isLoading && documents.length === 0 && canUpload && emptyWorkspace !== undefined\n\n // The width is measured before paint (a first frame at width 0 would flash one stretched column)\n // and rounded and deduplicated, so sub-pixel resize noise does not re-run the tile maths.\n useLayoutEffect(() => {\n const el = scrollRef.current\n if (!el) return\n const apply = () => {\n const next = Math.round(el.clientWidth)\n setContainerWidth((prev) => (prev === next ? prev : next))\n }\n apply()\n const ro = new ResizeObserver(apply)\n ro.observe(el)\n return () => ro.disconnect()\n }, [isWholeWorkspaceEmpty])\n\n // A new listing scrolls to the top and drops the range anchor.\n useEffect(() => {\n anchorRef.current = null\n if (scrollRef.current) scrollRef.current.scrollTop = 0\n }, [currentPath, search])\n\n // ---- Marquee selection: a drag from empty space selects, on release, every tile it touches;\n // \u2318/Ctrl/Shift at the start adds to the selection. Clamped to the scroller.\n useEffect(() => {\n const MARQUEE_THRESHOLD = 5\n let rafId = 0\n let cur: { left: number; top: number; right: number; bottom: number } | null = null\n\n const paint = () => {\n rafId = 0\n const el = marqueeOverlayRef.current\n if (!el || !cur) return\n el.style.display = 'block'\n el.style.left = `${cur.left}px`\n el.style.top = `${cur.top}px`\n el.style.width = `${cur.right - cur.left}px`\n el.style.height = `${cur.bottom - cur.top}px`\n }\n\n const onMove = (e: PointerEvent) => {\n const m = marqueeRef.current\n if (!m) return\n if (\n !didMarqueeRef.current &&\n Math.hypot(e.clientX - m.x, e.clientY - m.y) < MARQUEE_THRESHOLD\n )\n return\n didMarqueeRef.current = true\n const b = scrollRef.current?.getBoundingClientRect()\n const px = b ? Math.max(b.left, Math.min(e.clientX, b.right)) : e.clientX\n const py = b ? Math.max(b.top, Math.min(e.clientY, b.bottom)) : e.clientY\n cur = {\n left: Math.min(m.x, px),\n top: Math.min(m.y, py),\n right: Math.max(m.x, px),\n bottom: Math.max(m.y, py),\n }\n if (!rafId) rafId = requestAnimationFrame(paint)\n }\n\n const onUp = () => {\n const m = marqueeRef.current\n if (!m) return\n marqueeRef.current = null\n if (rafId) cancelAnimationFrame(rafId)\n rafId = 0\n const el = marqueeOverlayRef.current\n if (el) el.style.display = 'none'\n if (!didMarqueeRef.current || !cur) return\n const box = cur\n const hit: string[] = []\n scrollRef.current?.querySelectorAll('[data-doc-id]').forEach((node) => {\n const r = node.getBoundingClientRect()\n if (r.left < box.right && r.right > box.left && r.top < box.bottom && r.bottom > box.top) {\n const id = node.getAttribute('data-doc-id')\n if (id) hit.push(id)\n }\n })\n onSelectionChange(m.additive ? Array.from(new Set([...m.base, ...hit])) : hit)\n }\n\n window.addEventListener('pointermove', onMove)\n window.addEventListener('pointerup', onUp)\n return () => {\n window.removeEventListener('pointermove', onMove)\n window.removeEventListener('pointerup', onUp)\n if (rafId) cancelAnimationFrame(rafId)\n }\n }, [onSelectionChange])\n\n const handleScrollPointerDown = useCallback((e: React.PointerEvent) => {\n if (e.button !== 0) return\n const el = e.target as HTMLElement\n if (\n el.closest(\n '[data-testid=\"explorer-file\"],[data-testid=\"explorer-folder\"],button,input,select,a,[role=\"button\"]'\n )\n ) {\n return\n }\n const additive = e.shiftKey || e.metaKey || e.ctrlKey\n marqueeRef.current = {\n x: e.clientX,\n y: e.clientY,\n additive,\n base: additive ? selectedIdsRef.current : [],\n }\n didMarqueeRef.current = false\n }, [])\n\n // ---- Navigation\n\n const openFolder = useCallback(\n (folder: ExplorerFolder) => onFolderPathChange(folder.path),\n [onFolderPathChange]\n )\n\n // ---- Placeholder (empty) folders\n\n const handleNewFolder = useCallback(() => {\n if (!wsId) return\n const siblings = new Set(folders.map((f) => f.name.toLowerCase()))\n const base = 'New folder'\n let name = base\n let i = 2\n while (siblings.has(name.toLowerCase())) name = `${base} ${i++}`\n const path = joinFolderPath([...currentPath, name])\n if (!path) return\n addPendingFolder(wsId, path)\n setEditingFolderPath(path)\n }, [wsId, folders, currentPath, addPendingFolder])\n\n // Publish the displayed order only when the ids differ: `documents` is a new array on most\n // renders, and handing each new identity to the host's state would loop.\n const lastOrderedRef = useRef<string[]>([])\n useEffect(() => {\n const prev = lastOrderedRef.current\n if (prev.length === orderedFileIds.length && prev.every((id, i) => id === orderedFileIds[i])) {\n return\n }\n lastOrderedRef.current = orderedFileIds\n onOrderedFilesChange?.(orderedFileIds)\n }, [onOrderedFilesChange, orderedFileIds])\n\n const scrollToDocument = useCallback(\n (docId: string) => {\n const index = entries.findIndex((e) => e.kind === 'file' && e.doc.external_id === docId)\n if (index < 0) return\n rowVirtualizer.scrollToIndex(Math.floor(index / columnCount), { align: 'center' })\n },\n [entries, columnCount, rowVirtualizer]\n )\n\n useImperativeHandle(ref, () => ({ triggerNewFolder: handleNewFolder, scrollToDocument }), [\n handleNewFolder,\n scrollToDocument,\n ])\n\n const commitFolderName = useCallback(\n async (folder: ExplorerFolder, rawName: string) => {\n setEditingFolderPath(null)\n const name = rawName.trim()\n if (!wsId || !name || name === folder.name) return\n const siblings = new Set(folders.filter((f) => f !== folder).map((f) => f.name.toLowerCase()))\n if (siblings.has(name.toLowerCase())) {\n notify(`A folder named \"${name}\" already exists here.`, 'error')\n return\n }\n const oldPath = joinFolderPath(folder.path)\n const newPrefix = [...folder.path.slice(0, -1), name]\n const newPath = joinFolderPath(newPrefix)\n\n // Every document beneath the folder moves under the new name, the subtree with it.\n const docs = collectFolderDocs(documents, folder.path)\n try {\n if ((await renameFolder(docs, folder.path, newPrefix)) > 0) {\n notify(`Renamed folder to \"${name}\"`, 'success')\n }\n } catch {\n notify('Failed to rename folder. Please try again.', 'error')\n return\n }\n if (oldPath) removePendingFolder(wsId, oldPath)\n if (docs.length === 0 && newPath) addPendingFolder(wsId, newPath)\n },\n [wsId, folders, documents, renameFolder, notify, addPendingFolder, removePendingFolder]\n )\n\n const cancelFolderName = useCallback(() => setEditingFolderPath(null), [])\n\n // ---- Selection\n\n const clearSelection = useCallback(() => {\n if (selectedIdsRef.current.length > 0) onSelectionChange([])\n anchorRef.current = null\n }, [onSelectionChange])\n\n const handleSelect = useCallback(\n (doc: FileTileDocument, e: React.MouseEvent) => {\n const id = doc.external_id\n // Shift: the range from the anchor, which stays put so further shift-clicks re-extend it.\n if (e.shiftKey) {\n const from = anchorRef.current ?? id\n const a = orderedFileIds.indexOf(from)\n const b = orderedFileIds.indexOf(id)\n if (a !== -1 && b !== -1) {\n anchorRef.current = from\n const [lo, hi] = a < b ? [a, b] : [b, a]\n onSelectionChange(orderedFileIds.slice(lo, hi + 1))\n return\n }\n }\n // \u2318/Ctrl: toggle this file, keeping the rest; it becomes the anchor.\n if (e.metaKey || e.ctrlKey) {\n onSelectionChange(\n selectedSet.has(id) ? selectedIds.filter((s) => s !== id) : [...selectedIds, id]\n )\n anchorRef.current = id\n return\n }\n onSelectionChange([id])\n anchorRef.current = id\n },\n [onSelectionChange, orderedFileIds, selectedIds, selectedSet]\n )\n\n const handleToggle = useCallback(\n (doc: FileTileDocument, e: React.MouseEvent) => {\n e.stopPropagation()\n const id = doc.external_id\n onSelectionChange(\n selectedSet.has(id) ? selectedIds.filter((s) => s !== id) : [...selectedIds, id]\n )\n anchorRef.current = id\n },\n [onSelectionChange, selectedIds, selectedSet]\n )\n\n // A folder toggles every document inside it: a folder is shorthand for \"everything in it\".\n const handleToggleFolder = useCallback(\n (folder: ExplorerFolder, e: React.MouseEvent) => {\n e.stopPropagation()\n const ids = collectFolderDocs(documents, folder.path).map((d) => d.external_id)\n if (ids.length === 0) return\n if (ids.every((id) => selectedSet.has(id))) {\n const remove = new Set(ids)\n onSelectionChange(selectedIds.filter((id) => !remove.has(id)))\n } else {\n onSelectionChange(Array.from(new Set([...selectedIds, ...ids])))\n }\n anchorRef.current = null\n },\n [documents, onSelectionChange, selectedIds, selectedSet]\n )\n\n const handleOpenFile = useCallback(\n (doc: FileTileDocument) => onOpenDocument(doc.external_id),\n [onOpenDocument]\n )\n const handleOpenInReview = useMemo(\n () => (onOpenInReview ? (doc: FileTileDocument) => onOpenInReview(doc.external_id) : undefined),\n [onOpenInReview]\n )\n\n // ---- Rename (inline; the document's title)\n\n const startRename = useCallback((doc: FileTileDocument) => setRenamingId(doc.external_id), [])\n const cancelRename = useCallback(() => setRenamingId(null), [])\n const commitRename = useCallback(\n async (doc: FileTileDocument, name: string) => {\n setRenamingId(null)\n try {\n await updateDocument.mutateAsync({\n documents: [\n { external_id: doc.external_id, doc_metadata: { ...doc.doc_metadata, title: name } },\n ],\n })\n notify(`Renamed to \"${name}\"`, 'success')\n } catch {\n notify('Failed to rename. Please try again.', 'error')\n }\n },\n [updateDocument, notify]\n )\n\n // F2 renames the one selected file.\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== 'F2' || renamingId) return\n const target = e.target as HTMLElement | null\n if (target && /^(input|textarea|select)$/i.test(target.tagName)) return\n if (selectedIdsRef.current.length === 1) setRenamingId(selectedIdsRef.current[0])\n }\n window.addEventListener('keydown', onKey)\n return () => window.removeEventListener('keydown', onKey)\n }, [renamingId])\n\n // ---- A file's menu\n\n const handleDownload = useCallback(\n (doc: FileTileDocument) => void downloadDocument(doc),\n [downloadDocument]\n )\n\n // \"Move to\u2026\" acts on the selection: select just this file first.\n const handleMove = useMemo(\n () =>\n onMoveSelected\n ? (doc: FileTileDocument) => {\n onSelectionChange([doc.external_id])\n onMoveSelected()\n }\n : undefined,\n [onSelectionChange, onMoveSelected]\n )\n\n const handleDelete = useCallback(\n async (doc: FileTileDocument) => {\n const name = getExplorerDisplayName(doc)\n const confirmed = await confirm({\n message: `Delete \"${name}\"? ${RECENTLY_DELETED_HINT}`,\n title: 'Delete file',\n })\n if (!confirmed) return\n try {\n await deleteDocuments.mutateAsync([doc.external_id])\n onSelectionChange(selectedIdsRef.current.filter((id) => id !== doc.external_id))\n notify(`Deleted \"${name}\"`, 'success')\n } catch {\n notify('Failed to delete. Please try again.', 'error')\n }\n },\n [confirm, deleteDocuments, onSelectionChange, notify]\n )\n\n // ---- A folder's menu: each acts on everything the folder holds.\n\n const startFolderRename = useCallback(\n (folder: ExplorerFolder) => setEditingFolderPath(folder.path.join('/')),\n []\n )\n\n const handleFolderDownload = useCallback(\n (folder: ExplorerFolder) => {\n const docs = collectFolderDocs(documents, folder.path)\n if (docs.length > 0) void downloadDocuments(docs)\n },\n [documents, downloadDocuments]\n )\n\n const handleFolderMove = useMemo(() => {\n if (onFolderMove) return onFolderMove\n if (!onMoveSelected) return undefined\n // A flat move (the structure is not kept).\n return (folder: ExplorerFolder) => {\n const ids = collectFolderDocs(documents, folder.path).map((d) => d.external_id)\n if (ids.length === 0) return\n onSelectionChange(ids)\n onMoveSelected()\n }\n }, [documents, onFolderMove, onMoveSelected, onSelectionChange])\n\n const handleFolderDelete = useCallback(\n async (folder: ExplorerFolder) => {\n const docs = collectFolderDocs(documents, folder.path)\n // An empty placeholder: drop it (nothing to delete).\n if (docs.length === 0) {\n const path = joinFolderPath(folder.path)\n if (wsId && path) removePendingFolder(wsId, path)\n return\n }\n const confirmed = await confirm({\n message: `Delete folder \"${folder.name}\" and its ${docs.length} item${docs.length === 1 ? '' : 's'}? ${RECENTLY_DELETED_HINT_PLURAL}`,\n title: 'Delete folder',\n })\n if (!confirmed) return\n try {\n const ids = docs.map((d) => d.external_id)\n await deleteDocuments.mutateAsync(ids)\n const removed = new Set(ids)\n onSelectionChange(selectedIdsRef.current.filter((id) => !removed.has(id)))\n notify(`Deleted folder \"${folder.name}\"`, 'success')\n } catch {\n notify('Failed to delete folder. Please try again.', 'error')\n }\n },\n [confirm, documents, deleteDocuments, onSelectionChange, removePendingFolder, wsId, notify]\n )\n\n // Deleting a folder deletes every file inside: offered only when the viewer may delete them all.\n const canDeleteFolder = useCallback(\n (folder: ExplorerFolder) =>\n canUpload &&\n collectFolderDocs(documents, folder.path).every((doc) =>\n canDeleteDocument(doc, userId, role)\n ),\n [canUpload, documents, userId, role]\n )\n\n const handleBackgroundClick = useCallback(\n (e: React.MouseEvent) => {\n // The click that ends a marquee keeps its selection.\n if (didMarqueeRef.current) {\n didMarqueeRef.current = false\n return\n }\n if (!(e.target as HTMLElement).closest('[data-testid^=\"explorer-\"]')) clearSelection()\n },\n [clearSelection]\n )\n\n // ---- Moving: drag onto a folder\n\n const moveDocs = useCallback(\n async (ids: string[], folder: string | null) => {\n if (ids.length === 0) return\n try {\n await updateDocument.mutateAsync({\n documents: ids.map((external_id) => ({ external_id, folder })),\n })\n // The moved files left this view: a stale selection must not ride into the next drag.\n clearSelection()\n notify(\n `Moved ${ids.length} item${ids.length === 1 ? '' : 's'} to \"${folder ?? 'Home'}\"`,\n 'success'\n )\n } catch {\n notify('Failed to move. Please try again.', 'error')\n }\n },\n [updateDocument, clearSelection, notify]\n )\n\n // Mouse + touch sensors, not the pointer sensor: its pointer capture swallows the move events on\n // some setups, so the drop target is never found.\n const sensors = useSensors(\n useSensor(MouseSensor, { activationConstraint: { distance: 6 } }),\n useSensor(TouchSensor, { activationConstraint: { delay: 150, tolerance: 8 } })\n )\n\n // The folder under the pointer; else (between tiles, a folder's edge) the one the dragged tile\n // overlaps most, so a drop near a folder still moves the files.\n const collisionDetection = useCallback<CollisionDetection>((args) => {\n const hits = pointerWithin(args)\n return hits.length > 0 ? hits : rectIntersection(args)\n }, [])\n\n const handleDragStart = useCallback(\n (event: DragStartEvent) => {\n const docId = event.active.data.current?.docId as string | undefined\n if (!docId) return\n setActiveDragId(docId)\n if (!selectedIdsRef.current.includes(docId)) {\n onSelectionChange([docId])\n dragIdsRef.current = [docId]\n } else {\n dragIdsRef.current = selectedIdsRef.current\n }\n },\n [onSelectionChange]\n )\n\n const handleDragEnd = useCallback(\n (event: DragEndEvent) => {\n setActiveDragId(null)\n const data = event.over?.data.current as { type?: string; path?: string[] } | undefined\n if (data?.type === 'folder' && data.path) {\n const targetFolder = joinFolderPath(data.path)\n // Files already in the target stay put.\n const moving = dragIdsRef.current.filter((id) => {\n const doc = documents.find((d) => d.external_id === id)\n return doc && (doc.folder ?? null) !== targetFolder\n })\n void moveDocs(moving, targetFolder)\n }\n },\n [documents, moveDocs]\n )\n\n // ---- Drop to upload (OS files)\n\n const handleNativeDragOver = useCallback(\n (e: React.DragEvent) => {\n if (!canUpload) return\n if (e.dataTransfer.types.includes('Files')) {\n e.preventDefault()\n e.dataTransfer.dropEffect = 'copy'\n }\n },\n [canUpload]\n )\n\n const handleNativeDragEnter = useCallback(\n (e: React.DragEvent) => {\n if (!canUpload || !e.dataTransfer.types.includes('Files')) return\n fileDragDepth.current += 1\n setIsFileDragOver(true)\n },\n [canUpload]\n )\n\n const handleNativeDragLeave = useCallback(() => {\n fileDragDepth.current = Math.max(0, fileDragDepth.current - 1)\n if (fileDragDepth.current === 0) setIsFileDragOver(false)\n }, [])\n\n const handleNativeDrop = useCallback(\n (e: React.DragEvent) => {\n fileDragDepth.current = 0\n setIsFileDragOver(false)\n if (!canUpload) return\n const dropped = Array.from(e.dataTransfer.files ?? [])\n if (dropped.length > 0) {\n e.preventDefault()\n onUploadFiles(dropped, joinFolderPath(currentPath))\n }\n },\n [canUpload, currentPath, onUploadFiles]\n )\n\n // ---- Render\n\n const activeDoc = activeDragId ? documents.find((d) => d.external_id === activeDragId) : null\n const dragCount = dragIdsRef.current.length || 1\n\n if (isWholeWorkspaceEmpty) return <>{emptyWorkspace}</>\n\n return (\n <DndContext\n sensors={sensors}\n collisionDetection={collisionDetection}\n onDragStart={handleDragStart}\n onDragEnd={handleDragEnd}\n onDragCancel={() => setActiveDragId(null)}\n >\n <ExplorerFrame data-testid=\"documents-explorer\">\n <ExplorerStage>\n <ExplorerScroller\n ref={scrollRef}\n onClick={handleBackgroundClick}\n onPointerDown={handleScrollPointerDown}\n onDragEnter={handleNativeDragEnter}\n onDragOver={handleNativeDragOver}\n onDragLeave={handleNativeDragLeave}\n onDrop={handleNativeDrop}\n data-testid=\"explorer-scroll\"\n >\n {isLoading && documents.length === 0 ? (\n <ExplorerLoadingTiles />\n ) : entries.length === 0 ? (\n <ExplorerEmpty\n title={isSearching ? `No files match \"${search.trim()}\"` : 'This folder is empty'}\n description={\n isSearching\n ? 'Try a different search.'\n : canUpload\n ? 'Drop files here or use Upload to add documents.'\n : 'No documents here yet.'\n }\n />\n ) : containerWidth === 0 ? (\n // Not measured yet: rendering now would flash one stretched column.\n <ExplorerLoadingTiles />\n ) : (\n <div\n style={{\n height: rowVirtualizer.getTotalSize(),\n position: 'relative',\n width: '100%',\n }}\n >\n {virtualRows.map((virtualRow) => {\n const start = virtualRow.index * columnCount\n const rowEntries = entries.slice(start, start + columnCount)\n return (\n <div\n key={virtualRow.key}\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n height: tileHeight,\n transform: `translateY(${virtualRow.start}px)`,\n display: 'grid',\n gridTemplateColumns: `repeat(${columnCount}, minmax(0, 1fr))`,\n columnGap: GRID_GAP,\n }}\n >\n {rowEntries.map((entry) => {\n if (entry.kind === 'folder') {\n const key = entry.path.join('/')\n return (\n <FolderTile\n key={`folder:${key}`}\n folder={entry}\n density={density}\n editing={editingFolderPath === key}\n selected={folderSelection.get(key)?.all}\n partiallySelected={folderSelection.get(key)?.some}\n documents={folderDocs.get(key) ?? NO_DOCUMENTS}\n onOpen={openFolder}\n onToggleSelect={handleToggleFolder}\n onCommitName={commitFolderName}\n onCancelName={cancelFolderName}\n onStartRename={canUpload ? startFolderRename : undefined}\n onDownload={handleFolderDownload}\n onMove={canUpload ? handleFolderMove : undefined}\n onDelete={canDeleteFolder(entry) ? handleFolderDelete : undefined}\n actions={hostActions}\n />\n )\n }\n const doc = entry.doc\n return (\n <FileTile\n key={doc.external_id}\n doc={doc}\n density={density}\n selected={selectedSet.has(doc.external_id)}\n dragging={activeDragId === doc.external_id}\n dndActive={activeDragId !== null}\n renaming={renamingId === doc.external_id}\n canDelete={canDeleteDocument(doc, userId, role)}\n thumbnailUrl={thumbnailsById.get(doc.external_id)}\n modifiedBy={userById.get(\n doc.updated_by_ext_id ?? doc.created_by_ext_id\n )}\n tagNameById={tagNameById}\n onSelect={handleSelect}\n onToggle={handleToggle}\n onOpen={handleOpenFile}\n onReview={handleOpenInReview}\n onStartRename={startRename}\n onCommitRename={commitRename}\n onCancelRename={cancelRename}\n onDownload={handleDownload}\n onMove={canUpload ? handleMove : undefined}\n onDelete={handleDelete}\n actions={hostActions}\n />\n )\n })}\n </div>\n )\n })}\n </div>\n )}\n </ExplorerScroller>\n\n {/* The marquee: always mounted, drawn by mutating its style during a drag. */}\n <ExplorerMarquee ref={marqueeOverlayRef} data-testid=\"explorer-marquee\" />\n\n {isFileDragOver && (\n <ExplorerDropOverlay\n label={`Drop to upload${\n currentPath.length > 0 ? ` to \"${currentPath[currentPath.length - 1]}\"` : ''\n }`}\n />\n )}\n </ExplorerStage>\n </ExplorerFrame>\n\n <DragOverlay dropAnimation={null}>\n {activeDoc ? <DragPreview doc={activeDoc} count={dragCount} /> : null}\n </DragOverlay>\n </DndContext>\n )\n})\n\n/** The preview under the cursor while files are dragged. */\nfunction DragPreview({ doc, count }: { doc: FileTileDocument; count: number }) {\n const Icon = getFileTypeIcon(doc.file_name, { mime: doc.file_type, folder: doc.folder })\n return (\n <ExplorerDragPreview\n icon={<Icon size={20} />}\n title={getDocumentTitle(doc, doc.file_name ?? 'Untitled')}\n count={count}\n />\n )\n}\n"],
5
+ "mappings": ";AAw0BoC,wBAW5B,YAX4B;AA1zBpC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AACP,SAAS,sBAAsB;AAC/B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB,uBAAuB;AAClD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,4BAA4B;AACrC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AACP,SAAS,yBAAmD;AAC5D;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,4BAA4B;AACrC,SAAS,6BAA6B;AACtC,SAAS,iCAAiC;AAC1C,SAAS,eAAe,yBAAyB;AACjD;AAAA,EACE;AAAA,EACA;AAAA,OAIK;AAIP,MAAM,WAAW;AAEjB,MAAM,mBAAmB;AAEzB,MAAM,cAAc;AAEb,MAAM,WAAW;AACjB,MAAM,WAAW;AACjB,MAAM,eAAe;AAE5B,MAAM,gBAAgB;AACtB,MAAM,eAAmC,CAAC;AAwC1C,SAAS,oBAAoB;AAC3B,QAAM,EAAE,aAAa,QAAQ,KAAK,IAAI,sBAAsB;AAC5D,QAAM,EAAE,SAAS,KAAK,IAAI,0BAA0B;AACpD,QAAM,EAAE,MAAM,WAAW,IAAI,cAAc,EAAE,SAAS,KAAK,CAAC;AAC5D,QAAM,gBAAgB,YAAY,KAAK,CAAC,MAAM,EAAE,gBAAgB,WAAW,GAAG;AAC9E,SAAO;AAAA,IACL,aAAa,eAAe;AAAA,IAC5B;AAAA,IACA;AAAA,IACA,MAAO,QAAQ;AAAA,IACf;AAAA,EACF;AACF;AAEO,MAAM,yBAAyB,WAGpC,SAASA,wBACT;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GACA,KACA;AACA,QAAM,EAAE,SAAS,OAAO,IAAI,qBAAqB;AACjD,QAAM,cAAc;AACpB,QAAM,UAA2B,WAAW,gBAAgB,SAAS;AACrE,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAAS,CAAC;AACtD,QAAM,CAAC,cAAc,eAAe,IAAI,SAAwB,IAAI;AACpE,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAAS,KAAK;AAC1D,QAAM,CAAC,YAAY,aAAa,IAAI,SAAwB,IAAI;AAEhE,QAAM,YAAY,OAA8B,IAAI;AACpD,QAAM,YAAY,OAAsB,IAAI;AAC5C,QAAM,aAAa,OAAiB,CAAC,CAAC;AACtC,QAAM,gBAAgB,OAAO,CAAC;AAG9B,QAAM,oBAAoB,OAA8B,IAAI;AAE5D,QAAM,aAAa;AAAA,IACjB;AAAA,EACF;AAEA,QAAM,gBAAgB,OAAO,KAAK;AAElC,QAAM,iBAAiB,mBAAmB;AAC1C,QAAM,kBAAkB,mBAAmB;AAC3C,QAAM,eAAe,gBAAgB;AACrC,QAAM,EAAE,aAAa,MAAM,eAAe,QAAQ,MAAM,QAAQ,IAAI,kBAAkB;AACtF,QAAM,EAAE,mBAAmB,iBAAiB,IAAI,qBAAqB,EAAE,cAAc,CAAC;AACtF,QAAM,EAAE,MAAM,cAAc,IAAI,QAAQ;AACxC,QAAM,cAAc,uBAAuB;AAG3C,QAAM,WAAW,QAAQ,MAAM;AAC7B,UAAM,MAAM,oBAAI,IAA0B;AAC1C,eAAW,UAAU,QAAS,KAAI,IAAI,OAAO,KAAK,aAAa,OAAO,IAAI;AAC1E,WAAO;AAAA,EACT,GAAG,CAAC,OAAO,CAAC;AACZ,QAAM,cAAc,QAAQ,MAAM;AAChC,UAAM,MAAM,oBAAI,IAAoB;AACpC,eAAW,OAAO,iBAAiB,CAAC,EAAG,KAAI,IAAI,IAAI,aAAa,IAAI,IAAI;AACxE,WAAO;AAAA,EACT,GAAG,CAAC,aAAa,CAAC;AAGlB,QAAM,iBAAiB,kBAAkB,IAAI;AAC7C,QAAM,mBAAmB,cAAc,CAAC,UAAU,MAAM,gBAAgB;AACxE,QAAM,sBAAsB,cAAc,CAAC,UAAU,MAAM,mBAAmB;AAE9E,QAAM,CAAC,mBAAmB,oBAAoB,IAAI,SAAwB,IAAI;AAE9E,QAAM,cAAc,OAAO,KAAK,EAAE,SAAS;AAG3C,QAAM,cAAc,QAAQ,MAAM,IAAI,IAAI,WAAW,GAAG,CAAC,WAAW,CAAC;AACrE,QAAM,iBAAiB,OAAO,WAAW;AACzC,iBAAe,UAAU;AAGzB,QAAM,EAAE,SAAS,MAAM,IAAI,QAAQ,MAAM;AACvC,UAAM,SAAS,cACX;AAAA,MACE,SAAS,CAAC;AAAA,MACV,OAAO,wBAAwB,WAAW,QAAQ,IAAI;AAAA,IACxD,IACA,qBAAqB,WAAW,aAAa,MAAM,CAAC,GAAG,cAAc,CAAC;AAC1E,QAAI,aAAc,QAAO,QAAQ,CAAC,GAAG,OAAO,KAAK,EAAE,QAAQ;AAC3D,WAAO;AAAA,EACT,GAAG,CAAC,WAAW,aAAa,MAAM,aAAa,QAAQ,cAAc,cAAc,CAAC;AAEpF,QAAM,UAA6C;AAAA,IACjD,MAAM,CAAC,GAAG,SAAS,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,MAAM,QAAiB,IAAI,EAAE,CAAC;AAAA,IAC1E,CAAC,SAAS,KAAK;AAAA,EACjB;AACA,QAAM,iBAAiB,QAAQ,MAAM,MAAM,IAAI,CAAC,MAAM,EAAE,WAAW,GAAG,CAAC,KAAK,CAAC;AAG7E,QAAM,aAAa,QAAQ,MAAM;AAC/B,UAAM,MAAM,oBAAI,IAAgC;AAChD,eAAW,KAAK,QAAS,KAAI,IAAI,EAAE,KAAK,KAAK,GAAG,GAAG,kBAAkB,WAAW,EAAE,IAAI,CAAC;AACvF,WAAO;AAAA,EACT,GAAG,CAAC,SAAS,SAAS,CAAC;AACvB,QAAM,kBAAkB,QAAQ,MAAM;AACpC,UAAM,MAAM,oBAAI,IAA6C;AAC7D,eAAW,CAAC,KAAK,IAAI,KAAK,YAAY;AACpC,YAAM,MAAM,KAAK,OAAO,CAAC,GAAG,MAAO,YAAY,IAAI,EAAE,WAAW,IAAI,IAAI,IAAI,GAAI,CAAC;AACjF,UAAI,IAAI,KAAK,EAAE,KAAK,KAAK,SAAS,KAAK,QAAQ,KAAK,QAAQ,MAAM,MAAM,EAAE,CAAC;AAAA,IAC7E;AACA,WAAO;AAAA,EACT,GAAG,CAAC,YAAY,WAAW,CAAC;AAG5B,QAAM,eAAe,KAAK,IAAI,GAAG,iBAAiB,gBAAgB;AAClE,QAAM,cAAc,KAAK;AAAA,IACvB;AAAA,IACA,KAAK,OAAO,eAAe,aAAa,WAAW,SAAS,KAAK;AAAA,EACnE;AACA,QAAM,WACJ,eAAe,KAAK,gBAAgB,cAAc,KAAK,YAAY,cAAc;AACnF,QAAM,aAAa,KAAK,IAAI,KAAK,KAAK,MAAM,WAAW,WAAW,CAAC;AACnE,QAAM,YAAY,aAAa;AAC/B,QAAM,WAAW,KAAK,KAAK,QAAQ,SAAS,WAAW;AAEvD,QAAM,iBAAiB,eAAe;AAAA,IACpC,OAAO;AAAA,IACP,kBAAkB,MAAM,UAAU;AAAA,IAClC,cAAc,MAAM;AAAA,IACpB,UAAU;AAAA,EACZ,CAAC;AAGD,QAAM,cAAc,eAAe,gBAAgB;AACnD,QAAM,WAAW,YAAY,SAAS,IAAI,YAAY,CAAC,EAAE,QAAQ;AACjE,QAAM,UAAU,YAAY,SAAS,IAAI,YAAY,YAAY,SAAS,CAAC,EAAE,QAAQ;AACrF,QAAM,iBAAiB,QAAQ,MAAM;AACnC,UAAM,MAAgB,CAAC;AACvB,aAAS,IAAI,UAAU,KAAK,SAAS,KAAK;AACxC,YAAM,QAAQ,IAAI;AAClB,eAAS,IAAI,GAAG,IAAI,aAAa,KAAK;AACpC,cAAM,QAAQ,QAAQ,QAAQ,CAAC;AAC/B,YAAI,OAAO,SAAS,OAAQ,KAAI,KAAK,MAAM,IAAI,WAAW;AAAA,MAC5D;AAAA,IACF;AACA,WAAO;AAAA,EACT,GAAG,CAAC,UAAU,SAAS,aAAa,OAAO,CAAC;AAC5C,QAAM,iBAAiB,sBAAsB,cAAc;AAE3D,YAAU,MAAM;AACd,mBAAe,QAAQ;AAAA,EACzB,GAAG,CAAC,gBAAgB,aAAa,WAAW,QAAQ,MAAM,CAAC;AAK3D,QAAM,wBACJ,CAAC,aAAa,UAAU,WAAW,KAAK,aAAa,mBAAmB;AAI1E,kBAAgB,MAAM;AACpB,UAAM,KAAK,UAAU;AACrB,QAAI,CAAC,GAAI;AACT,UAAM,QAAQ,MAAM;AAClB,YAAM,OAAO,KAAK,MAAM,GAAG,WAAW;AACtC,wBAAkB,CAAC,SAAU,SAAS,OAAO,OAAO,IAAK;AAAA,IAC3D;AACA,UAAM;AACN,UAAM,KAAK,IAAI,eAAe,KAAK;AACnC,OAAG,QAAQ,EAAE;AACb,WAAO,MAAM,GAAG,WAAW;AAAA,EAC7B,GAAG,CAAC,qBAAqB,CAAC;AAG1B,YAAU,MAAM;AACd,cAAU,UAAU;AACpB,QAAI,UAAU,QAAS,WAAU,QAAQ,YAAY;AAAA,EACvD,GAAG,CAAC,aAAa,MAAM,CAAC;AAIxB,YAAU,MAAM;AACd,UAAM,oBAAoB;AAC1B,QAAI,QAAQ;AACZ,QAAI,MAA2E;AAE/E,UAAM,QAAQ,MAAM;AAClB,cAAQ;AACR,YAAM,KAAK,kBAAkB;AAC7B,UAAI,CAAC,MAAM,CAAC,IAAK;AACjB,SAAG,MAAM,UAAU;AACnB,SAAG,MAAM,OAAO,GAAG,IAAI,IAAI;AAC3B,SAAG,MAAM,MAAM,GAAG,IAAI,GAAG;AACzB,SAAG,MAAM,QAAQ,GAAG,IAAI,QAAQ,IAAI,IAAI;AACxC,SAAG,MAAM,SAAS,GAAG,IAAI,SAAS,IAAI,GAAG;AAAA,IAC3C;AAEA,UAAM,SAAS,CAAC,MAAoB;AAClC,YAAM,IAAI,WAAW;AACrB,UAAI,CAAC,EAAG;AACR,UACE,CAAC,cAAc,WACf,KAAK,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,IAAI;AAE/C;AACF,oBAAc,UAAU;AACxB,YAAM,IAAI,UAAU,SAAS,sBAAsB;AACnD,YAAM,KAAK,IAAI,KAAK,IAAI,EAAE,MAAM,KAAK,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,IAAI,EAAE;AAClE,YAAM,KAAK,IAAI,KAAK,IAAI,EAAE,KAAK,KAAK,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,IAAI,EAAE;AAClE,YAAM;AAAA,QACJ,MAAM,KAAK,IAAI,EAAE,GAAG,EAAE;AAAA,QACtB,KAAK,KAAK,IAAI,EAAE,GAAG,EAAE;AAAA,QACrB,OAAO,KAAK,IAAI,EAAE,GAAG,EAAE;AAAA,QACvB,QAAQ,KAAK,IAAI,EAAE,GAAG,EAAE;AAAA,MAC1B;AACA,UAAI,CAAC,MAAO,SAAQ,sBAAsB,KAAK;AAAA,IACjD;AAEA,UAAM,OAAO,MAAM;AACjB,YAAM,IAAI,WAAW;AACrB,UAAI,CAAC,EAAG;AACR,iBAAW,UAAU;AACrB,UAAI,MAAO,sBAAqB,KAAK;AACrC,cAAQ;AACR,YAAM,KAAK,kBAAkB;AAC7B,UAAI,GAAI,IAAG,MAAM,UAAU;AAC3B,UAAI,CAAC,cAAc,WAAW,CAAC,IAAK;AACpC,YAAM,MAAM;AACZ,YAAM,MAAgB,CAAC;AACvB,gBAAU,SAAS,iBAAiB,eAAe,EAAE,QAAQ,CAAC,SAAS;AACrE,cAAM,IAAI,KAAK,sBAAsB;AACrC,YAAI,EAAE,OAAO,IAAI,SAAS,EAAE,QAAQ,IAAI,QAAQ,EAAE,MAAM,IAAI,UAAU,EAAE,SAAS,IAAI,KAAK;AACxF,gBAAM,KAAK,KAAK,aAAa,aAAa;AAC1C,cAAI,GAAI,KAAI,KAAK,EAAE;AAAA,QACrB;AAAA,MACF,CAAC;AACD,wBAAkB,EAAE,WAAW,MAAM,KAAK,oBAAI,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,CAAC,IAAI,GAAG;AAAA,IAC/E;AAEA,WAAO,iBAAiB,eAAe,MAAM;AAC7C,WAAO,iBAAiB,aAAa,IAAI;AACzC,WAAO,MAAM;AACX,aAAO,oBAAoB,eAAe,MAAM;AAChD,aAAO,oBAAoB,aAAa,IAAI;AAC5C,UAAI,MAAO,sBAAqB,KAAK;AAAA,IACvC;AAAA,EACF,GAAG,CAAC,iBAAiB,CAAC;AAEtB,QAAM,0BAA0B,YAAY,CAAC,MAA0B;AACrE,QAAI,EAAE,WAAW,EAAG;AACpB,UAAM,KAAK,EAAE;AACb,QACE,GAAG;AAAA,MACD;AAAA,IACF,GACA;AACA;AAAA,IACF;AACA,UAAM,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE;AAC9C,eAAW,UAAU;AAAA,MACnB,GAAG,EAAE;AAAA,MACL,GAAG,EAAE;AAAA,MACL;AAAA,MACA,MAAM,WAAW,eAAe,UAAU,CAAC;AAAA,IAC7C;AACA,kBAAc,UAAU;AAAA,EAC1B,GAAG,CAAC,CAAC;AAIL,QAAM,aAAa;AAAA,IACjB,CAAC,WAA2B,mBAAmB,OAAO,IAAI;AAAA,IAC1D,CAAC,kBAAkB;AAAA,EACrB;AAIA,QAAM,kBAAkB,YAAY,MAAM;AACxC,QAAI,CAAC,KAAM;AACX,UAAM,WAAW,IAAI,IAAI,QAAQ,IAAI,CAAC,MAAM,EAAE,KAAK,YAAY,CAAC,CAAC;AACjE,UAAM,OAAO;AACb,QAAI,OAAO;AACX,QAAI,IAAI;AACR,WAAO,SAAS,IAAI,KAAK,YAAY,CAAC,EAAG,QAAO,GAAG,IAAI,IAAI,GAAG;AAC9D,UAAM,OAAO,eAAe,CAAC,GAAG,aAAa,IAAI,CAAC;AAClD,QAAI,CAAC,KAAM;AACX,qBAAiB,MAAM,IAAI;AAC3B,yBAAqB,IAAI;AAAA,EAC3B,GAAG,CAAC,MAAM,SAAS,aAAa,gBAAgB,CAAC;AAIjD,QAAM,iBAAiB,OAAiB,CAAC,CAAC;AAC1C,YAAU,MAAM;AACd,UAAM,OAAO,eAAe;AAC5B,QAAI,KAAK,WAAW,eAAe,UAAU,KAAK,MAAM,CAAC,IAAI,MAAM,OAAO,eAAe,CAAC,CAAC,GAAG;AAC5F;AAAA,IACF;AACA,mBAAe,UAAU;AACzB,2BAAuB,cAAc;AAAA,EACvC,GAAG,CAAC,sBAAsB,cAAc,CAAC;AAEzC,QAAM,mBAAmB;AAAA,IACvB,CAAC,UAAkB;AACjB,YAAM,QAAQ,QAAQ,UAAU,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,IAAI,gBAAgB,KAAK;AACvF,UAAI,QAAQ,EAAG;AACf,qBAAe,cAAc,KAAK,MAAM,QAAQ,WAAW,GAAG,EAAE,OAAO,SAAS,CAAC;AAAA,IACnF;AAAA,IACA,CAAC,SAAS,aAAa,cAAc;AAAA,EACvC;AAEA,sBAAoB,KAAK,OAAO,EAAE,kBAAkB,iBAAiB,iBAAiB,IAAI;AAAA,IACxF;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,mBAAmB;AAAA,IACvB,OAAO,QAAwB,YAAoB;AACjD,2BAAqB,IAAI;AACzB,YAAM,OAAO,QAAQ,KAAK;AAC1B,UAAI,CAAC,QAAQ,CAAC,QAAQ,SAAS,OAAO,KAAM;AAC5C,YAAM,WAAW,IAAI,IAAI,QAAQ,OAAO,CAAC,MAAM,MAAM,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,YAAY,CAAC,CAAC;AAC7F,UAAI,SAAS,IAAI,KAAK,YAAY,CAAC,GAAG;AACpC,eAAO,mBAAmB,IAAI,0BAA0B,OAAO;AAC/D;AAAA,MACF;AACA,YAAM,UAAU,eAAe,OAAO,IAAI;AAC1C,YAAM,YAAY,CAAC,GAAG,OAAO,KAAK,MAAM,GAAG,EAAE,GAAG,IAAI;AACpD,YAAM,UAAU,eAAe,SAAS;AAGxC,YAAM,OAAO,kBAAkB,WAAW,OAAO,IAAI;AACrD,UAAI;AACF,YAAK,MAAM,aAAa,MAAM,OAAO,MAAM,SAAS,IAAK,GAAG;AAC1D,iBAAO,sBAAsB,IAAI,KAAK,SAAS;AAAA,QACjD;AAAA,MACF,QAAQ;AACN,eAAO,8CAA8C,OAAO;AAC5D;AAAA,MACF;AACA,UAAI,QAAS,qBAAoB,MAAM,OAAO;AAC9C,UAAI,KAAK,WAAW,KAAK,QAAS,kBAAiB,MAAM,OAAO;AAAA,IAClE;AAAA,IACA,CAAC,MAAM,SAAS,WAAW,cAAc,QAAQ,kBAAkB,mBAAmB;AAAA,EACxF;AAEA,QAAM,mBAAmB,YAAY,MAAM,qBAAqB,IAAI,GAAG,CAAC,CAAC;AAIzE,QAAM,iBAAiB,YAAY,MAAM;AACvC,QAAI,eAAe,QAAQ,SAAS,EAAG,mBAAkB,CAAC,CAAC;AAC3D,cAAU,UAAU;AAAA,EACtB,GAAG,CAAC,iBAAiB,CAAC;AAEtB,QAAM,eAAe;AAAA,IACnB,CAAC,KAAuB,MAAwB;AAC9C,YAAM,KAAK,IAAI;AAEf,UAAI,EAAE,UAAU;AACd,cAAM,OAAO,UAAU,WAAW;AAClC,cAAM,IAAI,eAAe,QAAQ,IAAI;AACrC,cAAM,IAAI,eAAe,QAAQ,EAAE;AACnC,YAAI,MAAM,MAAM,MAAM,IAAI;AACxB,oBAAU,UAAU;AACpB,gBAAM,CAAC,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;AACvC,4BAAkB,eAAe,MAAM,IAAI,KAAK,CAAC,CAAC;AAClD;AAAA,QACF;AAAA,MACF;AAEA,UAAI,EAAE,WAAW,EAAE,SAAS;AAC1B;AAAA,UACE,YAAY,IAAI,EAAE,IAAI,YAAY,OAAO,CAAC,MAAM,MAAM,EAAE,IAAI,CAAC,GAAG,aAAa,EAAE;AAAA,QACjF;AACA,kBAAU,UAAU;AACpB;AAAA,MACF;AACA,wBAAkB,CAAC,EAAE,CAAC;AACtB,gBAAU,UAAU;AAAA,IACtB;AAAA,IACA,CAAC,mBAAmB,gBAAgB,aAAa,WAAW;AAAA,EAC9D;AAEA,QAAM,eAAe;AAAA,IACnB,CAAC,KAAuB,MAAwB;AAC9C,QAAE,gBAAgB;AAClB,YAAM,KAAK,IAAI;AACf;AAAA,QACE,YAAY,IAAI,EAAE,IAAI,YAAY,OAAO,CAAC,MAAM,MAAM,EAAE,IAAI,CAAC,GAAG,aAAa,EAAE;AAAA,MACjF;AACA,gBAAU,UAAU;AAAA,IACtB;AAAA,IACA,CAAC,mBAAmB,aAAa,WAAW;AAAA,EAC9C;AAGA,QAAM,qBAAqB;AAAA,IACzB,CAAC,QAAwB,MAAwB;AAC/C,QAAE,gBAAgB;AAClB,YAAM,MAAM,kBAAkB,WAAW,OAAO,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,WAAW;AAC9E,UAAI,IAAI,WAAW,EAAG;AACtB,UAAI,IAAI,MAAM,CAAC,OAAO,YAAY,IAAI,EAAE,CAAC,GAAG;AAC1C,cAAM,SAAS,IAAI,IAAI,GAAG;AAC1B,0BAAkB,YAAY,OAAO,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;AAAA,MAC/D,OAAO;AACL,0BAAkB,MAAM,KAAK,oBAAI,IAAI,CAAC,GAAG,aAAa,GAAG,GAAG,CAAC,CAAC,CAAC;AAAA,MACjE;AACA,gBAAU,UAAU;AAAA,IACtB;AAAA,IACA,CAAC,WAAW,mBAAmB,aAAa,WAAW;AAAA,EACzD;AAEA,QAAM,iBAAiB;AAAA,IACrB,CAAC,QAA0B,eAAe,IAAI,WAAW;AAAA,IACzD,CAAC,cAAc;AAAA,EACjB;AACA,QAAM,qBAAqB;AAAA,IACzB,MAAO,iBAAiB,CAAC,QAA0B,eAAe,IAAI,WAAW,IAAI;AAAA,IACrF,CAAC,cAAc;AAAA,EACjB;AAIA,QAAM,cAAc,YAAY,CAAC,QAA0B,cAAc,IAAI,WAAW,GAAG,CAAC,CAAC;AAC7F,QAAM,eAAe,YAAY,MAAM,cAAc,IAAI,GAAG,CAAC,CAAC;AAC9D,QAAM,eAAe;AAAA,IACnB,OAAO,KAAuB,SAAiB;AAC7C,oBAAc,IAAI;AAClB,UAAI;AACF,cAAM,eAAe,YAAY;AAAA,UAC/B,WAAW;AAAA,YACT,EAAE,aAAa,IAAI,aAAa,cAAc,EAAE,GAAG,IAAI,cAAc,OAAO,KAAK,EAAE;AAAA,UACrF;AAAA,QACF,CAAC;AACD,eAAO,eAAe,IAAI,KAAK,SAAS;AAAA,MAC1C,QAAQ;AACN,eAAO,uCAAuC,OAAO;AAAA,MACvD;AAAA,IACF;AAAA,IACA,CAAC,gBAAgB,MAAM;AAAA,EACzB;AAGA,YAAU,MAAM;AACd,UAAM,QAAQ,CAAC,MAAqB;AAClC,UAAI,EAAE,QAAQ,QAAQ,WAAY;AAClC,YAAM,SAAS,EAAE;AACjB,UAAI,UAAU,6BAA6B,KAAK,OAAO,OAAO,EAAG;AACjE,UAAI,eAAe,QAAQ,WAAW,EAAG,eAAc,eAAe,QAAQ,CAAC,CAAC;AAAA,IAClF;AACA,WAAO,iBAAiB,WAAW,KAAK;AACxC,WAAO,MAAM,OAAO,oBAAoB,WAAW,KAAK;AAAA,EAC1D,GAAG,CAAC,UAAU,CAAC;AAIf,QAAM,iBAAiB;AAAA,IACrB,CAAC,QAA0B,KAAK,iBAAiB,GAAG;AAAA,IACpD,CAAC,gBAAgB;AAAA,EACnB;AAGA,QAAM,aAAa;AAAA,IACjB,MACE,iBACI,CAAC,QAA0B;AACzB,wBAAkB,CAAC,IAAI,WAAW,CAAC;AACnC,qBAAe;AAAA,IACjB,IACA;AAAA,IACN,CAAC,mBAAmB,cAAc;AAAA,EACpC;AAEA,QAAM,eAAe;AAAA,IACnB,OAAO,QAA0B;AAC/B,YAAM,OAAO,uBAAuB,GAAG;AACvC,YAAM,YAAY,MAAM,QAAQ;AAAA,QAC9B,SAAS,WAAW,IAAI,MAAM,qBAAqB;AAAA,QACnD,OAAO;AAAA,MACT,CAAC;AACD,UAAI,CAAC,UAAW;AAChB,UAAI;AACF,cAAM,gBAAgB,YAAY,CAAC,IAAI,WAAW,CAAC;AACnD,0BAAkB,eAAe,QAAQ,OAAO,CAAC,OAAO,OAAO,IAAI,WAAW,CAAC;AAC/E,eAAO,YAAY,IAAI,KAAK,SAAS;AAAA,MACvC,QAAQ;AACN,eAAO,uCAAuC,OAAO;AAAA,MACvD;AAAA,IACF;AAAA,IACA,CAAC,SAAS,iBAAiB,mBAAmB,MAAM;AAAA,EACtD;AAIA,QAAM,oBAAoB;AAAA,IACxB,CAAC,WAA2B,qBAAqB,OAAO,KAAK,KAAK,GAAG,CAAC;AAAA,IACtE,CAAC;AAAA,EACH;AAEA,QAAM,uBAAuB;AAAA,IAC3B,CAAC,WAA2B;AAC1B,YAAM,OAAO,kBAAkB,WAAW,OAAO,IAAI;AACrD,UAAI,KAAK,SAAS,EAAG,MAAK,kBAAkB,IAAI;AAAA,IAClD;AAAA,IACA,CAAC,WAAW,iBAAiB;AAAA,EAC/B;AAEA,QAAM,mBAAmB,QAAQ,MAAM;AACrC,QAAI,aAAc,QAAO;AACzB,QAAI,CAAC,eAAgB,QAAO;AAE5B,WAAO,CAAC,WAA2B;AACjC,YAAM,MAAM,kBAAkB,WAAW,OAAO,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,WAAW;AAC9E,UAAI,IAAI,WAAW,EAAG;AACtB,wBAAkB,GAAG;AACrB,qBAAe;AAAA,IACjB;AAAA,EACF,GAAG,CAAC,WAAW,cAAc,gBAAgB,iBAAiB,CAAC;AAE/D,QAAM,qBAAqB;AAAA,IACzB,OAAO,WAA2B;AAChC,YAAM,OAAO,kBAAkB,WAAW,OAAO,IAAI;AAErD,UAAI,KAAK,WAAW,GAAG;AACrB,cAAM,OAAO,eAAe,OAAO,IAAI;AACvC,YAAI,QAAQ,KAAM,qBAAoB,MAAM,IAAI;AAChD;AAAA,MACF;AACA,YAAM,YAAY,MAAM,QAAQ;AAAA,QAC9B,SAAS,kBAAkB,OAAO,IAAI,aAAa,KAAK,MAAM,QAAQ,KAAK,WAAW,IAAI,KAAK,GAAG,KAAK,4BAA4B;AAAA,QACnI,OAAO;AAAA,MACT,CAAC;AACD,UAAI,CAAC,UAAW;AAChB,UAAI;AACF,cAAM,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,WAAW;AACzC,cAAM,gBAAgB,YAAY,GAAG;AACrC,cAAM,UAAU,IAAI,IAAI,GAAG;AAC3B,0BAAkB,eAAe,QAAQ,OAAO,CAAC,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;AACzE,eAAO,mBAAmB,OAAO,IAAI,KAAK,SAAS;AAAA,MACrD,QAAQ;AACN,eAAO,8CAA8C,OAAO;AAAA,MAC9D;AAAA,IACF;AAAA,IACA,CAAC,SAAS,WAAW,iBAAiB,mBAAmB,qBAAqB,MAAM,MAAM;AAAA,EAC5F;AAGA,QAAM,kBAAkB;AAAA,IACtB,CAAC,WACC,aACA,kBAAkB,WAAW,OAAO,IAAI,EAAE;AAAA,MAAM,CAAC,QAC/C,kBAAkB,KAAK,QAAQ,IAAI;AAAA,IACrC;AAAA,IACF,CAAC,WAAW,WAAW,QAAQ,IAAI;AAAA,EACrC;AAEA,QAAM,wBAAwB;AAAA,IAC5B,CAAC,MAAwB;AAEvB,UAAI,cAAc,SAAS;AACzB,sBAAc,UAAU;AACxB;AAAA,MACF;AACA,UAAI,CAAE,EAAE,OAAuB,QAAQ,4BAA4B,EAAG,gBAAe;AAAA,IACvF;AAAA,IACA,CAAC,cAAc;AAAA,EACjB;AAIA,QAAM,WAAW;AAAA,IACf,OAAO,KAAe,WAA0B;AAC9C,UAAI,IAAI,WAAW,EAAG;AACtB,UAAI;AACF,cAAM,eAAe,YAAY;AAAA,UAC/B,WAAW,IAAI,IAAI,CAAC,iBAAiB,EAAE,aAAa,OAAO,EAAE;AAAA,QAC/D,CAAC;AAED,uBAAe;AACf;AAAA,UACE,SAAS,IAAI,MAAM,QAAQ,IAAI,WAAW,IAAI,KAAK,GAAG,QAAQ,UAAU,MAAM;AAAA,UAC9E;AAAA,QACF;AAAA,MACF,QAAQ;AACN,eAAO,qCAAqC,OAAO;AAAA,MACrD;AAAA,IACF;AAAA,IACA,CAAC,gBAAgB,gBAAgB,MAAM;AAAA,EACzC;AAIA,QAAM,UAAU;AAAA,IACd,UAAU,aAAa,EAAE,sBAAsB,EAAE,UAAU,EAAE,EAAE,CAAC;AAAA,IAChE,UAAU,aAAa,EAAE,sBAAsB,EAAE,OAAO,KAAK,WAAW,EAAE,EAAE,CAAC;AAAA,EAC/E;AAIA,QAAM,qBAAqB,YAAgC,CAAC,SAAS;AACnE,UAAM,OAAO,cAAc,IAAI;AAC/B,WAAO,KAAK,SAAS,IAAI,OAAO,iBAAiB,IAAI;AAAA,EACvD,GAAG,CAAC,CAAC;AAEL,QAAM,kBAAkB;AAAA,IACtB,CAAC,UAA0B;AACzB,YAAM,QAAQ,MAAM,OAAO,KAAK,SAAS;AACzC,UAAI,CAAC,MAAO;AACZ,sBAAgB,KAAK;AACrB,UAAI,CAAC,eAAe,QAAQ,SAAS,KAAK,GAAG;AAC3C,0BAAkB,CAAC,KAAK,CAAC;AACzB,mBAAW,UAAU,CAAC,KAAK;AAAA,MAC7B,OAAO;AACL,mBAAW,UAAU,eAAe;AAAA,MACtC;AAAA,IACF;AAAA,IACA,CAAC,iBAAiB;AAAA,EACpB;AAEA,QAAM,gBAAgB;AAAA,IACpB,CAAC,UAAwB;AACvB,sBAAgB,IAAI;AACpB,YAAM,OAAO,MAAM,MAAM,KAAK;AAC9B,UAAI,MAAM,SAAS,YAAY,KAAK,MAAM;AACxC,cAAM,eAAe,eAAe,KAAK,IAAI;AAE7C,cAAM,SAAS,WAAW,QAAQ,OAAO,CAAC,OAAO;AAC/C,gBAAM,MAAM,UAAU,KAAK,CAAC,MAAM,EAAE,gBAAgB,EAAE;AACtD,iBAAO,QAAQ,IAAI,UAAU,UAAU;AAAA,QACzC,CAAC;AACD,aAAK,SAAS,QAAQ,YAAY;AAAA,MACpC;AAAA,IACF;AAAA,IACA,CAAC,WAAW,QAAQ;AAAA,EACtB;AAIA,QAAM,uBAAuB;AAAA,IAC3B,CAAC,MAAuB;AACtB,UAAI,CAAC,UAAW;AAChB,UAAI,EAAE,aAAa,MAAM,SAAS,OAAO,GAAG;AAC1C,UAAE,eAAe;AACjB,UAAE,aAAa,aAAa;AAAA,MAC9B;AAAA,IACF;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAEA,QAAM,wBAAwB;AAAA,IAC5B,CAAC,MAAuB;AACtB,UAAI,CAAC,aAAa,CAAC,EAAE,aAAa,MAAM,SAAS,OAAO,EAAG;AAC3D,oBAAc,WAAW;AACzB,wBAAkB,IAAI;AAAA,IACxB;AAAA,IACA,CAAC,SAAS;AAAA,EACZ;AAEA,QAAM,wBAAwB,YAAY,MAAM;AAC9C,kBAAc,UAAU,KAAK,IAAI,GAAG,cAAc,UAAU,CAAC;AAC7D,QAAI,cAAc,YAAY,EAAG,mBAAkB,KAAK;AAAA,EAC1D,GAAG,CAAC,CAAC;AAEL,QAAM,mBAAmB;AAAA,IACvB,CAAC,MAAuB;AACtB,oBAAc,UAAU;AACxB,wBAAkB,KAAK;AACvB,UAAI,CAAC,UAAW;AAChB,YAAM,UAAU,MAAM,KAAK,EAAE,aAAa,SAAS,CAAC,CAAC;AACrD,UAAI,QAAQ,SAAS,GAAG;AACtB,UAAE,eAAe;AACjB,sBAAc,SAAS,eAAe,WAAW,CAAC;AAAA,MACpD;AAAA,IACF;AAAA,IACA,CAAC,WAAW,aAAa,aAAa;AAAA,EACxC;AAIA,QAAM,YAAY,eAAe,UAAU,KAAK,CAAC,MAAM,EAAE,gBAAgB,YAAY,IAAI;AACzF,QAAM,YAAY,WAAW,QAAQ,UAAU;AAE/C,MAAI,sBAAuB,QAAO,gCAAG,0BAAe;AAEpD,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,aAAa;AAAA,MACb,WAAW;AAAA,MACX,cAAc,MAAM,gBAAgB,IAAI;AAAA,MAExC;AAAA,4BAAC,iBAAc,eAAY,sBACzB,+BAAC,iBACC;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,KAAK;AAAA,cACL,SAAS;AAAA,cACT,eAAe;AAAA,cACf,aAAa;AAAA,cACb,YAAY;AAAA,cACZ,aAAa;AAAA,cACb,QAAQ;AAAA,cACR,eAAY;AAAA,cAEX,uBAAa,UAAU,WAAW,IACjC,oBAAC,wBAAqB,IACpB,QAAQ,WAAW,IACrB;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO,cAAc,mBAAmB,OAAO,KAAK,CAAC,MAAM;AAAA,kBAC3D,aACE,cACI,4BACA,YACE,oDACA;AAAA;AAAA,cAEV,IACE,mBAAmB;AAAA;AAAA,gBAErB,oBAAC,wBAAqB;AAAA,kBAEtB;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,QAAQ,eAAe,aAAa;AAAA,oBACpC,UAAU;AAAA,oBACV,OAAO;AAAA,kBACT;AAAA,kBAEC,sBAAY,IAAI,CAAC,eAAe;AAC/B,0BAAM,QAAQ,WAAW,QAAQ;AACjC,0BAAM,aAAa,QAAQ,MAAM,OAAO,QAAQ,WAAW;AAC3D,2BACE;AAAA,sBAAC;AAAA;AAAA,wBAEC,OAAO;AAAA,0BACL,UAAU;AAAA,0BACV,KAAK;AAAA,0BACL,MAAM;AAAA,0BACN,OAAO;AAAA,0BACP,QAAQ;AAAA,0BACR,WAAW,cAAc,WAAW,KAAK;AAAA,0BACzC,SAAS;AAAA,0BACT,qBAAqB,UAAU,WAAW;AAAA,0BAC1C,WAAW;AAAA,wBACb;AAAA,wBAEC,qBAAW,IAAI,CAAC,UAAU;AACzB,8BAAI,MAAM,SAAS,UAAU;AAC3B,kCAAM,MAAM,MAAM,KAAK,KAAK,GAAG;AAC/B,mCACE;AAAA,8BAAC;AAAA;AAAA,gCAEC,QAAQ;AAAA,gCACR;AAAA,gCACA,SAAS,sBAAsB;AAAA,gCAC/B,UAAU,gBAAgB,IAAI,GAAG,GAAG;AAAA,gCACpC,mBAAmB,gBAAgB,IAAI,GAAG,GAAG;AAAA,gCAC7C,WAAW,WAAW,IAAI,GAAG,KAAK;AAAA,gCAClC,QAAQ;AAAA,gCACR,gBAAgB;AAAA,gCAChB,cAAc;AAAA,gCACd,cAAc;AAAA,gCACd,eAAe,YAAY,oBAAoB;AAAA,gCAC/C,YAAY;AAAA,gCACZ,QAAQ,YAAY,mBAAmB;AAAA,gCACvC,UAAU,gBAAgB,KAAK,IAAI,qBAAqB;AAAA,gCACxD,SAAS;AAAA;AAAA,8BAfJ,UAAU,GAAG;AAAA,4BAgBpB;AAAA,0BAEJ;AACA,gCAAM,MAAM,MAAM;AAClB,iCACE;AAAA,4BAAC;AAAA;AAAA,8BAEC;AAAA,8BACA;AAAA,8BACA,UAAU,YAAY,IAAI,IAAI,WAAW;AAAA,8BACzC,UAAU,iBAAiB,IAAI;AAAA,8BAC/B,WAAW,iBAAiB;AAAA,8BAC5B,UAAU,eAAe,IAAI;AAAA,8BAC7B,WAAW,kBAAkB,KAAK,QAAQ,IAAI;AAAA,8BAC9C,cAAc,eAAe,IAAI,IAAI,WAAW;AAAA,8BAChD,YAAY,SAAS;AAAA,gCACnB,IAAI,qBAAqB,IAAI;AAAA,8BAC/B;AAAA,8BACA;AAAA,8BACA,UAAU;AAAA,8BACV,UAAU;AAAA,8BACV,QAAQ;AAAA,8BACR,UAAU;AAAA,8BACV,eAAe;AAAA,8BACf,gBAAgB;AAAA,8BAChB,gBAAgB;AAAA,8BAChB,YAAY;AAAA,8BACZ,QAAQ,YAAY,aAAa;AAAA,8BACjC,UAAU;AAAA,8BACV,SAAS;AAAA;AAAA,4BAvBJ,IAAI;AAAA,0BAwBX;AAAA,wBAEJ,CAAC;AAAA;AAAA,sBAlEI,WAAW;AAAA,oBAmElB;AAAA,kBAEJ,CAAC;AAAA;AAAA,cACH;AAAA;AAAA,UAEJ;AAAA,UAGA,oBAAC,mBAAgB,KAAK,mBAAmB,eAAY,oBAAmB;AAAA,UAEvE,kBACC;AAAA,YAAC;AAAA;AAAA,cACC,OAAO,iBACL,YAAY,SAAS,IAAI,QAAQ,YAAY,YAAY,SAAS,CAAC,CAAC,MAAM,EAC5E;AAAA;AAAA,UACF;AAAA,WAEJ,GACF;AAAA,QAEA,oBAAC,eAAY,eAAe,MACzB,sBAAY,oBAAC,eAAY,KAAK,WAAW,OAAO,WAAW,IAAK,MACnE;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;AAGD,SAAS,YAAY,EAAE,KAAK,MAAM,GAA6C;AAC7E,QAAM,OAAO,gBAAgB,IAAI,WAAW,EAAE,MAAM,IAAI,WAAW,QAAQ,IAAI,OAAO,CAAC;AACvF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAM,oBAAC,QAAK,MAAM,IAAI;AAAA,MACtB,OAAO,iBAAiB,KAAK,IAAI,aAAa,UAAU;AAAA,MACxD;AAAA;AAAA,EACF;AAEJ;",
6
6
  "names": ["ConnectedFilesExplorer"]
7
7
  }