@arbidocs/blocks 0.5.123 → 0.5.125

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 (192) hide show
  1. package/dist/{ClippingMediaViewer-IEIBT74X.cjs → ClippingMediaViewer-ZFEX5A3U.cjs} +11 -10
  2. package/dist/ClippingMediaViewer-ZFEX5A3U.cjs.map +1 -0
  3. package/dist/{ClippingPdfViewer-OGYLMVCE.cjs → ClippingPdfViewer-3LRTEPHV.cjs} +45 -11
  4. package/dist/ClippingPdfViewer-3LRTEPHV.cjs.map +1 -0
  5. package/dist/ConnectedCallDock-XJOYVVAH.cjs +6 -6
  6. package/dist/ConnectedCallRoom-CUDYAPQK.cjs +6 -6
  7. package/dist/{ConnectedNativeDocxComparison-QKHCYD6W.cjs → ConnectedNativeDocxComparison-7QQ55JIO.cjs} +13 -13
  8. package/dist/{ConnectedNativeDocxComparison-QKHCYD6W.cjs.map → ConnectedNativeDocxComparison-7QQ55JIO.cjs.map} +1 -1
  9. package/dist/{ConnectedPresentation-5DOJ35XL.cjs → ConnectedPresentation-L32JPRFI.cjs} +30 -156
  10. package/dist/ConnectedPresentation-L32JPRFI.cjs.map +1 -0
  11. package/dist/{ConnectedProductionSetDialog-LHB4VQWC.cjs → ConnectedProductionSetDialog-4EAY6KAZ.cjs} +3 -3
  12. package/dist/{ConnectedProductionSetDialog-LHB4VQWC.cjs.map → ConnectedProductionSetDialog-4EAY6KAZ.cjs.map} +1 -1
  13. package/dist/{ConnectedSlidesTab-7YMEDGUU.cjs → ConnectedSlidesTab-P7GGNUTO.cjs} +31 -29
  14. package/dist/ConnectedSlidesTab-P7GGNUTO.cjs.map +1 -0
  15. package/dist/{ConnectedStreamedWordArtifact-AG62232A.cjs → ConnectedStreamedWordArtifact-7NJ3N52V.cjs} +13 -13
  16. package/dist/{ConnectedStreamedWordArtifact-AG62232A.cjs.map → ConnectedStreamedWordArtifact-7NJ3N52V.cjs.map} +1 -1
  17. package/dist/{DocumentReviewCard-M53XFLI2.cjs → DocumentReviewCard-BFPOFQXI.cjs} +16 -16
  18. package/dist/{DocumentReviewCard-M53XFLI2.cjs.map → DocumentReviewCard-BFPOFQXI.cjs.map} +1 -1
  19. package/dist/{FilesViewerDialog-2QCCRWF2.cjs → FilesViewerDialog-MHUVEZ7M.cjs} +35 -32
  20. package/dist/FilesViewerDialog-MHUVEZ7M.cjs.map +1 -0
  21. package/dist/{NativeDocxEditor-2LQY2CTV.cjs → NativeDocxEditor-SIRYPMBN.cjs} +6 -6
  22. package/dist/{NativeDocxEditor-2LQY2CTV.cjs.map → NativeDocxEditor-SIRYPMBN.cjs.map} +1 -1
  23. package/dist/SpotlightStrip-ED22UYTM.cjs +398 -0
  24. package/dist/SpotlightStrip-ED22UYTM.cjs.map +1 -0
  25. package/dist/{WorkspaceTableView-3XYAV4BV.cjs → WorkspaceTableView-MIFYXV3G.cjs} +8 -8
  26. package/dist/{WorkspaceTableView-3XYAV4BV.cjs.map → WorkspaceTableView-MIFYXV3G.cjs.map} +1 -1
  27. package/dist/agents/index.cjs +216 -216
  28. package/dist/ai-IEIR7SC2.cjs +3 -3
  29. package/dist/auth/index.cjs +1 -1
  30. package/dist/calls/index.cjs +2 -2
  31. package/dist/chat/index.cjs +6 -6
  32. package/dist/{chunk-GNZAH6UI.cjs → chunk-2K6IMIVL.cjs} +3 -3
  33. package/dist/{chunk-GNZAH6UI.cjs.map → chunk-2K6IMIVL.cjs.map} +1 -1
  34. package/dist/{chunk-NQML7IUC.cjs → chunk-3UP32FM3.cjs} +6 -6
  35. package/dist/{chunk-NQML7IUC.cjs.map → chunk-3UP32FM3.cjs.map} +1 -1
  36. package/dist/chunk-3ZZZO4F7.cjs +145 -0
  37. package/dist/chunk-3ZZZO4F7.cjs.map +1 -0
  38. package/dist/{chunk-L4CIFLCU.cjs → chunk-4LP5MJGQ.cjs} +4 -4
  39. package/dist/{chunk-L4CIFLCU.cjs.map → chunk-4LP5MJGQ.cjs.map} +1 -1
  40. package/dist/{chunk-JD2HX2BR.cjs → chunk-6JMW3IJ2.cjs} +152 -155
  41. package/dist/chunk-6JMW3IJ2.cjs.map +1 -0
  42. package/dist/{chunk-WV7BCGCK.cjs → chunk-7RJZIPLE.cjs} +33 -33
  43. package/dist/{chunk-WV7BCGCK.cjs.map → chunk-7RJZIPLE.cjs.map} +1 -1
  44. package/dist/{chunk-WFMWKPGY.cjs → chunk-ADPRIBSH.cjs} +9 -33
  45. package/dist/chunk-ADPRIBSH.cjs.map +1 -0
  46. package/dist/{chunk-7NLO7ASW.cjs → chunk-AISYXX4M.cjs} +4 -4
  47. package/dist/{chunk-7NLO7ASW.cjs.map → chunk-AISYXX4M.cjs.map} +1 -1
  48. package/dist/{chunk-5QERK4PK.cjs → chunk-AS6QZETU.cjs} +35 -35
  49. package/dist/{chunk-5QERK4PK.cjs.map → chunk-AS6QZETU.cjs.map} +1 -1
  50. package/dist/{chunk-V6MW7B4B.cjs → chunk-B3R62764.cjs} +6 -6
  51. package/dist/{chunk-V6MW7B4B.cjs.map → chunk-B3R62764.cjs.map} +1 -1
  52. package/dist/{chunk-VKH3BEZE.cjs → chunk-BLIO3B7Z.cjs} +3 -3
  53. package/dist/{chunk-VKH3BEZE.cjs.map → chunk-BLIO3B7Z.cjs.map} +1 -1
  54. package/dist/{chunk-46P7IDBX.cjs → chunk-CQ2RJYE2.cjs} +4 -4
  55. package/dist/chunk-CQ2RJYE2.cjs.map +1 -0
  56. package/dist/{chunk-MXBXZXXQ.cjs → chunk-ENOPKX7E.cjs} +3 -3
  57. package/dist/{chunk-MXBXZXXQ.cjs.map → chunk-ENOPKX7E.cjs.map} +1 -1
  58. package/dist/{chunk-2CSLFAGF.cjs → chunk-GAMRVB3I.cjs} +4 -3
  59. package/dist/chunk-GAMRVB3I.cjs.map +1 -0
  60. package/dist/chunk-IRGRMJPP.cjs +18 -0
  61. package/dist/{chunk-SDRYSLOX.cjs.map → chunk-IRGRMJPP.cjs.map} +1 -1
  62. package/dist/{chunk-ADDQKZ5I.cjs → chunk-J3FFSEKO.cjs} +4 -4
  63. package/dist/{chunk-ADDQKZ5I.cjs.map → chunk-J3FFSEKO.cjs.map} +1 -1
  64. package/dist/chunk-JITYC4OS.cjs +66 -0
  65. package/dist/chunk-JITYC4OS.cjs.map +1 -0
  66. package/dist/chunk-JY7UUZQG.cjs +1513 -0
  67. package/dist/chunk-JY7UUZQG.cjs.map +1 -0
  68. package/dist/{chunk-ALK3PUUB.cjs → chunk-L6HTZIBD.cjs} +3 -3
  69. package/dist/{chunk-ALK3PUUB.cjs.map → chunk-L6HTZIBD.cjs.map} +1 -1
  70. package/dist/chunk-MVXHTAJ4.cjs +111 -0
  71. package/dist/chunk-MVXHTAJ4.cjs.map +1 -0
  72. package/dist/{chunk-OHHKBURG.cjs → chunk-OGK377NL.cjs} +33 -33
  73. package/dist/{chunk-OHHKBURG.cjs.map → chunk-OGK377NL.cjs.map} +1 -1
  74. package/dist/{chunk-T73BHNQX.cjs → chunk-OHWHYVKG.cjs} +3 -3
  75. package/dist/{chunk-T73BHNQX.cjs.map → chunk-OHWHYVKG.cjs.map} +1 -1
  76. package/dist/{chunk-4TTX6ZNS.cjs → chunk-ORNLCBNE.cjs} +24 -2
  77. package/dist/chunk-ORNLCBNE.cjs.map +1 -0
  78. package/dist/{chunk-MLA2BJ2Y.cjs → chunk-PSB64T43.cjs} +28 -28
  79. package/dist/{chunk-MLA2BJ2Y.cjs.map → chunk-PSB64T43.cjs.map} +1 -1
  80. package/dist/{chunk-COD5ENHK.cjs → chunk-PVJ5ODDB.cjs} +4 -4
  81. package/dist/{chunk-COD5ENHK.cjs.map → chunk-PVJ5ODDB.cjs.map} +1 -1
  82. package/dist/{chunk-7557LDAN.cjs → chunk-PWBRE7JA.cjs} +5 -5
  83. package/dist/{chunk-7557LDAN.cjs.map → chunk-PWBRE7JA.cjs.map} +1 -1
  84. package/dist/{chunk-7PN3YENO.cjs → chunk-QIK7E6VF.cjs} +4 -4
  85. package/dist/{chunk-7PN3YENO.cjs.map → chunk-QIK7E6VF.cjs.map} +1 -1
  86. package/dist/{chunk-DWMWEALB.cjs → chunk-TSFNLY3K.cjs} +143 -1634
  87. package/dist/chunk-TSFNLY3K.cjs.map +1 -0
  88. package/dist/{chunk-YGBHY67W.cjs → chunk-UA7HOLAZ.cjs} +5 -5
  89. package/dist/{chunk-YGBHY67W.cjs.map → chunk-UA7HOLAZ.cjs.map} +1 -1
  90. package/dist/{chunk-KXIRVKCJ.cjs → chunk-UUENH4BJ.cjs} +3 -3
  91. package/dist/{chunk-KXIRVKCJ.cjs.map → chunk-UUENH4BJ.cjs.map} +1 -1
  92. package/dist/chunk-WVZLAAIZ.cjs +31 -0
  93. package/dist/chunk-WVZLAAIZ.cjs.map +1 -0
  94. package/dist/{chunk-E3L5DB5F.cjs → chunk-YOEP3I4V.cjs} +5 -5
  95. package/dist/{chunk-E3L5DB5F.cjs.map → chunk-YOEP3I4V.cjs.map} +1 -1
  96. package/dist/{chunk-SNPK3R3O.cjs → chunk-YVO6Z5BS.cjs} +10 -10
  97. package/dist/{chunk-SNPK3R3O.cjs.map → chunk-YVO6Z5BS.cjs.map} +1 -1
  98. package/dist/chunk-ZZZITHGK.cjs +119 -0
  99. package/dist/chunk-ZZZITHGK.cjs.map +1 -0
  100. package/dist/connect/docx.cjs +17 -17
  101. package/dist/connect/index.cjs +994 -994
  102. package/dist/connect/viewer.cjs +28 -25
  103. package/dist/connection/presentation/ClippingMediaViewer.js +3 -3
  104. package/dist/connection/presentation/ClippingMediaViewer.js.map +2 -2
  105. package/dist/connection/presentation/ClippingPdfViewer.d.ts +4 -3
  106. package/dist/connection/presentation/ClippingPdfViewer.js +48 -9
  107. package/dist/connection/presentation/ClippingPdfViewer.js.map +2 -2
  108. package/dist/connection/presentation/SpotlightLayer.d.ts +5 -0
  109. package/dist/connection/presentation/SpotlightLayer.js +19 -0
  110. package/dist/connection/presentation/SpotlightLayer.js.map +7 -0
  111. package/dist/connection/presentation/SpotlightStrip.d.ts +10 -0
  112. package/dist/connection/presentation/SpotlightStrip.js +237 -0
  113. package/dist/connection/presentation/SpotlightStrip.js.map +7 -0
  114. package/dist/connection/presentation/useViewerClipping.d.ts +4 -3
  115. package/dist/connection/presentation/useViewerClipping.js +8 -4
  116. package/dist/connection/presentation/useViewerClipping.js.map +2 -2
  117. package/dist/connection/viewer/ConnectedDocumentViewer.js +1 -1
  118. package/dist/connection/viewer/ConnectedDocumentViewer.js.map +2 -2
  119. package/dist/connection/viewer/VersionDropdown.js +1 -1
  120. package/dist/connection/viewer/VersionDropdown.js.map +1 -1
  121. package/dist/connection/viewer/ViewerPdfPane.js +2 -0
  122. package/dist/connection/viewer/ViewerPdfPane.js.map +2 -2
  123. package/dist/connection/viewer/pdf/passageHighlights.d.ts +5 -0
  124. package/dist/connection/viewer/pdf/passageHighlights.js +14 -1
  125. package/dist/connection/viewer/pdf/passageHighlights.js.map +2 -2
  126. package/dist/connection/viewer/pdf/usePassageTextFallback.d.ts +12 -0
  127. package/dist/connection/viewer/pdf/usePassageTextFallback.js +30 -0
  128. package/dist/connection/viewer/pdf/usePassageTextFallback.js.map +7 -0
  129. package/dist/connection/viewer/pdf/usePdfPassageHighlights.js +2 -11
  130. package/dist/connection/viewer/pdf/usePdfPassageHighlights.js.map +2 -2
  131. package/dist/connection/viewer/useCleanView.d.ts +3 -1
  132. package/dist/connection/viewer/useCleanView.js +6 -3
  133. package/dist/connection/viewer/useCleanView.js.map +2 -2
  134. package/dist/connection/viewer/useViewerTabs.js +13 -1
  135. package/dist/connection/viewer/useViewerTabs.js.map +2 -2
  136. package/dist/document-tools/DocumentToolButtons.js +1 -1
  137. package/dist/document-tools/DocumentToolButtons.js.map +1 -1
  138. package/dist/document-tools/index.cjs +20 -20
  139. package/dist/docx/DocxCommandMenu.js +2 -1
  140. package/dist/docx/DocxCommandMenu.js.map +2 -2
  141. package/dist/docx/index.cjs +38 -38
  142. package/dist/embed/index.cjs +20 -20
  143. package/dist/facts/index.cjs +64 -64
  144. package/dist/files/index.cjs +223 -223
  145. package/dist/index.cjs +521 -521
  146. package/dist/presentation/ClipCaptureOverlay.d.ts +7 -3
  147. package/dist/presentation/ClipCaptureOverlay.js +43 -14
  148. package/dist/presentation/ClipCaptureOverlay.js.map +2 -2
  149. package/dist/presentation/PresentControls.d.ts +8 -0
  150. package/dist/presentation/PresentControls.js +1 -0
  151. package/dist/presentation/PresentControls.js.map +2 -2
  152. package/dist/presentation/PresentationStage.d.ts +10 -2
  153. package/dist/presentation/PresentationStage.js +6 -3
  154. package/dist/presentation/PresentationStage.js.map +2 -2
  155. package/dist/presentation/PresenterView.js +1 -22
  156. package/dist/presentation/PresenterView.js.map +2 -2
  157. package/dist/presentation/SpotlightView.d.ts +19 -0
  158. package/dist/presentation/SpotlightView.js +180 -0
  159. package/dist/presentation/SpotlightView.js.map +7 -0
  160. package/dist/presentation/passage-clip.d.ts +17 -0
  161. package/dist/presentation/passage-clip.js +25 -0
  162. package/dist/presentation/passage-clip.js.map +7 -0
  163. package/dist/presentation/spotlight.d.ts +58 -0
  164. package/dist/presentation/spotlight.js +110 -0
  165. package/dist/presentation/spotlight.js.map +7 -0
  166. package/dist/presentation/store.d.ts +5 -0
  167. package/dist/presentation/store.js +19 -0
  168. package/dist/presentation/store.js.map +2 -2
  169. package/dist/presentation/usePointerActive.d.ts +2 -0
  170. package/dist/presentation/usePointerActive.js +28 -0
  171. package/dist/presentation/usePointerActive.js.map +7 -0
  172. package/dist/settings/index.cjs +146 -146
  173. package/dist/site/index.cjs +6 -6
  174. package/dist/studio/index.cjs +9 -9
  175. package/dist/styles.css +1 -1
  176. package/dist/workflow-canvas/index.cjs +35 -35
  177. package/node_modules/@arbidocs/coedit/package.json +1 -1
  178. package/package.json +5 -5
  179. package/dist/ClippingMediaViewer-IEIBT74X.cjs.map +0 -1
  180. package/dist/ClippingPdfViewer-OGYLMVCE.cjs.map +0 -1
  181. package/dist/ConnectedPresentation-5DOJ35XL.cjs.map +0 -1
  182. package/dist/ConnectedSlidesTab-7YMEDGUU.cjs.map +0 -1
  183. package/dist/FilesViewerDialog-2QCCRWF2.cjs.map +0 -1
  184. package/dist/chunk-2CSLFAGF.cjs.map +0 -1
  185. package/dist/chunk-46P7IDBX.cjs.map +0 -1
  186. package/dist/chunk-4TTX6ZNS.cjs.map +0 -1
  187. package/dist/chunk-DWMWEALB.cjs.map +0 -1
  188. package/dist/chunk-JD2HX2BR.cjs.map +0 -1
  189. package/dist/chunk-SDRYSLOX.cjs +0 -18
  190. package/dist/chunk-WFMWKPGY.cjs.map +0 -1
  191. package/dist/chunk-XK4TVJKD.cjs +0 -73
  192. package/dist/chunk-XK4TVJKD.cjs.map +0 -1
