pptx-react-viewer 1.25.4 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (230) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +1 -1
  3. package/dist/AiChatPanel-BRGQCYZM.mjs +1087 -0
  4. package/dist/AiChatPanel-BRGQCYZM.mjs.br +0 -0
  5. package/dist/AiChatPanel-BRGQCYZM.mjs.gz +0 -0
  6. package/dist/AiChatPanel-PW5OT25Z.js +1089 -0
  7. package/dist/AiChatPanel-PW5OT25Z.js.br +0 -0
  8. package/dist/AiChatPanel-PW5OT25Z.js.gz +0 -0
  9. package/dist/{GLTFLoader-NMAS6VRH.mjs → GLTFLoader-374ZNTXW.mjs} +1 -1
  10. package/dist/GLTFLoader-374ZNTXW.mjs.br +0 -0
  11. package/dist/GLTFLoader-374ZNTXW.mjs.gz +0 -0
  12. package/dist/{GLTFLoader-GP55DVVS.js → GLTFLoader-Q7BHCGAW.js} +1 -1
  13. package/dist/GLTFLoader-Q7BHCGAW.js.br +0 -0
  14. package/dist/GLTFLoader-Q7BHCGAW.js.gz +0 -0
  15. package/dist/{Model3DScene-SP6WOKSX.js → Model3DScene-JCGYRKXM.js} +4 -4
  16. package/dist/{Model3DScene-SP6WOKSX.js.br → Model3DScene-JCGYRKXM.js.br} +0 -0
  17. package/dist/Model3DScene-JCGYRKXM.js.gz +0 -0
  18. package/dist/{Model3DScene-DZFYJPUH.mjs → Model3DScene-TEF362W2.mjs} +3 -3
  19. package/dist/Model3DScene-TEF362W2.mjs.br +0 -0
  20. package/dist/Model3DScene-TEF362W2.mjs.gz +0 -0
  21. package/dist/{OrbitControls-VH6KILH7.js → OrbitControls-SMYCPLXO.js} +1 -1
  22. package/dist/OrbitControls-SMYCPLXO.js.br +3 -0
  23. package/dist/OrbitControls-SMYCPLXO.js.gz +0 -0
  24. package/dist/{OrbitControls-F5XPYD2Z.mjs → OrbitControls-ZTGHPI5G.mjs} +1 -1
  25. package/dist/OrbitControls-ZTGHPI5G.mjs.br +0 -0
  26. package/dist/{OrbitControls-F5XPYD2Z.mjs.gz → OrbitControls-ZTGHPI5G.mjs.gz} +0 -0
  27. package/dist/{PowerPointViewer-CnADroqZ.d.ts → PowerPointViewer-gmU5rc7K.d.ts} +2 -2
  28. package/dist/PowerPointViewer-gmU5rc7K.d.ts.map +1 -0
  29. package/dist/{SmartArt3DScene-WQIDFZ7X.mjs → SmartArt3DScene-XCFVGCXE.mjs} +1 -1
  30. package/dist/SmartArt3DScene-XCFVGCXE.mjs.br +0 -0
  31. package/dist/SmartArt3DScene-XCFVGCXE.mjs.gz +0 -0
  32. package/dist/{SmartArt3DScene-HCQBDRAM.js → SmartArt3DScene-ZO3KFDI2.js} +1 -1
  33. package/dist/SmartArt3DScene-ZO3KFDI2.js.br +0 -0
  34. package/dist/SmartArt3DScene-ZO3KFDI2.js.gz +0 -0
  35. package/dist/{SurfaceChart3DScene-GISPZ4C2.js → SurfaceChart3DScene-2SHCYZVC.js} +4 -4
  36. package/dist/SurfaceChart3DScene-2SHCYZVC.js.br +0 -0
  37. package/dist/SurfaceChart3DScene-2SHCYZVC.js.gz +0 -0
  38. package/dist/{SurfaceChart3DScene-54BRNPQ5.mjs → SurfaceChart3DScene-UPDCIMJM.mjs} +3 -3
  39. package/dist/{SurfaceChart3DScene-54BRNPQ5.mjs.br → SurfaceChart3DScene-UPDCIMJM.mjs.br} +0 -0
  40. package/dist/SurfaceChart3DScene-UPDCIMJM.mjs.gz +0 -0
  41. package/dist/{animation-timeline-CEJJLFqK.d.ts → animation-timeline-eb5z0SHW.d.ts} +250 -8
  42. package/dist/animation-timeline-eb5z0SHW.d.ts.map +1 -0
  43. package/dist/{chunk-M3SIFXWD.mjs → chunk-2X72MOPZ.mjs} +65 -0
  44. package/dist/chunk-2X72MOPZ.mjs.br +0 -0
  45. package/dist/chunk-2X72MOPZ.mjs.gz +0 -0
  46. package/dist/{chunk-QGM4M3NI.js → chunk-4VNS5WPM.js} +5 -0
  47. package/dist/chunk-4VNS5WPM.js.br +0 -0
  48. package/dist/chunk-4VNS5WPM.js.gz +0 -0
  49. package/dist/{chunk-P72VQ7WE.mjs → chunk-5XLLRPMV.mjs} +8966 -16340
  50. package/dist/chunk-5XLLRPMV.mjs.br +0 -0
  51. package/dist/chunk-5XLLRPMV.mjs.gz +0 -0
  52. package/dist/{chunk-UYNOPUSG.mjs → chunk-6YXLGMTN.mjs} +4137 -1927
  53. package/dist/chunk-6YXLGMTN.mjs.br +0 -0
  54. package/dist/chunk-6YXLGMTN.mjs.gz +0 -0
  55. package/dist/chunk-B6NRDUHJ.mjs +8029 -0
  56. package/dist/chunk-B6NRDUHJ.mjs.br +0 -0
  57. package/dist/chunk-B6NRDUHJ.mjs.gz +0 -0
  58. package/dist/chunk-BHVCED34.mjs +16664 -0
  59. package/dist/chunk-BHVCED34.mjs.br +0 -0
  60. package/dist/chunk-BHVCED34.mjs.gz +0 -0
  61. package/dist/{chunk-FWF2SP6N.js → chunk-CLNGAVNH.js} +4142 -1926
  62. package/dist/chunk-CLNGAVNH.js.br +0 -0
  63. package/dist/chunk-CLNGAVNH.js.gz +0 -0
  64. package/dist/{chunk-2EFVXYNA.js → chunk-CUUYYYC5.js} +65 -0
  65. package/dist/chunk-CUUYYYC5.js.br +0 -0
  66. package/dist/chunk-CUUYYYC5.js.gz +0 -0
  67. package/dist/{chunk-TPG2WKHQ.mjs → chunk-L63RAVM7.mjs} +1286 -151
  68. package/dist/chunk-L63RAVM7.mjs.br +0 -0
  69. package/dist/chunk-L63RAVM7.mjs.gz +0 -0
  70. package/dist/{chunk-5VYVKFMS.js → chunk-LFXG7SGG.js} +2074 -939
  71. package/dist/chunk-LFXG7SGG.js.br +0 -0
  72. package/dist/chunk-LFXG7SGG.js.gz +0 -0
  73. package/dist/{chunk-6F4WVHS3.js → chunk-OKOJVSKJ.js} +4701 -656
  74. package/dist/chunk-OKOJVSKJ.js.br +0 -0
  75. package/dist/chunk-OKOJVSKJ.js.gz +0 -0
  76. package/dist/{chunk-VUC3UPLM.mjs → chunk-R2N2UYT7.mjs} +4647 -618
  77. package/dist/chunk-R2N2UYT7.mjs.br +0 -0
  78. package/dist/chunk-R2N2UYT7.mjs.gz +0 -0
  79. package/dist/chunk-SYPHGLIB.js +16701 -0
  80. package/dist/chunk-SYPHGLIB.js.br +0 -0
  81. package/dist/chunk-SYPHGLIB.js.gz +0 -0
  82. package/dist/{chunk-6DZX6EAA.mjs → chunk-XGB3TDIC.mjs} +5 -1
  83. package/dist/chunk-XGB3TDIC.mjs.br +0 -0
  84. package/dist/chunk-XGB3TDIC.mjs.gz +0 -0
  85. package/dist/chunk-ZB4NZRCI.js +11111 -0
  86. package/dist/chunk-ZB4NZRCI.js.br +0 -0
  87. package/dist/chunk-ZB4NZRCI.js.gz +0 -0
  88. package/dist/chunk-ZKDE3HJI.js +8121 -0
  89. package/dist/chunk-ZKDE3HJI.js.br +0 -0
  90. package/dist/chunk-ZKDE3HJI.js.gz +0 -0
  91. package/dist/{dist-QU6JIDAF.js → dist-4LUVI3SW.js} +587 -563
  92. package/dist/dist-4LUVI3SW.js.br +0 -0
  93. package/dist/dist-4LUVI3SW.js.gz +0 -0
  94. package/dist/dist-J6PC54PZ.mjs +2 -0
  95. package/dist/dist-J6PC54PZ.mjs.br +0 -0
  96. package/dist/dist-J6PC54PZ.mjs.gz +0 -0
  97. package/dist/i18n.js +5 -5
  98. package/dist/i18n.js.br +0 -0
  99. package/dist/i18n.js.gz +0 -0
  100. package/dist/i18n.mjs +2 -2
  101. package/dist/i18n.mjs.br +0 -0
  102. package/dist/i18n.mjs.gz +0 -0
  103. package/dist/{index-DWvM1PBB.d.ts → index-a8wcFjRJ.d.ts} +24 -7
  104. package/dist/index-a8wcFjRJ.d.ts.map +1 -0
  105. package/dist/index.d.ts +3333 -301
  106. package/dist/index.d.ts.map +1 -1
  107. package/dist/index.js +41 -39
  108. package/dist/index.js.br +0 -0
  109. package/dist/index.js.gz +0 -0
  110. package/dist/index.mjs +8 -6
  111. package/dist/index.mjs.br +0 -0
  112. package/dist/index.mjs.gz +0 -0
  113. package/dist/{hooks-unstable.d.ts → internals.d.ts} +1298 -795
  114. package/dist/internals.d.ts.map +1 -0
  115. package/dist/{hooks-unstable.js → internals.js} +81 -80
  116. package/dist/internals.js.br +0 -0
  117. package/dist/internals.js.gz +0 -0
  118. package/dist/{hooks-unstable.mjs → internals.mjs} +6 -5
  119. package/dist/internals.mjs.br +0 -0
  120. package/dist/internals.mjs.gz +0 -0
  121. package/dist/pptx-viewer.css +1 -1
  122. package/dist/pptx-viewer.css.br +0 -0
  123. package/dist/pptx-viewer.css.gz +0 -0
  124. package/dist/{three.module-7CXEVRKB.mjs → three.module-AC7ESV4W.mjs} +1 -1
  125. package/dist/three.module-AC7ESV4W.mjs.br +0 -0
  126. package/dist/three.module-AC7ESV4W.mjs.gz +0 -0
  127. package/dist/{three.module-CPZZFD2Q.js → three.module-GNNNRIMK.js} +1 -1
  128. package/dist/three.module-GNNNRIMK.js.br +0 -0
  129. package/dist/three.module-GNNNRIMK.js.gz +0 -0
  130. package/dist/{useViewerBuildingBlocks-ll3_ncCH.d.ts → useViewerBuildingBlocks-CjureTRf.d.ts} +185 -174
  131. package/dist/useViewerBuildingBlocks-CjureTRf.d.ts.map +1 -0
  132. package/dist/viewer/index.d.ts +692 -53
  133. package/dist/viewer/index.d.ts.map +1 -1
  134. package/dist/viewer/index.js +35 -33
  135. package/dist/viewer/index.js.br +0 -0
  136. package/dist/viewer/index.js.gz +0 -0
  137. package/dist/viewer/index.mjs +8 -6
  138. package/dist/viewer/index.mjs.br +0 -0
  139. package/dist/viewer/index.mjs.gz +0 -0
  140. package/dist/{y-webrtc-6CRYHAXH.mjs → y-webrtc-DGVURJIF.mjs} +1 -1
  141. package/dist/y-webrtc-DGVURJIF.mjs.br +0 -0
  142. package/dist/y-webrtc-DGVURJIF.mjs.gz +0 -0
  143. package/dist/{y-webrtc-QCZF75JW.js → y-webrtc-YN53KW3J.js} +5 -5
  144. package/dist/y-webrtc-YN53KW3J.js.br +0 -0
  145. package/dist/y-webrtc-YN53KW3J.js.gz +0 -0
  146. package/dist/{y-websocket-QJEM6VOB.js → y-websocket-HZCIQLM6.js} +1 -1
  147. package/dist/y-websocket-HZCIQLM6.js.br +0 -0
  148. package/dist/y-websocket-HZCIQLM6.js.gz +0 -0
  149. package/dist/{y-websocket-57Q3RNHC.mjs → y-websocket-P5LTAJ5T.mjs} +1 -1
  150. package/dist/y-websocket-P5LTAJ5T.mjs.br +0 -0
  151. package/dist/y-websocket-P5LTAJ5T.mjs.gz +0 -0
  152. package/dist/{yjs-Y7IYUWOG.mjs → yjs-FKGX4QHS.mjs} +1 -1
  153. package/dist/yjs-FKGX4QHS.mjs.br +0 -0
  154. package/dist/yjs-FKGX4QHS.mjs.gz +0 -0
  155. package/dist/{yjs-UH3EPF3C.js → yjs-HBLSEMHP.js} +1 -1
  156. package/dist/yjs-HBLSEMHP.js.br +0 -0
  157. package/dist/yjs-HBLSEMHP.js.gz +0 -0
  158. package/package.json +19 -7
  159. package/dist/GLTFLoader-GP55DVVS.js.br +0 -0
  160. package/dist/GLTFLoader-GP55DVVS.js.gz +0 -0
  161. package/dist/GLTFLoader-NMAS6VRH.mjs.br +0 -0
  162. package/dist/GLTFLoader-NMAS6VRH.mjs.gz +0 -0
  163. package/dist/Model3DScene-DZFYJPUH.mjs.br +0 -0
  164. package/dist/Model3DScene-DZFYJPUH.mjs.gz +0 -0
  165. package/dist/Model3DScene-SP6WOKSX.js.gz +0 -0
  166. package/dist/OrbitControls-F5XPYD2Z.mjs.br +0 -0
  167. package/dist/OrbitControls-VH6KILH7.js.br +0 -2
  168. package/dist/OrbitControls-VH6KILH7.js.gz +0 -0
  169. package/dist/PowerPointViewer-CnADroqZ.d.ts.map +0 -1
  170. package/dist/SmartArt3DScene-HCQBDRAM.js.br +0 -0
  171. package/dist/SmartArt3DScene-HCQBDRAM.js.gz +0 -0
  172. package/dist/SmartArt3DScene-WQIDFZ7X.mjs.br +0 -0
  173. package/dist/SmartArt3DScene-WQIDFZ7X.mjs.gz +0 -0
  174. package/dist/SurfaceChart3DScene-54BRNPQ5.mjs.gz +0 -0
  175. package/dist/SurfaceChart3DScene-GISPZ4C2.js.br +0 -0
  176. package/dist/SurfaceChart3DScene-GISPZ4C2.js.gz +0 -0
  177. package/dist/animation-timeline-CEJJLFqK.d.ts.map +0 -1
  178. package/dist/chunk-2EFVXYNA.js.br +0 -0
  179. package/dist/chunk-2EFVXYNA.js.gz +0 -0
  180. package/dist/chunk-5VYVKFMS.js.br +0 -0
  181. package/dist/chunk-5VYVKFMS.js.gz +0 -0
  182. package/dist/chunk-6DZX6EAA.mjs.br +0 -0
  183. package/dist/chunk-6DZX6EAA.mjs.gz +0 -0
  184. package/dist/chunk-6F4WVHS3.js.br +0 -0
  185. package/dist/chunk-6F4WVHS3.js.gz +0 -0
  186. package/dist/chunk-7FE27DDH.js +0 -18559
  187. package/dist/chunk-7FE27DDH.js.br +0 -0
  188. package/dist/chunk-7FE27DDH.js.gz +0 -0
  189. package/dist/chunk-FWF2SP6N.js.br +0 -0
  190. package/dist/chunk-FWF2SP6N.js.gz +0 -0
  191. package/dist/chunk-M3SIFXWD.mjs.br +0 -0
  192. package/dist/chunk-M3SIFXWD.mjs.gz +0 -0
  193. package/dist/chunk-P72VQ7WE.mjs.br +0 -0
  194. package/dist/chunk-P72VQ7WE.mjs.gz +0 -0
  195. package/dist/chunk-QGM4M3NI.js.br +0 -0
  196. package/dist/chunk-QGM4M3NI.js.gz +0 -0
  197. package/dist/chunk-TPG2WKHQ.mjs.br +0 -0
  198. package/dist/chunk-TPG2WKHQ.mjs.gz +0 -0
  199. package/dist/chunk-UYNOPUSG.mjs.br +0 -0
  200. package/dist/chunk-UYNOPUSG.mjs.gz +0 -0
  201. package/dist/chunk-VUC3UPLM.mjs.br +0 -0
  202. package/dist/chunk-VUC3UPLM.mjs.gz +0 -0
  203. package/dist/dist-QNYKM7YS.mjs +0 -2
  204. package/dist/dist-QNYKM7YS.mjs.br +0 -0
  205. package/dist/dist-QNYKM7YS.mjs.gz +0 -0
  206. package/dist/dist-QU6JIDAF.js.br +0 -0
  207. package/dist/dist-QU6JIDAF.js.gz +0 -0
  208. package/dist/hooks-unstable.d.ts.map +0 -1
  209. package/dist/hooks-unstable.js.br +0 -0
  210. package/dist/hooks-unstable.js.gz +0 -0
  211. package/dist/hooks-unstable.mjs.br +0 -0
  212. package/dist/hooks-unstable.mjs.gz +0 -0
  213. package/dist/index-DWvM1PBB.d.ts.map +0 -1
  214. package/dist/three.module-7CXEVRKB.mjs.br +0 -0
  215. package/dist/three.module-7CXEVRKB.mjs.gz +0 -0
  216. package/dist/three.module-CPZZFD2Q.js.br +0 -0
  217. package/dist/three.module-CPZZFD2Q.js.gz +0 -0
  218. package/dist/useViewerBuildingBlocks-ll3_ncCH.d.ts.map +0 -1
  219. package/dist/y-webrtc-6CRYHAXH.mjs.br +0 -0
  220. package/dist/y-webrtc-6CRYHAXH.mjs.gz +0 -0
  221. package/dist/y-webrtc-QCZF75JW.js.br +0 -0
  222. package/dist/y-webrtc-QCZF75JW.js.gz +0 -0
  223. package/dist/y-websocket-57Q3RNHC.mjs.br +0 -0
  224. package/dist/y-websocket-57Q3RNHC.mjs.gz +0 -0
  225. package/dist/y-websocket-QJEM6VOB.js.br +0 -0
  226. package/dist/y-websocket-QJEM6VOB.js.gz +0 -0
  227. package/dist/yjs-UH3EPF3C.js.br +0 -0
  228. package/dist/yjs-UH3EPF3C.js.gz +0 -0
  229. package/dist/yjs-Y7IYUWOG.mjs.br +0 -0
  230. package/dist/yjs-Y7IYUWOG.mjs.gz +0 -0
