@arbidocs/blocks 0.5.120 → 0.5.122

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 (417) hide show
  1. package/dist/ClippingMediaViewer-IEIBT74X.cjs +156 -0
  2. package/dist/ClippingMediaViewer-IEIBT74X.cjs.map +1 -0
  3. package/dist/ClippingPdfViewer-OGYLMVCE.cjs +79 -0
  4. package/dist/ClippingPdfViewer-OGYLMVCE.cjs.map +1 -0
  5. package/dist/{ConnectedCallDock-WER7R222.cjs → ConnectedCallDock-XJOYVVAH.cjs} +9 -7
  6. package/dist/ConnectedCallDock-XJOYVVAH.cjs.map +1 -0
  7. package/dist/{ConnectedCallRoom-T7OBQTYP.cjs → ConnectedCallRoom-CUDYAPQK.cjs} +9 -7
  8. package/dist/{ConnectedCallRoom-T7OBQTYP.cjs.map → ConnectedCallRoom-CUDYAPQK.cjs.map} +1 -1
  9. package/dist/{ConnectedNativeDocxComparison-SGE4R3M4.cjs → ConnectedNativeDocxComparison-QKHCYD6W.cjs} +7 -7
  10. package/dist/{ConnectedNativeDocxComparison-SGE4R3M4.cjs.map → ConnectedNativeDocxComparison-QKHCYD6W.cjs.map} +1 -1
  11. package/dist/ConnectedPresentation-AU25OW25.cjs +321 -0
  12. package/dist/ConnectedPresentation-AU25OW25.cjs.map +1 -0
  13. package/dist/ConnectedSlidesTab-I75LKKN7.cjs +236 -0
  14. package/dist/ConnectedSlidesTab-I75LKKN7.cjs.map +1 -0
  15. package/dist/{ConnectedStreamedWordArtifact-6MCLJRIT.cjs → ConnectedStreamedWordArtifact-AG62232A.cjs} +7 -7
  16. package/dist/{ConnectedStreamedWordArtifact-6MCLJRIT.cjs.map → ConnectedStreamedWordArtifact-AG62232A.cjs.map} +1 -1
  17. package/dist/{DocumentReviewCard-BPIAJJED.cjs → DocumentReviewCard-M53XFLI2.cjs} +15 -14
  18. package/dist/DocumentReviewCard-M53XFLI2.cjs.map +1 -0
  19. package/dist/{FilesViewerDialog-67WK3TZC.cjs → FilesViewerDialog-4352KIOG.cjs} +30 -22
  20. package/dist/FilesViewerDialog-4352KIOG.cjs.map +1 -0
  21. package/dist/{GridViewImpl-ZMJJWTOM.cjs → GridViewImpl-LTYET77Q.cjs} +3 -3
  22. package/dist/GridViewImpl-LTYET77Q.cjs.map +1 -0
  23. package/dist/{WorkspaceTableView-J3C6VH4T.cjs → WorkspaceTableView-3XYAV4BV.cjs} +9 -8
  24. package/dist/WorkspaceTableView-3XYAV4BV.cjs.map +1 -0
  25. package/dist/agents/index.cjs +186 -186
  26. package/dist/{ai-IM4A23YT.cjs → ai-IEIR7SC2.cjs} +17 -15
  27. package/dist/ai-IEIR7SC2.cjs.map +1 -0
  28. package/dist/calls/connected/CallControls.d.ts +2 -0
  29. package/dist/calls/connected/CallControls.js +71 -9
  30. package/dist/calls/connected/CallControls.js.map +2 -2
  31. package/dist/calls/connected/ShareDocumentDialog.d.ts +14 -0
  32. package/dist/calls/connected/ShareDocumentDialog.js +77 -0
  33. package/dist/calls/connected/ShareDocumentDialog.js.map +7 -0
  34. package/dist/calls/index.cjs +2 -2
  35. package/dist/chat/index.cjs +8 -7
  36. package/dist/{chunk-557MJ4IH.cjs → chunk-2F57IO7S.cjs} +9 -146
  37. package/dist/chunk-2F57IO7S.cjs.map +1 -0
  38. package/dist/chunk-2RLA6QO2.cjs +174 -0
  39. package/dist/chunk-2RLA6QO2.cjs.map +1 -0
  40. package/dist/chunk-4TTX6ZNS.cjs +1374 -0
  41. package/dist/chunk-4TTX6ZNS.cjs.map +1 -0
  42. package/dist/chunk-5GCCUXMT.cjs +63 -0
  43. package/dist/chunk-5GCCUXMT.cjs.map +1 -0
  44. package/dist/{chunk-BUVIBHFU.cjs → chunk-5QERK4PK.cjs} +38 -38
  45. package/dist/chunk-5QERK4PK.cjs.map +1 -0
  46. package/dist/chunk-6OK7ESTL.cjs +134 -0
  47. package/dist/chunk-6OK7ESTL.cjs.map +1 -0
  48. package/dist/{chunk-ECLUFKYR.cjs → chunk-7557LDAN.cjs} +4 -4
  49. package/dist/{chunk-ECLUFKYR.cjs.map → chunk-7557LDAN.cjs.map} +1 -1
  50. package/dist/{chunk-KTQOGT2L.cjs → chunk-7L4X6QN2.cjs} +7 -7
  51. package/dist/{chunk-KTQOGT2L.cjs.map → chunk-7L4X6QN2.cjs.map} +1 -1
  52. package/dist/{chunk-BP3IJ34D.cjs → chunk-7NLO7ASW.cjs} +4 -4
  53. package/dist/{chunk-BP3IJ34D.cjs.map → chunk-7NLO7ASW.cjs.map} +1 -1
  54. package/dist/{chunk-3GWWOYGS.cjs → chunk-7PN3YENO.cjs} +4 -4
  55. package/dist/{chunk-3GWWOYGS.cjs.map → chunk-7PN3YENO.cjs.map} +1 -1
  56. package/dist/{chunk-DFBDQKGE.cjs → chunk-ADDQKZ5I.cjs} +4 -4
  57. package/dist/{chunk-DFBDQKGE.cjs.map → chunk-ADDQKZ5I.cjs.map} +1 -1
  58. package/dist/chunk-AFQTQC7A.cjs +35 -0
  59. package/dist/chunk-AFQTQC7A.cjs.map +1 -0
  60. package/dist/{chunk-NLSWDP42.cjs → chunk-ALK3PUUB.cjs} +21 -11
  61. package/dist/chunk-ALK3PUUB.cjs.map +1 -0
  62. package/dist/{chunk-775S43W7.cjs → chunk-CQQQIZU4.cjs} +8 -8
  63. package/dist/{chunk-775S43W7.cjs.map → chunk-CQQQIZU4.cjs.map} +1 -1
  64. package/dist/{chunk-TDO5UWXF.cjs → chunk-E3L5DB5F.cjs} +5 -5
  65. package/dist/{chunk-TDO5UWXF.cjs.map → chunk-E3L5DB5F.cjs.map} +1 -1
  66. package/dist/chunk-GFUOCGY6.cjs +32 -0
  67. package/dist/chunk-GFUOCGY6.cjs.map +1 -0
  68. package/dist/chunk-HYUKPHCT.cjs +66 -0
  69. package/dist/chunk-HYUKPHCT.cjs.map +1 -0
  70. package/dist/{chunk-QQWHG3KF.cjs → chunk-JJZOL5MG.cjs} +4 -4
  71. package/dist/{chunk-QQWHG3KF.cjs.map → chunk-JJZOL5MG.cjs.map} +1 -1
  72. package/dist/chunk-K4763GD5.cjs +301 -0
  73. package/dist/chunk-K4763GD5.cjs.map +1 -0
  74. package/dist/{chunk-B3LZITVF.cjs → chunk-KA3F6TIH.cjs} +2 -442
  75. package/dist/chunk-KA3F6TIH.cjs.map +1 -0
  76. package/dist/{chunk-PGJYD67F.cjs → chunk-KNGZZC4O.cjs} +7 -6
  77. package/dist/chunk-KNGZZC4O.cjs.map +1 -0
  78. package/dist/{chunk-YYPZOEED.cjs → chunk-LHWOKOMP.cjs} +23 -2
  79. package/dist/chunk-LHWOKOMP.cjs.map +1 -0
  80. package/dist/{chunk-HA66DHW6.cjs → chunk-MLA2BJ2Y.cjs} +28 -28
  81. package/dist/chunk-MLA2BJ2Y.cjs.map +1 -0
  82. package/dist/{chunk-CPR6EHG7.cjs → chunk-NG2EE7HR.cjs} +134 -10
  83. package/dist/chunk-NG2EE7HR.cjs.map +1 -0
  84. package/dist/{chunk-CKCG4NDB.cjs → chunk-OHHKBURG.cjs} +29 -29
  85. package/dist/chunk-OHHKBURG.cjs.map +1 -0
  86. package/dist/{chunk-4XJEHKVZ.cjs → chunk-PIYYBPHH.cjs} +4 -4
  87. package/dist/{chunk-4XJEHKVZ.cjs.map → chunk-PIYYBPHH.cjs.map} +1 -1
  88. package/dist/{chunk-YYSBWMDJ.cjs → chunk-QG2U2JGX.cjs} +4 -4
  89. package/dist/{chunk-YYSBWMDJ.cjs.map → chunk-QG2U2JGX.cjs.map} +1 -1
  90. package/dist/{chunk-5IZFSAEZ.cjs → chunk-SDRYSLOX.cjs} +4 -4
  91. package/dist/{chunk-5IZFSAEZ.cjs.map → chunk-SDRYSLOX.cjs.map} +1 -1
  92. package/dist/{chunk-NJCK6V6U.cjs → chunk-T73BHNQX.cjs} +2 -58
  93. package/dist/chunk-T73BHNQX.cjs.map +1 -0
  94. package/dist/{chunk-EOG6OT5I.cjs → chunk-TXP2N3DC.cjs} +4 -4
  95. package/dist/{chunk-EOG6OT5I.cjs.map → chunk-TXP2N3DC.cjs.map} +1 -1
  96. package/dist/{chunk-6UTKM5AB.cjs → chunk-UFT22LAB.cjs} +75 -75
  97. package/dist/chunk-UFT22LAB.cjs.map +1 -0
  98. package/dist/chunk-USNTRL22.cjs +4790 -0
  99. package/dist/chunk-USNTRL22.cjs.map +1 -0
  100. package/dist/{chunk-X36UR4A7.cjs → chunk-UTJ223TI.cjs} +413 -90
  101. package/dist/chunk-UTJ223TI.cjs.map +1 -0
  102. package/dist/{chunk-VZCPMXWC.cjs → chunk-V6MW7B4B.cjs} +4 -4
  103. package/dist/{chunk-VZCPMXWC.cjs.map → chunk-V6MW7B4B.cjs.map} +1 -1
  104. package/dist/{chunk-T23UTIRI.cjs → chunk-VWBYE3XY.cjs} +5 -5
  105. package/dist/{chunk-T23UTIRI.cjs.map → chunk-VWBYE3XY.cjs.map} +1 -1
  106. package/dist/chunk-WFMWKPGY.cjs +102 -0
  107. package/dist/chunk-WFMWKPGY.cjs.map +1 -0
  108. package/dist/chunk-WOOOMTTA.cjs +19 -0
  109. package/dist/chunk-WOOOMTTA.cjs.map +1 -0
  110. package/dist/{chunk-W6INT5GS.cjs → chunk-WRLGLZIA.cjs} +8 -8
  111. package/dist/{chunk-W6INT5GS.cjs.map → chunk-WRLGLZIA.cjs.map} +1 -1
  112. package/dist/{chunk-CJYWHUZR.cjs → chunk-XCKHOXRP.cjs} +4 -4
  113. package/dist/{chunk-CJYWHUZR.cjs.map → chunk-XCKHOXRP.cjs.map} +1 -1
  114. package/dist/chunk-XF355M7O.cjs +154 -0
  115. package/dist/chunk-XF355M7O.cjs.map +1 -0
  116. package/dist/{chunk-Q6CLWOP2.cjs → chunk-XGM4VVNV.cjs} +34 -34
  117. package/dist/{chunk-Q6CLWOP2.cjs.map → chunk-XGM4VVNV.cjs.map} +1 -1
  118. package/dist/{chunk-6WMMZLEV.cjs → chunk-XJEXFEWG.cjs} +2 -27
  119. package/dist/chunk-XJEXFEWG.cjs.map +1 -0
  120. package/dist/chunk-XK4TVJKD.cjs +73 -0
  121. package/dist/chunk-XK4TVJKD.cjs.map +1 -0
  122. package/dist/{chunk-E7TE2WVT.cjs → chunk-ZVEW3JBT.cjs} +3 -3
  123. package/dist/{chunk-E7TE2WVT.cjs.map → chunk-ZVEW3JBT.cjs.map} +1 -1
  124. package/dist/collaboration/index.cjs +70 -70
  125. package/dist/components/ZoomSlider.d.ts +25 -0
  126. package/dist/components/ZoomSlider.js +59 -0
  127. package/dist/components/ZoomSlider.js.map +7 -0
  128. package/dist/connect/docx.cjs +10 -10
  129. package/dist/connect/index.cjs +1066 -1147
  130. package/dist/connect/index.cjs.map +1 -1
  131. package/dist/connect/viewer.cjs +19 -12
  132. package/dist/connection/ai.d.ts +1 -1
  133. package/dist/connection/conversation/ConnectedMessage.js +1 -1
  134. package/dist/connection/conversation/ConnectedMessage.js.map +2 -2
  135. package/dist/connection/files/ConnectedNewFileMenu.d.ts +2 -1
  136. package/dist/connection/files/ConnectedNewFileMenu.js +9 -3
  137. package/dist/connection/files/ConnectedNewFileMenu.js.map +2 -2
  138. package/dist/connection/files/explorer/ConnectedFilesExplorer.js +1 -1
  139. package/dist/connection/files/explorer/ConnectedFilesExplorer.js.map +2 -2
  140. package/dist/connection/files/explorer/FileTiles.js +1 -1
  141. package/dist/connection/files/explorer/FileTiles.js.map +2 -2
  142. package/dist/connection/files/fields/documentField.js +1 -1
  143. package/dist/connection/files/fields/documentField.js.map +2 -2
  144. package/dist/connection/files/grid/documentColumns.js +1 -1
  145. package/dist/connection/files/grid/documentColumns.js.map +2 -2
  146. package/dist/connection/files/page/DocumentsFilterBarActions.js +17 -28
  147. package/dist/connection/files/page/DocumentsFilterBarActions.js.map +2 -2
  148. package/dist/connection/mail/useMailboxDefaults.js +1 -1
  149. package/dist/connection/mail/useMailboxDefaults.js.map +2 -2
  150. package/dist/connection/panels/useSessionPanelMode.js +3 -2
  151. package/dist/connection/panels/useSessionPanelMode.js.map +2 -2
  152. package/dist/connection/presentation/ClippingMediaViewer.d.ts +12 -0
  153. package/dist/connection/presentation/ClippingMediaViewer.js +153 -0
  154. package/dist/connection/presentation/ClippingMediaViewer.js.map +7 -0
  155. package/dist/connection/presentation/ClippingPdfViewer.d.ts +22 -0
  156. package/dist/connection/presentation/ClippingPdfViewer.js +75 -0
  157. package/dist/connection/presentation/ClippingPdfViewer.js.map +7 -0
  158. package/dist/connection/presentation/ConnectedPresentation.d.ts +12 -0
  159. package/dist/connection/presentation/ConnectedPresentation.js +100 -0
  160. package/dist/connection/presentation/ConnectedPresentation.js.map +7 -0
  161. package/dist/connection/presentation/ConnectedSlidesTab.d.ts +20 -0
  162. package/dist/connection/presentation/ConnectedSlidesTab.js +222 -0
  163. package/dist/connection/presentation/ConnectedSlidesTab.js.map +7 -0
  164. package/dist/connection/presentation/CropClipDialog.d.ts +11 -0
  165. package/dist/connection/presentation/CropClipDialog.js +86 -0
  166. package/dist/connection/presentation/CropClipDialog.js.map +7 -0
  167. package/dist/connection/presentation/GenerateTile.d.ts +4 -0
  168. package/dist/connection/presentation/GenerateTile.js +24 -0
  169. package/dist/connection/presentation/GenerateTile.js.map +7 -0
  170. package/dist/connection/presentation/LabelColumnMenu.d.ts +8 -0
  171. package/dist/connection/presentation/LabelColumnMenu.js +38 -0
  172. package/dist/connection/presentation/LabelColumnMenu.js.map +7 -0
  173. package/dist/connection/presentation/PresentationDialogs.d.ts +39 -0
  174. package/dist/connection/presentation/PresentationDialogs.js +295 -0
  175. package/dist/connection/presentation/PresentationDialogs.js.map +7 -0
  176. package/dist/connection/presentation/PresentationFileCard.d.ts +10 -0
  177. package/dist/connection/presentation/PresentationFileCard.js +35 -0
  178. package/dist/connection/presentation/PresentationFileCard.js.map +7 -0
  179. package/dist/connection/presentation/PresentationPill.d.ts +8 -0
  180. package/dist/connection/presentation/PresentationPill.js +39 -0
  181. package/dist/connection/presentation/PresentationPill.js.map +7 -0
  182. package/dist/connection/presentation/PresentationSlot.d.ts +7 -0
  183. package/dist/connection/presentation/PresentationSlot.js +35 -0
  184. package/dist/connection/presentation/PresentationSlot.js.map +7 -0
  185. package/dist/connection/presentation/requests.d.ts +21 -0
  186. package/dist/connection/presentation/requests.js +27 -0
  187. package/dist/connection/presentation/requests.js.map +7 -0
  188. package/dist/connection/presentation/useImageGeneration.d.ts +11 -0
  189. package/dist/connection/presentation/useImageGeneration.js +66 -0
  190. package/dist/connection/presentation/useImageGeneration.js.map +7 -0
  191. package/dist/connection/presentation/useLabelColumns.d.ts +15 -0
  192. package/dist/connection/presentation/useLabelColumns.js +33 -0
  193. package/dist/connection/presentation/useLabelColumns.js.map +7 -0
  194. package/dist/connection/presentation/usePresentationController.d.ts +15 -0
  195. package/dist/connection/presentation/usePresentationController.js +118 -0
  196. package/dist/connection/presentation/usePresentationController.js.map +7 -0
  197. package/dist/connection/presentation/usePresentationFiles.d.ts +44 -0
  198. package/dist/connection/presentation/usePresentationFiles.js +307 -0
  199. package/dist/connection/presentation/usePresentationFiles.js.map +7 -0
  200. package/dist/connection/presentation/useViewerClipping.d.ts +14 -0
  201. package/dist/connection/presentation/useViewerClipping.js +18 -0
  202. package/dist/connection/presentation/useViewerClipping.js.map +7 -0
  203. package/dist/connection/shell/ConnectedAppShell.js +5 -1
  204. package/dist/connection/shell/ConnectedAppShell.js.map +2 -2
  205. package/dist/connection/viewer/CleanViewControl.d.ts +8 -0
  206. package/dist/connection/viewer/CleanViewControl.js +76 -0
  207. package/dist/connection/viewer/CleanViewControl.js.map +7 -0
  208. package/dist/connection/viewer/ConnectedDocumentViewer.js +28 -29
  209. package/dist/connection/viewer/ConnectedDocumentViewer.js.map +2 -2
  210. package/dist/connection/viewer/ViewerCropModal.d.ts +5 -0
  211. package/dist/connection/viewer/ViewerCropModal.js +22 -0
  212. package/dist/connection/viewer/ViewerCropModal.js.map +7 -0
  213. package/dist/connection/viewer/ViewerPdfPane.d.ts +3 -1
  214. package/dist/connection/viewer/ViewerPdfPane.js +41 -1
  215. package/dist/connection/viewer/ViewerPdfPane.js.map +2 -2
  216. package/dist/connection/viewer/documentPlace.d.ts +5 -4
  217. package/dist/connection/viewer/documentPlace.js +2 -2
  218. package/dist/connection/viewer/documentPlace.js.map +2 -2
  219. package/dist/connection/viewer/drafts.js +6 -4
  220. package/dist/connection/viewer/drafts.js.map +2 -2
  221. package/dist/connection/viewer/pdf/PdfClipOutlines.d.ts +11 -0
  222. package/dist/connection/viewer/pdf/PdfClipOutlines.js +42 -0
  223. package/dist/connection/viewer/pdf/PdfClipOutlines.js.map +7 -0
  224. package/dist/connection/viewer/pdf/clipOutlines.d.ts +17 -0
  225. package/dist/connection/viewer/pdf/clipOutlines.js +24 -0
  226. package/dist/connection/viewer/pdf/clipOutlines.js.map +7 -0
  227. package/dist/connection/viewer/pdf/passageHighlights.d.ts +2 -0
  228. package/dist/connection/viewer/pdf/passageHighlights.js +12 -1
  229. package/dist/connection/viewer/pdf/passageHighlights.js.map +2 -2
  230. package/dist/connection/viewer/pdf/usePdfClipOutlines.d.ts +7 -0
  231. package/dist/connection/viewer/pdf/usePdfClipOutlines.js +36 -0
  232. package/dist/connection/viewer/pdf/usePdfClipOutlines.js.map +7 -0
  233. package/dist/connection/viewer/pdf/usePdfPassageHighlights.js +11 -2
  234. package/dist/connection/viewer/pdf/usePdfPassageHighlights.js.map +2 -2
  235. package/dist/connection/viewer/shareDocument.d.ts +11 -0
  236. package/dist/connection/viewer/shareDocument.js +11 -0
  237. package/dist/connection/viewer/shareDocument.js.map +7 -0
  238. package/dist/connection/viewer/slidesTabChunk.d.ts +2 -0
  239. package/dist/connection/viewer/slidesTabChunk.js +9 -0
  240. package/dist/connection/viewer/slidesTabChunk.js.map +7 -0
  241. package/dist/connection/viewer/useCleanView.d.ts +14 -0
  242. package/dist/connection/viewer/useCleanView.js +29 -0
  243. package/dist/connection/viewer/useCleanView.js.map +7 -0
  244. package/dist/connection/viewer/useViewedDocument.d.ts +1 -0
  245. package/dist/connection/viewer/useViewedDocument.js +9 -1
  246. package/dist/connection/viewer/useViewedDocument.js.map +2 -2
  247. package/dist/connection/viewer/useViewerTabs.js +18 -4
  248. package/dist/connection/viewer/useViewerTabs.js.map +2 -2
  249. package/dist/connection/workflows/ConnectedWorkflowStart.d.ts +14 -2
  250. package/dist/connection/workflows/ConnectedWorkflowStart.js +5 -2
  251. package/dist/connection/workflows/ConnectedWorkflowStart.js.map +2 -2
  252. package/dist/databases/index.cjs +49 -49
  253. package/dist/document-tools/DocumentToolButtons.d.ts +2 -0
  254. package/dist/document-tools/DocumentToolButtons.js +22 -1
  255. package/dist/document-tools/DocumentToolButtons.js.map +2 -2
  256. package/dist/document-tools/index.cjs +16 -12
  257. package/dist/document-tools/index.d.ts +1 -1
  258. package/dist/document-tools/index.js +2 -0
  259. package/dist/document-tools/index.js.map +2 -2
  260. package/dist/embed/index.cjs +17 -15
  261. package/dist/files/GridViewImpl.js +1 -1
  262. package/dist/files/GridViewImpl.js.map +2 -2
  263. package/dist/files/ViewerChrome.d.ts +5 -1
  264. package/dist/files/ViewerChrome.js +16 -6
  265. package/dist/files/ViewerChrome.js.map +2 -2
  266. package/dist/files/index.cjs +224 -224
  267. package/dist/files/navigator/DocumentSearchList.js +1 -1
  268. package/dist/files/navigator/DocumentSearchList.js.map +2 -2
  269. package/dist/index.cjs +359 -356
  270. package/dist/index.cjs.map +1 -1
  271. package/dist/presentation/BoxActionBar.d.ts +11 -0
  272. package/dist/presentation/BoxActionBar.js +182 -0
  273. package/dist/presentation/BoxActionBar.js.map +7 -0
  274. package/dist/presentation/ClipActionBar.d.ts +26 -0
  275. package/dist/presentation/ClipActionBar.js +103 -0
  276. package/dist/presentation/ClipActionBar.js.map +7 -0
  277. package/dist/presentation/ClipCaptureOverlay.d.ts +14 -0
  278. package/dist/presentation/ClipCaptureOverlay.js +69 -0
  279. package/dist/presentation/ClipCaptureOverlay.js.map +7 -0
  280. package/dist/presentation/ClipImage.d.ts +21 -0
  281. package/dist/presentation/ClipImage.js +119 -0
  282. package/dist/presentation/ClipImage.js.map +7 -0
  283. package/dist/presentation/ClipTray.d.ts +11 -0
  284. package/dist/presentation/ClipTray.js +152 -0
  285. package/dist/presentation/ClipTray.js.map +7 -0
  286. package/dist/presentation/ClipViewControls.d.ts +11 -0
  287. package/dist/presentation/ClipViewControls.js +142 -0
  288. package/dist/presentation/ClipViewControls.js.map +7 -0
  289. package/dist/presentation/DesignMenu.d.ts +8 -0
  290. package/dist/presentation/DesignMenu.js +199 -0
  291. package/dist/presentation/DesignMenu.js.map +7 -0
  292. package/dist/presentation/LayoutMenu.d.ts +17 -0
  293. package/dist/presentation/LayoutMenu.js +122 -0
  294. package/dist/presentation/LayoutMenu.js.map +7 -0
  295. package/dist/presentation/MediaClip.d.ts +15 -0
  296. package/dist/presentation/MediaClip.js +67 -0
  297. package/dist/presentation/MediaClip.js.map +7 -0
  298. package/dist/presentation/Notice.d.ts +6 -0
  299. package/dist/presentation/Notice.js +43 -0
  300. package/dist/presentation/Notice.js.map +7 -0
  301. package/dist/presentation/PresentControls.d.ts +11 -0
  302. package/dist/presentation/PresentControls.js +117 -0
  303. package/dist/presentation/PresentControls.js.map +7 -0
  304. package/dist/presentation/PresentationStage.d.ts +32 -0
  305. package/dist/presentation/PresentationStage.js +232 -0
  306. package/dist/presentation/PresentationStage.js.map +7 -0
  307. package/dist/presentation/PresenterView.d.ts +16 -0
  308. package/dist/presentation/PresenterView.js +100 -0
  309. package/dist/presentation/PresenterView.js.map +7 -0
  310. package/dist/presentation/SlideDecor.d.ts +25 -0
  311. package/dist/presentation/SlideDecor.js +189 -0
  312. package/dist/presentation/SlideDecor.js.map +7 -0
  313. package/dist/presentation/SlidesEditor.d.ts +25 -0
  314. package/dist/presentation/SlidesEditor.js +375 -0
  315. package/dist/presentation/SlidesEditor.js.map +7 -0
  316. package/dist/presentation/StageBox.d.ts +30 -0
  317. package/dist/presentation/StageBox.js +281 -0
  318. package/dist/presentation/StageBox.js.map +7 -0
  319. package/dist/presentation/StageItem.d.ts +37 -0
  320. package/dist/presentation/StageItem.js +211 -0
  321. package/dist/presentation/StageItem.js.map +7 -0
  322. package/dist/presentation/box-style.d.ts +6 -0
  323. package/dist/presentation/box-style.js +19 -0
  324. package/dist/presentation/box-style.js.map +7 -0
  325. package/dist/presentation/boxes.d.ts +105 -0
  326. package/dist/presentation/boxes.js +103 -0
  327. package/dist/presentation/boxes.js.map +7 -0
  328. package/dist/presentation/draw-boxes.d.ts +8 -0
  329. package/dist/presentation/draw-boxes.js +130 -0
  330. package/dist/presentation/draw-boxes.js.map +7 -0
  331. package/dist/presentation/export-boxes.d.ts +10 -0
  332. package/dist/presentation/export-boxes.js +74 -0
  333. package/dist/presentation/export-boxes.js.map +7 -0
  334. package/dist/presentation/export-pptx.d.ts +16 -0
  335. package/dist/presentation/export-pptx.js +194 -0
  336. package/dist/presentation/export-pptx.js.map +7 -0
  337. package/dist/presentation/import-pptx.d.ts +35 -0
  338. package/dist/presentation/import-pptx.js +659 -0
  339. package/dist/presentation/import-pptx.js.map +7 -0
  340. package/dist/presentation/merge-outside-edits.d.ts +12 -0
  341. package/dist/presentation/merge-outside-edits.js +35 -0
  342. package/dist/presentation/merge-outside-edits.js.map +7 -0
  343. package/dist/presentation/model.d.ts +201 -0
  344. package/dist/presentation/model.js +271 -0
  345. package/dist/presentation/model.js.map +7 -0
  346. package/dist/presentation/panel-id.d.ts +44 -0
  347. package/dist/presentation/panel-id.js +29 -0
  348. package/dist/presentation/panel-id.js.map +7 -0
  349. package/dist/presentation/persistence.d.ts +121 -0
  350. package/dist/presentation/persistence.js +141 -0
  351. package/dist/presentation/persistence.js.map +7 -0
  352. package/dist/presentation/pptx-data.d.ts +22 -0
  353. package/dist/presentation/pptx-data.js +83 -0
  354. package/dist/presentation/pptx-data.js.map +7 -0
  355. package/dist/presentation/pptx-xml.d.ts +90 -0
  356. package/dist/presentation/pptx-xml.js +333 -0
  357. package/dist/presentation/pptx-xml.js.map +7 -0
  358. package/dist/presentation/render-slides.d.ts +58 -0
  359. package/dist/presentation/render-slides.js +309 -0
  360. package/dist/presentation/render-slides.js.map +7 -0
  361. package/dist/presentation/saved-boxes.d.ts +11 -0
  362. package/dist/presentation/saved-boxes.js +80 -0
  363. package/dist/presentation/saved-boxes.js.map +7 -0
  364. package/dist/presentation/slide-layout.d.ts +58 -0
  365. package/dist/presentation/slide-layout.js +133 -0
  366. package/dist/presentation/slide-layout.js.map +7 -0
  367. package/dist/presentation/stage-videos.d.ts +5 -0
  368. package/dist/presentation/stage-videos.js +19 -0
  369. package/dist/presentation/stage-videos.js.map +7 -0
  370. package/dist/presentation/store.d.ts +203 -0
  371. package/dist/presentation/store.js +429 -0
  372. package/dist/presentation/store.js.map +7 -0
  373. package/dist/presentation/theme.d.ts +102 -0
  374. package/dist/presentation/theme.js +276 -0
  375. package/dist/presentation/theme.js.map +7 -0
  376. package/dist/presentation/useClipDrag.d.ts +26 -0
  377. package/dist/presentation/useClipDrag.js +65 -0
  378. package/dist/presentation/useClipDrag.js.map +7 -0
  379. package/dist/presentation/useObjectUrl.d.ts +6 -0
  380. package/dist/presentation/useObjectUrl.js +15 -0
  381. package/dist/presentation/useObjectUrl.js.map +7 -0
  382. package/dist/presentation/usePresenterKeys.d.ts +13 -0
  383. package/dist/presentation/usePresenterKeys.js +62 -0
  384. package/dist/presentation/usePresenterKeys.js.map +7 -0
  385. package/dist/settings/index.cjs +149 -148
  386. package/dist/shell/PanelPortal.js +13 -3
  387. package/dist/shell/PanelPortal.js.map +2 -2
  388. package/dist/shell/index.cjs +49 -46
  389. package/dist/shell/panel-windows.d.ts +2 -0
  390. package/dist/shell/panel-windows.js +8 -2
  391. package/dist/shell/panel-windows.js.map +2 -2
  392. package/dist/studio/index.cjs +8 -6
  393. package/dist/studio/index.cjs.map +1 -1
  394. package/dist/styles.css +1 -1
  395. package/dist/workflow-canvas/index.cjs +26 -25
  396. package/dist/workflow-canvas/index.cjs.map +1 -1
  397. package/node_modules/@arbidocs/coedit/package.json +1 -1
  398. package/package.json +6 -5
  399. package/dist/ConnectedCallDock-WER7R222.cjs.map +0 -1
  400. package/dist/DocumentReviewCard-BPIAJJED.cjs.map +0 -1
  401. package/dist/FilesViewerDialog-67WK3TZC.cjs.map +0 -1
  402. package/dist/GridViewImpl-ZMJJWTOM.cjs.map +0 -1
  403. package/dist/WorkspaceTableView-J3C6VH4T.cjs.map +0 -1
  404. package/dist/ai-IM4A23YT.cjs.map +0 -1
  405. package/dist/chunk-557MJ4IH.cjs.map +0 -1
  406. package/dist/chunk-6UTKM5AB.cjs.map +0 -1
  407. package/dist/chunk-6WMMZLEV.cjs.map +0 -1
  408. package/dist/chunk-B3LZITVF.cjs.map +0 -1
  409. package/dist/chunk-BUVIBHFU.cjs.map +0 -1
  410. package/dist/chunk-CKCG4NDB.cjs.map +0 -1
  411. package/dist/chunk-CPR6EHG7.cjs.map +0 -1
  412. package/dist/chunk-HA66DHW6.cjs.map +0 -1
  413. package/dist/chunk-NJCK6V6U.cjs.map +0 -1
  414. package/dist/chunk-NLSWDP42.cjs.map +0 -1
  415. package/dist/chunk-PGJYD67F.cjs.map +0 -1
  416. package/dist/chunk-X36UR4A7.cjs.map +0 -1
  417. package/dist/chunk-YYPZOEED.cjs.map +0 -1