@@ -1272,6 +1272,25 @@ var usePresentation = zustand.create()((set, get) => {
1272
1272
  ...adopted.filter((clip) => !state.clips.some((entry) => entry.id === clip.id))
1273
1273
  ]
1274
1274
  })),
1275
+ addSlideOf: (added, caption = "") => set((state) => {
1276
+ const fresh = added.map((clip) => ({ ...clip, id: nextId("clip") }));
1277
+ const clips = [...state.clips, ...fresh];
1278
+ const slide = arranged(
1279
+ {
1280
+ ...emptySlide("clips"),
1281
+ caption,
1282
+ items: fresh.map((clip) => ({ clipId: clip.id, frame: fitFrame(clip.aspect) }))
1283
+ },
1284
+ clips,
1285
+ state
1286
+ );
1287
+ const here = state.slides[state.current];
1288
+ const empty = !!here && !here.items.length && !here.boxes.length && !here.caption.trim() && !here.points.trim();
1289
+ const at = empty ? state.current : state.current + 1;
1290
+ const slides = state.slides.slice();
1291
+ slides.splice(at, empty ? 1 : 0, slide);
1292
+ return { clips, slides, current: at };
1293
+ }),
1275
1294
  load(opened) {
1276
1295
  get().reset();
1277
1296
  const clips = opened.clips.map((clip) => ({ ...clip, id: nextId("clip") }));
@@ -1338,11 +1357,13 @@ exports.STAGE_MARGIN = STAGE_MARGIN;
1338
1357
  exports.TEMPLATES_FOLDER = TEMPLATES_FOLDER;
1339
1358
  exports.TEXT_COLORS = TEXT_COLORS;
1340
1359
  exports.accentColor = accentColor;
1360
+ exports.autoLayout = autoLayout;
1341
1361
  exports.backgroundCss = backgroundCss;
1342
1362
  exports.boxText = boxText;
1343
1363
  exports.clipEdgeCss = clipEdgeCss;
1344
1364
  exports.clipLabel = clipLabel;
1345
1365
  exports.currentSlide = currentSlide;
1366
+ exports.defaultCaption = defaultCaption;
1346
1367
  exports.firstRun = firstRun;
1347
1368
  exports.formatTime = formatTime;
1348
1369
  exports.frameHeight = frameHeight;
@@ -1360,6 +1381,7 @@ exports.parsePresentation = parsePresentation;
1360
1381
  exports.pointsToStage = pointsToStage;
1361
1382
  exports.presentationFileName = presentationFileName;
1362
1383
  exports.presentationTitle = presentationTitle;
1384
+ exports.reserveOf = reserveOf;
1363
1385
  exports.reshapeFrame = reshapeFrame;
1364
1386
  exports.resizeFrame = resizeFrame;
1365
1387
  exports.safeFileStem = safeFileStem;
@@ -1370,5 +1392,5 @@ exports.stretchBox = stretchBox;
1370
1392
  exports.styleRuns = styleRuns;
1371
1393
  exports.textLines = textLines;
1372
1394
  exports.usePresentation = usePresentation;
1373
- //# sourceMappingURL=chunk-4TTX6ZNS.cjs.map
1374
- //# sourceMappingURL=chunk-4TTX6ZNS.cjs.map
1395
+ //# sourceMappingURL=chunk-ORNLCBNE.cjs.map
1396
+ //# sourceMappingURL=chunk-ORNLCBNE.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/presentation/model.ts","../src/presentation/slide-layout.ts","../src/presentation/theme.ts","../src/presentation/saved-boxes.ts","../src/presentation/persistence.ts","../src/presentation/boxes.ts","../src/presentation/store.ts"],"names":["title","color","HEX","PRESENTATION_FILE_SUFFIX","LEGACY_PRESENTATION_SUFFIX","clamp","sequence","create","slide","releasePdfRegionSource"],"mappings":"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","file":"chunk-ORNLCBNE.cjs","sourcesContent":["/**\n * A presentation: clips (a rectangle of a PDF page) arranged on 16:9 slides, shown on a stage that\n * can be shared or projected. A clip is a reference to its source (document, version, page,\n * rectangle), never a picture of it: it is drawn again from the PDF at whatever size it is shown,\n * and a later \"save as PDF\" can embed the same region as vector content.\n *\n * Layout is pure: a frame is the clip's place on the slide as fractions of the stage, and its\n * height always follows from the clip's own aspect, so a clip is never stretched.\n */\n\nimport type { SlideBackground, SlideBox } from './boxes'\n\n/** Fractions of a page or of the stage, origin top-left. */\nexport interface Rect {\n x: number\n y: number\n w: number\n h: number\n}\n\n/**\n * What a clip is cut from: a PDF page (drawn again from the PDF at the size shown), an image or a\n * video (the original file shown cropped, so at its own resolution; a video plays on the stage).\n */\nexport type ClipKind = 'pdf' | 'image' | 'video'\n\nexport interface Clip {\n id: string\n kind: ClipKind\n documentId: string\n /** The version clipped; absent = the current version when it was clipped. */\n version?: number\n fileName: string\n /** 1-based page number (1 for an image or a video). */\n page: number\n /** The clipped area, as fractions of the displayed page, image or video frame. */\n rect: Rect\n /** Width / height of the clipped area as displayed. */\n aspect: number\n caption: string\n /** Redactions over the clipped area (page fractions), painted black wherever it shows. */\n masks: Rect[]\n /** The file the clip is cut from (this session only; never stored). */\n source: Blob\n /**\n * The clip's width (a fraction of its source) when it was cut, so its zoom reads against that\n * (100%); absent = its width now.\n */\n zoomBase?: number\n /** A video clip starts playing here (seconds). */\n start?: number\n /**\n * An image embedded in the presentation itself (a key of its media), not a document: a picture\n * of a deck imported from PowerPoint. Its `documentId` is empty.\n */\n media?: string\n /**\n * Drawn as it is: no rounded corners, soft edge, shadow or source label (a picture that is part\n * of a slide's design, or a part of an imported slide shown as it was).\n */\n plain?: boolean\n}\n\n/** A clip's place on a slide: its left, top and width as fractions of the stage. */\nexport interface Frame {\n x: number\n y: number\n w: number\n}\n\nexport interface SlideItem {\n clipId: string\n frame: Frame\n}\n\nexport interface Slide {\n id: string\n items: SlideItem[]\n /** Arranged automatically (fit to the stage) until an item is moved by hand. */\n auto: boolean\n /** Shown across the top of the slide (e.g. \"Claims and defences\"); empty for none. */\n caption: string\n /** Where its title, text and clips go (`slide-layout`). */\n layout: SlideLayout\n /** Its text: one point per line (the subtitle on a title or section slide); empty for none. */\n points: string\n /** Its text boxes and shapes (`boxes`), in drawing order. */\n boxes: SlideBox[]\n /** Its own background, over the theme's (an imported slide's). */\n background?: SlideBackground\n /** What the presenter says (speaker notes: not shown on the slide). */\n notes?: string\n}\n\n/**\n * A slide's layout: a title slide, a section break, clips under a title, clips beside points, or\n * two clips side by side; or blank (`free`): only what is placed on it, its text in boxes (a slide\n * imported from PowerPoint).\n */\nexport type SlideLayout = 'title' | 'section' | 'clips' | 'points' | 'compare' | 'free'\n\nexport const SLIDE_LAYOUTS: readonly SlideLayout[] = [\n 'clips',\n 'points',\n 'compare',\n 'title',\n 'section',\n 'free',\n]\n\n/** The stage is 16:9, the shape of a shared screen or a projector. */\nexport const STAGE_ASPECT = 16 / 9\n/** Space kept clear around the edge of the stage, and between auto-arranged clips. */\nexport const STAGE_MARGIN = 0.03\nexport const STAGE_GAP = 0.02\n/** The smallest a clip can be resized to (fraction of the stage width). */\nexport const MIN_FRAME_WIDTH = 0.05\n/** How close (fraction of the stage) an edge or centre must come to snap. */\nexport const SNAP_DISTANCE = 0.012\n/**\n * Room kept under a clip for its source label (document · page), as a fraction of the stage\n * height, while labels show: it sits below the clip, never over it, so it hides nothing.\n */\nexport const CAPTION_SPACE = 0.06\n/** Room kept across the top of a slide for its caption, when it has one (stage height). */\nexport const SLIDE_CAPTION_SPACE = 0.1\n\n/**\n * Room an arrangement keeps free: above the clips and under each clip (stage height), at the right\n * (stage width, e.g. a slide's points) and at the bottom (the footer); `columns` fixes the grid's\n * columns (two clips side by side).\n */\nexport interface Reserve {\n top: number\n below: number\n right?: number\n bottom?: number\n columns?: number\n /** More room on both sides, beyond the stage margin (clips line up with a slide's text). */\n inset?: number\n}\nexport const NO_RESERVE: Reserve = { top: 0, below: 0 }\n\n/** The frame's height as a fraction of the stage height. */\nexport function frameHeight(frame: Pick<Frame, 'w'>, aspect: number): number {\n return (frame.w * STAGE_ASPECT) / aspect\n}\n\n/** The widest a clip can be inside a `width × height` box (stage fractions). */\nfunction containWidth(aspect: number, width: number, height: number): number {\n return Math.max(0, Math.min(width, (height * aspect) / STAGE_ASPECT))\n}\n\n/**\n * Clips arranged to fill the stage: every grid of columns × rows is tried and the one where the\n * clips are largest wins (two wide clips stack, two tall ones go side by side). Each clip is\n * centred in its cell; a last, shorter row is centred too. `reserve` keeps a band free above the\n * clips (the slide's caption) and room under each clip (its source label).\n */\nexport function autoLayout(aspects: readonly number[], reserve: Reserve = NO_RESERVE): Frame[] {\n const n = aspects.length\n if (n === 0) return []\n const { top, below, right = 0, bottom = 0, columns, inset = 0 } = reserve\n const left = STAGE_MARGIN + inset\n const innerW = 1 - 2 * left - right\n const innerH = 1 - 2 * STAGE_MARGIN - top - bottom\n let best: { frames: Frame[]; area: number } | null = null\n const fixed = columns ? Math.min(columns, n) : 0\n for (let cols = fixed || 1; cols <= (fixed || n); cols++) {\n const rows = Math.ceil(n / cols)\n const cellW = (innerW - (cols - 1) * STAGE_GAP) / cols\n const cellH = (innerH - (rows - 1) * STAGE_GAP) / rows\n if (cellW <= 0 || cellH <= below) continue\n const frames: Frame[] = []\n let area = 0\n for (let i = 0; i < n; i++) {\n const row = Math.floor(i / cols)\n const inRow = row === rows - 1 ? n - row * cols : cols\n const col = i - row * cols\n const rowStart = left + ((cols - inRow) * (cellW + STAGE_GAP)) / 2\n const w = containWidth(aspects[i], cellW, cellH - below)\n const h = frameHeight({ w }, aspects[i])\n frames.push({\n x: rowStart + col * (cellW + STAGE_GAP) + (cellW - w) / 2,\n y: STAGE_MARGIN + top + row * (cellH + STAGE_GAP) + (cellH - h - below) / 2,\n w,\n })\n area += w * h\n }\n // Strictly larger wins, so ties keep fewer columns.\n if (!best || area > best.area + 1e-9) best = { frames, area }\n }\n return best?.frames ?? []\n}\n\n/** As large as the stage allows, centred (keeping `reserve` free). */\nexport function fitFrame(aspect: number, reserve: Reserve = NO_RESERVE): Frame {\n return autoLayout([aspect], reserve)[0]\n}\n\n/** The full width of the stage (inside the margin), centred on the frame's own height. */\nexport function fullWidthFrame(frame: Frame, aspect: number, reserve: Reserve = NO_RESERVE): Frame {\n const { top, below, right = 0, bottom = 0, inset = 0 } = reserve\n const w = 1 - 2 * (STAGE_MARGIN + inset) - right\n const h = frameHeight({ w }, aspect)\n // Too tall to be full width: as large as fits instead.\n if (h + below > 1 - 2 * STAGE_MARGIN - top - bottom) return fitFrame(aspect, reserve)\n const centre = frame.y + frameHeight(frame, aspect) / 2\n return {\n x: STAGE_MARGIN + inset,\n y: clamp(centre - h / 2, STAGE_MARGIN + top, 1 - STAGE_MARGIN - h - below - bottom),\n w,\n }\n}\n\n/** The full height of the stage (inside the margin), centred on the frame's own centre. */\nexport function fullHeightFrame(\n frame: Frame,\n aspect: number,\n reserve: Reserve = NO_RESERVE\n): Frame {\n const { top, below, right = 0, bottom = 0 } = reserve\n const inner = 1 - 2 * STAGE_MARGIN\n const w = ((inner - top - below - bottom) * aspect) / STAGE_ASPECT\n if (w > inner - right) return fitFrame(aspect, reserve)\n const centre = frame.x + frame.w / 2\n return {\n x: clamp(centre - w / 2, STAGE_MARGIN, 1 - STAGE_MARGIN - right - w),\n y: STAGE_MARGIN + top,\n w,\n }\n}\n\nfunction clamp(value: number, min: number, max: number): number {\n return max < min ? (min + max) / 2 : Math.min(Math.max(value, min), max)\n}\n\n/** A clip on the slide (the others a moving clip snaps to). */\nexport interface Placed {\n frame: Frame\n aspect: number\n}\n\n/** A line a clip snapped to, drawn while it is dragged: `at` is a stage fraction on `axis`. */\nexport interface Guide {\n axis: 'x' | 'y'\n at: number\n}\n\n/** The snap distance across the stage height: the same on screen as SNAP_DISTANCE across. */\nconst SNAP_DISTANCE_Y = SNAP_DISTANCE * STAGE_ASPECT\n\n/**\n * What a clip's edges and centre snap to on one axis: the stage's edges, margins and centre line,\n * and the edges and centres of the other clips on the slide.\n */\nfunction snapTargets(axis: Guide['axis'], others: readonly Placed[]): number[] {\n const targets = [0, STAGE_MARGIN, 0.5, 1 - STAGE_MARGIN, 1]\n for (const { frame, aspect } of others) {\n const start = axis === 'x' ? frame.x : frame.y\n const size = axis === 'x' ? frame.w : frameHeight(frame, aspect)\n targets.push(start, start + size / 2, start + size)\n }\n return targets\n}\n\n/** The nearest snap for a span `start … start + size` on an axis (its edges or centre), if any. */\nfunction snapSpan(\n start: number,\n size: number,\n targets: readonly number[],\n distance: number\n): { start: number; at: number } | null {\n let best: { start: number; at: number } | null = null\n let bestDistance = distance\n for (const target of targets) {\n for (const offset of [0, size / 2, size]) {\n const d = Math.abs(start + offset - target)\n if (d < bestDistance) {\n bestDistance = d\n best = { start: target - offset, at: target }\n }\n }\n }\n return best\n}\n\n/**\n * The frame moved by `dx, dy` (stage fractions) and kept on the stage. Unless `free`, its edges\n * and centre snap to the stage's lines and to the other clips', and the lines snapped to are\n * returned as guides.\n */\nexport function moveFrame(\n frame: Frame,\n aspect: number,\n dx: number,\n dy: number,\n others: readonly Placed[] = [],\n free = false\n): { frame: Frame; guides: Guide[] } {\n const h = frameHeight(frame, aspect)\n let x = frame.x + dx\n let y = frame.y + dy\n const guides: Guide[] = []\n if (!free) {\n const sx = snapSpan(x, frame.w, snapTargets('x', others), SNAP_DISTANCE)\n const sy = snapSpan(y, h, snapTargets('y', others), SNAP_DISTANCE_Y)\n if (sx) {\n x = sx.start\n guides.push({ axis: 'x', at: sx.at })\n }\n if (sy) {\n y = sy.start\n guides.push({ axis: 'y', at: sy.at })\n }\n }\n return { frame: { x: clamp(x, 0, 1 - frame.w), y: clamp(y, 0, 1 - h), w: frame.w }, guides }\n}\n\n/** A corner a clip is resized from. */\nexport type Corner = 'nw' | 'ne' | 'sw' | 'se'\n\n/**\n * The frame resized by dragging `corner` by `dx, dy`: the opposite corner stays put, the aspect is\n * kept and the clip stays on the stage. Unless `free`, the moving edges snap like a move does.\n */\nexport function resizeFrame(\n frame: Frame,\n aspect: number,\n corner: Corner,\n dx: number,\n dy: number,\n others: readonly Placed[] = [],\n free = false\n): { frame: Frame; guides: Guide[] } {\n const h0 = frameHeight(frame, aspect)\n const west = corner === 'nw' || corner === 'sw'\n const north = corner === 'nw' || corner === 'ne'\n // The corner that stays put, and where the dragged one is now.\n const anchorX = west ? frame.x + frame.w : frame.x\n const anchorY = north ? frame.y + h0 : frame.y\n const pointerX = (west ? frame.x : frame.x + frame.w) + dx\n const pointerY = (north ? frame.y : frame.y + h0) + dy\n const widthOfHeight = (height: number) => (height * aspect) / STAGE_ASPECT\n // Follow whichever of the two directions the pointer has gone further in.\n let w = Math.max(Math.abs(pointerX - anchorX), widthOfHeight(Math.abs(pointerY - anchorY)))\n const guides: Guide[] = []\n if (!free) {\n const edgeX = west ? anchorX - w : anchorX + w\n const edgeY = north\n ? anchorY - frameHeight({ w }, aspect)\n : anchorY + frameHeight({ w }, aspect)\n const sx = snapSpan(edgeX, 0, snapTargets('x', others), SNAP_DISTANCE)\n const sy = snapSpan(edgeY, 0, snapTargets('y', others), SNAP_DISTANCE_Y)\n // The nearer snap wins (distances compared on screen); the other edge follows the aspect.\n const dxSnap = sx ? Math.abs(sx.at - edgeX) : Infinity\n const dySnap = sy ? Math.abs(sy.at - edgeY) / STAGE_ASPECT : Infinity\n if (sx && dxSnap <= dySnap) {\n w = Math.abs(sx.at - anchorX)\n guides.push({ axis: 'x', at: sx.at })\n } else if (sy) {\n w = widthOfHeight(Math.abs(sy.at - anchorY))\n guides.push({ axis: 'y', at: sy.at })\n }\n }\n // As large as the stage allows on the dragged side.\n const maxW = Math.min(west ? anchorX : 1 - anchorX, widthOfHeight(north ? anchorY : 1 - anchorY))\n w = clamp(w, Math.min(MIN_FRAME_WIDTH, maxW), maxW)\n const h = frameHeight({ w }, aspect)\n return { frame: { x: west ? anchorX - w : anchorX, y: north ? anchorY - h : anchorY, w }, guides }\n}\n\n/** An edge a clip is reshaped from. */\nexport type Edge = 'n' | 'e' | 's' | 'w'\n\n/** The least of its source a clip shows, each way (a fraction of the page, image or frame). */\nconst MIN_CLIP_SPAN = 0.02\n\n/**\n * The clip reshaped by dragging `edge` by `dx, dy`, at the same scale: the edge moves on the slide\n * and over the source together, so the clip shows more (or less) of the page beside it, never past\n * the source's edge or the stage's. Unless `free`, the edge snaps like a move does.\n */\nexport function reshapeFrame(\n frame: Frame,\n clip: Pick<Clip, 'rect' | 'aspect'>,\n edge: Edge,\n dx: number,\n dy: number,\n others: readonly Placed[] = [],\n free = false\n): { frame: Frame; rect: Rect; aspect: number; guides: Guide[] } {\n const { rect, aspect } = clip\n const horizontal = edge === 'e' || edge === 'w'\n const far = edge === 'e' || edge === 's'\n const start = horizontal ? frame.x : frame.y\n const size = horizontal ? frame.w : frameHeight(frame, aspect)\n const sourceStart = horizontal ? rect.x : rect.y\n const sourceSize = horizontal ? rect.w : rect.h\n // Stage per source along this axis: kept, so nothing on the clip changes size.\n const scale = size / sourceSize\n\n const axis: Guide['axis'] = horizontal ? 'x' : 'y'\n let at = (far ? start + size : start) + (horizontal ? dx : dy)\n if (!free) {\n const distance = horizontal ? SNAP_DISTANCE : SNAP_DISTANCE_Y\n const snap = snapSpan(at, 0, snapTargets(axis, others), distance)\n if (snap) at = snap.at\n }\n // As far as the stage and the source go; no smaller than a sliver of either.\n const least = Math.min(\n size,\n Math.max(horizontal ? MIN_FRAME_WIDTH : MIN_FRAME_WIDTH * STAGE_ASPECT, MIN_CLIP_SPAN * scale)\n )\n const end = start + size\n const most = far\n ? Math.min(1 - start, (1 - sourceStart) * scale)\n : Math.min(end, (sourceStart + sourceSize) * scale)\n const nextSize = clamp(far ? at - start : end - at, least, Math.max(most, size))\n const nextSourceSize = nextSize / scale\n const nextStart = far ? start : end - nextSize\n const nextSourceStart = far ? sourceStart : sourceStart + sourceSize - nextSourceSize\n\n const nextRect = horizontal\n ? { ...rect, x: nextSourceStart, w: nextSourceSize }\n : { ...rect, y: nextSourceStart, h: nextSourceSize }\n // The source's own shape (width / height as displayed), from the clip's.\n const sourceAspect = (aspect * rect.h) / rect.w\n const edgeAt = far ? nextStart + nextSize : nextStart\n return {\n frame: horizontal\n ? { x: nextStart, y: frame.y, w: nextSize }\n : { x: frame.x, y: nextStart, w: frame.w },\n rect: nextRect,\n aspect: (sourceAspect * nextRect.w) / nextRect.h,\n // A guide only where the edge did snap (not where a bound stopped it).\n guides:\n !free && Math.abs(edgeAt - at) < 1e-9 && snapTargets(axis, others).includes(at)\n ? [{ axis, at }]\n : [],\n }\n}\n\n/** Where a clip can be aligned on the stage. */\nexport type Alignment = 'left' | 'centre' | 'right' | 'top' | 'middle' | 'bottom'\n\n/** The frame aligned on the stage, inside its margins and the slide's reserved room. */\nexport function alignFrame(\n frame: Frame,\n aspect: number,\n alignment: Alignment,\n reserve: Reserve = NO_RESERVE\n): Frame {\n const h = frameHeight(frame, aspect)\n const right = reserve.right ?? 0\n const side = STAGE_MARGIN + (reserve.inset ?? 0)\n const below = reserve.below + (reserve.bottom ?? 0)\n switch (alignment) {\n case 'left':\n return { ...frame, x: side }\n case 'centre':\n return { ...frame, x: (1 - right - frame.w) / 2 }\n case 'right':\n return { ...frame, x: 1 - side - right - frame.w }\n case 'top':\n return { ...frame, y: STAGE_MARGIN + reserve.top }\n case 'middle':\n return { ...frame, y: (1 + reserve.top - below - h) / 2 }\n case 'bottom':\n return { ...frame, y: 1 - STAGE_MARGIN - below - h }\n }\n}\n\n/** A clip dropped at a point (stage fractions): centred there, at most 45% of the stage wide. */\nexport function dropFrame(aspect: number, at: { x: number; y: number }): Frame {\n const fit = fitFrame(aspect)\n const w = Math.min(fit.w, 0.45)\n const h = frameHeight({ w }, aspect)\n return { x: clamp(at.x - w / 2, 0, 1 - w), y: clamp(at.y - h / 2, 0, 1 - h), w }\n}\n\n/** \"Exhibit 12.pdf\", page 4 → \"Exhibit 12 · p. 4\". */\nexport function defaultCaption(fileName: string, page: number): string {\n return `${documentName(fileName)} · p. ${page}`\n}\n\nconst documentName = (fileName: string) => fileName.replace(/\\.[a-z0-9]{1,5}$/i, '') || 'Document'\n\n/** \"1:05\" (or \"1:02:05\"): a point in a video. */\nexport function formatTime(seconds: number): string {\n const total = Math.max(0, Math.floor(seconds))\n const h = Math.floor(total / 3600)\n const m = Math.floor((total % 3600) / 60)\n const s = String(total % 60).padStart(2, '0')\n return h ? `${h}:${String(m).padStart(2, '0')}:${s}` : `${m}:${s}`\n}\n\n/**\n * A clip's label as shown: its document's value in the presentation's label column (an exhibit\n * number, \"R-100\"), then its own label. `columnValues` maps a document id to that value.\n */\nexport function clipLabel(\n clip: Pick<Clip, 'caption' | 'documentId'>,\n columnValues: Readonly<Record<string, string>>\n): string {\n const value = columnValues[clip.documentId]?.trim()\n if (!value) return clip.caption\n return clip.caption ? `${value} · ${clip.caption}` : value\n}\n\n/** The source label of a clip of an image (\"Photo 3\") or a video, from where it starts (\"Interview · 1:05\"). */\nexport function mediaCaption(fileName: string, start?: number): string {\n const name = documentName(fileName)\n return start === undefined ? name : `${name} · ${formatTime(start)}`\n}\n","/**\n * Where a slide's parts go, by its layout: its title, the accent rule, its text (points, or a\n * subtitle), the logo in the footer, and the room its clips are arranged in. One description,\n * drawn by the stage, the saved PDF and the PowerPoint export alike.\n *\n * All positions are fractions of the stage (x, w of its width; y, h of its height); type sizes\n * are fractions of the stage width.\n */\n\nimport { CAPTION_SPACE, STAGE_MARGIN, type Reserve, type Slide, type SlideLayout } from './model'\nimport type { LogoCorner } from './theme'\n\n/** Text sits this far in from the stage's sides: a generous margin. */\nconst TEXT_INSET = 0.06\n\nexport interface TextBox {\n x: number\n y: number\n w: number\n h: number\n /** Type size, a fraction of the stage width. */\n size: number\n weight: 400 | 600 | 700\n align: 'left' | 'center'\n tone: 'title' | 'body' | 'muted'\n /** Lines start with a bullet in the accent colour. */\n bullets?: boolean\n /** Line height, a multiple of the type size. */\n leading: number\n /** Where the text sits in its box, top to bottom (default top). */\n anchor?: 'top' | 'middle' | 'bottom'\n}\n\nexport interface Box {\n x: number\n y: number\n w: number\n h: number\n}\n\nexport interface SlideGeometry {\n /** Where its title goes (none on a blank slide: its text is in its boxes). */\n title: TextBox | null\n /** The accent rule (under or above the title), when the slide shows a title. */\n rule: Box | null\n /** Where its points (or subtitle) go, if this layout has text. */\n text: TextBox | null\n logo: Box | null\n /** The room its clips keep free (they are arranged in the rest). */\n reserve: Reserve\n}\n\nexport const LAYOUT_INFO: Record<SlideLayout, { label: string; text?: string }> = {\n clips: { label: 'Title and clips' },\n points: { label: 'Clips and points', text: 'One point per line' },\n compare: { label: 'Side by side' },\n title: { label: 'Title slide', text: 'Subtitle' },\n section: { label: 'Section', text: 'Subtitle' },\n free: { label: 'Blank' },\n}\n\n/** The footer's height while a logo shows. */\nconst FOOTER = 0.085\n\nexport function slideGeometry(\n /** `items`, when given: a points slide with none puts its text across the slide. */\n slide: Pick<Slide, 'layout' | 'caption'> & { items?: readonly unknown[] },\n options: { labels: boolean; logo: LogoCorner | null }\n): SlideGeometry {\n const below = options.labels ? CAPTION_SPACE : 0\n const bottom = options.logo ? FOOTER : 0\n const logo: Box | null = options.logo\n ? {\n x: options.logo === 'bl' ? TEXT_INSET : 1 - TEXT_INSET - 0.16,\n y: 1 - 0.03 - 0.055,\n w: 0.16,\n h: 0.055,\n }\n : null\n const hasTitle = slide.caption.trim() !== ''\n\n // Blank: nothing of its own but the logo; whatever is placed on it goes anywhere.\n if (slide.layout === 'free') {\n return { title: null, rule: null, text: null, logo, reserve: { top: 0, below, bottom } }\n }\n\n if (slide.layout === 'title' || slide.layout === 'section') {\n const centred = slide.layout === 'title'\n const title: TextBox = centred\n ? {\n x: 0.1,\n y: 0.28,\n w: 0.8,\n h: 0.2,\n size: 0.052,\n weight: 700,\n align: 'center',\n tone: 'title',\n leading: 1.1,\n // Just above the rule, however many lines it takes.\n anchor: 'bottom',\n }\n : {\n x: TEXT_INSET + 0.02,\n y: 0.36,\n w: 0.8,\n h: 0.18,\n size: 0.046,\n weight: 700,\n align: 'left',\n tone: 'title',\n leading: 1.1,\n }\n return {\n title,\n rule: centred\n ? { x: 0.47, y: 0.505, w: 0.06, h: 0.007 }\n : { x: TEXT_INSET + 0.02, y: 0.33, w: 0.07, h: 0.008 },\n text: {\n x: title.x,\n y: centred ? 0.545 : 0.555,\n w: title.w,\n h: 0.1,\n size: 0.021,\n weight: 400,\n align: title.align,\n tone: 'muted',\n leading: 1.3,\n },\n logo,\n // Clips, if any, go under the text.\n reserve: { top: 0.62, below, bottom },\n }\n }\n\n const title: TextBox = {\n x: TEXT_INSET,\n y: 0.05,\n w: 1 - 2 * TEXT_INSET,\n h: 0.075,\n size: 0.03,\n weight: 600,\n align: 'left',\n tone: 'title',\n leading: 1.15,\n }\n const top = hasTitle ? 0.14 : 0\n // Clips line up with the slide's text (its title, its points); with none, they take the room.\n const inset = hasTitle || slide.layout === 'points' ? TEXT_INSET - STAGE_MARGIN : 0\n const geometry: SlideGeometry = {\n title,\n rule: hasTitle ? { x: TEXT_INSET, y: 0.128, w: 0.045, h: 0.006 } : null,\n text: null,\n logo,\n reserve: { top, below, bottom, inset },\n }\n if (slide.layout === 'points' && slide.items && slide.items.length === 0) {\n // Points alone: across the slide, under its title (no room kept for clips that are not there).\n const y = STAGE_MARGIN + top\n geometry.text = {\n x: TEXT_INSET,\n y,\n w: 1 - 2 * TEXT_INSET,\n h: 1 - y - STAGE_MARGIN - bottom,\n size: 0.024,\n weight: 400,\n align: 'left',\n tone: 'body',\n bullets: true,\n leading: 1.45,\n }\n return geometry\n }\n if (slide.layout === 'points') {\n const y = STAGE_MARGIN + top\n geometry.text = {\n x: 0.6,\n y,\n w: 1 - 0.6 - TEXT_INSET,\n h: 1 - y - STAGE_MARGIN - bottom - below,\n // Level with the clips, which are centred in their room.\n anchor: 'middle',\n size: 0.0195,\n weight: 400,\n align: 'left',\n tone: 'body',\n bullets: true,\n leading: 1.45,\n }\n geometry.reserve = { ...geometry.reserve, right: 0.4 - inset }\n }\n if (slide.layout === 'compare') geometry.reserve = { ...geometry.reserve, columns: 2 }\n return geometry\n}\n\n/** The lines of a slide's text (blank lines dropped). */\nexport const textLines = (text: string): string[] =>\n text\n .split('\\n')\n .map((line) => line.trim())\n .filter(Boolean)\n","/**\n * A presentation's theme: one look for every slide (background, typeface, accent colour, a logo\n * in the footer). The same values draw the stage (CSS), the saved PDF (canvas) and the PowerPoint\n * export, so they always match.\n *\n * Backgrounds are dark, for contrast with the clips: a deep diagonal gradient with a soft light\n * from the top left (the gloss), optionally a fine texture. A custom colour gets the same\n * treatment. Typefaces are ones PowerPoint has, so an exported deck keeps its type.\n */\n\nimport type { SlideBackground } from './boxes'\n\nexport type FontId = 'sans' | 'serif' | 'classic'\nexport type LogoCorner = 'bl' | 'br'\n\nexport interface ThemeLogo {\n /** An image document of the workspace (a reference; its file is fetched when opened). */\n documentId: string\n fileName: string\n corner: LogoCorner\n}\n\nexport interface Theme {\n /** A background preset's id, or a custom colour (`#rrggbb`). */\n background: string\n font: FontId\n /** `#rrggbb`: the rule under titles, bullets. */\n accent: string\n logo: ThemeLogo | null\n}\n\n/** The app's own colours (its `--primary` and `--secondary` tokens), as a background or accent. */\nexport const BRAND = 'brand'\n\n/** By default a presentation wears the app's brand: its primary as the background, its accent. */\nexport const DEFAULT_THEME: Theme = {\n background: BRAND,\n font: 'sans',\n accent: BRAND,\n logo: null,\n}\n\ninterface BackgroundSpec {\n /** Top left of the gradient. */\n from: string\n /** Bottom right. */\n to: string\n /** The light from the top left (white, this opacity). */\n glow: number\n texture?: 'linen'\n}\n\nexport const BACKGROUNDS: ({ id: string; label: string } & BackgroundSpec)[] = [\n // The app's primary colour, read from its tokens when drawn (`brandColors`).\n { id: BRAND, label: 'Brand', from: '', to: '', glow: 0.1 },\n { id: 'graphite', label: 'Graphite', from: '#2b3038', to: '#0c0e11', glow: 0.09 },\n { id: 'midnight', label: 'Midnight', from: '#17294a', to: '#050a15', glow: 0.1 },\n { id: 'oxford', label: 'Oxford', from: '#123d45', to: '#04141a', glow: 0.08 },\n { id: 'claret', label: 'Claret', from: '#4b1526', to: '#110409', glow: 0.08 },\n { id: 'linen', label: 'Linen', from: '#2a2b30', to: '#111215', glow: 0.06, texture: 'linen' },\n { id: 'onyx', label: 'Onyx', from: '#000000', to: '#000000', glow: 0 },\n]\n\nexport const FONTS: Record<FontId, { label: string; css: string; pptx: string }> = {\n sans: {\n label: 'Modern',\n css: 'Calibri, Carlito, \"Segoe UI\", \"Helvetica Neue\", Arial, sans-serif',\n pptx: 'Calibri',\n },\n serif: {\n label: 'Editorial',\n css: 'Georgia, Gelasio, \"Times New Roman\", serif',\n pptx: 'Georgia',\n },\n classic: {\n label: 'Classic',\n css: 'Garamond, \"EB Garamond\", \"Cormorant Garamond\", \"Times New Roman\", serif',\n pptx: 'Garamond',\n },\n}\n\nexport const ACCENTS: { label: string; color: string }[] = [\n { label: 'Brand', color: BRAND },\n { label: 'Gold', color: '#c9a96e' },\n { label: 'Teal', color: '#4fb3bf' },\n { label: 'Blue', color: '#6b9bf2' },\n { label: 'Coral', color: '#e57a6e' },\n { label: 'Silver', color: '#cfd4dc' },\n]\n\n/** Slide text colours, over the dark background. */\nexport const TEXT_COLORS = { title: '#ffffff', body: '#e6e8ec', muted: '#aab0ba' }\n\nconst HEX = /^#[0-9a-f]{6}$/i\n\nexport const isHexColor = (value: string): boolean => HEX.test(value)\n\nfunction mix(hex: string, toward: number, amount: number): string {\n const channel = (i: number) => {\n const value = parseInt(hex.slice(1 + i * 2, 3 + i * 2), 16)\n return Math.round(value + (toward - value) * amount)\n .toString(16)\n .padStart(2, '0')\n }\n return `#${channel(0)}${channel(1)}${channel(2)}`\n}\n\n/** The tokens as the app's light theme defines them, where the page has none (tests, workers). */\nconst BRAND_TOKENS = { primary: '229.85 50.43% 25.29%', secondary: '195 100% 47%' }\n\nfunction hslToHex(h: number, s: number, l: number): string {\n const k = (n: number) => (n + h / 30) % 12\n const a = s * Math.min(l, 1 - l)\n const f = (n: number) => l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)))\n return `#${[f(0), f(8), f(4)]\n .map((x) =>\n Math.round(x * 255)\n .toString(16)\n .padStart(2, '0')\n )\n .join('')}`\n}\n\n/** A token's value (\"H S% L%\"), as hue and fractions. */\nfunction readToken(name: string, fallback: string): [number, number, number] {\n const value =\n (typeof document !== 'undefined' &&\n getComputedStyle(document.documentElement).getPropertyValue(name).trim()) ||\n fallback\n const [h, s, l] = value.split(/\\s+/).map((part) => parseFloat(part))\n return [h, s / 100, l / 100]\n}\n\nlet brand: { primary: string; secondary: string } | null = null\n\n/**\n * The app's brand colours, from its `--primary` and `--secondary` tokens (another host's, in that\n * host). The primary stays deep, as a slide background: in a dark mode, where the token is light,\n * its hue is kept at the light theme's depth. Read once.\n */\nexport function brandColors(): { primary: string; secondary: string } {\n if (brand) return brand\n const [ph, ps, pl] = readToken('--primary', BRAND_TOKENS.primary)\n const [sh, ss, sl] = readToken('--secondary', BRAND_TOKENS.secondary)\n brand = { primary: hslToHex(ph, ps, Math.min(pl, 0.3)), secondary: hslToHex(sh, ss, sl) }\n return brand\n}\n\n/** A theme's accent as a colour (`brand`: the app's secondary colour). */\nexport const accentColor = (accent: string): string =>\n accent === BRAND ? brandColors().secondary : accent\n\n/** The background a theme names: a preset, or a custom colour given the presets' finish. */\nexport function backgroundSpec(background: string): BackgroundSpec {\n if (background === BRAND) {\n const { primary } = brandColors()\n return { from: mix(primary, 255, 0.05), to: mix(primary, 0, 0.6), glow: 0.1 }\n }\n const preset = BACKGROUNDS.find((entry) => entry.id === background)\n if (preset) return preset\n if (isHexColor(background)) {\n return { from: mix(background, 255, 0.06), to: mix(background, 0, 0.62), glow: 0.08 }\n }\n return backgroundSpec(BRAND)\n}\n\n/** The background as CSS (container units: the texture keeps its size on any stage). */\nexport function backgroundCss(background: string): string {\n const spec = backgroundSpec(background)\n const layers: string[] = []\n if (spec.glow > 0) {\n layers.push(\n `radial-gradient(120% 90% at 12% -10%, rgba(255,255,255,${spec.glow}), transparent 60%)`\n )\n }\n if (spec.texture === 'linen') {\n layers.push(\n 'repeating-linear-gradient(45deg, rgba(255,255,255,0.025) 0 0.06cqw, transparent 0.06cqw 0.32cqw)',\n 'repeating-linear-gradient(-45deg, rgba(255,255,255,0.02) 0 0.06cqw, transparent 0.06cqw 0.32cqw)'\n )\n }\n layers.push(`linear-gradient(155deg, ${spec.from} 0%, ${spec.to} 100%)`)\n return layers.join(', ')\n}\n\n/** The background painted on a canvas (the saved PDF's pages, the PowerPoint backgrounds). */\nexport function paintBackground(\n context: CanvasRenderingContext2D,\n width: number,\n height: number,\n background: string\n): void {\n const spec = backgroundSpec(background)\n // CSS's 155deg gradient line: through the centre, long enough to reach the corners.\n const angle = (155 * Math.PI) / 180\n const dx = Math.sin(angle)\n const dy = -Math.cos(angle)\n const length = Math.abs(width * dx) + Math.abs(height * dy)\n const cx = width / 2\n const cy = height / 2\n const gradient = context.createLinearGradient(\n cx - (dx * length) / 2,\n cy - (dy * length) / 2,\n cx + (dx * length) / 2,\n cy + (dy * length) / 2\n )\n gradient.addColorStop(0, spec.from)\n gradient.addColorStop(1, spec.to)\n context.fillStyle = gradient\n context.fillRect(0, 0, width, height)\n\n if (spec.texture === 'linen') {\n const step = width * 0.0032\n context.save()\n context.lineWidth = width * 0.0006\n for (const [direction, alpha] of [\n [1, 0.025],\n [-1, 0.02],\n ] as const) {\n context.strokeStyle = `rgba(255,255,255,${alpha})`\n context.beginPath()\n for (let offset = -height; offset < width + height; offset += step) {\n context.moveTo(offset, direction === 1 ? height : 0)\n context.lineTo(offset + height, direction === 1 ? 0 : height)\n }\n context.stroke()\n }\n context.restore()\n }\n\n if (spec.glow > 0) {\n // An ellipse 120% × 90% of the slide centred above its top left, fading out by 60%.\n const rx = width * 1.2\n const ry = height * 0.9\n context.save()\n context.translate(width * 0.12, -height * 0.1)\n context.scale(rx, ry)\n const glow = context.createRadialGradient(0, 0, 0, 0, 0, 1)\n glow.addColorStop(0, `rgba(255,255,255,${spec.glow})`)\n glow.addColorStop(0.6, 'rgba(255,255,255,0)')\n context.fillStyle = glow\n context.fillRect(-1, -1, 2, 2)\n context.restore()\n }\n}\n\n/**\n * A page clip's soft edge: paper white at its very edge (`CLIP_EDGE_SOLID`), fading to nothing by\n * `CLIP_EDGE_FADE` (fractions of the stage width; never more than `CLIP_EDGE_MAX` of the clip), so\n * text cut by the clip fades out instead of being sliced, and the clip has a little margin.\n */\nexport const CLIP_EDGE_SOLID = 0.002\nexport const CLIP_EDGE_FADE = 0.009\nexport const CLIP_EDGE_MAX = 0.08\n\n/** The soft edge as CSS (on the stage: container units). */\nexport function clipEdgeCss(): string {\n const solid = `min(${CLIP_EDGE_SOLID * 100}cqw, ${CLIP_EDGE_MAX * 25}%)`\n const fade = `min(${CLIP_EDGE_FADE * 100}cqw, ${CLIP_EDGE_MAX * 100}%)`\n return ['to right', 'to left', 'to bottom', 'to top']\n .map(\n (direction) =>\n `linear-gradient(${direction}, #fff 0, #fff ${solid}, rgba(255,255,255,0) ${fade})`\n )\n .join(', ')\n}\n\n/** The soft edge painted over a clip drawn in `box` (the saved PDF, the PowerPoint images). */\nexport function paintClipEdge(\n context: CanvasRenderingContext2D,\n box: { x: number; y: number; width: number; height: number },\n stageWidth: number\n): void {\n const sides = [\n { length: box.width, from: [box.x, 0], to: [box.x + 1, 0] },\n { length: box.width, from: [box.x + box.width, 0], to: [box.x + box.width - 1, 0] },\n { length: box.height, from: [0, box.y], to: [0, box.y + 1] },\n { length: box.height, from: [0, box.y + box.height], to: [0, box.y + box.height - 1] },\n ]\n for (const side of sides) {\n const fade = Math.min(CLIP_EDGE_FADE * stageWidth, CLIP_EDGE_MAX * side.length)\n const solid = Math.min(CLIP_EDGE_SOLID * stageWidth, CLIP_EDGE_MAX * 0.25 * side.length)\n // Along the side's inward normal, `fade` long.\n const [fx, fy] = side.from\n const [tx, ty] = side.to\n const gradient = context.createLinearGradient(\n fx,\n fy,\n fx + (tx - fx) * fade,\n fy + (ty - fy) * fade\n )\n gradient.addColorStop(0, 'rgba(255,255,255,1)')\n gradient.addColorStop(Math.min(1, solid / fade), 'rgba(255,255,255,1)')\n gradient.addColorStop(1, 'rgba(255,255,255,0)')\n context.fillStyle = gradient\n context.fillRect(box.x, box.y, box.width, box.height)\n }\n}\n\n/** A slide's own background as CSS: its image (from the presentation's media), gradient or colour. */\nexport function slideBackgroundCss(\n background: SlideBackground,\n media: Readonly<Record<string, string>>\n): string {\n const image = background.image ? media[background.image] : undefined\n if (image) return `center / cover no-repeat url(\"${image}\")`\n if (background.gradient) {\n const { angle, from, to } = background.gradient\n return `linear-gradient(${angle}deg, ${from}, ${to})`\n }\n return background.color ?? '#ffffff'\n}\n\n/** A slide's own background painted on a canvas. */\nexport async function paintSlideBackground(\n context: CanvasRenderingContext2D,\n width: number,\n height: number,\n background: SlideBackground,\n media: Readonly<Record<string, string>>\n): Promise<void> {\n const image = background.image ? media[background.image] : undefined\n if (image) {\n const picture = new Image()\n picture.src = image\n await picture.decode()\n // Cover: fill the slide, cropping the overflow.\n const scale = Math.max(width / picture.width, height / picture.height)\n const w = picture.width * scale\n const h = picture.height * scale\n context.drawImage(picture, (width - w) / 2, (height - h) / 2, w, h)\n return\n }\n if (background.gradient) {\n const { angle, from, to } = background.gradient\n const radians = (angle * Math.PI) / 180\n const dx = Math.sin(radians)\n const dy = -Math.cos(radians)\n const length = Math.abs(width * dx) + Math.abs(height * dy)\n const gradient = context.createLinearGradient(\n width / 2 - (dx * length) / 2,\n height / 2 - (dy * length) / 2,\n width / 2 + (dx * length) / 2,\n height / 2 + (dy * length) / 2\n )\n gradient.addColorStop(0, from)\n gradient.addColorStop(1, to)\n context.fillStyle = gradient\n } else {\n context.fillStyle = background.color ?? '#ffffff'\n }\n context.fillRect(0, 0, width, height)\n}\n\n/** Whether a slide's background is light (text on it should be dark). */\nexport function isLightBackground(background: SlideBackground | undefined): boolean {\n const color = background?.gradient?.from ?? background?.color\n if (!color || !isHexColor(color)) return false\n const n = parseInt(color.slice(1), 16)\n const luminance = 0.2126 * ((n >> 16) & 255) + 0.7152 * ((n >> 8) & 255) + 0.0722 * (n & 255)\n return luminance > 150\n}\n\n/** A theme read from saved data, every field checked (anything wrong falls back to the default). */\nexport function parseTheme(value: unknown): Theme {\n const data = (value ?? {}) as Partial<Theme>\n const logo = data.logo as Partial<ThemeLogo> | null | undefined\n return {\n background:\n typeof data.background === 'string' &&\n (BACKGROUNDS.some((entry) => entry.id === data.background) || isHexColor(data.background))\n ? data.background\n : DEFAULT_THEME.background,\n font: data.font && data.font in FONTS ? data.font : DEFAULT_THEME.font,\n accent:\n typeof data.accent === 'string' && (isHexColor(data.accent) || data.accent === BRAND)\n ? data.accent\n : DEFAULT_THEME.accent,\n logo:\n logo && typeof logo.documentId === 'string'\n ? {\n documentId: logo.documentId,\n fileName: typeof logo.fileName === 'string' ? logo.fileName : '',\n corner: logo.corner === 'bl' ? 'bl' : 'br',\n }\n : null,\n }\n}\n","/**\n * Slide boxes and backgrounds read from saved data (written by the app, an agent or an import):\n * every field checked, anything malformed dropped rather than trusted.\n */\n\nimport type { BoxShape, Paragraph, SlideBackground, SlideBox, TextAlign, TextRun } from './boxes'\n\n/** A box as saved: no session id. */\nexport type SavedBox = Omit<SlideBox, 'id'>\n\nconst HEX = /^#[0-9a-f]{6}$/i\nconst SHAPES: readonly BoxShape[] = ['text', 'rect', 'roundRect', 'ellipse', 'line']\nconst ALIGNS: readonly TextAlign[] = ['left', 'center', 'right', 'justify']\n\nconst num = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v)\nconst color = (v: unknown): string | undefined =>\n typeof v === 'string' && HEX.test(v) ? v.toLowerCase() : undefined\n\nfunction parseRun(value: unknown): TextRun | null {\n const run = value as Partial<TextRun> | null\n if (!run || typeof run.text !== 'string') return null\n return {\n text: run.text,\n ...(num(run.size) && run.size > 0 && run.size < 400 ? { size: run.size } : {}),\n ...(run.bold === true ? { bold: true } : {}),\n ...(run.italic === true ? { italic: true } : {}),\n ...(run.underline === true ? { underline: true } : {}),\n ...(color(run.color) ? { color: color(run.color) } : {}),\n ...(typeof run.font === 'string' && run.font ? { font: run.font.slice(0, 64) } : {}),\n }\n}\n\nfunction parseParagraph(value: unknown): Paragraph | null {\n const paragraph = value as Partial<Paragraph> | null\n if (!paragraph || !Array.isArray(paragraph.runs)) return null\n return {\n runs: paragraph.runs.map(parseRun).filter((run): run is TextRun => run !== null),\n ...(ALIGNS.includes(paragraph.align as TextAlign) ? { align: paragraph.align } : {}),\n ...(num(paragraph.level) && paragraph.level > 0\n ? { level: Math.min(8, Math.round(paragraph.level)) }\n : {}),\n ...(paragraph.bullet === true ? { bullet: true } : {}),\n }\n}\n\nexport function parseBox(value: unknown): SavedBox | null {\n const box = value as Partial<SavedBox> | null\n const frame = box?.frame\n if (\n !box ||\n !frame ||\n !num(frame.x) ||\n !num(frame.y) ||\n !num(frame.w) ||\n !num(frame.h) ||\n frame.w < 0 ||\n frame.h < 0 ||\n !SHAPES.includes(box.shape as BoxShape)\n ) {\n return null\n }\n const line = box.line\n return {\n frame: { x: frame.x, y: frame.y, w: frame.w, h: frame.h },\n shape: box.shape as BoxShape,\n paragraphs: Array.isArray(box.paragraphs)\n ? box.paragraphs.map(parseParagraph).filter((p): p is Paragraph => p !== null)\n : [],\n ...(num(box.rotation) && box.rotation % 360 !== 0 ? { rotation: box.rotation % 360 } : {}),\n ...(box.flipH === true ? { flipH: true } : {}),\n ...(box.flipV === true ? { flipV: true } : {}),\n ...(color(box.fill) ? { fill: color(box.fill) } : {}),\n ...(num(box.fillAlpha) && box.fillAlpha >= 0 && box.fillAlpha < 1\n ? { fillAlpha: box.fillAlpha }\n : {}),\n ...(line && color(line.color) && num(line.width) && line.width >= 0\n ? {\n line: {\n color: color(line.color)!,\n width: line.width,\n ...(line.dash === true ? { dash: true } : {}),\n },\n }\n : {}),\n ...(box.anchor === 'middle' || box.anchor === 'bottom' || box.anchor === 'top'\n ? { anchor: box.anchor }\n : {}),\n ...(num(box.inset) && box.inset >= 0 ? { inset: box.inset } : {}),\n ...(box.role === 'title' || box.role === 'body' ? { role: box.role } : {}),\n ...(box.front === true ? { front: true } : {}),\n }\n}\n\nexport function parseBoxes(value: unknown): SavedBox[] {\n return Array.isArray(value) ? value.map(parseBox).filter((b): b is SavedBox => b !== null) : []\n}\n\n/** A slide's background, if valid (an image only if `media` has it). */\nexport function parseBackground(\n value: unknown,\n media: Readonly<Record<string, string>>\n): SlideBackground | undefined {\n const background = value as Partial<SlideBackground> | null\n if (!background || typeof background !== 'object') return undefined\n const gradient = background.gradient\n const parsed: SlideBackground = {\n ...(color(background.color) ? { color: color(background.color) } : {}),\n ...(gradient && color(gradient.from) && color(gradient.to) && num(gradient.angle)\n ? {\n gradient: { from: color(gradient.from)!, to: color(gradient.to)!, angle: gradient.angle },\n }\n : {}),\n ...(typeof background.image === 'string' && media[background.image]\n ? { image: background.image }\n : {}),\n }\n return Object.keys(parsed).length ? parsed : undefined\n}\n","/**\n * A presentation saved as a document of the workspace's `Presentations` folder,\n * `<title>.presentation.pdf`: a PDF of its slides (each an image as presented, redactions burnt in,\n * its words searchable), with its editable data attached to the PDF as `arbi-presentation.json`\n * (the format below; see docs/presentation-format.md). One file: viewing, searching, downloading,\n * copying and versions are a PDF's, and the editable data can never part from its slides.\n *\n * The data holds references, never pixels: for each clip its source document (and version), page,\n * area and label; for each slide its title and where its clips sit. Opening it fetches the sources\n * again (so clips stay sharp and editable) and reads their redactions again (so a newer redaction\n * applies too).\n *\n * Agents and the API: read and write the attachment with any PDF library. Changing the data cannot\n * redraw the slides (that needs the sources and their redactions, decrypted in the app), so set\n * `slidesStale: true`: the editor says so on opening, and its next save draws them again.\n */\n\nimport {\n SLIDE_LAYOUTS,\n type Clip,\n type ClipKind,\n type Frame,\n type Rect,\n type SlideLayout,\n} from './model'\nimport { parseTheme, type Theme } from './theme'\nimport { parseBackground, parseBoxes, type SavedBox } from './saved-boxes'\nimport type { SlideBackground, SlideBox } from './boxes'\n\nexport const PRESENTATIONS_FOLDER = 'Presentations'\n/**\n * Templates: presentations kept here are offered by New from template (their look and slides,\n * without clips). A firm keeps its house look by keeping one here.\n */\nexport const TEMPLATES_FOLDER = `${PRESENTATIONS_FOLDER}/Templates`\n/** Exported PDFs and PowerPoint decks: kept apart, so they are not taken for presentations. */\nexport const EXPORTS_FOLDER = `${PRESENTATIONS_FOLDER}/Exports`\nimport { LEGACY_PRESENTATION_SUFFIX, PRESENTATION_FILE_SUFFIX } from './panel-id'\n\n/** The name of the editable data attached to a presentation's PDF. */\nexport const PRESENTATION_ATTACHMENT = 'arbi-presentation.json'\nconst FORMAT = 'arbi-presentation'\n\nexport interface SavedClip {\n kind: ClipKind\n documentId: string\n version?: number\n fileName: string\n page: number\n rect: Rect\n aspect: number\n caption: string\n start?: number\n zoomBase?: number\n /** An image embedded in the presentation (a key of `media`); `documentId` is empty. */\n media?: string\n /** Drawn as it is (no frame finish, no label). */\n plain?: boolean\n}\n\nexport interface SavedSlide {\n caption: string\n auto: boolean\n /** Absent in files saved before layouts: 'clips'. */\n layout?: SlideLayout\n /** One point per line (a subtitle on a title or section slide). */\n points?: string\n /** `clip` is an index into `clips`. */\n items: { clip: number; frame: Frame }[]\n /** Its text boxes and shapes (`boxes`). */\n boxes?: SavedBox[]\n background?: SlideBackground\n /** Speaker notes. */\n notes?: string\n /**\n * What its PowerPoint slide looked like when saved (`slideFingerprint`): a slide whose\n * fingerprint no longer matches was changed in PowerPoint, and is imported again.\n */\n fingerprint?: string\n}\n\nexport interface SavedPresentation {\n format: typeof FORMAT\n version: 1\n title: string\n captions: boolean\n /** The annotation column (tag id) whose value leads each clip's label, e.g. its exhibit number. */\n labelColumn?: string\n /** Absent in files saved before themes: the default theme. */\n theme?: Theme\n clips: SavedClip[]\n slides: SavedSlide[]\n /** Images embedded in the presentation (an imported deck's pictures), as data URLs. */\n media?: Record<string, string>\n /** The data was changed outside the editor (an agent): the PDF's slides do not show it yet. */\n slidesStale?: boolean\n}\n\nexport interface PresentationSnapshot {\n title: string\n captions: boolean\n labelColumn?: string | null\n theme?: Theme\n clips: readonly Clip[]\n slides: readonly {\n caption: string\n auto: boolean\n layout?: SlideLayout\n points?: string\n items: { clipId: string; frame: Frame }[]\n boxes?: readonly SlideBox[]\n background?: SlideBackground\n notes?: string\n }[]\n /** Embedded images by key (data URLs). */\n media?: Readonly<Record<string, string>>\n /** Each slide's PowerPoint fingerprint, as just written (`slideFingerprint`). */\n fingerprints?: readonly string[]\n}\n\n/** The presentation as saved: references only. */\nexport function serializePresentation(snapshot: PresentationSnapshot): SavedPresentation {\n const index = new Map(snapshot.clips.map((clip, i) => [clip.id, i]))\n return {\n format: FORMAT,\n version: 1,\n title: snapshot.title,\n captions: snapshot.captions,\n ...(snapshot.labelColumn ? { labelColumn: snapshot.labelColumn } : {}),\n ...(snapshot.theme ? { theme: snapshot.theme } : {}),\n clips: snapshot.clips.map((clip) => ({\n kind: clip.kind,\n documentId: clip.documentId,\n ...(clip.version !== undefined ? { version: clip.version } : {}),\n fileName: clip.fileName,\n page: clip.page,\n rect: clip.rect,\n aspect: clip.aspect,\n caption: clip.caption,\n ...(clip.start !== undefined ? { start: clip.start } : {}),\n ...(clip.zoomBase !== undefined ? { zoomBase: clip.zoomBase } : {}),\n ...(clip.media ? { media: clip.media } : {}),\n ...(clip.plain ? { plain: true } : {}),\n })),\n slides: snapshot.slides.map((slide, i) => ({\n caption: slide.caption,\n auto: slide.auto,\n layout: slide.layout ?? 'clips',\n ...(slide.points ? { points: slide.points } : {}),\n items: slide.items\n .filter((item) => index.has(item.clipId))\n .map((item) => ({ clip: index.get(item.clipId)!, frame: item.frame })),\n ...(slide.boxes?.length\n ? { boxes: slide.boxes.map(({ id: _id, ...box }) => (void _id, box)) }\n : {}),\n ...(slide.background ? { background: slide.background } : {}),\n ...(slide.notes?.trim() ? { notes: slide.notes } : {}),\n ...(snapshot.fingerprints?.[i] ? { fingerprint: snapshot.fingerprints[i] } : {}),\n })),\n ...(usedMedia(snapshot) ? { media: usedMedia(snapshot) } : {}),\n }\n}\n\n/** The embedded images still used (by a clip or a slide's background), or none. */\nfunction usedMedia(snapshot: PresentationSnapshot): Record<string, string> | undefined {\n const media = snapshot.media ?? {}\n const keys = new Set<string>()\n for (const clip of snapshot.clips) if (clip.media) keys.add(clip.media)\n for (const slide of snapshot.slides) if (slide.background?.image) keys.add(slide.background.image)\n const used = Object.fromEntries(\n [...keys].filter((key) => media[key]).map((key) => [key, media[key]])\n )\n return Object.keys(used).length ? used : undefined\n}\n\nconst isNumber = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v)\nconst isRect = (v: unknown): v is Rect => {\n const r = v as Rect | null\n return (\n !!r && isNumber(r.x) && isNumber(r.y) && isNumber(r.w) && isNumber(r.h) && r.w > 0 && r.h > 0\n )\n}\nconst isFrame = (v: unknown): v is Frame => {\n const f = v as Frame | null\n return !!f && isNumber(f.x) && isNumber(f.y) && isNumber(f.w) && f.w > 0\n}\n\n/** A saved presentation read from a file, checked; throws on anything else. */\nexport function parsePresentation(text: string): SavedPresentation {\n const data = JSON.parse(text) as Partial<SavedPresentation>\n if (data?.format !== FORMAT || data.version !== 1) throw new Error('Not a presentation file')\n const clips = Array.isArray(data.clips) ? data.clips : []\n const slides = Array.isArray(data.slides) ? data.slides : []\n const media =\n data.media && typeof data.media === 'object'\n ? Object.fromEntries(\n Object.entries(data.media).filter(\n ([, url]) => typeof url === 'string' && url.startsWith('data:image/')\n )\n )\n : {}\n for (const clip of clips) {\n if (\n !['pdf', 'image', 'video'].includes(clip.kind) ||\n typeof clip.documentId !== 'string' ||\n (clip.media !== undefined && !media[clip.media]) ||\n !isRect(clip.rect) ||\n !isNumber(clip.aspect) ||\n !isNumber(clip.page)\n ) {\n throw new Error('The presentation file is damaged')\n }\n }\n for (const slide of slides) {\n if (!Array.isArray(slide.items)) throw new Error('The presentation file is damaged')\n for (const item of slide.items) {\n if (!isNumber(item.clip) || !clips[item.clip] || !isFrame(item.frame)) {\n throw new Error('The presentation file is damaged')\n }\n }\n }\n return {\n format: FORMAT,\n version: 1,\n title: typeof data.title === 'string' ? data.title : 'Presentation',\n captions: data.captions !== false,\n ...(data.theme !== undefined ? { theme: parseTheme(data.theme) } : {}),\n ...(typeof data.labelColumn === 'string' && data.labelColumn\n ? { labelColumn: data.labelColumn }\n : {}),\n clips,\n slides: slides.map((slide) => {\n const { boxes, background, fingerprint, notes, ...rest } = slide\n const parsedBoxes = parseBoxes(boxes)\n const parsedBackground = parseBackground(background, media)\n return {\n ...rest,\n layout: SLIDE_LAYOUTS.includes(slide.layout as SlideLayout) ? slide.layout : 'clips',\n ...(typeof slide.points === 'string' && slide.points ? { points: slide.points } : {}),\n ...(parsedBoxes.length ? { boxes: parsedBoxes } : {}),\n ...(parsedBackground ? { background: parsedBackground } : {}),\n ...(typeof fingerprint === 'string' ? { fingerprint } : {}),\n ...(typeof notes === 'string' && notes.trim() ? { notes } : {}),\n }\n }),\n ...(Object.keys(media).length ? { media } : {}),\n ...(data.slidesStale === true ? { slidesStale: true } : {}),\n }\n}\n\n/** A title as a file name stem (characters a file name can hold). */\nexport function safeFileStem(title: string): string {\n return title.replace(/[\\\\/:*?\"<>|]+/g, ' ').trim() || 'Presentation'\n}\n\n/** \"Opening statement\" → \"Opening statement.pptx\": a presentation is a PowerPoint file. */\nexport function presentationFileName(title: string): string {\n return `${safeFileStem(title)}.pptx`\n}\n\n/** The title of a saved presentation, from its file name (older names too). */\nexport function presentationTitle(fileName: string): string {\n for (const suffix of [PRESENTATION_FILE_SUFFIX, LEGACY_PRESENTATION_SUFFIX, '.pptx', '.pdf']) {\n if (fileName.endsWith(suffix)) return fileName.slice(0, -suffix.length)\n }\n return fileName\n}\n","/**\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 × 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–1 (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","/**\n * The presentation of this session: the clips taken, the slides they are arranged on, the slide on\n * the stage, whether the stage is blanked and whether the presentation window presents (shows only\n * the stage, for sharing) or edits. Clips taken in the app's viewer land in it at once.\n *\n * Kept in memory only: a clip holds the decrypted PDF it is drawn from, so nothing is written to\n * storage, and everything is cleared when the session signs out (`ConnectedPresentation`).\n */\n\nimport { create } from 'zustand'\nimport { releasePdfRegionSource } from '@arbidocs/react/viewers'\nimport {\n alignFrame,\n autoLayout,\n defaultCaption,\n dropFrame,\n fitFrame,\n fullHeightFrame,\n fullWidthFrame,\n moveFrame,\n type Alignment,\n type Clip,\n type Rect,\n type Reserve,\n type Frame,\n type Slide,\n type SlideLayout,\n} from './model'\nimport { slideGeometry } from './slide-layout'\nimport { DEFAULT_THEME, type Theme } from './theme'\nimport { serializePresentation } from './persistence'\nimport { nextBoxId, withText, type SlideBackground, type SlideBox } from './boxes'\nimport type { SavedBox } from './saved-boxes'\n\n/** The smallest a clip's area can be zoomed to (a fraction of its source, either side). */\nconst MIN_CLIP_AREA = 0.02\n\n/** A slide holds a handful of clips: more would be too small to read on a shared screen. */\nexport const MAX_ITEMS_PER_SLIDE = 6\n/** A new clip goes on the slide by itself while the slide has fewer than this. */\nconst AUTO_PLACE_BELOW = 2\n\nexport type NewClip = Omit<Clip, 'id' | 'caption'> & { caption?: string }\nexport type FrameCommand = 'fullWidth' | 'fullHeight' | 'fit'\n\ninterface PresentationState {\n clips: Clip[]\n slides: Slide[]\n /** Index of the slide on the stage. */\n current: number\n /** The stage shows nothing (black) while true. */\n blank: boolean\n captions: boolean\n /** One look for every slide: background, typeface, accent, logo. Saved. */\n theme: Theme\n /** The theme's logo image (this session only; fetched by the host from `theme.logo`). */\n logoImage: Blob | null\n /**\n * The annotation column (a tag's id) whose value for each clip's document leads its label: an\n * Exhibit column's \"R-100\". Saved with the presentation.\n */\n labelColumn: string | null\n /** Each clip document's value in `labelColumn`, kept current by the host (not saved). */\n columnValues: Readonly<Record<string, string>>\n /** Present mode: the presentation window shows only the stage (what is shared). */\n presenting: boolean\n /** The presentation's name (its file's, once saved). */\n title: string\n /** The document it is saved as, once saved: saving again adds a version to it. */\n savedId: string | null\n /** Which version of that document this is (as opened or saved), when known. */\n version: number | null\n /**\n * The document (or draft) this presentation is edited as, in the viewer: its slides tab shows\n * it. Null: clips gathered with no presentation open yet (a new one takes them).\n */\n boundTo: string | null\n /** The presentation as last opened or saved (serialised), to tell unsaved changes; null: never. */\n clean: string | null\n /**\n * A message for the presentation window itself (saved, failed…): the app's notifications show in\n * the app's window, out of sight behind a popped-out presentation.\n */\n notice: { text: string; kind: 'success' | 'error'; id: number } | null\n /** The clip being dragged from the tray, while it is (the drop targets light up). */\n dragging: string | null\n /** Images embedded in the presentation (an imported deck's pictures), as data URLs, by key. */\n media: Readonly<Record<string, string>>\n}\n\ninterface PresentationActions {\n /** Add a clip; it is placed on the current slide while that has fewer than two. */\n addClip(clip: NewClip): string\n removeClip(clipId: string): void\n setCaption(clipId: string, caption: string): void\n /** Put a clip on the current slide (at a point, when dropped there). */\n place(clipId: string, at?: { x: number; y: number }): void\n unplace(clipId: string): void\n /** Move or resize a clip by hand: the slide stops arranging itself. */\n setFrame(clipId: string, frame: Frame): void\n applyFrame(clipId: string, command: FrameCommand): void\n /** Overlapping clips: this one on top of the others (later items are drawn over earlier ones). */\n bringToFront(clipId: string): void\n /** Overlapping clips: this one under the others. */\n sendToBack(clipId: string): void\n /**\n * Scroll what a clip shows over its page, image or video by `dx, dy` (fractions of the source),\n * its size kept and kept within the source: e.g. to show the lines above or below a passage.\n */\n panClip(clipId: string, dx: number, dy: number): void\n /**\n * Zoom what a clip shows by `factor` (2: twice as close) about its centre: its area over the\n * source shrinks or grows, its shape kept, never past the source's edges.\n */\n zoomClip(clipId: string, factor: number): void\n /** Zoom a clip to `percent` of how close it was cut (100: as cut), about its centre. */\n setClipZoom(clipId: string, percent: number): void\n /** Align a clip on the stage (inside the margins and the slide's reserved room). */\n align(clipId: string, alignment: Alignment): void\n /** Nudge a clip by `dx, dy` (stage fractions), kept on the stage, not snapped. */\n nudge(clipId: string, dx: number, dy: number): void\n /** The current slide's caption (shown across its top; empty for none). */\n /** A slide's title (default the current slide's). */\n setSlideCaption(caption: string, index?: number): void\n /** The current slide's layout: it is arranged for it again. */\n setSlideLayout(layout: SlideLayout, index?: number): void\n /** The current slide's text (its points, or subtitle). */\n setSlidePoints(points: string, index?: number): void\n /** Change the theme; slides arranging themselves make room for a logo (or give it back). */\n setTheme(change: Partial<Theme>): void\n setLogoImage(image: Blob | null): void\n /** Arrange the current slide automatically again. */\n arrange(): void\n /** A new slide after the current one (by default with the current slide's layout). */\n addSlide(layout?: SlideLayout, after?: number): void\n /** Remove a slide (default the current one); the last one left is emptied instead. */\n removeSlide(index?: number): void\n /** A copy of a slide (its title, points and clips), right after it. */\n duplicateSlide(index: number): void\n /** Move a slide to `to` (the others shift up or down). */\n moveSlide(index: number, to: number): void\n goTo(index: number): void\n setBlank(blank: boolean): void\n setCaptions(captions: boolean): void\n setLabelColumn(tagId: string | null): void\n setColumnValues(values: Readonly<Record<string, string>>): void\n setPresenting(presenting: boolean): void\n setDragging(clipId: string | null): void\n setTitle(title: string): void\n notify(text: string, kind: 'success' | 'error'): void\n clearNotice(id: number): void\n /** Show another part of an image or video clip's source (a new crop): its area and shape. */\n cropClip(clipId: string, rect: Rect, aspect: number): void\n /**\n * A clip reshaped on the current slide (`reshapeFrame`): it shows `rect` of its source, in\n * `frame`, at the same scale and zoom. Slides arranging themselves arrange around its new shape.\n */\n reshapeClip(clipId: string, frame: Frame, rect: Rect, aspect: number): void\n /** A text box or shape on a slide (default the current one), on top; resolves with its id. */\n addBox(box: Omit<SlideBox, 'id'>, index?: number): string\n /** Change a box (wherever it is). */\n updateBox(boxId: string, change: (box: SlideBox) => SlideBox): void\n /** Type a box's text (one paragraph per line, each keeping its style). */\n setBoxText(boxId: string, text: string): void\n removeBox(boxId: string): void\n /** A box over the slide's clips and other boxes, or under them all. */\n restackBox(boxId: string, to: 'front' | 'back'): void\n /** A slide's speaker notes (default the current slide's). */\n setSlideNotes(notes: string, index?: number): void\n /** A slide's own background (none: the theme's). */\n setSlideBackground(background: SlideBackground | undefined, index?: number): void\n /** Saved as this document (under this title), as its `version`. */\n setSaved(savedId: string, title: string, version?: number | null): void\n /** Edited as this document or draft (see `boundTo`). */\n bind(boundTo: string | null): void\n /** Clips gathered before (with no presentation open), added to the tray, not placed. */\n adoptClips(clips: readonly Clip[]): void\n /**\n * A slide of these clips (added to the tray too), arranged, with `caption` as its title: after\n * the current slide, or in its place while that is empty. It becomes the current slide.\n */\n addSlideOf(clips: readonly Clip[], caption?: string): void\n /** Replace the presentation with one opened from a file (its clips' sources fetched). */\n load(opened: {\n title: string\n /** The document it is saved as; null for a new one (from a template). */\n savedId: string | null\n /** Its version, when known. */\n version?: number | null\n /** Edited as (default `savedId`): an older file opened unsaved is still its own. */\n boundTo?: string | null\n captions: boolean\n labelColumn?: string | null\n theme?: Theme\n clips: Omit<Clip, 'id'>[]\n slides: {\n caption: string\n auto: boolean\n layout?: SlideLayout\n points?: string\n items: { clip: number; frame: Frame }[]\n boxes?: readonly SavedBox[]\n background?: SlideBackground\n notes?: string\n }[]\n media?: Readonly<Record<string, string>>\n }): void\n reset(): void\n}\n\nexport type PresentationStore = PresentationState & PresentationActions\n\nlet sequence = 0\nconst nextId = (kind: string) => `${kind}-${Date.now().toString(36)}-${++sequence}`\n\nconst emptySlide = (layout: SlideLayout = 'clips'): Slide => ({\n id: nextId('slide'),\n items: [],\n auto: true,\n caption: '',\n layout,\n points: '',\n boxes: [],\n})\n\nconst initialState = (): PresentationState => ({\n clips: [],\n slides: [emptySlide()],\n current: 0,\n blank: false,\n captions: true,\n theme: DEFAULT_THEME,\n logoImage: null,\n labelColumn: null,\n columnValues: {},\n presenting: false,\n dragging: null,\n notice: null,\n title: 'Untitled presentation',\n savedId: null,\n version: null,\n boundTo: null,\n clean: null,\n media: {},\n})\n\n/** What arranging a slide depends on besides its clips: labels shown, a logo in the footer. */\ntype Look = Pick<PresentationState, 'captions' | 'theme'>\n\n/** The slide arranged again from its clips' aspects, in the room its layout leaves them. */\nfunction arranged(slide: Slide, clips: readonly Clip[], look: Look): Slide {\n const aspects = slide.items.map((item) => aspectOf(clips, item.clipId))\n const frames = autoLayout(aspects, reserveOf(slide, look))\n return {\n ...slide,\n auto: true,\n items: slide.items.map((item, i) => ({ ...item, frame: frames[i] })),\n }\n}\n\n/**\n * The room a slide keeps free of clips: its title and text (by its layout), each clip's label\n * under it, the footer while a logo shows.\n */\nexport const reserveOf = (slide: Pick<Slide, 'caption' | 'layout'>, look: Look): Reserve =>\n slideGeometry(slide, { labels: look.captions, logo: look.theme.logo?.corner ?? null }).reserve\n\nfunction aspectOf(clips: readonly Clip[], clipId: string): number {\n return clips.find((clip) => clip.id === clipId)?.aspect ?? 1\n}\n\nexport const usePresentation = create<PresentationStore>()((set, get) => {\n /** Change the current slide; an auto slide is arranged again after the change. */\n const updateSlide = (change: (slide: Slide, clips: readonly Clip[]) => Slide, at?: number) =>\n set((state) => {\n const index = at ?? state.current\n const slide = state.slides[index]\n if (!slide) return state\n const next = change(slide, state.clips)\n if (next === slide) return state\n const slides = state.slides.slice()\n slides[index] = next.auto ? arranged(next, state.clips, state) : next\n return { slides }\n })\n\n /** Change the boxes of the slide holding `boxId` (`at`: the box's index there). */\n const updateBoxes = (\n boxId: string,\n change: (boxes: readonly SlideBox[], at: number) => SlideBox[]\n ) =>\n set((state) => {\n const index = state.slides.findIndex((slide) => slide.boxes.some((box) => box.id === boxId))\n if (index < 0) return state\n const slide = state.slides[index]\n const slides = state.slides.slice()\n slides[index] = {\n ...slide,\n boxes: change(\n slide.boxes,\n slide.boxes.findIndex((box) => box.id === boxId)\n ),\n }\n return { slides }\n })\n\n /** Restack a clip on the current slide: only the drawing order changes, never a position. */\n const restack = (clipId: string, to: 'front' | 'back') =>\n set((state) => {\n const slide = state.slides[state.current]\n const item = slide?.items.find((entry) => entry.clipId === clipId)\n if (!slide || !item) return state\n const rest = slide.items.filter((entry) => entry !== item)\n const items = to === 'front' ? [...rest, item] : [item, ...rest]\n if (items.every((entry, i) => entry === slide.items[i])) return state\n const slides = state.slides.slice()\n slides[state.current] = { ...slide, items }\n return { slides }\n })\n\n return {\n ...initialState(),\n\n addClip(clip) {\n const id = nextId('clip')\n const full: Clip = {\n ...clip,\n id,\n caption: clip.caption ?? defaultCaption(clip.fileName, clip.page),\n zoomBase: clip.zoomBase ?? clip.rect.w,\n }\n set((state) => ({ clips: [...state.clips, full] }))\n const slide = get().slides[get().current]\n if (slide && slide.items.length < AUTO_PLACE_BELOW) get().place(id)\n return id\n },\n\n removeClip(clipId) {\n const { clips, slides } = get()\n const removed = clips.find((clip) => clip.id === clipId)\n if (!removed) return\n const rest = clips.filter((clip) => clip.id !== clipId)\n set({\n clips: rest,\n slides: slides.map((slide) => {\n if (!slide.items.some((item) => item.clipId === clipId)) return slide\n const next = { ...slide, items: slide.items.filter((item) => item.clipId !== clipId) }\n return next.auto ? arranged(next, rest, get()) : next\n }),\n })\n // The PDF engine's copy of the file goes once no clip is drawn from it.\n if (!rest.some((clip) => clip.source === removed.source))\n releasePdfRegionSource(removed.source)\n },\n\n setCaption: (clipId, caption) =>\n set((state) => ({\n clips: state.clips.map((clip) => (clip.id === clipId ? { ...clip, caption } : clip)),\n })),\n\n place: (clipId, at) =>\n updateSlide((slide, clips) => {\n if (!clips.some((clip) => clip.id === clipId)) return slide\n const others = slide.items.filter((item) => item.clipId !== clipId)\n if (!at && others.length < slide.items.length) return slide\n if (others.length >= MAX_ITEMS_PER_SLIDE) return slide\n const aspect = aspectOf(clips, clipId)\n // An auto slide arranges it with the rest. A slide arranged by hand stays so: the clip goes\n // where it was dropped, or in the middle.\n const frame = slide.auto ? fitFrame(aspect) : dropFrame(aspect, at ?? { x: 0.5, y: 0.5 })\n return { ...slide, items: [...others, { clipId, frame }] }\n }),\n\n unplace: (clipId) =>\n updateSlide((slide) =>\n slide.items.some((item) => item.clipId === clipId)\n ? { ...slide, items: slide.items.filter((item) => item.clipId !== clipId) }\n : slide\n ),\n\n setFrame: (clipId, frame) =>\n updateSlide((slide) => ({\n ...slide,\n auto: false,\n items: slide.items.map((item) => (item.clipId === clipId ? { ...item, frame } : item)),\n })),\n\n applyFrame(clipId, command) {\n const slide = get().slides[get().current]\n const item = slide?.items.find((entry) => entry.clipId === clipId)\n if (!item) return\n const aspect = aspectOf(get().clips, clipId)\n const reserve = reserveOf(slide, get())\n const frame =\n command === 'fullWidth'\n ? fullWidthFrame(item.frame, aspect, reserve)\n : command === 'fullHeight'\n ? fullHeightFrame(item.frame, aspect, reserve)\n : fitFrame(aspect, reserve)\n get().setFrame(clipId, frame)\n // Made the size of the stage, it goes on top of the others.\n get().bringToFront(clipId)\n },\n\n bringToFront: (clipId) => restack(clipId, 'front'),\n sendToBack: (clipId) => restack(clipId, 'back'),\n\n panClip: (clipId, dx, dy) =>\n set((state) => {\n const clip = state.clips.find((entry) => entry.id === clipId)\n if (!clip) return state\n const { rect } = clip\n const x = Math.min(Math.max(rect.x + dx, 0), 1 - rect.w)\n const y = Math.min(Math.max(rect.y + dy, 0), 1 - rect.h)\n if (x === rect.x && y === rect.y) return state\n return {\n clips: state.clips.map((entry) =>\n entry === clip ? { ...clip, rect: { ...rect, x, y } } : entry\n ),\n }\n }),\n\n zoomClip: (clipId, factor) =>\n set((state) => {\n const clip = state.clips.find((entry) => entry.id === clipId)\n if (!clip || !(factor > 0)) return state\n const { rect } = clip\n // Its area scales by 1/factor; never larger than the source, nor smaller than a sliver.\n const largest = Math.min(1 / rect.w, 1 / rect.h)\n const smallest = Math.max(MIN_CLIP_AREA / rect.w, MIN_CLIP_AREA / rect.h)\n const scale = Math.min(Math.max(1 / factor, smallest), largest)\n if (scale === 1) return state\n const w = rect.w * scale\n const h = rect.h * scale\n const x = Math.min(Math.max(rect.x + (rect.w - w) / 2, 0), 1 - w)\n const y = Math.min(Math.max(rect.y + (rect.h - h) / 2, 0), 1 - h)\n return {\n clips: state.clips.map((entry) =>\n entry === clip ? { ...clip, rect: { x, y, w, h } } : entry\n ),\n }\n }),\n\n setClipZoom(clipId, percent) {\n const clip = get().clips.find((entry) => entry.id === clipId)\n if (!clip || !(percent > 0)) return\n const width = (clip.zoomBase ?? clip.rect.w) / (percent / 100)\n get().zoomClip(clipId, clip.rect.w / width)\n },\n\n align(clipId, alignment) {\n const slide = get().slides[get().current]\n const item = slide?.items.find((entry) => entry.clipId === clipId)\n if (!slide || !item) return\n const aspect = aspectOf(get().clips, clipId)\n get().setFrame(clipId, alignFrame(item.frame, aspect, alignment, reserveOf(slide, get())))\n },\n\n nudge(clipId, dx, dy) {\n const slide = get().slides[get().current]\n const item = slide?.items.find((entry) => entry.clipId === clipId)\n if (!item) return\n const aspect = aspectOf(get().clips, clipId)\n get().setFrame(clipId, moveFrame(item.frame, aspect, dx, dy, [], true).frame)\n },\n\n // An auto slide makes (or gives back) the caption's room; one arranged by hand keeps its places.\n // A blank slide's title is its title box's text.\n setSlideCaption: (caption, index) =>\n updateSlide(\n (slide) => ({\n ...slide,\n caption,\n boxes: slide.boxes.map((box) => (box.role === 'title' ? withText(box, caption) : box)),\n }),\n index\n ),\n setSlideLayout: (layout, index) =>\n updateSlide((slide) => ({ ...slide, layout, auto: true }), index),\n setSlidePoints: (points, index) => updateSlide((slide) => ({ ...slide, points }), index),\n\n setTheme: (change) =>\n set((state) => {\n const theme = { ...state.theme, ...change }\n const logoMoved = (theme.logo?.corner ?? null) !== (state.theme.logo?.corner ?? null)\n return {\n theme,\n ...(theme.logo?.documentId !== state.theme.logo?.documentId ? { logoImage: null } : {}),\n slides: logoMoved\n ? state.slides.map((slide) =>\n slide.auto ? arranged(slide, state.clips, { ...state, theme }) : slide\n )\n : state.slides,\n }\n }),\n setLogoImage: (logoImage) => set({ logoImage }),\n\n arrange: () => updateSlide((slide) => ({ ...slide, auto: true })),\n\n addSlide: (layout, after) =>\n set((state) => {\n const at = (after ?? state.current) + 1\n const slides = state.slides.slice()\n const before = state.slides[at - 1]\n const slide = emptySlide(layout ?? before?.layout ?? 'clips')\n // The slide it follows keeps its look (an imported deck's background).\n slides.splice(\n at,\n 0,\n before?.background ? { ...slide, background: before.background } : slide\n )\n return { slides, current: at }\n }),\n\n removeSlide: (index) =>\n set((state) => {\n const target = index ?? state.current\n if (state.slides.length <= 1) return { slides: [emptySlide()], current: 0 }\n const slides = state.slides.filter((_, i) => i !== target)\n const current = state.current > target ? state.current - 1 : state.current\n return { slides, current: Math.min(current, slides.length - 1) }\n }),\n\n duplicateSlide: (index) =>\n set((state) => {\n const slide = state.slides[index]\n if (!slide) return state\n const slides = state.slides.slice()\n slides.splice(index + 1, 0, {\n ...slide,\n id: nextId('slide'),\n items: slide.items.map((item) => ({ ...item, frame: { ...item.frame } })),\n boxes: slide.boxes.map((box) => ({ ...box, id: nextBoxId() })),\n })\n return { slides, current: index + 1 }\n }),\n\n moveSlide: (index, to) =>\n set((state) => {\n if (to < 0 || to >= state.slides.length || index === to || !state.slides[index]) {\n return state\n }\n const slides = state.slides.slice()\n const [slide] = slides.splice(index, 1)\n slides.splice(to, 0, slide)\n return { slides, current: to }\n }),\n\n goTo: (index) =>\n set((state) =>\n index < 0 || index >= state.slides.length || index === state.current\n ? state\n : { current: index }\n ),\n\n setBlank: (blank) => set({ blank }),\n // Slides arranged automatically make (or give back) the captions' room.\n setCaptions: (captions) =>\n set((state) => ({\n captions,\n slides: state.slides.map((slide) =>\n slide.auto ? arranged(slide, state.clips, { ...state, captions }) : slide\n ),\n })),\n setLabelColumn: (labelColumn) => set({ labelColumn }),\n setColumnValues: (columnValues) => set({ columnValues }),\n setPresenting: (presenting) => set({ presenting }),\n setDragging: (dragging) => set({ dragging }),\n setTitle: (title) => set({ title }),\n notify: (text, kind) => set({ notice: { text, kind, id: ++sequence } }),\n clearNotice: (id) => set((state) => (state.notice?.id === id ? { notice: null } : state)),\n\n cropClip: (clipId, rect, aspect) =>\n set((state) => {\n const clips = state.clips.map((clip) =>\n clip.id === clipId ? { ...clip, rect, aspect } : clip\n )\n return {\n clips,\n // Its shape changed: slides arranged automatically arrange again around it.\n slides: state.slides.map((slide) =>\n slide.auto && slide.items.some((item) => item.clipId === clipId)\n ? arranged(slide, clips, state)\n : slide\n ),\n }\n }),\n reshapeClip: (clipId, frame, rect, aspect) =>\n set((state) => {\n const clip = state.clips.find((entry) => entry.id === clipId)\n if (!clip) return state\n // Its zoom reads against its width when cut: that scales with the width it now shows.\n const zoomBase = ((clip.zoomBase ?? clip.rect.w) * rect.w) / clip.rect.w\n const clips = state.clips.map((entry) =>\n entry === clip ? { ...clip, rect, aspect, zoomBase } : entry\n )\n return {\n clips,\n slides: state.slides.map((slide, index) => {\n if (index === state.current) {\n return {\n ...slide,\n auto: false,\n items: slide.items.map((item) =>\n item.clipId === clipId ? { ...item, frame } : item\n ),\n }\n }\n return slide.auto && slide.items.some((item) => item.clipId === clipId)\n ? arranged(slide, clips, state)\n : slide\n }),\n }\n }),\n addBox(box, index) {\n const id = nextBoxId()\n updateSlide((slide) => ({ ...slide, boxes: [...slide.boxes, { ...box, id }] }), index)\n return id\n },\n updateBox: (boxId, change) =>\n updateBoxes(boxId, (boxes, at) => {\n const next = boxes.slice()\n next[at] = change(boxes[at])\n return next\n }),\n setBoxText(boxId, text) {\n get().updateBox(boxId, (box) => withText(box, text))\n // A blank slide's title box is its title too (what an outline reads).\n set((state) => ({\n slides: state.slides.map((slide) =>\n slide.boxes.some((box) => box.id === boxId && box.role === 'title')\n ? { ...slide, caption: text.replace(/\\s*\\n\\s*/g, ' ').trim() }\n : slide\n ),\n }))\n },\n removeBox: (boxId) => updateBoxes(boxId, (boxes, at) => boxes.filter((_, i) => i !== at)),\n restackBox: (boxId, to) =>\n updateBoxes(boxId, (boxes, at) => {\n const box = { ...boxes[at], front: to === 'front' }\n const rest = boxes.filter((_, i) => i !== at)\n return to === 'front' ? [...rest, box] : [box, ...rest]\n }),\n setSlideNotes: (notes, index) => updateSlide((slide) => ({ ...slide, notes }), index),\n setSlideBackground: (background, index) =>\n updateSlide((slide) => {\n const { background: _old, ...rest } = slide\n void _old\n return background ? { ...rest, background } : rest\n }, index),\n setSaved: (savedId, title, version = null) => {\n set({ savedId, title, boundTo: savedId, version })\n set({ clean: snapshotOf(get()) })\n },\n bind: (boundTo) => set({ boundTo }),\n adoptClips: (adopted) =>\n set((state) => ({\n clips: [\n ...state.clips,\n ...adopted.filter((clip) => !state.clips.some((entry) => entry.id === clip.id)),\n ],\n })),\n\n addSlideOf: (added, caption = '') =>\n set((state) => {\n const fresh = added.map((clip) => ({ ...clip, id: nextId('clip') }))\n const clips = [...state.clips, ...fresh]\n const slide = arranged(\n {\n ...emptySlide('clips'),\n caption,\n items: fresh.map((clip) => ({ clipId: clip.id, frame: fitFrame(clip.aspect) })),\n },\n clips,\n state\n )\n const here = state.slides[state.current]\n const empty =\n !!here &&\n !here.items.length &&\n !here.boxes.length &&\n !here.caption.trim() &&\n !here.points.trim()\n const at = empty ? state.current : state.current + 1\n const slides = state.slides.slice()\n slides.splice(at, empty ? 1 : 0, slide)\n return { clips, slides, current: at }\n }),\n\n load(opened) {\n get().reset()\n const clips: Clip[] = opened.clips.map((clip) => ({ ...clip, id: nextId('clip') }))\n const slides: Slide[] = opened.slides.map((slide) => ({\n id: nextId('slide'),\n caption: slide.caption,\n auto: slide.auto,\n layout: slide.layout ?? 'clips',\n points: slide.points ?? '',\n // Items whose clip could not be opened are left out.\n items: slide.items\n .filter((item) => clips[item.clip])\n .map((item) => ({ clipId: clips[item.clip].id, frame: item.frame })),\n boxes: (slide.boxes ?? []).map((box) => ({ ...box, id: nextBoxId() })),\n ...(slide.background ? { background: slide.background } : {}),\n ...(slide.notes ? { notes: slide.notes } : {}),\n }))\n set({\n title: opened.title,\n savedId: opened.savedId,\n version: opened.version ?? null,\n boundTo: opened.boundTo ?? opened.savedId,\n captions: opened.captions,\n labelColumn: opened.labelColumn ?? null,\n theme: opened.theme ?? DEFAULT_THEME,\n clips,\n slides: slides.length ? slides : [emptySlide()],\n current: 0,\n media: opened.media ?? {},\n })\n set({ clean: opened.savedId ? snapshotOf(get()) : null })\n },\n\n reset() {\n for (const source of new Set(get().clips.map((clip) => clip.source))) {\n releasePdfRegionSource(source)\n }\n set(initialState())\n },\n }\n})\n\n/** The slide on the stage. */\nexport const currentSlide = (state: PresentationState): Slide | undefined =>\n state.slides[state.current]\n\n/** What is saved of a presentation, as text (to compare). */\nfunction snapshotOf(state: PresentationState): string {\n // Embedded images change only with the clips that show them: left out, so comparing stays cheap.\n return JSON.stringify(serializePresentation({ ...state, media: undefined }))\n}\n\n/**\n * The presentation has changes not saved: since it was opened or saved; or, never saved, anything\n * in it at all (a clip, a title, a point).\n */\nexport function hasUnsavedChanges(state: PresentationState): boolean {\n if (state.clean !== null) return snapshotOf(state) !== state.clean\n return (\n state.clips.length > 0 ||\n state.slides.some(\n (slide) =>\n slide.items.length || slide.boxes.length || slide.caption.trim() || slide.points.trim()\n )\n )\n}\n"]}
@@ -1,9 +1,9 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunk7PN3YENO_cjs = require('./chunk-7PN3YENO.cjs');
5
- var chunk5QERK4PK_cjs = require('./chunk-5QERK4PK.cjs');
6
- var chunkALK3PUUB_cjs = require('./chunk-ALK3PUUB.cjs');
4
+ var chunkQIK7E6VF_cjs = require('./chunk-QIK7E6VF.cjs');
5
+ var chunkAS6QZETU_cjs = require('./chunk-AS6QZETU.cjs');
6
+ var chunkL6HTZIBD_cjs = require('./chunk-L6HTZIBD.cjs');
7
7
  var chunkTMX7YFVM_cjs = require('./chunk-TMX7YFVM.cjs');
8
8
  var react$1 = require('react');
9
9
  var react = require('@arbidocs/react');
@@ -87,14 +87,14 @@ function ConnectedTagEntity({
87
87
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Created:" }),
88
88
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: ui.formatFriendlyDate(tag.created_at) }),
89
89
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "by" }),
90
- /* @__PURE__ */ jsxRuntime.jsx(chunk5QERK4PK_cjs.UserAvatar, { user: creator ?? void 0 })
90
+ /* @__PURE__ */ jsxRuntime.jsx(chunkAS6QZETU_cjs.UserAvatar, { user: creator ?? void 0 })
91
91
  ] }),