@@ -206,6 +206,13 @@ interface PptxShapeLocks {
206
206
  noAdjustHandles?: boolean;
207
207
  noChangeArrowheads?: boolean;
208
208
  noChangeShapeType?: boolean;
209
+ /**
210
+ * Text-box flag from `p:cNvSpPr/@txBox`. Not a lock in the strict sense,
211
+ * but it lives on the same non-visual-properties node as `a:spLocks`, so
212
+ * it is captured here to round-trip through the model. When `true` the
213
+ * shape is a plain text box (no fill/line by default).
214
+ */
215
+ txBox?: boolean;
209
216
  }
210
217
  /**
211
218
  * A drawing guide parsed from OOXML extension lists.
@@ -795,6 +802,15 @@ interface ShapeStyle {
795
802
  r: number;
796
803
  b: number;
797
804
  };
805
+ /** Raw tileRect LTRB values (0..1 fractions, may be negative) from
806
+ * `a:gradFill/a:tileRect`. Defines the rectangle the gradient tile occupies
807
+ * before any flip/tiling is applied. */
808
+ fillGradientTileRect?: {
809
+ l: number;
810
+ t: number;
811
+ r: number;
812
+ b: number;
813
+ };
798
814
  /** Gradient tile flip mode (`a:gradFill/@flip`).
799
815
  * `none` = no tiling flip (default), `x|y|xy` = mirror in the named axis. */
800
816
  fillGradientFlip?: 'none' | 'x' | 'y' | 'xy';
