pptx-react-viewer 3.20.1 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/{AiChatPanel-7AU4A3A7.mjs → AiChatPanel-MHURGN6G.mjs} +3 -3
  3. package/dist/AiChatPanel-MHURGN6G.mjs.br +0 -0
  4. package/dist/AiChatPanel-MHURGN6G.mjs.gz +0 -0
  5. package/dist/{AiChatPanel-FIUTFT55.js → AiChatPanel-WMVQFNDC.js} +24 -24
  6. package/dist/AiChatPanel-WMVQFNDC.js.br +0 -0
  7. package/dist/AiChatPanel-WMVQFNDC.js.gz +0 -0
  8. package/dist/{Area3DChartScene-ZGVLTYDW.js → Area3DChartScene-IMGZEZNU.js} +2 -2
  9. package/dist/Area3DChartScene-IMGZEZNU.js.br +0 -0
  10. package/dist/Area3DChartScene-IMGZEZNU.js.gz +0 -0
  11. package/dist/{Area3DChartScene-SPRHDMNQ.mjs → Area3DChartScene-LKOWSMAU.mjs} +1 -1
  12. package/dist/{Area3DChartScene-SPRHDMNQ.mjs.br → Area3DChartScene-LKOWSMAU.mjs.br} +0 -0
  13. package/dist/Area3DChartScene-LKOWSMAU.mjs.gz +0 -0
  14. package/dist/{Bar3DChartScene-FJCRJCZV.mjs → Bar3DChartScene-NQNSIMUL.mjs} +1 -1
  15. package/dist/{Bar3DChartScene-FJCRJCZV.mjs.br → Bar3DChartScene-NQNSIMUL.mjs.br} +0 -0
  16. package/dist/Bar3DChartScene-NQNSIMUL.mjs.gz +0 -0
  17. package/dist/{Bar3DChartScene-GVIX7ENI.js → Bar3DChartScene-VLSYVFRT.js} +2 -2
  18. package/dist/Bar3DChartScene-VLSYVFRT.js.br +0 -0
  19. package/dist/Bar3DChartScene-VLSYVFRT.js.gz +0 -0
  20. package/dist/{Line3DChartScene-KP4RMVAQ.mjs → Line3DChartScene-ANZBJYQI.mjs} +1 -1
  21. package/dist/{Line3DChartScene-KP4RMVAQ.mjs.br → Line3DChartScene-ANZBJYQI.mjs.br} +0 -0
  22. package/dist/Line3DChartScene-ANZBJYQI.mjs.gz +0 -0
  23. package/dist/{Line3DChartScene-6C3WDA42.js → Line3DChartScene-IWZHA563.js} +2 -2
  24. package/dist/Line3DChartScene-IWZHA563.js.br +0 -0
  25. package/dist/Line3DChartScene-IWZHA563.js.gz +0 -0
  26. package/dist/{Model3DScene-SXZYGMN6.js → Model3DScene-2L3YRAMR.js} +2 -2
  27. package/dist/Model3DScene-2L3YRAMR.js.br +0 -0
  28. package/dist/Model3DScene-2L3YRAMR.js.gz +0 -0
  29. package/dist/{Model3DScene-SH6ZLOXE.mjs → Model3DScene-Y34HTZXK.mjs} +1 -1
  30. package/dist/Model3DScene-Y34HTZXK.mjs.br +0 -0
  31. package/dist/Model3DScene-Y34HTZXK.mjs.gz +0 -0
  32. package/dist/{PieChart3DScene-F4IE7565.mjs → PieChart3DScene-FBRPLHLG.mjs} +1 -1
  33. package/dist/{PieChart3DScene-F4IE7565.mjs.br → PieChart3DScene-FBRPLHLG.mjs.br} +0 -0
  34. package/dist/PieChart3DScene-FBRPLHLG.mjs.gz +0 -0
  35. package/dist/{PieChart3DScene-V2Q73UEQ.js → PieChart3DScene-NE3GN5VG.js} +2 -2
  36. package/dist/PieChart3DScene-NE3GN5VG.js.br +0 -0
  37. package/dist/PieChart3DScene-NE3GN5VG.js.gz +0 -0
  38. package/dist/{SurfaceChart3DScene-AXLDY5BB.mjs → SurfaceChart3DScene-7HE5DA3X.mjs} +1 -1
  39. package/dist/SurfaceChart3DScene-7HE5DA3X.mjs.br +0 -0
  40. package/dist/SurfaceChart3DScene-7HE5DA3X.mjs.gz +0 -0
  41. package/dist/{SurfaceChart3DScene-XUGVYHD2.js → SurfaceChart3DScene-OSMAVZJC.js} +2 -2
  42. package/dist/SurfaceChart3DScene-OSMAVZJC.js.br +0 -0
  43. package/dist/SurfaceChart3DScene-OSMAVZJC.js.gz +0 -0
  44. package/dist/{chunk-MWNB4BX5.mjs → chunk-33YE6E2O.mjs} +563 -183
  45. package/dist/chunk-33YE6E2O.mjs.br +0 -0
  46. package/dist/chunk-33YE6E2O.mjs.gz +0 -0
  47. package/dist/{chunk-OKIHMWGI.mjs → chunk-5F426BCZ.mjs} +1 -1
  48. package/dist/chunk-5F426BCZ.mjs.br +0 -0
  49. package/dist/chunk-5F426BCZ.mjs.gz +0 -0
  50. package/dist/{chunk-F65J67TW.mjs → chunk-GITM3RKP.mjs} +1 -1
  51. package/dist/chunk-GITM3RKP.mjs.br +0 -0
  52. package/dist/chunk-GITM3RKP.mjs.gz +0 -0
  53. package/dist/{chunk-GV6LVDBE.mjs → chunk-H7J4EYXS.mjs} +58 -36
  54. package/dist/chunk-H7J4EYXS.mjs.br +0 -0
  55. package/dist/chunk-H7J4EYXS.mjs.gz +0 -0
  56. package/dist/{chunk-2BQKGTIF.js → chunk-I5F3XLVR.js} +1101 -1079
  57. package/dist/chunk-I5F3XLVR.js.br +0 -0
  58. package/dist/chunk-I5F3XLVR.js.gz +0 -0
  59. package/dist/{chunk-JIP6BCRV.mjs → chunk-IWHZ2DUD.mjs} +452 -257
  60. package/dist/chunk-IWHZ2DUD.mjs.br +0 -0
  61. package/dist/chunk-IWHZ2DUD.mjs.gz +0 -0
  62. package/dist/{chunk-ML4MTTPV.js → chunk-L6I73WMO.js} +1217 -1022
  63. package/dist/chunk-L6I73WMO.js.br +0 -0
  64. package/dist/chunk-L6I73WMO.js.gz +0 -0
  65. package/dist/{chunk-HN5QJSVB.js → chunk-LAAXFMRE.js} +566 -182
  66. package/dist/chunk-LAAXFMRE.js.br +0 -0
  67. package/dist/chunk-LAAXFMRE.js.gz +0 -0
  68. package/dist/chunk-MRWGWKA2.mjs +1076 -0
  69. package/dist/chunk-MRWGWKA2.mjs.br +0 -0
  70. package/dist/chunk-MRWGWKA2.mjs.gz +0 -0
  71. package/dist/{chunk-U46O2NL5.js → chunk-NKACTGK5.js} +173 -173
  72. package/dist/chunk-NKACTGK5.js.br +0 -0
  73. package/dist/chunk-NKACTGK5.js.gz +0 -0
  74. package/dist/chunk-YQQXFRZT.js +1160 -0
  75. package/dist/chunk-YQQXFRZT.js.br +0 -0
  76. package/dist/chunk-YQQXFRZT.js.gz +0 -0
  77. package/dist/{chunk-K7TAGREH.js → chunk-ZOB6ITIM.js} +5 -5
  78. package/dist/chunk-ZOB6ITIM.js.br +0 -0
  79. package/dist/chunk-ZOB6ITIM.js.gz +0 -0
  80. package/dist/index.d.ts +60 -2
  81. package/dist/index.js +46 -46
  82. package/dist/index.js.br +0 -0
  83. package/dist/index.js.gz +0 -0
  84. package/dist/index.mjs +5 -5
  85. package/dist/index.mjs.br +0 -0
  86. package/dist/index.mjs.gz +0 -0
  87. package/dist/internals.d.ts +75 -43
  88. package/dist/internals.js +104 -104
  89. package/dist/internals.js.br +0 -0
  90. package/dist/internals.js.gz +0 -0
  91. package/dist/internals.mjs +3 -3
  92. package/dist/internals.mjs.br +0 -0
  93. package/dist/internals.mjs.gz +0 -0
  94. package/dist/viewer/index.d.ts +70 -6
  95. package/dist/viewer/index.js +26 -26
  96. package/dist/viewer/index.js.br +0 -0
  97. package/dist/viewer/index.js.gz +0 -0
  98. package/dist/viewer/index.mjs +5 -5
  99. package/dist/viewer/index.mjs.br +0 -0
  100. package/dist/viewer/index.mjs.gz +0 -0
  101. package/dist/{y-webrtc-TAJBJIKH.js → y-webrtc-6H3ROPRC.js} +1079 -128
  102. package/dist/y-webrtc-6H3ROPRC.js.br +0 -0
  103. package/dist/y-webrtc-6H3ROPRC.js.gz +0 -0
  104. package/dist/{y-webrtc-7DLWG3LJ.mjs → y-webrtc-XJDH2YTR.mjs} +984 -33
  105. package/dist/y-webrtc-XJDH2YTR.mjs.br +0 -0
  106. package/dist/y-webrtc-XJDH2YTR.mjs.gz +0 -0
  107. package/dist/{y-websocket-YRPS7AFF.js → y-websocket-6ISNPON7.js} +79 -80
  108. package/dist/y-websocket-6ISNPON7.js.br +0 -0
  109. package/dist/y-websocket-6ISNPON7.js.gz +0 -0
  110. package/dist/{y-websocket-HUEA7LH7.mjs → y-websocket-SJ3NCLBZ.mjs} +3 -4
  111. package/dist/y-websocket-SJ3NCLBZ.mjs.br +0 -0
  112. package/dist/y-websocket-SJ3NCLBZ.mjs.gz +0 -0
  113. package/package.json +8 -5
  114. package/dist/AiChatPanel-7AU4A3A7.mjs.br +0 -0
  115. package/dist/AiChatPanel-7AU4A3A7.mjs.gz +0 -0
  116. package/dist/AiChatPanel-FIUTFT55.js.br +0 -0
  117. package/dist/AiChatPanel-FIUTFT55.js.gz +0 -0
  118. package/dist/Area3DChartScene-SPRHDMNQ.mjs.gz +0 -0
  119. package/dist/Area3DChartScene-ZGVLTYDW.js.br +0 -0
  120. package/dist/Area3DChartScene-ZGVLTYDW.js.gz +0 -0
  121. package/dist/Bar3DChartScene-FJCRJCZV.mjs.gz +0 -0
  122. package/dist/Bar3DChartScene-GVIX7ENI.js.br +0 -0
  123. package/dist/Bar3DChartScene-GVIX7ENI.js.gz +0 -0
  124. package/dist/Line3DChartScene-6C3WDA42.js.br +0 -0
  125. package/dist/Line3DChartScene-6C3WDA42.js.gz +0 -0
  126. package/dist/Line3DChartScene-KP4RMVAQ.mjs.gz +0 -0
  127. package/dist/Model3DScene-SH6ZLOXE.mjs.br +0 -0
  128. package/dist/Model3DScene-SH6ZLOXE.mjs.gz +0 -0
  129. package/dist/Model3DScene-SXZYGMN6.js.br +0 -0
  130. package/dist/Model3DScene-SXZYGMN6.js.gz +0 -0
  131. package/dist/PieChart3DScene-F4IE7565.mjs.gz +0 -0
  132. package/dist/PieChart3DScene-V2Q73UEQ.js.br +0 -0
  133. package/dist/PieChart3DScene-V2Q73UEQ.js.gz +0 -0
  134. package/dist/SurfaceChart3DScene-AXLDY5BB.mjs.br +0 -0
  135. package/dist/SurfaceChart3DScene-AXLDY5BB.mjs.gz +0 -0
  136. package/dist/SurfaceChart3DScene-XUGVYHD2.js.br +0 -0
  137. package/dist/SurfaceChart3DScene-XUGVYHD2.js.gz +0 -0
  138. package/dist/chunk-2BQKGTIF.js.br +0 -0
  139. package/dist/chunk-2BQKGTIF.js.gz +0 -0
  140. package/dist/chunk-DWIIYEOG.mjs +0 -9596
  141. package/dist/chunk-DWIIYEOG.mjs.br +0 -0
  142. package/dist/chunk-DWIIYEOG.mjs.gz +0 -0
  143. package/dist/chunk-F65J67TW.mjs.br +0 -0
  144. package/dist/chunk-F65J67TW.mjs.gz +0 -0
  145. package/dist/chunk-FXGO5KLU.mjs +0 -304
  146. package/dist/chunk-FXGO5KLU.mjs.br +0 -0
  147. package/dist/chunk-FXGO5KLU.mjs.gz +0 -0
  148. package/dist/chunk-GV6LVDBE.mjs.br +0 -0
  149. package/dist/chunk-GV6LVDBE.mjs.gz +0 -0
  150. package/dist/chunk-HN5QJSVB.js.br +0 -0
  151. package/dist/chunk-HN5QJSVB.js.gz +0 -0
  152. package/dist/chunk-JIP6BCRV.mjs.br +0 -0
  153. package/dist/chunk-JIP6BCRV.mjs.gz +0 -0
  154. package/dist/chunk-K7TAGREH.js.br +0 -0
  155. package/dist/chunk-K7TAGREH.js.gz +0 -0
  156. package/dist/chunk-ML4MTTPV.js.br +0 -0
  157. package/dist/chunk-ML4MTTPV.js.gz +0 -0
  158. package/dist/chunk-MWNB4BX5.mjs.br +0 -0
  159. package/dist/chunk-MWNB4BX5.mjs.gz +0 -0
  160. package/dist/chunk-NB7M4XBG.js +0 -318
  161. package/dist/chunk-NB7M4XBG.js.br +0 -0
  162. package/dist/chunk-NB7M4XBG.js.gz +0 -0
  163. package/dist/chunk-OKIHMWGI.mjs.br +0 -0
  164. package/dist/chunk-OKIHMWGI.mjs.gz +0 -0
  165. package/dist/chunk-U46O2NL5.js.br +0 -0
  166. package/dist/chunk-U46O2NL5.js.gz +0 -0
  167. package/dist/chunk-ZYQT7I5C.js +0 -9743
  168. package/dist/chunk-ZYQT7I5C.js.br +0 -0
  169. package/dist/chunk-ZYQT7I5C.js.gz +0 -0
  170. package/dist/y-webrtc-7DLWG3LJ.mjs.br +0 -0
  171. package/dist/y-webrtc-7DLWG3LJ.mjs.gz +0 -0
  172. package/dist/y-webrtc-TAJBJIKH.js.br +0 -0
  173. package/dist/y-webrtc-TAJBJIKH.js.gz +0 -0
  174. package/dist/y-websocket-HUEA7LH7.mjs.br +0 -0
  175. package/dist/y-websocket-HUEA7LH7.mjs.gz +0 -0
  176. package/dist/y-websocket-YRPS7AFF.js.br +0 -0
  177. package/dist/y-websocket-YRPS7AFF.js.gz +0 -0
  178. package/dist/yjs-4ED7E5CZ.mjs +0 -2
  179. package/dist/yjs-4ED7E5CZ.mjs.br +0 -0
  180. package/dist/yjs-4ED7E5CZ.mjs.gz +0 -0
  181. package/dist/yjs-OWUA3UHD.js +0 -419
  182. package/dist/yjs-OWUA3UHD.js.br +0 -0
  183. package/dist/yjs-OWUA3UHD.js.gz +0 -0
