pptx-react-viewer 3.2.0 → 3.4.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 (166) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/dist/{AiChatPanel-TKBVSYD2.js → AiChatPanel-3Q4STA5E.js} +29 -28
  3. package/dist/AiChatPanel-3Q4STA5E.js.br +0 -0
  4. package/dist/AiChatPanel-3Q4STA5E.js.gz +0 -0
  5. package/dist/{AiChatPanel-C3E7NLX3.mjs → AiChatPanel-NQZBZIRM.mjs} +9 -8
  6. package/dist/AiChatPanel-NQZBZIRM.mjs.br +0 -0
  7. package/dist/AiChatPanel-NQZBZIRM.mjs.gz +0 -0
  8. package/dist/{Area3DChartScene-7YCFWEGX.mjs → Area3DChartScene-7PARQDOZ.mjs} +1 -1
  9. package/dist/Area3DChartScene-7PARQDOZ.mjs.br +3 -0
  10. package/dist/Area3DChartScene-7PARQDOZ.mjs.gz +0 -0
  11. package/dist/{Area3DChartScene-3A3CXKN3.js → Area3DChartScene-THLG74CM.js} +2 -2
  12. package/dist/Area3DChartScene-THLG74CM.js.br +0 -0
  13. package/dist/Area3DChartScene-THLG74CM.js.gz +0 -0
  14. package/dist/{Bar3DChartScene-BDUENAWJ.js → Bar3DChartScene-OLZ2V56I.js} +2 -2
  15. package/dist/Bar3DChartScene-OLZ2V56I.js.br +2 -0
  16. package/dist/Bar3DChartScene-OLZ2V56I.js.gz +0 -0
  17. package/dist/{Bar3DChartScene-7CNSJ35X.mjs → Bar3DChartScene-QUU6RUXM.mjs} +1 -1
  18. package/dist/Bar3DChartScene-QUU6RUXM.mjs.br +0 -0
  19. package/dist/Bar3DChartScene-QUU6RUXM.mjs.gz +0 -0
  20. package/dist/{Line3DChartScene-R352CZ5U.js → Line3DChartScene-2VZS52IB.js} +2 -2
  21. package/dist/Line3DChartScene-2VZS52IB.js.br +0 -0
  22. package/dist/Line3DChartScene-2VZS52IB.js.gz +0 -0
  23. package/dist/{Line3DChartScene-SMTHK6MD.mjs → Line3DChartScene-D77ORA4K.mjs} +1 -1
  24. package/dist/Line3DChartScene-D77ORA4K.mjs.br +3 -0
  25. package/dist/Line3DChartScene-D77ORA4K.mjs.gz +0 -0
  26. package/dist/{Model3DScene-Y4SGFQYW.js → Model3DScene-3WCALTXO.js} +2 -2
  27. package/dist/Model3DScene-3WCALTXO.js.br +0 -0
  28. package/dist/Model3DScene-3WCALTXO.js.gz +0 -0
  29. package/dist/{Model3DScene-AUVJXXPV.mjs → Model3DScene-ZEGWNILH.mjs} +1 -1
  30. package/dist/Model3DScene-ZEGWNILH.mjs.br +0 -0
  31. package/dist/Model3DScene-ZEGWNILH.mjs.gz +0 -0
  32. package/dist/{PieChart3DScene-TK2VT4RS.js → PieChart3DScene-7C3ACGKN.js} +2 -2
  33. package/dist/PieChart3DScene-7C3ACGKN.js.br +0 -0
  34. package/dist/PieChart3DScene-7C3ACGKN.js.gz +0 -0
  35. package/dist/{PieChart3DScene-UD7GRH55.mjs → PieChart3DScene-DGD4PZVV.mjs} +1 -1
  36. package/dist/PieChart3DScene-DGD4PZVV.mjs.br +0 -0
  37. package/dist/PieChart3DScene-DGD4PZVV.mjs.gz +0 -0
  38. package/dist/PowerPointViewer-Cl6jBPNw.d.ts.map +1 -1
  39. package/dist/{SurfaceChart3DScene-TXY6UZSW.mjs → SurfaceChart3DScene-QGH3OLJV.mjs} +1 -1
  40. package/dist/SurfaceChart3DScene-QGH3OLJV.mjs.br +0 -0
  41. package/dist/SurfaceChart3DScene-QGH3OLJV.mjs.gz +0 -0
  42. package/dist/{SurfaceChart3DScene-ERFXZW2O.js → SurfaceChart3DScene-SJPQGGGE.js} +2 -2
  43. package/dist/SurfaceChart3DScene-SJPQGGGE.js.br +0 -0
  44. package/dist/SurfaceChart3DScene-SJPQGGGE.js.gz +0 -0
  45. package/dist/{chunk-RRAL4Y7V.js → chunk-7E6SM42A.js} +2604 -2024
  46. package/dist/chunk-7E6SM42A.js.br +0 -0
  47. package/dist/chunk-7E6SM42A.js.gz +0 -0
  48. package/dist/{chunk-G7UBIKAG.mjs → chunk-B7WAGQW4.mjs} +5383 -873
  49. package/dist/chunk-B7WAGQW4.mjs.br +0 -0
  50. package/dist/chunk-B7WAGQW4.mjs.gz +0 -0
  51. package/dist/{chunk-RX6FE24O.mjs → chunk-C4WTQIC6.mjs} +302 -61
  52. package/dist/chunk-C4WTQIC6.mjs.br +0 -0
  53. package/dist/chunk-C4WTQIC6.mjs.gz +0 -0
  54. package/dist/{chunk-Q52HT4EZ.js → chunk-KY6JQJXK.js} +307 -63
  55. package/dist/chunk-KY6JQJXK.js.br +0 -0
  56. package/dist/chunk-KY6JQJXK.js.gz +0 -0
  57. package/dist/{chunk-PPNXPEEZ.mjs → chunk-L5MRKDRM.mjs} +1514 -934
  58. package/dist/chunk-L5MRKDRM.mjs.br +0 -0
  59. package/dist/chunk-L5MRKDRM.mjs.gz +0 -0
  60. package/dist/{chunk-UHR7EYFM.mjs → chunk-MSUUPLQ7.mjs} +718 -435
  61. package/dist/chunk-MSUUPLQ7.mjs.br +0 -0
  62. package/dist/chunk-MSUUPLQ7.mjs.gz +0 -0
  63. package/dist/{chunk-FJDZ7AEE.js → chunk-PCW2KT7Z.js} +5446 -879
  64. package/dist/chunk-PCW2KT7Z.js.br +0 -0
  65. package/dist/chunk-PCW2KT7Z.js.gz +0 -0
  66. package/dist/{chunk-FMEEIS6L.mjs → chunk-SFMATKNJ.mjs} +13 -114
  67. package/dist/chunk-SFMATKNJ.mjs.br +0 -0
  68. package/dist/chunk-SFMATKNJ.mjs.gz +0 -0
  69. package/dist/{chunk-ARQGUUYU.js → chunk-TJNG5VEK.js} +1114 -826
  70. package/dist/chunk-TJNG5VEK.js.br +0 -0
  71. package/dist/chunk-TJNG5VEK.js.gz +0 -0
  72. package/dist/{chunk-ALO4ZOHQ.js → chunk-UNIJUD5C.js} +45 -1
  73. package/dist/chunk-UNIJUD5C.js.br +0 -0
  74. package/dist/chunk-UNIJUD5C.js.gz +0 -0
  75. package/dist/{chunk-B6UIVRFA.js → chunk-XBTHWXNO.js} +177 -279
  76. package/dist/chunk-XBTHWXNO.js.br +0 -0
  77. package/dist/chunk-XBTHWXNO.js.gz +0 -0
  78. package/dist/{chunk-RHSA5BW5.mjs → chunk-XWUMM2TX.mjs} +45 -1
  79. package/dist/chunk-XWUMM2TX.mjs.br +0 -0
  80. package/dist/chunk-XWUMM2TX.mjs.gz +0 -0
  81. package/dist/i18n.js +4 -4
  82. package/dist/i18n.js.br +0 -0
  83. package/dist/i18n.js.gz +0 -0
  84. package/dist/i18n.mjs +1 -1
  85. package/dist/i18n.mjs.br +0 -0
  86. package/dist/i18n.mjs.gz +0 -0
  87. package/dist/index.d.ts +7 -0
  88. package/dist/index.js +47 -47
  89. package/dist/index.js.br +0 -0
  90. package/dist/index.js.gz +0 -0
  91. package/dist/index.mjs +6 -6
  92. package/dist/index.mjs.br +0 -0
  93. package/dist/index.mjs.gz +0 -0
  94. package/dist/internals.d.ts +176 -5
  95. package/dist/internals.d.ts.map +1 -1
  96. package/dist/internals.js +79 -79
  97. package/dist/internals.js.br +0 -0
  98. package/dist/internals.js.gz +0 -0
  99. package/dist/internals.mjs +4 -4
  100. package/dist/internals.mjs.br +0 -0
  101. package/dist/internals.mjs.gz +0 -0
  102. package/dist/pptx-viewer.css +1 -1
  103. package/dist/pptx-viewer.css.br +0 -0
  104. package/dist/pptx-viewer.css.gz +0 -0
  105. package/dist/{useViewerBuildingBlocks-X1L8BjsQ.d.ts → useViewerBuildingBlocks-f6oNGKMX.d.ts} +8 -1
  106. package/dist/useViewerBuildingBlocks-f6oNGKMX.d.ts.map +1 -0
  107. package/dist/viewer/index.js +27 -27
  108. package/dist/viewer/index.js.br +0 -0
  109. package/dist/viewer/index.js.gz +0 -0
  110. package/dist/viewer/index.mjs +6 -6
  111. package/dist/viewer/index.mjs.br +0 -0
  112. package/dist/viewer/index.mjs.gz +0 -0
  113. package/package.json +1 -1
  114. package/dist/AiChatPanel-C3E7NLX3.mjs.br +0 -0
  115. package/dist/AiChatPanel-C3E7NLX3.mjs.gz +0 -0
  116. package/dist/AiChatPanel-TKBVSYD2.js.br +0 -0
  117. package/dist/AiChatPanel-TKBVSYD2.js.gz +0 -0
  118. package/dist/Area3DChartScene-3A3CXKN3.js.br +0 -0
  119. package/dist/Area3DChartScene-3A3CXKN3.js.gz +0 -0
  120. package/dist/Area3DChartScene-7YCFWEGX.mjs.br +0 -3
  121. package/dist/Area3DChartScene-7YCFWEGX.mjs.gz +0 -0
  122. package/dist/Bar3DChartScene-7CNSJ35X.mjs.br +0 -0
  123. package/dist/Bar3DChartScene-7CNSJ35X.mjs.gz +0 -0
  124. package/dist/Bar3DChartScene-BDUENAWJ.js.br +0 -0
  125. package/dist/Bar3DChartScene-BDUENAWJ.js.gz +0 -0
  126. package/dist/Line3DChartScene-R352CZ5U.js.br +0 -0
  127. package/dist/Line3DChartScene-R352CZ5U.js.gz +0 -0
  128. package/dist/Line3DChartScene-SMTHK6MD.mjs.br +0 -3
  129. package/dist/Line3DChartScene-SMTHK6MD.mjs.gz +0 -0
  130. package/dist/Model3DScene-AUVJXXPV.mjs.br +0 -0
  131. package/dist/Model3DScene-AUVJXXPV.mjs.gz +0 -0
  132. package/dist/Model3DScene-Y4SGFQYW.js.br +0 -0
  133. package/dist/Model3DScene-Y4SGFQYW.js.gz +0 -0
  134. package/dist/PieChart3DScene-TK2VT4RS.js.br +0 -0
  135. package/dist/PieChart3DScene-TK2VT4RS.js.gz +0 -0
  136. package/dist/PieChart3DScene-UD7GRH55.mjs.br +0 -0
  137. package/dist/PieChart3DScene-UD7GRH55.mjs.gz +0 -0
  138. package/dist/SurfaceChart3DScene-ERFXZW2O.js.br +0 -0
  139. package/dist/SurfaceChart3DScene-ERFXZW2O.js.gz +0 -0
  140. package/dist/SurfaceChart3DScene-TXY6UZSW.mjs.br +0 -0
  141. package/dist/SurfaceChart3DScene-TXY6UZSW.mjs.gz +0 -0
  142. package/dist/chunk-ALO4ZOHQ.js.br +0 -0
  143. package/dist/chunk-ALO4ZOHQ.js.gz +0 -0
  144. package/dist/chunk-ARQGUUYU.js.br +0 -0
  145. package/dist/chunk-ARQGUUYU.js.gz +0 -0
  146. package/dist/chunk-B6UIVRFA.js.br +0 -0
  147. package/dist/chunk-B6UIVRFA.js.gz +0 -0
  148. package/dist/chunk-FJDZ7AEE.js.br +0 -0
  149. package/dist/chunk-FJDZ7AEE.js.gz +0 -0
  150. package/dist/chunk-FMEEIS6L.mjs.br +0 -0
  151. package/dist/chunk-FMEEIS6L.mjs.gz +0 -0
  152. package/dist/chunk-G7UBIKAG.mjs.br +0 -0
  153. package/dist/chunk-G7UBIKAG.mjs.gz +0 -0
  154. package/dist/chunk-PPNXPEEZ.mjs.br +0 -0
  155. package/dist/chunk-PPNXPEEZ.mjs.gz +0 -0
  156. package/dist/chunk-Q52HT4EZ.js.br +0 -0
  157. package/dist/chunk-Q52HT4EZ.js.gz +0 -0
  158. package/dist/chunk-RHSA5BW5.mjs.br +0 -0
  159. package/dist/chunk-RHSA5BW5.mjs.gz +0 -0
  160. package/dist/chunk-RRAL4Y7V.js.br +0 -0
  161. package/dist/chunk-RRAL4Y7V.js.gz +0 -0
  162. package/dist/chunk-RX6FE24O.mjs.br +0 -0
  163. package/dist/chunk-RX6FE24O.mjs.gz +0 -0
  164. package/dist/chunk-UHR7EYFM.mjs.br +0 -0
  165. package/dist/chunk-UHR7EYFM.mjs.gz +0 -0
  166. package/dist/useViewerBuildingBlocks-X1L8BjsQ.d.ts.map +0 -1
@@ -1,15 +1,15 @@
1
1
  'use strict';
2
2
 
3
- var chunkB6UIVRFA_js = require('./chunk-B6UIVRFA.js');
4
- var chunkFJDZ7AEE_js = require('./chunk-FJDZ7AEE.js');
5
- var chunkALO4ZOHQ_js = require('./chunk-ALO4ZOHQ.js');
3
+ var chunkXBTHWXNO_js = require('./chunk-XBTHWXNO.js');
4
+ var chunkPCW2KT7Z_js = require('./chunk-PCW2KT7Z.js');
5
+ var chunkUNIJUD5C_js = require('./chunk-UNIJUD5C.js');
6
6
  var react = require('react');
7
7
  var reactI18next = require('react-i18next');
8
8
 
9
9
  function useVirtualizedSlides({
10
10
  totalItems,
11
11
  itemHeight,
12
- overscan = chunkFJDZ7AEE_js.DEFAULT_VIRTUAL_OVERSCAN
12
+ overscan = chunkPCW2KT7Z_js.DEFAULT_VIRTUAL_OVERSCAN
13
13
  }) {
14
14
  const scrollContainerRef = react.useRef(null);
15
15
  const [scrollTop, setScrollTop] = react.useState(0);
@@ -39,7 +39,7 @@ function useVirtualizedSlides({
39
39
  resizeObserver?.disconnect();
40
40
  };
41
41
  }, []);
42
- const range = chunkFJDZ7AEE_js.computeVirtualRange(totalItems, itemHeight, scrollTop, viewportHeight, overscan);
42
+ const range = chunkPCW2KT7Z_js.computeVirtualRange(totalItems, itemHeight, scrollTop, viewportHeight, overscan);
43
43
  const safeItemHeight = Math.max(itemHeight, 1);