@@ -812,6 +828,20 @@ interface ShapeStyle {
812
828
  * round-trip serialisation. See {@link fillColorXml} for the rationale.
813
829
  */
814
830
  strokeColorXml?: XmlObject;
831
+ /**
832
+ * Kind of fill painted on the outline (`a:ln` child). Distinguishes a solid
833
+ * outline from a gradient/pattern/none outline so save can emit the correct
834
+ * single line fill instead of collapsing every outline to `a:solidFill`
835
+ * (which, alongside a preserved `a:gradFill`/`a:pattFill`, produces an
836
+ * invalid dual-fill `<a:ln>`).
837
+ */
838
+ strokeFillMode?: 'solid' | 'gradient' | 'pattern' | 'none';
839
+ /** Raw `a:ln/a:gradFill` XML preserved for round-trip when the outline is
840
+ * gradient-filled. Re-emitted verbatim as the line's single fill on save. */
841
+ strokeGradientXml?: XmlObject;
842
+ /** Raw `a:ln/a:pattFill` XML preserved for round-trip when the outline is
843
+ * pattern-filled. Re-emitted verbatim as the line's single fill on save. */
844
+ strokePatternXml?: XmlObject;
815
845
  strokeWidth?: number;
816
846
  strokeOpacity?: number;
817
847
  strokeDash?: StrokeDashType;
@@ -993,6 +1023,14 @@ interface ShapeStyle {
993
1023
  };
994
1024
  /** Fill overlay blend mode from effectDag `a:fillOverlay/@blend`. */
995
1025
  dagFillOverlayBlend?: 'over' | 'mult' | 'screen' | 'darken' | 'lighten';
1026
+ /**
1027
+ * Fill overlay tint colour (hex `#RRGGBB`) from effectDag `a:fillOverlay`'s
1028
+ * `a:solidFill`/`a:gradFill`. Painted as a blended overlay layer over the
1029
+ * element; the blend mode comes from {@link dagFillOverlayBlend}.
1030
+ */
1031
+ dagFillOverlayColor?: string;
1032
+ /** Fill overlay tint opacity (0-1), from the overlay fill colour's alpha. */
1033
+ dagFillOverlayOpacity?: number;
996
1034
  /** `<a:lnRef @idx>` — 1-based index into the theme's lnStyleLst. */
997
1035
  lnRefIdx?: number;
998
1036
  /** Raw XML colour child of `<a:lnRef>` (e.g. `<a:schemeClr>` with transforms). */
@@ -1120,6 +1158,13 @@ interface TextStyle {
1120
1158
  kerning?: number;
1121
1159
  /** Text highlight colour as hex string (`a:highlight`). */
1122
1160
  highlightColor?: string;
1161
+ /**
1162
+ * Raw colour-choice XML preserved from `a:highlight` so a themed highlight
1163
+ * (`a:schemeClr` / `a:sysClr` / `a:prstClr`) re-emits with its original
1164
+ * identity rather than being flattened to `<a:srgbClr/>` on save. On save we
1165
+ * re-emit verbatim when the resolved {@link highlightColor} still matches.
1166
+ */
1167
+ highlightColorXml?: XmlObject;
1123
1168
  /** Text-level gradient fill CSS string (from `a:rPr > a:gradFill`). */
1124
1169
  textFillGradient?: string;
1125
1170
  /** Structured gradient stops for text fill round-trip serialization. */
@@ -1231,10 +1276,36 @@ interface TextStyle {
1231
1276
  eastAsiaFont?: string;
1232
1277
  /** Complex Script font family from `a:cs`. */
1233
1278
  complexScriptFont?: string;
1279
+ /**
1280
+ * Theme-font token (`+mj-lt` / `+mn-lt` / ...) authored on `a:latin`, when
1281
+ * present. {@link fontFamily} holds the resolved concrete face for
1282
+ * rendering; this preserves the token linkage so the writer re-emits the
1283
+ * token rather than the flattened face (see #84).
1284
+ */
1285
+ latinFontThemeToken?: string;
1286
+ /** Theme-font token authored on `a:ea` (e.g. `+mn-ea`), when present. */
1287
+ eastAsiaFontThemeToken?: string;
1288
+ /** Theme-font token authored on `a:cs` (e.g. `+mn-cs`), when present. */
1289
+ complexScriptFontThemeToken?: string;
1290
+ /**
1291
+ * Automatic per-script fallback face resolved from the theme's
1292
+ * `<a:font script="...">` overrides for a run whose text is dominantly
1293
+ * CJK / Arabic / Hebrew / Thai (see #83). A rendering hint only: it is not
1294
+ * serialised back on save, so it never disturbs the round-trip typefaces.
1295
+ */
1296
+ scriptFallbackFont?: string;
1234
1297
  /** Text language from `a:rPr/@lang`. */
1235
1298
  language?: string;
1236
1299
  /** Hyperlink mouse-over target from `a:hlinkMouseOver`. */
1237
1300
  hyperlinkMouseOver?: string;
1301
+ /**
1302
+ * Raw `a:snd` (embedded WAV audio) child of `a:hlinkClick`, preserved
1303
+ * verbatim (carries `@r:embed` + `@name`). Round-tripped on save so the
1304
+ * click sound survives instead of being dropped.
1305
+ */
1306
+ hyperlinkSoundXml?: XmlObject;
1307
+ /** Raw `a:snd` child of `a:hlinkMouseOver`, preserved verbatim for round-trip. */
1308
+ hyperlinkMouseOverSoundXml?: XmlObject;
1238
1309
  /** Hyperlink invalidUrl attribute (`a:hlinkClick/@invalidUrl`). */
1239
1310
  hyperlinkInvalidUrl?: string;
1240
1311
  /** Hyperlink target frame (`a:hlinkClick/@tgtFrame`). */
@@ -1578,6 +1649,15 @@ interface TextSegment {
1578
1649
  * on the first segment of a paragraph.
1579
1650
  */
1580
1651
  endParaRunProperties?: Record<string, unknown>;
1652
+ /**
1653
+ * Per-paragraph properties (alignment, spacing, margins, indent, tab stops,
1654
+ * rtl) authored on this paragraph's own `a:pPr` (#69). Only meaningful on
1655
+ * the first segment of a paragraph. When present, the writer emits these
1656
+ * per paragraph instead of collapsing one shape-level pPr onto every
1657
+ * paragraph. Only the paragraph-geometry keys of {@link TextStyle} are
1658
+ * populated; unrelated fields fall back to the shape-level style.
1659
+ */
1660
+ paragraphProperties?: TextStyle;
1581
1661
  /**
1582
1662
  * Phonetic annotation text from `a:ruby > a:rt` (e.g. furigana, pinyin).
1583
1663
  * When present, the renderer should wrap the base text with an HTML `<ruby>` tag.
@@ -1883,6 +1963,75 @@ interface PptxChartProtection {
1883
1963
  rawXml?: XmlObject;
1884
1964
  }
1885
1965
  //#endregion
1966
+ //#region src/core/types/chart-user-shapes.d.ts
1967
+ /**
1968
+ * Types for chart drawing-overlay shapes (`c:userShapes`).
1969
+ *
1970
+ * A chart's `c:userShapes` element carries an `r:id` that references a
1971
+ * separate drawing part (`ppt/drawings/drawingN.xml`) whose root is a
1972
+ * `c:userShapes` element populated with `cdr:relSizeAnchor` /
1973
+ * `cdr:absSizeAnchor` wrappers around `sp` / `pic` / `cxnSp` shapes drawn on
1974
+ * top of the chart plot. These interfaces describe the parsed, renderable
1975
+ * overlay model. The raw reference is preserved separately on
1976
+ * {@link PptxChartData.userShapesXml} for verbatim round-trip save; this model
1977
+ * is render-only.
1978
+ *
1979
+ * @module pptx-types/chart-user-shapes
1980
+ */
1981
+ /** A single paragraph of overlay-shape text with light formatting. */
1982
+ interface PptxChartUserShapeParagraph {
1983
+ /** Joined run text of the paragraph. */
1984
+ text: string;
1985
+ /** Font size in points (`a:rPr/@sz` divided by 100), when present. */
1986
+ fontSize?: number;
1987
+ /** Whether the first run is bold (`a:rPr/@b`). */
1988
+ bold?: boolean;
1989
+ /** Whether the first run is italic (`a:rPr/@i`). */
1990
+ italic?: boolean;
1991
+ /** Resolved run colour hex (e.g. `"#FF0000"`), when present. */
1992
+ color?: string;
1993
+ /** Paragraph alignment (`a:pPr/@algn`): left / centre / right. */
1994
+ align?: 'l' | 'ctr' | 'r';
1995
+ }
1996
+ /**
1997
+ * A parsed chart-overlay shape positioned by a drawing anchor.
1998
+ *
1999
+ * Position is expressed as chart-relative fractions in {@link from}. For a
2000
+ * `relSizeAnchor` the opposite corner is {@link to} (also fractional); for an
2001
+ * `absSizeAnchor` the extent is {@link ext} in EMU.
2002
+ */
2003
+ interface PptxChartUserShape {
2004
+ /** Shape kind: text/preset shape, connector, or picture. */
2005
+ kind: 'sp' | 'cxnSp' | 'pic';
2006
+ /** Anchor kind that positioned the shape. */
2007
+ anchor: 'rel' | 'abs';
2008
+ /** Top-left corner as chart-relative fractions (0-1). */
2009
+ from: {
2010
+ x: number;
2011
+ y: number;
2012
+ };
2013
+ /** Bottom-right corner as chart-relative fractions (0-1); relSizeAnchor only. */
2014
+ to?: {
2015
+ x: number;
2016
+ y: number;
2017
+ };
2018
+ /** Extent in EMU (cx, cy); absSizeAnchor only. */
2019
+ ext?: {
2020
+ cx: number;
2021
+ cy: number;
2022
+ };
2023
+ /** Preset geometry name (`a:prstGeom/@prst`), defaulting to `"rect"`. */
2024
+ prst?: string;
2025
+ /** Resolved solid-fill hex colour, when present. */
2026
+ fill?: string;
2027
+ /** Resolved line/stroke hex colour, when present. */
2028
+ stroke?: string;
2029
+ /** Line width in points (`a:ln/@w` divided by 12700), when present. */
2030
+ strokeWidth?: number;
2031
+ /** Text paragraphs of the shape's `txBody`, when present. */
2032
+ paragraphs?: PptxChartUserShapeParagraph[];
2033
+ }
2034
+ //#endregion
1886
2035
  //#region src/core/types/chart.d.ts
1887
2036
  /**
1888
2037
  * Supported chart type discriminators.
@@ -2216,6 +2365,15 @@ interface PptxChartTreemapOptions {
2216
2365
  interface PptxChartSeries {
2217
2366
  name: string;
2218
2367
  values: number[];
2368
+ /**
2369
+ * Blank-value mask aligned index-for-index with {@link values}: `true` marks
2370
+ * a category whose numeric cache point (`c:numCache/c:pt`) was absent or
2371
+ * empty, i.e. a genuine blank rather than a real `0`. Present only when the
2372
+ * source series actually contains blanks; when set, blank slots in
2373
+ * {@link values} carry `0` as a placeholder. Renderers honour
2374
+ * `c:dispBlanksAs` (gap / zero / span) using this mask.
2375
+ */
2376
+ blanks?: boolean[];
2219
2377
  color?: string;
2220
2378
  trendlines?: PptxChartTrendline[];
2221
2379
  errBars?: PptxChartErrBars[];
@@ -2223,6 +2381,18 @@ interface PptxChartSeries {
2223
2381
  marker?: PptxChartMarker;
2224
2382
  dataLabels?: PptxChartDataLabel[];
2225
2383
  explosion?: number;
2384
+ /**
2385
+ * Series-level `c:invertIfNegative`: when true, bar/column data points with a
2386
+ * negative value are drawn with an inverted (lightened) fill. A per-point
2387
+ * `c:dPt/c:invertIfNegative` overrides this for that point. Absent when the
2388
+ * source XML omits the flag.
2389
+ */
2390
+ invertIfNegative?: boolean;
2391
+ /**
2392
+ * Whether this line/scatter series is drawn with bezier smoothing
2393
+ * (`c:ser/c:smooth/@val`). Absent when the source XML omits `c:smooth`.
2394
+ */
2395
+ smooth?: boolean;
2226
2396
  /** Axis ID this series is plotted against (links to PptxChartAxisFormatting.axisId). */
2227
2397
  axisId?: number;
2228
2398
  /**
@@ -2425,6 +2595,14 @@ interface PptxChartManualLayout {
2425
2595
  y?: number;
2426
2596
  width?: number;
2427
2597
  height?: number;
2598
+ /**
2599
+ * Raw `c:extLst` (CT_ExtensionList) of the `c:manualLayout`, captured
2600
+ * verbatim so it round-trips through the typed model. Without this, a dirty
2601
+ * write of an edited layout would drop the extension list (the manual node
2602
+ * is rebuilt from the typed fields). Emitted as the trailing child, matching
2603
+ * the CT_ManualLayout schema order.
2604
+ */
2605
+ ext?: XmlObject;
2428
2606
  }
2429
2607
  /**
2430
2608
  * Typed manual layouts for chart regions that accept `c:layout`.
@@ -2489,6 +2667,33 @@ interface PptxChartData {
2489
2667
  style?: PptxChartStyle;
2490
2668
  /** Grouping mode for bar/area/line charts: 'clustered' | 'stacked' | 'percentStacked' */
2491
2669
  grouping?: 'clustered' | 'stacked' | 'percentStacked';
2670
+ /**
2671
+ * Whether the first (or only) series varies its point colours
2672
+ * (`c:varyColors/@val`). Pie/doughnut default this on; single-series
2673
+ * bar/column honour it by giving each point a distinct palette colour.
2674
+ * Absent when the source XML omits `c:varyColors`.
2675
+ */
2676
+ varyColors?: boolean;
2677
+ /**
2678
+ * Pie/doughnut start angle in degrees clockwise from 12 o'clock
2679
+ * (`c:firstSliceAng/@val`, 0 through 360). Absent uses the default 0.
2680
+ */
2681
+ firstSliceAngle?: number;
2682
+ /**
2683
+ * Doughnut hole diameter as a percentage of the outer diameter
2684
+ * (`c:holeSize/@val`, 10 through 90). Absent uses the renderer default.
2685
+ */
2686
+ doughnutHoleSize?: number;
2687
+ /**
2688
+ * Bar/column gap between category clusters as a percentage of bar width
2689
+ * (`c:gapWidth/@val`, 0 through 500). Absent uses the renderer default.
2690
+ */
2691
+ barGapWidth?: number;
2692
+ /**
2693
+ * Clustered bar/column overlap between series within a category as a
2694
+ * percentage (`c:overlap/@val`, -100 through 100). Absent uses 0.
2695
+ */
2696
+ barOverlap?: number;
2492
2697
  /** Internal: path to the chart XML part in the PPTX archive (for round-trip save). */
2493
2698
  chartPartPath?: string;
2494
2699
  /** Internal: relationship ID linking the graphic frame to the chart part. */
@@ -2589,6 +2794,15 @@ interface PptxChartData {
2589
2794
  * attempting to parse the nested drawing tree.
2590
2795
  */
2591
2796
  userShapesXml?: unknown;
2797
+ /**
2798
+ * Parsed, renderable drawing-overlay shapes resolved from the separate
2799
+ * drawing part referenced by `c:userShapes/@r:id`
2800
+ * (`ppt/drawings/drawingN.xml`). Each entry carries chart-relative anchor
2801
+ * geometry plus light shape/text formatting so the viewer can render an
2802
+ * overlay on top of the chart plot. Render-only: {@link userShapesXml}
2803
+ * remains the source of truth for round-trip save.
2804
+ */
2805
+ userShapes?: PptxChartUserShape[];
2592
2806
  /**
2593
2807
  * Raw `c:pivotFmts` XML subtree preserved verbatim.
2594
2808
  *
@@ -2864,7 +3078,7 @@ interface PptxImageProperties {
2864
3078
  /** Crop-to-shape — CSS clip-path shape name. */
2865
3079
  cropShape?: PptxCropShape;
2866
3080
  }
2867
- declare module "./hooks-unstable" {
3081
+ declare module "./internals" {
2868
3082
  interface TextStyle {
2869
3083
  /**
2870
3084
  * Raw `a:effectDag` XML node from `a:rPr`, preserved verbatim for
@@ -2882,7 +3096,7 @@ declare module "./hooks-unstable" {
2882
3096
  textEffectDagTree?: EffectDagContainer;
2883
3097
  }
2884
3098
  }
2885
- declare module "./hooks-unstable" {
3099
+ declare module "./internals" {
2886
3100
  interface ShapeStyle {
2887
3101
  /**
2888
3102
  * Typed effect graph parsed from {@link ShapeStyle.effectDagXml}. The four
@@ -3296,6 +3510,18 @@ interface PptxSmartArtColorTransform extends PptxSmartArtDefinitionMetadata {
3296
3510
  fillColors: string[];
3297
3511
  /** Ordered resolved line colors for rendering. */
3298
3512
  lineColors: string[];
3513
+ /** Ordered resolved text-fill colors (primary styleLbl `txFillClrLst`). */
3514
+ textFillColors?: string[];
3515
+ /** Ordered resolved text-line colors (primary styleLbl `txLinClrLst`). */
3516
+ textLineColors?: string[];
3517
+ /** Ordered resolved effect colors (primary styleLbl `effectClrLst`). */
3518
+ effectColors?: string[];
3519
+ /** Ordered resolved text-effect colors (primary styleLbl `txEffectClrLst`). */
3520
+ textEffectColors?: string[];
3521
+ /** Fill-list span/cycle + hue-direction interpolation of the primary styleLbl. */
3522
+ fillInterpolation?: PptxSmartArtColorListMetadata;
3523
+ /** Line-list span/cycle + hue-direction interpolation of the primary styleLbl. */
3524
+ lineInterpolation?: PptxSmartArtColorListMetadata;
3299
3525
  /** Ordered CT_CTStyleLabel metadata. */
3300
3526
  labels?: PptxSmartArtColorStyleLabel[];
3301
3527
  }
@@ -3484,6 +3710,40 @@ interface PptxSmartArtChrome {
3484
3710
  /** Outline stroke width in points. */
3485
3711
  outlineWidth?: number;
3486
3712
  }
3713
+ /**
3714
+ * Presentation layout variables from `dgm:prSet/dgm:presLayoutVars` (data model)
3715
+ * or `dgm:varLst` (layout definition defaults).
3716
+ *
3717
+ * These drive how the DiagramML layout interpreter arranges points: flow
3718
+ * direction, hierarchy branch style, org-chart mode, and child count limits.
3719
+ * The fallback layout engine can consult them for direction/org-chart hints.
3720
+ *
3721
+ * @example
3722
+ * ```ts
3723
+ * const vars: PptxSmartArtPresLayoutVars = { direction: "rev", orgChart: true };
3724
+ * // => satisfies PptxSmartArtPresLayoutVars
3725
+ * ```
3726
+ */
3727
+ interface PptxSmartArtPresLayoutVars {
3728
+ /** Flow direction (`dgm:dir`): "norm" (default) or "rev" (reversed/RTL). */
3729
+ direction?: 'norm' | 'rev';
3730
+ /** Hierarchy branch style (`dgm:hierBranch`): std/init/l/r/hang. */
3731
+ hierarchyBranch?: 'std' | 'init' | 'l' | 'r' | 'hang';
3732
+ /** Org-chart mode enabled (`dgm:orgChart`). */
3733
+ orgChart?: boolean;
3734
+ /** Maximum children per node (`dgm:chMax`, -1 = unbounded). */
3735
+ childMax?: number;
3736
+ /** Preferred children per node (`dgm:chPref`, -1 = unbounded). */
3737
+ childPreferred?: number;
3738
+ /** Whether bullets are enabled (`dgm:bulletEnabled`). */
3739
+ bulletEnabled?: boolean;
3740
+ /** Animation-by-level setting (`dgm:animLvl`). */
3741
+ animationLevel?: string;
3742
+ /** Animate-one setting (`dgm:animOne`). */
3743
+ animateOne?: string;
3744
+ /** Allowed resize handles (`dgm:resizeHandles`). */
3745
+ resizeHandles?: string;
3746
+ }
3487
3747
  /**
3488
3748
  * Complete parsed SmartArt data for a {@link SmartArtPptxElement}.
3489
3749
  *
@@ -3525,6 +3785,12 @@ interface PptxSmartArtData {
3525
3785
  quickStyle?: PptxSmartArtQuickStyle;
3526
3786
  /** Editable metadata from the related DiagramML layout definition. */
3527
3787
  layoutDefinition?: PptxSmartArtLayoutDefinition;
3788
+ /**
3789
+ * Presentation layout variables (direction, hierarchy branch, org-chart,
3790
+ * child limits, bullets) from `dgm:presLayoutVars` / layout `dgm:varLst`.
3791
+ * Consulted by the fallback layout engine for direction/org-chart hints.
3792
+ */
3793
+ presLayoutVars?: PptxSmartArtPresLayoutVars;
3528
3794
  /** Relationship ID for the diagram data part (for round-trip save). */
3529
3795
  dataRelId?: string;
3530
3796
  /** Relationship ID for the diagram layout part. */
@@ -3557,7 +3823,7 @@ interface PptxSmartArtData {
3557
3823
  /**
3558
3824
  * Per-cell visual style for a table cell.
3559
3825
  *
3560
- * All fields are optional unset values inherit from the table style.
3826
+ * All fields are optional - unset values inherit from the table style.
3561
3827
  *
3562
3828
  * @example
3563
3829
  * ```ts
@@ -3685,6 +3951,52 @@ interface PptxTableCellStyle {
3685
3951
  patternFillForeground?: string;
3686
3952
  /** Pattern fill background colour. */
3687
3953
  patternFillBackground?: string;
3954
+ /**
3955
+ * Cell 3D bevel + lighting from `a:tcPr/a:cell3D` (CT_Cell3D,
3956
+ * ECMA-376 §21.1.3.1). Rendered as a CSS bevel treatment.
3957
+ */
3958
+ cell3D?: PptxTableCell3D;
3959
+ /**
3960
+ * `a:tcPr/@anchorCtr` - centre the text block in the direction
3961
+ * perpendicular to the text flow (horizontal centring for horizontal text).
3962
+ */
3963
+ anchorCtr?: boolean;
3964
+ /**
3965
+ * `a:tcPr/@horzOverflow` (ST_TextHorzOverflowType): `clip` clips text at
3966
+ * the cell edge, `overflow` (the default) lets it spill.
3967
+ */
3968
+ horzOverflow?: 'clip' | 'overflow';
3969
+ }
3970
+ /**
3971
+ * Cell 3D bevel + lighting parsed from `a:tcPr/a:cell3D` (CT_Cell3D).
3972
+ *
3973
+ * Only the fields needed to render a plausible bevel treatment are captured;
3974
+ * verbatim round-trip of the full node is handled separately by the save path.
3975
+ *
3976
+ * @example
3977
+ * ```ts
3978
+ * const c3d: PptxTableCell3D = {
3979
+ * bevelWidth: 8,
3980
+ * bevelHeight: 8,
3981
+ * bevelPreset: 'circle',
3982
+ * material: 'plastic',
3983
+ * };
3984
+ * // => satisfies PptxTableCell3D
3985
+ * ```
3986
+ */
3987
+ interface PptxTableCell3D {
3988
+ /** Bevel width in px (from `a:bevel@w`, EMU converted). */
3989
+ bevelWidth?: number;
3990
+ /** Bevel height in px (from `a:bevel@h`, EMU converted). */
3991
+ bevelHeight?: number;
3992
+ /** Bevel preset name (`a:bevel@prst`, e.g. `circle`, `relaxedInset`). */
3993
+ bevelPreset?: string;
3994
+ /** Preset material (`a:cell3D@prstMaterial`, e.g. `plastic`, `metal`). */
3995
+ material?: string;
3996
+ /** Light rig type (`a:lightRig@rig`, e.g. `threePt`, `soft`). */
3997
+ lightRig?: string;
3998
+ /** Light rig direction (`a:lightRig@dir`, e.g. `tl`, `t`, `tr`). */
3999
+ lightRigDirection?: string;
3688
4000
  }
3689
4001
  /**
3690
4002
  * A single table cell with text content, optional style, and merge info.
@@ -3797,12 +4109,50 @@ interface PptxTableData {
3797
4109
  * ```
3798
4110
  */
3799
4111
  interface ParsedTableStyleFill {
3800
- /** Theme colour key (e.g. `accent1`, `dk1`). */
4112
+ /**
4113
+ * Theme colour key (e.g. `accent1`, `dk1`). Empty string when the fill is a
4114
+ * non-scheme fill (explicit sRGB, gradient, pattern, or none) that carries
4115
+ * no theme colour reference; the renderer then resolves {@link color},
4116
+ * {@link gradient}, {@link pattern}, or {@link noFill} instead.
4117
+ */
3801
4118
  schemeColor: string;
3802
4119
  /** Tint value (0-100 000). */
3803
4120
  tint?: number;
3804
4121
  /** Shade value (0-100 000). */
3805
4122
  shade?: number;
4123
+ /** Explicit sRGB hex colour (e.g. `#FF8800`) from `a:srgbClr`. */
4124
+ color?: string;
4125
+ /** The fill was `a:noFill`: renders transparent and clears lower layers. */
4126
+ noFill?: boolean;
4127
+ /** Gradient fill parsed from `a:gradFill`. */
4128
+ gradient?: ParsedTableStyleGradient;
4129
+ /** Preset pattern fill parsed from `a:pattFill`. */
4130
+ pattern?: ParsedTableStylePattern;
4131
+ }
4132
+ /** A single colour stop within a {@link ParsedTableStyleGradient}. */
4133
+ interface ParsedTableStyleGradientStop {
4134
+ /** Stop position as a percentage (0-100). */
4135
+ position: number;
4136
+ /** Stop colour (scheme or explicit sRGB). */
4137
+ fill: ParsedTableStyleFill;
4138
+ }
4139
+ /** A gradient fill parsed from a table style section's `a:gradFill`. */
4140
+ interface ParsedTableStyleGradient {
4141
+ /** Ordered colour stops. */
4142
+ stops: ParsedTableStyleGradientStop[];
4143
+ /** Linear gradient angle in degrees (from `a:lin@ang`, 60000ths -> deg). */
4144
+ angle?: number;
4145
+ /** Gradient family: linear (`a:lin`) or radial (`a:path`). */
4146
+ type: 'linear' | 'radial';
4147
+ }
4148
+ /** A preset pattern fill parsed from a table style section's `a:pattFill`. */
4149
+ interface ParsedTableStylePattern {
4150
+ /** OOXML preset name (e.g. `ltDnDiag`) from `a:pattFill@prst`. */
4151
+ preset: string;
4152
+ /** Foreground colour (`a:fgClr`). */
4153
+ foreground?: ParsedTableStyleFill;
4154
+ /** Background colour (`a:bgClr`). */
4155
+ background?: ParsedTableStyleFill;
3806
4156
  }
3807
4157
  /**
3808
4158
  * A single entry in the parsed table style map.
@@ -3829,12 +4179,20 @@ interface ParsedTableStyleText {
3829
4179
  bold?: boolean;
3830
4180
  /** Font italic. */
3831
4181
  italic?: boolean;
4182
+ /** Font underline (from `a:tcTxStyle@u`, any value other than `none`). */
4183
+ underline?: boolean;
3832
4184
  /** Font colour as theme scheme key. */
3833
4185
  fontSchemeColor?: string;
3834
4186
  /** Font colour tint (0-100 000). */
3835
4187
  fontTint?: number;
3836
4188
  /** Font colour shade (0-100 000). */
3837
4189
  fontShade?: number;
4190
+ /** Explicit sRGB hex font colour (e.g. `#FF0000`) from `a:srgbClr`. */
4191
+ fontColor?: string;
4192
+ /** Typeface from `a:font@typeface` (latin font). */
4193
+ fontFace?: string;
4194
+ /** Font-collection index from `a:fontRef@idx` (`minor`, `major`, `none`). */
4195
+ fontRefIdx?: string;
3838
4196
  }
3839
4197
  /**
3840
4198
  * A single border side within a table style's `a:tcStyle/a:tcBdr`.
@@ -3862,7 +4220,7 @@ interface ParsedTableStyleBorder {
3862
4220
  fill?: ParsedTableStyleFill;
3863
4221
  /** Explicit hex colour when the line used `a:srgbClr` (e.g. `#808080`). */
3864
4222
  color?: string;
3865
- /** The line was `a:noFill` an explicit "no border" that clears lower layers. */
4223
+ /** The line was `a:noFill` - an explicit "no border" that clears lower layers. */
3866
4224
  noFill?: boolean;
3867
4225
  }
3868
4226
  /**
@@ -4753,6 +5111,19 @@ interface PptxNativeAnimation {
4753
5111
  durationMs?: number;
4754
5112
  /** Delay in milliseconds. */
4755
5113
  delayMs?: number;
5114
+ /**
5115
+ * Acceleration fraction in the range 0..1, parsed from `p:cTn/@accel`
5116
+ * (ST_PositiveFixedPercentage, stored as 1000ths of a percent). A non-zero
5117
+ * value means the effect eases in (starts slow). Absent means no easing-in.
5118
+ */
5119
+ accel?: number;
5120
+ /**
5121
+ * Deceleration fraction in the range 0..1, parsed from `p:cTn/@decel`.
5122
+ * A non-zero value means the effect eases out (ends slow). Absent means no
5123
+ * easing-out. When both {@link accel} and {@link decel} are set, the effect
5124
+ * eases in and out.
5125
+ */
5126
+ decel?: number;
4756
5127
  /** Trigger delay in milliseconds (for afterDelay). */
4757
5128
  triggerDelayMs?: number;
4758
5129
  /** SVG path string for motion path animations (`p:animMotion/@path`). */
@@ -4845,6 +5216,14 @@ interface PptxNativeAnimation {
4845
5216
  * that aren't OLE charts).
4846
5217
  */
4847
5218
  graphicBuild?: string;
5219
+ /**
5220
+ * OLE-embedded chart build attribute (`p:bldOleChart/@bld`) when this
5221
+ * animation stages an OLE chart graphic frame. Values follow
5222
+ * ST_TLOleChartBuildType: `allAtOnce`, `series`, `category`, `seriesEl`,
5223
+ * `categoryEl`. Lets a staged-reveal renderer build the chart by series /
5224
+ * category / element to match PowerPoint, rather than as one whole element.
5225
+ */
5226
+ oleChartBuild?: string;
4848
5227
  /** Schema-accurate `p:bldGraphic/p:bldAsOne|p:bldSub` representation. */
4849
5228
  graphicBuildProperties?: PptxGraphicBuild;
4850
5229
  /**
@@ -5334,6 +5713,18 @@ interface PptxAppProperties {
5334
5713
  template?: string;
5335
5714
  /** Hyperlink base URL. */
5336
5715
  hyperlinkBase?: string;
5716
+ /** Document security bitmask (`<DocSecurity>`). */
5717
+ docSecurity?: number;
5718
+ /** Number of multimedia clips (`<MMClips>`). */
5719
+ mmClips?: number;
5720
+ /** Whether thumbnail images were scaled to fit (`<ScaleCrop>`). */
5721
+ scaleCrop?: boolean;
5722
+ /** Whether hyperlinks are current (`<LinksUpToDate>`). */
5723
+ linksUpToDate?: boolean;
5724
+ /** Whether the document is shared (`<SharedDoc>`). */
5725
+ sharedDoc?: boolean;
5726
+ /** Whether hyperlinks changed since last save (`<HyperlinksChanged>`). */
5727
+ hyperlinksChanged?: boolean;
5337
5728
  }
5338
5729
  //#endregion
5339
5730
  //#region src/core/types/presentation-print-properties.d.ts
@@ -5838,6 +6229,21 @@ interface PptxActiveXControl {
5838
6229
  name?: string;
5839
6230
  /** Shape ID this control is linked to (from @spid). */
5840
6231
  shapeId?: string;
6232
+ /** X position (px) of the control's fallback picture, if present. */
6233
+ x?: number;
6234
+ /** Y position (px) of the control's fallback picture, if present. */
6235
+ y?: number;
6236
+ /** Width (px) of the control's fallback picture, if present. */
6237
+ width?: number;
6238
+ /** Height (px) of the control's fallback picture, if present. */
6239
+ height?: number;
6240
+ /**
6241
+ * Relationship ID of the control's static fallback picture
6242
+ * (`mc:AlternateContent > mc:Fallback > p:pic > p:blipFill > a:blip@r:embed`).
6243
+ * Renderers resolve this to an image so a control shows its last static
6244
+ * frame instead of a blank area (the live ActiveX cannot run in a viewer).
6245
+ */
6246
+ fallbackImageRelId?: string;
5841
6247
  /** Raw XML for round-trip preservation. */
5842
6248
  rawXml?: XmlObject;
5843
6249
  }
@@ -5964,6 +6370,13 @@ interface PptxSlide {
5964
6370
  customerData?: PptxCustomerData[];
5965
6371
  /** ActiveX control references from `p:controls` on this slide. */
5966
6372
  activeXControls?: PptxActiveXControl[];
6373
+ /**
6374
+ * Shapes parsed from a referenced legacy VML drawing part
6375
+ * (`ppt/drawings/vmlDrawing*.vml`, linked via a `legacyDrawing`
6376
+ * relationship). These are read-only render hints: the VML part itself is
6377
+ * preserved verbatim on save, so this field is not re-serialized.
6378
+ */
6379
+ legacyVmlElements?: PptxElement[];
5967
6380
  /** Per-slide header/footer flags from `<p:hf>` (P-H3). */
5968
6381
  headerFooterFlags?: PptxHeaderFooterFlags;
5969
6382
  /** Server-backed slide synchronization metadata stored in a related OPC part. */
@@ -6072,12 +6485,6 @@ interface PptxPresentationProperties {
6072
6485
  showSubtitles?: boolean;
6073
6486
  /** Typed `p:prnPr` settings. Set to null during save to remove the element. */
6074
6487
  printProperties?: PptxPresentationPrintProperties | null;
6075
- /** @deprecated Use `printProperties.printWhat`; retained as a handout compatibility alias. */
6076
- printSlidesPerPage?: number;
6077
- /** @deprecated Use `printProperties.frameSlides`. */
6078
- printFrameSlides?: boolean;
6079
- /** @deprecated Use `printProperties.colorMode`. */
6080
- printColorMode?: 'clr' | 'gray' | 'bw';
6081
6488
  /** Most-recently-used colours from the presentation palette. */
6082
6489
  mruColors?: string[];
6083
6490
  /** Grid spacing in EMUs (cx, cy). Default is 914400 / 8 = 114300. */
@@ -7920,12 +8327,69 @@ interface CollaborationConfig {
7920
8327
  */
7921
8328
  writeBackDebounceMs?: number;
7922
8329
  }
8330
+ /**
8331
+ * Normalized staged-reveal mode for a chart graphic frame, derived from the
8332
+ * OOXML `a:bldChart/@bld` (or `p:bldOleChart/@bld`) token:
8333
+ * - `asOne` the whole chart appears at once (`allAtOnce`).
8334
+ * - `bySeries` one data series is revealed per stage (`series`).
8335
+ * - `byCategory` one category is revealed per stage (`category`).
8336
+ * - `byElement` one series/category ELEMENT is revealed per stage
8337
+ * (`seriesElement` / `categoryElement`).
8338
+ */
8339
+ type ChartBuildMode = 'asOne' | 'bySeries' | 'byCategory' | 'byElement';
8340
+ /**
8341
+ * Normalized staged-reveal mode for a SmartArt diagram, derived from the OOXML
8342
+ * `a:bldDgm/@bld` or `p:bldDgm/@bld` token:
8343
+ * - `asOne` the whole diagram appears at once (`whole` / `allAtOnce`).
8344
+ * - `byOne` one node is revealed per stage (`one`, and the assorted
8345
+ * `depthBy*` / `breadthBy*` / directional traversals).
8346
+ * - `byLvl` levels are revealed one element at a time (`lvlOne`).
8347
+ * - `byLvlAtOnce` a whole level is revealed per stage (`lvlAtOnce`).
8348
+ */
8349
+ type DiagramBuildMode = 'asOne' | 'byOne' | 'byLvl' | 'byLvlAtOnce';
8350
+ /**
8351
+ * Playback-time staged-build state surfaced on {@link ElementAnimationState}.
8352
+ * `progress` is the 0..1 fraction of the build revealed at the current playback
8353
+ * time; a consumer maps it to its own item COUNT (see `revealedStageCount`).
8354
+ */
8355
+ type ElementBuildState = {
8356
+ kind: 'chart';
8357
+ mode: ChartBuildMode;
8358
+ progress: number;
8359
+ } | {
8360
+ kind: 'diagram';
8361
+ mode: DiagramBuildMode;
8362
+ progress: number;
8363
+ };
7923
8364
  /** Snapshot of a single element's animation state at a point in the timeline. */
7924
8365
  interface ElementAnimationState {
7925
8366
  /** Whether the element should be visible. */
7926
8367
  visible: boolean;
7927
8368
  /** CSS animation shorthand to apply (undefined = no active animation). */
7928
8369
  cssAnimation: string | undefined;
8370
+ /**
8371
+ * Staged-build reveal state, present only when the active animation builds a
8372
+ * chart or SmartArt diagram in stages (`p:bldChart` / `p:bldDgm`) rather than
8373
+ * revealing the whole element at once. A staged renderer multiplies
8374
+ * `build.progress` (0..1) by its own series / category / level COUNT to
8375
+ * decide how many stages are revealed at the current playback time; see
8376
+ * {@link import('./animation-build').revealedStageCount}. Absent for ordinary
8377
+ * whole-element entrances, so existing renderers are unaffected.
8378
+ */
8379
+ build?: ElementBuildState;
8380
+ /**
8381
+ * True when an active `p:animClr` color animation targets this shape's fill.
8382
+ * A vector renderer should then paint the fill with `fill: inherit` so the
8383
+ * wrapper-level colour keyframes cascade to the SVG path. Absent/false means
8384
+ * no active fill-colour animation.
8385
+ */
8386
+ animatesFill?: boolean;
8387
+ /**
8388
+ * True when an active `p:animClr` color animation targets this shape's
8389
+ * stroke. A vector renderer should then paint the stroke with
8390
+ * `stroke: inherit`. Absent/false means no active stroke-colour animation.
8391
+ */
8392
+ animatesStroke?: boolean;
7929
8393
  }
7930
8394
  /** The unit system used for ruler display. */
7931
8395
  type RulerUnit = 'inches' | 'centimetres';
@@ -8518,230 +8982,630 @@ interface PowerPointViewerHandle extends FileViewerHandle, PowerPointViewerAPI {
8518
8982
  getContent: () => Promise<Uint8Array>;
8519
8983
  }
8520
8984
 
8521
- //#region src/viewer/hooks/presentation-mode/types.d.ts
8522
- /**
8523
- * State describing the transition overlay that plays while advancing into a
8524
- * slide that carries a `p:transition`. The outgoing slide is snapshotted into
8525
- * an animated overlay layer while the incoming slide renders underneath on the
8526
- * main stage; the overlay tears down once `durationMs` elapses.
8527
- */
8528
- interface PresentationTransitionOverlayState {
8529
- /** Index of the leaving slide, rendered (animated) in the overlay layer. */
8530
- outgoingSlideIndex: number;
8531
- /** Index of the arriving slide, already live on the main stage. */
8532
- incomingSlideIndex: number;
8533
- /** The incoming slide's transition definition (drives the CSS animation). */
8534
- transition: PptxSlideTransition;
8535
- /** Resolved transition duration (ms). */
8536
- durationMs: number;
8537
- }
8538
- interface UsePresentationModeInput {
8985
+ //#region src/viewer/components/toolbar/toolbar-types.d.ts
8986
+ interface ToolbarProps {
8987
+ fileName?: string;
8539
8988
  mode: ViewerMode;
8540
- slides: PptxSlide[];
8541
- visibleSlideIndexes: number[];
8542
- activeSlideIndex: number;
8543
- containerRef: React.RefObject<HTMLElement | null>;
8544
- /** Raw PPTX bytes: forwarded to audience window for content sharing. */
8545
- content?: ArrayBuffer | Uint8Array | null;
8989
+ canEdit: boolean;
8990
+ isNarrowViewport: boolean;
8991
+ isSidebarCollapsed: boolean;
8992
+ isInspectorPaneOpen: boolean;
8993
+ isCompactToolbarOpen: boolean;
8994
+ toolbarSection: ToolbarSection;
8995
+ scale: number;
8996
+ canUndo: boolean;
8997
+ canRedo: boolean;
8998
+ undoLabel: string | undefined;
8999
+ redoLabel: string | undefined;
9000
+ findReplaceOpen: boolean;
9001
+ selectedElement: PptxElement | null;
9002
+ tableEditorState?: TableCellEditorState | null;
9003
+ editTemplateMode: boolean;
9004
+ newShapeType: SupportedShapeType;
9005
+ activeTool: DrawingTool;
9006
+ drawingColor: string;
9007
+ drawingWidth: number;
9008
+ clipboardPayload: ElementClipboardPayload | null;
8546
9009
  onSetMode: (mode: ViewerMode) => void;
8547
- onSetActiveSlideIndex: (index: number) => void;
8548
- onPlayActionSound?: (soundPath: string) => void;
8549
- /** Called when L key is pressed during presentation. */
8550
- onToggleLaser?: () => void;
8551
- /** Called when P key is pressed during presentation. */
8552
- onTogglePen?: () => void;
8553
- /** Called when E key is pressed during presentation. */
8554
- onToggleEraser?: () => void;
8555
- /** Called when Ctrl+M is pressed during presentation. */
8556
- onToggleToolbar?: () => void;
8557
- /** Called to persist rehearsal timings into slide transitions. */
8558
- onSaveRehearsalTimings?: (timings: Record<number, number>) => void;
8559
- /** Whether to loop continuously (kiosk or explicit loop setting). */
8560
- loopContinuously?: boolean;
8561
- /** Whether to play animations during the slide show (false = skip all animations). */
8562
- showWithAnimation?: boolean;
8563
- /** Whether to use rehearsed auto-advance timings (false = manual advance only). */
8564
- useTimings?: boolean;
8565
- /**
8566
- * Options > Advanced > "End with black slide". When true (PowerPoint's
8567
- * default), advancing past the last slide shows a black end-of-show
8568
- * screen; the next advance (or a click on it) exits. When false,
8569
- * advancing past the last slide exits the show directly.
8570
- */
8571
- endWithBlackSlide?: boolean;
8572
- }
8573
- interface UsePresentationModeResult {
8574
- presentationSlideIndex: number;
8575
- setPresentationSlideIndex: (index: number) => void;
8576
- presentationSlideVisible: boolean;
8577
- /** Active slide-transition overlay, or `null` when no transition is playing. */
8578
- transitionOverlay: PresentationTransitionOverlayState | null;
8579
- /** Tear down the transition overlay once its animation completes. */
8580
- handleTransitionOverlayComplete: () => void;
8581
- presentationAnimations: PresentationAnimationRuntime[];
8582
- presentationElementStates: Map<string, ElementAnimationState>;
8583
- presentationKeyframesCss: string;
8584
- clearPresentationTimers: () => void;
8585
- runPresentationEntranceAnimations: (slideIndex: number) => void;
8586
- /** True while the black "End of slide show" screen is displayed. */
8587
- endOfShowVisible: boolean;
8588
- movePresentationSlide: (direction: 1 | -1) => void;
8589
- navigateToSlide: (slideIndex: number) => void;
8590
- handlePresentationAction: (action: PptxAction) => void;
8591
- /**
8592
- * Handle a shape click in presentation mode. If the shape is an interactive
8593
- * trigger, play its animation sequence. Returns `true` if handled.
8594
- */
8595
- handleInteractiveShapeClick: (shapeId: string) => boolean;
8596
- /** Set of shape IDs that are interactive sequence triggers on the current slide. */
8597
- interactiveTriggerShapeIds: ReadonlySet<string>;
8598
- /** Set of shape IDs that are hover animation triggers on the current slide. */
8599
- hoverTriggerShapeIds: ReadonlySet<string>;
8600
- /** Handle hover start on a shape. If the shape has a hover sequence, play it. Returns `true` if handled. */
8601
- handleHoverStart: (shapeId: string) => boolean;
8602
- /** Handle hover end on a shape. Resets the hover sequence for replay. */
8603
- handleHoverEnd: (shapeId: string) => void;
8604
- /** Must be called from a user-gesture handler (click) to satisfy browser fullscreen policy. */
8605
- enterPresentMode: () => void;
8606
- /** Whether presenter view (split-screen with notes) is active instead of fullscreen. */
8607
- presenterMode: boolean;
8608
- /** Enter presenter view mode (no fullscreen, shows notes panel). */
8609
- enterPresenterView: () => void;
8610
- /** Toggle between fullscreen and presenter view during presentation. */
8611
- togglePresenterView: () => void;
8612
- /** Timestamp (ms) when the presentation started: used for elapsed timer. */
8613
- presentationStartTime: number | null;
8614
- /** Whether the current presentation session is in rehearse-timings mode. */
8615
- rehearsing: boolean;
8616
- /** Enter rehearse-timings mode (fullscreen presentation + timing HUD). */
8617
- enterRehearsalMode: () => void;
8618
- /** Recorded timings in ms, keyed by slide index. Populated during rehearsal. */
8619
- recordedTimings: Record<number, number>;
8620
- /** Timestamp when the current slide started (ms since epoch). */
8621
- slideStartTime: number | null;
8622
- /** Whether the rehearsal summary dialog should be shown. */
8623
- showRehearsalSummary: boolean;
8624
- /** Dismiss the rehearsal summary (discard timings). */
8625
- dismissRehearsalSummary: () => void;
8626
- /** Save recorded timings into each slide's transition.advanceAfterMs. */
8627
- saveRehearsalTimings: () => void;
8628
- /** Whether rehearsal timer is paused. */
8629
- rehearsalPaused: boolean;
8630
- /** Toggle the rehearsal timer pause state. */
8631
- toggleRehearsalPause: () => void;
8632
- /** Handle a zoom element click in presentation mode. */
8633
- handleZoomClick: (targetSlideIndex: number, returnSlideIndex: number) => void;
8634
- /** Ref holding the slide index to return to after zoom navigation. */
8635
- zoomReturnSlideIndex: React.RefObject<number | null>;
8636
- /** Navigate back to the zoom summary slide. Returns true if navigation occurred. */
8637
- returnToZoomSlide: () => boolean;
8638
- /** Clear the stored zoom return index. */
8639
- clearZoomReturn: () => void;
8640
- /** Open the audience display in a separate browser window. Returns `true` if successful. */
8641
- openAudienceWindow: () => boolean;
8642
- /** Close the audience display window. */
8643
- closeAudienceWindow: () => void;
8644
- /** Whether the audience window is currently open. */
8645
- isAudienceWindowOpen: () => boolean;
8646
- /** Send a slide index to the audience window explicitly. */
8647
- syncSlideToAudience: (slideIndex: number) => void;
8648
- syncStateToAudience: (snapshot: PresentationSnapshot) => void;
8649
- presenterSnapshot: PresentationSnapshot;
8650
- setPresenterBlackout: (blackout: PresentationSnapshot['blackout']) => void;
8651
- togglePresenterTimer: () => void;
8652
- resetPresenterTimer: () => void;
8653
- stepPresenterZoom: (direction: 1 | -1) => void;
8654
- resetPresenterZoom: () => void;
8655
- setPresenterCaption: (caption: string) => void;
8656
- setPresenterSubtitlesVisible: (visible: boolean) => void;
8657
- updatePresenterSnapshot: (patch: Partial<PresentationSnapshot>) => void;
8658
- swapPresenterDisplays: () => Promise<boolean>;
9010
+ onToggleSidebar: () => void;
9011
+ onToggleInspector: () => void;
9012
+ /** Opens the inspector pane and switches to the properties tab (for animation panel). */
9013
+ onOpenAnimationPanel: () => void;
9014
+ /** Adds an animation preset to the selected element. */
9015
+ onAddAnimation?: (preset: string, group: 'entrance' | 'emphasis' | 'exit') => void;
9016
+ /** Removes all animations from the selected element. */
9017
+ onRemoveAnimation?: () => void;
9018
+ onToggleCompactToolbar: () => void;
9019
+ onSetToolbarSection: (section: ToolbarSection) => void;
9020
+ onZoomIn: () => void;
9021
+ onZoomOut: () => void;
9022
+ onZoomToFit: () => void;
9023
+ onUndo: () => void;
9024
+ onRedo: () => void;
9025
+ onToggleFindReplace: () => void;
9026
+ onSetNewShapeType: (type: SupportedShapeType) => void;
9027
+ onAddTextBox: () => void;
9028
+ onAddShape: () => void;
9029
+ onAddTable: () => void;
9030
+ onAddChart?: (chartType: PptxChartType) => void;
9031
+ onAddSmartArt: () => void;
9032
+ onAddEquation: () => void;
9033
+ onAddActionButton: (shapeType: string) => void;
9034
+ onInsertField?: (fieldType: string, value?: string) => void;
9035
+ onOpenHeaderFooter?: () => void;
9036
+ onOpenImagePicker: () => void;
9037
+ onOpenMediaPicker: () => void;
9038
+ onSetActiveTool: (tool: DrawingTool) => void;
9039
+ onSetDrawingColor: (color: string) => void;
9040
+ onSetDrawingWidth: (width: number) => void;
9041
+ onSetEditTemplateMode: (mode: boolean) => void;
9042
+ spellCheckEnabled: boolean;
9043
+ showGrid: boolean;
9044
+ showRulers: boolean;
9045
+ snapToGrid: boolean;
9046
+ snapToShape: boolean;
9047
+ onSetSpellCheckEnabled: (enabled: boolean) => void;
9048
+ onSetShowGrid: (enabled: boolean) => void;
9049
+ onSetShowRulers: (enabled: boolean) => void;
9050
+ onSetSnapToGrid: (enabled: boolean) => void;
9051
+ onSetSnapToShape: (enabled: boolean) => void;
9052
+ onAddGuide: (axis: 'h' | 'v') => void;
9053
+ onAlignElements: (align: string) => void;
9054
+ onDistributeElements: (axis: string) => void;
9055
+ canDistribute: boolean;
9056
+ onCopy: () => void;
9057
+ onCut: () => void;
9058
+ onPaste: () => void;
9059
+ onFlip: (direction: 'horizontal' | 'vertical') => void;
9060
+ onMoveLayer: (direction: string) => void;
9061
+ onMoveLayerToEdge: (direction: string) => void;
9062
+ onDuplicate: () => void;
9063
+ onDelete: () => void;
9064
+ /** Open another presentation (File ▸ Open). Hidden when not provided. */
9065
+ onOpenFile?: () => void;
9066
+ onOpenRecentFile?: (key: string) => void;
9067
+ onCreatePresentation: (templateId: string) => void;
9068
+ onExportPng: () => void;
9069
+ onExportPdf: () => void;
9070
+ onExportVideo: () => void;
9071
+ onExportGif: () => void;
9072
+ onPackageForSharing: () => void;
9073
+ onOpenShareDialog?: () => void;
9074
+ onSaveAsPptx: () => void;
9075
+ onSaveAsPpsx: () => void;
9076
+ onSaveAsPptm: () => void;
9077
+ hasMacros: boolean;
9078
+ onCopySlideAsImage: () => void;
9079
+ onPrint: () => void;
9080
+ onToggleShortcuts: () => void;
9081
+ onOpenSettings?: () => void;
9082
+ onRunAccessibilityCheck: () => void;
9083
+ onToggleSlideSorter: () => void;
9084
+ onUpdateTextStyle: (updates: Partial<TextStyle>) => void;
9085
+ /** Rewrite the selected text's characters (PowerPoint's Aa "Change Case" dropdown). */
9086
+ onTransformTextCase: (mode: ChangeCaseMode) => void;
9087
+ isOverflowMenuOpen: boolean;
9088
+ onSetOverflowMenuOpen: (open: boolean) => void;
9089
+ layoutOptions: Array<{
9090
+ path: string;
9091
+ name: string;
9092
+ }>;
9093
+ onInsertSlideFromLayout: (path: string, name?: string) => void;
9094
+ customShows: PptxCustomShow[];
9095
+ activeCustomShowId: string | null;
9096
+ onSetActiveCustomShowId: (id: string | null) => void;
9097
+ onCreateCustomShow: () => void;
9098
+ onRenameActiveCustomShow: () => void;
9099
+ onDeleteActiveCustomShow: () => void;
9100
+ onToggleCurrentSlideInActiveShow: () => void;
9101
+ isCurrentSlideInActiveShow: boolean;
9102
+ onToggleVersionHistory?: () => void;
9103
+ onOpenPasswordProtection?: () => void;
9104
+ onOpenDocumentProperties?: () => void;
9105
+ onOpenFontEmbedding?: () => void;
9106
+ onOpenDigitalSignatures?: () => void;
9107
+ onEnterMasterView: () => void;
9108
+ onCloseMasterView: () => void;
9109
+ onEnterPresenterView?: () => void;
9110
+ onEnterRehearsalMode?: () => void;
9111
+ onToggleThemeEditor: () => void;
9112
+ isThemeEditorOpen: boolean;
9113
+ onToggleThemeGallery: () => void;
9114
+ isThemeGalleryOpen: boolean;
9115
+ onCompare?: () => void;
9116
+ onToggleComments?: () => void;
9117
+ isCommentsPanelOpen?: boolean;
9118
+ spellCheckActive?: boolean;
9119
+ slideCommentCount?: number;
9120
+ formatPainterActive?: boolean;
9121
+ onToggleFormatPainter?: () => void;
9122
+ canActivateFormatPainter?: boolean;
9123
+ isSelectionPaneOpen?: boolean;
9124
+ onToggleSelectionPane?: () => void;
9125
+ eyedropperActive?: boolean;
9126
+ onToggleEyedropper?: () => void;
9127
+ onOpenSetUpSlideShow?: () => void;
9128
+ onOpenBroadcastDialog?: () => void;
9129
+ onToggleSubtitles?: () => void;
9130
+ showSubtitles?: boolean;
9131
+ activeSlide?: PptxSlide;
9132
+ onTransitionChange: (updates: Partial<PptxSlideTransition>) => void;
9133
+ onApplyTransitionToAll: () => void;
9134
+ /** Host-supplied list of toolbar buttons/ribbon tabs to hide. See `PowerPointViewerProps.hiddenActions`. */
9135
+ hiddenActions?: readonly ToolbarActionId[];
9136
+ /** Whether the AI assistant is available (the host passed the `ai` prop). */
9137
+ aiEnabled?: boolean;
9138
+ /** Whether the AI assistant panel is currently open. */
9139
+ isAiPanelOpen?: boolean;
9140
+ /** Toggle the AI assistant panel. */
9141
+ onToggleAiPanel?: () => void;
8659
9142
  }
8660
9143
  //#endregion
8661
- //#region src/viewer/hooks/useThemeSwitching.d.ts
8662
- interface UseThemeSwitchingInput {
8663
- /** Ref to the PptxHandler instance. */
8664
- handlerRef: RefObject<PptxHandler | null>;
8665
- /** Current parsed presentation data (null when nothing is loaded). */
8666
- data: PptxData | null;
8667
- /** Callback to update the presentation data after theme switch. */
8668
- onDataChange: (newData: PptxData) => void;
8669
- /** Optional callback fired when theme switch completes successfully. */
8670
- onThemeChanged?: (preset: PptxThemePreset) => void;
9144
+ //#region src/viewer/utils/table-band-style.d.ts
9145
+ /** Context for resolving table style colours from the theme. */
9146
+ interface TableStyleContext {
9147
+ tableStyleMap?: ParsedTableStyleMap;
9148
+ theme?: PptxTheme;
8671
9149
  }
8672
- interface ThemeSwitchingResult {
8673
- /** All available built-in theme presets. */
8674
- presets: readonly PptxThemePreset[];
8675
- /**
8676
- * Apply a theme preset to the current presentation.
8677
- * Updates both the in-memory ZIP and all resolved element colours.
8678
- */
8679
- switchToPreset: (preset: PptxThemePreset) => Promise<void>;
9150
+ //#endregion
9151
+ //#region src/viewer/components/canvas/canvas-types.d.ts
9152
+ interface ZoomViewport {
9153
+ canvasViewportRef: React$1.RefObject<HTMLDivElement | null>;
9154
+ editWrapperRef: React$1.RefObject<HTMLDivElement | null>;
9155
+ canvasStageRef: React$1.RefObject<HTMLDivElement | null>;
9156
+ editorScale: number;
9157
+ }
9158
+ interface SlideCanvasProps {
9159
+ activeSlide: PptxSlide | undefined;
9160
+ templateElements: PptxElement[];
9161
+ canvasSize: CanvasSize;
9162
+ zoom: ZoomViewport;
9163
+ mode: ViewerMode;
9164
+ canEdit: boolean;
9165
+ editTemplateMode: boolean;
9166
+ selectedElementIdSet: Set<string>;
9167
+ selectedElement: PptxElement | null;
9168
+ inlineEditingElementId: string | null;
9169
+ inlineEditingText: string;
9170
+ spellCheckEnabled: boolean;
9171
+ mediaDataUrls: Map<string, string>;
9172
+ tableEditorState: TableCellEditorState | null;
9173
+ marqueeSelectionState: MarqueeSelectionState | null;
9174
+ snapLines: Array<{
9175
+ axis: string;
9176
+ position: number;
9177
+ }>;
9178
+ showGrid: boolean;
9179
+ /** Grid spacing in CSS px (derived from PPTX gridSpacing EMUs). */
9180
+ gridSpacingPx?: number;
9181
+ showRulers: boolean;
9182
+ /** Unit system for rulers (default: inches). */
9183
+ rulerUnit?: RulerUnit;
9184
+ guides: Array<{
9185
+ id: string;
9186
+ axis: 'h' | 'v';
9187
+ position: number;
9188
+ }>;
9189
+ presentationElementStates?: Map<string, ElementAnimationState>;
9190
+ presentationKeyframesCss?: string;
9191
+ onClick: (elementId: string, e: React$1.MouseEvent) => void;
9192
+ onDoubleClick: (elementId: string, e: React$1.MouseEvent) => void;
9193
+ onMouseDown: (elementId: string, e: React$1.MouseEvent) => void;
9194
+ onContextMenu: (elementId: string, e: React$1.MouseEvent) => void;
9195
+ /** Called when the user presses mouse down on empty canvas space. */
9196
+ onCanvasMouseDown?: (e: React$1.MouseEvent) => void;
9197
+ onResizePointerDown: (elementId: string, e: React$1.MouseEvent, handle: string) => void;
9198
+ onAdjustmentPointerDown: (elementId: string, e: React$1.MouseEvent) => void;
9199
+ /** Commit a new rotation (degrees) when the on-canvas rotate handle is dragged. */
9200
+ onRotate?: (elementId: string, rotationDeg: number) => void;
9201
+ onInlineEditChange: (text: string) => void;
9202
+ onInlineEditCommit: () => void;
9203
+ onInlineEditCancel: () => void;
9204
+ onTableCellSelect: (cell: Omit<TableCellEditorState, 'elementId'> | null, elementId: string) => void;
9205
+ /** Called when an edited table cell should be committed. */
9206
+ onCommitCellEdit?: (elementId: string, rowIndex: number, colIndex: number, text: string) => void;
8680
9207
  /**
8681
- * Apply a custom colour scheme (and optional font scheme) to the
8682
- * current presentation.
9208
+ * Commit a partial update to a SmartArt element from inline (on-canvas) node
9209
+ * editing. Routed to the same element-update path the inspector uses (undo/redo
9210
+ * + dirty marking). When absent, inline SmartArt editing is disabled.
8683
9211
  */
8684
- switchToCustom: (colorScheme: PptxThemeColorScheme, fontScheme?: PptxThemeFontScheme, themeName?: string) => Promise<void>;
9212
+ onUpdateSmartArtElement?: (elementId: string, updates: Partial<PptxElement>) => void;
8685
9213
  /**
8686
- * Get the preset matching the current presentation theme (if any).
8687
- * Returns undefined if the current theme does not match a built-in preset.
9214
+ * Apply a text-style toggle (Ctrl/Cmd+B/I/U) to the element being
9215
+ * inline-edited. Routed to the same updateSelectedTextStyle path as the
9216
+ * toolbar. When absent, the inline formatting shortcuts are inert.
8688
9217
  */
8689
- currentPreset: PptxThemePreset | undefined;
8690
- }
9218
+ onFormatText?: (updates: Partial<TextStyle>) => void;
9219
+ /** Called when table column widths are resized. */
9220
+ onResizeTableColumns?: (elementId: string, newWidths: number[]) => void;
9221
+ /** Called when a table row is resized. */
9222
+ onResizeTableRow?: (elementId: string, rowIndex: number, newHeight: number) => void;
9223
+ /** Find & Replace results (all matches across all slides). */
9224
+ findResults?: Array<{
9225
+ slideIndex: number;
9226
+ elementId: string;
9227
+ segmentIndex: number;
9228
+ startOffset: number;
9229
+ length: number;
9230
+ }>;
9231
+ /** Index of the currently focused find result (-1 for none). */
9232
+ findResultIndex?: number;
9233
+ /** Index of the currently visible slide (needed to filter find results). */
9234
+ activeSlideIndex?: number;
9235
+ /** Currently active drawing tool ("select" means no drawing overlay). */
9236
+ activeTool?: DrawingTool;
9237
+ /** Stroke colour for pen / highlighter. */
9238
+ drawingColor?: string;
9239
+ /** Stroke width for pen / highlighter. */
9240
+ drawingWidth?: number;
9241
+ /** Ref that is true while a pointer stroke is in progress. */
9242
+ isDrawingRef?: React$1.RefObject<boolean>;
9243
+ /** Called when a completed ink stroke should be added to the slide. */
9244
+ onAddInkElement?: (ink: InkPptxElement) => void;
9245
+ /** Called when a freeform drawing stroke should be added as a shape element. */
9246
+ onAddFreeformShape?: (shape: ShapePptxElement) => void;
9247
+ /** Called when the eraser tool removes an ink element. */
9248
+ onEraseInkElement?: (elementId: string) => void;
9249
+ /** Called when a shape-level action is clicked (e.g. slide jump, URL). */
9250
+ onActionClick?: (elementId: string, action: PptxAction) => void;
9251
+ /** Called when a text-level hyperlink is clicked. */
9252
+ onHyperlinkClick?: (url: string) => void;
9253
+ /** Comments for the current slide (used for on-canvas markers). */
9254
+ comments?: PptxComment[];
9255
+ /** Whether to show comment markers on the slide canvas. */
9256
+ showCommentMarkers?: boolean;
9257
+ /** Called when a comment marker is clicked. */
9258
+ onCommentMarkerClick?: (commentId: string) => void;
9259
+ onMoveGuide?: (guideId: string, position: number) => void;
9260
+ onDeleteGuide?: (guideId: string) => void;
9261
+ onCreateGuideFromRuler?: (axis: 'h' | 'v', positionPx: number) => void;
9262
+ /** When true, shows connection sites on shapes and enables connector drawing. */
9263
+ connectorCreationMode?: boolean;
9264
+ /** Called when a new connector is created between two shapes. */
9265
+ onCreateConnector?: (connector: ConnectorPptxElement) => void;
9266
+ /** All slides in the presentation (for zoom element thumbnails). */
9267
+ allSlides?: readonly PptxSlide[];
9268
+ /** Callback fired when a zoom element is clicked in presentation mode. */
9269
+ onZoomClick?: (targetSlideIndex: number, returnSlideIndex: number) => void;
9270
+ /** Index of the current slide (for zoom return navigation). */
9271
+ sourceSlideIndex?: number;
9272
+ /** Context for text field placeholder substitution (slide number, header/footer, etc.). */
9273
+ fieldContext?: FieldSubstitutionContext;
9274
+ /** Theme + table style map for resolving table band/header colours. */
9275
+ tableStyleContext?: TableStyleContext;
9276
+ /** Optional collaboration cursor overlay rendered on top of the canvas. */
9277
+ collaborationOverlay?: React$1.ReactNode;
9278
+ /**
9279
+ * When true, the stage marks itself `data-pptx-ai-active` so element colour
9280
+ * changes tween while the AI assistant is working (see AiFocusHighlightOverlay).
9281
+ */
9282
+ aiActive?: boolean;
9283
+ }
9284
+ //#endregion
9285
+ //#region src/viewer/hooks/useAutosave.d.ts
9286
+ type AutosaveStatus = {
9287
+ state: 'idle';
9288
+ } | {
9289
+ state: 'disabled';
9290
+ reason: string;
9291
+ } | {
9292
+ state: 'saving';
9293
+ } | {
9294
+ state: 'saved';
9295
+ timestamp: number;
9296
+ } | {
9297
+ state: 'error';
9298
+ message: string;
9299
+ };
9300
+ interface UseAutosaveInput {
9301
+ /** Whether the document has unsaved changes. */
9302
+ isDirty: boolean;
9303
+ /** File path or name of the currently-open PPTX. Required for autosave to work. */
9304
+ filePath: string | undefined;
9305
+ /** Serialise current editor state to a Uint8Array. */
9306
+ serializeSlides: () => Promise<Uint8Array | null>;
9307
+ /** Autosave interval in seconds (default 120). */
9308
+ intervalSeconds?: number;
9309
+ /** Whether autosave is enabled. */
9310
+ enabled?: boolean;
9311
+ }
9312
+ interface UseAutosaveResult {
9313
+ /** Current autosave status for display in the StatusBar. */
9314
+ autosaveStatus: AutosaveStatus;
9315
+ /** Manually trigger an autosave right now. */
9316
+ triggerAutosave: () => Promise<void>;
9317
+ }
9318
+ declare function useAutosave(input: UseAutosaveInput): UseAutosaveResult;
9319
+ //#endregion
9320
+ //#region src/viewer/hooks/useViewerBuildingBlocks.d.ts
9321
+ interface UseViewerBuildingBlocksInput {
9322
+ /** PPTX content as ArrayBuffer/Uint8Array, or null/undefined while no file is loaded. */
9323
+ content: ArrayBuffer | Uint8Array | null | undefined;
9324
+ /** Whether editing actions are enabled. Defaults to false (view-only). */
9325
+ canEdit?: boolean;
9326
+ /** Original file path, used for autosave recovery. */
9327
+ filePath?: string;
9328
+ /** Display name for the toolbar's file-name-aware controls (e.g. title bar hosts build themselves). */
9329
+ fileName?: string;
9330
+ /** Whether the built-in autosave-to-localStorage recovery timer is active. Defaults to true. */
9331
+ autosaveEnabled?: boolean;
9332
+ /** Display name used as the author for comments. */
9333
+ userName?: string;
9334
+ /** Host-supplied list of toolbar buttons/ribbon tabs to hide. */
9335
+ hiddenActions?: readonly ToolbarActionId[];
9336
+ /** Imperative handle ref, exposing the same `PowerPointViewerHandle` API `PowerPointViewer` does. */
9337
+ handle?: React.ForwardedRef<PowerPointViewerHandle>;
9338
+ onContentChange?: (content: Uint8Array) => void;
9339
+ onDirtyChange?: (dirty: boolean) => void;
9340
+ onActiveSlideChange?: (index: number) => void;
9341
+ onModeChange?: (mode: ViewerMode) => void;
9342
+ onZoomChange?: (zoom: number) => void;
9343
+ onSelectionChange?: (ids: string[]) => void;
9344
+ onSlideCountChange?: (count: number) => void;
9345
+ /** Fired by the toolbar's "Settings" button; the host owns rendering that dialog. */
9346
+ onOpenSettings?: () => void;
9347
+ /** Fired by the toolbar's "Header & Footer" button; the host owns rendering that panel. */
9348
+ onOpenHeaderFooter?: () => void;
9349
+ /** Fired by the toolbar's "Share" button; the host owns rendering that dialog. */
9350
+ onOpenShareDialog?: () => void;
9351
+ }
9352
+ interface ViewerBuildingBlocksResult {
9353
+ /** Flat, self-contained props for the standalone `<Toolbar>` component. */
9354
+ toolbarProps: ToolbarProps;
9355
+ /** Flat, self-contained props for the standalone `<SlideCanvas>` component. */
9356
+ canvasProps: SlideCanvasProps;
9357
+ /** Current viewer mode (edit, view, present, master). */
9358
+ mode: ViewerMode;
9359
+ /** True while the initial parse of `content` is in progress. */
9360
+ loading: boolean;
9361
+ /** Parse error message, or null. */
9362
+ error: string | null;
9363
+ /** Current autosave-to-localStorage recovery status. */
9364
+ autosaveStatus: AutosaveStatus;
9365
+ }
9366
+ declare function useViewerBuildingBlocks(input: UseViewerBuildingBlocksInput): ViewerBuildingBlocksResult;
9367
+
9368
+ //#region src/viewer/hooks/presentation-mode/types.d.ts
8691
9369
  /**
8692
- * React hook providing theme switching capabilities for the PowerPoint viewer.
8693
- *
8694
- * @example
8695
- * ```tsx
8696
- * const { presets, switchToPreset, currentPreset } = useThemeSwitching({
8697
- * handlerRef,
8698
- * data,
8699
- * onDataChange: setData,
8700
- * });
9370
+ * How a forward/backward slide advance was requested.
8701
9371
  *
8702
- * return (
8703
- * <div>
8704
- * {presets.map(preset => (
8705
- * <button
8706
- * key={preset.id}
8707
- * onClick={() => switchToPreset(preset)}
8708
- * aria-pressed={preset.id === currentPreset?.id}
8709
- * >
8710
- * {preset.name}
8711
- * </button>
8712
- * ))}
8713
- * </div>
8714
- * );
8715
- * ```
9372
+ * - `'click'`: a click/tap on the slide surface (PowerPoint's "On Mouse Click"
9373
+ * advance). This is the only trigger governed by `advanceOnClick`.
9374
+ * - `'explicit'`: keyboard, navigation buttons, action triggers, and timed
9375
+ * auto-advance. These always navigate regardless of `advanceOnClick`, matching
9376
+ * PowerPoint (arrow keys / Next always work even when click-advance is off).
8716
9377
  */
8717
- declare function useThemeSwitching(input: UseThemeSwitchingInput): ThemeSwitchingResult;
8718
- //#endregion
8719
- //#region ../../node_modules/.bun/lib0@0.2.117/node_modules/lib0/observable.d.ts
9378
+ type SlideAdvanceTrigger = 'click' | 'explicit';
8720
9379
  /**
8721
- * Handles named events.
8722
- *
8723
- * @deprecated
8724
- * @template N
9380
+ * State describing the transition overlay that plays while advancing into a
9381
+ * slide that carries a `p:transition`. The outgoing slide is snapshotted into
9382
+ * an animated overlay layer while the incoming slide renders underneath on the
9383
+ * main stage; the overlay tears down once `durationMs` elapses.
8725
9384
  */
8726
- declare class Observable<N> {
9385
+ interface PresentationTransitionOverlayState {
9386
+ /** Index of the leaving slide, rendered (animated) in the overlay layer. */
9387
+ outgoingSlideIndex: number;
9388
+ /** Index of the arriving slide, already live on the main stage. */
9389
+ incomingSlideIndex: number;
9390
+ /** The incoming slide's transition definition (drives the CSS animation). */
9391
+ transition: PptxSlideTransition;
9392
+ /** Resolved transition duration (ms). */
9393
+ durationMs: number;
9394
+ }
9395
+ interface UsePresentationModeInput {
9396
+ mode: ViewerMode;
9397
+ slides: PptxSlide[];
9398
+ visibleSlideIndexes: number[];
9399
+ activeSlideIndex: number;
9400
+ containerRef: React.RefObject<HTMLElement | null>;
9401
+ /** Raw PPTX bytes: forwarded to audience window for content sharing. */
9402
+ content?: ArrayBuffer | Uint8Array | null;
9403
+ onSetMode: (mode: ViewerMode) => void;
9404
+ onSetActiveSlideIndex: (index: number) => void;
8727
9405
  /**
8728
- * Some desc.
8729
- * @type {Map<N, any>}
9406
+ * Play a sound file for an action/transition. When `options.loop` is true the
9407
+ * audio repeats until the next animation sound plays or the show exits
9408
+ * (used for transition sounds flagged with `soundLoop`).
8730
9409
  */
8731
- _observers: Map<N, any>;
9410
+ onPlayActionSound?: (soundPath: string, options?: {
9411
+ loop?: boolean;
9412
+ }) => void;
9413
+ /** Called when L key is pressed during presentation. */
9414
+ onToggleLaser?: () => void;
9415
+ /** Called when P key is pressed during presentation. */
9416
+ onTogglePen?: () => void;
9417
+ /** Called when E key is pressed during presentation. */
9418
+ onToggleEraser?: () => void;
9419
+ /** Called when Ctrl+M is pressed during presentation. */
9420
+ onToggleToolbar?: () => void;
9421
+ /** Called to persist rehearsal timings into slide transitions. */
9422
+ onSaveRehearsalTimings?: (timings: Record<number, number>) => void;
9423
+ /** Whether to loop continuously (kiosk or explicit loop setting). */
9424
+ loopContinuously?: boolean;
9425
+ /** Whether to play animations during the slide show (false = skip all animations). */
9426
+ showWithAnimation?: boolean;
9427
+ /** Whether to use rehearsed auto-advance timings (false = manual advance only). */
9428
+ useTimings?: boolean;
8732
9429
  /**
8733
- * @param {N} name
8734
- * @param {function} f
9430
+ * Options > Advanced > "End with black slide". When true (PowerPoint's
9431
+ * default), advancing past the last slide shows a black end-of-show
9432
+ * screen; the next advance (or a click on it) exits. When false,
9433
+ * advancing past the last slide exits the show directly.
8735
9434
  */
8736
- on(name: N, f: Function): void;
9435
+ endWithBlackSlide?: boolean;
9436
+ }
9437
+ interface UsePresentationModeResult {
9438
+ presentationSlideIndex: number;
9439
+ setPresentationSlideIndex: (index: number) => void;
9440
+ presentationSlideVisible: boolean;
9441
+ /** Active slide-transition overlay, or `null` when no transition is playing. */
9442
+ transitionOverlay: PresentationTransitionOverlayState | null;
9443
+ /** Tear down the transition overlay once its animation completes. */
9444
+ handleTransitionOverlayComplete: () => void;
9445
+ presentationAnimations: PresentationAnimationRuntime[];
9446
+ presentationElementStates: Map<string, ElementAnimationState>;
9447
+ presentationKeyframesCss: string;
9448
+ clearPresentationTimers: () => void;
9449
+ runPresentationEntranceAnimations: (slideIndex: number) => void;
9450
+ /** True while the black "End of slide show" screen is displayed. */
9451
+ endOfShowVisible: boolean;
9452
+ movePresentationSlide: (direction: 1 | -1, trigger?: SlideAdvanceTrigger) => void;
9453
+ navigateToSlide: (slideIndex: number) => void;
9454
+ handlePresentationAction: (action: PptxAction) => void;
8737
9455
  /**
8738
- * @param {N} name
8739
- * @param {function} f
9456
+ * Handle a shape click in presentation mode. If the shape is an interactive
9457
+ * trigger, play its animation sequence. Returns `true` if handled.
8740
9458
  */
8741
- once(name: N, f: Function): void;
8742
- /**
8743
- * @param {N} name
8744
- * @param {function} f
9459
+ handleInteractiveShapeClick: (shapeId: string) => boolean;
9460
+ /** Set of shape IDs that are interactive sequence triggers on the current slide. */
9461
+ interactiveTriggerShapeIds: ReadonlySet<string>;
9462
+ /** Set of shape IDs that are hover animation triggers on the current slide. */
9463
+ hoverTriggerShapeIds: ReadonlySet<string>;
9464
+ /** Handle hover start on a shape. If the shape has a hover sequence, play it. Returns `true` if handled. */
9465
+ handleHoverStart: (shapeId: string) => boolean;
9466
+ /** Handle hover end on a shape. Resets the hover sequence for replay. */
9467
+ handleHoverEnd: (shapeId: string) => void;
9468
+ /** Must be called from a user-gesture handler (click) to satisfy browser fullscreen policy. */
9469
+ enterPresentMode: () => void;
9470
+ /** Whether presenter view (split-screen with notes) is active instead of fullscreen. */
9471
+ presenterMode: boolean;
9472
+ /** Enter presenter view mode (no fullscreen, shows notes panel). */
9473
+ enterPresenterView: () => void;
9474
+ /** Toggle between fullscreen and presenter view during presentation. */
9475
+ togglePresenterView: () => void;
9476
+ /** Timestamp (ms) when the presentation started: used for elapsed timer. */
9477
+ presentationStartTime: number | null;
9478
+ /** Whether the current presentation session is in rehearse-timings mode. */
9479
+ rehearsing: boolean;
9480
+ /** Enter rehearse-timings mode (fullscreen presentation + timing HUD). */
9481
+ enterRehearsalMode: () => void;
9482
+ /** Recorded timings in ms, keyed by slide index. Populated during rehearsal. */
9483
+ recordedTimings: Record<number, number>;
9484
+ /** Timestamp when the current slide started (ms since epoch). */
9485
+ slideStartTime: number | null;
9486
+ /** Whether the rehearsal summary dialog should be shown. */
9487
+ showRehearsalSummary: boolean;
9488
+ /** Dismiss the rehearsal summary (discard timings). */
9489
+ dismissRehearsalSummary: () => void;
9490
+ /** Save recorded timings into each slide's transition.advanceAfterMs. */
9491
+ saveRehearsalTimings: () => void;
9492
+ /** Whether rehearsal timer is paused. */
9493
+ rehearsalPaused: boolean;
9494
+ /** Toggle the rehearsal timer pause state. */
9495
+ toggleRehearsalPause: () => void;
9496
+ /** Handle a zoom element click in presentation mode. */
9497
+ handleZoomClick: (targetSlideIndex: number, returnSlideIndex: number) => void;
9498
+ /** Ref holding the slide index to return to after zoom navigation. */
9499
+ zoomReturnSlideIndex: React.RefObject<number | null>;
9500
+ /** Navigate back to the zoom summary slide. Returns true if navigation occurred. */
9501
+ returnToZoomSlide: () => boolean;
9502
+ /** Clear the stored zoom return index. */
9503
+ clearZoomReturn: () => void;
9504
+ /** Open the audience display in a separate browser window. Returns `true` if successful. */
9505
+ openAudienceWindow: () => boolean;
9506
+ /** Close the audience display window. */
9507
+ closeAudienceWindow: () => void;
9508
+ /** Whether the audience window is currently open. */
9509
+ isAudienceWindowOpen: () => boolean;
9510
+ /** Send a slide index to the audience window explicitly. */
9511
+ syncSlideToAudience: (slideIndex: number) => void;
9512
+ syncStateToAudience: (snapshot: PresentationSnapshot) => void;
9513
+ presenterSnapshot: PresentationSnapshot;
9514
+ setPresenterBlackout: (blackout: PresentationSnapshot['blackout']) => void;
9515
+ togglePresenterTimer: () => void;
9516
+ resetPresenterTimer: () => void;
9517
+ stepPresenterZoom: (direction: 1 | -1) => void;
9518
+ resetPresenterZoom: () => void;
9519
+ setPresenterCaption: (caption: string) => void;
9520
+ setPresenterSubtitlesVisible: (visible: boolean) => void;
9521
+ updatePresenterSnapshot: (patch: Partial<PresentationSnapshot>) => void;
9522
+ swapPresenterDisplays: () => Promise<boolean>;
9523
+ }
9524
+ //#endregion
9525
+ //#region src/viewer/hooks/useThemeSwitching.d.ts
9526
+ interface UseThemeSwitchingInput {
9527
+ /** Ref to the PptxHandler instance. */
9528
+ handlerRef: RefObject<PptxHandler | null>;
9529
+ /** Current parsed presentation data (null when nothing is loaded). */
9530
+ data: PptxData | null;
9531
+ /** Callback to update the presentation data after theme switch. */
9532
+ onDataChange: (newData: PptxData) => void;
9533
+ /** Optional callback fired when theme switch completes successfully. */
9534
+ onThemeChanged?: (preset: PptxThemePreset) => void;
9535
+ }
9536
+ interface ThemeSwitchingResult {
9537
+ /** All available built-in theme presets. */
9538
+ presets: readonly PptxThemePreset[];
9539
+ /**
9540
+ * Apply a theme preset to the current presentation.
9541
+ * Updates both the in-memory ZIP and all resolved element colours.
9542
+ */
9543
+ switchToPreset: (preset: PptxThemePreset) => Promise<void>;
9544
+ /**
9545
+ * Apply a custom colour scheme (and optional font scheme) to the
9546
+ * current presentation.
9547
+ */
9548
+ switchToCustom: (colorScheme: PptxThemeColorScheme, fontScheme?: PptxThemeFontScheme, themeName?: string) => Promise<void>;
9549
+ /**
9550
+ * Get the preset matching the current presentation theme (if any).
9551
+ * Returns undefined if the current theme does not match a built-in preset.
9552
+ */
9553
+ currentPreset: PptxThemePreset | undefined;
9554
+ }
9555
+ /**
9556
+ * React hook providing theme switching capabilities for the PowerPoint viewer.
9557
+ *
9558
+ * @example
9559
+ * ```tsx
9560
+ * const { presets, switchToPreset, currentPreset } = useThemeSwitching({
9561
+ * handlerRef,
9562
+ * data,
9563
+ * onDataChange: setData,
9564
+ * });
9565
+ *
9566
+ * return (
9567
+ * <div>
9568
+ * {presets.map(preset => (
9569
+ * <button
9570
+ * key={preset.id}
9571
+ * onClick={() => switchToPreset(preset)}
9572
+ * aria-pressed={preset.id === currentPreset?.id}
9573
+ * >
9574
+ * {preset.name}
9575
+ * </button>
9576
+ * ))}
9577
+ * </div>
9578
+ * );
9579
+ * ```
9580
+ */
9581
+ declare function useThemeSwitching(input: UseThemeSwitchingInput): ThemeSwitchingResult;
9582
+ //#endregion
9583
+ //#region ../../node_modules/.bun/lib0@0.2.117/node_modules/lib0/observable.d.ts
9584
+ /**
9585
+ * Handles named events.
9586
+ *
9587
+ * @deprecated
9588
+ * @template N
9589
+ */
9590
+ declare class Observable<N> {
9591
+ /**
9592
+ * Some desc.
9593
+ * @type {Map<N, any>}
9594
+ */
9595
+ _observers: Map<N, any>;
9596
+ /**
9597
+ * @param {N} name
9598
+ * @param {function} f
9599
+ */
9600
+ on(name: N, f: Function): void;
9601
+ /**
9602
+ * @param {N} name
9603
+ * @param {function} f
9604
+ */
9605
+ once(name: N, f: Function): void;
9606
+ /**
9607
+ * @param {N} name
9608
+ * @param {function} f
8745
9609
  */
8746
9610
  off(name: N, f: Function): void;
8747
9611
  /**
@@ -8939,591 +9803,219 @@ declare function useCollaborativeHistory({ localClientId: _localClientId, handle
8939
9803
  //#endregion
8940
9804
  //#region src/viewer/hooks/collaboration/useYjsDocumentSync.d.ts
8941
9805
  interface UseYjsDocumentSyncInput {
8942
- /** The Yjs document (from useYjsProvider). null when not collaborating. */
8943
- doc: Doc | null;
8944
- /** Current slides state. */
8945
- slides: PptxSlide[];
8946
- /** Separated master/layout (template) elements, merged back on write-back. */
8947
- templateElementsBySlideId: Record<string, PptxElement[]>;
8948
- /** React state setter for slides. */
8949
- setSlides: React.Dispatch<React.SetStateAction<PptxSlide[]>>;
8950
- /** Whether collaboration is active (status === 'connected'). */
8951
- isConnected: boolean;
8952
- /**
8953
- * Whether the provider completed its initial document sync. Local -> doc
8954
- * writes are gated on this so a late joiner never seeds its bootstrap deck
8955
- * into a room whose real content has not arrived yet. Defaults to true for
8956
- * callers that manage sync readiness themselves.
8957
- */
8958
- isSynced?: boolean;
8959
- /** Collaboration config (for role and write-back). */
8960
- config?: Pick<CollaborationConfig, 'role' | 'onWriteBack' | 'writeBackDebounceMs'>;
8961
- /**
8962
- * Return the source PPTX bytes for write-back serialization. Only called
8963
- * when role === 'owner' and onWriteBack is set.
8964
- */
8965
- getSourceBytes?: () => Uint8Array | null;
8966
- /**
8967
- * Monotonic counter bumped each time the content-load pipeline finishes
8968
- * applying a parsed deck to viewer state. A local load that lands while the
8969
- * shared doc already holds slides (a late joiner's bootstrap deck parsing
8970
- * after the room state arrived) would silently clobber the synced slides;
8971
- * each bump re-adopts the doc's slides when the room has content.
8972
- */
8973
- loadVersion?: number;
8974
- }
8975
- declare function useYjsDocumentSync({ doc, slides, templateElementsBySlideId, setSlides, isConnected, isSynced, config, getSourceBytes, loadVersion }: UseYjsDocumentSyncInput): void;
8976
- //#endregion
8977
- //#region src/viewer/hooks/collaboration/useBroadcastFollower.d.ts
8978
- interface UseBroadcastFollowerInput {
8979
- /** The collaboration context (null when collaboration is disabled). */
8980
- collab: CollaborationContextValue | null;
8981
- /** Current local active slide index. */
8982
- activeSlideIndex: number;
8983
- /** Setter for the active slide index. */
8984
- setActiveSlideIndex: (index: number) => void;
8985
- /** Total number of slides (for bounds checking). */
8986
- slideCount: number;
8987
- /**
8988
- * When true, auto-follow stands down (e.g. the local user is manually
8989
- * following a specific peer via the follow bar). Defaults to false.
8990
- */
8991
- paused?: boolean;
8992
- }
8993
- declare function useBroadcastFollower({ collab, activeSlideIndex, setActiveSlideIndex, slideCount, paused }: UseBroadcastFollowerInput): void;
8994
- //#endregion
8995
- //#region src/viewer/hooks/collaboration/useFollowMode.d.ts
8996
- interface UseFollowModeInput {
8997
- /** The collaboration context (null when collaboration is disabled). */
8998
- collab: CollaborationContextValue | null;
8999
- /** Current local active slide index. */
9000
- activeSlideIndex: number;
9001
- /** Setter for the active slide index. */
9002
- setActiveSlideIndex: (index: number) => void;
9003
- /** Total number of slides (for bounds checking). */
9004
- slideCount: number;
9005
- }
9006
- interface UseFollowModeResult {
9007
- /** The clientId currently being followed, or null. */
9008
- followedClientId: number | null;
9009
- /** Follow the given peer, or `null` to stop following. */
9010
- followUser: (clientId: number | null) => void;
9011
- }
9012
- declare function useFollowMode({ collab, activeSlideIndex, setActiveSlideIndex, slideCount }: UseFollowModeInput): UseFollowModeResult;
9013
- //#endregion
9014
- //#region src/viewer/hooks/presentation-mode/useAnimationPlayback.d.ts
9015
- interface UseAnimationPlaybackInput {
9016
- slides: PptxSlide[];
9017
- onPlayActionSound?: (soundPath: string) => void;
9018
- /** When false, all animations are skipped (elements shown immediately). */
9019
- showWithAnimation?: boolean;
9020
- }
9021
- interface UseAnimationPlaybackResult {
9022
- presentationAnimations: PresentationAnimationRuntime[];
9023
- presentationElementStates: Map<string, ElementAnimationState>;
9024
- presentationKeyframesCss: string;
9025
- interactiveTriggerShapeIds: ReadonlySet<string>;
9026
- hoverTriggerShapeIds: ReadonlySet<string>;
9027
- clearPresentationTimers: () => void;
9028
- playNextAnimationGroup: () => boolean;
9029
- handleInteractiveShapeClick: (shapeId: string) => boolean;
9030
- handleHoverStart: (shapeId: string) => boolean;
9031
- handleHoverEnd: (shapeId: string) => void;
9032
- runPresentationEntranceAnimations: (slideIndex: number) => void;
9033
- /** Exposed so the orchestrator can schedule additional timers (e.g. auto-advance). */
9034
- presentationTimersRef: React.RefObject<number[]>;
9035
- }
9036
- declare function useAnimationPlayback(input: UseAnimationPlaybackInput): UseAnimationPlaybackResult;
9037
- //#endregion
9038
- //#region src/viewer/hooks/presentation-mode/useRehearsalTimings.d.ts
9039
- interface UseRehearsalTimingsInput {
9040
- containerRef: React.RefObject<HTMLElement | null>;
9041
- onSetMode: (mode: ViewerMode) => void;
9042
- onSaveRehearsalTimings?: (timings: Record<number, number>) => void;
9043
- setPresentationStartTime: (time: number | null) => void;
9044
- setPresenterMode: (mode: boolean) => void;
9045
- }
9046
- interface UseRehearsalTimingsResult {
9047
- rehearsing: boolean;
9048
- setRehearsing: React.Dispatch<React.SetStateAction<boolean>>;
9049
- recordedTimings: Record<number, number>;
9050
- slideStartTime: number | null;
9051
- showRehearsalSummary: boolean;
9052
- setShowRehearsalSummary: React.Dispatch<React.SetStateAction<boolean>>;
9053
- rehearsalPaused: boolean;
9054
- recordCurrentSlideTime: (slideIndex: number) => void;
9055
- dismissRehearsalSummary: () => void;
9056
- saveRehearsalTimings: () => void;
9057
- enterRehearsalMode: () => void;
9058
- toggleRehearsalPause: () => void;
9059
- }
9060
- declare function useRehearsalTimings(input: UseRehearsalTimingsInput): UseRehearsalTimingsResult;
9061
- //#endregion
9062
- //#region src/viewer/hooks/presentation-mode/usePresentationKeyboard.d.ts
9063
- interface UsePresentationKeyboardInput {
9064
- mode: ViewerMode;
9065
- movePresentationSlide: (direction: 1 | -1) => void;
9066
- onSetMode: (mode: ViewerMode) => void;
9067
- onToggleLaser?: () => void;
9068
- onTogglePen?: () => void;
9069
- onToggleEraser?: () => void;
9070
- onToggleToolbar?: () => void;
9071
- /** Toggle between presenter view (split-screen with notes) and fullscreen. */
9072
- onTogglePresenterView?: () => void;
9073
- onToggleBlackScreen?: () => void;
9074
- onToggleWhiteScreen?: () => void;
9075
- rehearsing: boolean;
9076
- recordCurrentSlideTime: (slideIndex: number) => void;
9077
- presentationSlideIndex: number;
9078
- setShowRehearsalSummary: (value: boolean) => void;
9079
- }
9080
- /**
9081
- * Registers keyboard shortcuts for presentation mode: arrow/space
9082
- * for slide navigation, Escape to exit, and annotation tool toggles.
9083
- */
9084
- declare function usePresentationKeyboard(input: UsePresentationKeyboardInput): void;
9085
- //#endregion
9086
- //#region src/viewer/hooks/presentation-mode/useSlideNavigation.d.ts
9087
- interface UseSlideNavigationInput {
9088
- slides: PptxSlide[];
9089
- visibleSlideIndexes: number[];
9090
- presentationSlideIndex: number;
9091
- setPresentationSlideIndex: (index: number) => void;
9092
- setPresentationSlideVisible: (visible: boolean) => void;
9093
- setTransitionOverlay: (state: PresentationTransitionOverlayState | null) => void;
9094
- onSetMode: (mode: ViewerMode) => void;
9095
- onSetActiveSlideIndex: (index: number) => void;
9096
- onPlayActionSound?: (soundPath: string) => void;
9097
- loopContinuously?: boolean;
9098
- /** Whether to use rehearsed auto-advance timings. When false, slides advance only on click. */
9099
- useTimings?: boolean;
9100
- /**
9101
- * Fired when the user advances past the last slide (no loop, no rehearsal).
9102
- * The presentation-mode hook uses it for PowerPoint's "End with black
9103
- * slide" behavior. When absent, advancing past the end clamps as before.
9104
- */
9105
- onAdvancePastLastSlide?: () => void;
9106
- playNextAnimationGroup: () => boolean;
9107
- clearPresentationTimers: () => void;
9108
- runPresentationEntranceAnimations: (slideIndex: number) => void;
9109
- presentationTimersRef: {
9110
- current: number[];
9111
- };
9112
- rehearsing: boolean;
9113
- recordCurrentSlideTime: (slideIndex: number) => void;
9114
- setShowRehearsalSummary: (value: boolean) => void;
9115
- }
9116
- interface UseSlideNavigationResult {
9117
- movePresentationSlide: (direction: 1 | -1) => void;
9118
- navigateToSlide: (slideIndex: number) => void;
9119
- handlePresentationAction: (action: PptxAction) => void;
9120
- scheduleAutoAdvanceForSlide: (slideIndex: number) => void;
9121
- }
9122
- declare function useSlideNavigation(input: UseSlideNavigationInput): UseSlideNavigationResult;
9123
- interface UsePresenterWindowInput {
9124
- currentSlideIndex: number;
9125
- isPresenterMode: boolean;
9126
- /** Raw PPTX bytes to share with the audience tab via IndexedDB. */
9127
- content?: ArrayBuffer | Uint8Array | null;
9128
- snapshot: PresentationSnapshot;
9129
- }
9130
- interface UsePresenterWindowResult {
9131
- openAudienceWindow: () => boolean;
9132
- closeAudienceWindow: () => void;
9133
- isAudienceWindowOpen: () => boolean;
9134
- syncSlideToAudience: (slideIndex: number) => void;
9135
- syncStateToAudience: (snapshot: PresentationSnapshot) => void;
9136
- swapDisplays: () => Promise<boolean>;
9137
- }
9138
- declare function usePresenterWindow(input: UsePresenterWindowInput): UsePresenterWindowResult;
9139
- //#endregion
9140
- //#region src/viewer/hooks/presentation-mode/useAudienceMode.d.ts
9141
- interface UseAudienceModeInput {
9142
- mode: ViewerMode;
9143
- onSetMode: (mode: ViewerMode) => void;
9144
- onSetActiveSlideIndex: (index: number) => void;
9145
- containerRef: React.RefObject<HTMLElement | null>;
9146
- onSnapshot?: (snapshot: PresentationSnapshot) => void;
9147
- }
9148
- /**
9149
- * When the page was opened with the `#pptx-audience` hash, this hook:
9150
- * 1. Auto-enters fullscreen presentation mode after content loads
9151
- * 2. Listens on BroadcastChannel for slide-change messages from the presenter
9152
- * 3. Exits presentation mode when the presenter sends an exit signal
9153
- */
9154
- declare function useAudienceMode(input: UseAudienceModeInput): void;
9155
-
9156
- //#region src/viewer/hooks/useAutosave.d.ts
9157
- type AutosaveStatus = {
9158
- state: 'idle';
9159
- } | {
9160
- state: 'disabled';
9161
- reason: string;
9162
- } | {
9163
- state: 'saving';
9164
- } | {
9165
- state: 'saved';
9166
- timestamp: number;
9167
- } | {
9168
- state: 'error';
9169
- message: string;
9170
- };
9171
- interface UseAutosaveInput {
9172
- /** Whether the document has unsaved changes. */
9173
- isDirty: boolean;
9174
- /** File path or name of the currently-open PPTX. Required for autosave to work. */
9175
- filePath: string | undefined;
9176
- /** Serialise current editor state to a Uint8Array. */
9177
- serializeSlides: () => Promise<Uint8Array | null>;
9178
- /** Autosave interval in seconds (default 120). */
9179
- intervalSeconds?: number;
9180
- /** Whether autosave is enabled. */
9181
- enabled?: boolean;
9182
- }
9183
- interface UseAutosaveResult {
9184
- /** Current autosave status for display in the StatusBar. */
9185
- autosaveStatus: AutosaveStatus;
9186
- /** Manually trigger an autosave right now. */
9187
- triggerAutosave: () => Promise<void>;
9188
- }
9189
- declare function useAutosave(input: UseAutosaveInput): UseAutosaveResult;
9190
- //#endregion
9191
- //#region src/viewer/utils/table-band-style.d.ts
9192
- /** Context for resolving table style colours from the theme. */
9193
- interface TableStyleContext {
9194
- tableStyleMap?: ParsedTableStyleMap;
9195
- theme?: PptxTheme;
9196
- }
9197
- //#endregion
9198
- //#region src/viewer/components/canvas/canvas-types.d.ts
9199
- interface ZoomViewport {
9200
- canvasViewportRef: React$1.RefObject<HTMLDivElement | null>;
9201
- editWrapperRef: React$1.RefObject<HTMLDivElement | null>;
9202
- canvasStageRef: React$1.RefObject<HTMLDivElement | null>;
9203
- editorScale: number;
9204
- }
9205
- interface SlideCanvasProps {
9206
- activeSlide: PptxSlide | undefined;
9207
- templateElements: PptxElement[];
9208
- canvasSize: CanvasSize;
9209
- zoom: ZoomViewport;
9210
- mode: ViewerMode;
9211
- canEdit: boolean;
9212
- editTemplateMode: boolean;
9213
- selectedElementIdSet: Set<string>;
9214
- selectedElement: PptxElement | null;
9215
- inlineEditingElementId: string | null;
9216
- inlineEditingText: string;
9217
- spellCheckEnabled: boolean;
9218
- mediaDataUrls: Map<string, string>;
9219
- tableEditorState: TableCellEditorState | null;
9220
- marqueeSelectionState: MarqueeSelectionState | null;
9221
- snapLines: Array<{
9222
- axis: string;
9223
- position: number;
9224
- }>;
9225
- showGrid: boolean;
9226
- /** Grid spacing in CSS px (derived from PPTX gridSpacing EMUs). */
9227
- gridSpacingPx?: number;
9228
- showRulers: boolean;
9229
- /** Unit system for rulers (default: inches). */
9230
- rulerUnit?: RulerUnit;
9231
- guides: Array<{
9232
- id: string;
9233
- axis: 'h' | 'v';
9234
- position: number;
9235
- }>;
9236
- presentationElementStates?: Map<string, ElementAnimationState>;
9237
- presentationKeyframesCss?: string;
9238
- onClick: (elementId: string, e: React$1.MouseEvent) => void;
9239
- onDoubleClick: (elementId: string, e: React$1.MouseEvent) => void;
9240
- onMouseDown: (elementId: string, e: React$1.MouseEvent) => void;
9241
- onContextMenu: (elementId: string, e: React$1.MouseEvent) => void;
9242
- /** Called when the user presses mouse down on empty canvas space. */
9243
- onCanvasMouseDown?: (e: React$1.MouseEvent) => void;
9244
- onResizePointerDown: (elementId: string, e: React$1.MouseEvent, handle: string) => void;
9245
- onAdjustmentPointerDown: (elementId: string, e: React$1.MouseEvent) => void;
9246
- /** Commit a new rotation (degrees) when the on-canvas rotate handle is dragged. */
9247
- onRotate?: (elementId: string, rotationDeg: number) => void;
9248
- onInlineEditChange: (text: string) => void;
9249
- onInlineEditCommit: () => void;
9250
- onInlineEditCancel: () => void;
9251
- onTableCellSelect: (cell: Omit<TableCellEditorState, 'elementId'> | null, elementId: string) => void;
9252
- /** Called when an edited table cell should be committed. */
9253
- onCommitCellEdit?: (elementId: string, rowIndex: number, colIndex: number, text: string) => void;
9254
- /**
9255
- * Commit a partial update to a SmartArt element from inline (on-canvas) node
9256
- * editing. Routed to the same element-update path the inspector uses (undo/redo
9257
- * + dirty marking). When absent, inline SmartArt editing is disabled.
9258
- */
9259
- onUpdateSmartArtElement?: (elementId: string, updates: Partial<PptxElement>) => void;
9260
- /**
9261
- * Apply a text-style toggle (Ctrl/Cmd+B/I/U) to the element being
9262
- * inline-edited. Routed to the same updateSelectedTextStyle path as the
9263
- * toolbar. When absent, the inline formatting shortcuts are inert.
9264
- */
9265
- onFormatText?: (updates: Partial<TextStyle>) => void;
9266
- /** Called when table column widths are resized. */
9267
- onResizeTableColumns?: (elementId: string, newWidths: number[]) => void;
9268
- /** Called when a table row is resized. */
9269
- onResizeTableRow?: (elementId: string, rowIndex: number, newHeight: number) => void;
9270
- /** Find & Replace results (all matches across all slides). */
9271
- findResults?: Array<{
9272
- slideIndex: number;
9273
- elementId: string;
9274
- segmentIndex: number;
9275
- startOffset: number;
9276
- length: number;
9277
- }>;
9278
- /** Index of the currently focused find result (-1 for none). */
9279
- findResultIndex?: number;
9280
- /** Index of the currently visible slide (needed to filter find results). */
9281
- activeSlideIndex?: number;
9282
- /** Currently active drawing tool ("select" means no drawing overlay). */
9283
- activeTool?: DrawingTool;
9284
- /** Stroke colour for pen / highlighter. */
9285
- drawingColor?: string;
9286
- /** Stroke width for pen / highlighter. */
9287
- drawingWidth?: number;
9288
- /** Ref that is true while a pointer stroke is in progress. */
9289
- isDrawingRef?: React$1.RefObject<boolean>;
9290
- /** Called when a completed ink stroke should be added to the slide. */
9291
- onAddInkElement?: (ink: InkPptxElement) => void;
9292
- /** Called when a freeform drawing stroke should be added as a shape element. */
9293
- onAddFreeformShape?: (shape: ShapePptxElement) => void;
9294
- /** Called when the eraser tool removes an ink element. */
9295
- onEraseInkElement?: (elementId: string) => void;
9296
- /** Called when a shape-level action is clicked (e.g. slide jump, URL). */
9297
- onActionClick?: (elementId: string, action: PptxAction) => void;
9298
- /** Called when a text-level hyperlink is clicked. */
9299
- onHyperlinkClick?: (url: string) => void;
9300
- /** Comments for the current slide (used for on-canvas markers). */
9301
- comments?: PptxComment[];
9302
- /** Whether to show comment markers on the slide canvas. */
9303
- showCommentMarkers?: boolean;
9304
- /** Called when a comment marker is clicked. */
9305
- onCommentMarkerClick?: (commentId: string) => void;
9306
- onMoveGuide?: (guideId: string, position: number) => void;
9307
- onDeleteGuide?: (guideId: string) => void;
9308
- onCreateGuideFromRuler?: (axis: 'h' | 'v', positionPx: number) => void;
9309
- /** When true, shows connection sites on shapes and enables connector drawing. */
9310
- connectorCreationMode?: boolean;
9311
- /** Called when a new connector is created between two shapes. */
9312
- onCreateConnector?: (connector: ConnectorPptxElement) => void;
9313
- /** All slides in the presentation (for zoom element thumbnails). */
9314
- allSlides?: readonly PptxSlide[];
9315
- /** Callback fired when a zoom element is clicked in presentation mode. */
9316
- onZoomClick?: (targetSlideIndex: number, returnSlideIndex: number) => void;
9317
- /** Index of the current slide (for zoom return navigation). */
9318
- sourceSlideIndex?: number;
9319
- /** Context for text field placeholder substitution (slide number, header/footer, etc.). */
9320
- fieldContext?: FieldSubstitutionContext;
9321
- /** Theme + table style map for resolving table band/header colours. */
9322
- tableStyleContext?: TableStyleContext;
9323
- /** Optional collaboration cursor overlay rendered on top of the canvas. */
9324
- collaborationOverlay?: React$1.ReactNode;
9325
- }
9326
- //#endregion
9327
- //#region src/viewer/components/toolbar/toolbar-types.d.ts
9328
- interface ToolbarProps {
9329
- fileName?: string;
9330
- mode: ViewerMode;
9331
- canEdit: boolean;
9332
- isNarrowViewport: boolean;
9333
- isSidebarCollapsed: boolean;
9334
- isInspectorPaneOpen: boolean;
9335
- isCompactToolbarOpen: boolean;
9336
- toolbarSection: ToolbarSection;
9337
- scale: number;
9338
- canUndo: boolean;
9339
- canRedo: boolean;
9340
- undoLabel: string | undefined;
9341
- redoLabel: string | undefined;
9342
- findReplaceOpen: boolean;
9343
- selectedElement: PptxElement | null;
9344
- tableEditorState?: TableCellEditorState | null;
9345
- editTemplateMode: boolean;
9346
- newShapeType: SupportedShapeType;
9347
- activeTool: DrawingTool;
9348
- drawingColor: string;
9349
- drawingWidth: number;
9350
- clipboardPayload: ElementClipboardPayload | null;
9351
- onSetMode: (mode: ViewerMode) => void;
9352
- onToggleSidebar: () => void;
9353
- onToggleInspector: () => void;
9354
- /** Opens the inspector pane and switches to the properties tab (for animation panel). */
9355
- onOpenAnimationPanel: () => void;
9356
- /** Adds an animation preset to the selected element. */
9357
- onAddAnimation?: (preset: string, group: 'entrance' | 'emphasis' | 'exit') => void;
9358
- /** Removes all animations from the selected element. */
9359
- onRemoveAnimation?: () => void;
9360
- onToggleCompactToolbar: () => void;
9361
- onSetToolbarSection: (section: ToolbarSection) => void;
9362
- onZoomIn: () => void;
9363
- onZoomOut: () => void;
9364
- onZoomToFit: () => void;
9365
- onUndo: () => void;
9366
- onRedo: () => void;
9367
- onToggleFindReplace: () => void;
9368
- onSetNewShapeType: (type: SupportedShapeType) => void;
9369
- onAddTextBox: () => void;
9370
- onAddShape: () => void;
9371
- onAddTable: () => void;
9372
- onAddChart?: (chartType: PptxChartType) => void;
9373
- onAddSmartArt: () => void;
9374
- onAddEquation: () => void;
9375
- onAddActionButton: (shapeType: string) => void;
9376
- onInsertField?: (fieldType: string, value?: string) => void;
9377
- onOpenHeaderFooter?: () => void;
9378
- onOpenImagePicker: () => void;
9379
- onOpenMediaPicker: () => void;
9380
- onSetActiveTool: (tool: DrawingTool) => void;
9381
- onSetDrawingColor: (color: string) => void;
9382
- onSetDrawingWidth: (width: number) => void;
9383
- onSetEditTemplateMode: (mode: boolean) => void;
9384
- spellCheckEnabled: boolean;
9385
- showGrid: boolean;
9386
- showRulers: boolean;
9387
- snapToGrid: boolean;
9388
- snapToShape: boolean;
9389
- onSetSpellCheckEnabled: (enabled: boolean) => void;
9390
- onSetShowGrid: (enabled: boolean) => void;
9391
- onSetShowRulers: (enabled: boolean) => void;
9392
- onSetSnapToGrid: (enabled: boolean) => void;
9393
- onSetSnapToShape: (enabled: boolean) => void;
9394
- onAddGuide: (axis: 'h' | 'v') => void;
9395
- onAlignElements: (align: string) => void;
9396
- onDistributeElements: (axis: string) => void;
9397
- canDistribute: boolean;
9398
- onCopy: () => void;
9399
- onCut: () => void;
9400
- onPaste: () => void;
9401
- onFlip: (direction: 'horizontal' | 'vertical') => void;
9402
- onMoveLayer: (direction: string) => void;
9403
- onMoveLayerToEdge: (direction: string) => void;
9404
- onDuplicate: () => void;
9405
- onDelete: () => void;
9406
- /** Open another presentation (File ▸ Open). Hidden when not provided. */
9407
- onOpenFile?: () => void;
9408
- onOpenRecentFile?: (key: string) => void;
9409
- onCreatePresentation: (templateId: string) => void;
9410
- onExportPng: () => void;
9411
- onExportPdf: () => void;
9412
- onExportVideo: () => void;
9413
- onExportGif: () => void;
9414
- onPackageForSharing: () => void;
9415
- onOpenShareDialog?: () => void;
9416
- onSaveAsPptx: () => void;
9417
- onSaveAsPpsx: () => void;
9418
- onSaveAsPptm: () => void;
9419
- hasMacros: boolean;
9420
- onCopySlideAsImage: () => void;
9421
- onPrint: () => void;
9422
- onToggleShortcuts: () => void;
9423
- onOpenSettings?: () => void;
9424
- onRunAccessibilityCheck: () => void;
9425
- onToggleSlideSorter: () => void;
9426
- onUpdateTextStyle: (updates: Partial<TextStyle>) => void;
9427
- /** Rewrite the selected text's characters (PowerPoint's Aa "Change Case" dropdown). */
9428
- onTransformTextCase: (mode: ChangeCaseMode) => void;
9429
- isOverflowMenuOpen: boolean;
9430
- onSetOverflowMenuOpen: (open: boolean) => void;
9431
- layoutOptions: Array<{
9432
- path: string;
9433
- name: string;
9434
- }>;
9435
- onInsertSlideFromLayout: (path: string, name?: string) => void;
9436
- customShows: PptxCustomShow[];
9437
- activeCustomShowId: string | null;
9438
- onSetActiveCustomShowId: (id: string | null) => void;
9439
- onCreateCustomShow: () => void;
9440
- onRenameActiveCustomShow: () => void;
9441
- onDeleteActiveCustomShow: () => void;
9442
- onToggleCurrentSlideInActiveShow: () => void;
9443
- isCurrentSlideInActiveShow: boolean;
9444
- onToggleVersionHistory?: () => void;
9445
- onOpenPasswordProtection?: () => void;
9446
- onOpenDocumentProperties?: () => void;
9447
- onOpenFontEmbedding?: () => void;
9448
- onOpenDigitalSignatures?: () => void;
9449
- onEnterMasterView: () => void;
9450
- onCloseMasterView: () => void;
9451
- onEnterPresenterView?: () => void;
9452
- onEnterRehearsalMode?: () => void;
9453
- onToggleThemeEditor: () => void;
9454
- isThemeEditorOpen: boolean;
9455
- onToggleThemeGallery: () => void;
9456
- isThemeGalleryOpen: boolean;
9457
- onCompare?: () => void;
9458
- onToggleComments?: () => void;
9459
- isCommentsPanelOpen?: boolean;
9460
- spellCheckActive?: boolean;
9461
- slideCommentCount?: number;
9462
- formatPainterActive?: boolean;
9463
- onToggleFormatPainter?: () => void;
9464
- canActivateFormatPainter?: boolean;
9465
- isSelectionPaneOpen?: boolean;
9466
- onToggleSelectionPane?: () => void;
9467
- eyedropperActive?: boolean;
9468
- onToggleEyedropper?: () => void;
9469
- onOpenSetUpSlideShow?: () => void;
9470
- onOpenBroadcastDialog?: () => void;
9471
- onToggleSubtitles?: () => void;
9472
- showSubtitles?: boolean;
9473
- activeSlide?: PptxSlide;
9474
- onTransitionChange: (updates: Partial<PptxSlideTransition>) => void;
9475
- onApplyTransitionToAll: () => void;
9476
- /** Host-supplied list of toolbar buttons/ribbon tabs to hide. See `PowerPointViewerProps.hiddenActions`. */
9477
- hiddenActions?: readonly ToolbarActionId[];
9806
+ /** The Yjs document (from useYjsProvider). null when not collaborating. */
9807
+ doc: Doc | null;
9808
+ /** Current slides state. */
9809
+ slides: PptxSlide[];
9810
+ /** Separated master/layout (template) elements, merged back on write-back. */
9811
+ templateElementsBySlideId: Record<string, PptxElement[]>;
9812
+ /** React state setter for slides. */
9813
+ setSlides: React.Dispatch<React.SetStateAction<PptxSlide[]>>;
9814
+ /** Whether collaboration is active (status === 'connected'). */
9815
+ isConnected: boolean;
9816
+ /**
9817
+ * Whether the provider completed its initial document sync. Local -> doc
9818
+ * writes are gated on this so a late joiner never seeds its bootstrap deck
9819
+ * into a room whose real content has not arrived yet. Defaults to true for
9820
+ * callers that manage sync readiness themselves.
9821
+ */
9822
+ isSynced?: boolean;
9823
+ /** Collaboration config (for role and write-back). */
9824
+ config?: Pick<CollaborationConfig, 'role' | 'onWriteBack' | 'writeBackDebounceMs'>;
9825
+ /**
9826
+ * Return the source PPTX bytes for write-back serialization. Only called
9827
+ * when role === 'owner' and onWriteBack is set.
9828
+ */
9829
+ getSourceBytes?: () => Uint8Array | null;
9830
+ /**
9831
+ * Monotonic counter bumped each time the content-load pipeline finishes
9832
+ * applying a parsed deck to viewer state. A local load that lands while the
9833
+ * shared doc already holds slides (a late joiner's bootstrap deck parsing
9834
+ * after the room state arrived) would silently clobber the synced slides;
9835
+ * each bump re-adopts the doc's slides when the room has content.
9836
+ */
9837
+ loadVersion?: number;
9478
9838
  }
9839
+ declare function useYjsDocumentSync({ doc, slides, templateElementsBySlideId, setSlides, isConnected, isSynced, config, getSourceBytes, loadVersion }: UseYjsDocumentSyncInput): void;
9479
9840
  //#endregion
9480
- //#region src/viewer/hooks/useViewerBuildingBlocks.d.ts
9481
- interface UseViewerBuildingBlocksInput {
9482
- /** PPTX content as ArrayBuffer/Uint8Array, or null/undefined while no file is loaded. */
9483
- content: ArrayBuffer | Uint8Array | null | undefined;
9484
- /** Whether editing actions are enabled. Defaults to false (view-only). */
9485
- canEdit?: boolean;
9486
- /** Original file path, used for autosave recovery. */
9487
- filePath?: string;
9488
- /** Display name for the toolbar's file-name-aware controls (e.g. title bar hosts build themselves). */
9489
- fileName?: string;
9490
- /** Whether the built-in autosave-to-localStorage recovery timer is active. Defaults to true. */
9491
- autosaveEnabled?: boolean;
9492
- /** Display name used as the author for comments. */
9493
- userName?: string;
9494
- /** Host-supplied list of toolbar buttons/ribbon tabs to hide. */
9495
- hiddenActions?: readonly ToolbarActionId[];
9496
- /** Imperative handle ref, exposing the same `PowerPointViewerHandle` API `PowerPointViewer` does. */
9497
- handle?: React.ForwardedRef<PowerPointViewerHandle>;
9498
- onContentChange?: (content: Uint8Array) => void;
9499
- onDirtyChange?: (dirty: boolean) => void;
9500
- onActiveSlideChange?: (index: number) => void;
9501
- onModeChange?: (mode: ViewerMode) => void;
9502
- onZoomChange?: (zoom: number) => void;
9503
- onSelectionChange?: (ids: string[]) => void;
9504
- onSlideCountChange?: (count: number) => void;
9505
- /** Fired by the toolbar's "Settings" button; the host owns rendering that dialog. */
9506
- onOpenSettings?: () => void;
9507
- /** Fired by the toolbar's "Header & Footer" button; the host owns rendering that panel. */
9508
- onOpenHeaderFooter?: () => void;
9509
- /** Fired by the toolbar's "Share" button; the host owns rendering that dialog. */
9510
- onOpenShareDialog?: () => void;
9841
+ //#region src/viewer/hooks/collaboration/useBroadcastFollower.d.ts
9842
+ interface UseBroadcastFollowerInput {
9843
+ /** The collaboration context (null when collaboration is disabled). */
9844
+ collab: CollaborationContextValue | null;
9845
+ /** Current local active slide index. */
9846
+ activeSlideIndex: number;
9847
+ /** Setter for the active slide index. */
9848
+ setActiveSlideIndex: (index: number) => void;
9849
+ /** Total number of slides (for bounds checking). */
9850
+ slideCount: number;
9851
+ /**
9852
+ * When true, auto-follow stands down (e.g. the local user is manually
9853
+ * following a specific peer via the follow bar). Defaults to false.
9854
+ */
9855
+ paused?: boolean;
9511
9856
  }
9512
- interface ViewerBuildingBlocksResult {
9513
- /** Flat, self-contained props for the standalone `<Toolbar>` component. */
9514
- toolbarProps: ToolbarProps;
9515
- /** Flat, self-contained props for the standalone `<SlideCanvas>` component. */
9516
- canvasProps: SlideCanvasProps;
9517
- /** Current viewer mode (edit, view, present, master). */
9857
+ declare function useBroadcastFollower({ collab, activeSlideIndex, setActiveSlideIndex, slideCount, paused }: UseBroadcastFollowerInput): void;
9858
+ //#endregion
9859
+ //#region src/viewer/hooks/collaboration/useFollowMode.d.ts
9860
+ interface UseFollowModeInput {
9861
+ /** The collaboration context (null when collaboration is disabled). */
9862
+ collab: CollaborationContextValue | null;
9863
+ /** Current local active slide index. */
9864
+ activeSlideIndex: number;
9865
+ /** Setter for the active slide index. */
9866
+ setActiveSlideIndex: (index: number) => void;
9867
+ /** Total number of slides (for bounds checking). */
9868
+ slideCount: number;
9869
+ }
9870
+ interface UseFollowModeResult {
9871
+ /** The clientId currently being followed, or null. */
9872
+ followedClientId: number | null;
9873
+ /** Follow the given peer, or `null` to stop following. */
9874
+ followUser: (clientId: number | null) => void;
9875
+ }
9876
+ declare function useFollowMode({ collab, activeSlideIndex, setActiveSlideIndex, slideCount }: UseFollowModeInput): UseFollowModeResult;
9877
+ //#endregion
9878
+ //#region src/viewer/hooks/presentation-mode/useAnimationPlayback.d.ts
9879
+ interface UseAnimationPlaybackInput {
9880
+ slides: PptxSlide[];
9881
+ onPlayActionSound?: (soundPath: string) => void;
9882
+ /** When false, all animations are skipped (elements shown immediately). */
9883
+ showWithAnimation?: boolean;
9884
+ }
9885
+ interface UseAnimationPlaybackResult {
9886
+ presentationAnimations: PresentationAnimationRuntime[];
9887
+ presentationElementStates: Map<string, ElementAnimationState>;
9888
+ presentationKeyframesCss: string;
9889
+ interactiveTriggerShapeIds: ReadonlySet<string>;
9890
+ hoverTriggerShapeIds: ReadonlySet<string>;
9891
+ clearPresentationTimers: () => void;
9892
+ playNextAnimationGroup: () => boolean;
9893
+ handleInteractiveShapeClick: (shapeId: string) => boolean;
9894
+ handleHoverStart: (shapeId: string) => boolean;
9895
+ handleHoverEnd: (shapeId: string) => void;
9896
+ runPresentationEntranceAnimations: (slideIndex: number) => void;
9897
+ /** Exposed so the orchestrator can schedule additional timers (e.g. auto-advance). */
9898
+ presentationTimersRef: React.RefObject<number[]>;
9899
+ }
9900
+ declare function useAnimationPlayback(input: UseAnimationPlaybackInput): UseAnimationPlaybackResult;
9901
+ //#endregion
9902
+ //#region src/viewer/hooks/presentation-mode/useRehearsalTimings.d.ts
9903
+ interface UseRehearsalTimingsInput {
9904
+ containerRef: React.RefObject<HTMLElement | null>;
9905
+ onSetMode: (mode: ViewerMode) => void;
9906
+ onSaveRehearsalTimings?: (timings: Record<number, number>) => void;
9907
+ setPresentationStartTime: (time: number | null) => void;
9908
+ setPresenterMode: (mode: boolean) => void;
9909
+ }
9910
+ interface UseRehearsalTimingsResult {
9911
+ rehearsing: boolean;
9912
+ setRehearsing: React.Dispatch<React.SetStateAction<boolean>>;
9913
+ recordedTimings: Record<number, number>;
9914
+ slideStartTime: number | null;
9915
+ showRehearsalSummary: boolean;
9916
+ setShowRehearsalSummary: React.Dispatch<React.SetStateAction<boolean>>;
9917
+ rehearsalPaused: boolean;
9918
+ recordCurrentSlideTime: (slideIndex: number) => void;
9919
+ dismissRehearsalSummary: () => void;
9920
+ saveRehearsalTimings: () => void;
9921
+ enterRehearsalMode: () => void;
9922
+ toggleRehearsalPause: () => void;
9923
+ }
9924
+ declare function useRehearsalTimings(input: UseRehearsalTimingsInput): UseRehearsalTimingsResult;
9925
+ //#endregion
9926
+ //#region src/viewer/hooks/presentation-mode/usePresentationKeyboard.d.ts
9927
+ interface UsePresentationKeyboardInput {
9518
9928
  mode: ViewerMode;
9519
- /** True while the initial parse of `content` is in progress. */
9520
- loading: boolean;
9521
- /** Parse error message, or null. */
9522
- error: string | null;
9523
- /** Current autosave-to-localStorage recovery status. */
9524
- autosaveStatus: AutosaveStatus;
9929
+ movePresentationSlide: (direction: 1 | -1) => void;
9930
+ onSetMode: (mode: ViewerMode) => void;
9931
+ onToggleLaser?: () => void;
9932
+ onTogglePen?: () => void;
9933
+ onToggleEraser?: () => void;
9934
+ onToggleToolbar?: () => void;
9935
+ /** Toggle between presenter view (split-screen with notes) and fullscreen. */
9936
+ onTogglePresenterView?: () => void;
9937
+ onToggleBlackScreen?: () => void;
9938
+ onToggleWhiteScreen?: () => void;
9939
+ rehearsing: boolean;
9940
+ recordCurrentSlideTime: (slideIndex: number) => void;
9941
+ presentationSlideIndex: number;
9942
+ setShowRehearsalSummary: (value: boolean) => void;
9525
9943
  }
9526
- declare function useViewerBuildingBlocks(input: UseViewerBuildingBlocksInput): ViewerBuildingBlocksResult;
9944
+ /**
9945
+ * Registers keyboard shortcuts for presentation mode: arrow/space
9946
+ * for slide navigation, Escape to exit, and annotation tool toggles.
9947
+ */
9948
+ declare function usePresentationKeyboard(input: UsePresentationKeyboardInput): void;
9949
+ //#endregion
9950
+ //#region src/viewer/hooks/presentation-mode/useSlideNavigation.d.ts
9951
+ interface UseSlideNavigationInput {
9952
+ slides: PptxSlide[];
9953
+ visibleSlideIndexes: number[];
9954
+ presentationSlideIndex: number;
9955
+ setPresentationSlideIndex: (index: number) => void;
9956
+ setPresentationSlideVisible: (visible: boolean) => void;
9957
+ setTransitionOverlay: (state: PresentationTransitionOverlayState | null) => void;
9958
+ onSetMode: (mode: ViewerMode) => void;
9959
+ onSetActiveSlideIndex: (index: number) => void;
9960
+ onPlayActionSound?: (soundPath: string) => void;
9961
+ loopContinuously?: boolean;
9962
+ /** Whether to use rehearsed auto-advance timings. When false, slides advance only on click. */
9963
+ useTimings?: boolean;
9964
+ /**
9965
+ * Fired when the user advances past the last slide (no loop, no rehearsal).
9966
+ * The presentation-mode hook uses it for PowerPoint's "End with black
9967
+ * slide" behavior. When absent, advancing past the end clamps as before.
9968
+ */
9969
+ onAdvancePastLastSlide?: () => void;
9970
+ playNextAnimationGroup: () => boolean;
9971
+ clearPresentationTimers: () => void;
9972
+ runPresentationEntranceAnimations: (slideIndex: number) => void;
9973
+ presentationTimersRef: {
9974
+ current: number[];
9975
+ };
9976
+ rehearsing: boolean;
9977
+ recordCurrentSlideTime: (slideIndex: number) => void;
9978
+ setShowRehearsalSummary: (value: boolean) => void;
9979
+ }
9980
+ interface UseSlideNavigationResult {
9981
+ movePresentationSlide: (direction: 1 | -1, trigger?: SlideAdvanceTrigger) => void;
9982
+ navigateToSlide: (slideIndex: number) => void;
9983
+ handlePresentationAction: (action: PptxAction) => void;
9984
+ scheduleAutoAdvanceForSlide: (slideIndex: number) => void;
9985
+ }
9986
+ declare function useSlideNavigation(input: UseSlideNavigationInput): UseSlideNavigationResult;
9987
+ interface UsePresenterWindowInput {
9988
+ currentSlideIndex: number;
9989
+ isPresenterMode: boolean;
9990
+ /** Raw PPTX bytes to share with the audience tab via IndexedDB. */
9991
+ content?: ArrayBuffer | Uint8Array | null;
9992
+ snapshot: PresentationSnapshot;
9993
+ }
9994
+ interface UsePresenterWindowResult {
9995
+ openAudienceWindow: () => boolean;
9996
+ closeAudienceWindow: () => void;
9997
+ isAudienceWindowOpen: () => boolean;
9998
+ syncSlideToAudience: (slideIndex: number) => void;
9999
+ syncStateToAudience: (snapshot: PresentationSnapshot) => void;
10000
+ swapDisplays: () => Promise<boolean>;
10001
+ }
10002
+ declare function usePresenterWindow(input: UsePresenterWindowInput): UsePresenterWindowResult;
10003
+ //#endregion
10004
+ //#region src/viewer/hooks/presentation-mode/useAudienceMode.d.ts
10005
+ interface UseAudienceModeInput {
10006
+ mode: ViewerMode;
10007
+ onSetMode: (mode: ViewerMode) => void;
10008
+ onSetActiveSlideIndex: (index: number) => void;
10009
+ containerRef: React.RefObject<HTMLElement | null>;
10010
+ onSnapshot?: (snapshot: PresentationSnapshot) => void;
10011
+ }
10012
+ /**
10013
+ * When the page was opened with the `#pptx-audience` hash, this hook:
10014
+ * 1. Auto-enters fullscreen presentation mode after content loads
10015
+ * 2. Listens on BroadcastChannel for slide-change messages from the presenter
10016
+ * 3. Exits presentation mode when the presenter sends an exit signal
10017
+ */
10018
+ declare function useAudienceMode(input: UseAudienceModeInput): void;
9527
10019
 
9528
10020
  //#region src/viewer/hooks/useEditorHistory.d.ts
9529
10021
  interface EditorHistoryInput {
@@ -10590,6 +11082,15 @@ interface UseThemeHandlersInput {
10590
11082
  setSlideMasters: React.Dispatch<React.SetStateAction<Array<Record<string, unknown>>>>;
10591
11083
  slideMasters: Array<Record<string, unknown>>;
10592
11084
  history: EditorHistoryResult;
11085
+ /** Current live slides, re-coloured in place on a scheme-colour change. */
11086
+ setSlides: React.Dispatch<React.SetStateAction<PptxSlide[]>>;
11087
+ /** Current theme, used to derive the previous colour map for re-resolution. */
11088
+ theme: PptxTheme | undefined;
11089
+ /**
11090
+ * Force the history stack to capture the next slides change so an in-place
11091
+ * theme re-colour lands as a single undoable entry (mirrors the AI path).
11092
+ */
11093
+ bumpHistory: () => void;
10593
11094
  }
10594
11095
  interface ThemeHandlersResult {
10595
11096
  handleApplyTheme: (themePath: string, applyToAllMasters: boolean) => Promise<void>;
@@ -11104,6 +11605,8 @@ interface ViewerIntegrationResult {
11104
11605
  autosaveStatus: AutosaveStatus;
11105
11606
  isEncryptedDialogOpen: boolean;
11106
11607
  setIsEncryptedDialogOpen: Dispatch<SetStateAction<boolean>>;
11608
+ /** The loaded core handler, exposed for the AI bridge (`getHandler`). */
11609
+ handlerRef: RefObject<PptxHandler | null>;
11107
11610
  /**
11108
11611
  * Bumped each time the load pipeline finishes applying parsed content to
11109
11612
  * viewer state. Collaboration watches it to re-adopt the shared doc's