@@ -12,7 +12,7 @@ var DOMPurify__default = /*#__PURE__*/_interopDefault(DOMPurify);
12
12
 
13
13
  // ../core/dist/index.mjs
14
14
 
15
- // ../../node_modules/.bun/emf-converter@2.0.2/node_modules/emf-converter/dist/index.mjs
15
+ // ../../node_modules/.bun/emf-converter@3.0.1/node_modules/emf-converter/dist/index.mjs
16
16
  function colorRefToHex(r, g2, b) {
17
17
  const toHex4 = (v) => v.toString(16).padStart(2, "0");
18
18
  return `#${toHex4(r & 255)}${toHex4(g2 & 255)}${toHex4(b & 255)}`;
@@ -238,6 +238,26 @@ var emfLog = (...args) => {
238
238
  };
239
239
  var emfWarn = (...args) => {
240
240
  };
241
+ var nodeCanvasModule;
242
+ async function ensureNodeCanvasModule() {
243
+ if (nodeCanvasModule !== void 0) {
244
+ return nodeCanvasModule;
245
+ }
246
+ if (typeof OffscreenCanvas !== "undefined" || typeof document !== "undefined") {
247
+ nodeCanvasModule = null;
248
+ return nodeCanvasModule;
249
+ }
250
+ if (typeof process === "undefined" || !process.versions?.node) {
251
+ nodeCanvasModule = null;
252
+ return nodeCanvasModule;
253
+ }
254
+ try {
255
+ nodeCanvasModule = await import('@napi-rs/canvas');
256
+ } catch {
257
+ nodeCanvasModule = null;
258
+ }
259
+ return nodeCanvasModule;
260
+ }
241
261
  var DEFAULT_DPI_SCALE = 1;
242
262
  function createCanvas(width, height, maxWidth, maxHeight, dpiScale = DEFAULT_DPI_SCALE, maxCanvasDimension = MAX_CANVAS_DIMENSION) {
243
263
  const effectiveScale = Math.max(1, Math.min(dpiScale, 4));
@@ -274,30 +294,44 @@ function createCanvas(width, height, maxWidth, maxHeight, dpiScale = DEFAULT_DPI
274
294
  emfLog(
275
295
  `createCanvas: using OffscreenCanvas ${w}\xD7${h2}, scale=(${scaleX.toFixed(3)},${scaleY.toFixed(3)})`
276
296
  );
277
- const canvas2 = new OffscreenCanvas(w, h2);
278
- const ctx2 = canvas2.getContext("2d");
279
- if (!ctx2) {
297
+ const canvas = new OffscreenCanvas(w, h2);
298
+ const ctx = canvas.getContext("2d");
299
+ if (!ctx) {
280
300
  emfWarn('createCanvas: OffscreenCanvas.getContext("2d") returned null');
281
301
  return null;
282
302
  }
283
- return { canvas: canvas2, ctx: ctx2, scaleX, scaleY };
303
+ return { canvas, ctx, scaleX, scaleY };
284
304
  }
285
- if (typeof document === "undefined") {
286
- emfWarn("createCanvas: no OffscreenCanvas and no document \u2014 cannot create canvas");
287
- return null;
305
+ if (typeof document !== "undefined") {
306
+ emfLog(
307
+ `createCanvas: using HTMLCanvasElement ${w}\xD7${h2}, scale=(${scaleX.toFixed(3)},${scaleY.toFixed(3)})`
308
+ );
309
+ const canvas = document.createElement("canvas");
310
+ canvas.width = w;
311
+ canvas.height = h2;
312
+ const ctx = canvas.getContext("2d");
313
+ if (!ctx) {
314
+ emfWarn('createCanvas: HTMLCanvasElement.getContext("2d") returned null');
315
+ return null;
316
+ }
317
+ return { canvas, ctx, scaleX, scaleY };
288
318
  }
289
- emfLog(
290
- `createCanvas: using HTMLCanvasElement ${w}\xD7${h2}, scale=(${scaleX.toFixed(3)},${scaleY.toFixed(3)})`
291
- );
292
- const canvas = document.createElement("canvas");
293
- canvas.width = w;
294
- canvas.height = h2;
295
- const ctx = canvas.getContext("2d");
296
- if (!ctx) {
297
- emfWarn('createCanvas: HTMLCanvasElement.getContext("2d") returned null');
298
- return null;
319
+ if (nodeCanvasModule) {
320
+ emfLog(
321
+ `createCanvas: using @napi-rs/canvas ${w}\xD7${h2}, scale=(${scaleX.toFixed(3)},${scaleY.toFixed(3)})`
322
+ );
323
+ const canvas = nodeCanvasModule.createCanvas(w, h2);
324
+ const ctx = canvas.getContext("2d");
325
+ if (!ctx) {
326
+ emfWarn('createCanvas: @napi-rs/canvas getContext("2d") returned null');
327
+ return null;
328
+ }
329
+ return { canvas, ctx, scaleX, scaleY };
299
330
  }
300
- return { canvas, ctx, scaleX, scaleY };
331
+ emfWarn(
332
+ "createCanvas: no OffscreenCanvas, no document, and no @napi-rs/canvas, cannot create canvas"
333
+ );
334
+ return null;
301
335
  } catch (err) {
302
336
  return null;
303
337
  }
@@ -326,6 +360,14 @@ function createTempCanvas(width, height) {
326
360
  }
327
361
  return { canvas, ctx };
328
362
  }
363
+ if (nodeCanvasModule) {
364
+ const canvas = nodeCanvasModule.createCanvas(width, height);
365
+ const ctx = canvas.getContext("2d");
366
+ if (!ctx) {
367
+ return null;
368
+ }
369
+ return { canvas, ctx };
370
+ }
329
371
  return null;
330
372
  }
331
373
  function rop2Paint(rop2) {
@@ -559,8 +601,31 @@ async function exportCanvasToPngDataUrl(canvas) {
559
601
  );
560
602
  return canvas.toDataURL("image/png");
561
603
  }
604
+ if (nodeCanvasModule && canvas instanceof nodeCanvasModule.Canvas) {
605
+ emfLog(
606
+ `exportCanvasToPngDataUrl: using @napi-rs/canvas toDataURLAsync (${canvas.width}\xD7${canvas.height})`
607
+ );
608
+ return canvas.toDataURLAsync();
609
+ }
562
610
  return null;
563
611
  }
612
+ async function decodeDeferredImageBytes(bytes, mime) {
613
+ if (nodeCanvasModule) {
614
+ const image = await nodeCanvasModule.loadImage(new Uint8Array(bytes));
615
+ return { drawable: image, width: image.width, height: image.height, close: () => {
616
+ } };
617
+ }
618
+ if (typeof createImageBitmap !== "function") {
619
+ return null;
620
+ }
621
+ const blob = mime !== void 0 ? new Blob([bytes], { type: mime }) : new Blob([bytes]);
622
+ const bitmap = await createImageBitmap(blob);
623
+ return { drawable: bitmap, width: bitmap.width, height: bitmap.height, close: () => bitmap.close() };
624
+ }
625
+ function canvasDrawImage(ctx, image, dx, dy, dw, dh) {
626
+ const draw = ctx.drawImage;
627
+ draw.call(ctx, image, dx, dy, dw, dh);
628
+ }
564
629
  function parseEmfHeader(view) {
565
630
  emfLog("parseEmfHeader: byteLength =", view.byteLength);
566
631
  if (view.byteLength < 88) {
@@ -1462,7 +1527,8 @@ function handleBitBlt(rCtx, offset, dataOff, recSize) {
1462
1527
  const temp = createTempCanvas(imageData.width, imageData.height);
1463
1528
  if (temp) {
1464
1529
  temp.ctx.putImageData(imageData, 0, 0);
1465
- ctx.drawImage(
1530
+ canvasDrawImage(
1531
+ ctx,
1466
1532
  temp.canvas,
1467
1533
  gmx(rCtx, dstX),
1468
1534
  gmy(rCtx, dstY),
@@ -1497,7 +1563,8 @@ function handleStretchDibits(rCtx, offset, dataOff, recSize) {
1497
1563
  const temp = createTempCanvas(imageData.width, imageData.height);
1498
1564
  if (temp) {
1499
1565
  temp.ctx.putImageData(imageData, 0, 0);
1500
- ctx.drawImage(
1566
+ canvasDrawImage(
1567
+ ctx,
1501
1568
  temp.canvas,
1502
1569
  gmx(rCtx, dstX),
1503
1570
  gmy(rCtx, dstY),
@@ -4814,12 +4881,16 @@ async function processDeferredImages(ctx, deferredImages, recursionDepth = 0) {
4814
4881
  if (img.isMetafile) {
4815
4882
  if (recursionDepth >= MAX_METAFILE_RECURSION) {
4816
4883
  emfWarn(
4817
- ` Deferred image [${idx}]: skipping embedded metafile \u2014 recursion depth ${recursionDepth} >= ${MAX_METAFILE_RECURSION}`
4884
+ ` Deferred image [${idx}]: skipping embedded metafile, recursion depth ${recursionDepth} >= ${MAX_METAFILE_RECURSION}`
4818
4885
  );
4819
4886
  continue;
4820
4887
  }
4821
4888
  emfLog(` Deferred image [${idx}]: recursively converting embedded metafile...`);
4822
- const metafileDataUrl = await convertEmfToDataUrl(plainBuffer, void 0, recursionDepth + 1) ?? await convertWmfToDataUrl(plainBuffer, void 0, recursionDepth + 1);
4889
+ const metafileDataUrl = await convertMetafileToDataUrl(
4890
+ plainBuffer,
4891
+ void 0,
4892
+ recursionDepth + 1
4893
+ );
4823
4894
  if (metafileDataUrl) {
4824
4895
  emfLog(
4825
4896
  ` Deferred image [${idx}]: metafile converted, dataUrl length=${metafileDataUrl.length}`
@@ -4832,26 +4903,28 @@ async function processDeferredImages(ctx, deferredImages, recursionDepth = 0) {
4832
4903
  for (let i2 = 0; i2 < byteString.length; i2++) {
4833
4904
  ia[i2] = byteString.charCodeAt(i2);
4834
4905
  }
4835
- const metaBlob = new Blob([ab], { type: mime });
4836
- emfLog(
4837
- ` Deferred image [${idx}]: creating ImageBitmap from ${metaBlob.size} byte blob (${mime})...`
4838
- );
4839
- const bitmap = await createImageBitmap(metaBlob);
4840
- emfLog(` Deferred image [${idx}]: ImageBitmap created ${bitmap.width}\xD7${bitmap.height}`);
4841
- ctx.drawImage(bitmap, img.dx, img.dy, img.dw, img.dh);
4842
- bitmap.close();
4906
+ emfLog(` Deferred image [${idx}]: decoding ${ab.byteLength} byte image (${mime})...`);
4907
+ const decoded = await decodeDeferredImageBytes(ab, mime);
4908
+ if (decoded) {
4909
+ emfLog(` Deferred image [${idx}]: decoded ${decoded.width}\xD7${decoded.height}`);
4910
+ canvasDrawImage(ctx, decoded.drawable, img.dx, img.dy, img.dw, img.dh);
4911
+ decoded.close();
4912
+ } else {
4913
+ emfWarn(` Deferred image [${idx}]: no image decoder available`);
4914
+ }
4843
4915
  } else {
4844
4916
  emfWarn(` Deferred image [${idx}]: metafile conversion returned null`);
4845
4917
  }
4846
4918
  } else {
4847
- emfLog(
4848
- ` Deferred image [${idx}]: creating ImageBitmap from ${plainBuffer.byteLength} byte blob...`
4849
- );
4850
- const blob = new Blob([plainBuffer]);
4851
- const bitmap = await createImageBitmap(blob);
4852
- emfLog(` Deferred image [${idx}]: ImageBitmap created ${bitmap.width}\xD7${bitmap.height}`);
4853
- ctx.drawImage(bitmap, img.dx, img.dy, img.dw, img.dh);
4854
- bitmap.close();
4919
+ emfLog(` Deferred image [${idx}]: decoding ${plainBuffer.byteLength} byte image...`);
4920
+ const decoded = await decodeDeferredImageBytes(plainBuffer);
4921
+ if (decoded) {
4922
+ emfLog(` Deferred image [${idx}]: decoded ${decoded.width}\xD7${decoded.height}`);
4923
+ canvasDrawImage(ctx, decoded.drawable, img.dx, img.dy, img.dw, img.dh);
4924
+ decoded.close();
4925
+ } else {
4926
+ emfWarn(` Deferred image [${idx}]: no image decoder available`);
4927
+ }
4855
4928
  }
4856
4929
  } catch (imgErr) {
4857
4930
  imgErr instanceof Error ? imgErr.message : String(imgErr);
@@ -4864,10 +4937,35 @@ async function processDeferredImages(ctx, deferredImages, recursionDepth = 0) {
4864
4937
  }
4865
4938
  ctx.setTransform(1, 0, 0, 1, 0, 0);
4866
4939
  }
4867
- async function convertEmfToDataUrl(buffer, options, recursionDepth = 0) {
4940
+ async function convertMetafileToDataUrl(buffer, options, recursionDepth = 0) {
4941
+ await ensureNodeCanvasModule();
4868
4942
  if (recursionDepth > MAX_METAFILE_RECURSION) {
4869
4943
  return null;
4870
4944
  }
4945
+ emfLog(`convertMetafileToDataUrl: input buffer ${buffer.byteLength} bytes`);
4946
+ if (buffer.byteLength >= 16) {
4947
+ const hdrBytes = new Uint8Array(buffer, 0, 16);
4948
+ emfLog(
4949
+ `convertMetafileToDataUrl: first 16 bytes: [${Array.from(hdrBytes).map((b) => b.toString(16).padStart(2, "0")).join(" ")}]`
4950
+ );
4951
+ }
4952
+ const view = new DataView(buffer);
4953
+ let emfHeader = null;
4954
+ try {
4955
+ emfHeader = parseEmfHeader(view);
4956
+ } catch (err) {
4957
+ emfWarn(
4958
+ "convertMetafileToDataUrl: parseEmfHeader threw during detection:",
4959
+ err instanceof Error ? err.message : err
4960
+ );
4961
+ emfHeader = null;
4962
+ }
4963
+ if (emfHeader) {
4964
+ return convertEmfInternal(buffer, view, emfHeader, options, recursionDepth);
4965
+ }
4966
+ return convertWmfInternal(buffer, view);
4967
+ }
4968
+ async function convertEmfInternal(buffer, view, header, options, recursionDepth) {
4871
4969
  const opts = {};
4872
4970
  const dpiScale = opts.dpiScale ?? DEFAULT_DPI_SCALE;
4873
4971
  const effectiveMaxWidth = opts.maxWidth;
@@ -4878,30 +4976,18 @@ async function convertEmfToDataUrl(buffer, options, recursionDepth = 0) {
4878
4976
  fontFamilyMap: opts.fontFamilyMap
4879
4977
  };
4880
4978
  try {
4881
- emfLog("=== convertEmfToDataUrl START ===");
4979
+ emfLog("=== convertEmfInternal START ===");
4882
4980
  emfLog(
4883
4981
  `Input buffer: ${buffer.byteLength} bytes, maxWidth=${effectiveMaxWidth}, maxHeight=${effectiveMaxHeight}, dpiScale=${dpiScale}`
4884
4982
  );
4885
- if (buffer.byteLength >= 16) {
4886
- const hdrBytes = new Uint8Array(buffer, 0, 16);
4887
- emfLog(
4888
- `First 16 bytes: [${Array.from(hdrBytes).map((b) => b.toString(16).padStart(2, "0")).join(" ")}]`
4889
- );
4890
- }
4891
- const view = new DataView(buffer);
4892
- const header = parseEmfHeader(view);
4893
- if (!header) {
4894
- emfLog("convertEmfToDataUrl: parseEmfHeader returned null \u2014 returning null");
4895
- return null;
4896
- }
4897
4983
  const renderBounds = getRenderableEmfBounds(header);
4898
4984
  if (!renderBounds) {
4899
- emfLog("convertEmfToDataUrl: getRenderableEmfBounds returned null \u2014 returning null");
4985
+ emfLog("convertEmfInternal: getRenderableEmfBounds returned null, returning null");
4900
4986
  return null;
4901
4987
  }
4902
4988
  const logicalW = renderBounds.right - renderBounds.left;
4903
4989
  const logicalH = renderBounds.bottom - renderBounds.top;
4904
- emfLog(`convertEmfToDataUrl: logicalSize=${logicalW}\xD7${logicalH}`);
4990
+ emfLog(`convertEmfInternal: logicalSize=${logicalW}\xD7${logicalH}`);
4905
4991
  const setup = createCanvas(
4906
4992
  logicalW,
4907
4993
  logicalH,
@@ -4911,15 +4997,15 @@ async function convertEmfToDataUrl(buffer, options, recursionDepth = 0) {
4911
4997
  opts.maxCanvasDimension
4912
4998
  );
4913
4999
  if (!setup) {
4914
- emfLog("convertEmfToDataUrl: createCanvas returned null \u2014 returning null");
5000
+ emfLog("convertEmfInternal: createCanvas returned null, returning null");
4915
5001
  return null;
4916
5002
  }
4917
5003
  const { canvas, ctx } = setup;
4918
5004
  emfLog(
4919
- `convertEmfToDataUrl: canvas created ${canvas.width}\xD7${canvas.height} (dpiScale=${dpiScale})`
5005
+ `convertEmfInternal: canvas created ${canvas.width}\xD7${canvas.height} (dpiScale=${dpiScale})`
4920
5006
  );
4921
5007
  ctx.save();
4922
- emfLog("convertEmfToDataUrl: starting replayEmfRecords...");
5008
+ emfLog("convertEmfInternal: starting replayEmfRecords...");
4923
5009
  const deferredImages = replayEmfRecords(
4924
5010
  view,
4925
5011
  ctx,
@@ -4929,30 +5015,25 @@ async function convertEmfToDataUrl(buffer, options, recursionDepth = 0) {
4929
5015
  dpiScale,
4930
5016
  replayOptions
4931
5017
  );
4932
- emfLog(
4933
- `convertEmfToDataUrl: replayEmfRecords returned ${deferredImages.length} deferred images`
4934
- );
5018
+ emfLog(`convertEmfInternal: replayEmfRecords returned ${deferredImages.length} deferred images`);
4935
5019
  ctx.restore();
4936
- await processDeferredImages(ctx, deferredImages);
4937
- emfLog("convertEmfToDataUrl: exporting canvas to PNG data URL...");
5020
+ await processDeferredImages(ctx, deferredImages, recursionDepth);
5021
+ emfLog("convertEmfInternal: exporting canvas to PNG data URL...");
4938
5022
  const result = await exportCanvasToPngDataUrl(canvas);
4939
5023
  if (result) {
4940
- emfLog(`convertEmfToDataUrl: SUCCESS \u2014 data URL length=${result.length}`);
5024
+ emfLog(`convertEmfInternal: SUCCESS, data URL length=${result.length}`);
4941
5025
  } else {
4942
- emfWarn("convertEmfToDataUrl: exportCanvasToPngDataUrl returned null");
5026
+ emfWarn("convertEmfInternal: exportCanvasToPngDataUrl returned null");
4943
5027
  }
4944
- emfLog("=== convertEmfToDataUrl END ===");
5028
+ emfLog("=== convertEmfInternal END ===");
4945
5029
  return result;
4946
5030
  } catch (err) {
4947
- emfWarn("convertEmfToDataUrl: EXCEPTION:", err instanceof Error ? err.message : err);
4948
- console.warn("[pptx-editor] EMF conversion failed:", err instanceof Error ? err.message : err);
5031
+ emfWarn("convertEmfInternal: EXCEPTION:", err instanceof Error ? err.message : err);
5032
+ console.warn("[emf-converter] EMF conversion failed:", err instanceof Error ? err.message : err);
4949
5033
  return null;
4950
5034
  }
4951
5035
  }
4952
- async function convertWmfToDataUrl(buffer, options, recursionDepth = 0) {
4953
- if (recursionDepth > MAX_METAFILE_RECURSION) {
4954
- return null;
4955
- }
5036
+ async function convertWmfInternal(buffer, view, options, recursionDepth) {
4956
5037
  const opts = {};
4957
5038
  const dpiScale = opts.dpiScale ?? DEFAULT_DPI_SCALE;
4958
5039
  const effectiveMaxWidth = opts.maxWidth;
@@ -4963,20 +5044,19 @@ async function convertWmfToDataUrl(buffer, options, recursionDepth = 0) {
4963
5044
  };
4964
5045
  try {
4965
5046
  emfLog(
4966
- "=== convertWmfToDataUrl START ===",
5047
+ "=== convertWmfInternal START ===",
4967
5048
  `buffer=${buffer.byteLength} bytes, dpiScale=${dpiScale}`
4968
5049
  );
4969
- const view = new DataView(buffer);
4970
5050
  const header = parseWmfHeader(view);
4971
5051
  if (!header) {
4972
- emfLog("convertWmfToDataUrl: parseWmfHeader returned null");
5052
+ emfLog("convertWmfInternal: parseWmfHeader returned null");
4973
5053
  return null;
4974
5054
  }
4975
5055
  const logicalW = header.boundsRight - header.boundsLeft;
4976
5056
  const logicalH = header.boundsBottom - header.boundsTop;
4977
- emfLog(`convertWmfToDataUrl: logicalSize=${logicalW}\xD7${logicalH}`);
5057
+ emfLog(`convertWmfInternal: logicalSize=${logicalW}\xD7${logicalH}`);
4978
5058
  if (logicalW <= 0 || logicalH <= 0) {
4979
- emfLog("convertWmfToDataUrl: invalid dimensions \u2014 returning null");
5059
+ emfLog("convertWmfInternal: invalid dimensions, returning null");
4980
5060
  return null;
4981
5061
  }
4982
5062
  const setup = createCanvas(
@@ -4995,12 +5075,12 @@ async function convertWmfToDataUrl(buffer, options, recursionDepth = 0) {
4995
5075
  replayWmfRecords(view, ctx, header, canvas.width, canvas.height, replayOptions);
4996
5076
  ctx.restore();
4997
5077
  const result = await exportCanvasToPngDataUrl(canvas);
4998
- emfLog(`convertWmfToDataUrl: result=${result ? `dataUrl len=${result.length}` : "null"}`);
4999
- emfLog("=== convertWmfToDataUrl END ===");
5078
+ emfLog(`convertWmfInternal: result=${result ? `dataUrl len=${result.length}` : "null"}`);
5079
+ emfLog("=== convertWmfInternal END ===");
5000
5080
  return result;
5001
5081
  } catch (err) {
5002
- emfWarn("convertWmfToDataUrl: EXCEPTION:", err instanceof Error ? err.message : err);
5003
- console.warn("[pptx-editor] WMF conversion failed:", err instanceof Error ? err.message : err);
5082
+ emfWarn("convertWmfInternal: EXCEPTION:", err instanceof Error ? err.message : err);
5083
+ console.warn("[emf-converter] WMF conversion failed:", err instanceof Error ? err.message : err);
5004
5084
  return null;
5005
5085
  }
5006
5086
  }
@@ -96143,7 +96223,7 @@ var init_PptxHandlerRuntimeMediaData = __esm({
96143
96223
  try {
96144
96224
  if (ext === "emf" || ext === "wmf") {
96145
96225
  const binaryBuffer = await imageFile2.async("arraybuffer");
96146
- const converted = ext === "emf" ? await convertEmfToDataUrl(binaryBuffer) : await convertWmfToDataUrl(binaryBuffer);
96226
+ const converted = await convertMetafileToDataUrl(binaryBuffer);
96147
96227
  if (converted) {
96148
96228
  this.imageDataCache.set(imagePath, converted);
96149
96229
  return converted;
@@ -185735,105 +185815,90 @@ function presenceToCursors(presence, activeSlideIndex) {
185735
185815
  }
185736
185816
  return cursors;
185737
185817
  }
185738
- function zoomEqual(a, b) {
185739
- if (a === b) {
185740
- return true;
185741
- }
185742
- if (!a || !b) {
185743
- return false;
185744
- }
185745
- return a.scale === b.scale && a.originX === b.originX && a.originY === b.originY;
185746
- }
185747
- function pointerEqual(a, b) {
185748
- if (a === b) {
185749
- return true;
185750
- }
185751
- if (!a || !b) {
185752
- return false;
185753
- }
185754
- return a.tool === b.tool && a.x === b.x && a.y === b.y && a.color === b.color;
185755
- }
185756
- function presentationSnapshotsEqual(a, b) {
185757
- if (a === b) {
185758
- return true;
185759
- }
185760
- return a.slideIndex === b.slideIndex && a.buildStep === b.buildStep && a.blackout === b.blackout && a.paused === b.paused && a.elapsedMs === b.elapsedMs && a.caption === b.caption && a.subtitlesVisible === b.subtitlesVisible && a.inkMarkupVisible === b.inkMarkupVisible && a.inkStrokes === b.inkStrokes && zoomEqual(a.zoom, b.zoom) && pointerEqual(a.pointer, b.pointer);
185761
- }
185762
- function presenceEntriesEqual(a, b) {
185763
- if (a === b) {
185764
- return true;
185765
- }
185766
- return a.clientId === b.clientId && a.userName === b.userName && a.userColor === b.userColor && a.userAvatar === b.userAvatar && a.role === b.role && a.activeSlideIndex === b.activeSlideIndex && a.cursorX === b.cursorX && a.cursorY === b.cursorY && a.selectedElementId === b.selectedElementId;
185767
- }
185768
- function presenceListsEqual(a, b) {
185769
- if (a === b) {
185770
- return true;
185771
- }
185772
- if (a.length !== b.length) {
185773
- return false;
185818
+ function observeExternalCollaborationSession(session, onSnapshot) {
185819
+ let active2 = true;
185820
+ let subscribing = true;
185821
+ let previous;
185822
+ let unsubscribe;
185823
+ const notify = () => {
185824
+ if (!active2 || subscribing) {
185825
+ return;
185826
+ }
185827
+ const snapshot = session.getSnapshot();
185828
+ if (previous?.status === snapshot.status && previous.synced === snapshot.synced) {
185829
+ return;
185830
+ }
185831
+ previous = { status: snapshot.status, synced: snapshot.synced };
185832
+ onSnapshot(previous);
185833
+ };
185834
+ const dispose = () => {
185835
+ if (!active2) {
185836
+ return;
185837
+ }
185838
+ active2 = false;
185839
+ unsubscribe?.();
185840
+ };
185841
+ try {
185842
+ unsubscribe = session.subscribe(notify);
185843
+ subscribing = false;
185844
+ notify();
185845
+ } catch (error) {
185846
+ dispose();
185847
+ throw error;
185774
185848
  }
185775
- return a.every((entry2, index) => {
185776
- const other = b[index];
185777
- return other !== void 0 && presenceEntriesEqual(entry2, other);
185778
- });
185849
+ return dispose;
185779
185850
  }
185780
- function createPresenceProjector() {
185781
- let lastList = [];
185782
- let lastCursors = [];
185783
- let lastActiveSlideIndex;
185784
- let primed = false;
185851
+ function borrowExternalCollaborationAwareness(host) {
185852
+ let disposed = false;
185853
+ let ownsPresence = false;
185854
+ let hadPresence = false;
185855
+ let previousPresence;
185856
+ let lastPresence;
185857
+ const awareness = {
185858
+ clientID: host.clientID,
185859
+ getStates: () => host.getStates(),
185860
+ on: (event, callback) => host.on(event, callback),
185861
+ off: (event, callback) => host.off(event, callback),
185862
+ setLocalStateField: (field, value) => {
185863
+ if (disposed) {
185864
+ return;
185865
+ }
185866
+ const state = host.getLocalState();
185867
+ if (state === null) {
185868
+ return;
185869
+ }
185870
+ if (field === "presence") {
185871
+ if (!ownsPresence || state.presence !== lastPresence) {
185872
+ hadPresence = Object.hasOwn(state, "presence");
185873
+ previousPresence = state.presence;
185874
+ }
185875
+ lastPresence = value;
185876
+ ownsPresence = true;
185877
+ }
185878
+ host.setLocalStateField(field, value);
185879
+ }
185880
+ };
185785
185881
  return {
185786
- project(states, localClientId, canvasWidth, canvasHeight, localActiveSlideIndex, now) {
185787
- const list = derivePresenceList(
185788
- states,
185789
- localClientId,
185790
- canvasWidth,
185791
- canvasHeight,
185792
- now ?? Date.now()
185793
- );
185794
- if (primed && localActiveSlideIndex === lastActiveSlideIndex && presenceListsEqual(lastList, list)) {
185795
- return { list: lastList, cursors: lastCursors, changed: false };
185882
+ awareness,
185883
+ dispose: () => {
185884
+ if (disposed) {
185885
+ return;
185796
185886
  }
185797
- lastList = list;
185798
- lastCursors = presenceToCursors(list, localActiveSlideIndex);
185799
- lastActiveSlideIndex = localActiveSlideIndex;
185800
- primed = true;
185801
- return { list, cursors: lastCursors, changed: true };
185802
- },
185803
- reset() {
185804
- lastList = [];
185805
- lastCursors = [];
185806
- lastActiveSlideIndex = void 0;
185807
- primed = false;
185887
+ disposed = true;
185888
+ const current = host.getLocalState();
185889
+ if (!ownsPresence || current === null || current.presence !== lastPresence) {
185890
+ return;
185891
+ }
185892
+ const restored = { ...current };
185893
+ if (hadPresence) {
185894
+ restored.presence = previousPresence;
185895
+ } else {
185896
+ delete restored.presence;
185897
+ }
185898
+ host.setLocalState(restored);
185808
185899
  }
185809
185900
  };
185810
185901
  }
185811
- var DEFAULT_LOCAL_COLOR = "#6366f1";
185812
- function getUserInitials(name) {
185813
- const trimmed = name.trim(), parts = trimmed.split(/\s+/u).filter(Boolean), first = parts[0], last = parts[parts.length - 1];
185814
- if (parts.length >= 2 && first && last) {
185815
- return (first[0] + last[0]).toUpperCase();
185816
- }
185817
- return trimmed.slice(0, 2).toUpperCase();
185818
- }
185819
- function buildActiveSessionUsers(params) {
185820
- const local = {
185821
- id: "local",
185822
- name: params.localUserName,
185823
- initials: params.localUserInitials?.trim() ? params.localUserInitials.trim().slice(0, 2).toUpperCase() : getUserInitials(params.localUserName),
185824
- color: params.localUserColor ?? DEFAULT_LOCAL_COLOR,
185825
- isLocal: true
185826
- }, remote = params.remoteUsers.map((user) => ({
185827
- id: String(user.clientId),
185828
- name: user.userName,
185829
- initials: getUserInitials(user.userName),
185830
- color: user.userColor,
185831
- avatarUrl: user.userAvatar,
185832
- isLocal: false,
185833
- slideNumber: user.activeSlideIndex + 1
185834
- }));
185835
- return [local, ...remote];
185836
- }
185837
185902
  var YDOC_ASSETS_KEY = "pptx:assets";
185838
185903
  var ASSET_ELEMENT_FIELDS = /* @__PURE__ */ new Set([
185839
185904
  "mediaData",
@@ -186102,8 +186167,14 @@ function decodeDelta(delta) {
186102
186167
  } catch {
186103
186168
  }
186104
186169
  }
186105
- const isBreakMarker = op2.insert === "\n" && (a.pb === "1" || a.lb === "1");
186106
- if (!isBreakMarker && op2.insert !== "\u200B") {
186170
+ const isBreakMarker = /^\n+$/u.test(op2.insert) && (a.pb === "1" || a.lb === "1");
186171
+ if (isBreakMarker) {
186172
+ for (let index = 0; index < op2.insert.length; index++) {
186173
+ segments.push(structuredClone(seg));
186174
+ }
186175
+ continue;
186176
+ }
186177
+ if (op2.insert !== "\u200B") {
186107
186178
  seg.text = op2.insert;
186108
186179
  }
186109
186180
  segments.push(seg);
@@ -186429,9 +186500,6 @@ function observeYDocSlides(ydoc, onChange) {
186429
186500
  arr.observeDeep(onChange);
186430
186501
  return () => arr.unobserveDeep(onChange);
186431
186502
  }
186432
- function shouldAutoFollowBroadcaster(input) {
186433
- return input.localRole === "viewer" && input.broadcasterRole === "owner";
186434
- }
186435
186503
  function isYTextEditable(value) {
186436
186504
  return isYTextLike(value) && typeof value.delete === "function" && typeof value.format === "function";
186437
186505
  }
@@ -186704,6 +186772,231 @@ function reconcileSlidesInYDoc(slides, ydoc, factories, origin = LOCAL_SYNC_ORIG
186704
186772
  });
186705
186773
  }, origin);
186706
186774
  }
186775
+ function observeExternalCollaborationReadiness(session, options) {
186776
+ let active2 = true;
186777
+ let established = false;
186778
+ let awaitingJoin = options.sessionIntent === "join";
186779
+ let lastAdopted;
186780
+ let lastReadOnly;
186781
+ let unsubscribe;
186782
+ const canWrite = () => active2 && options.gate.isOpen() && session.getSnapshot().synced && options.role !== "viewer";
186783
+ const notifyReadOnly = () => {
186784
+ const readOnly = !canWrite();
186785
+ if (lastReadOnly !== readOnly) {
186786
+ lastReadOnly = readOnly;
186787
+ options.onReadOnlyChange?.(readOnly);
186788
+ }
186789
+ };
186790
+ const suspend = () => {
186791
+ options.gate.reset();
186792
+ options.livePatcher?.configure(null, null);
186793
+ options.onSuspend?.();
186794
+ notifyReadOnly();
186795
+ };
186796
+ const adopt = (slides) => {
186797
+ const serialized = JSON.stringify(slides);
186798
+ if (serialized !== lastAdopted) {
186799
+ lastAdopted = serialized;
186800
+ options.adoptSlides(slides);
186801
+ }
186802
+ };
186803
+ const refresh = () => {
186804
+ if (!active2) {
186805
+ return;
186806
+ }
186807
+ const snapshot = session.getSnapshot();
186808
+ options.onStatus(snapshot.status);
186809
+ if (!snapshot.synced) {
186810
+ suspend();
186811
+ return;
186812
+ }
186813
+ if (options.gate.isOpen()) {
186814
+ return;
186815
+ }
186816
+ lastAdopted = void 0;
186817
+ const slides = readSlidesFromYDoc(session.doc);
186818
+ if (slides.length > 0) {
186819
+ established = true;
186820
+ awaitingJoin = false;
186821
+ adopt(slides);
186822
+ } else if (established) {
186823
+ adopt(slides);
186824
+ } else if (awaitingJoin) {
186825
+ suspend();
186826
+ return;
186827
+ }
186828
+ options.livePatcher?.configure(
186829
+ options.role === "viewer" ? null : session.doc,
186830
+ options.role === "viewer" ? null : options.factories,
186831
+ // The host owns readiness, so accepted edits cannot wait in our timer.
186832
+ true
186833
+ );
186834
+ options.gate.open();
186835
+ notifyReadOnly();
186836
+ options.onReady?.({ seedEmptyRoom: slides.length === 0 && !established });
186837
+ };
186838
+ const unobserve = observeYDocSlides(session.doc, (_events, transaction) => {
186839
+ if (!active2 || !session.getSnapshot().synced) {
186840
+ return;
186841
+ }
186842
+ const slides = readSlidesFromYDoc(session.doc);
186843
+ if (slides.length > 0) {
186844
+ established = true;
186845
+ awaitingJoin = false;
186846
+ }
186847
+ if (transaction?.origin === LOCAL_SYNC_ORIGIN) {
186848
+ lastAdopted = JSON.stringify(slides);
186849
+ return;
186850
+ }
186851
+ if (!options.gate.isOpen()) {
186852
+ refresh();
186853
+ } else if (slides.length > 0 || established) {
186854
+ adopt(slides);
186855
+ }
186856
+ });
186857
+ const dispose = () => {
186858
+ if (!active2) {
186859
+ return;
186860
+ }
186861
+ active2 = false;
186862
+ unsubscribe?.();
186863
+ unobserve();
186864
+ suspend();
186865
+ };
186866
+ try {
186867
+ unsubscribe = observeExternalCollaborationSession(session, refresh);
186868
+ } catch (error) {
186869
+ dispose();
186870
+ throw error;
186871
+ }
186872
+ return Object.assign(dispose, {
186873
+ refresh,
186874
+ canWrite,
186875
+ handleLoad: (origin) => {
186876
+ if (!active2) {
186877
+ return false;
186878
+ }
186879
+ if (origin === "user") {
186880
+ awaitingJoin = false;
186881
+ refresh();
186882
+ } else if (session.getSnapshot().synced) {
186883
+ const slides = readSlidesFromYDoc(session.doc);
186884
+ if (slides.length > 0) {
186885
+ lastAdopted = void 0;
186886
+ adopt(slides);
186887
+ return true;
186888
+ }
186889
+ }
186890
+ return false;
186891
+ },
186892
+ allowLocalLoad: () => {
186893
+ awaitingJoin = false;
186894
+ refresh();
186895
+ }
186896
+ });
186897
+ }
186898
+ function zoomEqual(a, b) {
186899
+ if (a === b) {
186900
+ return true;
186901
+ }
186902
+ if (!a || !b) {
186903
+ return false;
186904
+ }
186905
+ return a.scale === b.scale && a.originX === b.originX && a.originY === b.originY;
186906
+ }
186907
+ function pointerEqual(a, b) {
186908
+ if (a === b) {
186909
+ return true;
186910
+ }
186911
+ if (!a || !b) {
186912
+ return false;
186913
+ }
186914
+ return a.tool === b.tool && a.x === b.x && a.y === b.y && a.color === b.color;
186915
+ }
186916
+ function presentationSnapshotsEqual(a, b) {
186917
+ if (a === b) {
186918
+ return true;
186919
+ }
186920
+ return a.slideIndex === b.slideIndex && a.buildStep === b.buildStep && a.blackout === b.blackout && a.paused === b.paused && a.elapsedMs === b.elapsedMs && a.caption === b.caption && a.subtitlesVisible === b.subtitlesVisible && a.inkMarkupVisible === b.inkMarkupVisible && a.inkStrokes === b.inkStrokes && zoomEqual(a.zoom, b.zoom) && pointerEqual(a.pointer, b.pointer);
186921
+ }
186922
+ function presenceEntriesEqual(a, b) {
186923
+ if (a === b) {
186924
+ return true;
186925
+ }
186926
+ return a.clientId === b.clientId && a.userName === b.userName && a.userColor === b.userColor && a.userAvatar === b.userAvatar && a.role === b.role && a.activeSlideIndex === b.activeSlideIndex && a.cursorX === b.cursorX && a.cursorY === b.cursorY && a.selectedElementId === b.selectedElementId;
186927
+ }
186928
+ function presenceListsEqual(a, b) {
186929
+ if (a === b) {
186930
+ return true;
186931
+ }
186932
+ if (a.length !== b.length) {
186933
+ return false;
186934
+ }
186935
+ return a.every((entry2, index) => {
186936
+ const other = b[index];
186937
+ return other !== void 0 && presenceEntriesEqual(entry2, other);
186938
+ });
186939
+ }
186940
+ function createPresenceProjector() {
186941
+ let lastList = [];
186942
+ let lastCursors = [];
186943
+ let lastActiveSlideIndex;
186944
+ let primed = false;
186945
+ return {
186946
+ project(states, localClientId, canvasWidth, canvasHeight, localActiveSlideIndex, now) {
186947
+ const list = derivePresenceList(
186948
+ states,
186949
+ localClientId,
186950
+ canvasWidth,
186951
+ canvasHeight,
186952
+ now ?? Date.now()
186953
+ );
186954
+ if (primed && localActiveSlideIndex === lastActiveSlideIndex && presenceListsEqual(lastList, list)) {
186955
+ return { list: lastList, cursors: lastCursors, changed: false };
186956
+ }
186957
+ lastList = list;
186958
+ lastCursors = presenceToCursors(list, localActiveSlideIndex);
186959
+ lastActiveSlideIndex = localActiveSlideIndex;
186960
+ primed = true;
186961
+ return { list, cursors: lastCursors, changed: true };
186962
+ },
186963
+ reset() {
186964
+ lastList = [];
186965
+ lastCursors = [];
186966
+ lastActiveSlideIndex = void 0;
186967
+ primed = false;
186968
+ }
186969
+ };
186970
+ }
186971
+ var DEFAULT_LOCAL_COLOR = "#6366f1";
186972
+ function getUserInitials(name) {
186973
+ const trimmed = name.trim(), parts = trimmed.split(/\s+/u).filter(Boolean), first = parts[0], last = parts[parts.length - 1];
186974
+ if (parts.length >= 2 && first && last) {
186975
+ return (first[0] + last[0]).toUpperCase();
186976
+ }
186977
+ return trimmed.slice(0, 2).toUpperCase();
186978
+ }
186979
+ function buildActiveSessionUsers(params) {
186980
+ const local = {
186981
+ id: "local",
186982
+ name: params.localUserName,
186983
+ initials: params.localUserInitials?.trim() ? params.localUserInitials.trim().slice(0, 2).toUpperCase() : getUserInitials(params.localUserName),
186984
+ color: params.localUserColor ?? DEFAULT_LOCAL_COLOR,
186985
+ isLocal: true
186986
+ }, remote = params.remoteUsers.map((user) => ({
186987
+ id: String(user.clientId),
186988
+ name: user.userName,
186989
+ initials: getUserInitials(user.userName),
186990
+ color: user.userColor,
186991
+ avatarUrl: user.userAvatar,
186992
+ isLocal: false,
186993
+ slideNumber: user.activeSlideIndex + 1
186994
+ }));
186995
+ return [local, ...remote];
186996
+ }
186997
+ function shouldAutoFollowBroadcaster(input) {
186998
+ return input.localRole === "viewer" && input.broadcasterRole === "owner";
186999
+ }
186707
187000
  var GEOMETRY_KEYS = ["x", "y", "width", "height", "rotation"];
186708
187001
  var MAX_LIVE_TEXT_LENGTH = 1e5;
186709
187002
  var asMap = (value) => typeof value === "object" && value !== null && typeof value.get === "function" ? value : void 0;
@@ -186761,6 +187054,7 @@ function createCollaborationLivePatcher(options = {}) {
186761
187054
  let factories = null;
186762
187055
  let timer = null;
186763
187056
  let lastWriteAt = Number.NEGATIVE_INFINITY;
187057
+ let immediate = false;
186764
187058
  const cancelTimer = () => {
186765
187059
  if (timer !== null) {
186766
187060
  clearTimeout(timer);
@@ -186787,6 +187081,10 @@ function createCollaborationLivePatcher(options = {}) {
186787
187081
  }
186788
187082
  };
186789
187083
  const schedule = () => {
187084
+ if (immediate) {
187085
+ writePending();
187086
+ return;
187087
+ }
186790
187088
  if (timer !== null) {
186791
187089
  return;
186792
187090
  }
@@ -186813,14 +187111,15 @@ function createCollaborationLivePatcher(options = {}) {
186813
187111
  return entry2;
186814
187112
  };
186815
187113
  return {
186816
- configure(nextDoc, nextFactories) {
186817
- if (nextDoc === doc && nextFactories === factories) {
187114
+ configure(nextDoc, nextFactories, nextImmediate = false) {
187115
+ if (nextDoc === doc && nextFactories === factories && nextImmediate === immediate) {
186818
187116
  return;
186819
187117
  }
186820
187118
  cancelTimer();
186821
187119
  pending.clear();
186822
187120
  doc = nextDoc;
186823
187121
  factories = nextFactories;
187122
+ immediate = nextImmediate;
186824
187123
  lastWriteAt = Number.NEGATIVE_INFINITY;
186825
187124
  },
186826
187125
  isActive() {
@@ -186947,7 +187246,10 @@ function registerCollaborationTeardown(options) {
186947
187246
  doLeave();
186948
187247
  };
186949
187248
  const onBeforeUnload = () => {
186950
- doLeave();
187249
+ const allowed = typeof options.leaveOnBeforeUnload === "function" ? options.leaveOnBeforeUnload() : options.leaveOnBeforeUnload !== false;
187250
+ if (allowed) {
187251
+ doLeave();
187252
+ }
186951
187253
  };
186952
187254
  const onPageShow = (event) => {
186953
187255
  if (event.persisted !== true || !left || !rejoin) {
@@ -187046,6 +187348,84 @@ function createDepartureChannel(roomId, awareness, factory) {
187046
187348
  }
187047
187349
  };
187048
187350
  }
187351
+ var DEFAULT_DEBOUNCE_MS = 5e3;
187352
+ function createWriteBackScheduler(deps) {
187353
+ let timer = null;
187354
+ let generation = 0;
187355
+ let unsubscribe = null;
187356
+ function cancel() {
187357
+ generation++;
187358
+ unsubscribe?.();
187359
+ unsubscribe = null;
187360
+ if (timer !== null) {
187361
+ clearTimeout(timer);
187362
+ timer = null;
187363
+ }
187364
+ }
187365
+ function schedule(config) {
187366
+ const isReady = () => config.externalSession?.getSnapshot().synced ?? true;
187367
+ if (!config.onWriteBack || config.role !== "owner" || !deps.getYDoc()) {
187368
+ return;
187369
+ }
187370
+ cancel();
187371
+ if (!isReady()) {
187372
+ return;
187373
+ }
187374
+ const token2 = generation;
187375
+ if (config.externalSession) {
187376
+ const detach2 = config.externalSession.subscribe(() => {
187377
+ if (!isReady()) {
187378
+ cancel();
187379
+ }
187380
+ });
187381
+ if (token2 !== generation || !isReady()) {
187382
+ detach2();
187383
+ return;
187384
+ }
187385
+ unsubscribe = detach2;
187386
+ }
187387
+ const debounceMs = config.writeBackDebounceMs ?? DEFAULT_DEBOUNCE_MS;
187388
+ timer = setTimeout(async () => {
187389
+ timer = null;
187390
+ const ydoc = deps.getYDoc();
187391
+ const isCurrent = () => token2 === generation && isReady() && deps.getYDoc() === ydoc;
187392
+ try {
187393
+ if (!ydoc || !config.onWriteBack || !isReady()) {
187394
+ return;
187395
+ }
187396
+ if (deps.serialize) {
187397
+ const bytes2 = await deps.serialize(isCurrent);
187398
+ if (bytes2 && isCurrent()) {
187399
+ await config.onWriteBack(bytes2);
187400
+ }
187401
+ return;
187402
+ }
187403
+ const sourceBytes = deps.getSourceBytes?.();
187404
+ if (!sourceBytes) {
187405
+ return;
187406
+ }
187407
+ const handler = new exports.PptxHandler();
187408
+ await handler.load(sourceBytes.buffer);
187409
+ if (!isCurrent()) {
187410
+ return;
187411
+ }
187412
+ const slides = readSlidesFromYDoc(ydoc);
187413
+ const merged = deps.mergeTemplateElements ? deps.mergeTemplateElements(slides, deps.getTemplateElements?.() ?? {}) : slides;
187414
+ const bytes = await handler.save(merged, deps.getSaveOptions?.());
187415
+ if (isCurrent()) {
187416
+ await config.onWriteBack(bytes);
187417
+ }
187418
+ } catch {
187419
+ } finally {
187420
+ if (token2 === generation) {
187421
+ unsubscribe?.();
187422
+ unsubscribe = null;
187423
+ }
187424
+ }
187425
+ }, debounceMs);
187426
+ }
187427
+ return { schedule, cancel };
187428
+ }
187049
187429
  var POSITION_THRESHOLD = 2;
187050
187430
  var SIZE_THRESHOLD = 2;
187051
187431
  function getElementText(element) {
@@ -208002,6 +208382,7 @@ exports.beginChartValueDrag = beginChartValueDrag;
208002
208382
  exports.beginShapeAdjustment = beginShapeAdjustment;
208003
208383
  exports.bindInlineListParagraph = bindInlineListParagraph;
208004
208384
  exports.bindInlineListRun = bindInlineListRun;
208385
+ exports.borrowExternalCollaborationAwareness = borrowExternalCollaborationAwareness;
208005
208386
  exports.bringForward = bringForward;
208006
208387
  exports.bringToFront = bringToFront;
208007
208388
  exports.build3DExtrusionData = build3DExtrusionData;
@@ -208204,6 +208585,7 @@ exports.createTouchGestureRecognizer = createTouchGestureRecognizer;
208204
208585
  exports.createViewerOptionsStore = createViewerOptionsStore;
208205
208586
  exports.createViewerZoomStore = createViewerZoomStore;
208206
208587
  exports.createWheelStepBuffer = createWheelStepBuffer;
208588
+ exports.createWriteBackScheduler = createWriteBackScheduler;
208207
208589
  exports.cursorForTool = cursorForTool;
208208
208590
  exports.customGeometryPathsToSvgSubpaths = customGeometryPathsToSvgSubpaths;
208209
208591
  exports.defaultCssVars = defaultCssVars;
@@ -208482,6 +208864,8 @@ exports.normalizeHexColor = normalizeHexColor2;
208482
208864
  exports.normalizeStrokeDashType = normalizeStrokeDashType;
208483
208865
  exports.normalizeTableStyleGuid = normalizeTableStyleGuid;
208484
208866
  exports.notesSegmentsToSpans = notesSegmentsToSpans;
208867
+ exports.observeExternalCollaborationReadiness = observeExternalCollaborationReadiness;
208868
+ exports.observeExternalCollaborationSession = observeExternalCollaborationSession;
208485
208869
  exports.observeYDocSlides = observeYDocSlides;
208486
208870
  exports.ooxmlGradientAngleToCssDegrees = ooxmlGradientAngleToCssDegrees;
208487
208871
  exports.openNativeEyeDropper = openNativeEyeDropper;