@@ -0,0 +1,211 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { memo, useRef, useState } from "react";
4
+ import { cn } from "@arbidocs/react/ui";
5
+ import { ClipImage } from "./ClipImage.js";
6
+ import { ClipViewControls } from "./ClipViewControls.js";
7
+ import {
8
+ frameHeight,
9
+ moveFrame,
10
+ reshapeFrame,
11
+ resizeFrame
12
+ } from "./model.js";
13
+ import { TEXT_COLORS, clipEdgeCss } from "./theme.js";
14
+ const isEdge = (kind) => kind === "n" || kind === "e" || kind === "s" || kind === "w";
15
+ const EDGES = [
16
+ { edge: "n", left: "50%", top: "0%", cursor: "ns-resize", label: "top" },
17
+ { edge: "e", left: "100%", top: "50%", cursor: "ew-resize", label: "right" },
18
+ { edge: "s", left: "50%", top: "100%", cursor: "ns-resize", label: "bottom" },
19
+ { edge: "w", left: "0%", top: "50%", cursor: "ew-resize", label: "left" }
20
+ ];
21
+ const CORNERS = [
22
+ { corner: "nw", left: "0%", top: "0%", cursor: "nwse-resize" },
23
+ { corner: "ne", left: "100%", top: "0%", cursor: "nesw-resize" },
24
+ { corner: "sw", left: "0%", top: "100%", cursor: "nesw-resize" },
25
+ { corner: "se", left: "100%", top: "100%", cursor: "nwse-resize" }
26
+ ];
27
+ const EDGE_CSS = clipEdgeCss();
28
+ const StageItem = memo(function StageItem2({
29
+ clip,
30
+ frame,
31
+ editable,
32
+ selected,
33
+ dim,
34
+ label,
35
+ host
36
+ }) {
37
+ const element = useRef(null);
38
+ const gesture = useRef(null);
39
+ const [dragging, setDragging] = useState(false);
40
+ const [reshape, setReshape] = useState(null);
41
+ const shown = reshape ? { ...clip, ...reshape.shape } : clip;
42
+ const box = reshape?.frame ?? frame;
43
+ const view = () => element.current?.ownerDocument.defaultView ?? window;
44
+ const apply = () => {
45
+ const g = gesture.current;
46
+ const el = element.current;
47
+ if (!g) return;
48
+ g.request = null;
49
+ const next = g.next;
50
+ if (!next || !el) return;
51
+ if (next.shape) {
52
+ setReshape({ frame: next.frame, shape: next.shape });
53
+ } else {
54
+ const dx = (next.frame.x - g.frame.x) * g.stage.width;
55
+ const dy = (next.frame.y - g.frame.y) * g.stage.height;
56
+ const scale = next.frame.w / g.frame.w;
57
+ el.style.transform = `translate3d(${dx}px, ${dy}px, 0) scale(${scale})`;
58
+ }
59
+ const key = next.guides.map((guide) => `${guide.axis}${guide.at}`).join();
60
+ if (key !== g.guidesKey) {
61
+ g.guidesKey = key;
62
+ host.guides(next.guides);
63
+ }
64
+ };
65
+ const start = (event, kind) => {
66
+ if (!editable || event.button !== 0) return;
67
+ const stage = host.stageBox();
68
+ if (!stage) return;
69
+ event.preventDefault();
70
+ event.stopPropagation();
71
+ host.select(clip.id);
72
+ event.currentTarget.setPointerCapture(event.pointerId);
73
+ gesture.current = {
74
+ kind,
75
+ pointer: { x: event.clientX, y: event.clientY },
76
+ frame,
77
+ shape: { rect: clip.rect, aspect: clip.aspect },
78
+ stage,
79
+ others: host.others(clip.id),
80
+ next: null,
81
+ request: null,
82
+ guidesKey: ""
83
+ };
84
+ };
85
+ const move = (event) => {
86
+ const g = gesture.current;
87
+ if (!g) return;
88
+ if (!g.next) {
89
+ setDragging(true);
90
+ host.dragging(true);
91
+ if (element.current) element.current.style.willChange = "transform";
92
+ }
93
+ const dx = (event.clientX - g.pointer.x) / g.stage.width;
94
+ const dy = (event.clientY - g.pointer.y) / g.stage.height;
95
+ const free = event.altKey;
96
+ if (isEdge(g.kind)) {
97
+ const result = reshapeFrame(g.frame, g.shape, g.kind, dx, dy, g.others, free);
98
+ g.next = {
99
+ frame: result.frame,
100
+ shape: { rect: result.rect, aspect: result.aspect },
101
+ guides: result.guides
102
+ };
103
+ } else {
104
+ g.next = g.kind === "move" ? moveFrame(g.frame, g.shape.aspect, dx, dy, g.others, free) : resizeFrame(g.frame, g.shape.aspect, g.kind, dx, dy, g.others, free);
105
+ }
106
+ g.request ??= view().requestAnimationFrame(apply);
107
+ };
108
+ const end = () => {
109
+ const g = gesture.current;
110
+ gesture.current = null;
111
+ if (!g) return;
112
+ if (g.request !== null) view().cancelAnimationFrame(g.request);
113
+ const el = element.current;
114
+ if (el) {
115
+ el.style.transform = "";
116
+ el.style.willChange = "";
117
+ }
118
+ if (!g.next) return;
119
+ setReshape(null);
120
+ setDragging(false);
121
+ host.dragging(false);
122
+ host.guides([]);
123
+ host.commit(clip.id, g.next.frame, g.next.shape);
124
+ };
125
+ return /* @__PURE__ */ jsxs(
126
+ "div",
127
+ {
128
+ ref: element,
129
+ className: cn(
130
+ "absolute origin-top-left",
131
+ // Lifted off the background (a picture that is part of the slide's design is not).
132
+ !clip.plain && "rounded-[0.6cqw] shadow-[0_0.5cqw_1.6cqw_rgba(0,0,0,0.5)]",
133
+ editable && "cursor-move touch-none",
134
+ selected && "outline outline-2 outline-offset-2 outline-primary",
135
+ dim && "opacity-30"
136
+ ),
137
+ style: {
138
+ left: `${box.x * 100}%`,
139
+ top: `${box.y * 100}%`,
140
+ width: `${box.w * 100}%`,
141
+ height: `${frameHeight(box, shown.aspect) * 100}%`
142
+ },
143
+ onPointerDown: (event) => start(event, "move"),
144
+ onPointerMove: move,
145
+ onPointerUp: end,
146
+ onPointerCancel: end,
147
+ "data-testid": `stage-item-${clip.id}`,
148
+ children: [
149
+ /* @__PURE__ */ jsxs("div", { className: cn("absolute inset-0 overflow-hidden", !clip.plain && "rounded-[0.6cqw]"), children: [
150
+ /* @__PURE__ */ jsx(ClipImage, { clip: shown, live: !editable }),
151
+ clip.kind === "pdf" && !clip.plain && /* @__PURE__ */ jsx(
152
+ "div",
153
+ {
154
+ className: "pointer-events-none absolute inset-0",
155
+ style: { background: EDGE_CSS },
156
+ "data-testid": "stage-clip-edge"
157
+ }
158
+ ),
159
+ !clip.plain && /* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-0 rounded-[0.6cqw] ring-1 ring-inset ring-white/15" })
160
+ ] }),
161
+ label && !clip.plain && // Under the clip, in the room the layout keeps (CAPTION_SPACE): never over it.
162
+ /* @__PURE__ */ jsx(
163
+ "div",
164
+ {
165
+ className: "pointer-events-none absolute left-0 top-full mt-[0.5cqw] max-w-full truncate text-[1.7cqw] leading-tight",
166
+ style: { color: TEXT_COLORS.muted },
167
+ children: label
168
+ }
169
+ ),
170
+ selected && !dragging && /* @__PURE__ */ jsx(ClipViewControls, { clip }),
171
+ selected && CORNERS.map(({ corner, left, top, cursor }) => /* @__PURE__ */ jsx(
172
+ "div",
173
+ {
174
+ className: "absolute flex size-6 -translate-x-1/2 -translate-y-1/2 items-center justify-center pointer-coarse:size-11",
175
+ style: { left, top, cursor, touchAction: "none" },
176
+ onPointerDown: (event) => start(event, corner),
177
+ "aria-label": `Resize from the ${corner} corner`,
178
+ "data-testid": `stage-item-resize-${corner}`,
179
+ children: /* @__PURE__ */ jsx("span", { className: "pointer-events-none size-3 rounded-full border-2 border-primary bg-background" })
180
+ },
181
+ corner
182
+ )),
183
+ selected && EDGES.map(({ edge, left, top, cursor, label: side }) => /* @__PURE__ */ jsx(
184
+ "div",
185
+ {
186
+ className: "absolute flex size-6 -translate-x-1/2 -translate-y-1/2 items-center justify-center pointer-coarse:size-11",
187
+ style: { left, top, cursor, touchAction: "none" },
188
+ onPointerDown: (event) => start(event, edge),
189
+ "aria-label": `Show more or less at the ${side}`,
190
+ title: "Drag to show more or less of the page",
191
+ "data-testid": `stage-item-reshape-${edge}`,
192
+ children: /* @__PURE__ */ jsx(
193
+ "span",
194
+ {
195
+ className: cn(
196
+ "pointer-events-none rounded-full border-2 border-primary bg-background",
197
+ edge === "n" || edge === "s" ? "h-2 w-4" : "h-4 w-2"
198
+ )
199
+ }
200
+ )
201
+ },
202
+ edge
203
+ ))
204
+ ]
205
+ }
206
+ );
207
+ });
208
+ export {
209
+ StageItem
210
+ };
211
+ //# sourceMappingURL=StageItem.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/presentation/StageItem.tsx"],
4
+ "sourcesContent": ["/**\n * One clip on the stage, and its own gestures: moved by dragging it, resized from a corner (its\n * shape kept), reshaped from a side's middle (more or less of the page that way), snapping to the\n * stage and to the other clips.\n *\n * Built for smooth dragging: while a clip is moved or resized nothing re-renders and nothing is\n * laid out again. Its element is moved by a GPU transform (translate, scale) once per animation\n * frame, and the new frame reaches the presentation once, when the drag ends. Only reshaping, which\n * changes what the clip shows, re-renders the clip itself (and nothing else). The component is\n * memoised: other clips, the slide's text and the other slides are untouched by its drags.\n */\n\nimport { memo, useRef, useState, type PointerEvent as ReactPointerEvent } from 'react'\nimport { cn } from '@arbidocs/react/ui'\nimport { ClipImage } from './ClipImage'\nimport { ClipViewControls } from './ClipViewControls'\nimport {\n frameHeight,\n moveFrame,\n reshapeFrame,\n resizeFrame,\n type Clip,\n type Corner,\n type Edge,\n type Frame,\n type Guide,\n type Placed,\n} from './model'\nimport { TEXT_COLORS, clipEdgeCss } from './theme'\n\ntype Kind = 'move' | Corner | Edge\n\nconst isEdge = (kind: Kind): kind is Edge =>\n kind === 'n' || kind === 'e' || kind === 's' || kind === 'w'\n\n/** The handle on each side's middle: drag it to show more (or less) of the page that way. */\nconst EDGES: { edge: Edge; left: string; top: string; cursor: string; label: string }[] = [\n { edge: 'n', left: '50%', top: '0%', cursor: 'ns-resize', label: 'top' },\n { edge: 'e', left: '100%', top: '50%', cursor: 'ew-resize', label: 'right' },\n { edge: 's', left: '50%', top: '100%', cursor: 'ns-resize', label: 'bottom' },\n { edge: 'w', left: '0%', top: '50%', cursor: 'ew-resize', label: 'left' },\n]\n\nconst CORNERS: { corner: Corner; left: string; top: string; cursor: string }[] = [\n { corner: 'nw', left: '0%', top: '0%', cursor: 'nwse-resize' },\n { corner: 'ne', left: '100%', top: '0%', cursor: 'nesw-resize' },\n { corner: 'sw', left: '0%', top: '100%', cursor: 'nesw-resize' },\n { corner: 'se', left: '100%', top: '100%', cursor: 'nwse-resize' },\n]\n\nconst EDGE_CSS = clipEdgeCss()\n\n/** What a stage gives its clips (stable across renders: the clips are memoised). */\nexport interface StageItemHost {\n /** The stage's box on screen, as a gesture begins. */\n stageBox(): DOMRect | null\n /** The other clips of the slide, as a gesture begins: what this one snaps to. */\n others(clipId: string): Placed[]\n select(clipId: string): void\n /** The snap lines to draw while a clip is dragged (empty: none). */\n guides(guides: Guide[]): void\n /** A drag is on (the stage hides the selected clip's floating actions meanwhile). */\n dragging(on: boolean): void\n /** The drag's result, once it ends. */\n commit(clipId: string, frame: Frame, shape?: Pick<Clip, 'rect' | 'aspect'>): void\n}\n\nexport interface StageItemProps {\n clip: Clip\n frame: Frame\n editable: boolean\n selected: boolean\n dim: boolean\n /** Its source label, under it (empty: none). */\n label: string\n host: StageItemHost\n}\n\ninterface Gesture {\n kind: Kind\n pointer: { x: number; y: number }\n frame: Frame\n shape: Pick<Clip, 'rect' | 'aspect'>\n stage: DOMRect\n others: Placed[]\n /** The latest result, applied at the next animation frame and committed at the end. */\n next: { frame: Frame; shape?: Pick<Clip, 'rect' | 'aspect'>; guides: Guide[] } | null\n request: number | null\n guidesKey: string\n}\n\nexport const StageItem = memo(function StageItem({\n clip,\n frame,\n editable,\n selected,\n dim,\n label,\n host,\n}: StageItemProps) {\n const element = useRef<HTMLDivElement>(null)\n const gesture = useRef<Gesture | null>(null)\n const [dragging, setDragging] = useState(false)\n // Being reshaped: drawn as it will be (the one case that re-renders while dragging).\n const [reshape, setReshape] = useState<{\n frame: Frame\n shape: Pick<Clip, 'rect' | 'aspect'>\n } | null>(null)\n\n const shown = reshape ? { ...clip, ...reshape.shape } : clip\n const box = reshape?.frame ?? frame\n\n const view = () => element.current?.ownerDocument.defaultView ?? window\n\n const apply = () => {\n const g = gesture.current\n const el = element.current\n if (!g) return\n g.request = null\n const next = g.next\n if (!next || !el) return\n if (next.shape) {\n setReshape({ frame: next.frame, shape: next.shape })\n } else {\n // Moved or resized: a transform from where the drag began (top left fixed as the origin).\n const dx = (next.frame.x - g.frame.x) * g.stage.width\n const dy = (next.frame.y - g.frame.y) * g.stage.height\n const scale = next.frame.w / g.frame.w\n el.style.transform = `translate3d(${dx}px, ${dy}px, 0) scale(${scale})`\n }\n const key = next.guides.map((guide) => `${guide.axis}${guide.at}`).join()\n if (key !== g.guidesKey) {\n g.guidesKey = key\n host.guides(next.guides)\n }\n }\n\n const start = (event: ReactPointerEvent, kind: Kind) => {\n if (!editable || event.button !== 0) return\n const stage = host.stageBox()\n if (!stage) return\n event.preventDefault()\n event.stopPropagation()\n host.select(clip.id)\n event.currentTarget.setPointerCapture(event.pointerId)\n gesture.current = {\n kind,\n pointer: { x: event.clientX, y: event.clientY },\n frame,\n shape: { rect: clip.rect, aspect: clip.aspect },\n stage,\n others: host.others(clip.id),\n next: null,\n request: null,\n guidesKey: '',\n }\n }\n\n const move = (event: ReactPointerEvent) => {\n const g = gesture.current\n if (!g) return\n if (!g.next) {\n // The first move: the drag is on (handles and actions hide; the layer is promoted).\n setDragging(true)\n host.dragging(true)\n if (element.current) element.current.style.willChange = 'transform'\n }\n const dx = (event.clientX - g.pointer.x) / g.stage.width\n const dy = (event.clientY - g.pointer.y) / g.stage.height\n // Alt (Option) places freely, without snapping.\n const free = event.altKey\n if (isEdge(g.kind)) {\n const result = reshapeFrame(g.frame, g.shape, g.kind, dx, dy, g.others, free)\n g.next = {\n frame: result.frame,\n shape: { rect: result.rect, aspect: result.aspect },\n guides: result.guides,\n }\n } else {\n g.next =\n g.kind === 'move'\n ? moveFrame(g.frame, g.shape.aspect, dx, dy, g.others, free)\n : resizeFrame(g.frame, g.shape.aspect, g.kind, dx, dy, g.others, free)\n }\n g.request ??= view().requestAnimationFrame(apply)\n }\n\n const end = () => {\n const g = gesture.current\n gesture.current = null\n if (!g) return\n if (g.request !== null) view().cancelAnimationFrame(g.request)\n const el = element.current\n if (el) {\n el.style.transform = ''\n el.style.willChange = ''\n }\n if (!g.next) return // a click: the clip is selected, nothing moved\n setReshape(null)\n setDragging(false)\n host.dragging(false)\n host.guides([])\n host.commit(clip.id, g.next.frame, g.next.shape)\n }\n\n return (\n <div\n ref={element}\n className={cn(\n 'absolute origin-top-left',\n // Lifted off the background (a picture that is part of the slide's design is not).\n !clip.plain && 'rounded-[0.6cqw] shadow-[0_0.5cqw_1.6cqw_rgba(0,0,0,0.5)]',\n editable && 'cursor-move touch-none',\n selected && 'outline outline-2 outline-offset-2 outline-primary',\n dim && 'opacity-30'\n )}\n style={{\n left: `${box.x * 100}%`,\n top: `${box.y * 100}%`,\n width: `${box.w * 100}%`,\n height: `${frameHeight(box, shown.aspect) * 100}%`,\n }}\n onPointerDown={(event) => start(event, 'move')}\n onPointerMove={move}\n onPointerUp={end}\n onPointerCancel={end}\n data-testid={`stage-item-${clip.id}`}\n >\n {/* Softly rounded, with a faint light edge: crisp on any background. */}\n <div className={cn('absolute inset-0 overflow-hidden', !clip.plain && 'rounded-[0.6cqw]')}>\n <ClipImage clip={shown} live={!editable} />\n {/* A page's text fades out at the clip's edge rather than being sliced. */}\n {clip.kind === 'pdf' && !clip.plain && (\n <div\n className=\"pointer-events-none absolute inset-0\"\n style={{ background: EDGE_CSS }}\n data-testid=\"stage-clip-edge\"\n />\n )}\n {!clip.plain && (\n <div className=\"pointer-events-none absolute inset-0 rounded-[0.6cqw] ring-1 ring-inset ring-white/15\" />\n )}\n </div>\n {label && !clip.plain && (\n // Under the clip, in the room the layout keeps (CAPTION_SPACE): never over it.\n <div\n className=\"pointer-events-none absolute left-0 top-full mt-[0.5cqw] max-w-full truncate text-[1.7cqw] leading-tight\"\n style={{ color: TEXT_COLORS.muted }}\n >\n {label}\n </div>\n )}\n {/* Scroll and zoom what it shows, on a layer over it (not while it is dragged). */}\n {selected && !dragging && <ClipViewControls clip={clip} />}\n {/* A handle on each corner (a small dot in a finger-sized target), and a bar on each side's\n middle; their moves bubble to the clip's handlers while the gesture lasts. */}\n {selected &&\n CORNERS.map(({ corner, left, top, cursor }) => (\n <div\n key={corner}\n className=\"absolute flex size-6 -translate-x-1/2 -translate-y-1/2 items-center justify-center pointer-coarse:size-11\"\n style={{ left, top, cursor, touchAction: 'none' }}\n onPointerDown={(event) => start(event, corner)}\n aria-label={`Resize from the ${corner} corner`}\n data-testid={`stage-item-resize-${corner}`}\n >\n <span className=\"pointer-events-none size-3 rounded-full border-2 border-primary bg-background\" />\n </div>\n ))}\n {selected &&\n EDGES.map(({ edge, left, top, cursor, label: side }) => (\n <div\n key={edge}\n className=\"absolute flex size-6 -translate-x-1/2 -translate-y-1/2 items-center justify-center pointer-coarse:size-11\"\n style={{ left, top, cursor, touchAction: 'none' }}\n onPointerDown={(event) => start(event, edge)}\n aria-label={`Show more or less at the ${side}`}\n title=\"Drag to show more or less of the page\"\n data-testid={`stage-item-reshape-${edge}`}\n >\n <span\n className={cn(\n 'pointer-events-none rounded-full border-2 border-primary bg-background',\n edge === 'n' || edge === 's' ? 'h-2 w-4' : 'h-4 w-2'\n )}\n />\n </div>\n ))}\n </div>\n )\n})\n"],
5
+ "mappings": "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",
6
+ "names": ["StageItem"]
7
+ }
@@ -0,0 +1,6 @@
1
+ /** Text boxes' type as CSS (container units: it scales with the stage). */
2
+ import type { CSSProperties } from 'react';
3
+ import { type TextRun } from './boxes';
4
+ /** A size in points as CSS (container units). */
5
+ export declare const cqw: (points: number) => string;
6
+ export declare function runStyle(run: TextRun, font: string): CSSProperties;
@@ -0,0 +1,19 @@
1
+ "use client";
2
+ import { DEFAULT_TEXT_SIZE, pointsToStage } from "./boxes.js";
3
+ import { TEXT_COLORS } from "./theme.js";
4
+ const cqw = (points) => `${pointsToStage(points) * 100}cqw`;
5
+ function runStyle(run, font) {
6
+ return {
7
+ fontSize: cqw(run.size ?? DEFAULT_TEXT_SIZE),
8
+ fontWeight: run.bold ? 700 : 400,
9
+ fontStyle: run.italic ? "italic" : void 0,
10
+ textDecoration: run.underline ? "underline" : void 0,
11
+ color: run.color ?? TEXT_COLORS.body,
12
+ fontFamily: run.font ? `"${run.font}", ${font}` : font
13
+ };
14
+ }
15
+ export {
16
+ cqw,
17
+ runStyle
18
+ };
19
+ //# sourceMappingURL=box-style.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/presentation/box-style.ts"],
4
+ "sourcesContent": ["/** Text boxes' type as CSS (container units: it scales with the stage). */\n\nimport type { CSSProperties } from 'react'\nimport { DEFAULT_TEXT_SIZE, pointsToStage, type TextRun } from './boxes'\nimport { TEXT_COLORS } from './theme'\n\n/** A size in points as CSS (container units). */\nexport const cqw = (points: number) => `${pointsToStage(points) * 100}cqw`\n\nexport function runStyle(run: TextRun, font: string): CSSProperties {\n return {\n fontSize: cqw(run.size ?? DEFAULT_TEXT_SIZE),\n fontWeight: run.bold ? 700 : 400,\n fontStyle: run.italic ? 'italic' : undefined,\n textDecoration: run.underline ? 'underline' : undefined,\n color: run.color ?? TEXT_COLORS.body,\n fontFamily: run.font ? `\"${run.font}\", ${font}` : font,\n }\n}\n"],
5
+ "mappings": ";AAGA,SAAS,mBAAmB,qBAAmC;AAC/D,SAAS,mBAAmB;AAGrB,MAAM,MAAM,CAAC,WAAmB,GAAG,cAAc,MAAM,IAAI,GAAG;AAE9D,SAAS,SAAS,KAAc,MAA6B;AAClE,SAAO;AAAA,IACL,UAAU,IAAI,IAAI,QAAQ,iBAAiB;AAAA,IAC3C,YAAY,IAAI,OAAO,MAAM;AAAA,IAC7B,WAAW,IAAI,SAAS,WAAW;AAAA,IACnC,gBAAgB,IAAI,YAAY,cAAc;AAAA,IAC9C,OAAO,IAAI,SAAS,YAAY;AAAA,IAChC,YAAY,IAAI,OAAO,IAAI,IAAI,IAAI,MAAM,IAAI,KAAK;AAAA,EACpD;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,105 @@
1
+ /**
2
+ * A slide's text boxes and shapes: what a PowerPoint slide is made of besides pictures, so a deck
3
+ * imported from PowerPoint keeps its look and its words stay editable. A box sits in a frame of its
4
+ * own (fractions of the stage, its height free), holds styled text (paragraphs of runs) and can be
5
+ * a shape (a rectangle, a rounded one, an ellipse, a line) with a fill and an outline.
6
+ *
7
+ * Type sizes are points on PowerPoint's widescreen slide (13.333 × 7.5 in), so they read the same
8
+ * here, in the saved PDF and in an exported deck.
9
+ */
10
+ /** A box's place: left, top, width and height as fractions of the stage. */
11
+ export interface BoxFrame {
12
+ x: number;
13
+ y: number;
14
+ w: number;
15
+ h: number;
16
+ }
17
+ export type BoxShape = 'text' | 'rect' | 'roundRect' | 'ellipse' | 'line';
18
+ export type TextAlign = 'left' | 'center' | 'right' | 'justify';
19
+ export type BoxAnchor = 'top' | 'middle' | 'bottom';
20
+ export interface TextRun {
21
+ text: string;
22
+ /** Points on the widescreen slide; absent: `DEFAULT_TEXT_SIZE`. */
23
+ size?: number;
24
+ bold?: boolean;
25
+ italic?: boolean;
26
+ underline?: boolean;
27
+ /** `#rrggbb`; absent: the theme's body text colour. */
28
+ color?: string;
29
+ /** A typeface name; absent: the theme's. */
30
+ font?: string;
31
+ }
32
+ export interface Paragraph {
33
+ runs: TextRun[];
34
+ align?: TextAlign;
35
+ /** Its indent level (0 is the outermost). */
36
+ level?: number;
37
+ bullet?: boolean;
38
+ }
39
+ export interface SlideBox {
40
+ id: string;
41
+ frame: BoxFrame;
42
+ shape: BoxShape;
43
+ /** Degrees, clockwise. */
44
+ rotation?: number;
45
+ flipH?: boolean;
46
+ flipV?: boolean;
47
+ /** `#rrggbb`; absent: no fill. */
48
+ fill?: string;
49
+ /** The fill's opacity, 0–1 (default 1). */
50
+ fillAlpha?: number;
51
+ line?: {
52
+ color: string;
53
+ width: number;
54
+ dash?: boolean;
55
+ };
56
+ paragraphs: Paragraph[];
57
+ anchor?: BoxAnchor;
58
+ /** Room between the box's edge and its text, in points (default `DEFAULT_INSET`). */
59
+ inset?: number;
60
+ /** The slide's title or body text (a PowerPoint placeholder): what an outline reads. */
61
+ role?: 'title' | 'body';
62
+ /** Drawn over the slide's clips (default: under them). */
63
+ front?: boolean;
64
+ }
65
+ /** A slide's own background, over the theme's: an image (a media key), a gradient or a colour. */
66
+ export interface SlideBackground {
67
+ color?: string;
68
+ gradient?: {
69
+ from: string;
70
+ to: string;
71
+ angle: number;
72
+ };
73
+ image?: string;
74
+ }
75
+ /** PowerPoint's widescreen slide in points: type sizes are measured against it. */
76
+ export declare const SLIDE_POINTS: {
77
+ w: number;
78
+ h: number;
79
+ };
80
+ export declare const DEFAULT_TEXT_SIZE = 18;
81
+ export declare const DEFAULT_INSET = 7.2;
82
+ /** The smallest a box can be made (fractions of the stage). */
83
+ export declare const MIN_BOX = 0.02;
84
+ /** A size in points as a fraction of the stage width (the stage's `cqw` / 100). */
85
+ export declare const pointsToStage: (points: number) => number;
86
+ /** The text of a box, one line per paragraph. */
87
+ export declare const boxText: (box: Pick<SlideBox, "paragraphs">) => string;
88
+ /**
89
+ * New text typed into a box: one paragraph per line, each keeping the style of the paragraph it
90
+ * replaces (its first run's type, its alignment, level and bullet), so retyping keeps the look.
91
+ */
92
+ export declare function withText(box: SlideBox, text: string): SlideBox;
93
+ /** Every run of a box changed by `change` (bold, a size, a colour: the whole box at once). */
94
+ export declare function styleRuns(box: SlideBox, change: (run: TextRun) => TextRun): SlideBox;
95
+ /** A box's first run (what its style controls show). */
96
+ export declare const firstRun: (box: SlideBox) => TextRun | undefined;
97
+ /** The box moved by `dx, dy`, kept on the stage. */
98
+ export declare function moveBox(frame: BoxFrame, dx: number, dy: number): BoxFrame;
99
+ /** A box handle: a corner or a side's middle. */
100
+ export type BoxHandle = 'nw' | 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w';
101
+ /** The box resized from `handle` by `dx, dy` (its shape is free; the opposite side stays put). */
102
+ export declare function stretchBox(frame: BoxFrame, handle: BoxHandle, dx: number, dy: number): BoxFrame;
103
+ export declare const nextBoxId: () => string;
104
+ /** A new box of `shape`, in the middle of the slide, ready to type in. */
105
+ export declare function newBox(shape: BoxShape, accent: string): SlideBox;
@@ -0,0 +1,103 @@
1
+ "use client";
2
+ const SLIDE_POINTS = { w: 960, h: 540 };
3
+ const DEFAULT_TEXT_SIZE = 18;
4
+ const DEFAULT_INSET = 7.2;
5
+ const MIN_BOX = 0.02;
6
+ const pointsToStage = (points) => points / SLIDE_POINTS.w;
7
+ const boxText = (box) => box.paragraphs.map((paragraph) => paragraph.runs.map((run) => run.text).join("")).join("\n");
8
+ function withText(box, text) {
9
+ const lines = text.split("\n");
10
+ const fallback = box.paragraphs[box.paragraphs.length - 1] ?? { runs: [{ text: "" }] };
11
+ const paragraphs = lines.map((line, index) => {
12
+ const before = box.paragraphs[index] ?? fallback;
13
+ const { text: _old, ...style } = before.runs[0] ?? { text: "" };
14
+ void _old;
15
+ return { ...before, runs: [{ ...style, text: line }] };
16
+ });
17
+ return { ...box, paragraphs };
18
+ }
19
+ function styleRuns(box, change) {
20
+ return {
21
+ ...box,
22
+ paragraphs: box.paragraphs.map((paragraph) => ({
23
+ ...paragraph,
24
+ runs: paragraph.runs.map(change)
25
+ }))
26
+ };
27
+ }
28
+ const firstRun = (box) => box.paragraphs.find((paragraph) => paragraph.runs.length)?.runs[0];
29
+ const clamp = (value, min, max) => max < min ? (min + max) / 2 : Math.min(Math.max(value, min), max);
30
+ function moveBox(frame, dx, dy) {
31
+ return {
32
+ ...frame,
33
+ x: clamp(frame.x + dx, -frame.w / 2, 1 - frame.w / 2),
34
+ y: clamp(frame.y + dy, -frame.h / 2, 1 - frame.h / 2)
35
+ };
36
+ }
37
+ function stretchBox(frame, handle, dx, dy) {
38
+ let { x, y, w, h } = frame;
39
+ if (handle.includes("w")) {
40
+ const right = x + w;
41
+ x = Math.min(x + dx, right - MIN_BOX);
42
+ w = right - x;
43
+ } else if (handle.includes("e")) {
44
+ w = Math.max(MIN_BOX, w + dx);
45
+ }
46
+ if (handle.startsWith("n")) {
47
+ const bottom = y + h;
48
+ y = Math.min(y + dy, bottom - MIN_BOX);
49
+ h = bottom - y;
50
+ } else if (handle.startsWith("s")) {
51
+ h = Math.max(MIN_BOX, h + dy);
52
+ }
53
+ return { x, y, w, h };
54
+ }
55
+ let sequence = 0;
56
+ const nextBoxId = () => `box-${Date.now().toString(36)}-${++sequence}`;
57
+ function newBox(shape, accent) {
58
+ const id = nextBoxId();
59
+ if (shape === "text") {
60
+ return {
61
+ id,
62
+ shape,
63
+ frame: { x: 0.3, y: 0.42, w: 0.4, h: 0.12 },
64
+ paragraphs: [{ runs: [{ text: "", size: 24 }] }],
65
+ front: true
66
+ };
67
+ }
68
+ if (shape === "line") {
69
+ return {
70
+ id,
71
+ shape,
72
+ frame: { x: 0.35, y: 0.5, w: 0.3, h: 0 },
73
+ line: { color: accent, width: 2 },
74
+ paragraphs: [],
75
+ front: true
76
+ };
77
+ }
78
+ return {
79
+ id,
80
+ shape,
81
+ frame: { x: 0.35, y: 0.35, w: 0.3, h: 0.3 },
82
+ fill: accent,
83
+ paragraphs: [{ runs: [{ text: "", size: 20, color: "#ffffff" }], align: "center" }],
84
+ anchor: "middle",
85
+ front: false
86
+ };
87
+ }
88
+ export {
89
+ DEFAULT_INSET,
90
+ DEFAULT_TEXT_SIZE,
91
+ MIN_BOX,
92
+ SLIDE_POINTS,
93
+ boxText,
94
+ firstRun,
95
+ moveBox,
96
+ newBox,
97
+ nextBoxId,
98
+ pointsToStage,
99
+ stretchBox,
100
+ styleRuns,
101
+ withText
102
+ };
103
+ //# sourceMappingURL=boxes.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/presentation/boxes.ts"],
4
+ "sourcesContent": ["/**\n * A slide's text boxes and shapes: what a PowerPoint slide is made of besides pictures, so a deck\n * imported from PowerPoint keeps its look and its words stay editable. A box sits in a frame of its\n * own (fractions of the stage, its height free), holds styled text (paragraphs of runs) and can be\n * a shape (a rectangle, a rounded one, an ellipse, a line) with a fill and an outline.\n *\n * Type sizes are points on PowerPoint's widescreen slide (13.333 \u00D7 7.5 in), so they read the same\n * here, in the saved PDF and in an exported deck.\n */\n\n/** A box's place: left, top, width and height as fractions of the stage. */\nexport interface BoxFrame {\n x: number\n y: number\n w: number\n h: number\n}\n\nexport type BoxShape = 'text' | 'rect' | 'roundRect' | 'ellipse' | 'line'\nexport type TextAlign = 'left' | 'center' | 'right' | 'justify'\nexport type BoxAnchor = 'top' | 'middle' | 'bottom'\n\nexport interface TextRun {\n text: string\n /** Points on the widescreen slide; absent: `DEFAULT_TEXT_SIZE`. */\n size?: number\n bold?: boolean\n italic?: boolean\n underline?: boolean\n /** `#rrggbb`; absent: the theme's body text colour. */\n color?: string\n /** A typeface name; absent: the theme's. */\n font?: string\n}\n\nexport interface Paragraph {\n runs: TextRun[]\n align?: TextAlign\n /** Its indent level (0 is the outermost). */\n level?: number\n bullet?: boolean\n}\n\nexport interface SlideBox {\n id: string\n frame: BoxFrame\n shape: BoxShape\n /** Degrees, clockwise. */\n rotation?: number\n flipH?: boolean\n flipV?: boolean\n /** `#rrggbb`; absent: no fill. */\n fill?: string\n /** The fill's opacity, 0\u20131 (default 1). */\n fillAlpha?: number\n line?: { color: string; width: number; dash?: boolean }\n paragraphs: Paragraph[]\n anchor?: BoxAnchor\n /** Room between the box's edge and its text, in points (default `DEFAULT_INSET`). */\n inset?: number\n /** The slide's title or body text (a PowerPoint placeholder): what an outline reads. */\n role?: 'title' | 'body'\n /** Drawn over the slide's clips (default: under them). */\n front?: boolean\n}\n\n/** A slide's own background, over the theme's: an image (a media key), a gradient or a colour. */\nexport interface SlideBackground {\n color?: string\n gradient?: { from: string; to: string; angle: number }\n image?: string\n}\n\n/** PowerPoint's widescreen slide in points: type sizes are measured against it. */\nexport const SLIDE_POINTS = { w: 960, h: 540 }\nexport const DEFAULT_TEXT_SIZE = 18\nexport const DEFAULT_INSET = 7.2\n/** The smallest a box can be made (fractions of the stage). */\nexport const MIN_BOX = 0.02\n\n/** A size in points as a fraction of the stage width (the stage's `cqw` / 100). */\nexport const pointsToStage = (points: number): number => points / SLIDE_POINTS.w\n\n/** The text of a box, one line per paragraph. */\nexport const boxText = (box: Pick<SlideBox, 'paragraphs'>): string =>\n box.paragraphs.map((paragraph) => paragraph.runs.map((run) => run.text).join('')).join('\\n')\n\n/**\n * New text typed into a box: one paragraph per line, each keeping the style of the paragraph it\n * replaces (its first run's type, its alignment, level and bullet), so retyping keeps the look.\n */\nexport function withText(box: SlideBox, text: string): SlideBox {\n const lines = text.split('\\n')\n const fallback = box.paragraphs[box.paragraphs.length - 1] ?? { runs: [{ text: '' }] }\n const paragraphs = lines.map((line, index) => {\n const before = box.paragraphs[index] ?? fallback\n const { text: _old, ...style } = before.runs[0] ?? { text: '' }\n void _old\n return { ...before, runs: [{ ...style, text: line }] }\n })\n return { ...box, paragraphs }\n}\n\n/** Every run of a box changed by `change` (bold, a size, a colour: the whole box at once). */\nexport function styleRuns(box: SlideBox, change: (run: TextRun) => TextRun): SlideBox {\n return {\n ...box,\n paragraphs: box.paragraphs.map((paragraph) => ({\n ...paragraph,\n runs: paragraph.runs.map(change),\n })),\n }\n}\n\n/** A box's first run (what its style controls show). */\nexport const firstRun = (box: SlideBox): TextRun | undefined =>\n box.paragraphs.find((paragraph) => paragraph.runs.length)?.runs[0]\n\nconst clamp = (value: number, min: number, max: number) =>\n max < min ? (min + max) / 2 : Math.min(Math.max(value, min), max)\n\n/** The box moved by `dx, dy`, kept on the stage. */\nexport function moveBox(frame: BoxFrame, dx: number, dy: number): BoxFrame {\n return {\n ...frame,\n x: clamp(frame.x + dx, -frame.w / 2, 1 - frame.w / 2),\n y: clamp(frame.y + dy, -frame.h / 2, 1 - frame.h / 2),\n }\n}\n\n/** A box handle: a corner or a side's middle. */\nexport type BoxHandle = 'nw' | 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w'\n\n/** The box resized from `handle` by `dx, dy` (its shape is free; the opposite side stays put). */\nexport function stretchBox(frame: BoxFrame, handle: BoxHandle, dx: number, dy: number): BoxFrame {\n let { x, y, w, h } = frame\n if (handle.includes('w')) {\n const right = x + w\n x = Math.min(x + dx, right - MIN_BOX)\n w = right - x\n } else if (handle.includes('e')) {\n w = Math.max(MIN_BOX, w + dx)\n }\n if (handle.startsWith('n')) {\n const bottom = y + h\n y = Math.min(y + dy, bottom - MIN_BOX)\n h = bottom - y\n } else if (handle.startsWith('s')) {\n h = Math.max(MIN_BOX, h + dy)\n }\n return { x, y, w, h }\n}\n\nlet sequence = 0\nexport const nextBoxId = (): string => `box-${Date.now().toString(36)}-${++sequence}`\n\n/** A new box of `shape`, in the middle of the slide, ready to type in. */\nexport function newBox(shape: BoxShape, accent: string): SlideBox {\n const id = nextBoxId()\n if (shape === 'text') {\n return {\n id,\n shape,\n frame: { x: 0.3, y: 0.42, w: 0.4, h: 0.12 },\n paragraphs: [{ runs: [{ text: '', size: 24 }] }],\n front: true,\n }\n }\n if (shape === 'line') {\n return {\n id,\n shape,\n frame: { x: 0.35, y: 0.5, w: 0.3, h: 0 },\n line: { color: accent, width: 2 },\n paragraphs: [],\n front: true,\n }\n }\n return {\n id,\n shape,\n frame: { x: 0.35, y: 0.35, w: 0.3, h: 0.3 },\n fill: accent,\n paragraphs: [{ runs: [{ text: '', size: 20, color: '#ffffff' }], align: 'center' }],\n anchor: 'middle',\n front: false,\n }\n}\n"],
5
+ "mappings": ";AA0EO,MAAM,eAAe,EAAE,GAAG,KAAK,GAAG,IAAI;AACtC,MAAM,oBAAoB;AAC1B,MAAM,gBAAgB;AAEtB,MAAM,UAAU;AAGhB,MAAM,gBAAgB,CAAC,WAA2B,SAAS,aAAa;AAGxE,MAAM,UAAU,CAAC,QACtB,IAAI,WAAW,IAAI,CAAC,cAAc,UAAU,KAAK,IAAI,CAAC,QAAQ,IAAI,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,IAAI;AAMtF,SAAS,SAAS,KAAe,MAAwB;AAC9D,QAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,QAAM,WAAW,IAAI,WAAW,IAAI,WAAW,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,EAAE;AACrF,QAAM,aAAa,MAAM,IAAI,CAAC,MAAM,UAAU;AAC5C,UAAM,SAAS,IAAI,WAAW,KAAK,KAAK;AACxC,UAAM,EAAE,MAAM,MAAM,GAAG,MAAM,IAAI,OAAO,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG;AAC9D,SAAK;AACL,WAAO,EAAE,GAAG,QAAQ,MAAM,CAAC,EAAE,GAAG,OAAO,MAAM,KAAK,CAAC,EAAE;AAAA,EACvD,CAAC;AACD,SAAO,EAAE,GAAG,KAAK,WAAW;AAC9B;AAGO,SAAS,UAAU,KAAe,QAA6C;AACpF,SAAO;AAAA,IACL,GAAG;AAAA,IACH,YAAY,IAAI,WAAW,IAAI,CAAC,eAAe;AAAA,MAC7C,GAAG;AAAA,MACH,MAAM,UAAU,KAAK,IAAI,MAAM;AAAA,IACjC,EAAE;AAAA,EACJ;AACF;AAGO,MAAM,WAAW,CAAC,QACvB,IAAI,WAAW,KAAK,CAAC,cAAc,UAAU,KAAK,MAAM,GAAG,KAAK,CAAC;AAEnE,MAAM,QAAQ,CAAC,OAAe,KAAa,QACzC,MAAM,OAAO,MAAM,OAAO,IAAI,KAAK,IAAI,KAAK,IAAI,OAAO,GAAG,GAAG,GAAG;AAG3D,SAAS,QAAQ,OAAiB,IAAY,IAAsB;AACzE,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG,MAAM,MAAM,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG,IAAI,MAAM,IAAI,CAAC;AAAA,IACpD,GAAG,MAAM,MAAM,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG,IAAI,MAAM,IAAI,CAAC;AAAA,EACtD;AACF;AAMO,SAAS,WAAW,OAAiB,QAAmB,IAAY,IAAsB;AAC/F,MAAI,EAAE,GAAG,GAAG,GAAG,EAAE,IAAI;AACrB,MAAI,OAAO,SAAS,GAAG,GAAG;AACxB,UAAM,QAAQ,IAAI;AAClB,QAAI,KAAK,IAAI,IAAI,IAAI,QAAQ,OAAO;AACpC,QAAI,QAAQ;AAAA,EACd,WAAW,OAAO,SAAS,GAAG,GAAG;AAC/B,QAAI,KAAK,IAAI,SAAS,IAAI,EAAE;AAAA,EAC9B;AACA,MAAI,OAAO,WAAW,GAAG,GAAG;AAC1B,UAAM,SAAS,IAAI;AACnB,QAAI,KAAK,IAAI,IAAI,IAAI,SAAS,OAAO;AACrC,QAAI,SAAS;AAAA,EACf,WAAW,OAAO,WAAW,GAAG,GAAG;AACjC,QAAI,KAAK,IAAI,SAAS,IAAI,EAAE;AAAA,EAC9B;AACA,SAAO,EAAE,GAAG,GAAG,GAAG,EAAE;AACtB;AAEA,IAAI,WAAW;AACR,MAAM,YAAY,MAAc,OAAO,KAAK,IAAI,EAAE,SAAS,EAAE,CAAC,IAAI,EAAE,QAAQ;AAG5E,SAAS,OAAO,OAAiB,QAA0B;AAChE,QAAM,KAAK,UAAU;AACrB,MAAI,UAAU,QAAQ;AACpB,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,OAAO,EAAE,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK;AAAA,MAC1C,YAAY,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;AAAA,MAC/C,OAAO;AAAA,IACT;AAAA,EACF;AACA,MAAI,UAAU,QAAQ;AACpB,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,OAAO,EAAE,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,EAAE;AAAA,MACvC,MAAM,EAAE,OAAO,QAAQ,OAAO,EAAE;AAAA,MAChC,YAAY,CAAC;AAAA,MACb,OAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,OAAO,EAAE,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,IAAI;AAAA,IAC1C,MAAM;AAAA,IACN,YAAY,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,IAAI,MAAM,IAAI,OAAO,UAAU,CAAC,GAAG,OAAO,SAAS,CAAC;AAAA,IAClF,QAAQ;AAAA,IACR,OAAO;AAAA,EACT;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * A slide's text boxes and shapes drawn on a canvas, as the stage draws them (`StageBox`): for the
3
+ * saved PDF's pages. Text wraps by words across runs of different type.
4
+ */
5
+ import { type SlideBox } from './boxes';
6
+ export declare function drawBox(context: CanvasRenderingContext2D, box: SlideBox, width: number, height: number, themeFont: string): void;
7
+ /** The words a box shows, for a searchable PDF. */
8
+ export declare const boxWords: (box: SlideBox) => string[];
@@ -0,0 +1,130 @@
1
+ "use client";
2
+ import {
3
+ DEFAULT_INSET,
4
+ DEFAULT_TEXT_SIZE,
5
+ pointsToStage
6
+ } from "./boxes.js";
7
+ import { TEXT_COLORS } from "./theme.js";
8
+ const LINE_HEIGHT = 1.2;
9
+ function fontOf(run, themeFont, width) {
10
+ const size = pointsToStage(run.size ?? DEFAULT_TEXT_SIZE) * width;
11
+ const family = run.font ? `"${run.font}", ${themeFont}` : themeFont;
12
+ return `${run.italic ? "italic " : ""}${run.bold ? 700 : 400} ${size}px ${family}`;
13
+ }
14
+ function outline(context, box, w, h) {
15
+ context.beginPath();
16
+ if (box.shape === "ellipse") context.ellipse(w / 2, h / 2, w / 2, h / 2, 0, 0, Math.PI * 2);
17
+ else if (box.shape === "roundRect") context.roundRect(0, 0, w, h, Math.min(w, h) / 6);
18
+ else context.rect(0, 0, w, h);
19
+ }
20
+ function drawBox(context, box, width, height, themeFont) {
21
+ const { frame } = box;
22
+ const w = frame.w * width;
23
+ const h = frame.h * height;
24
+ context.save();
25
+ context.translate(frame.x * width + w / 2, frame.y * height + h / 2);
26
+ if (box.rotation) context.rotate(box.rotation * Math.PI / 180);
27
+ context.translate(-w / 2, -h / 2);
28
+ const lineWidth = box.line ? Math.max(1, pointsToStage(box.line.width) * width) : 0;
29
+ if (box.shape === "line") {
30
+ context.strokeStyle = box.line?.color ?? TEXT_COLORS.body;
31
+ context.lineWidth = lineWidth || 1;
32
+ if (box.line?.dash) context.setLineDash([lineWidth * 3, lineWidth * 2]);
33
+ context.beginPath();
34
+ context.moveTo(0, box.flipV ? h : 0);
35
+ context.lineTo(w, box.flipV ? 0 : h);
36
+ context.stroke();
37
+ context.restore();
38
+ return;
39
+ }
40
+ if (box.fill) {
41
+ context.globalAlpha = box.fillAlpha ?? 1;
42
+ context.fillStyle = box.fill;
43
+ outline(context, box, w, h);
44
+ context.fill();
45
+ context.globalAlpha = 1;
46
+ }
47
+ if (box.line && lineWidth) {
48
+ context.strokeStyle = box.line.color;
49
+ context.lineWidth = lineWidth;
50
+ if (box.line.dash) context.setLineDash([lineWidth * 3, lineWidth * 2]);
51
+ outline(context, box, w, h);
52
+ context.stroke();
53
+ context.setLineDash([]);
54
+ }
55
+ const inset = pointsToStage(box.inset ?? DEFAULT_INSET) * width;
56
+ const room = w - 2 * inset;
57
+ context.textBaseline = "alphabetic";
58
+ const lines = [];
59
+ for (const paragraph of box.paragraphs) {
60
+ const size = pointsToStage(paragraph.runs[0]?.size ?? DEFAULT_TEXT_SIZE) * width;
61
+ const indent = (paragraph.level ?? 0) * 0.5 * size + (paragraph.bullet ? size * 0.9 : 0);
62
+ const words = [];
63
+ for (const run of paragraph.runs) {
64
+ context.font = fontOf(run, themeFont, width);
65
+ for (const part of run.text.split(/(\s+)/).filter(Boolean)) {
66
+ words.push({ text: part, run, width: context.measureText(part).width });
67
+ }
68
+ }
69
+ let line = [];
70
+ let used = 0;
71
+ let first = true;
72
+ const flush = () => {
73
+ lines.push({
74
+ pieces: line,
75
+ size,
76
+ align: paragraph.align ?? "left",
77
+ indent,
78
+ ...first && paragraph.bullet ? { bullet: paragraph.runs[0] } : {}
79
+ });
80
+ first = false;
81
+ line = [];
82
+ used = 0;
83
+ };
84
+ for (const word of words) {
85
+ if (used + word.width > room - indent && line.length && word.text.trim()) flush();
86
+ if (!line.length && !word.text.trim()) continue;
87
+ line.push(word);
88
+ used += word.width;
89
+ }
90
+ flush();
91
+ }
92
+ const total = lines.reduce((sum, line) => sum + line.size * LINE_HEIGHT, 0);
93
+ const free = h - 2 * inset - total;
94
+ let y = inset + (box.anchor === "middle" ? free / 2 : box.anchor === "bottom" ? free : 0);
95
+ context.save();
96
+ context.beginPath();
97
+ context.rect(0, 0, w, h);
98
+ context.clip();
99
+ for (const line of lines) {
100
+ const lineWidth2 = line.pieces.reduce((sum, piece) => sum + piece.width, 0);
101
+ const space = room - line.indent;
102
+ let x = inset + line.indent + (line.align === "center" ? (space - lineWidth2) / 2 : line.align === "right" ? space - lineWidth2 : 0);
103
+ const baseline = y + line.size * (LINE_HEIGHT - 0.2);
104
+ if (line.bullet) {
105
+ context.font = fontOf(line.bullet, themeFont, width);
106
+ context.fillStyle = line.bullet.color ?? TEXT_COLORS.body;
107
+ context.fillText("\u2022", inset + line.indent - line.size * 0.9, baseline);
108
+ }
109
+ for (const piece of line.pieces) {
110
+ context.font = fontOf(piece.run, themeFont, width);
111
+ context.fillStyle = piece.run.color ?? TEXT_COLORS.body;
112
+ context.fillText(piece.text, x, baseline);
113
+ if (piece.run.underline) {
114
+ context.fillRect(x, baseline + line.size * 0.08, piece.width, Math.max(1, line.size * 0.05));
115
+ }
116
+ x += piece.width;
117
+ }
118
+ y += line.size * LINE_HEIGHT;
119
+ }
120
+ context.restore();
121
+ context.restore();
122
+ }
123
+ const boxWords = (box) => box.paragraphs.map(
124
+ (paragraph) => paragraph.runs.map((run) => run.text).join("").trim()
125
+ ).filter(Boolean);
126
+ export {
127
+ boxWords,
128
+ drawBox
129
+ };
130
+ //# sourceMappingURL=draw-boxes.js.map