92
92
  tag.updated_at && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
93
93
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "Updated:" }),
94
94
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: ui.formatFriendlyDate(tag.updated_at) }),
95
95
  updater && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
96
96
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: "by" }),
97
- /* @__PURE__ */ jsxRuntime.jsx(chunk5QERK4PK_cjs.UserAvatar, { user: updater })
97
+ /* @__PURE__ */ jsxRuntime.jsx(chunkAS6QZETU_cjs.UserAvatar, { user: updater })
98
98
  ] })
99
99
  ] })
100
100
  ] })
@@ -116,8 +116,8 @@ function FolderPicker({
116
116
  value,
117
117
  onSelect
118
118
  }) {
119
- const folders = chunk5QERK4PK_cjs.useDocumentFolders(documents, value);
120
- return /* @__PURE__ */ jsxRuntime.jsx(chunkALK3PUUB_cjs.FolderCommandList, { folders, value, onSelect, showRemove: !!value });
119
+ const folders = chunkAS6QZETU_cjs.useDocumentFolders(documents, value);
120
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkL6HTZIBD_cjs.FolderCommandList, { folders, value, onSelect, showRemove: !!value });
121
121
  }
122
122
  function RelatedDocuments({
123
123
  doc,
@@ -129,7 +129,7 @@ function RelatedDocuments({
129
129
  }) {
130
130
  const viewingDocumentId = react.useOpenViewerDocumentId();
131
131
  return /* @__PURE__ */ jsxRuntime.jsx(
132
- chunk5QERK4PK_cjs.RelatedDocumentsCell,
132
+ chunkAS6QZETU_cjs.RelatedDocumentsCell,
133
133
  {
134
134
  currentDoc: doc,
135
135
  related,
@@ -152,9 +152,9 @@ function DocTagAttribution({ doctag }) {
152
152
  updater && `Updated ${ui.formatFriendlyDate(doctag.updated_at)} by ${updater.given_name || updater.email}`
153
153
  ].filter((line) => !!line);
154
154
  return /* @__PURE__ */ jsxRuntime.jsx(
155
- chunkALK3PUUB_cjs.FieldAttribution,
155
+ chunkL6HTZIBD_cjs.FieldAttribution,
156
156
  {
157
- avatar: /* @__PURE__ */ jsxRuntime.jsx(chunk7PN3YENO_cjs.DocumentUser, { user: lastUser, tooltip: false }),
157
+ avatar: /* @__PURE__ */ jsxRuntime.jsx(chunkQIK7E6VF_cjs.DocumentUser, { user: lastUser, tooltip: false }),
158
158
  date: ui.formatFriendlyDate(updater ? doctag.updated_at : doctag.created_at),
159
159
  lines
160
160
  }
@@ -182,7 +182,7 @@ function LabelsCombobox({
182
182
  else if (!appliedTagIds.has(existing.external_id)) onToggle(existing);
183
183
  };
184
184
  return /* @__PURE__ */ jsxRuntime.jsx(
185
- chunkALK3PUUB_cjs.FieldLabelsSelect,
185
+ chunkL6HTZIBD_cjs.FieldLabelsSelect,
186
186
  {
187
187
  options,
188
188
  appliedIds: appliedTagIds,
@@ -204,15 +204,15 @@ var METADATA_FIELDS = {
204
204
  };
205
205
  var INPUT_CLASS = "text-sm bg-muted/40 focus:bg-background transition-colors";
206
206
  var READ_ONLY_FIELDS = {
207
- file_name: (doc) => /* @__PURE__ */ jsxRuntime.jsx(chunkALK3PUUB_cjs.FieldValue, { tone: "strong", children: doc.file_name || "N/A" }),
208
- status: (doc) => /* @__PURE__ */ jsxRuntime.jsx(chunkALK3PUUB_cjs.FieldValue, { tone: "muted", children: doc.status || "N/A" }),
209
- n_pages: (doc) => /* @__PURE__ */ jsxRuntime.jsx(chunkALK3PUUB_cjs.FieldValue, { tone: "muted", children: doc.n_pages || "N/A" }),
210
- created_at: (doc) => /* @__PURE__ */ jsxRuntime.jsx(chunkALK3PUUB_cjs.FieldValue, { tone: "muted", children: doc.created_at ? ui.formatFriendlyDate(doc.created_at) : "N/A" }),
211
- updated_at: (doc) => /* @__PURE__ */ jsxRuntime.jsx(chunkALK3PUUB_cjs.FieldValue, { tone: "muted", children: doc.updated_at ? ui.formatFriendlyDate(doc.updated_at) : "N/A" }),
212
- file_type: (doc) => /* @__PURE__ */ jsxRuntime.jsx(chunkALK3PUUB_cjs.FieldValue, { tone: "muted", children: ui.friendlyFileType(doc.file_type, doc.file_name, doc.folder) }),
213
- file_size: (doc) => /* @__PURE__ */ jsxRuntime.jsx(chunkALK3PUUB_cjs.FieldValue, { tone: "muted", children: doc.file_size ? `${Math.round(doc.file_size / 1024)} KB` : "N/A" }),
214
- doc_id: (doc) => /* @__PURE__ */ jsxRuntime.jsx(chunkALK3PUUB_cjs.FieldValue, { tone: "muted", isMono: true, children: doc.external_id || "N/A" }),
215
- content_hash: (doc) => /* @__PURE__ */ jsxRuntime.jsx(chunkALK3PUUB_cjs.FieldValue, { tone: "muted", isMono: true, isTruncated: true, children: doc.content_hash || "N/A" })
207
+ file_name: (doc) => /* @__PURE__ */ jsxRuntime.jsx(chunkL6HTZIBD_cjs.FieldValue, { tone: "strong", children: doc.file_name || "N/A" }),
208
+ status: (doc) => /* @__PURE__ */ jsxRuntime.jsx(chunkL6HTZIBD_cjs.FieldValue, { tone: "muted", children: doc.status || "N/A" }),
209
+ n_pages: (doc) => /* @__PURE__ */ jsxRuntime.jsx(chunkL6HTZIBD_cjs.FieldValue, { tone: "muted", children: doc.n_pages || "N/A" }),
210
+ created_at: (doc) => /* @__PURE__ */ jsxRuntime.jsx(chunkL6HTZIBD_cjs.FieldValue, { tone: "muted", children: doc.created_at ? ui.formatFriendlyDate(doc.created_at) : "N/A" }),
211
+ updated_at: (doc) => /* @__PURE__ */ jsxRuntime.jsx(chunkL6HTZIBD_cjs.FieldValue, { tone: "muted", children: doc.updated_at ? ui.formatFriendlyDate(doc.updated_at) : "N/A" }),
212
+ file_type: (doc) => /* @__PURE__ */ jsxRuntime.jsx(chunkL6HTZIBD_cjs.FieldValue, { tone: "muted", children: ui.friendlyFileType(doc.file_type, doc.file_name, doc.folder) }),
213
+ file_size: (doc) => /* @__PURE__ */ jsxRuntime.jsx(chunkL6HTZIBD_cjs.FieldValue, { tone: "muted", children: doc.file_size ? `${Math.round(doc.file_size / 1024)} KB` : "N/A" }),
214
+ doc_id: (doc) => /* @__PURE__ */ jsxRuntime.jsx(chunkL6HTZIBD_cjs.FieldValue, { tone: "muted", isMono: true, children: doc.external_id || "N/A" }),
215
+ content_hash: (doc) => /* @__PURE__ */ jsxRuntime.jsx(chunkL6HTZIBD_cjs.FieldValue, { tone: "muted", isMono: true, isTruncated: true, children: doc.content_hash || "N/A" })
216
216
  };
217
217
  function documentFieldContent(options) {
218
218
  const { columnId, doc, canEdit, workspaceTags, getColumnLabel, getColumnIcon } = options;
@@ -235,16 +235,16 @@ function documentFieldContent(options) {
235
235
  placeholder: `Add ${getColumnLabel(columnId).toLowerCase()}\u2026`,
236
236
  className: INPUT_CLASS
237
237
  }
238
- ) : /* @__PURE__ */ jsxRuntime.jsx(chunkALK3PUUB_cjs.FieldValue, { children: metadata(doc) || "N/A" })
238
+ ) : /* @__PURE__ */ jsxRuntime.jsx(chunkL6HTZIBD_cjs.FieldValue, { children: metadata(doc) || "N/A" })
239
239
  );
240
240
  }
241
241
  const readOnly = READ_ONLY_FIELDS[columnId];
242
242
  if (readOnly) return standard(readOnly(doc));
243
- if (columnId === "created_by") return standard(/* @__PURE__ */ jsxRuntime.jsx(chunk7PN3YENO_cjs.DocumentUser, { user: options.creator }));
243
+ if (columnId === "created_by") return standard(/* @__PURE__ */ jsxRuntime.jsx(chunkQIK7E6VF_cjs.DocumentUser, { user: options.creator }));
244
244
  if (columnId === "folder") {
245
245
  return standard(
246
246
  canEdit ? /* @__PURE__ */ jsxRuntime.jsx(
247
- chunkALK3PUUB_cjs.FieldFolderSelect,
247
+ chunkL6HTZIBD_cjs.FieldFolderSelect,
248
248
  {
249
249
  folder: doc.folder,
250
250
  picker: /* @__PURE__ */ jsxRuntime.jsx(
@@ -256,7 +256,7 @@ function documentFieldContent(options) {
256
256
  }
257
257
  )
258
258
  }
259
- ) : /* @__PURE__ */ jsxRuntime.jsx(chunkALK3PUUB_cjs.FieldFolderValue, { folder: doc.folder })
259
+ ) : /* @__PURE__ */ jsxRuntime.jsx(chunkL6HTZIBD_cjs.FieldFolderValue, { folder: doc.folder })
260
260
  );
261
261
  }
262
262
  if (columnId === "related") {
@@ -299,7 +299,7 @@ function documentFieldContent(options) {
299
299
  let value;
300
300
  if (tag.tag_type.type === "select") {
301
301
  value = /* @__PURE__ */ jsxRuntime.jsx(
302
- chunkALK3PUUB_cjs.FieldNativeSelect,
302
+ chunkL6HTZIBD_cjs.FieldNativeSelect,
303
303
  {
304
304
  value: doctag?.note || "",
305
305
  options: tag.tag_type.options,
@@ -333,12 +333,12 @@ function documentFieldContent(options) {
333
333
  return {
334
334
  label: tag.name,
335
335
  tag,
336
- children: doctag ? /* @__PURE__ */ jsxRuntime.jsx(chunkALK3PUUB_cjs.FieldWithAttribution, { attribution: /* @__PURE__ */ jsxRuntime.jsx(DocTagAttribution, { doctag }), children: value }) : value
336
+ children: doctag ? /* @__PURE__ */ jsxRuntime.jsx(chunkL6HTZIBD_cjs.FieldWithAttribution, { attribution: /* @__PURE__ */ jsxRuntime.jsx(DocTagAttribution, { doctag }), children: value }) : value
337
337
  };
338
338
  }
339
339
 
340
340
  exports.ConnectedTagEntity = ConnectedTagEntity;
341
341
  exports.documentFieldContent = documentFieldContent;
342
342
  exports.useMemberLookup = useMemberLookup;
343
- //# sourceMappingURL=chunk-MLA2BJ2Y.cjs.map
344
- //# sourceMappingURL=chunk-MLA2BJ2Y.cjs.map
343
+ //# sourceMappingURL=chunk-PSB64T43.cjs.map
344
+ //# sourceMappingURL=chunk-PSB64T43.cjs.map