44
44
  const scrollToIndex = react.useCallback(
45
45
  (index, behavior = "smooth") => {
@@ -80,7 +80,7 @@ function usePresenceTracking({
80
80
  }) {
81
81
  const [remoteUsers, setRemoteUsers] = react.useState([]);
82
82
  const projectorRef = react.useRef(null);
83
- projectorRef.current ??= chunkFJDZ7AEE_js.createPresenceProjector();
83
+ projectorRef.current ??= chunkPCW2KT7Z_js.createPresenceProjector();
84
84
  const projector = projectorRef.current;
85
85
  const lastBroadcastRef = react.useRef(0);
86
86
  const pendingBroadcastRef = react.useRef(null);
@@ -105,7 +105,7 @@ function usePresenceTracking({
105
105
  awareness.setLocalStateField("presence", state);
106
106
  lastBroadcastRef.current = Date.now();
107
107
  };
108
- if (elapsed >= chunkFJDZ7AEE_js.BROADCAST_THROTTLE_MS) {
108
+ if (elapsed >= chunkPCW2KT7Z_js.BROADCAST_THROTTLE_MS) {
109
109
  if (pendingBroadcastRef.current) {
110
110
  clearTimeout(pendingBroadcastRef.current);
111
111
  pendingBroadcastRef.current = null;
@@ -115,7 +115,7 @@ function usePresenceTracking({
115
115
  pendingBroadcastRef.current = setTimeout(() => {
116
116
  pendingBroadcastRef.current = null;
117
117
  flush();
118
- }, chunkFJDZ7AEE_js.BROADCAST_THROTTLE_MS - elapsed);
118
+ }, chunkPCW2KT7Z_js.BROADCAST_THROTTLE_MS - elapsed);
119
119
  }
120
120
  },
121
121
  [awareness, userName, userColor, userAvatar, role]
@@ -195,7 +195,7 @@ function useYjsProvider({ config }) {
195
195
  const departureRef = react.useRef(null);
196
196
  const gateRef = react.useRef(null);
197
197
  if (!gateRef.current) {
198
- gateRef.current = chunkFJDZ7AEE_js.createSyncGate(() => setSynced(true));
198
+ gateRef.current = chunkPCW2KT7Z_js.createSyncGate(() => setSynced(true));
199
199
  }
200
200
  const teardown = react.useCallback(() => {
201
201
  if (timeoutRef.current) {
@@ -215,7 +215,7 @@ function useYjsProvider({ config }) {
215
215
  const buildCleanup = react.useCallback(
216
216
  (provider, yDoc) => () => {
217
217
  announceDeparture();
218
- chunkFJDZ7AEE_js.clearLocalAwareness(provider.awareness);
218
+ chunkPCW2KT7Z_js.clearLocalAwareness(provider.awareness);
219
219
  provider.destroy();
220
220
  yDoc.destroy();
221
221
  setDoc(null);
@@ -240,9 +240,9 @@ function useYjsProvider({ config }) {
240
240
  if (config.authToken) {
241
241
  opts.password = config.authToken;
242
242
  }
243
- const roomId = chunkFJDZ7AEE_js.validateRoomId(config.roomId);
243
+ const roomId = chunkPCW2KT7Z_js.validateRoomId(config.roomId);
244
244
  const provider = new WebrtcProvider(roomId, yDoc, opts);
245
- departureRef.current = chunkFJDZ7AEE_js.createDepartureChannel(roomId, provider.awareness);
245
+ departureRef.current = chunkPCW2KT7Z_js.createDepartureChannel(roomId, provider.awareness);
246
246
  setDoc(yDoc);
247
247
  setAwareness(provider.awareness);
248
248
  setClientId(provider.awareness.clientID);
@@ -284,13 +284,13 @@ function useYjsProvider({ config }) {
284
284
  if (!config) {
285
285
  return;
286
286
  }
287
- const roomId = chunkFJDZ7AEE_js.validateRoomId(config.roomId);
288
- const transport = config.transport ?? chunkFJDZ7AEE_js.resolveTransportForServerUrl(config.serverUrl);
287
+ const roomId = chunkPCW2KT7Z_js.validateRoomId(config.roomId);
288
+ const transport = config.transport ?? chunkPCW2KT7Z_js.resolveTransportForServerUrl(config.serverUrl);
289
289
  if (transport === "webrtc") {
290
290
  await initWebrtc();
291
291
  return;
292
292
  }
293
- if (chunkFJDZ7AEE_js.isMixedContentBlocked(config.serverUrl)) {
293
+ if (chunkPCW2KT7Z_js.isMixedContentBlocked(config.serverUrl)) {
294
294
  console.warn(
295
295
  `[pptx-viewer] Refusing to connect: insecure ws:// server "${config.serverUrl}" is blocked from a secure (https) page. Use a wss:// URL.`
296
296
  );
@@ -304,7 +304,7 @@ function useYjsProvider({ config }) {
304
304
  const provider = new WebsocketProvider(config.serverUrl, roomId, yDoc, {
305
305
  params: config.authToken ? { token: config.authToken } : void 0
306
306
  });
307
- departureRef.current = chunkFJDZ7AEE_js.createDepartureChannel(roomId, provider.awareness);
307
+ departureRef.current = chunkPCW2KT7Z_js.createDepartureChannel(roomId, provider.awareness);
308
308
  let connected = false;
309
309
  const handleStatus = (event) => {
310
310
  if (event.status === "connected") {
@@ -344,7 +344,7 @@ function useYjsProvider({ config }) {
344
344
  provider.off("status", handleStatus);
345
345
  provider.off("sync", handleSynced);
346
346
  announceDeparture();
347
- chunkFJDZ7AEE_js.clearLocalAwareness(provider.awareness);
347
+ chunkPCW2KT7Z_js.clearLocalAwareness(provider.awareness);
348
348
  provider.destroy();
349
349
  yDoc.destroy();
350
350
  setDoc(null);
@@ -353,7 +353,7 @@ function useYjsProvider({ config }) {
353
353
  cleanupRef.current = null;
354
354
  setStatus("error");
355
355
  }
356
- }, chunkFJDZ7AEE_js.CONNECTION_TIMEOUT_MS);
356
+ }, chunkPCW2KT7Z_js.CONNECTION_TIMEOUT_MS);
357
357
  }
358
358
  setDoc(yDoc);
359
359
  setAwareness(provider.awareness);
@@ -362,7 +362,7 @@ function useYjsProvider({ config }) {
362
362
  provider.off("status", handleStatus);
363
363
  provider.off("sync", handleSynced);
364
364
  announceDeparture();
365
- chunkFJDZ7AEE_js.clearLocalAwareness(provider.awareness);
365
+ chunkPCW2KT7Z_js.clearLocalAwareness(provider.awareness);
366
366
  provider.destroy();
367
367
  yDoc.destroy();
368
368
  setDoc(null);
@@ -388,7 +388,7 @@ function useYjsProvider({ config }) {
388
388
  ]);
389
389
  react.useEffect(() => {
390
390
  init();
391
- const disposeTeardown = chunkFJDZ7AEE_js.registerCollaborationTeardown({
391
+ const disposeTeardown = chunkPCW2KT7Z_js.registerCollaborationTeardown({
392
392
  leave: teardown,
393
393
  rejoin: init
394
394
  });
@@ -409,7 +409,7 @@ function useCollaborativeState({
409
409
  canvasWidth,
410
410
  canvasHeight
411
411
  }) {
412
- const userColor = chunkFJDZ7AEE_js.sanitizeColor(config?.userColor, "#6366f1");
412
+ const userColor = chunkPCW2KT7Z_js.sanitizeColor(config?.userColor, "#6366f1");
413
413
  const { status, awareness, doc, clientId, synced, retry } = useYjsProvider({ config });
414
414
  const { remoteUsers, broadcastPresence } = usePresenceTracking({
415
415
  awareness,
@@ -527,8 +527,8 @@ function useEditorHistory(input) {
527
527
  width: canvasSize.width,
528
528
  height: canvasSize.height,
529
529
  activeSlideIndex,
530
- slides: slides.map(chunkFJDZ7AEE_js.cloneSlide),
531
- templateElementsBySlideId: chunkFJDZ7AEE_js.cloneTemplateElementsBySlideId(templateElementsBySlideId),
530
+ slides: slides.map(chunkPCW2KT7Z_js.cloneSlide),
531
+ templateElementsBySlideId: chunkPCW2KT7Z_js.cloneTemplateElementsBySlideId(templateElementsBySlideId),
532
532
  ...actionLabel ? { actionLabel } : {}
533
533
  };
534
534
  },
@@ -541,9 +541,9 @@ function useEditorHistory(input) {
541
541
  width: snapshot.width,
542
542
  height: snapshot.height
543
543
  });
544
- setSlides(snapshot.slides.map(chunkFJDZ7AEE_js.cloneSlide));
544
+ setSlides(snapshot.slides.map(chunkPCW2KT7Z_js.cloneSlide));
545
545
  setTemplateElementsBySlideId(
546
- chunkFJDZ7AEE_js.cloneTemplateElementsBySlideId(snapshot.templateElementsBySlideId)
546
+ chunkPCW2KT7Z_js.cloneTemplateElementsBySlideId(snapshot.templateElementsBySlideId)
547
547
  );
548
548
  setActiveSlideIndex(Math.min(snapshot.activeSlideIndex, maxSlideIndex));
549
549
  setSelectedElementIds([]);
@@ -582,8 +582,8 @@ function useEditorHistory(input) {
582
582
  const currentSnapshot = buildHistorySnapshot();
583
583
  historyFutureRef.current.push(currentSnapshot);
584
584
  isApplyingHistoryRef.current = true;
585
- const nextSnapshot = chunkB6UIVRFA_js.cloneHistorySnapshot(previousSnapshot);
586
- lastHistorySnapshotRef.current = chunkB6UIVRFA_js.cloneHistorySnapshot(nextSnapshot);
585
+ const nextSnapshot = chunkXBTHWXNO_js.cloneHistorySnapshot(previousSnapshot);
586
+ lastHistorySnapshotRef.current = chunkXBTHWXNO_js.cloneHistorySnapshot(nextSnapshot);
587
587
  lastHistorySerializedRef.current = serializeDocument(nextSnapshot);
588
588
  applyHistorySnapshot(nextSnapshot);
589
589
  updateHistoryAvailability();
@@ -604,8 +604,8 @@ function useEditorHistory(input) {
604
604
  const currentSnapshot = buildHistorySnapshot();
605
605
  historyPastRef.current.push(currentSnapshot);
606
606
  isApplyingHistoryRef.current = true;
607
- const targetSnapshot = chunkB6UIVRFA_js.cloneHistorySnapshot(nextSnapshot);
608
- lastHistorySnapshotRef.current = chunkB6UIVRFA_js.cloneHistorySnapshot(targetSnapshot);
607
+ const targetSnapshot = chunkXBTHWXNO_js.cloneHistorySnapshot(nextSnapshot);
608
+ lastHistorySnapshotRef.current = chunkXBTHWXNO_js.cloneHistorySnapshot(targetSnapshot);
609
609
  lastHistorySerializedRef.current = serializeDocument(targetSnapshot);
610
610
  applyHistorySnapshot(targetSnapshot);
611
611
  updateHistoryAvailability();
@@ -623,7 +623,7 @@ function useEditorHistory(input) {
623
623
  historyPastRef.current = [];
624
624
  historyFutureRef.current = [];
625
625
  if (initialSnapshot) {
626
- const clonedInitial = chunkB6UIVRFA_js.cloneHistorySnapshot(initialSnapshot);
626
+ const clonedInitial = chunkXBTHWXNO_js.cloneHistorySnapshot(initialSnapshot);
627
627
  lastHistorySnapshotRef.current = clonedInitial;
628
628
  lastHistorySerializedRef.current = serializeDocument(clonedInitial);
629
629
  } else {
@@ -671,19 +671,19 @@ function useEditorHistory(input) {
671
671
  }
672
672
  const previousSnapshot = lastHistorySnapshotRef.current;
673
673
  if (!previousSnapshot) {
674
- lastHistorySnapshotRef.current = chunkB6UIVRFA_js.cloneHistorySnapshot(snapshot);
674
+ lastHistorySnapshotRef.current = chunkXBTHWXNO_js.cloneHistorySnapshot(snapshot);
675
675
  lastHistorySerializedRef.current = serialized;
676
676
  lastCheapHashRef.current = cheapHash;
677
677
  updateHistoryAvailability();
678
678
  return;
679
679
  }
680
680
  onDirtyRef.current?.();
681
- historyPastRef.current.push(chunkB6UIVRFA_js.cloneHistorySnapshot(previousSnapshot));
681
+ historyPastRef.current.push(chunkXBTHWXNO_js.cloneHistorySnapshot(previousSnapshot));
682
682
  while (historyPastRef.current.length > Math.max(1, maxHistoryEntries)) {
683
683
  historyPastRef.current.shift();
684
684
  }
685
685
  historyFutureRef.current = [];
686
- lastHistorySnapshotRef.current = chunkB6UIVRFA_js.cloneHistorySnapshot(snapshot);
686
+ lastHistorySnapshotRef.current = chunkXBTHWXNO_js.cloneHistorySnapshot(snapshot);
687
687
  lastHistorySerializedRef.current = serialized;
688
688
  lastCheapHashRef.current = cheapHash;
689
689
  updateHistoryAvailability();
@@ -743,9 +743,9 @@ function useZoomViewport({
743
743
  const canvasStageRef = react.useRef(null);
744
744
  const canvasViewportRef = react.useRef(null);
745
745
  const renderScaleRef = react.useRef(1);
746
- const wheelBufferRef = react.useRef(chunkFJDZ7AEE_js.createWheelStepBuffer());
746
+ const wheelBufferRef = react.useRef(chunkPCW2KT7Z_js.createWheelStepBuffer());
747
747
  const storeRef = react.useRef(null);
748
- storeRef.current ??= chunkFJDZ7AEE_js.createViewerZoomStore();
748
+ storeRef.current ??= chunkPCW2KT7Z_js.createViewerZoomStore();
749
749
  const store = storeRef.current;
750
750
  const scale = useViewerStore(store, selectZoom);
751
751
  const setScale = react.useCallback(
@@ -806,7 +806,7 @@ function useZoomViewport({
806
806
  if (!wrapper || !canvasViewport) {
807
807
  return;
808
808
  }
809
- const boundedScale = chunkFJDZ7AEE_js.clampZoomScale(nextScale);
809
+ const boundedScale = chunkPCW2KT7Z_js.clampZoomScale(nextScale);
810
810
  const nextEditorScale = fitScale * boundedScale;
811
811
  const centerX = (bounds.minX + bounds.maxX) / 2;
812
812
  const centerY = (bounds.minY + bounds.maxY) / 2;
@@ -843,29 +843,29 @@ function useZoomViewport({
843
843
  selectedElements.forEach((element) => {
844
844
  minX = Math.min(minX, element.x);
845
845
  minY = Math.min(minY, element.y);
846
- maxX = Math.max(maxX, element.x + Math.max(element.width, chunkB6UIVRFA_js.MIN_ELEMENT_SIZE));
847
- maxY = Math.max(maxY, element.y + Math.max(element.height, chunkB6UIVRFA_js.MIN_ELEMENT_SIZE));
846
+ maxX = Math.max(maxX, element.x + Math.max(element.width, chunkXBTHWXNO_js.MIN_ELEMENT_SIZE));
847
+ maxY = Math.max(maxY, element.y + Math.max(element.height, chunkXBTHWXNO_js.MIN_ELEMENT_SIZE));
848
848
  });
849
849
  if (!Number.isFinite(minX) || !Number.isFinite(minY) || !Number.isFinite(maxX) || !Number.isFinite(maxY)) {
850
850
  return;
851
851
  }
852
852
  const selectionBounds = { minX, minY, maxX, maxY };
853
- const boundsWidth = Math.max(selectionBounds.maxX - selectionBounds.minX, chunkB6UIVRFA_js.MIN_ELEMENT_SIZE);
854
- const boundsHeight = Math.max(selectionBounds.maxY - selectionBounds.minY, chunkB6UIVRFA_js.MIN_ELEMENT_SIZE);
853
+ const boundsWidth = Math.max(selectionBounds.maxX - selectionBounds.minX, chunkXBTHWXNO_js.MIN_ELEMENT_SIZE);
854
+ const boundsHeight = Math.max(selectionBounds.maxY - selectionBounds.minY, chunkXBTHWXNO_js.MIN_ELEMENT_SIZE);
855
855
  const availableWidth = Math.max(
856
- effectiveEditorDimensions.width - chunkB6UIVRFA_js.ZOOM_TO_SELECTION_PADDING,
857
- chunkB6UIVRFA_js.MIN_ELEMENT_SIZE
856
+ effectiveEditorDimensions.width - chunkXBTHWXNO_js.ZOOM_TO_SELECTION_PADDING,
857
+ chunkXBTHWXNO_js.MIN_ELEMENT_SIZE
858
858
  );
859
859
  const availableHeight = Math.max(
860
- effectiveEditorDimensions.height - chunkB6UIVRFA_js.ZOOM_TO_SELECTION_PADDING,
861
- chunkB6UIVRFA_js.MIN_ELEMENT_SIZE
860
+ effectiveEditorDimensions.height - chunkXBTHWXNO_js.ZOOM_TO_SELECTION_PADDING,
861
+ chunkXBTHWXNO_js.MIN_ELEMENT_SIZE
862
862
  );
863
863
  const targetEditorScale = Math.min(
864
864
  availableWidth / boundsWidth,
865
865
  availableHeight / boundsHeight
866
866
  );
867
867
  const safeFitScale = fitScale > Number.EPSILON ? fitScale : Number.EPSILON;
868
- const nextScale = chunkFJDZ7AEE_js.clampZoomScale(targetEditorScale / safeFitScale);
868
+ const nextScale = chunkPCW2KT7Z_js.clampZoomScale(targetEditorScale / safeFitScale);
869
869
  setScale(nextScale);
870
870
  window.requestAnimationFrame(() => {
871
871
  window.requestAnimationFrame(() => {
@@ -882,14 +882,14 @@ function useZoomViewport({
882
882
  ]);
883
883
  const handleWheel = react.useCallback(
884
884
  (event) => {
885
- const mapped = chunkFJDZ7AEE_js.mapEditingWheel(event, wheelBufferRef.current, true);
885
+ const mapped = chunkPCW2KT7Z_js.mapEditingWheel(event, wheelBufferRef.current, true);
886
886
  if (mapped.intent !== "zoom") {
887
887
  return;
888
888
  }
889
889
  event.preventDefault();
890
890
  store.dispatch({
891
891
  type: "set-zoom",
892
- zoom: chunkFJDZ7AEE_js.clampZoomScale(store.getState().zoom + mapped.deltaScale)
892
+ zoom: chunkPCW2KT7Z_js.clampZoomScale(store.getState().zoom + mapped.deltaScale)
893
893
  });
894
894
  },
895
895
  [store]
@@ -971,67 +971,6 @@ function stopAnimationSound() {
971
971
  }
972
972
 
973
973
  // src/viewer/hooks/presentation-mode/animation-helpers.ts
974
- function applyAnimationGroupSteps(group, onPlayActionSound, setPresentationElementStates, presentationTimersRef) {
975
- for (const step of group.steps) {
976
- if (step.command) {
977
- const command = step.command;
978
- const timer = window.setTimeout(
979
- () => {
980
- chunkB6UIVRFA_js.executeMediaCommand(command);
981
- },
982
- Math.max(0, step.delayMs)
983
- );
984
- presentationTimersRef.current.push(timer);
985
- continue;
986
- }
987
- if (step.stopSound) {
988
- stopAnimationSound();
989
- } else if (step.soundPath && onPlayActionSound) {
990
- onPlayActionSound(step.soundPath);
991
- }
992
- }
993
- setPresentationElementStates((previousStates) => {
994
- const nextStates = new Map(previousStates);
995
- for (const step of group.steps) {
996
- if (step.command) {
997
- continue;
998
- }
999
- const currentState = nextStates.get(step.elementId) ?? {
1000
- visible: true};
1001
- const shouldBeVisible = step.presetClass === "exit" ? currentState.visible : true;
1002
- const colorTargets = step.colorTargets;
1003
- nextStates.set(step.elementId, {
1004
- visible: shouldBeVisible,
1005
- cssAnimation: step.cssAnimation,
1006
- animatesFill: colorTargets?.includes("fill") ? true : void 0,
1007
- animatesStroke: colorTargets?.includes("stroke") ? true : void 0
1008
- });
1009
- }
1010
- return nextStates;
1011
- });
1012
- for (const step of group.steps) {
1013
- if (step.command) {
1014
- continue;
1015
- }
1016
- const timer = window.setTimeout(
1017
- () => {
1018
- setPresentationElementStates((previousStates) => {
1019
- const nextStates = new Map(previousStates);
1020
- const currentState = nextStates.get(step.elementId) ?? {
1021
- visible: true};
1022
- const visibleAfterStep = step.presetClass === "exit" || step.hideAfterEffect ? false : currentState.visible;
1023
- nextStates.set(step.elementId, {
1024
- visible: visibleAfterStep,
1025
- cssAnimation: step.holdEndState ? step.cssAnimation : void 0
1026
- });
1027
- return nextStates;
1028
- });
1029
- },
1030
- Math.max(0, step.delayMs + step.durationMs + 8)
1031
- );
1032
- presentationTimersRef.current.push(timer);
1033
- }
1034
- }
1035
974
  function shouldSeekAnimationGroup(group, endAtMs, nowMs) {
1036
975
  return group?.seqNextAction === "seek" && nowMs < endAtMs;
1037
976
  }
@@ -1104,49 +1043,8 @@ function finishAnimationGroupSteps(group, setPresentationElementStates, complete
1104
1043
  });
1105
1044
  }
1106
1045
 
1107
- // src/viewer/hooks/presentation-mode/build-playback.ts
1108
- function cancelBuildReveal(handle) {
1109
- if (handle.current !== null) {
1110
- cancelAnimationFrame(handle.current);
1111
- handle.current = null;
1112
- }
1113
- }
1114
- function driveBuildReveal(controller, buildIds, setStates, handle) {
1115
- cancelBuildReveal(handle);
1116
- if (buildIds.length === 0 || typeof requestAnimationFrame !== "function") {
1117
- return;
1118
- }
1119
- const start = performance.now();
1120
- const tick = () => {
1121
- const elapsedMs = performance.now() - start;
1122
- const states = controller.computeStatesFor(buildIds, { elapsedMs });
1123
- setStates((prev) => {
1124
- const next = new Map(prev);
1125
- for (const id of buildIds) {
1126
- const build = states.get(id)?.build;
1127
- if (!build) {
1128
- continue;
1129
- }
1130
- const existing = next.get(id) ?? { visible: true, cssAnimation: void 0 };
1131
- next.set(id, { ...existing, build });
1132
- }
1133
- return next;
1134
- });
1135
- let pending = false;
1136
- for (const id of buildIds) {
1137
- const build = states.get(id)?.build;
1138
- if (build && build.progress < 1) {
1139
- pending = true;
1140
- break;
1141
- }
1142
- }
1143
- handle.current = pending ? requestAnimationFrame(tick) : null;
1144
- };
1145
- tick();
1146
- }
1147
-
1148
1046
  // src/viewer/hooks/presentation-mode/entrance-animation-timers.ts
1149
- function scheduleOpeningAutoPlayGroup(controller, deps) {
1047
+ function scheduleOpeningAutoPlayGroup(controller, ctx) {
1150
1048
  if (!controller.hasMoreSteps()) {
1151
1049
  return;
1152
1050
  }
@@ -1159,17 +1057,10 @@ function scheduleOpeningAutoPlayGroup(controller, deps) {
1159
1057
  if (!group) {
1160
1058
  return;
1161
1059
  }
1162
- applyAnimationGroupSteps(
1163
- group,
1164
- deps.onPlayActionSound,
1165
- deps.setPresentationElementStates,
1166
- deps.presentationTimersRef
1167
- );
1168
- deps.markAnimationGroupActive(group);
1169
- deps.startBuildReveal(controller, group);
1170
- deps.scheduleAutoAdvanceChain(controller);
1060
+ chunkPCW2KT7Z_js.playGroup(controller, group, ctx);
1061
+ chunkPCW2KT7Z_js.scheduleAutoAdvanceChain(controller, ctx);
1171
1062
  }, firstGroup.autoAdvanceDelayMs ?? 0);
1172
- deps.presentationTimersRef.current.push(timer);
1063
+ ctx.timers.push(timer);
1173
1064
  }
1174
1065
  function scheduleEntranceAnimationTimers(slide, setPresentationAnimations, presentationTimersRef) {
1175
1066
  const entranceAnimations = [...slide.animations || []].filter((animation) => Boolean(animation.entrance)).sort(
@@ -1186,7 +1077,7 @@ function scheduleEntranceAnimationTimers(slide, setPresentationAnimations, prese
1186
1077
  }))
1187
1078
  );
1188
1079
  entranceAnimations.forEach((animation, animationIndex) => {
1189
- const delay = chunkFJDZ7AEE_js.computeEntranceAnimationDelay(animation.delayMs, animationIndex);
1080
+ const delay = chunkPCW2KT7Z_js.computeEntranceAnimationDelay(animation.delayMs, animationIndex);
1190
1081
  const timer = window.setTimeout(() => {
1191
1082
  setPresentationAnimations(
1192
1083
  (previousAnimations) => previousAnimations.map(
@@ -1216,20 +1107,19 @@ function useAnimationPlayback(input) {
1216
1107
  const activeAnimationEndAtRef = react.useRef(0);
1217
1108
  const seededCompletedRef = react.useRef(false);
1218
1109
  const lastSeedCompletedRef = react.useRef(false);
1219
- const startBuildReveal = react.useCallback(
1220
- (controller, group) => {
1221
- driveBuildReveal(
1222
- controller,
1223
- chunkFJDZ7AEE_js.PresentationAnimationController.collectBuildStepIds(group),
1224
- setPresentationElementStates,
1225
- buildRafRef
1226
- );
1227
- },
1228
- []
1229
- );
1110
+ const buildPlaybackContext = react.useCallback(() => {
1111
+ return {
1112
+ setStates: setPresentationElementStates,
1113
+ timers: presentationTimersRef.current,
1114
+ buildHandle: buildRafRef,
1115
+ onPlayActionSound,
1116
+ playSound: playAnimationSound,
1117
+ stopSound: stopAnimationSound
1118
+ };
1119
+ }, [onPlayActionSound]);
1230
1120
  react.useEffect(() => {
1231
1121
  return () => {
1232
- cancelBuildReveal(buildRafRef);
1122
+ chunkPCW2KT7Z_js.cancelBuildReveal(buildRafRef);
1233
1123
  };
1234
1124
  }, []);
1235
1125
  const clearPresentationTimers = react.useCallback(() => {
@@ -1237,7 +1127,7 @@ function useAnimationPlayback(input) {
1237
1127
  window.clearTimeout(timer);
1238
1128
  });
1239
1129
  presentationTimersRef.current = [];
1240
- cancelBuildReveal(buildRafRef);
1130
+ chunkPCW2KT7Z_js.cancelBuildReveal(buildRafRef);
1241
1131
  activeAnimationGroupRef.current = null;
1242
1132
  activeAnimationEndAtRef.current = 0;
1243
1133
  }, []);
@@ -1245,48 +1135,9 @@ function useAnimationPlayback(input) {
1245
1135
  activeAnimationGroupRef.current = group;
1246
1136
  activeAnimationEndAtRef.current = performance.now() + Math.max(0, group.totalDurationMs);
1247
1137
  }, []);
1248
- const scheduleAutoAdvanceChain = react.useCallback(
1249
- (controller) => {
1250
- if (!controller.shouldAutoAdvance()) {
1251
- return;
1252
- }
1253
- const delay = controller.getAutoAdvanceDelay();
1254
- const previousGroup = controller.peekNext();
1255
- if (!previousGroup) {
1256
- return;
1257
- }
1258
- const totalDelay = delay + (previousGroup.autoAdvanceDelayMs ?? 0);
1259
- const timer = window.setTimeout(
1260
- () => {
1261
- const group = controller.advance();
1262
- if (!group) {
1263
- return;
1264
- }
1265
- applyAnimationGroupSteps(
1266
- group,
1267
- onPlayActionSound,
1268
- setPresentationElementStates,
1269
- presentationTimersRef
1270
- );
1271
- markAnimationGroupActive(group);
1272
- startBuildReveal(controller, group);
1273
- scheduleAutoAdvanceChain(controller);
1274
- },
1275
- Math.max(0, totalDelay)
1276
- );
1277
- presentationTimersRef.current.push(timer);
1278
- },
1279
- // `scheduleAutoAdvanceChain` recursively calls itself (line 190) to walk the
1280
- // auto-advance chain; it can't list itself as its own dependency (the const
1281
- // isn't assigned yet when the array is evaluated). The recursive call still
1282
- // resolves correctly because the setTimeout callback only reads the binding
1283
- // once the outer const has been assigned.
1284
- // oxlint-disable-next-line react/memo-dependencies -- see comment above
1285
- [markAnimationGroupActive, onPlayActionSound, startBuildReveal]
1286
- );
1287
1138
  const resetSlideTimeline = react.useCallback(
1288
1139
  (slideIndex) => {
1289
- cancelBuildReveal(buildRafRef);
1140
+ chunkPCW2KT7Z_js.cancelBuildReveal(buildRafRef);
1290
1141
  const slide = slides[slideIndex];
1291
1142
  if (!slide) {
1292
1143
  controllerRef.current = null;
@@ -1296,7 +1147,7 @@ function useAnimationPlayback(input) {
1296
1147
  setHoverTriggerShapeIds(/* @__PURE__ */ new Set());
1297
1148
  return;
1298
1149
  }
1299
- const controller = chunkFJDZ7AEE_js.PresentationAnimationController.fromSlide(slide);
1150
+ const controller = chunkPCW2KT7Z_js.PresentationAnimationController.fromSlide(slide);
1300
1151
  controllerRef.current = controller;
1301
1152
  setPresentationKeyframesCss(controller.keyframesCss);
1302
1153
  setInteractiveTriggerShapeIds(controller.interactiveTriggerShapeIds);
@@ -1313,11 +1164,11 @@ function useAnimationPlayback(input) {
1313
1164
  const activeGroup = activeAnimationGroupRef.current;
1314
1165
  if (controller && controller.hasMoreSteps() && shouldSeekAnimationGroup(activeGroup, activeAnimationEndAtRef.current, performance.now())) {
1315
1166
  finishDomAnimationsForGroup(activeGroup);
1316
- const buildIds = chunkFJDZ7AEE_js.PresentationAnimationController.collectBuildStepIds(activeGroup);
1167
+ const buildIds = chunkPCW2KT7Z_js.PresentationAnimationController.collectBuildStepIds(activeGroup);
1317
1168
  const completedStates = controller.computeStatesFor(buildIds);
1318
1169
  clearPresentationTimers();
1319
1170
  finishAnimationGroupSteps(activeGroup, setPresentationElementStates, completedStates);
1320
- scheduleAutoAdvanceChain(controller);
1171
+ chunkPCW2KT7Z_js.scheduleAutoAdvanceChain(controller, buildPlaybackContext());
1321
1172
  return true;
1322
1173
  }
1323
1174
  if (!controller || !controller.hasMoreSteps()) {
@@ -1327,24 +1178,12 @@ function useAnimationPlayback(input) {
1327
1178
  if (!group) {
1328
1179
  return false;
1329
1180
  }
1330
- applyAnimationGroupSteps(
1331
- group,
1332
- onPlayActionSound,
1333
- setPresentationElementStates,
1334
- presentationTimersRef
1335
- );
1181
+ const ctx = buildPlaybackContext();
1182
+ chunkPCW2KT7Z_js.playGroup(controller, group, ctx);
1336
1183
  markAnimationGroupActive(group);
1337
- startBuildReveal(controller, group);
1338
- scheduleAutoAdvanceChain(controller);
1184
+ chunkPCW2KT7Z_js.scheduleAutoAdvanceChain(controller, ctx);
1339
1185
  return true;
1340
- }, [
1341
- animationsEnabled,
1342
- clearPresentationTimers,
1343
- markAnimationGroupActive,
1344
- onPlayActionSound,
1345
- scheduleAutoAdvanceChain,
1346
- startBuildReveal
1347
- ]);
1186
+ }, [animationsEnabled, buildPlaybackContext, clearPresentationTimers, markAnimationGroupActive]);
1348
1187
  const handleInteractiveShapeClick = react.useCallback(
1349
1188
  (shapeId) => {
1350
1189
  const controller = controllerRef.current;
@@ -1355,16 +1194,10 @@ function useAnimationPlayback(input) {
1355
1194
  if (!group) {
1356
1195
  return false;
1357
1196
  }
1358
- applyAnimationGroupSteps(
1359
- group,
1360
- onPlayActionSound,
1361
- setPresentationElementStates,
1362
- presentationTimersRef
1363
- );
1364
- startBuildReveal(controller, group);
1197
+ chunkPCW2KT7Z_js.playGroup(controller, group, buildPlaybackContext());
1365
1198
  return true;
1366
1199
  },
1367
- [onPlayActionSound, startBuildReveal]
1200
+ [buildPlaybackContext]
1368
1201
  );
1369
1202
  const handleHoverStart = react.useCallback(
1370
1203
  (shapeId) => {
@@ -1380,16 +1213,10 @@ function useAnimationPlayback(input) {
1380
1213
  if (!group) {
1381
1214
  return false;
1382
1215
  }
1383
- applyAnimationGroupSteps(
1384
- group,
1385
- onPlayActionSound,
1386
- setPresentationElementStates,
1387
- presentationTimersRef
1388
- );
1389
- startBuildReveal(controller, group);
1216
+ chunkPCW2KT7Z_js.playGroup(controller, group, buildPlaybackContext());
1390
1217
  return true;
1391
1218
  },
1392
- [animationsEnabled, onPlayActionSound, startBuildReveal]
1219
+ [animationsEnabled, buildPlaybackContext]
1393
1220
  );
1394
1221
  const handleHoverEnd = react.useCallback((shapeId) => {
1395
1222
  const controller = controllerRef.current;
@@ -1435,25 +1262,12 @@ function useAnimationPlayback(input) {
1435
1262
  }
1436
1263
  const controller = controllerRef.current;
1437
1264
  if (controller) {
1438
- scheduleOpeningAutoPlayGroup(controller, {
1439
- onPlayActionSound,
1440
- setPresentationElementStates,
1441
- presentationTimersRef,
1442
- startBuildReveal,
1443
- scheduleAutoAdvanceChain,
1444
- markAnimationGroupActive
1445
- });
1265
+ const ctx = buildPlaybackContext();
1266
+ scheduleOpeningAutoPlayGroup(controller, ctx);
1446
1267
  }
1447
1268
  scheduleEntranceAnimationTimers(slide, setPresentationAnimations, presentationTimersRef);
1448
1269
  },
1449
- [
1450
- animationsEnabled,
1451
- slides,
1452
- onPlayActionSound,
1453
- markAnimationGroupActive,
1454
- scheduleAutoAdvanceChain,
1455
- startBuildReveal
1456
- ]
1270
+ [animationsEnabled, slides, buildPlaybackContext]
1457
1271
  );
1458
1272
  const runPresentationEntranceAnimations = react.useCallback(
1459
1273
  (slideIndex, options) => {
@@ -1480,12 +1294,12 @@ function useAnimationPlayback(input) {
1480
1294
  presentationTimersRef
1481
1295
  };
1482
1296
  }
1483
- var PRESENTER_CHANNEL_NAME = chunkFJDZ7AEE_js.PRESENTATION_CHANNEL_NAME;
1484
- var AUDIENCE_HASH = chunkFJDZ7AEE_js.PRESENTATION_HASH;
1485
- var PRESENTER_MSG_ORIGIN = chunkFJDZ7AEE_js.PRESENTATION_MESSAGE_ORIGIN;
1486
- var AUDIENCE_NONCE_KEY = chunkFJDZ7AEE_js.PRESENTATION_NONCE_KEY;
1297
+ var PRESENTER_CHANNEL_NAME = chunkPCW2KT7Z_js.PRESENTATION_CHANNEL_NAME;
1298
+ var AUDIENCE_HASH = chunkPCW2KT7Z_js.PRESENTATION_HASH;
1299
+ var PRESENTER_MSG_ORIGIN = chunkPCW2KT7Z_js.PRESENTATION_MESSAGE_ORIGIN;
1300
+ var AUDIENCE_NONCE_KEY = chunkPCW2KT7Z_js.PRESENTATION_NONCE_KEY;
1487
1301
  function generateSessionId() {
1488
- return chunkFJDZ7AEE_js.createPresentationSessionId();
1302
+ return chunkPCW2KT7Z_js.createPresentationSessionId();
1489
1303
  }
1490
1304
  function parseAudienceNonce() {
1491
1305
  const hash = window.location.hash;
@@ -1521,7 +1335,7 @@ function usePresenterWindow(input) {
1521
1335
  }, []);
1522
1336
  const swapDisplays = react.useCallback(async () => {
1523
1337
  const audience = audienceWindowRef.current;
1524
- return audience && !audience.closed ? chunkFJDZ7AEE_js.swapPresentationWindows(window, audience) : false;
1338
+ return audience && !audience.closed ? chunkPCW2KT7Z_js.swapPresentationWindows(window, audience) : false;
1525
1339
  }, []);
1526
1340
  const syncSlideToAudience = react.useCallback(
1527
1341
  (slideIndex) => {
@@ -1585,7 +1399,7 @@ function usePresenterWindow(input) {
1585
1399
  pollTimerRef.current = null;
1586
1400
  }
1587
1401
  if (closingSessionId) {
1588
- void chunkFJDZ7AEE_js.clearAudienceContent(closingSessionId);
1402
+ void chunkPCW2KT7Z_js.clearAudienceContent(closingSessionId);
1589
1403
  }
1590
1404
  }, [getChannel]);
1591
1405
  const openAudienceWindow = react.useCallback(() => {
@@ -1603,10 +1417,10 @@ function usePresenterWindow(input) {
1603
1417
  audienceWindowRef.current = blankWin;
1604
1418
  const sessionId = generateSessionId();
1605
1419
  sessionIdRef.current = sessionId;
1606
- const audienceUrl = chunkFJDZ7AEE_js.buildPresentationAudienceUrl(window.location.href, sessionId);
1607
- void chunkFJDZ7AEE_js.resolveAudienceScreenPlacement(window).then((placement) => {
1420
+ const audienceUrl = chunkPCW2KT7Z_js.buildPresentationAudienceUrl(window.location.href, sessionId);
1421
+ void chunkPCW2KT7Z_js.resolveAudienceScreenPlacement(window).then((placement) => {
1608
1422
  if (placement && audienceWindowRef.current === blankWin && !blankWin.closed) {
1609
- chunkFJDZ7AEE_js.placeAudienceWindow(blankWin, placement);
1423
+ chunkPCW2KT7Z_js.placeAudienceWindow(blankWin, placement);
1610
1424
  }
1611
1425
  return void 0;
1612
1426
  });
@@ -1636,7 +1450,7 @@ function usePresenterWindow(input) {
1636
1450
  }
1637
1451
  };
1638
1452
  if (content) {
1639
- void chunkFJDZ7AEE_js.storeAudienceContent(content, sessionId).then(() => navigateOrClose(true)).catch(() => navigateOrClose(false));
1453
+ void chunkPCW2KT7Z_js.storeAudienceContent(content, sessionId).then(() => navigateOrClose(true)).catch(() => navigateOrClose(false));
1640
1454
  } else {
1641
1455
  navigateOrClose(true);
1642
1456
  }
@@ -1662,7 +1476,7 @@ function usePresenterWindow(input) {
1662
1476
  }
1663
1477
  const handleMessage = (event) => {
1664
1478
  const message = event.data;
1665
- if (chunkFJDZ7AEE_js.isPresentationSessionMessage(message) && message.type === "audience-ready" && message.sessionId === sessionIdRef.current) {
1479
+ if (chunkPCW2KT7Z_js.isPresentationSessionMessage(message) && message.type === "audience-ready" && message.sessionId === sessionIdRef.current) {
1666
1480
  syncStateToAudience(snapshotRef.current);
1667
1481
  }
1668
1482
  };
@@ -1691,7 +1505,7 @@ function usePresenterWindow(input) {
1691
1505
  react.useEffect(() => {
1692
1506
  const handleBeforeUnload = () => {
1693
1507
  if (sessionIdRef.current) {
1694
- void chunkFJDZ7AEE_js.clearAudienceContent(sessionIdRef.current);
1508
+ void chunkPCW2KT7Z_js.clearAudienceContent(sessionIdRef.current);
1695
1509
  }
1696
1510
  };
1697
1511
  window.addEventListener("beforeunload", handleBeforeUnload);
@@ -1753,7 +1567,7 @@ function useAudienceMode(input) {
1753
1567
  }
1754
1568
  channel.onmessage = (event) => {
1755
1569
  const data = event.data;
1756
- if (!chunkFJDZ7AEE_js.isPresentationSessionMessage(data) || data.origin !== PRESENTER_MSG_ORIGIN) {
1570
+ if (!chunkPCW2KT7Z_js.isPresentationSessionMessage(data) || data.origin !== PRESENTER_MSG_ORIGIN) {
1757
1571
  return;
1758
1572
  }
1759
1573
  if (expectedSessionId && data.sessionId !== expectedSessionId) {
@@ -1769,16 +1583,16 @@ function useAudienceMode(input) {
1769
1583
  }
1770
1584
  if (data.type === "presenter-exit") {
1771
1585
  if (expectedSessionId) {
1772
- void chunkFJDZ7AEE_js.clearAudienceContent(expectedSessionId);
1586
+ void chunkPCW2KT7Z_js.clearAudienceContent(expectedSessionId);
1773
1587
  }
1774
- if (chunkFJDZ7AEE_js.endAudienceDisplay(window)) {
1588
+ if (chunkPCW2KT7Z_js.endAudienceDisplay(window)) {
1775
1589
  handlers.onPresenterEnded?.();
1776
1590
  }
1777
1591
  }
1778
1592
  };
1779
1593
  if (expectedSessionId) {
1780
1594
  channel.postMessage({
1781
- origin: chunkFJDZ7AEE_js.PRESENTATION_MESSAGE_ORIGIN,
1595
+ origin: chunkPCW2KT7Z_js.PRESENTATION_MESSAGE_ORIGIN,
1782
1596
  type: "audience-ready",
1783
1597
  sessionId: expectedSessionId
1784
1598
  });
@@ -1792,7 +1606,7 @@ function useAudienceMode(input) {
1792
1606
  }, []);
1793
1607
  }
1794
1608
  function usePresentationKeyboard(input) {
1795
- const wheelBufferRef = react.useRef(chunkFJDZ7AEE_js.createWheelStepBuffer());
1609
+ const wheelBufferRef = react.useRef(chunkPCW2KT7Z_js.createWheelStepBuffer());
1796
1610
  const {
1797
1611
  mode,
1798
1612
  movePresentationSlide,
@@ -1813,14 +1627,14 @@ function usePresentationKeyboard(input) {
1813
1627
  presentationSlideIndex,
1814
1628
  setShowRehearsalSummary
1815
1629
  } = input;
1816
- const keyBufferRef = react.useRef(chunkFJDZ7AEE_js.createPresentationKeyBuffer());
1630
+ const keyBufferRef = react.useRef(chunkPCW2KT7Z_js.createPresentationKeyBuffer());
1817
1631
  react.useEffect(() => {
1818
- if (mode !== "present" || !chunkFJDZ7AEE_js.acceptsPresentationInput()) {
1819
- keyBufferRef.current = chunkFJDZ7AEE_js.createPresentationKeyBuffer();
1632
+ if (mode !== "present" || !chunkPCW2KT7Z_js.acceptsPresentationInput()) {
1633
+ keyBufferRef.current = chunkPCW2KT7Z_js.createPresentationKeyBuffer();
1820
1634
  return;
1821
1635
  }
1822
1636
  const handleKeyDown = (event) => {
1823
- const mapped = chunkFJDZ7AEE_js.mapPresentationKey(event, keyBufferRef.current);
1637
+ const mapped = chunkPCW2KT7Z_js.mapPresentationKey(event, keyBufferRef.current);
1824
1638
  if (mapped.action === "none") {
1825
1639
  return;
1826
1640
  }
@@ -1840,12 +1654,12 @@ function usePresentationKeyboard(input) {
1840
1654
  movePresentationSlide(-1);
1841
1655
  return;
1842
1656
  case "first": {
1843
- const first = chunkFJDZ7AEE_js.firstShowSlideIndex(showSlideIndexes);
1657
+ const first = chunkPCW2KT7Z_js.firstShowSlideIndex(showSlideIndexes);
1844
1658
  navigateToSlide(first ?? 0);
1845
1659
  return;
1846
1660
  }
1847
1661
  case "last": {
1848
- const last = chunkFJDZ7AEE_js.lastShowSlideIndex(showSlideIndexes);
1662
+ const last = chunkPCW2KT7Z_js.lastShowSlideIndex(showSlideIndexes);
1849
1663
  navigateToSlide(last ?? Math.max(0, slideCount - 1));
1850
1664
  return;
1851
1665
  }
@@ -1883,10 +1697,10 @@ function usePresentationKeyboard(input) {
1883
1697
  }
1884
1698
  };
1885
1699
  const handleWheel = (event) => {
1886
- if (mode !== "present" || !chunkFJDZ7AEE_js.acceptsPresentationInput()) {
1700
+ if (mode !== "present" || !chunkPCW2KT7Z_js.acceptsPresentationInput()) {
1887
1701
  return;
1888
1702
  }
1889
- const mapped = chunkFJDZ7AEE_js.mapPresentationWheel(event, wheelBufferRef.current);
1703
+ const mapped = chunkPCW2KT7Z_js.mapPresentationWheel(event, wheelBufferRef.current);
1890
1704
  if (mapped.intent === "next-slide") {
1891
1705
  event.preventDefault();
1892
1706
  movePresentationSlide(1);
@@ -2019,9 +1833,9 @@ function useRehearsalTimings(input) {
2019
1833
 
2020
1834
  // src/viewer/hooks/presentation-mode/presentation-actions.ts
2021
1835
  function handlePresentationActionImpl(action, deps) {
2022
- chunkFJDZ7AEE_js.runPresentationAction(
1836
+ chunkPCW2KT7Z_js.runPresentationAction(
2023
1837
  action,
2024
- { slideCount: deps.slidesLength },
1838
+ { slideCount: deps.slidesLength, ...deps.elementId ? { elementId: deps.elementId } : {} },
2025
1839
  {
2026
1840
  goToSlide: (slideIndex) => {
2027
1841
  deps.navigateToSlide(slideIndex);
@@ -2032,7 +1846,13 @@ function handlePresentationActionImpl(action, deps) {
2032
1846
  endShow: () => {
2033
1847
  deps.onSetMode("edit");
2034
1848
  },
2035
- playSound: deps.onPlayActionSound ? (soundPath) => deps.onPlayActionSound?.(soundPath) : void 0
1849
+ playSound: deps.onPlayActionSound ? (soundPath) => deps.onPlayActionSound?.(soundPath) : void 0,
1850
+ lastViewed: deps.onLastViewed,
1851
+ customShow: deps.onCustomShow,
1852
+ openFile: deps.onOpenFile,
1853
+ openPresentation: deps.onOpenPresentation,
1854
+ playMedia: deps.onPlayMedia,
1855
+ oleVerb: deps.onOleVerb
2036
1856
  }
2037
1857
  );
2038
1858
  }
@@ -2040,8 +1860,8 @@ function handlePresentationActionImpl(action, deps) {
2040
1860
  // src/viewer/hooks/presentation-mode/slide-transition.ts
2041
1861
  function executeSlideTransition(nextSlideIndex, deps) {
2042
1862
  const incomingSlide = deps.slides[nextSlideIndex];
2043
- const transition = incomingSlide?.transition;
2044
- const durationMs = deps.playTransition ? chunkFJDZ7AEE_js.resolveTransitionDurationMs(transition) : 0;
1863
+ const transition = deps.reverse ? deps.slides[deps.currentSlideIndex]?.transition : incomingSlide?.transition;
1864
+ const durationMs = deps.playTransition ? chunkPCW2KT7Z_js.resolveTransitionDurationMs(transition) : 0;
2045
1865
  deps.clearPresentationTimers();
2046
1866
  deps.setPresentationSlideIndex(nextSlideIndex);
2047
1867
  deps.onSetActiveSlideIndex(nextSlideIndex);
@@ -2094,13 +1914,19 @@ function useSlideNavigation(input) {
2094
1914
  presentationTimersRef,
2095
1915
  rehearsing,
2096
1916
  recordCurrentSlideTime,
2097
- setShowRehearsalSummary
1917
+ setShowRehearsalSummary,
1918
+ onLastViewed,
1919
+ onCustomShow,
1920
+ onOpenFile,
1921
+ onOpenPresentation,
1922
+ onPlayMedia,
1923
+ onOleVerb
2098
1924
  } = input;
2099
1925
  const movePresentationSlideRef = react.useRef(() => {
2100
1926
  });
2101
1927
  const scheduleAutoAdvanceForSlide = react.useCallback(
2102
1928
  (slideIndex) => {
2103
- const delayMs = chunkFJDZ7AEE_js.resolveAutoAdvanceDelayMs(slides[slideIndex], { useTimings });
1929
+ const delayMs = chunkPCW2KT7Z_js.resolveAutoAdvanceDelayMs(slides[slideIndex], { useTimings });
2104
1930
  if (delayMs === void 0) {
2105
1931
  return;
2106
1932
  }
@@ -2123,7 +1949,7 @@ function useSlideNavigation(input) {
2123
1949
  if (availableSlideIndexes.length === 0) {
2124
1950
  return;
2125
1951
  }
2126
- const pastLastSlide = direction === 1 && !chunkFJDZ7AEE_js.hasShowSlideAfter(presentationSlideIndex, availableSlideIndexes);
1952
+ const pastLastSlide = direction === 1 && !chunkPCW2KT7Z_js.hasShowSlideAfter(presentationSlideIndex, availableSlideIndexes);
2127
1953
  if (rehearsing && pastLastSlide) {
2128
1954
  recordCurrentSlideTime(presentationSlideIndex);
2129
1955
  try {
@@ -2141,9 +1967,9 @@ function useSlideNavigation(input) {
2141
1967
  onAdvancePastLastSlide();
2142
1968
  return;
2143
1969
  }
2144
- const nextSlideIndex = direction === 1 ? chunkFJDZ7AEE_js.nextShowSlideIndex(presentationSlideIndex, availableSlideIndexes, {
1970
+ const nextSlideIndex = direction === 1 ? chunkPCW2KT7Z_js.nextShowSlideIndex(presentationSlideIndex, availableSlideIndexes, {
2145
1971
  loop: Boolean(loopContinuously) && !rehearsing
2146
- }) : chunkFJDZ7AEE_js.previousShowSlideIndex(presentationSlideIndex, availableSlideIndexes);
1972
+ }) : chunkPCW2KT7Z_js.previousShowSlideIndex(presentationSlideIndex, availableSlideIndexes);
2147
1973
  if (nextSlideIndex === void 0 || nextSlideIndex === presentationSlideIndex) {
2148
1974
  return;
2149
1975
  }
@@ -2163,8 +1989,11 @@ function useSlideNavigation(input) {
2163
1989
  scheduleAutoAdvanceForSlide: rehearsing ? void 0 : scheduleAutoAdvanceForSlide,
2164
1990
  presentationTimersRef,
2165
1991
  setTransitionOverlay,
2166
- // PowerPoint plays a slide's transition only when advancing into it.
2167
- playTransition: direction === 1,
1992
+ // PowerPoint plays a slide's transition only when advancing into it,
1993
+ // and replays the LEAVING slide's transition in reverse when stepping
1994
+ // back (a morph glides its shapes back to where they came from).
1995
+ playTransition: true,
1996
+ reverse: direction === -1,
2168
1997
  // Stepping back onto a slide shows it with its builds already played.
2169
1998
  seedCompleted: direction === -1
2170
1999
  });
@@ -2240,16 +2069,35 @@ function useSlideNavigation(input) {
2240
2069
  ]
2241
2070
  );
2242
2071
  const handlePresentationAction = react.useCallback(
2243
- (action) => {
2072
+ (action, elementId) => {
2244
2073
  handlePresentationActionImpl(action, {
2074
+ elementId,
2245
2075
  movePresentationSlide,
2246
2076
  navigateToSlide,
2247
2077
  onPlayActionSound,
2248
2078
  onSetMode,
2249
- slidesLength: slides.length
2079
+ slidesLength: slides.length,
2080
+ onLastViewed,
2081
+ onCustomShow,
2082
+ onOpenFile,
2083
+ onOpenPresentation,
2084
+ onPlayMedia,
2085
+ onOleVerb
2250
2086
  });
2251
2087
  },
2252
- [movePresentationSlide, navigateToSlide, onPlayActionSound, onSetMode, slides.length]
2088
+ [
2089
+ movePresentationSlide,
2090
+ navigateToSlide,
2091
+ onPlayActionSound,
2092
+ onSetMode,
2093
+ slides.length,
2094
+ onLastViewed,
2095
+ onCustomShow,
2096
+ onOpenFile,
2097
+ onOpenPresentation,
2098
+ onPlayMedia,
2099
+ onOleVerb
2100
+ ]
2253
2101
  );
2254
2102
  return {
2255
2103
  movePresentationSlide,
@@ -2287,23 +2135,153 @@ function useZoomNavigation(input) {
2287
2135
  clearZoomReturn
2288
2136
  };
2289
2137
  }
2138
+ function createCustomShowRunner(deps) {
2139
+ let origin = null;
2140
+ return {
2141
+ runCustomShow(customShowId, returnAfter) {
2142
+ const target = deps.getCustomShows().find((show) => show.id === customShowId);
2143
+ if (!target) {
2144
+ return;
2145
+ }
2146
+ origin = returnAfter ? { showId: deps.getActiveCustomShowId(), slideIndex: deps.getPresentationSlideIndex() } : null;
2147
+ const first = chunkPCW2KT7Z_js.firstShowSlideIndex(chunkPCW2KT7Z_js.resolveShowSlideIndexes(deps.getSlides(), target));
2148
+ deps.setActiveCustomShowId(customShowId);
2149
+ if (first !== void 0) {
2150
+ deps.navigateToSlide(first);
2151
+ }
2152
+ },
2153
+ tryReturnFromCustomShow() {
2154
+ if (!origin) {
2155
+ return false;
2156
+ }
2157
+ const { showId, slideIndex } = origin;
2158
+ origin = null;
2159
+ deps.setActiveCustomShowId(showId);
2160
+ deps.navigateToSlide(slideIndex);
2161
+ return true;
2162
+ }
2163
+ };
2164
+ }
2165
+ function useCustomShowRunner(deps) {
2166
+ const depsRef = react.useRef(deps);
2167
+ depsRef.current = deps;
2168
+ const runnerRef = react.useRef(null);
2169
+ runnerRef.current ??= createCustomShowRunner({
2170
+ getSlides: () => depsRef.current.getSlides(),
2171
+ getCustomShows: () => depsRef.current.getCustomShows(),
2172
+ getActiveCustomShowId: () => depsRef.current.getActiveCustomShowId(),
2173
+ setActiveCustomShowId: (id) => depsRef.current.setActiveCustomShowId(id),
2174
+ navigateToSlide: (index) => depsRef.current.navigateToSlide(index),
2175
+ getPresentationSlideIndex: () => depsRef.current.getPresentationSlideIndex()
2176
+ });
2177
+ return runnerRef.current;
2178
+ }
2179
+
2180
+ // src/viewer/hooks/presentation-mode/usePresentationActionExtensions.ts
2181
+ function usePresentationActionExtensions(input) {
2182
+ const {
2183
+ slides,
2184
+ customShows,
2185
+ activeCustomShowId,
2186
+ onSetActiveCustomShowId,
2187
+ presentationSlideIndex,
2188
+ containerRef,
2189
+ endWithBlackSlide,
2190
+ onSetMode,
2191
+ setEndOfShowVisible
2192
+ } = input;
2193
+ const navigateToSlideRef = react.useRef(null);
2194
+ const navigateToSlideViaRef = react.useCallback((index) => {
2195
+ navigateToSlideRef.current?.(index);
2196
+ }, []);
2197
+ const customShowRunner = useCustomShowRunner({
2198
+ getSlides: () => slides,
2199
+ getCustomShows: () => customShows,
2200
+ getActiveCustomShowId: () => activeCustomShowId,
2201
+ setActiveCustomShowId: (id) => onSetActiveCustomShowId?.(id),
2202
+ navigateToSlide: navigateToSlideViaRef,
2203
+ getPresentationSlideIndex: () => presentationSlideIndex
2204
+ });
2205
+ const previousSlideRef = react.useRef(presentationSlideIndex);
2206
+ const lastViewedSlideRef = react.useRef(null);
2207
+ react.useEffect(() => {
2208
+ lastViewedSlideRef.current = previousSlideRef.current;
2209
+ previousSlideRef.current = presentationSlideIndex;
2210
+ }, [presentationSlideIndex]);
2211
+ const onCustomShow = react.useCallback(
2212
+ (customShowId, returnAfter) => {
2213
+ customShowRunner.runCustomShow(customShowId, returnAfter);
2214
+ },
2215
+ [customShowRunner]
2216
+ );
2217
+ const onLastViewed = react.useCallback(() => {
2218
+ const previous = lastViewedSlideRef.current;
2219
+ if (previous !== null) {
2220
+ navigateToSlideViaRef(previous);
2221
+ }
2222
+ }, [navigateToSlideViaRef]);
2223
+ const onOpenFile = react.useCallback((target) => {
2224
+ chunkPCW2KT7Z_js.safeOpenUrl(target);
2225
+ }, []);
2226
+ const onOpenPresentation = react.useCallback((target) => {
2227
+ chunkPCW2KT7Z_js.safeOpenUrl(target);
2228
+ }, []);
2229
+ const onPlayMedia = react.useCallback(
2230
+ (elementId) => {
2231
+ chunkPCW2KT7Z_js.toggleStageElementMedia(containerRef.current, elementId);
2232
+ },
2233
+ [containerRef]
2234
+ );
2235
+ const onOleVerb = react.useCallback(
2236
+ (verb, elementId) => {
2237
+ const target = chunkPCW2KT7Z_js.resolveOleVerbTarget(slides[presentationSlideIndex], elementId, verb);
2238
+ if (target) {
2239
+ chunkPCW2KT7Z_js.openUrlInNewTab(target.url);
2240
+ }
2241
+ },
2242
+ [slides, presentationSlideIndex]
2243
+ );
2244
+ const handleAdvancePastLastSlide = react.useCallback(() => {
2245
+ if (customShowRunner.tryReturnFromCustomShow()) {
2246
+ return;
2247
+ }
2248
+ if (endWithBlackSlide) {
2249
+ setEndOfShowVisible(true);
2250
+ } else {
2251
+ onSetMode("edit");
2252
+ }
2253
+ }, [customShowRunner, endWithBlackSlide, onSetMode, setEndOfShowVisible]);
2254
+ const bindNavigateToSlide = react.useCallback((navigateToSlide) => {
2255
+ navigateToSlideRef.current = navigateToSlide;
2256
+ }, []);
2257
+ return {
2258
+ onLastViewed,
2259
+ onCustomShow,
2260
+ onOpenFile,
2261
+ onOpenPresentation,
2262
+ onPlayMedia,
2263
+ onOleVerb,
2264
+ handleAdvancePastLastSlide,
2265
+ bindNavigateToSlide
2266
+ };
2267
+ }
2290
2268
  function usePresenterConsole(slideIndex, active) {
2291
- const timerRef = react.useRef(chunkFJDZ7AEE_js.createPresenterTimer());
2292
- const [snapshot, setSnapshot] = react.useState(() => chunkFJDZ7AEE_js.createInitialPresentationSnapshot(slideIndex));
2269
+ const timerRef = react.useRef(chunkPCW2KT7Z_js.createPresenterTimer());
2270
+ const [snapshot, setSnapshot] = react.useState(() => chunkPCW2KT7Z_js.createInitialPresentationSnapshot(slideIndex));
2293
2271
  const patch = react.useCallback((value) => {
2294
- setSnapshot((current) => chunkFJDZ7AEE_js.mergePresentationSnapshot(current, value));
2272
+ setSnapshot((current) => chunkPCW2KT7Z_js.mergePresentationSnapshot(current, value));
2295
2273
  }, []);
2296
2274
  react.useEffect(() => patch({ slideIndex }), [patch, slideIndex]);
2297
2275
  react.useEffect(() => {
2298
2276
  if (!active) {
2299
2277
  return;
2300
2278
  }
2301
- timerRef.current = chunkFJDZ7AEE_js.resetPresenterTimer();
2279
+ timerRef.current = chunkPCW2KT7Z_js.resetPresenterTimer();
2302
2280
  patch({ paused: false, elapsedMs: 0 });
2303
2281
  const timer = window.setInterval(() => {
2304
2282
  patch({
2305
2283
  paused: timerRef.current.paused,
2306
- elapsedMs: chunkFJDZ7AEE_js.presenterElapsed(timerRef.current)
2284
+ elapsedMs: chunkPCW2KT7Z_js.presenterElapsed(timerRef.current)
2307
2285
  });
2308
2286
  }, 1e3);
2309
2287
  return () => window.clearInterval(timer);
@@ -2313,19 +2291,19 @@ function usePresenterConsole(slideIndex, active) {
2313
2291
  applyAudienceSnapshot: setSnapshot,
2314
2292
  setBlackout: (blackout) => patch({ blackout }),
2315
2293
  toggleTimer: () => {
2316
- timerRef.current = chunkFJDZ7AEE_js.togglePresenterTimer(timerRef.current);
2294
+ timerRef.current = chunkPCW2KT7Z_js.togglePresenterTimer(timerRef.current);
2317
2295
  patch({
2318
2296
  paused: timerRef.current.paused,
2319
- elapsedMs: chunkFJDZ7AEE_js.presenterElapsed(timerRef.current)
2297
+ elapsedMs: chunkPCW2KT7Z_js.presenterElapsed(timerRef.current)
2320
2298
  });
2321
2299
  },
2322
2300
  resetTimer: () => {
2323
- timerRef.current = chunkFJDZ7AEE_js.resetPresenterTimer();
2301
+ timerRef.current = chunkPCW2KT7Z_js.resetPresenterTimer();
2324
2302
  patch({ paused: false, elapsedMs: 0 });
2325
2303
  },
2326
2304
  stepZoom: (direction) => setSnapshot(
2327
- (current) => chunkFJDZ7AEE_js.mergePresentationSnapshot(current, {
2328
- zoom: chunkFJDZ7AEE_js.stepPresenterZoom(
2305
+ (current) => chunkPCW2KT7Z_js.mergePresentationSnapshot(current, {
2306
+ zoom: chunkPCW2KT7Z_js.stepPresenterZoom(
2329
2307
  current.zoom ?? { scale: 1, originX: 0.5, originY: 0.5 },
2330
2308
  direction
2331
2309
  )
@@ -2343,6 +2321,7 @@ function usePresentationMode(input) {
2343
2321
  const {
2344
2322
  mode,
2345
2323
  slides,
2324
+ templateElementsBySlideId,
2346
2325
  visibleSlideIndexes,
2347
2326
  activeSlideIndex,
2348
2327
  containerRef,
@@ -2359,7 +2338,10 @@ function usePresentationMode(input) {
2359
2338
  loopContinuously,
2360
2339
  showWithAnimation,
2361
2340
  useTimings,
2362
- endWithBlackSlide = true
2341
+ endWithBlackSlide = true,
2342
+ customShows = [],
2343
+ activeCustomShowId = null,
2344
+ onSetActiveCustomShowId
2363
2345
  } = input;
2364
2346
  const [presentationSlideIndex, setPresentationSlideIndex] = react.useState(0);
2365
2347
  const [presentationSlideVisible, setPresentationSlideVisible] = react.useState(true);
@@ -2371,7 +2353,7 @@ function usePresentationMode(input) {
2371
2353
  const [allSlidesOpen, setAllSlidesOpen] = react.useState(false);
2372
2354
  const [endOfShowVisible, setEndOfShowVisible] = react.useState(false);
2373
2355
  const [presentationStartTime, setPresentationStartTime] = react.useState(null);
2374
- const showGuard = react.useMemo(() => chunkFJDZ7AEE_js.createPresenterShowGuard(), []);
2356
+ const showGuard = react.useMemo(() => chunkPCW2KT7Z_js.createPresenterShowGuard(), []);
2375
2357
  const {
2376
2358
  presentationAnimations,
2377
2359
  presentationElementStates,
@@ -2414,13 +2396,17 @@ function usePresentationMode(input) {
2414
2396
  setPresenterMode(false);
2415
2397
  }
2416
2398
  }, [mode]);
2417
- const handleAdvancePastLastSlide = react.useCallback(() => {
2418
- if (endWithBlackSlide) {
2419
- setEndOfShowVisible(true);
2420
- } else {
2421
- onSetMode("edit");
2422
- }
2423
- }, [endWithBlackSlide, onSetMode]);
2399
+ const actionExtensions = usePresentationActionExtensions({
2400
+ slides,
2401
+ customShows,
2402
+ activeCustomShowId,
2403
+ onSetActiveCustomShowId,
2404
+ presentationSlideIndex,
2405
+ containerRef,
2406
+ endWithBlackSlide,
2407
+ onSetMode,
2408
+ setEndOfShowVisible
2409
+ });
2424
2410
  const {
2425
2411
  movePresentationSlide: moveNavigationSlide,
2426
2412
  navigateToSlide,
@@ -2438,7 +2424,7 @@ function usePresentationMode(input) {
2438
2424
  onPlayActionSound,
2439
2425
  loopContinuously,
2440
2426
  useTimings,
2441
- onAdvancePastLastSlide: handleAdvancePastLastSlide,
2427
+ onAdvancePastLastSlide: actionExtensions.handleAdvancePastLastSlide,
2442
2428
  playNextAnimationGroup,
2443
2429
  clearPresentationTimers,
2444
2430
  seedSlideAnimations,
@@ -2446,11 +2432,18 @@ function usePresentationMode(input) {
2446
2432
  presentationTimersRef,
2447
2433
  rehearsing,
2448
2434
  recordCurrentSlideTime,
2449
- setShowRehearsalSummary
2435
+ setShowRehearsalSummary,
2436
+ onLastViewed: actionExtensions.onLastViewed,
2437
+ onCustomShow: actionExtensions.onCustomShow,
2438
+ onOpenFile: actionExtensions.onOpenFile,
2439
+ onOpenPresentation: actionExtensions.onOpenPresentation,
2440
+ onPlayMedia: actionExtensions.onPlayMedia,
2441
+ onOleVerb: actionExtensions.onOleVerb
2450
2442
  });
2443
+ actionExtensions.bindNavigateToSlide(navigateToSlide);
2451
2444
  const movePresentationSlide = react.useCallback(
2452
2445
  (direction, trigger = "explicit") => {
2453
- if (!chunkFJDZ7AEE_js.acceptsPresentationInput()) {
2446
+ if (!chunkPCW2KT7Z_js.acceptsPresentationInput()) {
2454
2447
  return;
2455
2448
  }
2456
2449
  if (endOfShowVisible) {
@@ -2518,6 +2511,13 @@ function usePresentationMode(input) {
2518
2511
  }
2519
2512
  onSetMode("present");
2520
2513
  }, [containerRef, onSetMode, setRehearsing]);
2514
+ const enterPresentModeFromBeginning = react.useCallback(() => {
2515
+ const first = chunkPCW2KT7Z_js.firstShowSlideIndex(visibleSlideIndexes);
2516
+ if (first !== void 0) {
2517
+ onSetActiveSlideIndex(first);
2518
+ }
2519
+ enterPresentMode();
2520
+ }, [visibleSlideIndexes, onSetActiveSlideIndex, enterPresentMode]);
2521
2521
  const enterPresenterView = react.useCallback(() => {
2522
2522
  setPresenterMode(true);
2523
2523
  setRehearsing(false);
@@ -2580,6 +2580,10 @@ function usePresentationMode(input) {
2580
2580
  scheduleAutoAdvanceRef.current = scheduleAutoAdvanceForSlide;
2581
2581
  const activeSlideIndexRef = react.useRef(activeSlideIndex);
2582
2582
  activeSlideIndexRef.current = activeSlideIndex;
2583
+ const visibleSlideIndexesRef = react.useRef(visibleSlideIndexes);
2584
+ visibleSlideIndexesRef.current = visibleSlideIndexes;
2585
+ const onSetActiveSlideIndexRef = react.useRef(onSetActiveSlideIndex);
2586
+ onSetActiveSlideIndexRef.current = onSetActiveSlideIndex;
2583
2587
  const presentationSlideIndexRef = react.useRef(presentationSlideIndex);
2584
2588
  presentationSlideIndexRef.current = presentationSlideIndex;
2585
2589
  const clearPresentationTimersRef = react.useRef(clearPresentationTimers);
@@ -2588,7 +2592,7 @@ function usePresentationMode(input) {
2588
2592
  if (mode !== "present") {
2589
2593
  return;
2590
2594
  }
2591
- return chunkFJDZ7AEE_js.attachPresentationVisibilityPause({
2595
+ return chunkPCW2KT7Z_js.attachPresentationVisibilityPause({
2592
2596
  root: containerRef.current ?? void 0,
2593
2597
  onHidden: () => clearPresentationTimersRef.current(),
2594
2598
  onVisible: () => scheduleAutoAdvanceRef.current(presentationSlideIndexRef.current)
@@ -2596,8 +2600,14 @@ function usePresentationMode(input) {
2596
2600
  }, [mode, containerRef]);
2597
2601
  react.useLayoutEffect(() => {
2598
2602
  if (mode === "present") {
2599
- const idx = activeSlideIndexRef.current;
2603
+ const idx = chunkPCW2KT7Z_js.presentationEntrySlideIndex(
2604
+ activeSlideIndexRef.current,
2605
+ visibleSlideIndexesRef.current
2606
+ );
2600
2607
  setPresentationSlideIndex(idx);
2608
+ if (idx !== activeSlideIndexRef.current) {
2609
+ onSetActiveSlideIndexRef.current(idx);
2610
+ }
2601
2611
  runEntranceAnimationsRef.current(idx);
2602
2612
  scheduleAutoAdvanceRef.current(idx);
2603
2613
  } else {
@@ -2668,13 +2678,18 @@ function usePresentationMode(input) {
2668
2678
  if (!transitionOverlay || transitionOverlay.transition.type !== "morph") {
2669
2679
  return void 0;
2670
2680
  }
2671
- return chunkFJDZ7AEE_js.buildMorphTransitionPlan(
2681
+ const incoming = slides[transitionOverlay.incomingSlideIndex];
2682
+ return chunkPCW2KT7Z_js.buildMorphTransitionPlan(
2672
2683
  slides[transitionOverlay.outgoingSlideIndex],
2673
- slides[transitionOverlay.incomingSlideIndex],
2684
+ incoming,
2674
2685
  transitionOverlay.durationMs,
2675
- chunkFJDZ7AEE_js.morphOptionToMode(transitionOverlay.transition.morphOption)
2686
+ chunkPCW2KT7Z_js.morphOptionToMode(transitionOverlay.transition.morphOption),
2687
+ // `PresentationStage` stacks the incoming slide's elements above its
2688
+ // template shapes (`zIndex = templateElements.length + index`), so a
2689
+ // z-index journey has to start counting where the stage does.
2690
+ { zIndexBase: incoming ? templateElementsBySlideId?.[incoming.id]?.length ?? 0 : 0 }
2676
2691
  );
2677
- }, [transitionOverlay, slides]);
2692
+ }, [transitionOverlay, slides, templateElementsBySlideId]);
2678
2693
  const morphedElementStates = react.useMemo(() => {
2679
2694
  if (!morphPlan || morphPlan.incomingAnimations.size === 0) {
2680
2695
  return presentationElementStates;
@@ -2693,7 +2708,7 @@ function usePresentationMode(input) {
2693
2708
  if (!morphPlan) {
2694
2709
  return presentationKeyframesCss;
2695
2710
  }
2696
- const imageRules = chunkFJDZ7AEE_js.buildMorphAnimationRules(morphPlan, "", "incoming", "image");
2711
+ const imageRules = chunkPCW2KT7Z_js.buildMorphAnimationRules(morphPlan, "", "incoming", "image");
2697
2712
  return `${presentationKeyframesCss ?? ""}
2698
2713
  ${morphPlan.keyframesCss}
2699
2714
  ${imageRules}`;
@@ -2723,6 +2738,7 @@ ${imageRules}`;
2723
2738
  handleHoverStart,
2724
2739
  handleHoverEnd,
2725
2740
  enterPresentMode,
2741
+ enterPresentModeFromBeginning,
2726
2742
  presenterMode,
2727
2743
  enterPresenterView,
2728
2744
  togglePresenterView,
@@ -2989,7 +3005,7 @@ function useFindReplace({
2989
3005
  const [findResults, setFindResults] = react.useState([]);
2990
3006
  const [findResultIndex, setFindResultIndex] = react.useState(-1);
2991
3007
  const performFind = react.useCallback(() => {
2992
- const results = chunkFJDZ7AEE_js.findInSlides(slides, findQuery, { matchCase: findMatchCase });
3008
+ const results = chunkPCW2KT7Z_js.findInSlides(slides, findQuery, { matchCase: findMatchCase });
2993
3009
  if (!findQuery) {
2994
3010
  setFindResults([]);
2995
3011
  setFindResultIndex(-1);
@@ -3023,7 +3039,7 @@ function useFindReplace({
3023
3039
  return;
3024
3040
  }
3025
3041
  onUpdateSlides(
3026
- (prevSlides) => chunkFJDZ7AEE_js.applyFindReplacements(prevSlides, toReplace, replaceQuery).slides
3042
+ (prevSlides) => chunkPCW2KT7Z_js.applyFindReplacements(prevSlides, toReplace, replaceQuery).slides
3027
3043
  );
3028
3044
  onMarkDirty();
3029
3045
  },
@@ -3045,9 +3061,9 @@ function useFindReplace({
3045
3061
  }, [findResults, applyReplacements, performFind]);
3046
3062
  react.useEffect(() => {
3047
3063
  const handler = (event) => {
3048
- const { action } = chunkFJDZ7AEE_js.mapEditorKey(event, {
3064
+ const { action } = chunkPCW2KT7Z_js.mapEditorKey(event, {
3049
3065
  canEdit: mode === "edit",
3050
- isTextInputTarget: chunkFJDZ7AEE_js.isEditorTextInputTarget(event.target)
3066
+ isTextInputTarget: chunkPCW2KT7Z_js.isEditorTextInputTarget(event.target)
3051
3067
  });
3052
3068
  if (action !== "find") {
3053
3069
  return;
@@ -3114,6 +3130,38 @@ function useModalDismissDrag(onClose, threshold = 120) {
3114
3130
  handlers: { onPointerDown, onPointerMove, onPointerUp, onPointerCancel: onPointerUp }
3115
3131
  };
3116
3132
  }
3133
+ function withoutKey(map, key) {
3134
+ if (!(key in map)) {
3135
+ return map;
3136
+ }
3137
+ const next = { ...map };
3138
+ delete next[key];
3139
+ return next;
3140
+ }
3141
+ function useCommentMentionDrafts() {
3142
+ const [commentDraftMentionsBySlideId, setCommentDraftMentionsBySlideId] = react.useState({});
3143
+ const [replyDraftMentionsByCommentId, setReplyDraftMentionsByCommentId] = react.useState({});
3144
+ const setCommentDraftMentions = react.useCallback((slideId, mentions) => {
3145
+ setCommentDraftMentionsBySlideId((prev) => ({ ...prev, [slideId]: mentions }));
3146
+ }, []);
3147
+ const setReplyDraftMentions = react.useCallback((commentId, mentions) => {
3148
+ setReplyDraftMentionsByCommentId((prev) => ({ ...prev, [commentId]: mentions }));
3149
+ }, []);
3150
+ const clearCommentDraftMentions = react.useCallback((slideId) => {
3151
+ setCommentDraftMentionsBySlideId((prev) => withoutKey(prev, slideId));
3152
+ }, []);
3153
+ const clearReplyDraftMentions = react.useCallback((commentId) => {
3154
+ setReplyDraftMentionsByCommentId((prev) => withoutKey(prev, commentId));
3155
+ }, []);
3156
+ return {
3157
+ commentDraftMentionsBySlideId,
3158
+ replyDraftMentionsByCommentId,
3159
+ setCommentDraftMentions,
3160
+ setReplyDraftMentions,
3161
+ clearCommentDraftMentions,
3162
+ clearReplyDraftMentions
3163
+ };
3164
+ }
3117
3165
 
3118
3166
  // src/viewer/hooks/useComments-helpers.ts
3119
3167
  function replaceCommentsOnSlide(slides, slideIndex, next) {
@@ -3121,12 +3169,12 @@ function replaceCommentsOnSlide(slides, slideIndex, next) {
3121
3169
  (entry, index) => index === slideIndex ? { ...entry, comments: next } : entry
3122
3170
  );
3123
3171
  }
3124
- function addCommentToSlide(slides, slideIndex, text, authorName, elementId) {
3172
+ function addCommentToSlide(slides, slideIndex, text, authorName, elementId, mentions) {
3125
3173
  const slide = slides[slideIndex];
3126
3174
  if (!slide) {
3127
3175
  return { slides, didAdd: false };
3128
3176
  }
3129
- const next = chunkFJDZ7AEE_js.addCommentToList(
3177
+ const next = chunkPCW2KT7Z_js.addCommentToList(
3130
3178
  slide.comments || [],
3131
3179
  text,
3132
3180
  authorName,
@@ -3137,14 +3185,17 @@ function addCommentToSlide(slides, slideIndex, text, authorName, elementId) {
3137
3185
  if (!next) {
3138
3186
  return { slides, didAdd: false };
3139
3187
  }
3140
- return { slides: replaceCommentsOnSlide(slides, slideIndex, next), didAdd: true };
3188
+ const withMentions = mentions && mentions.length > 0 ? next.map(
3189
+ (comment, index) => index === next.length - 1 ? { ...comment, mentions } : comment
3190
+ ) : next;
3191
+ return { slides: replaceCommentsOnSlide(slides, slideIndex, withMentions), didAdd: true };
3141
3192
  }
3142
3193
  function removeCommentFromSlide(slides, slideIndex, commentId) {
3143
3194
  const slide = slides[slideIndex];
3144
3195
  if (!slide) {
3145
3196
  return { slides, didDelete: false };
3146
3197
  }
3147
- const next = chunkFJDZ7AEE_js.removeCommentFromList(slide.comments || [], commentId);
3198
+ const next = chunkPCW2KT7Z_js.removeCommentFromList(slide.comments || [], commentId);
3148
3199
  if (!next) {
3149
3200
  return { slides, didDelete: false };
3150
3201
  }
@@ -3155,7 +3206,7 @@ function editCommentInSlide(slides, slideIndex, commentId, newText) {
3155
3206
  if (!slide) {
3156
3207
  return { slides, didUpdate: false };
3157
3208
  }
3158
- const next = chunkFJDZ7AEE_js.editCommentInList(slide.comments || [], commentId, newText);
3209
+ const next = chunkPCW2KT7Z_js.editCommentInList(slide.comments || [], commentId, newText);
3159
3210
  if (!next) {
3160
3211
  return { slides, didUpdate: false };
3161
3212
  }
@@ -3166,22 +3217,30 @@ function toggleResolvedInSlide(slides, slideIndex, commentId) {
3166
3217
  if (!slide) {
3167
3218
  return { slides, didUpdate: false };
3168
3219
  }
3169
- const next = chunkFJDZ7AEE_js.toggleCommentResolvedInList(slide.comments || [], commentId);
3220
+ const next = chunkPCW2KT7Z_js.toggleCommentResolvedInList(slide.comments || [], commentId);
3170
3221
  if (!next) {
3171
3222
  return { slides, didUpdate: false };
3172
3223
  }
3173
3224
  return { slides: replaceCommentsOnSlide(slides, slideIndex, next), didUpdate: true };
3174
3225
  }
3175
- function addReplyToSlide(slides, slideIndex, parentId, text, authorName) {
3226
+ function addReplyToSlide(slides, slideIndex, parentId, text, authorName, mentions) {
3176
3227
  const slide = slides[slideIndex];
3177
3228
  if (!slide) {
3178
3229
  return { slides, didAdd: false };
3179
3230
  }
3180
- const next = chunkFJDZ7AEE_js.replyToCommentInList(slide.comments || [], parentId, text, authorName);
3231
+ const next = chunkPCW2KT7Z_js.replyToCommentInList(slide.comments || [], parentId, text, authorName);
3181
3232
  if (!next) {
3182
3233
  return { slides, didAdd: false };
3183
3234
  }
3184
- return { slides: replaceCommentsOnSlide(slides, slideIndex, next), didAdd: true };
3235
+ const withMentions = mentions && mentions.length > 0 ? next.map(
3236
+ (comment) => comment.id === parentId && comment.replies && comment.replies.length > 0 ? {
3237
+ ...comment,
3238
+ replies: comment.replies.map(
3239
+ (reply, index) => index === comment.replies.length - 1 ? { ...reply, mentions } : reply
3240
+ )
3241
+ } : comment
3242
+ ) : next;
3243
+ return { slides: replaceCommentsOnSlide(slides, slideIndex, withMentions), didAdd: true };
3185
3244
  }
3186
3245
  function pruneSlideDrafts(drafts, slideIds) {
3187
3246
  const next = {};
@@ -3196,6 +3255,95 @@ function pruneSlideDrafts(drafts, slideIds) {
3196
3255
  return changed ? next : null;
3197
3256
  }
3198
3257
 
3258
+ // src/viewer/hooks/useCommentReplyHandlers.ts
3259
+ function useCommentReplyHandlers(input) {
3260
+ const {
3261
+ slides,
3262
+ canEdit,
3263
+ userName,
3264
+ onUpdateSlides,
3265
+ onMarkDirty,
3266
+ replyDraftMentionsByCommentId,
3267
+ setReplyDraftMentions,
3268
+ clearReplyDraftMentions
3269
+ } = input;
3270
+ const [replyDraftByCommentId, setReplyDraftByCommentId] = react.useState({});
3271
+ const [replyingToCommentId, setReplyingToCommentId] = react.useState(null);
3272
+ const handleStartReply = react.useCallback((_slideIndex, commentId) => {
3273
+ setReplyingToCommentId(commentId);
3274
+ setReplyDraftByCommentId((prev) => ({ ...prev, [commentId]: "" }));
3275
+ }, []);
3276
+ const handleCancelReply = react.useCallback(() => {
3277
+ setReplyingToCommentId(null);
3278
+ }, []);
3279
+ const handleReplyDraftChange = react.useCallback(
3280
+ (commentId, draft, mentions) => {
3281
+ setReplyDraftByCommentId((prev) => ({ ...prev, [commentId]: draft }));
3282
+ if (mentions) {
3283
+ setReplyDraftMentions(commentId, mentions);
3284
+ }
3285
+ },
3286
+ [setReplyDraftMentions]
3287
+ );
3288
+ const handleSubmitReply = react.useCallback(
3289
+ (slideIndex, commentId) => {
3290
+ if (!canEdit) {
3291
+ return;
3292
+ }
3293
+ const slide = slides[slideIndex];
3294
+ if (!slide) {
3295
+ return;
3296
+ }
3297
+ const replyText = String(replyDraftByCommentId[commentId] || "").trim();
3298
+ if (replyText.length === 0) {
3299
+ return;
3300
+ }
3301
+ let didAdd = false;
3302
+ onUpdateSlides((prev) => {
3303
+ const result = addReplyToSlide(
3304
+ prev,
3305
+ slideIndex,
3306
+ commentId,
3307
+ replyText,
3308
+ userName,
3309
+ replyDraftMentionsByCommentId[commentId]
3310
+ );
3311
+ didAdd = result.didAdd;
3312
+ return result.slides;
3313
+ });
3314
+ if (!didAdd) {
3315
+ return;
3316
+ }
3317
+ setReplyingToCommentId(null);
3318
+ setReplyDraftByCommentId((prev) => {
3319
+ const next = { ...prev };
3320
+ delete next[commentId];
3321
+ return next;
3322
+ });
3323
+ clearReplyDraftMentions(commentId);
3324
+ onMarkDirty();
3325
+ },
3326
+ [
3327
+ canEdit,
3328
+ onMarkDirty,
3329
+ onUpdateSlides,
3330
+ replyDraftByCommentId,
3331
+ replyDraftMentionsByCommentId,
3332
+ clearReplyDraftMentions,
3333
+ slides,
3334
+ userName
3335
+ ]
3336
+ );
3337
+ return {
3338
+ replyingToCommentId,
3339
+ replyDraftByCommentId,
3340
+ handleStartReply,
3341
+ handleCancelReply,
3342
+ handleReplyDraftChange,
3343
+ handleSubmitReply
3344
+ };
3345
+ }
3346
+
3199
3347
  // src/viewer/hooks/useComments.ts
3200
3348
  function useComments({
3201
3349
  slides,
@@ -3208,11 +3356,33 @@ function useComments({
3208
3356
  const [commentDraftBySlideId, setCommentDraftBySlideId] = react.useState({});
3209
3357
  const [editingCommentIdBySlideId, setEditingCommentIdBySlideId] = react.useState({});
3210
3358
  const [commentEditDraftByCommentId, setCommentEditDraftByCommentId] = react.useState({});
3211
- const [replyDraftByCommentId, setReplyDraftByCommentId] = react.useState({});
3212
- const [replyingToCommentId, setReplyingToCommentId] = react.useState(null);
3213
- const handleCommentDraftChange = react.useCallback((slideId, draft) => {
3214
- setCommentDraftBySlideId((prev) => ({ ...prev, [slideId]: draft }));
3215
- }, []);
3359
+ const {
3360
+ commentDraftMentionsBySlideId,
3361
+ replyDraftMentionsByCommentId,
3362
+ setCommentDraftMentions,
3363
+ setReplyDraftMentions,
3364
+ clearCommentDraftMentions,
3365
+ clearReplyDraftMentions
3366
+ } = useCommentMentionDrafts();
3367
+ const reply = useCommentReplyHandlers({
3368
+ slides,
3369
+ canEdit,
3370
+ userName,
3371
+ onUpdateSlides,
3372
+ onMarkDirty,
3373
+ replyDraftMentionsByCommentId,
3374
+ setReplyDraftMentions,
3375
+ clearReplyDraftMentions
3376
+ });
3377
+ const handleCommentDraftChange = react.useCallback(
3378
+ (slideId, draft, mentions) => {
3379
+ setCommentDraftBySlideId((prev) => ({ ...prev, [slideId]: draft }));
3380
+ if (mentions) {
3381
+ setCommentDraftMentions(slideId, mentions);
3382
+ }
3383
+ },
3384
+ [setCommentDraftMentions]
3385
+ );
3216
3386
  const handleSetCommentEditDraft = react.useCallback((commentId, draft) => {
3217
3387
  setCommentEditDraftByCommentId((prev) => ({
3218
3388
  ...prev,
@@ -3239,7 +3409,8 @@ function useComments({
3239
3409
  slideIndex,
3240
3410
  draft,
3241
3411
  userName,
3242
- selectedElementId ?? void 0
3412
+ selectedElementId ?? void 0,
3413
+ commentDraftMentionsBySlideId[slide.id]
3243
3414
  );
3244
3415
  didAdd = result.didAdd;
3245
3416
  return result.slides;
@@ -3251,11 +3422,14 @@ function useComments({
3251
3422
  ...prev,
3252
3423
  [slide.id]: ""
3253
3424
  }));
3425
+ clearCommentDraftMentions(slide.id);
3254
3426
  onMarkDirty();
3255
3427
  },
3256
3428
  [
3257
3429
  canEdit,
3258
3430
  commentDraftBySlideId,
3431
+ commentDraftMentionsBySlideId,
3432
+ clearCommentDraftMentions,
3259
3433
  onMarkDirty,
3260
3434
  onUpdateSlides,
3261
3435
  selectedElementId,
@@ -3367,48 +3541,6 @@ function useComments({
3367
3541
  },
3368
3542
  [canEdit, onMarkDirty, onUpdateSlides, slides]
3369
3543
  );
3370
- const handleStartReply = react.useCallback((_slideIndex, commentId) => {
3371
- setReplyingToCommentId(commentId);
3372
- setReplyDraftByCommentId((prev) => ({ ...prev, [commentId]: "" }));
3373
- }, []);
3374
- const handleCancelReply = react.useCallback(() => {
3375
- setReplyingToCommentId(null);
3376
- }, []);
3377
- const handleReplyDraftChange = react.useCallback((commentId, draft) => {
3378
- setReplyDraftByCommentId((prev) => ({ ...prev, [commentId]: draft }));
3379
- }, []);
3380
- const handleSubmitReply = react.useCallback(
3381
- (slideIndex, commentId) => {
3382
- if (!canEdit) {
3383
- return;
3384
- }
3385
- const slide = slides[slideIndex];
3386
- if (!slide) {
3387
- return;
3388
- }
3389
- const replyText = String(replyDraftByCommentId[commentId] || "").trim();
3390
- if (replyText.length === 0) {
3391
- return;
3392
- }
3393
- let didAdd = false;
3394
- onUpdateSlides((prev) => {
3395
- const result = addReplyToSlide(prev, slideIndex, commentId, replyText, userName);
3396
- didAdd = result.didAdd;
3397
- return result.slides;
3398
- });
3399
- if (!didAdd) {
3400
- return;
3401
- }
3402
- setReplyingToCommentId(null);
3403
- setReplyDraftByCommentId((prev) => {
3404
- const next = { ...prev };
3405
- delete next[commentId];
3406
- return next;
3407
- });
3408
- onMarkDirty();
3409
- },
3410
- [canEdit, onMarkDirty, onUpdateSlides, replyDraftByCommentId, slides, userName]
3411
- );
3412
3544
  react.useEffect(() => {
3413
3545
  const slideIds = new Set(slides.map((slide) => slide.id));
3414
3546
  setCommentDraftBySlideId((prev) => {
@@ -3420,8 +3552,8 @@ function useComments({
3420
3552
  commentDraftBySlideId,
3421
3553
  editingCommentIdBySlideId,
3422
3554
  commentEditDraftByCommentId,
3423
- replyingToCommentId,
3424
- replyDraftByCommentId,
3555
+ commentDraftMentionsBySlideId,
3556
+ replyDraftMentionsByCommentId,
3425
3557
  handleCommentDraftChange,
3426
3558
  handleAddSlideComment,
3427
3559
  handleDeleteSlideComment,
@@ -3430,10 +3562,7 @@ function useComments({
3430
3562
  handleSaveCommentEdit,
3431
3563
  handleSetCommentEditDraft,
3432
3564
  handleToggleCommentResolved,
3433
- handleStartReply,
3434
- handleCancelReply,
3435
- handleReplyDraftChange,
3436
- handleSubmitReply
3565
+ ...reply
3437
3566
  };
3438
3567
  }
3439
3568
  function buildElementLookup(templateElements, slideElements) {
@@ -3551,7 +3680,7 @@ function useViewerCoreState(_input) {
3551
3680
  const marqueeStateRef = react.useRef(null);
3552
3681
  const isDrawingRef = react.useRef(false);
3553
3682
  const justInteractedRef = react.useRef(false);
3554
- const livePatcher = react.useMemo(() => chunkFJDZ7AEE_js.createCollaborationLivePatcher(), []);
3683
+ const livePatcher = react.useMemo(() => chunkPCW2KT7Z_js.createCollaborationLivePatcher(), []);
3555
3684
  react.useEffect(() => () => livePatcher.dispose(), [livePatcher]);
3556
3685
  const slidesRef = react.useRef([]);
3557
3686
  const [mode, setMode] = react.useState("edit");
@@ -3560,8 +3689,8 @@ function useViewerCoreState(_input) {
3560
3689
  const [slides, setSlides] = react.useState([]);
3561
3690
  const [templateElementsBySlideId, setTemplateElementsBySlideId] = react.useState({});
3562
3691
  const [canvasSize, setCanvasSize] = react.useState({
3563
- width: chunkB6UIVRFA_js.DEFAULT_CANVAS_WIDTH,
3564
- height: chunkB6UIVRFA_js.DEFAULT_CANVAS_HEIGHT
3692
+ width: chunkXBTHWXNO_js.DEFAULT_CANVAS_WIDTH,
3693
+ height: chunkXBTHWXNO_js.DEFAULT_CANVAS_HEIGHT
3565
3694
  });
3566
3695
  const [slideSizeEmu, setSlideSizeEmu] = react.useState();
3567
3696
  const [activeSlideIndex, setActiveSlideIndex] = react.useState(0);
@@ -3582,7 +3711,7 @@ function useViewerCoreState(_input) {
3582
3711
  const resolved = typeof value === "function" ? value(inlineEditingTextRef.current) : value;
3583
3712
  inlineEditingTextRef.current = resolved;
3584
3713
  setInlineEditingTextBase(value);
3585
- chunkFJDZ7AEE_js.publishLiveInlineText(
3714
+ chunkPCW2KT7Z_js.publishLiveInlineText(
3586
3715
  livePatcher,
3587
3716
  slidesRef.current[activeSlideIndexRef.current],
3588
3717
  inlineEditingElementIdRef.current,
@@ -3598,6 +3727,8 @@ function useViewerCoreState(_input) {
3598
3727
  const [headerFooter, setHeaderFooter] = react.useState({});
3599
3728
  const [layoutOptions, setLayoutOptions] = react.useState([]);
3600
3729
  const [slideMasters, setSlideMasters] = react.useState([]);
3730
+ const [modernCommentAuthors, setModernCommentAuthors] = react.useState([]);
3731
+ const [recentColors, setRecentColors] = react.useState([]);
3601
3732
  const [theme, setTheme] = react.useState();
3602
3733
  const [tableStyleMap, setTableStyleMap] = react.useState();
3603
3734
  const [themeOptions, setThemeOptions] = react.useState([]);
@@ -3691,6 +3822,10 @@ function useViewerCoreState(_input) {
3691
3822
  setLayoutOptions,
3692
3823
  slideMasters,
3693
3824
  setSlideMasters,
3825
+ modernCommentAuthors,
3826
+ setModernCommentAuthors,
3827
+ recentColors,
3828
+ setRecentColors,
3694
3829
  theme,
3695
3830
  setTheme,
3696
3831
  tableStyleMap,
@@ -3875,6 +4010,8 @@ function useLoadContent({
3875
4010
  setHeaderFooter,
3876
4011
  setLayoutOptions,
3877
4012
  setSlideMasters,
4013
+ setModernCommentAuthors,
4014
+ setRecentColors,
3878
4015
  setTheme,
3879
4016
  setTableStyleMap,
3880
4017
  setThemeOptions,
@@ -3896,6 +4033,8 @@ function useLoadContent({
3896
4033
  setHasDigitalSignatures,
3897
4034
  setDigitalSignatureCount,
3898
4035
  setGuides,
4036
+ setReadOnlyRecommendation,
4037
+ setCompatToasts,
3899
4038
  setLoading,
3900
4039
  setError,
3901
4040
  setIsDirty,
@@ -3926,7 +4065,7 @@ function useLoadContent({
3926
4065
  );
3927
4066
  }
3928
4067
  const previousHandler = handlerRef.current;
3929
- const handler = new chunkFJDZ7AEE_js.PptxHandler();
4068
+ const handler = new chunkPCW2KT7Z_js.PptxHandler();
3930
4069
  const parsed = await handler.load(buffer, { allowExternalImages });
3931
4070
  if (cancelled || token !== renderTokenRef.current) {
3932
4071
  handler.dispose();
@@ -3938,7 +4077,7 @@ function useLoadContent({
3938
4077
  handlerRef.current = null;
3939
4078
  const mediaElements = [];
3940
4079
  for (const slide of parsed.slides) {
3941
- chunkFJDZ7AEE_js.collectMediaElements(slide.elements, mediaElements);
4080
+ chunkPCW2KT7Z_js.collectMediaElements(slide.elements, mediaElements);
3942
4081
  }
3943
4082
  for (const url of mediaDataUrls.values()) {
3944
4083
  if (url.startsWith("blob:")) {
@@ -3979,7 +4118,7 @@ function useLoadContent({
3979
4118
  }
3980
4119
  })
3981
4120
  );
3982
- const { paths: imagePaths, refs: imageRefs } = chunkFJDZ7AEE_js.collectImagePaths(parsed.slides);
4121
+ const { paths: imagePaths, refs: imageRefs } = chunkPCW2KT7Z_js.collectImagePaths(parsed.slides);
3983
4122
  let nextSlides = parsed.slides;
3984
4123
  if (imagePaths.size > 0) {
3985
4124
  const resolvedMap = /* @__PURE__ */ new Map();
@@ -3994,100 +4133,26 @@ function useLoadContent({
3994
4133
  }
3995
4134
  })
3996
4135
  );
3997
- const elementPatches = /* @__PURE__ */ new Map();
3998
- for (const ref of imageRefs) {
3999
- const url = resolvedMap.get(ref.path);
4000
- if (!url) {
4001
- continue;
4002
- }
4003
- const id = ref.element.id;
4004
- const existing = elementPatches.get(id) ?? {};
4005
- existing[ref.field] = url;
4006
- elementPatches.set(id, existing);
4007
- }
4008
- if (elementPatches.size > 0) {
4009
- const patchElements = (elements) => {
4010
- let mutated = false;
4011
- const next = elements.map((el) => {
4012
- let updated = el;
4013
- const patch = elementPatches.get(el.id);
4014
- if (patch) {
4015
- updated = { ...el, ...patch };
4016
- }
4017
- if (updated.type === "group" && updated.children?.length) {
4018
- const newChildren = patchElements(updated.children);
4019
- if (newChildren !== updated.children) {
4020
- updated = { ...updated, children: newChildren };
4021
- }
4022
- }
4023
- if (updated !== el) {
4024
- mutated = true;
4025
- }
4026
- return updated;
4027
- });
4028
- return mutated ? next : elements;
4029
- };
4030
- nextSlides = parsed.slides.map((s) => {
4031
- const newElements = patchElements(s.elements);
4032
- return newElements === s.elements ? s : { ...s, elements: newElements };
4033
- });
4034
- }
4035
- }
4036
- const { paths: tableImagePaths, refs: tableImageRefs } = chunkFJDZ7AEE_js.collectTableCellImagePaths(nextSlides);
4037
- if (tableImagePaths.size > 0) {
4038
- const resolvedTableMap = /* @__PURE__ */ new Map();
4039
- await Promise.all(
4040
- Array.from(tableImagePaths).map(async (path) => {
4041
- try {
4042
- const url = await handler.getImageData(path);
4043
- if (url) {
4044
- resolvedTableMap.set(path, url);
4045
- }
4046
- } catch {
4047
- }
4048
- })
4049
- );
4050
- if (resolvedTableMap.size > 0) {
4051
- nextSlides = nextSlides.map((s) => {
4052
- const newElements = chunkFJDZ7AEE_js.applyTableCellImagePatches(
4053
- s.elements,
4054
- resolvedTableMap,
4055
- tableImageRefs
4056
- );
4057
- return newElements === s.elements ? s : { ...s, elements: newElements };
4058
- });
4059
- }
4060
- }
4061
- let nextTableStyleMap = parsed.tableStyleMap;
4062
- const { paths: tableStyleImagePaths, refs: tableStyleImageRefs } = chunkFJDZ7AEE_js.collectTableStyleImagePaths(nextTableStyleMap);
4063
- if (tableStyleImagePaths.size > 0) {
4064
- const resolvedStyleMap = /* @__PURE__ */ new Map();
4065
- await Promise.all(
4066
- Array.from(tableStyleImagePaths).map(async (path) => {
4067
- try {
4068
- const url = await handler.getImageData(path);
4069
- if (url) {
4070
- resolvedStyleMap.set(path, url);
4071
- }
4072
- } catch {
4073
- }
4074
- })
4075
- );
4076
- if (resolvedStyleMap.size > 0 && nextTableStyleMap) {
4077
- nextTableStyleMap = chunkFJDZ7AEE_js.applyTableStyleImagePatches(
4078
- nextTableStyleMap,
4079
- resolvedStyleMap,
4080
- tableStyleImageRefs
4081
- );
4082
- }
4136
+ nextSlides = parsed.slides.map((s) => {
4137
+ const newElements = chunkPCW2KT7Z_js.applyImagePathPatches(s.elements, resolvedMap, imageRefs);
4138
+ return newElements === s.elements ? s : { ...s, elements: newElements };
4139
+ });
4083
4140
  }
4141
+ nextSlides = await chunkPCW2KT7Z_js.resolveTableCellImageUrls(
4142
+ nextSlides,
4143
+ (path) => handler.getImageData(path)
4144
+ );
4145
+ const nextTableStyleMap = await chunkPCW2KT7Z_js.resolveTableStyleImageUrls(
4146
+ parsed.tableStyleMap,
4147
+ (path) => handler.getImageData(path)
4148
+ );
4084
4149
  handlerRef.current = handler;
4085
- const partition = chunkFJDZ7AEE_js.partitionTemplateElements(nextSlides);
4150
+ const partition = chunkPCW2KT7Z_js.partitionTemplateElements(nextSlides);
4086
4151
  setSlides(partition.slides);
4087
4152
  setTemplateElementsBySlideId(partition.templateElementsBySlideId);
4088
4153
  setCanvasSize({
4089
- width: parsed.width ?? chunkB6UIVRFA_js.DEFAULT_CANVAS_WIDTH,
4090
- height: parsed.height ?? chunkB6UIVRFA_js.DEFAULT_CANVAS_HEIGHT
4154
+ width: parsed.width ?? chunkXBTHWXNO_js.DEFAULT_CANVAS_WIDTH,
4155
+ height: parsed.height ?? chunkXBTHWXNO_js.DEFAULT_CANVAS_HEIGHT
4091
4156
  });
4092
4157
  setSlideSizeEmu(
4093
4158
  typeof parsed.widthEmu === "number" && typeof parsed.heightEmu === "number" && parsed.widthEmu > 0 && parsed.heightEmu > 0 ? {
@@ -4099,12 +4164,14 @@ function useLoadContent({
4099
4164
  setHeaderFooter(parsed.headerFooter ?? {});
4100
4165
  setLayoutOptions(parsed.layoutOptions ?? []);
4101
4166
  setSlideMasters(parsed.slideMasters ?? []);
4167
+ setModernCommentAuthors(parsed.modernCommentAuthors ?? []);
4168
+ setRecentColors(chunkPCW2KT7Z_js.seedRecentColors({ mruColors: parsed.mruColors }));
4102
4169
  setTheme(parsed.theme);
4103
4170
  setTableStyleMap(nextTableStyleMap);
4104
4171
  setThemeOptions(parsed.themeOptions ?? []);
4105
4172
  setCustomShows(parsed.customShows ?? []);
4106
4173
  setActiveCustomShowId(
4107
- chunkFJDZ7AEE_js.resolveAuthoredCustomShowId(parsed.presentationProperties, parsed.customShows) ?? null
4174
+ chunkPCW2KT7Z_js.resolveAuthoredCustomShowId(parsed.presentationProperties, parsed.customShows) ?? null
4108
4175
  );
4109
4176
  setSections(parsed.sections ?? []);
4110
4177
  setPresentationProperties(parsed.presentationProperties ?? {});
@@ -4127,7 +4194,14 @@ function useLoadContent({
4127
4194
  setHasMacros(parsed.hasMacros === true);
4128
4195
  setHasDigitalSignatures(parsed.hasDigitalSignatures === true);
4129
4196
  setDigitalSignatureCount(parsed.digitalSignatureCount ?? 0);
4130
- setGuides(chunkFJDZ7AEE_js.buildInitialGuides(parsed.presentationGuides, parsed.slides[0]?.guides));
4197
+ setGuides(chunkPCW2KT7Z_js.buildInitialGuides(parsed.presentationGuides, parsed.slides[0]?.guides));
4198
+ setReadOnlyRecommendation(chunkPCW2KT7Z_js.readOnlyRecommendation(parsed));
4199
+ setCompatToasts(
4200
+ chunkPCW2KT7Z_js.compatibilityWarningToasts([
4201
+ ...parsed.warnings ?? [],
4202
+ ...parsed.slides.flatMap((slide) => slide.warnings ?? [])
4203
+ ])
4204
+ );
4131
4205
  setActiveSlideIndex(0);
4132
4206
  clearSelection();
4133
4207
  setIsDirty(false);
@@ -4135,7 +4209,7 @@ function useLoadContent({
4135
4209
  onContentApplied?.();
4136
4210
  } catch (err) {
4137
4211
  if (!cancelled && token === renderTokenRef.current) {
4138
- if (err instanceof chunkFJDZ7AEE_js.EncryptedFileError) {
4212
+ if (err instanceof chunkPCW2KT7Z_js.EncryptedFileError) {
4139
4213
  setIsEncrypted(true);
4140
4214
  } else {
4141
4215
  console.error("[pptx] Failed to load presentation content:", err);
@@ -4163,7 +4237,7 @@ function useLoadContent({
4163
4237
  }
4164
4238
  function useAutosave(input) {
4165
4239
  const { isDirty, filePath, serializeSlides, enabled = true, getChangeSources } = input;
4166
- const intervalMs = chunkFJDZ7AEE_js.resolveAutosaveIntervalMs({
4240
+ const intervalMs = chunkPCW2KT7Z_js.resolveAutosaveIntervalMs({
4167
4241
  hostIntervalMs: input.intervalMs,
4168
4242
  optionsIntervalSeconds: input.intervalSeconds
4169
4243
  });
@@ -4194,7 +4268,7 @@ function useAutosave(input) {
4194
4268
  return;
4195
4269
  }
4196
4270
  const sources = changeSourcesRef.current?.() ?? [];
4197
- if (!chunkFJDZ7AEE_js.shouldWriteAutosaveSnapshot({
4271
+ if (!chunkPCW2KT7Z_js.shouldWriteAutosaveSnapshot({
4198
4272
  filePath: path,
4199
4273
  isDirty: isDirtyRef.current,
4200
4274
  saving: isSavingRef.current,
@@ -4212,8 +4286,8 @@ function useAutosave(input) {
4212
4286
  isSavingRef.current = false;
4213
4287
  return;
4214
4288
  }
4215
- await chunkFJDZ7AEE_js.saveAutosaveSnapshot(path, data);
4216
- lastSnapshotRef.current = chunkFJDZ7AEE_js.autosaveSnapshotMark(path, sources);
4289
+ await chunkPCW2KT7Z_js.saveAutosaveSnapshot(path, data);
4290
+ lastSnapshotRef.current = chunkPCW2KT7Z_js.autosaveSnapshotMark(path, sources);
4217
4291
  setAutosaveStatus({ state: "saved", timestamp: Date.now() });
4218
4292
  } catch (err) {
4219
4293
  setAutosaveStatus({
@@ -4299,11 +4373,11 @@ function useElementOperations(input) {
4299
4373
  (elementId, updates) => {
4300
4374
  if (masterView?.target) {
4301
4375
  applyMasterViewWrite(
4302
- chunkFJDZ7AEE_js.updateMasterViewElement(masterView, masterView.target, elementId, updates)
4376
+ chunkPCW2KT7Z_js.updateMasterViewElement(masterView, masterView.target, elementId, updates)
4303
4377
  );
4304
4378
  return;
4305
4379
  }
4306
- if (chunkFJDZ7AEE_js.isTemplateElementId(elementId)) {
4380
+ if (chunkPCW2KT7Z_js.isTemplateElementId(elementId)) {
4307
4381
  const slideId = activeSlide?.id;
4308
4382
  if (slideId) {
4309
4383
  setTemplateElementsBySlideId((prev) => ({
@@ -4314,19 +4388,7 @@ function useElementOperations(input) {
4314
4388
  }));
4315
4389
  }
4316
4390
  } else {
4317
- setSlides(
4318
- (prev) => prev.map(
4319
- (s, i) => i !== activeSlideIndex ? s : {
4320
- ...s,
4321
- elements: s.elements.map(
4322
- (el) => el.id === elementId ? {
4323
- ...el,
4324
- ...updates
4325
- } : el
4326
- )
4327
- }
4328
- )
4329
- );
4391
+ setSlides((prev) => chunkPCW2KT7Z_js.updateElement(prev, activeSlideIndex, elementId, updates));
4330
4392
  }
4331
4393
  history.markDirty();
4332
4394
  },
@@ -4351,7 +4413,7 @@ function useElementOperations(input) {
4351
4413
  );
4352
4414
  const updateSelectedShapeStyle = react.useCallback(
4353
4415
  (updates) => {
4354
- if (!selectedElement || !chunkFJDZ7AEE_js.hasShapeProperties(selectedElement)) {
4416
+ if (!selectedElement || !chunkPCW2KT7Z_js.hasShapeProperties(selectedElement)) {
4355
4417
  return;
4356
4418
  }
4357
4419
  updateSelectedElement({
@@ -4362,17 +4424,17 @@ function useElementOperations(input) {
4362
4424
  );
4363
4425
  const updateSelectedTextStyle = react.useCallback(
4364
4426
  (updates) => {
4365
- if (!selectedElement || !chunkFJDZ7AEE_js.hasTextProperties(selectedElement)) {
4427
+ if (!selectedElement || !chunkPCW2KT7Z_js.hasTextProperties(selectedElement)) {
4366
4428
  return;
4367
4429
  }
4368
- const inlineSel = chunkFJDZ7AEE_js.getInlineEditorSelection(selectedElement.textSegments);
4430
+ const inlineSel = chunkPCW2KT7Z_js.getInlineEditorSelection(selectedElement.textSegments);
4369
4431
  if (inlineSel && selectedElement.textSegments) {
4370
- const { newSegments: newSegments2, newSelection } = chunkFJDZ7AEE_js.applyStyleToSelectedSegments(
4432
+ const { newSegments: newSegments2, newSelection } = chunkPCW2KT7Z_js.applyStyleToSelectedSegments(
4371
4433
  selectedElement.textSegments,
4372
4434
  inlineSel,
4373
4435
  updates
4374
4436
  );
4375
- chunkFJDZ7AEE_js.setPendingSelectionRestore(newSelection);
4437
+ chunkPCW2KT7Z_js.setPendingSelectionRestore(newSelection);
4376
4438
  updateSelectedElement({
4377
4439
  textSegments: newSegments2
4378
4440
  });
@@ -4392,12 +4454,12 @@ function useElementOperations(input) {
4392
4454
  );
4393
4455
  const updateSelectedTextCase = react.useCallback(
4394
4456
  (mode) => {
4395
- if (!selectedElement || !chunkFJDZ7AEE_js.hasTextProperties(selectedElement)) {
4457
+ if (!selectedElement || !chunkPCW2KT7Z_js.hasTextProperties(selectedElement)) {
4396
4458
  return;
4397
4459
  }
4398
- const inlineSel = chunkFJDZ7AEE_js.getInlineEditorSelection(selectedElement.textSegments);
4460
+ const inlineSel = chunkPCW2KT7Z_js.getInlineEditorSelection(selectedElement.textSegments);
4399
4461
  if (inlineSel && selectedElement.textSegments) {
4400
- const newSegments = chunkFJDZ7AEE_js.applyCaseTransformToSegments(
4462
+ const newSegments = chunkPCW2KT7Z_js.applyCaseTransformToSegments(
4401
4463
  selectedElement.textSegments,
4402
4464
  inlineSel,
4403
4465
  mode
@@ -4407,14 +4469,14 @@ function useElementOperations(input) {
4407
4469
  }
4408
4470
  const updates = {};
4409
4471
  if (selectedElement.textSegments && selectedElement.textSegments.length > 0) {
4410
- updates.textSegments = chunkFJDZ7AEE_js.applyCaseTransformToSegments(
4472
+ updates.textSegments = chunkPCW2KT7Z_js.applyCaseTransformToSegments(
4411
4473
  selectedElement.textSegments,
4412
4474
  null,
4413
4475
  mode
4414
4476
  );
4415
4477
  }
4416
4478
  if (typeof selectedElement.text === "string") {
4417
- updates.text = chunkFJDZ7AEE_js.transformTextCase(selectedElement.text, mode);
4479
+ updates.text = chunkPCW2KT7Z_js.transformTextCase(selectedElement.text, mode);
4418
4480
  }
4419
4481
  updateSelectedElement(updates);
4420
4482
  },
@@ -4427,15 +4489,15 @@ function useElementOperations(input) {
4427
4489
  [setSlides]
4428
4490
  );
4429
4491
  const masterViewTarget = masterView?.target ?? null;
4430
- const activeElements = masterViewTarget ? chunkFJDZ7AEE_js.masterViewElements(masterView, masterViewTarget) : editTemplateMode ? templateElements : activeSlide?.elements ?? [];
4492
+ const activeElements = masterViewTarget ? chunkPCW2KT7Z_js.masterViewElements(masterView, masterViewTarget) : editTemplateMode ? templateElements : activeSlide?.elements ?? [];
4431
4493
  const updateActiveElements = react.useCallback(
4432
4494
  (updater) => {
4433
4495
  if (masterView?.target) {
4434
4496
  applyMasterViewWrite(
4435
- chunkFJDZ7AEE_js.replaceMasterViewElements(
4497
+ chunkPCW2KT7Z_js.replaceMasterViewElements(
4436
4498
  masterView,
4437
4499
  masterView.target,
4438
- updater(chunkFJDZ7AEE_js.masterViewElements(masterView, masterView.target))
4500
+ updater(chunkPCW2KT7Z_js.masterViewElements(masterView, masterView.target))
4439
4501
  )
4440
4502
  );
4441
4503
  return;
@@ -4488,7 +4550,7 @@ function useSectionOperations(input) {
4488
4550
  const { sections, setSections, slides, setSlides, markDirty } = input;
4489
4551
  const addSection2 = react.useCallback(
4490
4552
  (name, afterSlideIndex) => {
4491
- const result = chunkFJDZ7AEE_js.addSection(sections, slides, name, afterSlideIndex);
4553
+ const result = chunkPCW2KT7Z_js.addSection(sections, slides, name, afterSlideIndex);
4492
4554
  setSlides(result.slides);
4493
4555
  setSections(result.sections);
4494
4556
  markDirty();
@@ -4497,7 +4559,7 @@ function useSectionOperations(input) {
4497
4559
  );
4498
4560
  const renameSection2 = react.useCallback(
4499
4561
  (sectionId, newName) => {
4500
- const result = chunkFJDZ7AEE_js.renameSection(sections, slides, sectionId, newName);
4562
+ const result = chunkPCW2KT7Z_js.renameSection(sections, slides, sectionId, newName);
4501
4563
  setSections(result.sections);
4502
4564
  setSlides(result.slides);
4503
4565
  markDirty();
@@ -4506,7 +4568,7 @@ function useSectionOperations(input) {
4506
4568
  );
4507
4569
  const deleteSection2 = react.useCallback(
4508
4570
  (sectionId) => {
4509
- const result = chunkFJDZ7AEE_js.deleteSection(sections, slides, sectionId);
4571
+ const result = chunkPCW2KT7Z_js.deleteSection(sections, slides, sectionId);
4510
4572
  setSections(result.sections);
4511
4573
  setSlides(result.slides);
4512
4574
  markDirty();
@@ -4515,21 +4577,21 @@ function useSectionOperations(input) {
4515
4577
  );
4516
4578
  const moveSectionUp2 = react.useCallback(
4517
4579
  (sectionId) => {
4518
- setSections(chunkFJDZ7AEE_js.moveSectionUp(sections, sectionId));
4580
+ setSections(chunkPCW2KT7Z_js.moveSectionUp(sections, sectionId));
4519
4581
  markDirty();
4520
4582
  },
4521
4583
  [sections, setSections, markDirty]
4522
4584
  );
4523
4585
  const moveSectionDown2 = react.useCallback(
4524
4586
  (sectionId) => {
4525
- setSections(chunkFJDZ7AEE_js.moveSectionDown(sections, sectionId));
4587
+ setSections(chunkPCW2KT7Z_js.moveSectionDown(sections, sectionId));
4526
4588
  markDirty();
4527
4589
  },
4528
4590
  [sections, setSections, markDirty]
4529
4591
  );
4530
4592
  const moveSlidesToSection2 = react.useCallback(
4531
4593
  (slideIndexes, targetSectionId) => {
4532
- const result = chunkFJDZ7AEE_js.moveSlidesToSection(sections, slides, slideIndexes, targetSectionId);
4594
+ const result = chunkPCW2KT7Z_js.moveSlidesToSection(sections, slides, slideIndexes, targetSectionId);
4533
4595
  setSlides(result.slides);
4534
4596
  setSections(result.sections);
4535
4597
  markDirty();
@@ -4556,21 +4618,54 @@ function useSectionOperations(input) {
4556
4618
  };
4557
4619
  }
4558
4620
 
4621
+ // src/viewer/utils/selection-handle-overlay.ts
4622
+ var VIEWPORT_SELECTOR = "[data-pptx-viewport]";
4623
+ function findSelectionHandleHost(elementNode, elementId) {
4624
+ const scope = elementNode.closest(VIEWPORT_SELECTOR) ?? elementNode.parentElement;
4625
+ if (!scope) {
4626
+ return null;
4627
+ }
4628
+ for (const candidate of scope.querySelectorAll("[data-pptx-handle-for]")) {
4629
+ if (candidate.getAttribute("data-pptx-handle-for") === elementId) {
4630
+ return candidate;
4631
+ }
4632
+ }
4633
+ return null;
4634
+ }
4635
+ function syncSelectionHandleOverlay(elementNode, elementId, geometry) {
4636
+ const host = findSelectionHandleHost(elementNode, elementId);
4637
+ if (!host) {
4638
+ return;
4639
+ }
4640
+ if (geometry.x !== void 0) {
4641
+ host.style.left = `${geometry.x}px`;
4642
+ }
4643
+ if (geometry.y !== void 0) {
4644
+ host.style.top = `${geometry.y}px`;
4645
+ }
4646
+ if (geometry.width !== void 0) {
4647
+ host.style.width = `${geometry.width}px`;
4648
+ }
4649
+ if (geometry.height !== void 0) {
4650
+ host.style.height = `${geometry.height}px`;
4651
+ }
4652
+ if (geometry.transform !== void 0) {
4653
+ host.style.transform = geometry.transform;
4654
+ }
4655
+ }
4656
+
4559
4657
  // src/viewer/hooks/pointer-move-handlers.ts
4560
- function computeResizeGeometry(handle, startX, startY, startWidth, startHeight, dx, dy, snapToGrid, gridSpacingPx) {
4561
- const resized = chunkFJDZ7AEE_js.applyResize(
4562
- { x: startX, y: startY, width: startWidth, height: startHeight },
4563
- handle,
4564
- dx,
4565
- dy,
4566
- 1,
4567
- { minSize: chunkB6UIVRFA_js.MIN_ELEMENT_SIZE }
4568
- );
4658
+ function computeResizeGeometry(handle, startX, startY, startWidth, startHeight, dx, dy, snapToGrid, gridSpacingPx, lockAspect = false) {
4659
+ const startBox = { x: startX, y: startY, width: startWidth, height: startHeight };
4660
+ let resized = chunkPCW2KT7Z_js.applyResize(startBox, handle, dx, dy, 1, { minSize: chunkXBTHWXNO_js.MIN_ELEMENT_SIZE });
4661
+ if (lockAspect) {
4662
+ resized = chunkPCW2KT7Z_js.lockResizeAspect(resized, startBox, handle, chunkXBTHWXNO_js.MIN_ELEMENT_SIZE);
4663
+ }
4569
4664
  const box = { x: resized.x, y: resized.y, width: resized.width, height: resized.height };
4570
4665
  if (!snapToGrid) {
4571
4666
  return box;
4572
4667
  }
4573
- return chunkFJDZ7AEE_js.snapBoxToGrid(box, handle, gridSpacingPx, chunkB6UIVRFA_js.MIN_ELEMENT_SIZE);
4668
+ return chunkPCW2KT7Z_js.snapBoxToGrid(box, handle, gridSpacingPx, chunkXBTHWXNO_js.MIN_ELEMENT_SIZE);
4574
4669
  }
4575
4670
  function resolveLiveTarget(input) {
4576
4671
  const { livePatcher, editTemplateMode, activeSlide } = input;
@@ -4683,7 +4778,7 @@ function processDragMove(e, drag, editorScale, snapToGrid, snapToShape, gridSpac
4683
4778
  width: el.width,
4684
4779
  height: el.height
4685
4780
  }));
4686
- const snapResult = chunkFJDZ7AEE_js.computeSnapToShape(
4781
+ const snapResult = chunkPCW2KT7Z_js.computeSnapToShape(
4687
4782
  targetX,
4688
4783
  targetY,
4689
4784
  primaryEl.width,
@@ -4715,14 +4810,17 @@ function processDragMove(e, drag, editorScale, snapToGrid, snapToShape, gridSpac
4715
4810
  for (const [id, domEl] of drag.domEls) {
4716
4811
  const start = drag.startPositionsById[id];
4717
4812
  if (start) {
4718
- domEl.style.left = `${start.x + appliedDx}px`;
4719
- domEl.style.top = `${start.y + appliedDy}px`;
4813
+ const x = start.x + appliedDx;
4814
+ const y = start.y + appliedDy;
4815
+ domEl.style.left = `${x}px`;
4816
+ domEl.style.top = `${y}px`;
4817
+ syncSelectionHandleOverlay(domEl, id, { x, y });
4720
4818
  }
4721
4819
  }
4722
4820
  if (live) {
4723
4821
  for (const id of Object.keys(drag.startPositionsById)) {
4724
4822
  const start = drag.startPositionsById[id];
4725
- chunkFJDZ7AEE_js.publishLiveGeometry(live.patcher, live.slideId, id, {
4823
+ chunkPCW2KT7Z_js.publishLiveGeometry(live.patcher, live.slideId, id, {
4726
4824
  x: start.x + appliedDx,
4727
4825
  y: start.y + appliedDy
4728
4826
  });
@@ -4747,31 +4845,35 @@ function processResizeMove(e, rs, editorScale, snapToGrid, gridSpacingPx, live)
4747
4845
  dx,
4748
4846
  dy,
4749
4847
  snapToGrid,
4750
- gridSpacingPx
4848
+ gridSpacingPx,
4849
+ e.shiftKey
4751
4850
  );
4752
4851
  rs.lastX = geo.x;
4753
4852
  rs.lastY = geo.y;
4754
4853
  rs.lastWidth = geo.width;
4755
4854
  rs.lastHeight = geo.height;
4855
+ const width = Math.max(geo.width, chunkXBTHWXNO_js.MIN_ELEMENT_SIZE);
4856
+ const height = Math.max(geo.height, chunkXBTHWXNO_js.MIN_ELEMENT_SIZE);
4756
4857
  if (rs.domEl) {
4757
4858
  rs.domEl.style.left = `${geo.x}px`;
4758
4859
  rs.domEl.style.top = `${geo.y}px`;
4759
- rs.domEl.style.width = `${Math.max(geo.width, chunkB6UIVRFA_js.MIN_ELEMENT_SIZE)}px`;
4760
- rs.domEl.style.height = `${Math.max(geo.height, chunkB6UIVRFA_js.MIN_ELEMENT_SIZE)}px`;
4860
+ rs.domEl.style.width = `${width}px`;
4861
+ rs.domEl.style.height = `${height}px`;
4862
+ syncSelectionHandleOverlay(rs.domEl, rs.elementId, { x: geo.x, y: geo.y, width, height });
4761
4863
  }
4762
4864
  if (live) {
4763
- chunkFJDZ7AEE_js.publishLiveGeometry(live.patcher, live.slideId, rs.elementId, {
4865
+ chunkPCW2KT7Z_js.publishLiveGeometry(live.patcher, live.slideId, rs.elementId, {
4764
4866
  x: geo.x,
4765
4867
  y: geo.y,
4766
- width: Math.max(geo.width, chunkB6UIVRFA_js.MIN_ELEMENT_SIZE),
4767
- height: Math.max(geo.height, chunkB6UIVRFA_js.MIN_ELEMENT_SIZE)
4868
+ width,
4869
+ height
4768
4870
  });
4769
4871
  }
4770
4872
  }
4771
4873
  function processAdjustmentMove(e, adj, editorScale, updateElementById) {
4772
4874
  const dx = (e.clientX - adj.startClientX) / editorScale;
4773
4875
  const dy = (e.clientY - adj.startClientY) / editorScale;
4774
- const adjustments = chunkFJDZ7AEE_js.getDraggedShapeAdjustments(adj, dx, dy);
4876
+ const adjustments = chunkPCW2KT7Z_js.getDraggedShapeAdjustments(adj, dx, dy);
4775
4877
  if (!adj.moved && Math.hypot(dx, dy) > 2) {
4776
4878
  adj.moved = true;
4777
4879
  }
@@ -4846,13 +4948,13 @@ function processPointerUp(input) {
4846
4948
  if (i !== activeSlideIndex) {
4847
4949
  return s;
4848
4950
  }
4849
- const rerouted = chunkFJDZ7AEE_js.rerouteConnectorsForMovedElements(s.elements, movedIds);
4951
+ const rerouted = chunkPCW2KT7Z_js.rerouteConnectorsForMovedElements(s.elements, movedIds);
4850
4952
  if (rerouted.length === 0) {
4851
4953
  return s;
4852
4954
  }
4853
4955
  return {
4854
4956
  ...s,
4855
- elements: chunkFJDZ7AEE_js.applyReroutedConnectors(s.elements, rerouted)
4957
+ elements: chunkPCW2KT7Z_js.applyReroutedConnectors(s.elements, rerouted)
4856
4958
  };
4857
4959
  })
4858
4960
  );
@@ -4877,9 +4979,9 @@ function processPointerUp(input) {
4877
4979
  }
4878
4980
  function commitMarquee(marquee, editTemplateMode, templateElements, activeSlide, applySelection, clearSelection) {
4879
4981
  const sourceElements = editTemplateMode ? templateElements : activeSlide?.elements ?? [];
4880
- const hitIds = chunkFJDZ7AEE_js.computeMarqueeHitIds(marquee, sourceElements);
4982
+ const hitIds = chunkPCW2KT7Z_js.computeMarqueeHitIds(marquee, sourceElements);
4881
4983
  if (marquee.additive) {
4882
- const merged = chunkFJDZ7AEE_js.mergeAdditiveSelection(marquee.baseSelectionIds, hitIds);
4984
+ const merged = chunkPCW2KT7Z_js.mergeAdditiveSelection(marquee.baseSelectionIds, hitIds);
4883
4985
  if (merged.length > 0) {
4884
4986
  applySelection(merged[0], merged);
4885
4987
  } else {
@@ -4902,8 +5004,8 @@ function commitDrag(drag, editTemplateMode, activeSlide, activeSlideIndex, setTe
4902
5004
  }
4903
5005
  return { ...el, x: start.x + dx, y: start.y + dy };
4904
5006
  });
4905
- const rerouted = chunkFJDZ7AEE_js.rerouteConnectorsForMovedElements(movedElements, movedIds);
4906
- return chunkFJDZ7AEE_js.applyReroutedConnectors(movedElements, rerouted);
5007
+ const rerouted = chunkPCW2KT7Z_js.rerouteConnectorsForMovedElements(movedElements, movedIds);
5008
+ return chunkPCW2KT7Z_js.applyReroutedConnectors(movedElements, rerouted);
4907
5009
  };
4908
5010
  if (editTemplateMode) {
4909
5011
  const slideId = activeSlide?.id;
@@ -5059,11 +5161,11 @@ function useCanvasInteractions(input) {
5059
5161
  return;
5060
5162
  }
5061
5163
  const el = elementLookup.get(editId);
5062
- if (el && chunkFJDZ7AEE_js.hasTextProperties(el)) {
5164
+ if (el && chunkPCW2KT7Z_js.hasTextProperties(el)) {
5063
5165
  const committedText = transformCommittedText ? transformCommittedText(inlineEditingText) : inlineEditingText;
5064
- const newSegments = chunkFJDZ7AEE_js.remapTextToSegments(committedText, el.textSegments, el.textStyle);
5166
+ const newSegments = chunkPCW2KT7Z_js.remapTextToSegments(committedText, el.textSegments, el.textStyle);
5065
5167
  const editorEl = document.querySelector("[data-inline-editor]");
5066
- const newHeight = chunkFJDZ7AEE_js.resolveInlineEditAutoFitHeight(el.textStyle, el.height, editorEl);
5168
+ const newHeight = chunkPCW2KT7Z_js.resolveInlineEditAutoFitHeight(el.textStyle, el.height, editorEl);
5067
5169
  ops.updateElementById(editId, {
5068
5170
  text: committedText,
5069
5171
  textSegments: newSegments,
@@ -5075,7 +5177,7 @@ function useCanvasInteractions(input) {
5075
5177
  setInlineEditingText("");
5076
5178
  };
5077
5179
  const openEquationEditorForElement = (el) => {
5078
- if (!chunkFJDZ7AEE_js.hasTextProperties(el)) {
5180
+ if (!chunkPCW2KT7Z_js.hasTextProperties(el)) {
5079
5181
  return false;
5080
5182
  }
5081
5183
  const eqSeg = el.textSegments?.find((seg) => seg.equationXml);
@@ -5105,7 +5207,7 @@ function useCanvasInteractions(input) {
5105
5207
  justInteractedRef.current = false;
5106
5208
  } else {
5107
5209
  const el = elementLookup.get(elementId);
5108
- if (el && chunkFJDZ7AEE_js.hasTextProperties(el) && chunkFJDZ7AEE_js.canInteractWithElement(el, "textEdit")) {
5210
+ if (el && chunkPCW2KT7Z_js.hasTextProperties(el) && chunkPCW2KT7Z_js.canInteractWithElement(el, "textEdit")) {
5109
5211
  if (!openEquationEditorForElement(el)) {
5110
5212
  setInlineEditingElementId(elementId);
5111
5213
  setInlineEditingText(el.text ?? "");
@@ -5124,7 +5226,7 @@ function useCanvasInteractions(input) {
5124
5226
  if (openEquationEditorForElement(el)) {
5125
5227
  return;
5126
5228
  }
5127
- if (chunkFJDZ7AEE_js.hasTextProperties(el) && chunkFJDZ7AEE_js.canInteractWithElement(el, "textEdit")) {
5229
+ if (chunkPCW2KT7Z_js.hasTextProperties(el) && chunkPCW2KT7Z_js.canInteractWithElement(el, "textEdit")) {
5128
5230
  setInlineEditingElementId(elementId);
5129
5231
  setInlineEditingText(el.text ?? "");
5130
5232
  }
@@ -5147,7 +5249,7 @@ function useCanvasInteractions(input) {
5147
5249
  justSelectedRef.current = false;
5148
5250
  }
5149
5251
  const ids = !wasSelected ? [elementId] : effectiveSelectedIds.length ? effectiveSelectedIds : [elementId];
5150
- const movableIds = chunkFJDZ7AEE_js.filterInteractableIds(ids, (id) => elementLookup.get(id), "move");
5252
+ const movableIds = chunkPCW2KT7Z_js.filterInteractableIds(ids, (id) => elementLookup.get(id), "move");
5151
5253
  if (movableIds.length === 0) {
5152
5254
  return;
5153
5255
  }
@@ -5217,7 +5319,7 @@ function useCanvasInteractions(input) {
5217
5319
  const handleResizePointerDown = (elementId, e, handle) => {
5218
5320
  e.stopPropagation();
5219
5321
  const el = elementLookup.get(elementId);
5220
- if (!el || !chunkFJDZ7AEE_js.canInteractWithElement(el, "resize")) {
5322
+ if (!el || !chunkPCW2KT7Z_js.canInteractWithElement(el, "resize")) {
5221
5323
  return;
5222
5324
  }
5223
5325
  resizeStateRef.current = {
@@ -5239,7 +5341,7 @@ function useCanvasInteractions(input) {
5239
5341
  };
5240
5342
  const handleRotate = (elementId, rotationDeg) => {
5241
5343
  const el = elementLookup.get(elementId);
5242
- if (!el || !chunkFJDZ7AEE_js.canInteractWithElement(el, "rotate")) {
5344
+ if (!el || !chunkPCW2KT7Z_js.canInteractWithElement(el, "rotate")) {
5243
5345
  return;
5244
5346
  }
5245
5347
  ops.updateElementById(elementId, { rotation: rotationDeg });
@@ -5259,10 +5361,10 @@ function useCanvasInteractions(input) {
5259
5361
  const handleAdjustmentPointerDown = (elementId, e, descriptor) => {
5260
5362
  e.stopPropagation();
5261
5363
  const el = elementLookup.get(elementId);
5262
- if (!el || !chunkFJDZ7AEE_js.canInteractWithElement(el, "adjustHandle")) {
5364
+ if (!el || !chunkPCW2KT7Z_js.canInteractWithElement(el, "adjustHandle")) {
5263
5365
  return;
5264
5366
  }
5265
- shapeAdjustmentDragStateRef.current = chunkFJDZ7AEE_js.beginShapeAdjustment(
5367
+ shapeAdjustmentDragStateRef.current = chunkPCW2KT7Z_js.beginShapeAdjustment(
5266
5368
  el,
5267
5369
  descriptor,
5268
5370
  e.clientX,
@@ -5309,7 +5411,7 @@ function createFileHandlers(deps) {
5309
5411
  h = Math.round(h * scale);
5310
5412
  }
5311
5413
  addElement({
5312
- id: chunkFJDZ7AEE_js.generateElementId(),
5414
+ id: chunkPCW2KT7Z_js.generateElementId(),
5313
5415
  type: "image",
5314
5416
  x: Math.round((canvasSize.width - w) / 2),
5315
5417
  y: Math.round((canvasSize.height - h) / 2),
@@ -5320,7 +5422,7 @@ function createFileHandlers(deps) {
5320
5422
  };
5321
5423
  img.onerror = () => {
5322
5424
  addElement({
5323
- id: chunkFJDZ7AEE_js.generateElementId(),
5425
+ id: chunkPCW2KT7Z_js.generateElementId(),
5324
5426
  type: "image",
5325
5427
  x: 100,
5326
5428
  y: 100,
@@ -5339,14 +5441,14 @@ function createFileHandlers(deps) {
5339
5441
  return;
5340
5442
  }
5341
5443
  e.target.value = "";
5342
- const mediaType = chunkFJDZ7AEE_js.classifyMediaType(file.type);
5444
+ const mediaType = chunkPCW2KT7Z_js.classifyMediaType(file.type);
5343
5445
  if (!mediaType) {
5344
5446
  return;
5345
5447
  }
5346
5448
  const elFilePath = file.path;
5347
5449
  const insertMediaElement = (mediaSourceUrl, width, height) => {
5348
5450
  addElement({
5349
- id: chunkFJDZ7AEE_js.generateElementId(),
5451
+ id: chunkPCW2KT7Z_js.generateElementId(),
5350
5452
  type: "media",
5351
5453
  mediaType,
5352
5454
  mediaMimeType: file.type || void 0,
@@ -5521,13 +5623,13 @@ function createStructuredElementHandlers(deps) {
5521
5623
  return;
5522
5624
  }
5523
5625
  addElement({
5524
- id: chunkFJDZ7AEE_js.generateElementId(),
5626
+ id: chunkPCW2KT7Z_js.generateElementId(),
5525
5627
  type: "smartArt",
5526
5628
  x: 100,
5527
5629
  y: 120,
5528
5630
  width: 600,
5529
5631
  height: 340,
5530
- smartArtData: chunkFJDZ7AEE_js.buildSmartArtPresetData(
5632
+ smartArtData: chunkPCW2KT7Z_js.buildSmartArtPresetData(
5531
5633
  layout,
5532
5634
  defaultItems,
5533
5635
  (i) => `node-${Date.now()}-${i}-${Math.random().toString(36).slice(2, 8)}`
@@ -5539,7 +5641,7 @@ function createStructuredElementHandlers(deps) {
5539
5641
  return;
5540
5642
  }
5541
5643
  addElement({
5542
- id: chunkFJDZ7AEE_js.generateElementId(),
5644
+ id: chunkPCW2KT7Z_js.generateElementId(),
5543
5645
  type: "shape",
5544
5646
  x: 120,
5545
5647
  y: 200,
@@ -5577,7 +5679,7 @@ function createStructuredElementHandlers(deps) {
5577
5679
  return;
5578
5680
  }
5579
5681
  const resolved = resolveHyperlinkEditResult(data);
5580
- if (resolved.url && !chunkFJDZ7AEE_js.isUrlSafe(resolved.url)) {
5682
+ if (resolved.url && !chunkPCW2KT7Z_js.isUrlSafe(resolved.url)) {
5581
5683
  return;
5582
5684
  }
5583
5685
  const actionClick = {
@@ -5601,7 +5703,7 @@ function createStructuredElementHandlers(deps) {
5601
5703
  const displayText = value || fieldTexts[fieldType] || fieldType;
5602
5704
  const fieldGuid = `{${crypto.randomUUID().toUpperCase()}}`;
5603
5705
  addElement({
5604
- id: chunkFJDZ7AEE_js.generateElementId(),
5706
+ id: chunkPCW2KT7Z_js.generateElementId(),
5605
5707
  type: "shape",
5606
5708
  x: 120,
5607
5709
  y: 200,
@@ -5623,11 +5725,11 @@ function createStructuredElementHandlers(deps) {
5623
5725
  if (!activeSlide) {
5624
5726
  return;
5625
5727
  }
5626
- const preset = chunkFJDZ7AEE_js.ACTION_BUTTON_PRESETS.find((p) => p.shapeType === shapeType);
5728
+ const preset = chunkPCW2KT7Z_js.ACTION_BUTTON_PRESETS.find((p) => p.shapeType === shapeType);
5627
5729
  if (!preset) {
5628
5730
  return;
5629
5731
  }
5630
- const defaultPptxAction = chunkFJDZ7AEE_js.elementActionToPptxAction({
5732
+ const defaultPptxAction = chunkPCW2KT7Z_js.elementActionToPptxAction({
5631
5733
  trigger: "click",
5632
5734
  type: preset.defaultAction
5633
5735
  });
@@ -5636,7 +5738,7 @@ function createStructuredElementHandlers(deps) {
5636
5738
  defaultPptxAction.highlightClick = true;
5637
5739
  }
5638
5740
  addElement({
5639
- id: chunkFJDZ7AEE_js.generateElementId(),
5741
+ id: chunkPCW2KT7Z_js.generateElementId(),
5640
5742
  type: "shape",
5641
5743
  x: 150,
5642
5744
  y: 150,
@@ -5703,14 +5805,14 @@ function useInsertElements(input) {
5703
5805
  return;
5704
5806
  }
5705
5807
  addElement({
5706
- id: chunkFJDZ7AEE_js.generateElementId(),
5808
+ id: chunkPCW2KT7Z_js.generateElementId(),
5707
5809
  type: "text",
5708
5810
  x: 100,
5709
5811
  y: 100,
5710
5812
  width: 300,
5711
5813
  height: 60,
5712
5814
  text: "",
5713
- textStyle: { fontSize: chunkB6UIVRFA_js.DEFAULT_TEXT_FONT_SIZE }
5815
+ textStyle: { fontSize: chunkXBTHWXNO_js.DEFAULT_TEXT_FONT_SIZE }
5714
5816
  });
5715
5817
  };
5716
5818
  const handleAddShape = () => {
@@ -5718,7 +5820,7 @@ function useInsertElements(input) {
5718
5820
  return;
5719
5821
  }
5720
5822
  addElement({
5721
- id: chunkFJDZ7AEE_js.generateElementId(),
5823
+ id: chunkPCW2KT7Z_js.generateElementId(),
5722
5824
  type: "shape",
5723
5825
  x: 150,
5724
5826
  y: 150,
@@ -5737,15 +5839,15 @@ function useInsertElements(input) {
5737
5839
  return;
5738
5840
  }
5739
5841
  addElement({
5740
- ...chunkFJDZ7AEE_js.newTableElement(chunkB6UIVRFA_js.DEFAULT_TABLE_ROWS, chunkB6UIVRFA_js.DEFAULT_TABLE_COLUMNS, 100, 200),
5741
- id: chunkFJDZ7AEE_js.generateElementId()
5842
+ ...chunkPCW2KT7Z_js.newTableElement(chunkXBTHWXNO_js.DEFAULT_TABLE_ROWS, chunkXBTHWXNO_js.DEFAULT_TABLE_COLUMNS, 100, 200),
5843
+ id: chunkPCW2KT7Z_js.generateElementId()
5742
5844
  });
5743
5845
  };
5744
5846
  const handleAddChart = (chartKind) => {
5745
5847
  if (!activeSlide) {
5746
5848
  return;
5747
5849
  }
5748
- addElement(chunkFJDZ7AEE_js.createDefaultChartElement(chartKind));
5850
+ addElement(chunkPCW2KT7Z_js.createDefaultChartElement(chartKind));
5749
5851
  };
5750
5852
  const structured = createStructuredElementHandlers({
5751
5853
  activeSlide,
@@ -5815,7 +5917,7 @@ function useClipboardHandlers(input) {
5815
5917
  if (!selectedElement) {
5816
5918
  return;
5817
5919
  }
5818
- setClipboardPayload(chunkFJDZ7AEE_js.buildElementClipboardPayload(selectedElement, editTemplateMode));
5920
+ setClipboardPayload(chunkPCW2KT7Z_js.buildElementClipboardPayload(selectedElement, editTemplateMode));
5819
5921
  };
5820
5922
  const handleDelete = () => {
5821
5923
  const idsToDelete = effectiveSelectedIds;
@@ -5832,7 +5934,7 @@ function useClipboardHandlers(input) {
5832
5934
  handleDelete();
5833
5935
  };
5834
5936
  const insertClone = (source) => {
5835
- const clone = chunkFJDZ7AEE_js.cloneElementForPaste(source, { intoTemplate: editTemplateMode });
5937
+ const clone = chunkPCW2KT7Z_js.cloneElementForPaste(source, { intoTemplate: editTemplateMode });
5836
5938
  ops.updateActiveElements((els) => [...els, clone]);
5837
5939
  ops.applySelection(clone.id);
5838
5940
  history.markDirty();
@@ -5867,7 +5969,7 @@ function resolveShapePath(el) {
5867
5969
  return el.pathData;
5868
5970
  }
5869
5971
  if ("shapeType" in el && typeof el.shapeType === "string") {
5870
- const clipPath = chunkFJDZ7AEE_js.getPresetShapeClipPath(el.shapeType);
5972
+ const clipPath = chunkPCW2KT7Z_js.getPresetShapeClipPath(el.shapeType);
5871
5973
  if (clipPath) {
5872
5974
  const svgPath = clipPathToSvgPath(clipPath, el.width, el.height);
5873
5975
  if (svgPath) {
@@ -5918,7 +6020,7 @@ function clipPathToSvgPath(clipPath, width, height) {
5918
6020
  return parts.join(" ");
5919
6021
  }
5920
6022
  function transformPathToGlobal(pathData, el) {
5921
- const polys = chunkFJDZ7AEE_js.svgPathToPolygons(pathData);
6023
+ const polys = chunkPCW2KT7Z_js.svgPathToPolygons(pathData);
5922
6024
  if (polys.length === 0) {
5923
6025
  return pathData;
5924
6026
  }
@@ -5938,10 +6040,10 @@ function transformPathToGlobal(pathData, el) {
5938
6040
  y: pt.y * scaleY + el.y
5939
6041
  }))
5940
6042
  );
5941
- return chunkFJDZ7AEE_js.polygonsToSvgPath(transformed);
6043
+ return chunkPCW2KT7Z_js.polygonsToSvgPath(transformed);
5942
6044
  }
5943
6045
  function transformPathToLocal(pathData, x, y, _width, _height) {
5944
- const polys = chunkFJDZ7AEE_js.svgPathToPolygons(pathData);
6046
+ const polys = chunkPCW2KT7Z_js.svgPathToPolygons(pathData);
5945
6047
  if (polys.length === 0) {
5946
6048
  return pathData;
5947
6049
  }
@@ -5951,10 +6053,10 @@ function transformPathToLocal(pathData, x, y, _width, _height) {
5951
6053
  y: pt.y - y
5952
6054
  }))
5953
6055
  );
5954
- return chunkFJDZ7AEE_js.polygonsToSvgPath(transformed);
6056
+ return chunkPCW2KT7Z_js.polygonsToSvgPath(transformed);
5955
6057
  }
5956
6058
  function pathBounds(pathData) {
5957
- const polys = chunkFJDZ7AEE_js.svgPathToPolygons(pathData);
6059
+ const polys = chunkPCW2KT7Z_js.svgPathToPolygons(pathData);
5958
6060
  let minX = Infinity;
5959
6061
  let minY = Infinity;
5960
6062
  let maxX = -Infinity;
@@ -6013,7 +6115,7 @@ function useMergeShapesHandler(input) {
6013
6115
  let allFragments = [];
6014
6116
  let remaining = globalPaths[0];
6015
6117
  for (let i = 1; i < globalPaths.length; i++) {
6016
- const frags = chunkFJDZ7AEE_js.mergeShapes("fragment", remaining, globalPaths[i]);
6118
+ const frags = chunkPCW2KT7Z_js.mergeShapes("fragment", remaining, globalPaths[i]);
6017
6119
  if (Array.isArray(frags)) {
6018
6120
  allFragments = frags;
6019
6121
  }
@@ -6042,7 +6144,7 @@ function useMergeShapesHandler(input) {
6042
6144
  bounds.height
6043
6145
  );
6044
6146
  const newEl = {
6045
- id: chunkFJDZ7AEE_js.generateElementId(),
6147
+ id: chunkPCW2KT7Z_js.generateElementId(),
6046
6148
  type: "shape",
6047
6149
  x: bounds.x,
6048
6150
  y: bounds.y,
@@ -6080,7 +6182,7 @@ function useMergeShapesHandler(input) {
6080
6182
  } else {
6081
6183
  let resultPath = globalPaths[0];
6082
6184
  for (let i = 1; i < globalPaths.length; i++) {
6083
- const result = chunkFJDZ7AEE_js.mergeShapes(operation, resultPath, globalPaths[i]);
6185
+ const result = chunkPCW2KT7Z_js.mergeShapes(operation, resultPath, globalPaths[i]);
6084
6186
  if (typeof result === "string") {
6085
6187
  resultPath = result;
6086
6188
  }
@@ -6101,7 +6203,7 @@ function useMergeShapesHandler(input) {
6101
6203
  );
6102
6204
  const primary = targets[0];
6103
6205
  const newEl = {
6104
- id: chunkFJDZ7AEE_js.generateElementId(),
6206
+ id: chunkPCW2KT7Z_js.generateElementId(),
6105
6207
  type: "shape",
6106
6208
  x: bounds.x,
6107
6209
  y: bounds.y,
@@ -6164,7 +6266,7 @@ function useGroupAlignLayerHandlers(input) {
6164
6266
  if (ids.length < 2 || !activeSlide) {
6165
6267
  return;
6166
6268
  }
6167
- const { elements, groupId } = chunkFJDZ7AEE_js.groupElements(ops.activeElements, ids, chunkFJDZ7AEE_js.generateElementId());
6269
+ const { elements, groupId } = chunkPCW2KT7Z_js.groupElements(ops.activeElements, ids, chunkPCW2KT7Z_js.generateElementId());
6168
6270
  if (groupId === null) {
6169
6271
  return;
6170
6272
  }
@@ -6177,11 +6279,11 @@ function useGroupAlignLayerHandlers(input) {
6177
6279
  return;
6178
6280
  }
6179
6281
  const group = selectedElement;
6180
- const intoTemplate = chunkFJDZ7AEE_js.isTemplateElementId(group.id);
6282
+ const intoTemplate = chunkPCW2KT7Z_js.isTemplateElementId(group.id);
6181
6283
  const childIds = group.children.map(
6182
- (child) => intoTemplate ? chunkFJDZ7AEE_js.makeCloneId(true, child.id || group.id) : child.id || chunkFJDZ7AEE_js.generateElementId()
6284
+ (child) => intoTemplate ? chunkPCW2KT7Z_js.makeCloneId(true, child.id || group.id) : child.id || chunkPCW2KT7Z_js.generateElementId()
6183
6285
  );
6184
- const { elements, childIds: usedIds } = chunkFJDZ7AEE_js.ungroupElements(
6286
+ const { elements, childIds: usedIds } = chunkPCW2KT7Z_js.ungroupElements(
6185
6287
  ops.activeElements,
6186
6288
  group.id,
6187
6289
  childIds,
@@ -6210,7 +6312,7 @@ function useGroupAlignLayerHandlers(input) {
6210
6312
  if (!edge) {
6211
6313
  return;
6212
6314
  }
6213
- const positions = chunkFJDZ7AEE_js.alignElements(selectedElements, edge);
6315
+ const positions = chunkPCW2KT7Z_js.alignElements(selectedElements, edge);
6214
6316
  for (const [id, pos] of positions) {
6215
6317
  const el = elementLookup.get(id);
6216
6318
  if (!el) {
@@ -6228,7 +6330,7 @@ function useGroupAlignLayerHandlers(input) {
6228
6330
  if (!distAxis) {
6229
6331
  return;
6230
6332
  }
6231
- const positions = chunkFJDZ7AEE_js.distributeElements(selectedElements, distAxis);
6333
+ const positions = chunkPCW2KT7Z_js.distributeElements(selectedElements, distAxis);
6232
6334
  for (const [id, pos] of positions) {
6233
6335
  const el = elementLookup.get(id);
6234
6336
  if (!el) {
@@ -6245,7 +6347,7 @@ function useGroupAlignLayerHandlers(input) {
6245
6347
  }
6246
6348
  const id = selectedElement.id;
6247
6349
  ops.updateActiveElements(
6248
- (els) => direction === "forward" ? chunkFJDZ7AEE_js.bringForward(els, id) : direction === "backward" ? chunkFJDZ7AEE_js.sendBackward(els, id) : els
6350
+ (els) => direction === "forward" ? chunkPCW2KT7Z_js.bringForward(els, id) : direction === "backward" ? chunkPCW2KT7Z_js.sendBackward(els, id) : els
6249
6351
  );
6250
6352
  history.markDirty();
6251
6353
  };
@@ -6255,7 +6357,7 @@ function useGroupAlignLayerHandlers(input) {
6255
6357
  }
6256
6358
  const id = selectedElement.id;
6257
6359
  ops.updateActiveElements(
6258
- (els) => direction === "front" ? chunkFJDZ7AEE_js.bringToFront(els, id) : chunkFJDZ7AEE_js.sendToBack(els, id)
6360
+ (els) => direction === "front" ? chunkPCW2KT7Z_js.bringToFront(els, id) : chunkPCW2KT7Z_js.sendToBack(els, id)
6259
6361
  );
6260
6362
  history.markDirty();
6261
6363
  };
@@ -6386,7 +6488,7 @@ function useSlideManagement(input) {
6386
6488
  theme
6387
6489
  } = input;
6388
6490
  const handleAddSlide = () => {
6389
- const newSlide = chunkFJDZ7AEE_js.createBlankSlide(slides.length + 1);
6491
+ const newSlide = chunkPCW2KT7Z_js.createBlankSlide(slides.length + 1);
6390
6492
  ops.updateSlides((prev) => {
6391
6493
  const next = [...prev];
6392
6494
  next.splice(activeSlideIndex + 1, 0, newSlide);
@@ -6449,7 +6551,7 @@ function useSlideManagement(input) {
6449
6551
  }
6450
6552
  const clone = {
6451
6553
  ...src,
6452
- id: chunkFJDZ7AEE_js.makeSlideId(),
6554
+ id: chunkPCW2KT7Z_js.makeSlideId(),
6453
6555
  elements: src.elements.map((el) => ({
6454
6556
  ...el,
6455
6557
  id: `${el.id}-dup-${Math.random().toString(36).slice(2, 6)}`
@@ -6481,7 +6583,7 @@ function useSlideManagement(input) {
6481
6583
  const handleInsertSlideFromLayout = (layoutPath, layoutName) => {
6482
6584
  const insertAt = activeSlideIndex + 1;
6483
6585
  const draft = {
6484
- ...chunkFJDZ7AEE_js.createBlankSlide(slides.length + 1),
6586
+ ...chunkPCW2KT7Z_js.createBlankSlide(slides.length + 1),
6485
6587
  layoutPath,
6486
6588
  ...layoutName ? { layoutName } : {}
6487
6589
  };
@@ -6514,9 +6616,9 @@ function useSlideManagement(input) {
6514
6616
  };
6515
6617
  const handleInsertSlideFromTemplate = (templateId) => {
6516
6618
  const insertAt = activeSlideIndex + 1;
6517
- const draft = chunkFJDZ7AEE_js.buildSlideTemplateSlide(templateId, chunkFJDZ7AEE_js.makeSlideId(), slides.length + 1, {
6619
+ const draft = chunkPCW2KT7Z_js.buildSlideTemplateSlide(templateId, chunkPCW2KT7Z_js.makeSlideId(), slides.length + 1, {
6518
6620
  ...canvasSize ? { slideWidth: canvasSize.width, slideHeight: canvasSize.height } : {},
6519
- scheme: chunkFJDZ7AEE_js.templateSchemeFromTheme(theme?.colorScheme)
6621
+ scheme: chunkPCW2KT7Z_js.templateSchemeFromTheme(theme?.colorScheme)
6520
6622
  });
6521
6623
  ops.updateSlides((prev) => insertSlideFromLayoutUpdater(prev, activeSlideIndex, draft));
6522
6624
  setActiveSlideIndex(insertAt);
@@ -6553,7 +6655,7 @@ function createTableMergeHandlers(input) {
6553
6655
  if (!nextCell || nextCell.hMerge || nextCell.vMerge) {
6554
6656
  return;
6555
6657
  }
6556
- const newTableData = chunkFJDZ7AEE_js.mergeCells(
6658
+ const newTableData = chunkPCW2KT7Z_js.mergeCells(
6557
6659
  [
6558
6660
  { row: rowIndex, col: columnIndex },
6559
6661
  { row: rowIndex, col: nextColIdx }
@@ -6561,7 +6663,7 @@ function createTableMergeHandlers(input) {
6561
6663
  td
6562
6664
  );
6563
6665
  const updates = { tableData: newTableData };
6564
- const newRawXml = chunkFJDZ7AEE_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
6666
+ const newRawXml = chunkPCW2KT7Z_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
6565
6667
  if (newRawXml) {
6566
6668
  updates.rawXml = newRawXml;
6567
6669
  }
@@ -6587,7 +6689,7 @@ function createTableMergeHandlers(input) {
6587
6689
  if (!targetNextCell || targetNextCell.hMerge || targetNextCell.vMerge) {
6588
6690
  return;
6589
6691
  }
6590
- const newTableData = chunkFJDZ7AEE_js.mergeCells(
6692
+ const newTableData = chunkPCW2KT7Z_js.mergeCells(
6591
6693
  [
6592
6694
  { row: rowIndex, col: columnIndex },
6593
6695
  { row: targetNextRowIdx, col: columnIndex }
@@ -6595,7 +6697,7 @@ function createTableMergeHandlers(input) {
6595
6697
  td
6596
6698
  );
6597
6699
  const updates = { tableData: newTableData };
6598
- const newRawXml = chunkFJDZ7AEE_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
6700
+ const newRawXml = chunkPCW2KT7Z_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
6599
6701
  if (newRawXml) {
6600
6702
  updates.rawXml = newRawXml;
6601
6703
  }
@@ -6610,9 +6712,9 @@ function createTableMergeHandlers(input) {
6610
6712
  return;
6611
6713
  }
6612
6714
  const td = selectedElement.tableData;
6613
- const newTableData = chunkFJDZ7AEE_js.mergeCells(ts.selectedCells, td);
6715
+ const newTableData = chunkPCW2KT7Z_js.mergeCells(ts.selectedCells, td);
6614
6716
  const updates = { tableData: newTableData };
6615
- const newRawXml = chunkFJDZ7AEE_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
6717
+ const newRawXml = chunkPCW2KT7Z_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
6616
6718
  if (newRawXml) {
6617
6719
  updates.rawXml = newRawXml;
6618
6720
  }
@@ -6629,9 +6731,9 @@ function createTableMergeHandlers(input) {
6629
6731
  }
6630
6732
  const { rowIndex, columnIndex } = ts;
6631
6733
  const td = selectedElement.tableData;
6632
- const newTableData = chunkFJDZ7AEE_js.splitCell(rowIndex, columnIndex, td);
6734
+ const newTableData = chunkPCW2KT7Z_js.splitCell(rowIndex, columnIndex, td);
6633
6735
  const updates = { tableData: newTableData };
6634
- const newRawXml = chunkFJDZ7AEE_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
6736
+ const newRawXml = chunkPCW2KT7Z_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
6635
6737
  if (newRawXml) {
6636
6738
  updates.rawXml = newRawXml;
6637
6739
  }
@@ -6665,10 +6767,10 @@ function createTableStructHandlers(input) {
6665
6767
  const text = transformCommittedText ? transformCommittedText(rawText) : rawText;
6666
6768
  const updates = {};
6667
6769
  if (el.tableData) {
6668
- updates.tableData = chunkFJDZ7AEE_js.setCellText(el, rowIndex, colIndex, text).tableData;
6770
+ updates.tableData = chunkPCW2KT7Z_js.setCellText(el, rowIndex, colIndex, text).tableData;
6669
6771
  }
6670
6772
  if (el.rawXml) {
6671
- const newRawXml = chunkFJDZ7AEE_js.updateCellTextInRawXml(el, rowIndex, colIndex, text);
6773
+ const newRawXml = chunkPCW2KT7Z_js.updateCellTextInRawXml(el, rowIndex, colIndex, text);
6672
6774
  if (newRawXml) {
6673
6775
  updates.rawXml = newRawXml;
6674
6776
  }
@@ -6692,7 +6794,7 @@ function createTableStructHandlers(input) {
6692
6794
  const { rowIndex, columnIndex: colIndex } = ts;
6693
6795
  const updates = {};
6694
6796
  if (selectedElement.rawXml) {
6695
- const newRawXml = chunkFJDZ7AEE_js.updateCellTextStyleInRawXml(
6797
+ const newRawXml = chunkPCW2KT7Z_js.updateCellTextStyleInRawXml(
6696
6798
  selectedElement,
6697
6799
  rowIndex,
6698
6800
  colIndex,
@@ -6756,9 +6858,9 @@ function createTableStructHandlers(input) {
6756
6858
  return;
6757
6859
  }
6758
6860
  const rowIdx = ts?.rowIndex ?? 0;
6759
- const newTableData = chunkFJDZ7AEE_js.insertTableRow(selectedElement.tableData, rowIdx, position);
6861
+ const newTableData = chunkPCW2KT7Z_js.insertTableRow(selectedElement.tableData, rowIdx, position);
6760
6862
  const updates = { tableData: newTableData };
6761
- const newRawXml = chunkFJDZ7AEE_js.rebuildTableStructureInRawXml(selectedElement, newTableData);
6863
+ const newRawXml = chunkPCW2KT7Z_js.rebuildTableStructureInRawXml(selectedElement, newTableData);
6762
6864
  if (newRawXml) {
6763
6865
  updates.rawXml = newRawXml;
6764
6866
  }
@@ -6771,12 +6873,12 @@ function createTableStructHandlers(input) {
6771
6873
  }
6772
6874
  const td = selectedElement.tableData;
6773
6875
  const rowIdx = ts?.rowIndex ?? 0;
6774
- const newTableData = chunkFJDZ7AEE_js.deleteTableRow(td, rowIdx);
6876
+ const newTableData = chunkPCW2KT7Z_js.deleteTableRow(td, rowIdx);
6775
6877
  if (newTableData === td) {
6776
6878
  return;
6777
6879
  }
6778
6880
  const updates = { tableData: newTableData };
6779
- const newRawXml = chunkFJDZ7AEE_js.rebuildTableStructureInRawXml(selectedElement, newTableData);
6881
+ const newRawXml = chunkPCW2KT7Z_js.rebuildTableStructureInRawXml(selectedElement, newTableData);
6780
6882
  if (newRawXml) {
6781
6883
  updates.rawXml = newRawXml;
6782
6884
  }
@@ -6788,9 +6890,9 @@ function createTableStructHandlers(input) {
6788
6890
  return;
6789
6891
  }
6790
6892
  const colIdx = ts?.columnIndex ?? 0;
6791
- const newTableData = chunkFJDZ7AEE_js.insertTableColumn(selectedElement.tableData, colIdx, position);
6893
+ const newTableData = chunkPCW2KT7Z_js.insertTableColumn(selectedElement.tableData, colIdx, position);
6792
6894
  const updates = { tableData: newTableData };
6793
- const newRawXml = chunkFJDZ7AEE_js.rebuildTableStructureInRawXml(selectedElement, newTableData);
6895
+ const newRawXml = chunkPCW2KT7Z_js.rebuildTableStructureInRawXml(selectedElement, newTableData);
6794
6896
  if (newRawXml) {
6795
6897
  updates.rawXml = newRawXml;
6796
6898
  }
@@ -6803,12 +6905,12 @@ function createTableStructHandlers(input) {
6803
6905
  }
6804
6906
  const td = selectedElement.tableData;
6805
6907
  const colIdx = ts?.columnIndex ?? 0;
6806
- const newTableData = chunkFJDZ7AEE_js.deleteTableColumn(td, colIdx);
6908
+ const newTableData = chunkPCW2KT7Z_js.deleteTableColumn(td, colIdx);
6807
6909
  if (newTableData === td) {
6808
6910
  return;
6809
6911
  }
6810
6912
  const updates = { tableData: newTableData };
6811
- const newRawXml = chunkFJDZ7AEE_js.rebuildTableStructureInRawXml(selectedElement, newTableData);
6913
+ const newRawXml = chunkPCW2KT7Z_js.rebuildTableStructureInRawXml(selectedElement, newTableData);
6812
6914
  if (newRawXml) {
6813
6915
  updates.rawXml = newRawXml;
6814
6916
  }
@@ -6844,8 +6946,8 @@ async function renderToCanvas(element, options = {}) {
6844
6946
  return html2canvasPro(element, {
6845
6947
  ...options,
6846
6948
  onclone: async (doc, clonedEl) => {
6847
- await chunkFJDZ7AEE_js.normalizeColorsForCapture(doc, clonedEl);
6848
- chunkFJDZ7AEE_js.preprocessCssForCapture(clonedEl);
6949
+ await chunkPCW2KT7Z_js.normalizeColorsForCapture(doc, clonedEl);
6950
+ chunkPCW2KT7Z_js.preprocessCssForCapture(clonedEl);
6849
6951
  if (typeof userOnClone === "function") {
6850
6952
  userOnClone(doc, clonedEl);
6851
6953
  }
@@ -6883,13 +6985,13 @@ function useExportSaveAs(input) {
6883
6985
  if (!handler) {
6884
6986
  return;
6885
6987
  }
6886
- const downloadName = chunkFJDZ7AEE_js.savedPresentationFileName(filePath, format);
6988
+ const downloadName = chunkPCW2KT7Z_js.savedPresentationFileName(filePath, format);
6887
6989
  try {
6888
6990
  const data = await buildSaveAsData(handler, format);
6889
6991
  const blob = new Blob([data], {
6890
6992
  type: "application/vnd.openxmlformats-officedocument.presentationml.presentation"
6891
6993
  });
6892
- chunkFJDZ7AEE_js.downloadBlob(blob, downloadName);
6994
+ chunkPCW2KT7Z_js.downloadBlob(blob, downloadName);
6893
6995
  } catch (err) {
6894
6996
  console.error(`[PowerPointViewer] Save as .${format} failed:`, err);
6895
6997
  }
@@ -6902,18 +7004,18 @@ function useExportSaveAs(input) {
6902
7004
  const pptxGuides = guides.map((g) => ({
6903
7005
  id: g.id,
6904
7006
  orientation: g.axis === "h" ? "horz" : "vert",
6905
- positionEmu: chunkFJDZ7AEE_js.guidePxToEmu(g.position)
7007
+ positionEmu: chunkPCW2KT7Z_js.guidePxToEmu(g.position)
6906
7008
  }));
6907
7009
  return {
6908
7010
  ...slide,
6909
7011
  guides: pptxGuides.length > 0 ? pptxGuides : void 0
6910
7012
  };
6911
7013
  });
6912
- const slidesToSave = chunkFJDZ7AEE_js.buildSaveSlides(slidesWithGuides, templateElementsBySlideId);
7014
+ const slidesToSave = chunkPCW2KT7Z_js.buildSaveSlides(slidesWithGuides, templateElementsBySlideId);
6913
7015
  const saveOptions = {
6914
7016
  // Save As shares Save's slide-size decision; leaving it out here is how
6915
7017
  // a preset picked in the inspector reached one save path and not the other.
6916
- slideSize: chunkFJDZ7AEE_js.resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size,
7018
+ slideSize: chunkPCW2KT7Z_js.resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size,
6917
7019
  headerFooter,
6918
7020
  presentationProperties,
6919
7021
  customShows: customShows.length > 0 ? customShows : void 0,
@@ -6927,13 +7029,13 @@ function useExportSaveAs(input) {
6927
7029
  handoutMaster,
6928
7030
  outputFormat: format
6929
7031
  };
6930
- return chunkFJDZ7AEE_js.saveDeckWithPassword(handler, slidesToSave, saveOptions, password);
7032
+ return chunkPCW2KT7Z_js.saveDeckWithPassword(handler, slidesToSave, saveOptions, password);
6931
7033
  };
6932
7034
  const handleExportJson = () => {
6933
7035
  const sourceName = filePath ? filePath.replace(/\\/gu, "/").split("/").pop() : void 0;
6934
- const slideSize = chunkFJDZ7AEE_js.resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size;
7036
+ const slideSize = chunkPCW2KT7Z_js.resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size;
6935
7037
  const data = {
6936
- slides: chunkFJDZ7AEE_js.buildSaveSlides(slides, templateElementsBySlideId),
7038
+ slides: chunkPCW2KT7Z_js.buildSaveSlides(slides, templateElementsBySlideId),
6937
7039
  width: canvasSize.width,
6938
7040
  height: canvasSize.height,
6939
7041
  widthEmu: slideSize.widthEmu,
@@ -6952,7 +7054,7 @@ function useExportSaveAs(input) {
6952
7054
  handoutMaster
6953
7055
  };
6954
7056
  try {
6955
- chunkFJDZ7AEE_js.exportDeckJson(data, sourceName);
7057
+ chunkPCW2KT7Z_js.exportDeckJson(data, sourceName);
6956
7058
  } catch (err) {
6957
7059
  console.error("[PowerPointViewer] JSON export failed:", err);
6958
7060
  }
@@ -7039,7 +7141,7 @@ async function exportSlideToPngBlob(slideElement, options = {}) {
7039
7141
  }
7040
7142
  async function exportSlideAsPng(slideElement, slideIndex, options = {}) {
7041
7143
  const blob = await exportSlideToPngBlob(slideElement, options);
7042
- chunkFJDZ7AEE_js.downloadBlob(blob, `slide-${slideIndex + 1}.png`);
7144
+ chunkPCW2KT7Z_js.downloadBlob(blob, `slide-${slideIndex + 1}.png`);
7043
7145
  }
7044
7146
  async function copySlideToClipboard(slideElement, options = {}) {
7045
7147
  const blob = await exportSlideToPngBlob(slideElement, options);
@@ -7061,15 +7163,15 @@ async function exportAllSlidesAsPdf(slideStageRef, totalSlides, setActiveSlide,
7061
7163
  continue;
7062
7164
  }
7063
7165
  const canvas = await renderElementToCanvas(stageEl, scale);
7064
- images.push(chunkFJDZ7AEE_js.canvasToJpegData(canvas));
7166
+ images.push(chunkPCW2KT7Z_js.canvasToJpegData(canvas));
7065
7167
  }
7066
7168
  onProgress?.(totalSlides, totalSlides);
7067
7169
  setActiveSlide(currentSlideIndex);
7068
7170
  if (images.length === 0) {
7069
- throw new Error(chunkALO4ZOHQ_js.translationsEn["pptx.export.errorNoSlidesPdf"]);
7171
+ throw new Error(chunkUNIJUD5C_js.translationsEn["pptx.export.errorNoSlidesPdf"]);
7070
7172
  }
7071
- const pdfBlobUrl = chunkB6UIVRFA_js.buildPdfFromImageData(images);
7072
- chunkFJDZ7AEE_js.downloadDataUrl(pdfBlobUrl, filename);
7173
+ const pdfBlobUrl = chunkXBTHWXNO_js.buildPdfFromImageData(images);
7174
+ chunkPCW2KT7Z_js.downloadDataUrl(pdfBlobUrl, filename);
7073
7175
  }
7074
7176
  async function captureAllSlidesAsPngDataUrls(slideStageRef, totalSlides, setActiveSlide, currentSlideIndex, options = {}) {
7075
7177
  const { scale = 2, onProgress } = options;
@@ -7115,10 +7217,10 @@ async function exportAllSlidesAsNotesPdf(slideStageRef, totalSlides, setActiveSl
7115
7217
  onProgress?.(totalSlides, totalSlides);
7116
7218
  setActiveSlide(currentSlideIndex);
7117
7219
  if (pages.length === 0) {
7118
- throw new Error(chunkALO4ZOHQ_js.translationsEn["pptx.export.errorNoSlidesNotesPdf"]);
7220
+ throw new Error(chunkUNIJUD5C_js.translationsEn["pptx.export.errorNoSlidesNotesPdf"]);
7119
7221
  }
7120
- const pdfDataUrl = chunkB6UIVRFA_js.buildNotesPdf(pages);
7121
- chunkFJDZ7AEE_js.downloadDataUrl(pdfDataUrl, filename);
7222
+ const pdfDataUrl = chunkXBTHWXNO_js.buildNotesPdf(pages);
7223
+ chunkPCW2KT7Z_js.downloadDataUrl(pdfDataUrl, filename);
7122
7224
  }
7123
7225
 
7124
7226
  // src/viewer/utils/export-video.ts
@@ -7149,7 +7251,7 @@ async function exportAllSlidesAsVideo(slideStageRef, totalSlides, setActiveSlide
7149
7251
  }
7150
7252
  setActiveSlide(currentSlideIndex);
7151
7253
  if (slideCanvases.length === 0) {
7152
- throw new Error(chunkALO4ZOHQ_js.translationsEn["pptx.export.errorNoSlidesVideo"]);
7254
+ throw new Error(chunkUNIJUD5C_js.translationsEn["pptx.export.errorNoSlidesVideo"]);
7153
7255
  }
7154
7256
  const firstCanvas = slideCanvases[0];
7155
7257
  const recordingCanvas = document.createElement("canvas");
@@ -7157,12 +7259,12 @@ async function exportAllSlidesAsVideo(slideStageRef, totalSlides, setActiveSlide
7157
7259
  recordingCanvas.height = firstCanvas.height;
7158
7260
  const ctx = recordingCanvas.getContext("2d");
7159
7261
  if (!ctx) {
7160
- throw new Error(chunkALO4ZOHQ_js.translationsEn["pptx.export.errorNo2dContext"]);
7262
+ throw new Error(chunkUNIJUD5C_js.translationsEn["pptx.export.errorNo2dContext"]);
7161
7263
  }
7162
7264
  const fps = 30;
7163
7265
  const stream = recordingCanvas.captureStream(fps);
7164
7266
  const recorder = new MediaRecorder(stream, {
7165
- mimeType: chunkFJDZ7AEE_js.pickSupportedMimeType([...chunkFJDZ7AEE_js.WEBM_MIME_CANDIDATES]),
7267
+ mimeType: chunkPCW2KT7Z_js.pickSupportedMimeType([...chunkPCW2KT7Z_js.WEBM_MIME_CANDIDATES]),
7166
7268
  videoBitsPerSecond: 5e6
7167
7269
  });
7168
7270
  const chunks = [];
@@ -7185,8 +7287,8 @@ async function exportAllSlidesAsVideo(slideStageRef, totalSlides, setActiveSlide
7185
7287
  const duration = slideTimingsMs?.[i] ?? slideDurationMs;
7186
7288
  ctx.clearRect(0, 0, recordingCanvas.width, recordingCanvas.height);
7187
7289
  ctx.drawImage(slideCanvases[i], 0, 0);
7188
- const frameInterval = chunkFJDZ7AEE_js.fpsToFrameIntervalMs(fps);
7189
- const framesNeeded = chunkFJDZ7AEE_js.segmentFrameCount(duration, fps);
7290
+ const frameInterval = chunkPCW2KT7Z_js.fpsToFrameIntervalMs(fps);
7291
+ const framesNeeded = chunkPCW2KT7Z_js.segmentFrameCount(duration, fps);
7190
7292
  for (let f = 0; f < framesNeeded; f++) {
7191
7293
  if (signal?.aborted) {
7192
7294
  recorder.stop();
@@ -7233,9 +7335,9 @@ async function exportAllSlidesAsGif(slideStageRef, totalSlides, setActiveSlide,
7233
7335
  }
7234
7336
  setActiveSlide(currentSlideIndex);
7235
7337
  if (frames.length === 0) {
7236
- throw new Error(chunkALO4ZOHQ_js.translationsEn["pptx.export.errorNoSlidesGif"]);
7338
+ throw new Error(chunkUNIJUD5C_js.translationsEn["pptx.export.errorNoSlidesGif"]);
7237
7339
  }
7238
- const gifBytes = chunkFJDZ7AEE_js.encodeGif(frames, Math.round(slideDurationMs / 10));
7340
+ const gifBytes = chunkPCW2KT7Z_js.encodeGif(frames, Math.round(slideDurationMs / 10));
7239
7341
  onProgress?.(totalSlides, totalSlides);
7240
7342
  const buf = new ArrayBuffer(gifBytes.length);
7241
7343
  new Uint8Array(buf).set(gifBytes);
@@ -7289,7 +7391,7 @@ function exportAllSlidesToSvg(data, options = {}) {
7289
7391
  continue;
7290
7392
  }
7291
7393
  onProgress?.(processedCount, data.slides.length);
7292
- let svg = chunkFJDZ7AEE_js.SvgExporter.exportSlide(slide, data.width, data.height, svgOptions);
7394
+ let svg = chunkPCW2KT7Z_js.SvgExporter.exportSlide(slide, data.width, data.height, svgOptions);
7293
7395
  if (embedFonts && fontFaces?.length) {
7294
7396
  svg = injectFontFaces(svg, fontFaces);
7295
7397
  }
@@ -7398,21 +7500,21 @@ function useExportHandlers(input) {
7398
7500
  {
7399
7501
  scale: imageExportScale,
7400
7502
  onProgress: (current, total) => {
7401
- setExportProgress(chunkFJDZ7AEE_js.slideProgressPercent(current, total));
7402
- setExportStatusMessage(chunkFJDZ7AEE_js.slideStatusLabel("Rendering", current, total));
7503
+ setExportProgress(chunkPCW2KT7Z_js.slideProgressPercent(current, total));
7504
+ setExportStatusMessage(chunkPCW2KT7Z_js.slideStatusLabel("Rendering", current, total));
7403
7505
  },
7404
7506
  signal: abortCtrl.signal
7405
7507
  }
7406
7508
  );
7407
- setExportProgress(chunkFJDZ7AEE_js.EXPORT_ASSEMBLING_PERCENT);
7509
+ setExportProgress(chunkPCW2KT7Z_js.EXPORT_ASSEMBLING_PERCENT);
7408
7510
  setExportStatusMessage("Building PDF...");
7409
7511
  await new Promise((r) => {
7410
7512
  setTimeout(r, 100);
7411
7513
  });
7412
- setExportProgress(chunkFJDZ7AEE_js.EXPORT_DONE_PERCENT);
7514
+ setExportProgress(chunkPCW2KT7Z_js.EXPORT_DONE_PERCENT);
7413
7515
  setExportStatusMessage("Done!");
7414
7516
  } catch (err) {
7415
- if (!chunkFJDZ7AEE_js.isExportAbortError(err)) {
7517
+ if (!chunkPCW2KT7Z_js.isExportAbortError(err)) {
7416
7518
  console.error("[PowerPointViewer] PDF export failed:", err);
7417
7519
  }
7418
7520
  } finally {
@@ -7442,21 +7544,21 @@ function useExportHandlers(input) {
7442
7544
  {
7443
7545
  scale: imageExportScale,
7444
7546
  onProgress: (current, total) => {
7445
- setExportProgress(chunkFJDZ7AEE_js.slideProgressPercent(current, total));
7446
- setExportStatusMessage(chunkFJDZ7AEE_js.slideStatusLabel("Rendering", current, total));
7547
+ setExportProgress(chunkPCW2KT7Z_js.slideProgressPercent(current, total));
7548
+ setExportStatusMessage(chunkPCW2KT7Z_js.slideStatusLabel("Rendering", current, total));
7447
7549
  },
7448
7550
  signal: abortCtrl.signal
7449
7551
  }
7450
7552
  );
7451
- setExportProgress(chunkFJDZ7AEE_js.EXPORT_ASSEMBLING_PERCENT);
7553
+ setExportProgress(chunkPCW2KT7Z_js.EXPORT_ASSEMBLING_PERCENT);
7452
7554
  setExportStatusMessage("Building PDF...");
7453
7555
  await new Promise((r) => {
7454
7556
  setTimeout(r, 100);
7455
7557
  });
7456
- setExportProgress(chunkFJDZ7AEE_js.EXPORT_DONE_PERCENT);
7558
+ setExportProgress(chunkPCW2KT7Z_js.EXPORT_DONE_PERCENT);
7457
7559
  setExportStatusMessage("Done!");
7458
7560
  } catch (err) {
7459
- if (!chunkFJDZ7AEE_js.isExportAbortError(err)) {
7561
+ if (!chunkPCW2KT7Z_js.isExportAbortError(err)) {
7460
7562
  console.error("[PowerPointViewer] Notes PDF export failed:", err);
7461
7563
  }
7462
7564
  } finally {
@@ -7498,22 +7600,22 @@ function useExportHandlers(input) {
7498
7600
  scale: 1,
7499
7601
  slideDurationMs: 3e3,
7500
7602
  onProgress: (current, total) => {
7501
- setExportProgress(chunkFJDZ7AEE_js.slideProgressPercent(current, total, 45));
7502
- setExportStatusMessage(chunkFJDZ7AEE_js.slideStatusLabel("Capturing", current, total));
7603
+ setExportProgress(chunkPCW2KT7Z_js.slideProgressPercent(current, total, 45));
7604
+ setExportStatusMessage(chunkPCW2KT7Z_js.slideStatusLabel("Capturing", current, total));
7503
7605
  },
7504
7606
  onRecordProgress: (current, total) => {
7505
- setExportProgress(chunkFJDZ7AEE_js.recordProgressPercent(current, total));
7506
- setExportStatusMessage(chunkFJDZ7AEE_js.slideStatusLabel("Recording", current, total));
7607
+ setExportProgress(chunkPCW2KT7Z_js.recordProgressPercent(current, total));
7608
+ setExportStatusMessage(chunkPCW2KT7Z_js.slideStatusLabel("Recording", current, total));
7507
7609
  },
7508
7610
  signal: abortCtrl.signal
7509
7611
  }
7510
7612
  );
7511
- setExportProgress(chunkFJDZ7AEE_js.EXPORT_ASSEMBLING_PERCENT);
7613
+ setExportProgress(chunkPCW2KT7Z_js.EXPORT_ASSEMBLING_PERCENT);
7512
7614
  setExportStatusMessage("Saving file...");
7513
- chunkFJDZ7AEE_js.downloadBlob(blob, "presentation.webm");
7514
- setExportProgress(chunkFJDZ7AEE_js.EXPORT_DONE_PERCENT);
7615
+ chunkPCW2KT7Z_js.downloadBlob(blob, "presentation.webm");
7616
+ setExportProgress(chunkPCW2KT7Z_js.EXPORT_DONE_PERCENT);
7515
7617
  } catch (err) {
7516
- if (!chunkFJDZ7AEE_js.isExportAbortError(err)) {
7618
+ if (!chunkPCW2KT7Z_js.isExportAbortError(err)) {
7517
7619
  console.error("[PowerPointViewer] Video export failed:", err);
7518
7620
  }
7519
7621
  } finally {
@@ -7541,18 +7643,18 @@ function useExportHandlers(input) {
7541
7643
  scale: 0.5,
7542
7644
  slideDurationMs: 2e3,
7543
7645
  onProgress: (current, total) => {
7544
- setExportProgress(chunkFJDZ7AEE_js.slideProgressPercent(current, total));
7545
- setExportStatusMessage(chunkFJDZ7AEE_js.slideStatusLabel("Encoding", current, total));
7646
+ setExportProgress(chunkPCW2KT7Z_js.slideProgressPercent(current, total));
7647
+ setExportStatusMessage(chunkPCW2KT7Z_js.slideStatusLabel("Encoding", current, total));
7546
7648
  },
7547
7649
  signal: abortCtrl.signal
7548
7650
  }
7549
7651
  );
7550
- setExportProgress(chunkFJDZ7AEE_js.EXPORT_ASSEMBLING_PERCENT);
7652
+ setExportProgress(chunkPCW2KT7Z_js.EXPORT_ASSEMBLING_PERCENT);
7551
7653
  setExportStatusMessage("Saving file...");
7552
- chunkFJDZ7AEE_js.downloadBlob(blob, "presentation.gif");
7553
- setExportProgress(chunkFJDZ7AEE_js.EXPORT_DONE_PERCENT);
7654
+ chunkPCW2KT7Z_js.downloadBlob(blob, "presentation.gif");
7655
+ setExportProgress(chunkPCW2KT7Z_js.EXPORT_DONE_PERCENT);
7554
7656
  } catch (err) {
7555
- if (!chunkFJDZ7AEE_js.isExportAbortError(err)) {
7657
+ if (!chunkPCW2KT7Z_js.isExportAbortError(err)) {
7556
7658
  console.error("[PowerPointViewer] GIF export failed:", err);
7557
7659
  }
7558
7660
  } finally {
@@ -7585,7 +7687,7 @@ function useExportHandlers(input) {
7585
7687
  exportStatusMessage
7586
7688
  };
7587
7689
  }
7588
- var ViewerOptionsContext = react.createContext(chunkFJDZ7AEE_js.DEFAULT_VIEWER_OPTIONS);
7690
+ var ViewerOptionsContext = react.createContext(chunkPCW2KT7Z_js.DEFAULT_VIEWER_OPTIONS);
7589
7691
  function useViewerOptionsContext() {
7590
7692
  return react.useContext(ViewerOptionsContext);
7591
7693
  }
@@ -7597,13 +7699,13 @@ function usePrintHandlers(input) {
7597
7699
  const { t } = reactI18next.useTranslation();
7598
7700
  const viewerOptions = useViewerOptionsContext();
7599
7701
  const includeHiddenSlides = viewerOptions.advanced.printHiddenSlides;
7600
- const printRasterScale = (viewerOptions.advanced.printHighQuality ? 4 : 3) * chunkFJDZ7AEE_js.resolveImageResolutionScale(viewerOptions);
7702
+ const printRasterScale = (viewerOptions.advanced.printHighQuality ? 4 : 3) * chunkPCW2KT7Z_js.resolveImageResolutionScale(viewerOptions);
7601
7703
  const handlePrint = () => {
7602
7704
  setIsPrintDialogOpen(true);
7603
7705
  };
7604
7706
  const handlePrintSvg = async (settings) => {
7605
7707
  setIsPrintDialogOpen(false);
7606
- const printWindow = chunkFJDZ7AEE_js.openPendingPrintWindow(t("pptx.print.preparingToPrint"));
7708
+ const printWindow = chunkPCW2KT7Z_js.openPendingPrintWindow(t("pptx.print.preparingToPrint"));
7607
7709
  if (!printWindow) {
7608
7710
  console.warn(
7609
7711
  "[PowerPointViewer] Print window was blocked by the browser. Allow popups for this site to print."
@@ -7613,9 +7715,9 @@ function usePrintHandlers(input) {
7613
7715
  if (!pptxData || settings.printWhat !== "slides") {
7614
7716
  return runRasterPrint(printWindow, settings);
7615
7717
  }
7616
- const colorFilter = chunkFJDZ7AEE_js.computeColorFilter(settings.colorMode);
7617
- const slideIndices = chunkFJDZ7AEE_js.filterHiddenSlideIndices(
7618
- chunkFJDZ7AEE_js.computeSlideIndices(
7718
+ const colorFilter = chunkPCW2KT7Z_js.computeColorFilter(settings.colorMode);
7719
+ const slideIndices = chunkPCW2KT7Z_js.filterHiddenSlideIndices(
7720
+ chunkPCW2KT7Z_js.computeSlideIndices(
7619
7721
  settings.slideRange,
7620
7722
  activeSlideIndex,
7621
7723
  slides.length,
@@ -7633,22 +7735,22 @@ function usePrintHandlers(input) {
7633
7735
  printWindow.close();
7634
7736
  return;
7635
7737
  }
7636
- const printDoc = chunkFJDZ7AEE_js.buildPrintDocument(svgs, pptxData.width, pptxData.height, {
7738
+ const printDoc = chunkPCW2KT7Z_js.buildPrintDocument(svgs, pptxData.width, pptxData.height, {
7637
7739
  title: "Slides (Vector)",
7638
7740
  orientation: settings.orientation,
7639
7741
  colorFilter,
7640
7742
  scaleToFit: settings.scaleToFit
7641
7743
  });
7642
- chunkFJDZ7AEE_js.finishPrintWindow(printWindow, printDoc);
7744
+ chunkPCW2KT7Z_js.finishPrintWindow(printWindow, printDoc);
7643
7745
  } catch (err) {
7644
7746
  console.warn("[PowerPointViewer] SVG print path failed, falling back to raster:", err);
7645
7747
  return runRasterPrint(printWindow, settings);
7646
7748
  }
7647
7749
  };
7648
7750
  const runRasterPrint = async (printWindow, settings) => {
7649
- const colorFilter = chunkFJDZ7AEE_js.computeColorFilter(settings.colorMode);
7650
- const slideIndices = chunkFJDZ7AEE_js.filterHiddenSlideIndices(
7651
- chunkFJDZ7AEE_js.computeSlideIndices(
7751
+ const colorFilter = chunkPCW2KT7Z_js.computeColorFilter(settings.colorMode);
7752
+ const slideIndices = chunkPCW2KT7Z_js.filterHiddenSlideIndices(
7753
+ chunkPCW2KT7Z_js.computeSlideIndices(
7652
7754
  settings.slideRange,
7653
7755
  activeSlideIndex,
7654
7756
  slides.length,
@@ -7659,11 +7761,11 @@ function usePrintHandlers(input) {
7659
7761
  includeHiddenSlides
7660
7762
  );
7661
7763
  if (settings.printWhat === "outline") {
7662
- chunkFJDZ7AEE_js.finishPrintWindow(
7764
+ chunkPCW2KT7Z_js.finishPrintWindow(
7663
7765
  printWindow,
7664
- chunkFJDZ7AEE_js.buildPrintHtmlDocument({
7766
+ chunkPCW2KT7Z_js.buildPrintHtmlDocument({
7665
7767
  title: "Outline",
7666
- bodyHtml: `<div class="outline-page">${chunkFJDZ7AEE_js.buildOutlineHtml(slideIndices, slides)}</div>`,
7768
+ bodyHtml: `<div class="outline-page">${chunkPCW2KT7Z_js.buildOutlineHtml(slideIndices, slides)}</div>`,
7667
7769
  orientation: settings.orientation,
7668
7770
  colorFilter,
7669
7771
  frameSlides: settings.frameSlides,
@@ -7690,11 +7792,11 @@ function usePrintHandlers(input) {
7690
7792
  }
7691
7793
  const slideImages = slideIndices.map((idx) => allImages[idx]).filter(Boolean);
7692
7794
  if (settings.printWhat === "slides") {
7693
- chunkFJDZ7AEE_js.finishPrintWindow(
7795
+ chunkPCW2KT7Z_js.finishPrintWindow(
7694
7796
  printWindow,
7695
- chunkFJDZ7AEE_js.buildPrintHtmlDocument({
7797
+ chunkPCW2KT7Z_js.buildPrintHtmlDocument({
7696
7798
  title: "Slides",
7697
- bodyHtml: chunkFJDZ7AEE_js.buildSlidesHtml(slideImages, slideIndices),
7799
+ bodyHtml: chunkPCW2KT7Z_js.buildSlidesHtml(slideImages, slideIndices),
7698
7800
  orientation: settings.orientation,
7699
7801
  colorFilter,
7700
7802
  frameSlides: settings.frameSlides,
@@ -7704,11 +7806,11 @@ function usePrintHandlers(input) {
7704
7806
  return;
7705
7807
  }
7706
7808
  if (settings.printWhat === "notes") {
7707
- chunkFJDZ7AEE_js.finishPrintWindow(
7809
+ chunkPCW2KT7Z_js.finishPrintWindow(
7708
7810
  printWindow,
7709
- chunkFJDZ7AEE_js.buildPrintHtmlDocument({
7811
+ chunkPCW2KT7Z_js.buildPrintHtmlDocument({
7710
7812
  title: "Notes Pages",
7711
- bodyHtml: chunkFJDZ7AEE_js.buildNotesHtml(slideImages, slideIndices, slides),
7813
+ bodyHtml: chunkPCW2KT7Z_js.buildNotesHtml(slideImages, slideIndices, slides),
7712
7814
  orientation: "portrait",
7713
7815
  colorFilter,
7714
7816
  frameSlides: settings.frameSlides,
@@ -7719,11 +7821,11 @@ function usePrintHandlers(input) {
7719
7821
  }
7720
7822
  if (settings.printWhat === "handouts") {
7721
7823
  const spp = settings.slidesPerPage;
7722
- chunkFJDZ7AEE_js.finishPrintWindow(
7824
+ chunkPCW2KT7Z_js.finishPrintWindow(
7723
7825
  printWindow,
7724
- chunkFJDZ7AEE_js.buildPrintHtmlDocument({
7826
+ chunkPCW2KT7Z_js.buildPrintHtmlDocument({
7725
7827
  title: `Handout ${spp} per page`,
7726
- bodyHtml: chunkFJDZ7AEE_js.buildHandoutsHtml(slideImages, slideIndices, spp),
7828
+ bodyHtml: chunkPCW2KT7Z_js.buildHandoutsHtml(slideImages, slideIndices, spp, pptxData?.handoutMaster),
7727
7829
  orientation: "portrait",
7728
7830
  colorFilter,
7729
7831
  frameSlides: settings.frameSlides,
@@ -7737,7 +7839,7 @@ function usePrintHandlers(input) {
7737
7839
  };
7738
7840
  const handlePrintWithSettings = async (settings) => {
7739
7841
  setIsPrintDialogOpen(false);
7740
- const printWindow = chunkFJDZ7AEE_js.openPendingPrintWindow(t("pptx.print.preparingToPrint"));
7842
+ const printWindow = chunkPCW2KT7Z_js.openPendingPrintWindow(t("pptx.print.preparingToPrint"));
7741
7843
  if (!printWindow) {
7742
7844
  console.warn(
7743
7845
  "[PowerPointViewer] Print window was blocked by the browser. Allow popups for this site to print."
@@ -7800,8 +7902,8 @@ function useThemeHandlers(input) {
7800
7902
  return;
7801
7903
  }
7802
7904
  await handler.updateThemeColorScheme(colorScheme);
7803
- const previousMap = theme?.colorScheme ? chunkFJDZ7AEE_js.buildThemeColorMap(theme.colorScheme) : {};
7804
- setSlides((prev) => chunkFJDZ7AEE_js.reResolveSlideColors(prev, previousMap, colorScheme));
7905
+ const previousMap = theme?.colorScheme ? chunkPCW2KT7Z_js.buildThemeColorMap(theme.colorScheme) : {};
7906
+ setSlides((prev) => chunkPCW2KT7Z_js.reResolveSlideColors(prev, previousMap, colorScheme));
7805
7907
  setTheme((prev) => prev ? { ...prev, colorScheme } : { colorScheme });
7806
7908
  bumpHistory();
7807
7909
  history.markDirty();
@@ -7906,7 +8008,7 @@ function useThemeSwitching(input) {
7906
8008
  }
7907
8009
  try {
7908
8010
  await handler.applyTheme(preset.colorScheme, preset.fontScheme, preset.name);
7909
- const newData = chunkFJDZ7AEE_js.applyThemeToData(data, preset.colorScheme, preset.fontScheme, preset.name);
8011
+ const newData = chunkPCW2KT7Z_js.applyThemeToData(data, preset.colorScheme, preset.fontScheme, preset.name);
7910
8012
  onDataChange(newData);
7911
8013
  onThemeChanged?.(preset);
7912
8014
  } catch (error) {
@@ -7923,7 +8025,7 @@ function useThemeSwitching(input) {
7923
8025
  }
7924
8026
  try {
7925
8027
  await handler.applyTheme(colorScheme, fontScheme ?? {}, themeName);
7926
- const newData = chunkFJDZ7AEE_js.applyThemeToData(data, colorScheme, fontScheme, themeName);
8028
+ const newData = chunkPCW2KT7Z_js.applyThemeToData(data, colorScheme, fontScheme, themeName);
7927
8029
  onDataChange(newData);
7928
8030
  } catch (error) {
7929
8031
  console.error("Failed to switch to custom theme:", error);
@@ -7935,12 +8037,12 @@ function useThemeSwitching(input) {
7935
8037
  if (!data?.theme?.colorScheme) {
7936
8038
  return void 0;
7937
8039
  }
7938
- return chunkFJDZ7AEE_js.THEME_PRESETS.find(
7939
- (p) => chunkFJDZ7AEE_js.themeColorSchemesEqual(data.theme?.colorScheme, p.colorScheme)
8040
+ return chunkPCW2KT7Z_js.THEME_PRESETS.find(
8041
+ (p) => chunkPCW2KT7Z_js.themeColorSchemesEqual(data.theme?.colorScheme, p.colorScheme)
7940
8042
  );
7941
8043
  }, [data?.theme?.colorScheme]);
7942
8044
  return {
7943
- presets: chunkFJDZ7AEE_js.THEME_PRESETS,
8045
+ presets: chunkPCW2KT7Z_js.THEME_PRESETS,
7944
8046
  switchToPreset,
7945
8047
  switchToCustom,
7946
8048
  currentPreset
@@ -8015,7 +8117,7 @@ function usePropertyHandlers(input) {
8015
8117
  }
8016
8118
  try {
8017
8119
  const ab = await file.arrayBuffer();
8018
- const h = new chunkFJDZ7AEE_js.PptxHandler();
8120
+ const h = new chunkPCW2KT7Z_js.PptxHandler();
8019
8121
  const other = await h.load(ab);
8020
8122
  if (!other) {
8021
8123
  return;
@@ -8025,7 +8127,7 @@ function usePropertyHandlers(input) {
8025
8127
  width: canvasSize.width,
8026
8128
  height: canvasSize.height
8027
8129
  };
8028
- setCompareResult(chunkFJDZ7AEE_js.comparePresentation(cur, other));
8130
+ setCompareResult(chunkPCW2KT7Z_js.comparePresentation(cur, other));
8029
8131
  setIsComparePanelOpen(true);
8030
8132
  } catch (err) {
8031
8133
  console.warn("Compare failed:", err);
@@ -8042,7 +8144,7 @@ function usePropertyHandlers(input) {
8042
8144
  if (!diff || diff.status === "unchanged") {
8043
8145
  return;
8044
8146
  }
8045
- setSlides((prev) => chunkFJDZ7AEE_js.applyAcceptSlide(prev, diff));
8147
+ setSlides((prev) => chunkPCW2KT7Z_js.applyAcceptSlide(prev, diff));
8046
8148
  setIsDirty(true);
8047
8149
  },
8048
8150
  [compareResult, setSlides, setIsDirty]
@@ -8053,10 +8155,10 @@ function usePropertyHandlers(input) {
8053
8155
  if (!compareResult) {
8054
8156
  return;
8055
8157
  }
8056
- setSlides((prev) => chunkFJDZ7AEE_js.applyAcceptAllSlides(prev, compareResult));
8158
+ setSlides((prev) => chunkPCW2KT7Z_js.applyAcceptAllSlides(prev, compareResult));
8057
8159
  setIsDirty(true);
8058
8160
  }, [compareResult, setSlides, setIsDirty]);
8059
- const usedFontFamilies = react.useMemo(() => chunkFJDZ7AEE_js.collectUsedFonts(slides), [slides]);
8161
+ const usedFontFamilies = react.useMemo(() => chunkPCW2KT7Z_js.collectUsedFonts(slides), [slides]);
8060
8162
  return {
8061
8163
  handleUpdateNotes,
8062
8164
  handleUpdateSlide,
@@ -8211,7 +8313,7 @@ function useViewerDialogs(input) {
8211
8313
  );
8212
8314
  const embeddedFontKey = (embeddedFontFamilies ?? []).join("\0");
8213
8315
  const fontEmbedding = react.useMemo(
8214
- () => chunkFJDZ7AEE_js.describeFontEmbedding(embeddedFontKey ? embeddedFontKey.split("\0") : []),
8316
+ () => chunkPCW2KT7Z_js.describeFontEmbedding(embeddedFontKey ? embeddedFontKey.split("\0") : []),
8215
8317
  [embeddedFontKey]
8216
8318
  );
8217
8319
  const [embedFontsEnabled, setEmbedFontsEnabled] = react.useState(fontEmbedding.initialEnabled);
@@ -8221,11 +8323,11 @@ function useViewerDialogs(input) {
8221
8323
  setEmbedFontsEnabled(fontEmbedding.initialEnabled);
8222
8324
  }
8223
8325
  const [isNarrowViewport, setIsNarrowViewport] = react.useState(
8224
- () => typeof window !== "undefined" ? chunkFJDZ7AEE_js.isMobileViewport(window.innerWidth, window.innerHeight, viewportIsTouch()) : false
8326
+ () => typeof window !== "undefined" ? chunkPCW2KT7Z_js.isMobileViewport(window.innerWidth, window.innerHeight, viewportIsTouch()) : false
8225
8327
  );
8226
8328
  react.useEffect(() => {
8227
8329
  const handleWindow = () => setIsNarrowViewport(
8228
- chunkFJDZ7AEE_js.isMobileViewport(window.innerWidth, window.innerHeight, viewportIsTouch())
8330
+ chunkPCW2KT7Z_js.isMobileViewport(window.innerWidth, window.innerHeight, viewportIsTouch())
8229
8331
  );
8230
8332
  window.addEventListener("resize", handleWindow);
8231
8333
  return () => window.removeEventListener("resize", handleWindow);
@@ -8378,15 +8480,16 @@ function useViewerDialogs(input) {
8378
8480
  };
8379
8481
  }
8380
8482
  function computeGridSpacingPx2(documentGridSpacing) {
8381
- return chunkFJDZ7AEE_js.computeGridSpacingPx(documentGridSpacing, chunkB6UIVRFA_js.GRID_SIZE);
8483
+ return chunkPCW2KT7Z_js.computeGridSpacingPx(documentGridSpacing, chunkXBTHWXNO_js.GRID_SIZE);
8382
8484
  }
8383
- function computeVisibleSlideIndexes(slides, activeCustomShowId, customShows) {
8485
+ function computeVisibleSlideIndexes(slides, activeCustomShowId, customShows, presentationProperties) {
8384
8486
  const activeShow = activeCustomShowId ? customShows.find((show) => show.id === activeCustomShowId) : void 0;
8385
- return chunkFJDZ7AEE_js.resolveShowSlideIndexes(slides, activeShow);
8487
+ const authoredRange = chunkPCW2KT7Z_js.resolveAuthoredSlideRange(presentationProperties, slides.length);
8488
+ return chunkPCW2KT7Z_js.resolveShowSlideIndexes(slides, activeShow, authoredRange);
8386
8489
  }
8387
8490
  function computeSlideSectionGroups(slides, sections) {
8388
- return chunkFJDZ7AEE_js.groupSlidesBySection(sections, slides).map((group) => ({
8389
- id: group.section?.id ?? (sections.length > 0 ? chunkB6UIVRFA_js.UNGROUPED_SECTION_ID : chunkB6UIVRFA_js.DEFAULT_SECTION_GROUP_ID),
8491
+ return chunkPCW2KT7Z_js.groupSlidesBySection(sections, slides).map((group) => ({
8492
+ id: group.section?.id ?? (sections.length > 0 ? chunkXBTHWXNO_js.UNGROUPED_SECTION_ID : chunkXBTHWXNO_js.DEFAULT_SECTION_GROUP_ID),
8390
8493
  label: group.section?.name ?? (sections.length > 0 ? "Ungrouped Slides" : "Slides"),
8391
8494
  slideIndexes: group.slideIndexes,
8392
8495
  ...group.section?.color !== void 0 ? { color: group.section.color } : {},
@@ -8398,7 +8501,7 @@ function computeMasterPseudoSlide(mode, activeLayout, activeMaster) {
8398
8501
  return void 0;
8399
8502
  }
8400
8503
  const document2 = activeLayout ? { slideMasters: [{ ...activeMaster, layouts: [activeLayout] }] } : { slideMasters: [activeMaster] };
8401
- return chunkFJDZ7AEE_js.masterViewPseudoSlide(document2, {
8504
+ return chunkPCW2KT7Z_js.masterViewPseudoSlide(document2, {
8402
8505
  tab: "slides",
8403
8506
  masterIndex: 0,
8404
8507
  layoutIndex: activeLayout ? 0 : null
@@ -8411,6 +8514,7 @@ function useDerivedSlideState(input) {
8411
8514
  sections,
8412
8515
  customShows,
8413
8516
  activeCustomShowId,
8517
+ presentationProperties,
8414
8518
  mode,
8415
8519
  activeLayout,
8416
8520
  activeMaster,
@@ -8421,15 +8525,19 @@ function useDerivedSlideState(input) {
8421
8525
  [documentGridSpacing]
8422
8526
  );
8423
8527
  const visibleSlideIndexes = react.useMemo(
8424
- () => computeVisibleSlideIndexes(slides, activeCustomShowId, customShows),
8425
- [slides, activeCustomShowId, customShows]
8528
+ () => computeVisibleSlideIndexes(slides, activeCustomShowId, customShows, presentationProperties),
8529
+ [slides, activeCustomShowId, customShows, presentationProperties]
8530
+ );
8531
+ const authoredRange = react.useMemo(
8532
+ () => chunkPCW2KT7Z_js.resolveAuthoredSlideRange(presentationProperties, slides.length),
8533
+ [presentationProperties, slides.length]
8426
8534
  );
8427
8535
  const slideSectionGroups = react.useMemo(
8428
8536
  () => computeSlideSectionGroups(slides, sections).map((group) => {
8429
- if (group.id === chunkB6UIVRFA_js.UNGROUPED_SECTION_ID && group.label === "Ungrouped Slides") {
8537
+ if (group.id === chunkXBTHWXNO_js.UNGROUPED_SECTION_ID && group.label === "Ungrouped Slides") {
8430
8538
  return { ...group, label: t("pptx.slides.ungroupedSlides") };
8431
8539
  }
8432
- if (group.id === chunkB6UIVRFA_js.DEFAULT_SECTION_GROUP_ID && group.label === "Slides") {
8540
+ if (group.id === chunkXBTHWXNO_js.DEFAULT_SECTION_GROUP_ID && group.label === "Slides") {
8433
8541
  return { ...group, label: t("pptx.sections.slides") };
8434
8542
  }
8435
8543
  return group;
@@ -8444,7 +8552,8 @@ function useDerivedSlideState(input) {
8444
8552
  gridSpacingPx,
8445
8553
  visibleSlideIndexes,
8446
8554
  slideSectionGroups,
8447
- masterPseudoSlide
8555
+ masterPseudoSlide,
8556
+ authoredRange
8448
8557
  };
8449
8558
  }
8450
8559
  function useAnnotationHandlers(input) {
@@ -8529,13 +8638,13 @@ function useAnnotationHandlers(input) {
8529
8638
  }, [annotations, setMode, setSlides, history]);
8530
8639
  const handleSetMode = react.useCallback(
8531
8640
  (nextMode) => {
8532
- if (mode === "present" && nextMode !== "present" && !chunkFJDZ7AEE_js.mayLeaveSlideShow()) {
8641
+ if (mode === "present" && nextMode !== "present" && !chunkPCW2KT7Z_js.mayLeaveSlideShow()) {
8533
8642
  return;
8534
8643
  }
8535
8644
  if (nextMode === "present") {
8536
8645
  presentation.enterPresentMode();
8537
8646
  } else if (mode === "present" && annotations.hasAnyAnnotations) {
8538
- chunkFJDZ7AEE_js.stopAllPersistentAudio();
8647
+ chunkPCW2KT7Z_js.stopAllPersistentAudio();
8539
8648
  if (promptKeepInkAnnotations) {
8540
8649
  pendingModeAfterAnnotationsRef.current = nextMode;
8541
8650
  setShowKeepAnnotationsDialog(true);
@@ -8545,7 +8654,7 @@ function useAnnotationHandlers(input) {
8545
8654
  }
8546
8655
  } else {
8547
8656
  if (mode === "present") {
8548
- chunkFJDZ7AEE_js.stopAllPersistentAudio();
8657
+ chunkPCW2KT7Z_js.stopAllPersistentAudio();
8549
8658
  }
8550
8659
  setMode(nextMode);
8551
8660
  }
@@ -8582,6 +8691,7 @@ function useSerialize(input) {
8582
8691
  guides,
8583
8692
  headerFooter,
8584
8693
  presentationProperties,
8694
+ viewProperties,
8585
8695
  customShows,
8586
8696
  sections,
8587
8697
  coreProperties,
@@ -8609,13 +8719,13 @@ function useSerialize(input) {
8609
8719
  let processedSlide = slide;
8610
8720
  if (pendingEditId) {
8611
8721
  const updatedElements = slide.elements.map((el) => {
8612
- if (el.id !== pendingEditId || !chunkFJDZ7AEE_js.hasTextProperties(el)) {
8722
+ if (el.id !== pendingEditId || !chunkPCW2KT7Z_js.hasTextProperties(el)) {
8613
8723
  return el;
8614
8724
  }
8615
8725
  return {
8616
8726
  ...el,
8617
8727
  text: pendingEditText,
8618
- textSegments: chunkFJDZ7AEE_js.remapTextToSegments(pendingEditText, el.textSegments, el.textStyle)
8728
+ textSegments: chunkPCW2KT7Z_js.remapTextToSegments(pendingEditText, el.textSegments, el.textStyle)
8619
8729
  };
8620
8730
  });
8621
8731
  if (updatedElements.some((el, i) => el !== slide.elements[i])) {
@@ -8628,21 +8738,22 @@ function useSerialize(input) {
8628
8738
  const pptxGuides = guides.map((g) => ({
8629
8739
  id: g.id,
8630
8740
  orientation: g.axis === "h" ? "horz" : "vert",
8631
- positionEmu: chunkFJDZ7AEE_js.guidePxToEmu(g.position)
8741
+ positionEmu: chunkPCW2KT7Z_js.guidePxToEmu(g.position)
8632
8742
  }));
8633
8743
  return {
8634
8744
  ...processedSlide,
8635
8745
  guides: pptxGuides.length > 0 ? pptxGuides : void 0
8636
8746
  };
8637
8747
  });
8638
- const slidesToSave = chunkFJDZ7AEE_js.buildSaveSlides(slidesWithGuides, templateElementsBySlideId);
8748
+ const slidesToSave = chunkPCW2KT7Z_js.buildSaveSlides(slidesWithGuides, templateElementsBySlideId);
8639
8749
  const saveOptions = {
8640
8750
  // Without this the Slide Size card edited a viewer-only pixel value and
8641
8751
  // the saved `p:sldSz` never moved: passing `slideSize` is the only way a
8642
8752
  // slide-size edit reaches the file.
8643
- slideSize: chunkFJDZ7AEE_js.resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size,
8753
+ slideSize: chunkPCW2KT7Z_js.resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size,
8644
8754
  headerFooter,
8645
8755
  presentationProperties,
8756
+ viewProperties,
8646
8757
  customShows: customShows.length > 0 ? customShows : void 0,
8647
8758
  sections: sections.length > 0 ? sections : void 0,
8648
8759
  coreProperties,
@@ -8652,9 +8763,9 @@ function useSerialize(input) {
8652
8763
  slideMasters,
8653
8764
  notesMaster,
8654
8765
  handoutMaster,
8655
- ...chunkFJDZ7AEE_js.embeddedFontSaveOptions(embedFonts)
8766
+ ...chunkPCW2KT7Z_js.embeddedFontSaveOptions(embedFonts)
8656
8767
  };
8657
- return chunkFJDZ7AEE_js.saveDeckWithPassword(handler, slidesToSave, saveOptions, { password, purpose });
8768
+ return chunkPCW2KT7Z_js.saveDeckWithPassword(handler, slidesToSave, saveOptions, { password, purpose });
8658
8769
  }, [
8659
8770
  slides,
8660
8771
  templateElementsBySlideId,
@@ -8662,6 +8773,7 @@ function useSerialize(input) {
8662
8773
  slideSizeEmu,
8663
8774
  headerFooter,
8664
8775
  presentationProperties,
8776
+ viewProperties,
8665
8777
  customShows,
8666
8778
  sections,
8667
8779
  coreProperties,
@@ -8689,7 +8801,7 @@ function useRecoveryDetection(input) {
8689
8801
  const onRestore = input.onRestore;
8690
8802
  const openVersionHistory = input.openVersionHistory;
8691
8803
  react.useEffect(() => {
8692
- if (!chunkFJDZ7AEE_js.shouldProbeAutosaveRecovery({
8804
+ if (!chunkPCW2KT7Z_js.shouldProbeAutosaveRecovery({
8693
8805
  alreadyChecked: recoveryCheckedRef.current,
8694
8806
  filePath,
8695
8807
  loading,
@@ -8701,7 +8813,7 @@ function useRecoveryDetection(input) {
8701
8813
  }
8702
8814
  recoveryCheckedRef.current = true;
8703
8815
  void (async () => {
8704
- const offer = await chunkFJDZ7AEE_js.probeAutosaveRecovery(filePath);
8816
+ const offer = await chunkPCW2KT7Z_js.probeAutosaveRecovery(filePath);
8705
8817
  if (!offer) {
8706
8818
  return;
8707
8819
  }
@@ -8714,7 +8826,7 @@ function useRecoveryDetection(input) {
8714
8826
  const record = recordRef.current;
8715
8827
  setPrompt(null);
8716
8828
  if (record && onRestore) {
8717
- onRestore(chunkFJDZ7AEE_js.acceptAutosaveRecovery(record));
8829
+ onRestore(chunkPCW2KT7Z_js.acceptAutosaveRecovery(record));
8718
8830
  }
8719
8831
  recordRef.current = null;
8720
8832
  }, [onRestore]);
@@ -8723,7 +8835,7 @@ function useRecoveryDetection(input) {
8723
8835
  setPrompt(null);
8724
8836
  recordRef.current = null;
8725
8837
  if (record) {
8726
- void chunkFJDZ7AEE_js.discardAutosaveRecovery(record);
8838
+ void chunkPCW2KT7Z_js.discardAutosaveRecovery(record);
8727
8839
  }
8728
8840
  }, []);
8729
8841
  return { prompt, restore, discard };
@@ -8732,6 +8844,7 @@ function usePresentationSetup(input) {
8732
8844
  const {
8733
8845
  mode,
8734
8846
  slides,
8847
+ templateElementsBySlideId,
8735
8848
  visibleSlideIndexes,
8736
8849
  activeSlideIndex,
8737
8850
  containerRef,
@@ -8745,7 +8858,10 @@ function usePresentationSetup(input) {
8745
8858
  endWithBlackSlide = true,
8746
8859
  promptKeepInkAnnotations = true,
8747
8860
  popupToolbarEnabled = true,
8748
- onToggleSubtitles
8861
+ onToggleSubtitles,
8862
+ customShows = [],
8863
+ activeCustomShowId = null,
8864
+ onSetActiveCustomShowId
8749
8865
  } = input;
8750
8866
  const actionSoundHandlerRef = react.useRef(null);
8751
8867
  const exitModeHandlerRef = react.useRef(null);
@@ -8757,16 +8873,17 @@ function usePresentationSetup(input) {
8757
8873
  const presentation = usePresentationMode({
8758
8874
  mode,
8759
8875
  slides,
8876
+ templateElementsBySlideId,
8760
8877
  visibleSlideIndexes,
8761
8878
  activeSlideIndex,
8762
8879
  containerRef,
8763
8880
  content,
8764
8881
  onSetMode: (nextMode) => {
8765
- if (mode === "present" && nextMode !== "present" && !chunkFJDZ7AEE_js.mayLeaveSlideShow()) {
8882
+ if (mode === "present" && nextMode !== "present" && !chunkPCW2KT7Z_js.mayLeaveSlideShow()) {
8766
8883
  return;
8767
8884
  }
8768
8885
  if (mode === "present" && nextMode !== "present") {
8769
- chunkFJDZ7AEE_js.stopAllPersistentAudio();
8886
+ chunkPCW2KT7Z_js.stopAllPersistentAudio();
8770
8887
  stopAnimationSound();
8771
8888
  const exitHandler = exitModeHandlerRef.current;
8772
8889
  if (exitHandler) {
@@ -8828,13 +8945,16 @@ function usePresentationSetup(input) {
8828
8945
  onToggleToolbar: () => annotations.setToolbarVisible(!annotations.toolbarVisible),
8829
8946
  onToggleSubtitles,
8830
8947
  onSaveRehearsalTimings: (timings) => {
8831
- setSlides((prev) => chunkFJDZ7AEE_js.applyRehearsalTimings(prev, timings));
8948
+ setSlides((prev) => chunkPCW2KT7Z_js.applyRehearsalTimings(prev, timings));
8832
8949
  history.markDirty();
8833
8950
  },
8834
- loopContinuously: chunkFJDZ7AEE_js.shouldLoopContinuously(presentationProperties),
8951
+ loopContinuously: chunkPCW2KT7Z_js.shouldLoopContinuously(presentationProperties),
8835
8952
  showWithAnimation: presentationProperties.showWithAnimation,
8836
8953
  useTimings: presentationProperties.advanceMode !== "manual",
8837
- endWithBlackSlide
8954
+ endWithBlackSlide,
8955
+ customShows,
8956
+ activeCustomShowId,
8957
+ onSetActiveCustomShowId
8838
8958
  });
8839
8959
  return {
8840
8960
  presentation,
@@ -9032,7 +9152,7 @@ function useEditorOperations(input) {
9032
9152
  const { formatPainterActive, setFormatPainterActive, elementLookup } = state;
9033
9153
  react.useEffect(() => {
9034
9154
  if (formatPainterActive && !prevFormatPainterRef.current && selectedElement) {
9035
- copiedFormatRef.current = chunkFJDZ7AEE_js.copyFormatFromElement(selectedElement);
9155
+ copiedFormatRef.current = chunkPCW2KT7Z_js.copyFormatFromElement(selectedElement);
9036
9156
  } else if (!formatPainterActive) {
9037
9157
  copiedFormatRef.current = null;
9038
9158
  }
@@ -9058,12 +9178,12 @@ function useEditorOperations(input) {
9058
9178
  e.stopPropagation();
9059
9179
  const element = elementLookup.get(elementId);
9060
9180
  if (element) {
9061
- const updated = chunkFJDZ7AEE_js.applyFormatToElement(element, copiedFormatRef.current);
9181
+ const updated = chunkPCW2KT7Z_js.applyFormatToElement(element, copiedFormatRef.current);
9062
9182
  const updates = {};
9063
- if (chunkFJDZ7AEE_js.hasShapeProperties(updated)) {
9183
+ if (chunkPCW2KT7Z_js.hasShapeProperties(updated)) {
9064
9184
  updates.shapeStyle = updated.shapeStyle;
9065
9185
  }
9066
- if (chunkFJDZ7AEE_js.hasTextProperties(updated)) {
9186
+ if (chunkPCW2KT7Z_js.hasTextProperties(updated)) {
9067
9187
  updates.textStyle = updated.textStyle;
9068
9188
  }
9069
9189
  ops.updateElementById(elementId, updates);
@@ -9249,10 +9369,10 @@ function useFontInjection({ embeddedFonts, slides }) {
9249
9369
  }
9250
9370
  };
9251
9371
  }, [embeddedFonts]);
9252
- const referencedFamilies = react.useMemo(() => chunkFJDZ7AEE_js.collectReferencedFontFamilies(slides), [slides]);
9372
+ const referencedFamilies = react.useMemo(() => chunkPCW2KT7Z_js.collectReferencedFontFamilies(slides), [slides]);
9253
9373
  react.useEffect(() => {
9254
9374
  let cancelled = false;
9255
- void chunkFJDZ7AEE_js.resolveGoogleWebfontHref(slides, embeddedFonts).then((href) => {
9375
+ void chunkPCW2KT7Z_js.resolveGoogleWebfontHref(slides, embeddedFonts).then((href) => {
9256
9376
  if (cancelled) {
9257
9377
  return null;
9258
9378
  }
@@ -9318,7 +9438,9 @@ function useContentLifecycle(input) {
9318
9438
  setIsEncryptedDialogOpen,
9319
9439
  password,
9320
9440
  onContentApplied,
9321
- allowExternalImages
9441
+ allowExternalImages,
9442
+ setReadOnlyRecommendation,
9443
+ setCompatToasts
9322
9444
  } = input;
9323
9445
  const { handlerRef } = useLoadContent({
9324
9446
  content,
@@ -9332,6 +9454,8 @@ function useContentLifecycle(input) {
9332
9454
  setHeaderFooter: state.setHeaderFooter,
9333
9455
  setLayoutOptions: state.setLayoutOptions,
9334
9456
  setSlideMasters: state.setSlideMasters,
9457
+ setModernCommentAuthors: state.setModernCommentAuthors,
9458
+ setRecentColors: state.setRecentColors,
9335
9459
  setTheme: state.setTheme,
9336
9460
  setTableStyleMap: state.setTableStyleMap,
9337
9461
  setThemeOptions: state.setThemeOptions,
@@ -9353,6 +9477,8 @@ function useContentLifecycle(input) {
9353
9477
  setHasDigitalSignatures: state.setHasDigitalSignatures,
9354
9478
  setDigitalSignatureCount: state.setDigitalSignatureCount,
9355
9479
  setGuides: state.setGuides,
9480
+ setReadOnlyRecommendation,
9481
+ setCompatToasts,
9356
9482
  setLoading: state.setLoading,
9357
9483
  setError: state.setError,
9358
9484
  setIsDirty: state.setIsDirty,
@@ -9373,6 +9499,7 @@ function useContentLifecycle(input) {
9373
9499
  guides: state.guides,
9374
9500
  headerFooter: state.headerFooter,
9375
9501
  presentationProperties: state.presentationProperties,
9502
+ viewProperties: state.viewProperties,
9376
9503
  customShows: state.customShows,
9377
9504
  sections: state.sections,
9378
9505
  coreProperties: state.coreProperties,
@@ -9428,7 +9555,17 @@ function useKeyboardShortcuts(input) {
9428
9555
  inputRef.current = input;
9429
9556
  const handleKeyDown = react.useCallback((e) => {
9430
9557
  const current = inputRef.current;
9431
- const { action, dx, dy } = chunkFJDZ7AEE_js.mapEditorKey(e, {
9558
+ const startAction = chunkPCW2KT7Z_js.mapSlideShowStartKey(e, { isPresenting: current.mode === "present" });
9559
+ if (startAction !== null) {
9560
+ e.preventDefault();
9561
+ if (startAction === "fromBeginning") {
9562
+ current.onStartShowFromBeginning();
9563
+ } else {
9564
+ current.onStartShowFromCurrent();
9565
+ }
9566
+ return;
9567
+ }
9568
+ const { action, dx, dy } = chunkPCW2KT7Z_js.mapEditorKey(e, {
9432
9569
  canEdit: current.canEdit,
9433
9570
  // The Slide Master view is an editing surface, not a viewing one.
9434
9571
  // Gating on `mode !== 'edit'` alone made `mapEditorKey` return
@@ -9441,7 +9578,7 @@ function useKeyboardShortcuts(input) {
9441
9578
  hasSelection: current.hasSelection,
9442
9579
  isEditingText: Boolean(current.inlineEditingElementId || current.tableEditorState?.isEditing),
9443
9580
  isDrawing: current.activeTool !== "select",
9444
- isTextInputTarget: chunkFJDZ7AEE_js.isEditorTextInputTarget(e.target)
9581
+ isTextInputTarget: chunkPCW2KT7Z_js.isEditorTextInputTarget(e.target)
9445
9582
  });
9446
9583
  if (action === null) {
9447
9584
  return;
@@ -9508,7 +9645,18 @@ function useKeyboardShortcuts(input) {
9508
9645
 
9509
9646
  // src/viewer/hooks/useKeyboardShortcutWiring.ts
9510
9647
  function useKeyboardShortcutWiring(input) {
9511
- const { state, mode, canEdit, slides, activeSlide, ops, manipulation, history } = input;
9648
+ const {
9649
+ state,
9650
+ mode,
9651
+ canEdit,
9652
+ slides,
9653
+ activeSlide,
9654
+ ops,
9655
+ manipulation,
9656
+ history,
9657
+ onEnterPresentModeFromBeginning,
9658
+ onSetMode
9659
+ } = input;
9512
9660
  useKeyboardShortcuts({
9513
9661
  containerRef: state.containerRef,
9514
9662
  mode,
@@ -9578,7 +9726,9 @@ function useKeyboardShortcutWiring(input) {
9578
9726
  return;
9579
9727
  }
9580
9728
  state.setActiveSlideIndex((prev) => Math.min(slides.length - 1, prev + 1));
9581
- }
9729
+ },
9730
+ onStartShowFromBeginning: onEnterPresentModeFromBeginning,
9731
+ onStartShowFromCurrent: () => onSetMode("present")
9582
9732
  });
9583
9733
  }
9584
9734
  function useViewerIntegration(input) {
@@ -9598,6 +9748,8 @@ function useViewerIntegration(input) {
9598
9748
  autosaveAllowed = true,
9599
9749
  autosaveIntervalMs,
9600
9750
  allowExternalImages,
9751
+ setReadOnlyRecommendation,
9752
+ setCompatToasts,
9601
9753
  canEdit,
9602
9754
  promptKeepInkAnnotations,
9603
9755
  imageExportScale,
@@ -9666,7 +9818,9 @@ function useViewerIntegration(input) {
9666
9818
  setIsEncryptedDialogOpen,
9667
9819
  password: dialogs.presentationPassword ?? void 0,
9668
9820
  onContentApplied: () => setLoadVersion((v) => v + 1),
9669
- allowExternalImages
9821
+ allowExternalImages,
9822
+ setReadOnlyRecommendation,
9823
+ setCompatToasts
9670
9824
  }
9671
9825
  );
9672
9826
  const { exportHandlers, printHandlers, themeHandlers, propertyHandlers } = useIOHandlers({
@@ -9752,7 +9906,7 @@ function useViewerIntegration(input) {
9752
9906
  return zoom.scale;
9753
9907
  },
9754
9908
  setZoom(level) {
9755
- zoom.setScale(chunkFJDZ7AEE_js.clampZoomScale(level));
9909
+ zoom.setScale(chunkPCW2KT7Z_js.clampZoomScale(level));
9756
9910
  },
9757
9911
  zoomIn() {
9758
9912
  zoom.handleZoomIn();
@@ -9901,7 +10055,9 @@ function useViewerIntegration(input) {
9901
10055
  activeSlide,
9902
10056
  ops: editorOps.ops,
9903
10057
  manipulation: editorOps.manipulation,
9904
- history
10058
+ history,
10059
+ onEnterPresentModeFromBeginning: presentation.enterPresentModeFromBeginning,
10060
+ onSetMode: handleSetMode
9905
10061
  });
9906
10062
  return {
9907
10063
  exportHandlers,
@@ -9968,7 +10124,7 @@ function useReducedMotion() {
9968
10124
  }
9969
10125
  function useViewerOptions() {
9970
10126
  const storeRef = react.useRef(null);
9971
- storeRef.current ??= chunkFJDZ7AEE_js.createViewerOptionsStore();
10127
+ storeRef.current ??= chunkPCW2KT7Z_js.createViewerOptionsStore();
9972
10128
  const store = storeRef.current;
9973
10129
  const options = react.useSyncExternalStore(
9974
10130
  (onStoreChange) => store.subscribe(onStoreChange),
@@ -9977,9 +10133,9 @@ function useViewerOptions() {
9977
10133
  );
9978
10134
  return { optionsStore: store, options };
9979
10135
  }
9980
- var KNOWN_TAB_IDS = new Set(chunkFJDZ7AEE_js.TOOLBAR_TABS.map((tab) => tab.id));
10136
+ var KNOWN_TAB_IDS = new Set(chunkPCW2KT7Z_js.TOOLBAR_TABS.map((tab) => tab.id));
9981
10137
  function computeToolbarVisibility(hiddenActions, hiddenTabIds = []) {
9982
- const isHidden = (id) => chunkFJDZ7AEE_js.isActionHidden(id, hiddenActions);
10138
+ const isHidden = (id) => chunkPCW2KT7Z_js.isActionHidden(id, hiddenActions);
9983
10139
  const userHidden = new Set(hiddenTabIds);
9984
10140
  userHidden.delete("file");
9985
10141
  const isTabVisible = (id) => !KNOWN_TAB_IDS.has(id) || !isHidden(id) && !userHidden.has(id);
@@ -10071,12 +10227,12 @@ function useYjsDocumentSync({
10071
10227
  return;
10072
10228
  }
10073
10229
  try {
10074
- const handler = new chunkFJDZ7AEE_js.PptxHandler();
10230
+ const handler = new chunkPCW2KT7Z_js.PptxHandler();
10075
10231
  await handler.load(sourceBytes.buffer);
10076
- const currentSlides = chunkFJDZ7AEE_js.readSlidesFromYDoc(
10232
+ const currentSlides = chunkPCW2KT7Z_js.readSlidesFromYDoc(
10077
10233
  doc
10078
10234
  );
10079
- const slidesToSave = chunkFJDZ7AEE_js.buildSaveSlides(currentSlides, templateElementsBySlideId);
10235
+ const slidesToSave = chunkPCW2KT7Z_js.buildSaveSlides(currentSlides, templateElementsBySlideId);
10080
10236
  const bytes = await handler.save(slidesToSave);
10081
10237
  config.onWriteBack(bytes);
10082
10238
  } catch {
@@ -10091,10 +10247,10 @@ function useYjsDocumentSync({
10091
10247
  if (!doc || !isConnected) {
10092
10248
  return;
10093
10249
  }
10094
- const docSlides = chunkFJDZ7AEE_js.readSlidesFromYDoc(
10250
+ const docSlides = chunkPCW2KT7Z_js.readSlidesFromYDoc(
10095
10251
  doc
10096
10252
  );
10097
- if (!chunkFJDZ7AEE_js.shouldRoomSlidesReplaceLoad(loadOrigin, docSlides.length)) {
10253
+ if (!chunkPCW2KT7Z_js.shouldRoomSlidesReplaceLoad(loadOrigin, docSlides.length)) {
10098
10254
  return;
10099
10255
  }
10100
10256
  lastSyncedRef.current = JSON.stringify(docSlides);
@@ -10113,11 +10269,11 @@ function useYjsDocumentSync({
10113
10269
  lastSyncedRef.current = serialized;
10114
10270
  void (async () => {
10115
10271
  const factories = await getFactories();
10116
- chunkFJDZ7AEE_js.reconcileSlidesInYDoc(
10272
+ chunkPCW2KT7Z_js.reconcileSlidesInYDoc(
10117
10273
  slides,
10118
10274
  doc,
10119
10275
  factories,
10120
- chunkFJDZ7AEE_js.LOCAL_SYNC_ORIGIN
10276
+ chunkPCW2KT7Z_js.LOCAL_SYNC_ORIGIN
10121
10277
  );
10122
10278
  scheduleWriteBack();
10123
10279
  })();
@@ -10131,10 +10287,10 @@ function useYjsDocumentSync({
10131
10287
  return;
10132
10288
  }
10133
10289
  const handleChange = (_events, transaction) => {
10134
- if (transaction?.origin === chunkFJDZ7AEE_js.LOCAL_SYNC_ORIGIN) {
10290
+ if (transaction?.origin === chunkPCW2KT7Z_js.LOCAL_SYNC_ORIGIN) {
10135
10291
  return;
10136
10292
  }
10137
- const remoteSlides = chunkFJDZ7AEE_js.readSlidesFromYDoc(
10293
+ const remoteSlides = chunkPCW2KT7Z_js.readSlidesFromYDoc(
10138
10294
  doc
10139
10295
  );
10140
10296
  if (remoteSlides.length === 0) {
@@ -10150,7 +10306,7 @@ function useYjsDocumentSync({
10150
10306
  isApplyingRemoteRef.current = false;
10151
10307
  scheduleWriteBack();
10152
10308
  };
10153
- const unobserve = chunkFJDZ7AEE_js.observeYDocSlides(
10309
+ const unobserve = chunkPCW2KT7Z_js.observeYDocSlides(
10154
10310
  doc,
10155
10311
  handleChange
10156
10312
  );
@@ -10188,7 +10344,7 @@ function useBroadcastFollower({
10188
10344
  if (!broadcaster) {
10189
10345
  return;
10190
10346
  }
10191
- if (!chunkFJDZ7AEE_js.shouldAutoFollowBroadcaster({
10347
+ if (!chunkPCW2KT7Z_js.shouldAutoFollowBroadcaster({
10192
10348
  localRole: collab.config.role,
10193
10349
  broadcasterRole: broadcaster.role
10194
10350
  })) {
@@ -10359,7 +10515,7 @@ function subscribeTouchCapability(callback) {
10359
10515
  function useIsMobile() {
10360
10516
  const isTouchDevice = react.useSyncExternalStore(
10361
10517
  subscribeTouchCapability,
10362
- chunkFJDZ7AEE_js.detectTouchDevice,
10518
+ chunkPCW2KT7Z_js.detectTouchDevice,
10363
10519
  () => false
10364
10520
  // server snapshot
10365
10521
  );
@@ -10369,7 +10525,7 @@ function useIsMobile() {
10369
10525
  const [viewportHeight, setViewportHeight] = react.useState(
10370
10526
  () => typeof window === "undefined" ? 768 : window.innerHeight
10371
10527
  );
10372
- const [orientation, setOrientation] = react.useState(chunkFJDZ7AEE_js.detectOrientation);
10528
+ const [orientation, setOrientation] = react.useState(chunkPCW2KT7Z_js.detectOrientation);
10373
10529
  const [isVirtualKeyboardOpen, setIsVirtualKeyboardOpen] = react.useState(false);
10374
10530
  const [initialViewportHeight] = react.useState(
10375
10531
  () => typeof window !== "undefined" ? window.innerHeight : 800
@@ -10390,7 +10546,7 @@ function useIsMobile() {
10390
10546
  return;
10391
10547
  }
10392
10548
  const handleOrientationChange = () => {
10393
- setOrientation(chunkFJDZ7AEE_js.detectOrientation());
10549
+ setOrientation(chunkPCW2KT7Z_js.detectOrientation());
10394
10550
  };
10395
10551
  if (screen.orientation) {
10396
10552
  screen.orientation.addEventListener("change", handleOrientationChange);
@@ -10420,7 +10576,7 @@ function useIsMobile() {
10420
10576
  window.addEventListener("resize", handleResize);
10421
10577
  return () => window.removeEventListener("resize", handleResize);
10422
10578
  }, [isTouchDevice, initialViewportHeight]);
10423
- const { isMobile, isTablet, isDesktop } = chunkFJDZ7AEE_js.deriveViewportBreakpoints(
10579
+ const { isMobile, isTablet, isDesktop } = chunkPCW2KT7Z_js.deriveViewportBreakpoints(
10424
10580
  viewportWidth,
10425
10581
  viewportHeight,
10426
10582
  isTouchDevice
@@ -10451,10 +10607,10 @@ function useTouchGestures(input) {
10451
10607
  if (!el || !enabled) {
10452
10608
  return;
10453
10609
  }
10454
- const recognizer = chunkFJDZ7AEE_js.createTouchGestureRecognizer({
10610
+ const recognizer = chunkPCW2KT7Z_js.createTouchGestureRecognizer({
10455
10611
  getScale: () => scaleRef.current,
10456
- minScale: chunkFJDZ7AEE_js.MIN_ZOOM_SCALE,
10457
- maxScale: chunkFJDZ7AEE_js.MAX_ZOOM_SCALE,
10612
+ minScale: chunkPCW2KT7Z_js.MIN_ZOOM_SCALE,
10613
+ maxScale: chunkPCW2KT7Z_js.MAX_ZOOM_SCALE,
10458
10614
  callbacks: {
10459
10615
  onPinchZoom: (newScale) => callbacksRef.current.onPinchZoom?.(newScale),
10460
10616
  onSwipe: (direction) => callbacksRef.current.onSwipe?.(direction),
@@ -10494,7 +10650,7 @@ function scrollFocusedIntoView(keyboardInset) {
10494
10650
  return;
10495
10651
  }
10496
10652
  const rect = active.getBoundingClientRect();
10497
- const delta = chunkFJDZ7AEE_js.computeScrollDelta(
10653
+ const delta = chunkPCW2KT7Z_js.computeScrollDelta(
10498
10654
  { top: rect.top, bottom: rect.bottom },
10499
10655
  window.innerHeight,
10500
10656
  keyboardInset
@@ -10514,8 +10670,8 @@ function useKeyboardInsets(enabled = true) {
10514
10670
  return;
10515
10671
  }
10516
10672
  const update = () => {
10517
- const metrics = chunkFJDZ7AEE_js.readViewportMetrics(window);
10518
- const inset = metrics ? chunkFJDZ7AEE_js.computeKeyboardInset(metrics) : 0;
10673
+ const metrics = chunkPCW2KT7Z_js.readViewportMetrics(window);
10674
+ const inset = metrics ? chunkPCW2KT7Z_js.computeKeyboardInset(metrics) : 0;
10519
10675
  setKeyboardInset(inset);
10520
10676
  if (inset > 0) {
10521
10677
  window.requestAnimationFrame(() => scrollFocusedIntoView(inset));
@@ -10526,8 +10682,8 @@ function useKeyboardInsets(enabled = true) {
10526
10682
  vv.addEventListener("scroll", update);
10527
10683
  const onFocusIn = () => {
10528
10684
  window.requestAnimationFrame(() => {
10529
- const metrics = chunkFJDZ7AEE_js.readViewportMetrics(window);
10530
- const inset = metrics ? chunkFJDZ7AEE_js.computeKeyboardInset(metrics) : 0;
10685
+ const metrics = chunkPCW2KT7Z_js.readViewportMetrics(window);
10686
+ const inset = metrics ? chunkPCW2KT7Z_js.computeKeyboardInset(metrics) : 0;
10531
10687
  if (inset > 0) {
10532
10688
  scrollFocusedIntoView(inset);
10533
10689
  }
@@ -10540,7 +10696,7 @@ function useKeyboardInsets(enabled = true) {
10540
10696
  document.removeEventListener("focusin", onFocusIn);
10541
10697
  };
10542
10698
  }, [enabled]);
10543
- return { keyboardInset, isKeyboardOpen: chunkFJDZ7AEE_js.isKeyboardOpen(keyboardInset) };
10699
+ return { keyboardInset, isKeyboardOpen: chunkPCW2KT7Z_js.isKeyboardOpen(keyboardInset) };
10544
10700
  }
10545
10701
 
10546
10702
  // src/viewer/hooks/useViewerBuildingBlocks-canvas-props.ts
@@ -10569,34 +10725,34 @@ function buildCanvasProps(input) {
10569
10725
  } = input;
10570
10726
  const effectiveSlide = mode === "master" ? masterPseudoSlide : activeSlide;
10571
10727
  const effectiveTemplateElements = mode === "master" ? s.activeLayout ? s.activeMaster?.elements ?? [] : [] : templateElements;
10572
- const fieldContext = chunkFJDZ7AEE_js.buildFieldSubstitutionContext({
10728
+ const fieldContext = chunkPCW2KT7Z_js.buildFieldSubstitutionContext({
10573
10729
  headerFooter: s.headerFooter,
10574
10730
  customProperties: s.customProperties,
10575
10731
  slide: activeSlide
10576
10732
  });
10577
10733
  const tableStyleContext = s.theme || s.tableStyleMap ? { theme: s.theme, tableStyleMap: s.tableStyleMap } : void 0;
10578
10734
  const openExternalUrl = (url) => {
10579
- if (chunkFJDZ7AEE_js.shouldConfirmExternalHyperlink(viewerOptions, url) && !window.confirm(buildHyperlinkConfirmMessage(url))) {
10735
+ if (chunkPCW2KT7Z_js.shouldConfirmExternalHyperlink(viewerOptions, url) && !window.confirm(buildHyperlinkConfirmMessage(url))) {
10580
10736
  return;
10581
10737
  }
10582
- chunkFJDZ7AEE_js.safeOpenUrl(url);
10738
+ chunkPCW2KT7Z_js.safeOpenUrl(url);
10583
10739
  };
10584
- const handleActionClick = (_elementId, action) => {
10740
+ const handleActionClick = (elementId, action) => {
10585
10741
  if (mode === "present") {
10586
- const resolved = chunkFJDZ7AEE_js.resolvePresentationAction(action, { slideCount: slides.length });
10742
+ const resolved = chunkPCW2KT7Z_js.resolvePresentationAction(action, { slideCount: slides.length });
10587
10743
  if (resolved.intent.kind === "openUrl") {
10588
10744
  openExternalUrl(resolved.intent.url);
10589
10745
  return;
10590
10746
  }
10591
- presentation.handlePresentationAction(action);
10747
+ presentation.handlePresentationAction(action, elementId);
10592
10748
  } else if (action.url) {
10593
10749
  openExternalUrl(action.url);
10594
10750
  }
10595
10751
  };
10596
10752
  const handleHyperlinkClick = (url) => {
10597
- if (chunkFJDZ7AEE_js.isPpactionUrl(url)) {
10753
+ if (chunkPCW2KT7Z_js.isPpactionUrl(url)) {
10598
10754
  if (mode === "present") {
10599
- const parsed = chunkFJDZ7AEE_js.parsePpactionUrl(url);
10755
+ const parsed = chunkPCW2KT7Z_js.parsePpactionUrl(url);
10600
10756
  if (parsed) {
10601
10757
  presentation.handlePresentationAction({
10602
10758
  action: parsed.action,
@@ -10702,7 +10858,7 @@ function buildCanvasProps(input) {
10702
10858
 
10703
10859
  // src/viewer/hooks/useScopedLayoutOptions.ts
10704
10860
  function scopeLayoutOptionsToActiveSlide(options, activeSlide) {
10705
- return chunkFJDZ7AEE_js.scopeLayoutOptionsToSlide(options, activeSlide?.layoutPath);
10861
+ return chunkPCW2KT7Z_js.scopeLayoutOptionsToSlide(options, activeSlide?.layoutPath);
10706
10862
  }
10707
10863
 
10708
10864
  // src/viewer/hooks/useViewerBuildingBlocks-toolbar-handlers.ts
@@ -10715,7 +10871,7 @@ function buildToolbarAnimationHandlers(input) {
10715
10871
  const current = activeSlide.animations ?? [];
10716
10872
  if (group === "motionPath") {
10717
10873
  propertyHandlers.handleUpdateSlide({
10718
- animations: chunkFJDZ7AEE_js.applyMotionPathPreset(current, selectedElement.id, preset)
10874
+ animations: chunkPCW2KT7Z_js.applyMotionPathPreset(current, selectedElement.id, preset)
10719
10875
  });
10720
10876
  return;
10721
10877
  }
@@ -10797,7 +10953,8 @@ function buildToolbarProps(input) {
10797
10953
  onOpenFile,
10798
10954
  onOpenRecentFile,
10799
10955
  fileName,
10800
- hiddenActions
10956
+ hiddenActions,
10957
+ viewPreferencesSync
10801
10958
  } = input;
10802
10959
  const {
10803
10960
  handleAddAnimation,
@@ -10881,9 +11038,9 @@ function buildToolbarProps(input) {
10881
11038
  onSetSpellCheckEnabled: s.setSpellCheckEnabled,
10882
11039
  onSetShowGrid: s.setShowGrid,
10883
11040
  onSetShowRulers: s.setShowRulers,
10884
- onSetShowGuides: s.setShowGuides,
10885
- onSetSnapToGrid: s.setSnapToGrid,
10886
- onSetSnapToShape: s.setSnapToShape,
11041
+ onSetShowGuides: viewPreferencesSync?.handleSetShowGuides ?? s.setShowGuides,
11042
+ onSetSnapToGrid: viewPreferencesSync?.handleSetSnapToGrid ?? s.setSnapToGrid,
11043
+ onSetSnapToShape: viewPreferencesSync?.handleSetSnapToShape ?? s.setSnapToShape,
10887
11044
  onAddGuide: dialogs.handleAddGuide,
10888
11045
  onAlignElements: manipulation.handleAlignElements,
10889
11046
  onDistributeElements: manipulation.handleDistributeElements,
@@ -10909,7 +11066,7 @@ function buildToolbarProps(input) {
10909
11066
  onOpenFile,
10910
11067
  onOpenRecentFile,
10911
11068
  onCreatePresentation: (templateId) => {
10912
- s.setSlides(chunkFJDZ7AEE_js.createBackstagePresentation(templateId));
11069
+ s.setSlides(chunkPCW2KT7Z_js.createBackstagePresentation(templateId));
10913
11070
  s.setActiveSlideIndex(0);
10914
11071
  s.setSelectedElementId(null);
10915
11072
  s.setSelectedElementIds([]);
@@ -10938,7 +11095,7 @@ function buildToolbarProps(input) {
10938
11095
  loadLayoutPreviews: input.loadLayoutPreviews,
10939
11096
  onInsertSlideFromLayout: slideOps.handleInsertSlideFromLayout,
10940
11097
  onInsertSlideFromTemplate: slideOps.handleInsertSlideFromTemplate,
10941
- templateScheme: chunkFJDZ7AEE_js.templateSchemeFromTheme(s.theme?.colorScheme),
11098
+ templateScheme: chunkPCW2KT7Z_js.templateSchemeFromTheme(s.theme?.colorScheme),
10942
11099
  customShows: s.customShows,
10943
11100
  activeCustomShowId: s.activeCustomShowId,
10944
11101
  onSetActiveCustomShowId: s.setActiveCustomShowId,
@@ -10979,7 +11136,7 @@ function buildToolbarProps(input) {
10979
11136
  isCommentsPanelOpen: s.isInspectorPaneOpen,
10980
11137
  slideCommentCount: activeSlide?.comments?.length ?? 0,
10981
11138
  formatPainterActive: s.formatPainterActive,
10982
- canActivateFormatPainter: chunkFJDZ7AEE_js.hasCopyableFormat(selectedElement),
11139
+ canActivateFormatPainter: chunkPCW2KT7Z_js.hasCopyableFormat(selectedElement),
10983
11140
  onToggleFormatPainter: () => s.setFormatPainterActive((p) => !p),
10984
11141
  isSelectionPaneOpen: s.isSelectionPaneOpen,
10985
11142
  onToggleSelectionPane: () => s.setIsSelectionPaneOpen((p) => !p),
@@ -11053,7 +11210,7 @@ function useViewerBuildingBlocksCore(input) {
11053
11210
  headerFooter: state.headerFooter,
11054
11211
  loading,
11055
11212
  error,
11056
- maxHistoryEntries: chunkFJDZ7AEE_js.resolveHistoryDepth(viewerOptions),
11213
+ maxHistoryEntries: chunkPCW2KT7Z_js.resolveHistoryDepth(viewerOptions),
11057
11214
  hasActivePointerInteraction,
11058
11215
  pointerCommitNonce: state.pointerCommitNonce,
11059
11216
  setSlides: state.setSlides,
@@ -11070,6 +11227,7 @@ function useViewerBuildingBlocksCore(input) {
11070
11227
  sections: state.sections,
11071
11228
  customShows: state.customShows,
11072
11229
  activeCustomShowId: state.activeCustomShowId,
11230
+ presentationProperties: state.presentationProperties,
11073
11231
  mode,
11074
11232
  activeLayout: state.activeLayout,
11075
11233
  activeMaster: state.activeMaster,
@@ -11078,6 +11236,7 @@ function useViewerBuildingBlocksCore(input) {
11078
11236
  const { presentation, annotations, actionSoundHandlerRef, setExitModeHandler } = usePresentationSetup({
11079
11237
  mode,
11080
11238
  slides,
11239
+ templateElementsBySlideId,
11081
11240
  visibleSlideIndexes,
11082
11241
  endWithBlackSlide: viewerOptions.advanced.slideShowEndWithBlackSlide,
11083
11242
  // File > Options > Advanced > "Prompt to keep ink annotations when
@@ -11118,10 +11277,115 @@ function useViewerBuildingBlocksCore(input) {
11118
11277
  gridSpacingPx,
11119
11278
  // Multiplied against the pre-existing 2x baseline; see the matching
11120
11279
  // comment in `PowerPointViewer.tsx`.
11121
- imageExportScale: 2 * chunkFJDZ7AEE_js.resolveImageResolutionScale(viewerOptions),
11280
+ imageExportScale: 2 * chunkPCW2KT7Z_js.resolveImageResolutionScale(viewerOptions),
11122
11281
  viewerOptions
11123
11282
  };
11124
11283
  }
11284
+ function useCompatibilityToastsState() {
11285
+ const [toasts, setToasts] = react.useState([]);
11286
+ const dismiss = react.useCallback((id) => {
11287
+ setToasts((prev) => prev.filter((toast) => toast.id !== id));
11288
+ }, []);
11289
+ const dismissAll = react.useCallback(() => {
11290
+ setToasts([]);
11291
+ }, []);
11292
+ return { toasts, setToasts, dismiss, dismissAll };
11293
+ }
11294
+ function useReadOnlyRecommendationState(content) {
11295
+ const [recommendation, setRecommendation] = react.useState(
11296
+ () => chunkPCW2KT7Z_js.readOnlyRecommendation(void 0)
11297
+ );
11298
+ const [bannerHidden, setBannerHidden] = react.useState(false);
11299
+ const [editAnywayActive, setEditAnywayActive] = react.useState(false);
11300
+ react.useEffect(() => {
11301
+ setBannerHidden(false);
11302
+ setEditAnywayActive(false);
11303
+ }, [content]);
11304
+ const editAnyway = react.useCallback(() => {
11305
+ setEditAnywayActive(true);
11306
+ setBannerHidden(true);
11307
+ }, []);
11308
+ const dismiss = react.useCallback(() => {
11309
+ setBannerHidden(true);
11310
+ }, []);
11311
+ return {
11312
+ recommendation,
11313
+ setRecommendation,
11314
+ /** Whether the viewer's `canEdit` should be forced off. */
11315
+ locked: recommendation.defaultReadOnly && !editAnywayActive,
11316
+ bannerVisible: recommendation.kind !== null && !bannerHidden,
11317
+ editAnyway,
11318
+ dismiss
11319
+ };
11320
+ }
11321
+ function useViewPreferencesSync(input) {
11322
+ const {
11323
+ loadVersion,
11324
+ viewProperties,
11325
+ setViewProperties,
11326
+ snapToGrid,
11327
+ setSnapToGrid,
11328
+ snapToShape,
11329
+ setSnapToShape,
11330
+ showGuides,
11331
+ setShowGuides
11332
+ } = input;
11333
+ react.useEffect(() => {
11334
+ const seeded = chunkPCW2KT7Z_js.viewerPreferencesFromViewProperties(
11335
+ { viewProperties },
11336
+ { ...chunkPCW2KT7Z_js.DEFAULT_VIEWER_PREFERENCES, snapToGrid, snapToObjects: snapToShape, showGuides }
11337
+ );
11338
+ setSnapToGrid(seeded.snapToGrid);
11339
+ setSnapToShape(seeded.snapToObjects ?? snapToShape);
11340
+ setShowGuides(seeded.showGuides ?? showGuides);
11341
+ }, [loadVersion]);
11342
+ const patchViewProperties = react.useCallback(
11343
+ (prefsOverride) => {
11344
+ setViewProperties((prev) => {
11345
+ const merged = {
11346
+ ...chunkPCW2KT7Z_js.DEFAULT_VIEWER_PREFERENCES,
11347
+ snapToGrid,
11348
+ snapToObjects: snapToShape,
11349
+ showGuides,
11350
+ gridSpacingCx: prev?.gridSpacing?.cx,
11351
+ gridSpacingCy: prev?.gridSpacing?.cy,
11352
+ ...prefsOverride
11353
+ };
11354
+ const patch = chunkPCW2KT7Z_js.viewPropertiesPatchFromPreferences(merged);
11355
+ return {
11356
+ ...prev,
11357
+ slideViewPr: { ...prev?.slideViewPr, ...patch.slideViewPr },
11358
+ ...patch.gridSpacing ? { gridSpacing: patch.gridSpacing } : {}
11359
+ };
11360
+ });
11361
+ },
11362
+ [setViewProperties, snapToGrid, snapToShape, showGuides]
11363
+ );
11364
+ const handleSetSnapToGrid = react.useCallback(
11365
+ (value) => {
11366
+ setSnapToGrid(value);
11367
+ patchViewProperties({ snapToGrid: value });
11368
+ },
11369
+ [setSnapToGrid, patchViewProperties]
11370
+ );
11371
+ const handleSetSnapToShape = react.useCallback(
11372
+ (value) => {
11373
+ setSnapToShape(value);
11374
+ patchViewProperties({ snapToObjects: value });
11375
+ },
11376
+ [setSnapToShape, patchViewProperties]
11377
+ );
11378
+ const handleSetShowGuides = react.useCallback(
11379
+ (value) => {
11380
+ setShowGuides(value);
11381
+ patchViewProperties({ showGuides: value });
11382
+ },
11383
+ [setShowGuides, patchViewProperties]
11384
+ );
11385
+ return { handleSetSnapToGrid, handleSetSnapToShape, handleSetShowGuides };
11386
+ }
11387
+
11388
+ // src/viewer/hooks/useViewerBuildingBlocksState.ts
11125
11389
  function useViewerBuildingBlocksState(input) {
11126
11390
  const { core, content, canEdit, filePath, autosaveEnabled, userName, handle, setContent } = input;
11127
11391
  const {
@@ -11177,6 +11441,8 @@ function useViewerBuildingBlocksState(input) {
11177
11441
  isDirty: state.isDirty,
11178
11442
  history
11179
11443
  });
11444
+ const readOnlyRec = useReadOnlyRecommendationState(content);
11445
+ const compatToastsState = useCompatibilityToastsState();
11180
11446
  react.useEffect(() => {
11181
11447
  state.setSelectedElementId(null);
11182
11448
  state.setSelectedElementIds([]);
@@ -11207,7 +11473,8 @@ function useViewerBuildingBlocksState(input) {
11207
11473
  handleSetMode,
11208
11474
  handleEnterPresenterView,
11209
11475
  handleEnterRehearsalMode,
11210
- autosaveStatus
11476
+ autosaveStatus,
11477
+ loadVersion
11211
11478
  } = useViewerIntegration({
11212
11479
  state,
11213
11480
  zoom,
@@ -11225,6 +11492,8 @@ function useViewerBuildingBlocksState(input) {
11225
11492
  // applies, so the headless building-blocks API loads http(s) images
11226
11493
  // under the same default-off, core-side SSRF/privacy guard.
11227
11494
  allowExternalImages: viewerOptions.trust.allowExternalContent,
11495
+ setReadOnlyRecommendation: readOnlyRec.setRecommendation,
11496
+ setCompatToasts: compatToastsState.setToasts,
11228
11497
  canEdit,
11229
11498
  promptKeepInkAnnotations: viewerOptions.advanced.slideShowPromptKeepInkAnnotations,
11230
11499
  imageExportScale,
@@ -11246,6 +11515,17 @@ function useViewerBuildingBlocksState(input) {
11246
11515
  onSlideCountChange
11247
11516
  });
11248
11517
  setExitModeHandler(handleSetMode);
11518
+ const viewPreferencesSync = useViewPreferencesSync({
11519
+ loadVersion,
11520
+ viewProperties: state.viewProperties,
11521
+ setViewProperties: state.setViewProperties,
11522
+ snapToGrid: state.snapToGrid,
11523
+ setSnapToGrid: state.setSnapToGrid,
11524
+ snapToShape: state.snapToShape,
11525
+ setSnapToShape: state.setSnapToShape,
11526
+ showGuides: state.showGuides,
11527
+ setShowGuides: state.setShowGuides
11528
+ });
11249
11529
  return {
11250
11530
  dialogs,
11251
11531
  editorOps,
@@ -11255,7 +11535,8 @@ function useViewerBuildingBlocksState(input) {
11255
11535
  handleSetMode,
11256
11536
  handleEnterPresenterView,
11257
11537
  handleEnterRehearsalMode,
11258
- autosaveStatus
11538
+ autosaveStatus,
11539
+ viewPreferencesSync
11259
11540
  };
11260
11541
  }
11261
11542
 
@@ -11288,7 +11569,7 @@ function useViewerBuildingBlocks(input) {
11288
11569
  }, [incomingContent]);
11289
11570
  const onOpenFile = react.useCallback(() => {
11290
11571
  void (async () => {
11291
- const picked = await chunkFJDZ7AEE_js.openPptxFile();
11572
+ const picked = await chunkPCW2KT7Z_js.openPptxFile();
11292
11573
  if (picked) {
11293
11574
  setContent(picked.buffer);
11294
11575
  }
@@ -11296,7 +11577,7 @@ function useViewerBuildingBlocks(input) {
11296
11577
  }, []);
11297
11578
  const onOpenRecentFile = react.useCallback((key) => {
11298
11579
  void (async () => {
11299
- const bytes = await chunkFJDZ7AEE_js.readBackstageRecentFile(key);
11580
+ const bytes = await chunkPCW2KT7Z_js.readBackstageRecentFile(key);
11300
11581
  if (bytes) {
11301
11582
  setContent(bytes);
11302
11583
  }
@@ -11328,7 +11609,8 @@ function useViewerBuildingBlocks(input) {
11328
11609
  handleSetMode,
11329
11610
  handleEnterPresenterView,
11330
11611
  handleEnterRehearsalMode,
11331
- autosaveStatus
11612
+ autosaveStatus,
11613
+ viewPreferencesSync
11332
11614
  } = useViewerBuildingBlocksState({
11333
11615
  core,
11334
11616
  content,
@@ -11373,7 +11655,8 @@ function useViewerBuildingBlocks(input) {
11373
11655
  onOpenFile,
11374
11656
  onOpenRecentFile,
11375
11657
  fileName,
11376
- hiddenActions
11658
+ hiddenActions,
11659
+ viewPreferencesSync
11377
11660
  });
11378
11661
  const canvasProps = buildCanvasProps({
11379
11662
  mode,
@@ -11481,7 +11764,9 @@ exports.parseAudienceNonce = parseAudienceNonce;
11481
11764
  exports.parseEmailUrl = parseEmailUrl;
11482
11765
  exports.parseSlideFromUrl = parseSlideFromUrl;
11483
11766
  exports.renderToCanvas = renderToCanvas;
11767
+ exports.safePrompt = safePrompt;
11484
11768
  exports.scopeLayoutOptionsToActiveSlide = scopeLayoutOptionsToActiveSlide;
11769
+ exports.syncSelectionHandleOverlay = syncSelectionHandleOverlay;
11485
11770
  exports.useAnimationPlayback = useAnimationPlayback;
11486
11771
  exports.useAnnotationHandlers = useAnnotationHandlers;
11487
11772
  exports.useAudienceMode = useAudienceMode;
@@ -11493,6 +11778,7 @@ exports.useCollaborationLivePatch = useCollaborationLivePatch;
11493
11778
  exports.useCollaborativeHistory = useCollaborativeHistory;
11494
11779
  exports.useCollaborativeState = useCollaborativeState;
11495
11780
  exports.useComments = useComments;
11781
+ exports.useCompatibilityToastsState = useCompatibilityToastsState;
11496
11782
  exports.useContentLifecycle = useContentLifecycle;
11497
11783
  exports.useDerivedElementState = useDerivedElementState;
11498
11784
  exports.useDerivedSlideState = useDerivedSlideState;
@@ -11526,6 +11812,7 @@ exports.usePresentationSetup = usePresentationSetup;
11526
11812
  exports.usePresenterWindow = usePresenterWindow;
11527
11813
  exports.usePrintHandlers = usePrintHandlers;
11528
11814
  exports.usePropertyHandlers = usePropertyHandlers;
11815
+ exports.useReadOnlyRecommendationState = useReadOnlyRecommendationState;
11529
11816
  exports.useRecoveryDetection = useRecoveryDetection;
11530
11817
  exports.useReducedMotion = useReducedMotion;
11531
11818
  exports.useRehearsalTimings = useRehearsalTimings;
@@ -11541,6 +11828,7 @@ exports.useThemeHandlers = useThemeHandlers;
11541
11828
  exports.useThemeSwitching = useThemeSwitching;
11542
11829
  exports.useToolbarVisibility = useToolbarVisibility;
11543
11830
  exports.useTouchGestures = useTouchGestures;
11831
+ exports.useViewPreferencesSync = useViewPreferencesSync;
11544
11832
  exports.useViewerBuildingBlocks = useViewerBuildingBlocks;
11545
11833
  exports.useViewerCoreState = useViewerCoreState;
11546
11834
  exports.useViewerDialogs = useViewerDialogs;