pptx-react-viewer 3.13.0 → 3.14.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.
- package/CHANGELOG.md +18 -0
- package/dist/{AiChatPanel-E53JJRZX.js → AiChatPanel-42X7I5I2.js} +32 -32
- package/dist/AiChatPanel-42X7I5I2.js.br +0 -0
- package/dist/AiChatPanel-42X7I5I2.js.gz +0 -0
- package/dist/{AiChatPanel-JTXC5WWH.mjs → AiChatPanel-NJBUCO4X.mjs} +11 -11
- package/dist/AiChatPanel-NJBUCO4X.mjs.br +0 -0
- package/dist/AiChatPanel-NJBUCO4X.mjs.gz +0 -0
- package/dist/{Area3DChartScene-J7G54OH4.js → Area3DChartScene-IDS5APPJ.js} +2 -2
- package/dist/Area3DChartScene-IDS5APPJ.js.br +0 -0
- package/dist/Area3DChartScene-IDS5APPJ.js.gz +0 -0
- package/dist/{Area3DChartScene-JQ2VU73H.mjs → Area3DChartScene-TFZPHEZ6.mjs} +1 -1
- package/dist/Area3DChartScene-TFZPHEZ6.mjs.br +0 -0
- package/dist/Area3DChartScene-TFZPHEZ6.mjs.gz +0 -0
- package/dist/{Bar3DChartScene-JV3A2P6O.js → Bar3DChartScene-C3CQCKB6.js} +2 -2
- package/dist/Bar3DChartScene-C3CQCKB6.js.br +0 -0
- package/dist/Bar3DChartScene-C3CQCKB6.js.gz +0 -0
- package/dist/{Bar3DChartScene-5HC7LYBH.mjs → Bar3DChartScene-L3VXO7BS.mjs} +1 -1
- package/dist/Bar3DChartScene-L3VXO7BS.mjs.br +0 -0
- package/dist/Bar3DChartScene-L3VXO7BS.mjs.gz +0 -0
- package/dist/{Line3DChartScene-4ZAOOU7U.mjs → Line3DChartScene-UM4ZJJSY.mjs} +1 -1
- package/dist/Line3DChartScene-UM4ZJJSY.mjs.br +0 -0
- package/dist/Line3DChartScene-UM4ZJJSY.mjs.gz +0 -0
- package/dist/{Line3DChartScene-7SN7TVKQ.js → Line3DChartScene-YU4M3VMW.js} +2 -2
- package/dist/Line3DChartScene-YU4M3VMW.js.br +0 -0
- package/dist/Line3DChartScene-YU4M3VMW.js.gz +0 -0
- package/dist/{Model3DScene-GWIBUQ2U.mjs → Model3DScene-YEWZQAN5.mjs} +1 -1
- package/dist/Model3DScene-YEWZQAN5.mjs.br +0 -0
- package/dist/Model3DScene-YEWZQAN5.mjs.gz +0 -0
- package/dist/{Model3DScene-GQANXXQD.js → Model3DScene-YRRNSOYK.js} +2 -2
- package/dist/Model3DScene-YRRNSOYK.js.br +0 -0
- package/dist/Model3DScene-YRRNSOYK.js.gz +0 -0
- package/dist/{PieChart3DScene-RDTOLFTD.mjs → PieChart3DScene-2OBYYK55.mjs} +1 -1
- package/dist/PieChart3DScene-2OBYYK55.mjs.br +0 -0
- package/dist/PieChart3DScene-2OBYYK55.mjs.gz +0 -0
- package/dist/{PieChart3DScene-QPFDRMEA.js → PieChart3DScene-GH4X3W3E.js} +2 -2
- package/dist/PieChart3DScene-GH4X3W3E.js.br +0 -0
- package/dist/PieChart3DScene-GH4X3W3E.js.gz +0 -0
- package/dist/{SurfaceChart3DScene-5JQCRWA5.mjs → SurfaceChart3DScene-DYG5I5UP.mjs} +1 -1
- package/dist/SurfaceChart3DScene-DYG5I5UP.mjs.br +0 -0
- package/dist/SurfaceChart3DScene-DYG5I5UP.mjs.gz +0 -0
- package/dist/{SurfaceChart3DScene-JLYGC7QU.js → SurfaceChart3DScene-J5CAPHVA.js} +2 -2
- package/dist/SurfaceChart3DScene-J5CAPHVA.js.br +0 -0
- package/dist/SurfaceChart3DScene-J5CAPHVA.js.gz +0 -0
- package/dist/{chunk-UGVPKJSU.js → chunk-7OMXJNYI.js} +1568 -1416
- package/dist/chunk-7OMXJNYI.js.br +0 -0
- package/dist/chunk-7OMXJNYI.js.gz +0 -0
- package/dist/{chunk-H3GHGSGW.js → chunk-7Z7AY4MH.js} +688 -546
- package/dist/chunk-7Z7AY4MH.js.br +0 -0
- package/dist/chunk-7Z7AY4MH.js.gz +0 -0
- package/dist/{chunk-PKHTTHA2.mjs → chunk-EZ3EI2VM.mjs} +323 -171
- package/dist/chunk-EZ3EI2VM.mjs.br +0 -0
- package/dist/chunk-EZ3EI2VM.mjs.gz +0 -0
- package/dist/{chunk-M7SNS3DQ.mjs → chunk-GQMVEUHM.mjs} +263 -122
- package/dist/chunk-GQMVEUHM.mjs.br +0 -0
- package/dist/chunk-GQMVEUHM.mjs.gz +0 -0
- package/dist/{chunk-IVCYND7A.js → chunk-H4LMXJ2Z.js} +167 -167
- package/dist/chunk-H4LMXJ2Z.js.br +0 -0
- package/dist/chunk-H4LMXJ2Z.js.gz +0 -0
- package/dist/{chunk-TS2DHMBS.mjs → chunk-HADPGII2.mjs} +43955 -43185
- package/dist/chunk-HADPGII2.mjs.br +0 -0
- package/dist/chunk-HADPGII2.mjs.gz +0 -0
- package/dist/{chunk-G2Z7QULX.js → chunk-INKQT4SQ.js} +5 -5
- package/dist/chunk-INKQT4SQ.js.br +0 -0
- package/dist/chunk-INKQT4SQ.js.gz +0 -0
- package/dist/{chunk-TWUAZRCG.js → chunk-MH4VFSDL.js} +43966 -43185
- package/dist/chunk-MH4VFSDL.js.br +0 -0
- package/dist/chunk-MH4VFSDL.js.gz +0 -0
- package/dist/{chunk-Y3SA5H5H.mjs → chunk-OVOXRK7D.mjs} +1 -1
- package/dist/chunk-OVOXRK7D.mjs.br +0 -0
- package/dist/chunk-OVOXRK7D.mjs.gz +0 -0
- package/dist/{chunk-HB7DJENT.mjs → chunk-YFYSY7ZL.mjs} +1 -1
- package/dist/chunk-YFYSY7ZL.mjs.br +0 -0
- package/dist/{chunk-HB7DJENT.mjs.gz → chunk-YFYSY7ZL.mjs.gz} +0 -0
- package/dist/index.js +45 -45
- package/dist/index.js.br +0 -0
- package/dist/index.js.gz +0 -0
- package/dist/index.mjs +5 -5
- package/dist/index.mjs.br +0 -0
- package/dist/index.mjs.gz +0 -0
- package/dist/internals.d.ts +33 -1
- package/dist/internals.d.ts.map +1 -1
- package/dist/internals.js +78 -78
- package/dist/internals.js.br +0 -0
- package/dist/internals.js.gz +0 -0
- package/dist/internals.mjs +3 -3
- package/dist/internals.mjs.br +0 -0
- package/dist/internals.mjs.gz +0 -0
- package/dist/pptx-viewer.css +1 -1
- package/dist/pptx-viewer.css.br +0 -0
- package/dist/pptx-viewer.css.gz +0 -0
- package/dist/viewer/index.js +26 -26
- package/dist/viewer/index.js.br +0 -0
- package/dist/viewer/index.js.gz +0 -0
- package/dist/viewer/index.mjs +5 -5
- package/dist/viewer/index.mjs.br +0 -0
- package/dist/viewer/index.mjs.gz +0 -0
- package/package.json +3 -1
- package/dist/AiChatPanel-E53JJRZX.js.br +0 -0
- package/dist/AiChatPanel-E53JJRZX.js.gz +0 -0
- package/dist/AiChatPanel-JTXC5WWH.mjs.br +0 -0
- package/dist/AiChatPanel-JTXC5WWH.mjs.gz +0 -0
- package/dist/Area3DChartScene-J7G54OH4.js.br +0 -0
- package/dist/Area3DChartScene-J7G54OH4.js.gz +0 -0
- package/dist/Area3DChartScene-JQ2VU73H.mjs.br +0 -0
- package/dist/Area3DChartScene-JQ2VU73H.mjs.gz +0 -0
- package/dist/Bar3DChartScene-5HC7LYBH.mjs.br +0 -0
- package/dist/Bar3DChartScene-5HC7LYBH.mjs.gz +0 -0
- package/dist/Bar3DChartScene-JV3A2P6O.js.br +0 -0
- package/dist/Bar3DChartScene-JV3A2P6O.js.gz +0 -0
- package/dist/Line3DChartScene-4ZAOOU7U.mjs.br +0 -0
- package/dist/Line3DChartScene-4ZAOOU7U.mjs.gz +0 -0
- package/dist/Line3DChartScene-7SN7TVKQ.js.br +0 -0
- package/dist/Line3DChartScene-7SN7TVKQ.js.gz +0 -0
- package/dist/Model3DScene-GQANXXQD.js.br +0 -0
- package/dist/Model3DScene-GQANXXQD.js.gz +0 -0
- package/dist/Model3DScene-GWIBUQ2U.mjs.br +0 -0
- package/dist/Model3DScene-GWIBUQ2U.mjs.gz +0 -0
- package/dist/PieChart3DScene-QPFDRMEA.js.br +0 -0
- package/dist/PieChart3DScene-QPFDRMEA.js.gz +0 -0
- package/dist/PieChart3DScene-RDTOLFTD.mjs.br +0 -0
- package/dist/PieChart3DScene-RDTOLFTD.mjs.gz +0 -0
- package/dist/SurfaceChart3DScene-5JQCRWA5.mjs.br +0 -0
- package/dist/SurfaceChart3DScene-5JQCRWA5.mjs.gz +0 -0
- package/dist/SurfaceChart3DScene-JLYGC7QU.js.br +0 -0
- package/dist/SurfaceChart3DScene-JLYGC7QU.js.gz +0 -0
- package/dist/chunk-G2Z7QULX.js.br +0 -0
- package/dist/chunk-G2Z7QULX.js.gz +0 -0
- package/dist/chunk-H3GHGSGW.js.br +0 -0
- package/dist/chunk-H3GHGSGW.js.gz +0 -0
- package/dist/chunk-HB7DJENT.mjs.br +0 -0
- package/dist/chunk-IVCYND7A.js.br +0 -0
- package/dist/chunk-IVCYND7A.js.gz +0 -0
- package/dist/chunk-M7SNS3DQ.mjs.br +0 -0
- package/dist/chunk-M7SNS3DQ.mjs.gz +0 -0
- package/dist/chunk-PKHTTHA2.mjs.br +0 -0
- package/dist/chunk-PKHTTHA2.mjs.gz +0 -0
- package/dist/chunk-TS2DHMBS.mjs.br +0 -0
- package/dist/chunk-TS2DHMBS.mjs.gz +0 -0
- package/dist/chunk-TWUAZRCG.js.br +0 -0
- package/dist/chunk-TWUAZRCG.js.gz +0 -0
- package/dist/chunk-UGVPKJSU.js.br +0 -0
- package/dist/chunk-UGVPKJSU.js.gz +0 -0
- package/dist/chunk-Y3SA5H5H.mjs.br +0 -0
- package/dist/chunk-Y3SA5H5H.mjs.gz +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunkH4LMXJ2Z_js = require('./chunk-H4LMXJ2Z.js');
|
|
4
|
+
var chunkMH4VFSDL_js = require('./chunk-MH4VFSDL.js');
|
|
5
5
|
var chunk3AJ54EAB_js = require('./chunk-3AJ54EAB.js');
|
|
6
6
|
var react = require('react');
|
|
7
7
|
var reactI18next = require('react-i18next');
|
|
@@ -9,7 +9,7 @@ var reactI18next = require('react-i18next');
|
|
|
9
9
|
function useVirtualizedSlides({
|
|
10
10
|
totalItems,
|
|
11
11
|
itemHeight,
|
|
12
|
-
overscan =
|
|
12
|
+
overscan = chunkMH4VFSDL_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 =
|
|
42
|
+
const range = chunkMH4VFSDL_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 ??=
|
|
83
|
+
projectorRef.current ??= chunkMH4VFSDL_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 >=
|
|
108
|
+
if (elapsed >= chunkMH4VFSDL_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
|
-
},
|
|
118
|
+
}, chunkMH4VFSDL_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 =
|
|
198
|
+
gateRef.current = chunkMH4VFSDL_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
|
-
|
|
218
|
+
chunkMH4VFSDL_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 =
|
|
243
|
+
const roomId = chunkMH4VFSDL_js.validateRoomId(config.roomId);
|
|
244
244
|
const provider = new WebrtcProvider(roomId, yDoc, opts);
|
|
245
|
-
departureRef.current =
|
|
245
|
+
departureRef.current = chunkMH4VFSDL_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 =
|
|
288
|
-
const transport = config.transport ??
|
|
287
|
+
const roomId = chunkMH4VFSDL_js.validateRoomId(config.roomId);
|
|
288
|
+
const transport = config.transport ?? chunkMH4VFSDL_js.resolveTransportForServerUrl(config.serverUrl);
|
|
289
289
|
if (transport === "webrtc") {
|
|
290
290
|
await initWebrtc();
|
|
291
291
|
return;
|
|
292
292
|
}
|
|
293
|
-
if (
|
|
293
|
+
if (chunkMH4VFSDL_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 =
|
|
307
|
+
departureRef.current = chunkMH4VFSDL_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
|
-
|
|
347
|
+
chunkMH4VFSDL_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
|
-
},
|
|
356
|
+
}, chunkMH4VFSDL_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
|
-
|
|
365
|
+
chunkMH4VFSDL_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 =
|
|
391
|
+
const disposeTeardown = chunkMH4VFSDL_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 =
|
|
412
|
+
const userColor = chunkMH4VFSDL_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(
|
|
531
|
-
templateElementsBySlideId:
|
|
530
|
+
slides: slides.map(chunkMH4VFSDL_js.cloneSlide),
|
|
531
|
+
templateElementsBySlideId: chunkMH4VFSDL_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(
|
|
544
|
+
setSlides(snapshot.slides.map(chunkMH4VFSDL_js.cloneSlide));
|
|
545
545
|
setTemplateElementsBySlideId(
|
|
546
|
-
|
|
546
|
+
chunkMH4VFSDL_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 =
|
|
586
|
-
lastHistorySnapshotRef.current =
|
|
585
|
+
const nextSnapshot = chunkH4LMXJ2Z_js.cloneHistorySnapshot(previousSnapshot);
|
|
586
|
+
lastHistorySnapshotRef.current = chunkH4LMXJ2Z_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 =
|
|
608
|
-
lastHistorySnapshotRef.current =
|
|
607
|
+
const targetSnapshot = chunkH4LMXJ2Z_js.cloneHistorySnapshot(nextSnapshot);
|
|
608
|
+
lastHistorySnapshotRef.current = chunkH4LMXJ2Z_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 =
|
|
626
|
+
const clonedInitial = chunkH4LMXJ2Z_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 =
|
|
674
|
+
lastHistorySnapshotRef.current = chunkH4LMXJ2Z_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(
|
|
681
|
+
historyPastRef.current.push(chunkH4LMXJ2Z_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 =
|
|
686
|
+
lastHistorySnapshotRef.current = chunkH4LMXJ2Z_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(
|
|
746
|
+
const wheelBufferRef = react.useRef(chunkMH4VFSDL_js.createWheelStepBuffer());
|
|
747
747
|
const storeRef = react.useRef(null);
|
|
748
|
-
storeRef.current ??=
|
|
748
|
+
storeRef.current ??= chunkMH4VFSDL_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 =
|
|
809
|
+
const boundedScale = chunkMH4VFSDL_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,
|
|
847
|
-
maxY = Math.max(maxY, element.y + Math.max(element.height,
|
|
846
|
+
maxX = Math.max(maxX, element.x + Math.max(element.width, chunkH4LMXJ2Z_js.MIN_ELEMENT_SIZE));
|
|
847
|
+
maxY = Math.max(maxY, element.y + Math.max(element.height, chunkH4LMXJ2Z_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,
|
|
854
|
-
const boundsHeight = Math.max(selectionBounds.maxY - selectionBounds.minY,
|
|
853
|
+
const boundsWidth = Math.max(selectionBounds.maxX - selectionBounds.minX, chunkH4LMXJ2Z_js.MIN_ELEMENT_SIZE);
|
|
854
|
+
const boundsHeight = Math.max(selectionBounds.maxY - selectionBounds.minY, chunkH4LMXJ2Z_js.MIN_ELEMENT_SIZE);
|
|
855
855
|
const availableWidth = Math.max(
|
|
856
|
-
effectiveEditorDimensions.width -
|
|
857
|
-
|
|
856
|
+
effectiveEditorDimensions.width - chunkH4LMXJ2Z_js.ZOOM_TO_SELECTION_PADDING,
|
|
857
|
+
chunkH4LMXJ2Z_js.MIN_ELEMENT_SIZE
|
|
858
858
|
);
|
|
859
859
|
const availableHeight = Math.max(
|
|
860
|
-
effectiveEditorDimensions.height -
|
|
861
|
-
|
|
860
|
+
effectiveEditorDimensions.height - chunkH4LMXJ2Z_js.ZOOM_TO_SELECTION_PADDING,
|
|
861
|
+
chunkH4LMXJ2Z_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 =
|
|
868
|
+
const nextScale = chunkMH4VFSDL_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 =
|
|
885
|
+
const mapped = chunkMH4VFSDL_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:
|
|
892
|
+
zoom: chunkMH4VFSDL_js.clampZoomScale(store.getState().zoom + mapped.deltaScale)
|
|
893
893
|
});
|
|
894
894
|
},
|
|
895
895
|
[store]
|
|
@@ -984,8 +984,8 @@ function scheduleOpeningAutoPlayGroup(controller, ctx) {
|
|
|
984
984
|
if (!group) {
|
|
985
985
|
return;
|
|
986
986
|
}
|
|
987
|
-
|
|
988
|
-
|
|
987
|
+
chunkMH4VFSDL_js.playGroup(controller, group, ctx);
|
|
988
|
+
chunkMH4VFSDL_js.scheduleAutoAdvanceChain(controller, ctx);
|
|
989
989
|
}, firstGroup.autoAdvanceDelayMs ?? 0);
|
|
990
990
|
ctx.timers.push(timer);
|
|
991
991
|
}
|
|
@@ -1004,7 +1004,7 @@ function scheduleEntranceAnimationTimers(slide, setPresentationAnimations, prese
|
|
|
1004
1004
|
}))
|
|
1005
1005
|
);
|
|
1006
1006
|
entranceAnimations.forEach((animation, animationIndex) => {
|
|
1007
|
-
const delay =
|
|
1007
|
+
const delay = chunkMH4VFSDL_js.computeEntranceAnimationDelay(animation.delayMs, animationIndex);
|
|
1008
1008
|
const timer = window.setTimeout(() => {
|
|
1009
1009
|
setPresentationAnimations(
|
|
1010
1010
|
(previousAnimations) => previousAnimations.map(
|
|
@@ -1037,7 +1037,7 @@ function useAnimationPlayback(input) {
|
|
|
1037
1037
|
const presentationTimersRef = react.useRef([]);
|
|
1038
1038
|
const controllerRef = react.useRef(null);
|
|
1039
1039
|
const buildRafRef = react.useRef(null);
|
|
1040
|
-
const activeAnimationGroupRef = react.useRef(
|
|
1040
|
+
const activeAnimationGroupRef = react.useRef(chunkMH4VFSDL_js.createActiveAnimationGroup());
|
|
1041
1041
|
const seededCompletedRef = react.useRef(false);
|
|
1042
1042
|
const mediaTimeNodeElementIdsRef = react.useRef(/* @__PURE__ */ new Map());
|
|
1043
1043
|
const lastSeedCompletedRef = react.useRef(false);
|
|
@@ -1054,15 +1054,15 @@ function useAnimationPlayback(input) {
|
|
|
1054
1054
|
}, [onPlayActionSound]);
|
|
1055
1055
|
react.useEffect(() => {
|
|
1056
1056
|
return () => {
|
|
1057
|
-
|
|
1057
|
+
chunkMH4VFSDL_js.cancelBuildReveal(buildRafRef);
|
|
1058
1058
|
};
|
|
1059
1059
|
}, []);
|
|
1060
1060
|
const clearPresentationTimers = react.useCallback(() => {
|
|
1061
|
-
|
|
1061
|
+
chunkMH4VFSDL_js.clearPlaybackTimers(buildPlaybackContext(), activeAnimationGroupRef.current);
|
|
1062
1062
|
}, [buildPlaybackContext]);
|
|
1063
1063
|
const resetSlideTimeline = react.useCallback(
|
|
1064
1064
|
(slideIndex) => {
|
|
1065
|
-
|
|
1065
|
+
chunkMH4VFSDL_js.cancelBuildReveal(buildRafRef);
|
|
1066
1066
|
const slide = slides[slideIndex];
|
|
1067
1067
|
if (!slide) {
|
|
1068
1068
|
controllerRef.current = null;
|
|
@@ -1073,14 +1073,14 @@ function useAnimationPlayback(input) {
|
|
|
1073
1073
|
setHoverTriggerShapeIds(/* @__PURE__ */ new Set());
|
|
1074
1074
|
return;
|
|
1075
1075
|
}
|
|
1076
|
-
const controller =
|
|
1076
|
+
const controller = chunkMH4VFSDL_js.PresentationAnimationController.fromSlide(slide, {
|
|
1077
1077
|
slideHeightPx: canvasSize?.height,
|
|
1078
1078
|
slideWidthPx: canvasSize?.width,
|
|
1079
1079
|
themeColorMap,
|
|
1080
1080
|
pixelateMosaic: pixelateMosaicAnimation
|
|
1081
1081
|
});
|
|
1082
1082
|
controllerRef.current = controller;
|
|
1083
|
-
mediaTimeNodeElementIdsRef.current =
|
|
1083
|
+
mediaTimeNodeElementIdsRef.current = chunkMH4VFSDL_js.resolveMediaTimeNodeElementIds(
|
|
1084
1084
|
slide.nativeAnimations ?? []
|
|
1085
1085
|
);
|
|
1086
1086
|
setPresentationKeyframesCss(controller.keyframesCss);
|
|
@@ -1094,7 +1094,7 @@ function useAnimationPlayback(input) {
|
|
|
1094
1094
|
if (!animationsEnabled) {
|
|
1095
1095
|
return false;
|
|
1096
1096
|
}
|
|
1097
|
-
return
|
|
1097
|
+
return chunkMH4VFSDL_js.advanceMainSequence(
|
|
1098
1098
|
controllerRef.current,
|
|
1099
1099
|
buildPlaybackContext(),
|
|
1100
1100
|
activeAnimationGroupRef.current
|
|
@@ -1110,7 +1110,7 @@ function useAnimationPlayback(input) {
|
|
|
1110
1110
|
if (!group) {
|
|
1111
1111
|
return false;
|
|
1112
1112
|
}
|
|
1113
|
-
|
|
1113
|
+
chunkMH4VFSDL_js.playGroup(controller, group, buildPlaybackContext());
|
|
1114
1114
|
return true;
|
|
1115
1115
|
},
|
|
1116
1116
|
[buildPlaybackContext]
|
|
@@ -1129,7 +1129,7 @@ function useAnimationPlayback(input) {
|
|
|
1129
1129
|
if (!group) {
|
|
1130
1130
|
return false;
|
|
1131
1131
|
}
|
|
1132
|
-
|
|
1132
|
+
chunkMH4VFSDL_js.playGroup(controller, group, buildPlaybackContext());
|
|
1133
1133
|
return true;
|
|
1134
1134
|
},
|
|
1135
1135
|
[animationsEnabled, buildPlaybackContext]
|
|
@@ -1210,12 +1210,12 @@ function useAnimationPlayback(input) {
|
|
|
1210
1210
|
presentationTimersRef
|
|
1211
1211
|
};
|
|
1212
1212
|
}
|
|
1213
|
-
var PRESENTER_CHANNEL_NAME =
|
|
1214
|
-
var AUDIENCE_HASH =
|
|
1215
|
-
var PRESENTER_MSG_ORIGIN =
|
|
1216
|
-
var AUDIENCE_NONCE_KEY =
|
|
1213
|
+
var PRESENTER_CHANNEL_NAME = chunkMH4VFSDL_js.PRESENTATION_CHANNEL_NAME;
|
|
1214
|
+
var AUDIENCE_HASH = chunkMH4VFSDL_js.PRESENTATION_HASH;
|
|
1215
|
+
var PRESENTER_MSG_ORIGIN = chunkMH4VFSDL_js.PRESENTATION_MESSAGE_ORIGIN;
|
|
1216
|
+
var AUDIENCE_NONCE_KEY = chunkMH4VFSDL_js.PRESENTATION_NONCE_KEY;
|
|
1217
1217
|
function generateSessionId() {
|
|
1218
|
-
return
|
|
1218
|
+
return chunkMH4VFSDL_js.createPresentationSessionId();
|
|
1219
1219
|
}
|
|
1220
1220
|
function parseAudienceNonce() {
|
|
1221
1221
|
const hash = window.location.hash;
|
|
@@ -1251,7 +1251,7 @@ function usePresenterWindow(input) {
|
|
|
1251
1251
|
}, []);
|
|
1252
1252
|
const swapDisplays = react.useCallback(async () => {
|
|
1253
1253
|
const audience = audienceWindowRef.current;
|
|
1254
|
-
return audience && !audience.closed ?
|
|
1254
|
+
return audience && !audience.closed ? chunkMH4VFSDL_js.swapPresentationWindows(window, audience) : false;
|
|
1255
1255
|
}, []);
|
|
1256
1256
|
const syncSlideToAudience = react.useCallback(
|
|
1257
1257
|
(slideIndex) => {
|
|
@@ -1315,7 +1315,7 @@ function usePresenterWindow(input) {
|
|
|
1315
1315
|
pollTimerRef.current = null;
|
|
1316
1316
|
}
|
|
1317
1317
|
if (closingSessionId) {
|
|
1318
|
-
void
|
|
1318
|
+
void chunkMH4VFSDL_js.clearAudienceContent(closingSessionId);
|
|
1319
1319
|
}
|
|
1320
1320
|
}, [getChannel]);
|
|
1321
1321
|
const openAudienceWindow = react.useCallback(() => {
|
|
@@ -1333,10 +1333,10 @@ function usePresenterWindow(input) {
|
|
|
1333
1333
|
audienceWindowRef.current = blankWin;
|
|
1334
1334
|
const sessionId = generateSessionId();
|
|
1335
1335
|
sessionIdRef.current = sessionId;
|
|
1336
|
-
const audienceUrl =
|
|
1337
|
-
void
|
|
1336
|
+
const audienceUrl = chunkMH4VFSDL_js.buildPresentationAudienceUrl(window.location.href, sessionId);
|
|
1337
|
+
void chunkMH4VFSDL_js.resolveAudienceScreenPlacement(window).then((placement) => {
|
|
1338
1338
|
if (placement && audienceWindowRef.current === blankWin && !blankWin.closed) {
|
|
1339
|
-
|
|
1339
|
+
chunkMH4VFSDL_js.placeAudienceWindow(blankWin, placement);
|
|
1340
1340
|
}
|
|
1341
1341
|
return void 0;
|
|
1342
1342
|
});
|
|
@@ -1366,7 +1366,7 @@ function usePresenterWindow(input) {
|
|
|
1366
1366
|
}
|
|
1367
1367
|
};
|
|
1368
1368
|
if (content) {
|
|
1369
|
-
void
|
|
1369
|
+
void chunkMH4VFSDL_js.storeAudienceContent(content, sessionId).then(() => navigateOrClose(true)).catch(() => navigateOrClose(false));
|
|
1370
1370
|
} else {
|
|
1371
1371
|
navigateOrClose(true);
|
|
1372
1372
|
}
|
|
@@ -1392,7 +1392,7 @@ function usePresenterWindow(input) {
|
|
|
1392
1392
|
}
|
|
1393
1393
|
const handleMessage = (event) => {
|
|
1394
1394
|
const message = event.data;
|
|
1395
|
-
if (
|
|
1395
|
+
if (chunkMH4VFSDL_js.isPresentationSessionMessage(message) && message.type === "audience-ready" && message.sessionId === sessionIdRef.current) {
|
|
1396
1396
|
syncStateToAudience(snapshotRef.current);
|
|
1397
1397
|
}
|
|
1398
1398
|
};
|
|
@@ -1421,7 +1421,7 @@ function usePresenterWindow(input) {
|
|
|
1421
1421
|
react.useEffect(() => {
|
|
1422
1422
|
const handleBeforeUnload = () => {
|
|
1423
1423
|
if (sessionIdRef.current) {
|
|
1424
|
-
void
|
|
1424
|
+
void chunkMH4VFSDL_js.clearAudienceContent(sessionIdRef.current);
|
|
1425
1425
|
}
|
|
1426
1426
|
};
|
|
1427
1427
|
window.addEventListener("beforeunload", handleBeforeUnload);
|
|
@@ -1483,7 +1483,7 @@ function useAudienceMode(input) {
|
|
|
1483
1483
|
}
|
|
1484
1484
|
channel.onmessage = (event) => {
|
|
1485
1485
|
const data = event.data;
|
|
1486
|
-
if (!
|
|
1486
|
+
if (!chunkMH4VFSDL_js.isPresentationSessionMessage(data) || data.origin !== PRESENTER_MSG_ORIGIN) {
|
|
1487
1487
|
return;
|
|
1488
1488
|
}
|
|
1489
1489
|
if (expectedSessionId && data.sessionId !== expectedSessionId) {
|
|
@@ -1499,16 +1499,16 @@ function useAudienceMode(input) {
|
|
|
1499
1499
|
}
|
|
1500
1500
|
if (data.type === "presenter-exit") {
|
|
1501
1501
|
if (expectedSessionId) {
|
|
1502
|
-
void
|
|
1502
|
+
void chunkMH4VFSDL_js.clearAudienceContent(expectedSessionId);
|
|
1503
1503
|
}
|
|
1504
|
-
if (
|
|
1504
|
+
if (chunkMH4VFSDL_js.endAudienceDisplay(window)) {
|
|
1505
1505
|
handlers.onPresenterEnded?.();
|
|
1506
1506
|
}
|
|
1507
1507
|
}
|
|
1508
1508
|
};
|
|
1509
1509
|
if (expectedSessionId) {
|
|
1510
1510
|
channel.postMessage({
|
|
1511
|
-
origin:
|
|
1511
|
+
origin: chunkMH4VFSDL_js.PRESENTATION_MESSAGE_ORIGIN,
|
|
1512
1512
|
type: "audience-ready",
|
|
1513
1513
|
sessionId: expectedSessionId
|
|
1514
1514
|
});
|
|
@@ -1522,7 +1522,7 @@ function useAudienceMode(input) {
|
|
|
1522
1522
|
}, []);
|
|
1523
1523
|
}
|
|
1524
1524
|
function usePresentationKeyboard(input) {
|
|
1525
|
-
const wheelBufferRef = react.useRef(
|
|
1525
|
+
const wheelBufferRef = react.useRef(chunkMH4VFSDL_js.createWheelStepBuffer());
|
|
1526
1526
|
const {
|
|
1527
1527
|
mode,
|
|
1528
1528
|
movePresentationSlide,
|
|
@@ -1543,14 +1543,14 @@ function usePresentationKeyboard(input) {
|
|
|
1543
1543
|
presentationSlideIndex,
|
|
1544
1544
|
setShowRehearsalSummary
|
|
1545
1545
|
} = input;
|
|
1546
|
-
const keyBufferRef = react.useRef(
|
|
1546
|
+
const keyBufferRef = react.useRef(chunkMH4VFSDL_js.createPresentationKeyBuffer());
|
|
1547
1547
|
react.useEffect(() => {
|
|
1548
|
-
if (mode !== "present" || !
|
|
1549
|
-
keyBufferRef.current =
|
|
1548
|
+
if (mode !== "present" || !chunkMH4VFSDL_js.acceptsPresentationInput()) {
|
|
1549
|
+
keyBufferRef.current = chunkMH4VFSDL_js.createPresentationKeyBuffer();
|
|
1550
1550
|
return;
|
|
1551
1551
|
}
|
|
1552
1552
|
const handleKeyDown = (event) => {
|
|
1553
|
-
const mapped =
|
|
1553
|
+
const mapped = chunkMH4VFSDL_js.mapPresentationKey(event, keyBufferRef.current);
|
|
1554
1554
|
if (mapped.action === "none") {
|
|
1555
1555
|
return;
|
|
1556
1556
|
}
|
|
@@ -1570,12 +1570,12 @@ function usePresentationKeyboard(input) {
|
|
|
1570
1570
|
movePresentationSlide(-1);
|
|
1571
1571
|
return;
|
|
1572
1572
|
case "first": {
|
|
1573
|
-
const first =
|
|
1573
|
+
const first = chunkMH4VFSDL_js.firstShowSlideIndex(showSlideIndexes);
|
|
1574
1574
|
navigateToSlide(first ?? 0);
|
|
1575
1575
|
return;
|
|
1576
1576
|
}
|
|
1577
1577
|
case "last": {
|
|
1578
|
-
const last =
|
|
1578
|
+
const last = chunkMH4VFSDL_js.lastShowSlideIndex(showSlideIndexes);
|
|
1579
1579
|
navigateToSlide(last ?? Math.max(0, slideCount - 1));
|
|
1580
1580
|
return;
|
|
1581
1581
|
}
|
|
@@ -1613,10 +1613,10 @@ function usePresentationKeyboard(input) {
|
|
|
1613
1613
|
}
|
|
1614
1614
|
};
|
|
1615
1615
|
const handleWheel = (event) => {
|
|
1616
|
-
if (mode !== "present" || !
|
|
1616
|
+
if (mode !== "present" || !chunkMH4VFSDL_js.acceptsPresentationInput()) {
|
|
1617
1617
|
return;
|
|
1618
1618
|
}
|
|
1619
|
-
const mapped =
|
|
1619
|
+
const mapped = chunkMH4VFSDL_js.mapPresentationWheel(event, wheelBufferRef.current);
|
|
1620
1620
|
if (mapped.intent === "next-slide") {
|
|
1621
1621
|
event.preventDefault();
|
|
1622
1622
|
movePresentationSlide(1);
|
|
@@ -1749,7 +1749,7 @@ function useRehearsalTimings(input) {
|
|
|
1749
1749
|
|
|
1750
1750
|
// src/viewer/hooks/presentation-mode/presentation-actions.ts
|
|
1751
1751
|
function handlePresentationActionImpl(action, deps) {
|
|
1752
|
-
|
|
1752
|
+
chunkMH4VFSDL_js.runPresentationAction(
|
|
1753
1753
|
action,
|
|
1754
1754
|
{ slideCount: deps.slidesLength, ...deps.elementId ? { elementId: deps.elementId } : {} },
|
|
1755
1755
|
{
|
|
@@ -1778,13 +1778,13 @@ function handlePresentationActionImpl(action, deps) {
|
|
|
1778
1778
|
function executeSlideTransition(nextSlideIndex, deps) {
|
|
1779
1779
|
const incomingSlide = deps.slides[nextSlideIndex];
|
|
1780
1780
|
const transition = deps.reverse ? deps.slides[deps.currentSlideIndex]?.transition : incomingSlide?.transition;
|
|
1781
|
-
const durationMs = deps.playTransition ?
|
|
1781
|
+
const durationMs = deps.playTransition ? chunkMH4VFSDL_js.resolveTransitionDurationMs(transition) : 0;
|
|
1782
1782
|
deps.clearPresentationTimers();
|
|
1783
1783
|
deps.setPresentationSlideIndex(nextSlideIndex);
|
|
1784
1784
|
deps.onSetActiveSlideIndex(nextSlideIndex);
|
|
1785
1785
|
deps.setPresentationSlideVisible(true);
|
|
1786
1786
|
deps.seedSlideAnimations(nextSlideIndex, { completed: deps.seedCompleted });
|
|
1787
|
-
const soundAction =
|
|
1787
|
+
const soundAction = chunkMH4VFSDL_js.resolveTransitionSoundAction(transition);
|
|
1788
1788
|
if (soundAction.kind === "play" && deps.onPlayActionSound) {
|
|
1789
1789
|
deps.onPlayActionSound(soundAction.soundPath, { loop: soundAction.loop });
|
|
1790
1790
|
} else if (soundAction.kind === "stop" && deps.onStopActionSound) {
|
|
@@ -1848,7 +1848,7 @@ function useSlideNavigation(input) {
|
|
|
1848
1848
|
});
|
|
1849
1849
|
const scheduleAutoAdvanceForSlide = react.useCallback(
|
|
1850
1850
|
(slideIndex) => {
|
|
1851
|
-
const delayMs =
|
|
1851
|
+
const delayMs = chunkMH4VFSDL_js.resolveAutoAdvanceDelayMs(slides[slideIndex], { useTimings });
|
|
1852
1852
|
if (delayMs === void 0) {
|
|
1853
1853
|
return;
|
|
1854
1854
|
}
|
|
@@ -1871,7 +1871,7 @@ function useSlideNavigation(input) {
|
|
|
1871
1871
|
if (availableSlideIndexes.length === 0) {
|
|
1872
1872
|
return;
|
|
1873
1873
|
}
|
|
1874
|
-
const pastLastSlide = direction === 1 && !
|
|
1874
|
+
const pastLastSlide = direction === 1 && !chunkMH4VFSDL_js.hasShowSlideAfter(presentationSlideIndex, availableSlideIndexes);
|
|
1875
1875
|
if (rehearsing && pastLastSlide) {
|
|
1876
1876
|
recordCurrentSlideTime(presentationSlideIndex);
|
|
1877
1877
|
try {
|
|
@@ -1889,9 +1889,9 @@ function useSlideNavigation(input) {
|
|
|
1889
1889
|
onAdvancePastLastSlide();
|
|
1890
1890
|
return;
|
|
1891
1891
|
}
|
|
1892
|
-
const nextSlideIndex = direction === 1 ?
|
|
1892
|
+
const nextSlideIndex = direction === 1 ? chunkMH4VFSDL_js.nextShowSlideIndex(presentationSlideIndex, availableSlideIndexes, {
|
|
1893
1893
|
loop: Boolean(loopContinuously) && !rehearsing
|
|
1894
|
-
}) :
|
|
1894
|
+
}) : chunkMH4VFSDL_js.previousShowSlideIndex(presentationSlideIndex, availableSlideIndexes);
|
|
1895
1895
|
if (nextSlideIndex === void 0 || nextSlideIndex === presentationSlideIndex) {
|
|
1896
1896
|
return;
|
|
1897
1897
|
}
|
|
@@ -2072,7 +2072,7 @@ function createCustomShowRunner(deps) {
|
|
|
2072
2072
|
return;
|
|
2073
2073
|
}
|
|
2074
2074
|
origin = returnAfter ? { showId: deps.getActiveCustomShowId(), slideIndex: deps.getPresentationSlideIndex() } : null;
|
|
2075
|
-
const first =
|
|
2075
|
+
const first = chunkMH4VFSDL_js.firstShowSlideIndex(chunkMH4VFSDL_js.resolveShowSlideIndexes(deps.getSlides(), target));
|
|
2076
2076
|
deps.setActiveCustomShowId(customShowId);
|
|
2077
2077
|
if (first !== void 0) {
|
|
2078
2078
|
deps.navigateToSlide(first);
|
|
@@ -2150,33 +2150,33 @@ function usePresentationActionExtensions(input) {
|
|
|
2150
2150
|
}
|
|
2151
2151
|
}, [navigateToSlideViaRef]);
|
|
2152
2152
|
const onOpenFile = react.useCallback((target) => {
|
|
2153
|
-
|
|
2153
|
+
chunkMH4VFSDL_js.safeOpenUrl(target);
|
|
2154
2154
|
}, []);
|
|
2155
2155
|
const onOpenPresentation = react.useCallback((target) => {
|
|
2156
|
-
|
|
2156
|
+
chunkMH4VFSDL_js.safeOpenUrl(target);
|
|
2157
2157
|
}, []);
|
|
2158
2158
|
const onRunProgram = react.useCallback(
|
|
2159
2159
|
(target) => {
|
|
2160
|
-
onAddRunProgramNotice?.(
|
|
2160
|
+
onAddRunProgramNotice?.(chunkMH4VFSDL_js.buildRunProgramNotice(target));
|
|
2161
2161
|
},
|
|
2162
2162
|
[onAddRunProgramNotice]
|
|
2163
2163
|
);
|
|
2164
2164
|
const onPlayMedia = react.useCallback(
|
|
2165
2165
|
(elementId) => {
|
|
2166
|
-
|
|
2166
|
+
chunkMH4VFSDL_js.toggleStageElementMedia(containerRef.current, elementId);
|
|
2167
2167
|
},
|
|
2168
2168
|
[containerRef]
|
|
2169
2169
|
);
|
|
2170
2170
|
const onOleVerb = react.useCallback(
|
|
2171
2171
|
(verb, elementId) => {
|
|
2172
|
-
const target =
|
|
2172
|
+
const target = chunkMH4VFSDL_js.resolveOleVerbTarget(slides[presentationSlideIndex], elementId, verb);
|
|
2173
2173
|
if (!target) {
|
|
2174
2174
|
return;
|
|
2175
2175
|
}
|
|
2176
2176
|
if (target.action === "download") {
|
|
2177
|
-
|
|
2177
|
+
chunkMH4VFSDL_js.downloadDataUrl(target.url, target.fileName ?? "download");
|
|
2178
2178
|
} else {
|
|
2179
|
-
|
|
2179
|
+
chunkMH4VFSDL_js.openUrlInNewTab(target.url);
|
|
2180
2180
|
}
|
|
2181
2181
|
},
|
|
2182
2182
|
[slides, presentationSlideIndex]
|
|
@@ -2207,22 +2207,22 @@ function usePresentationActionExtensions(input) {
|
|
|
2207
2207
|
};
|
|
2208
2208
|
}
|
|
2209
2209
|
function usePresenterConsole(slideIndex, active) {
|
|
2210
|
-
const timerRef = react.useRef(
|
|
2211
|
-
const [snapshot, setSnapshot] = react.useState(() =>
|
|
2210
|
+
const timerRef = react.useRef(chunkMH4VFSDL_js.createPresenterTimer());
|
|
2211
|
+
const [snapshot, setSnapshot] = react.useState(() => chunkMH4VFSDL_js.createInitialPresentationSnapshot(slideIndex));
|
|
2212
2212
|
const patch = react.useCallback((value) => {
|
|
2213
|
-
setSnapshot((current) =>
|
|
2213
|
+
setSnapshot((current) => chunkMH4VFSDL_js.mergePresentationSnapshot(current, value));
|
|
2214
2214
|
}, []);
|
|
2215
2215
|
react.useEffect(() => patch({ slideIndex }), [patch, slideIndex]);
|
|
2216
2216
|
react.useEffect(() => {
|
|
2217
2217
|
if (!active) {
|
|
2218
2218
|
return;
|
|
2219
2219
|
}
|
|
2220
|
-
timerRef.current =
|
|
2220
|
+
timerRef.current = chunkMH4VFSDL_js.resetPresenterTimer();
|
|
2221
2221
|
patch({ paused: false, elapsedMs: 0 });
|
|
2222
2222
|
const timer = window.setInterval(() => {
|
|
2223
2223
|
patch({
|
|
2224
2224
|
paused: timerRef.current.paused,
|
|
2225
|
-
elapsedMs:
|
|
2225
|
+
elapsedMs: chunkMH4VFSDL_js.presenterElapsed(timerRef.current)
|
|
2226
2226
|
});
|
|
2227
2227
|
}, 1e3);
|
|
2228
2228
|
return () => window.clearInterval(timer);
|
|
@@ -2232,19 +2232,19 @@ function usePresenterConsole(slideIndex, active) {
|
|
|
2232
2232
|
applyAudienceSnapshot: setSnapshot,
|
|
2233
2233
|
setBlackout: (blackout) => patch({ blackout }),
|
|
2234
2234
|
toggleTimer: () => {
|
|
2235
|
-
timerRef.current =
|
|
2235
|
+
timerRef.current = chunkMH4VFSDL_js.togglePresenterTimer(timerRef.current);
|
|
2236
2236
|
patch({
|
|
2237
2237
|
paused: timerRef.current.paused,
|
|
2238
|
-
elapsedMs:
|
|
2238
|
+
elapsedMs: chunkMH4VFSDL_js.presenterElapsed(timerRef.current)
|
|
2239
2239
|
});
|
|
2240
2240
|
},
|
|
2241
2241
|
resetTimer: () => {
|
|
2242
|
-
timerRef.current =
|
|
2242
|
+
timerRef.current = chunkMH4VFSDL_js.resetPresenterTimer();
|
|
2243
2243
|
patch({ paused: false, elapsedMs: 0 });
|
|
2244
2244
|
},
|
|
2245
2245
|
stepZoom: (direction) => setSnapshot(
|
|
2246
|
-
(current) =>
|
|
2247
|
-
zoom:
|
|
2246
|
+
(current) => chunkMH4VFSDL_js.mergePresentationSnapshot(current, {
|
|
2247
|
+
zoom: chunkMH4VFSDL_js.stepPresenterZoom(
|
|
2248
2248
|
current.zoom ?? { scale: 1, originX: 0.5, originY: 0.5 },
|
|
2249
2249
|
direction
|
|
2250
2250
|
)
|
|
@@ -2299,7 +2299,7 @@ function usePresentationMode(input) {
|
|
|
2299
2299
|
const [allSlidesOpen, setAllSlidesOpen] = react.useState(false);
|
|
2300
2300
|
const [endOfShowVisible, setEndOfShowVisible] = react.useState(false);
|
|
2301
2301
|
const [presentationStartTime, setPresentationStartTime] = react.useState(null);
|
|
2302
|
-
const showGuard = react.useMemo(() =>
|
|
2302
|
+
const showGuard = react.useMemo(() => chunkMH4VFSDL_js.createPresenterShowGuard(), []);
|
|
2303
2303
|
const {
|
|
2304
2304
|
presentationAnimations,
|
|
2305
2305
|
presentationElementStates,
|
|
@@ -2399,7 +2399,7 @@ function usePresentationMode(input) {
|
|
|
2399
2399
|
actionExtensions.bindNavigateToSlide(navigateToSlide);
|
|
2400
2400
|
const movePresentationSlide = react.useCallback(
|
|
2401
2401
|
(direction, trigger = "explicit") => {
|
|
2402
|
-
if (!
|
|
2402
|
+
if (!chunkMH4VFSDL_js.acceptsPresentationInput()) {
|
|
2403
2403
|
return;
|
|
2404
2404
|
}
|
|
2405
2405
|
if (endOfShowVisible) {
|
|
@@ -2468,7 +2468,7 @@ function usePresentationMode(input) {
|
|
|
2468
2468
|
onSetMode("present");
|
|
2469
2469
|
}, [containerRef, onSetMode, setRehearsing]);
|
|
2470
2470
|
const enterPresentModeFromBeginning = react.useCallback(() => {
|
|
2471
|
-
const first =
|
|
2471
|
+
const first = chunkMH4VFSDL_js.firstShowSlideIndex(visibleSlideIndexes);
|
|
2472
2472
|
if (first !== void 0) {
|
|
2473
2473
|
onSetActiveSlideIndex(first);
|
|
2474
2474
|
}
|
|
@@ -2548,7 +2548,7 @@ function usePresentationMode(input) {
|
|
|
2548
2548
|
if (mode !== "present") {
|
|
2549
2549
|
return;
|
|
2550
2550
|
}
|
|
2551
|
-
return
|
|
2551
|
+
return chunkMH4VFSDL_js.attachPresentationVisibilityPause({
|
|
2552
2552
|
root: containerRef.current ?? void 0,
|
|
2553
2553
|
onHidden: () => clearPresentationTimersRef.current(),
|
|
2554
2554
|
onVisible: () => scheduleAutoAdvanceRef.current(presentationSlideIndexRef.current)
|
|
@@ -2556,7 +2556,7 @@ function usePresentationMode(input) {
|
|
|
2556
2556
|
}, [mode, containerRef]);
|
|
2557
2557
|
react.useLayoutEffect(() => {
|
|
2558
2558
|
if (mode === "present") {
|
|
2559
|
-
const idx =
|
|
2559
|
+
const idx = chunkMH4VFSDL_js.presentationEntrySlideIndex(
|
|
2560
2560
|
activeSlideIndexRef.current,
|
|
2561
2561
|
visibleSlideIndexesRef.current
|
|
2562
2562
|
);
|
|
@@ -2635,11 +2635,11 @@ function usePresentationMode(input) {
|
|
|
2635
2635
|
return void 0;
|
|
2636
2636
|
}
|
|
2637
2637
|
const incoming = slides[transitionOverlay.incomingSlideIndex];
|
|
2638
|
-
return
|
|
2638
|
+
return chunkMH4VFSDL_js.buildMorphTransitionPlan(
|
|
2639
2639
|
slides[transitionOverlay.outgoingSlideIndex],
|
|
2640
2640
|
incoming,
|
|
2641
2641
|
transitionOverlay.durationMs,
|
|
2642
|
-
|
|
2642
|
+
chunkMH4VFSDL_js.morphOptionToMode(transitionOverlay.transition.morphOption),
|
|
2643
2643
|
// `PresentationStage` stacks the incoming slide's elements above its
|
|
2644
2644
|
// template shapes (`zIndex = templateElements.length + index`), so a
|
|
2645
2645
|
// z-index journey has to start counting where the stage does.
|
|
@@ -2664,7 +2664,7 @@ function usePresentationMode(input) {
|
|
|
2664
2664
|
if (!morphPlan) {
|
|
2665
2665
|
return presentationKeyframesCss;
|
|
2666
2666
|
}
|
|
2667
|
-
const imageRules =
|
|
2667
|
+
const imageRules = chunkMH4VFSDL_js.buildMorphAnimationRules(morphPlan, "", "incoming", "image");
|
|
2668
2668
|
return `${presentationKeyframesCss ?? ""}
|
|
2669
2669
|
${morphPlan.keyframesCss}
|
|
2670
2670
|
${imageRules}`;
|
|
@@ -2961,7 +2961,7 @@ function useFindReplace({
|
|
|
2961
2961
|
const [findResults, setFindResults] = react.useState([]);
|
|
2962
2962
|
const [findResultIndex, setFindResultIndex] = react.useState(-1);
|
|
2963
2963
|
const performFind = react.useCallback(() => {
|
|
2964
|
-
const results =
|
|
2964
|
+
const results = chunkMH4VFSDL_js.findInSlides(slides, findQuery, { matchCase: findMatchCase });
|
|
2965
2965
|
if (!findQuery) {
|
|
2966
2966
|
setFindResults([]);
|
|
2967
2967
|
setFindResultIndex(-1);
|
|
@@ -2995,7 +2995,7 @@ function useFindReplace({
|
|
|
2995
2995
|
return;
|
|
2996
2996
|
}
|
|
2997
2997
|
onUpdateSlides(
|
|
2998
|
-
(prevSlides) =>
|
|
2998
|
+
(prevSlides) => chunkMH4VFSDL_js.applyFindReplacements(prevSlides, toReplace, replaceQuery).slides
|
|
2999
2999
|
);
|
|
3000
3000
|
onMarkDirty();
|
|
3001
3001
|
},
|
|
@@ -3017,9 +3017,9 @@ function useFindReplace({
|
|
|
3017
3017
|
}, [findResults, applyReplacements, performFind]);
|
|
3018
3018
|
react.useEffect(() => {
|
|
3019
3019
|
const handler = (event) => {
|
|
3020
|
-
const { action } =
|
|
3020
|
+
const { action } = chunkMH4VFSDL_js.mapEditorKey(event, {
|
|
3021
3021
|
canEdit: mode === "edit",
|
|
3022
|
-
isTextInputTarget:
|
|
3022
|
+
isTextInputTarget: chunkMH4VFSDL_js.isEditorTextInputTarget(event.target)
|
|
3023
3023
|
});
|
|
3024
3024
|
if (action !== "find") {
|
|
3025
3025
|
return;
|
|
@@ -3130,7 +3130,7 @@ function addCommentToSlide(slides, slideIndex, text, authorName, elementId, ment
|
|
|
3130
3130
|
if (!slide) {
|
|
3131
3131
|
return { slides, didAdd: false };
|
|
3132
3132
|
}
|
|
3133
|
-
const next =
|
|
3133
|
+
const next = chunkMH4VFSDL_js.addCommentToList(
|
|
3134
3134
|
slide.comments || [],
|
|
3135
3135
|
text,
|
|
3136
3136
|
authorName,
|
|
@@ -3151,7 +3151,7 @@ function removeCommentFromSlide(slides, slideIndex, commentId) {
|
|
|
3151
3151
|
if (!slide) {
|
|
3152
3152
|
return { slides, didDelete: false };
|
|
3153
3153
|
}
|
|
3154
|
-
const next =
|
|
3154
|
+
const next = chunkMH4VFSDL_js.removeCommentFromList(slide.comments || [], commentId);
|
|
3155
3155
|
if (!next) {
|
|
3156
3156
|
return { slides, didDelete: false };
|
|
3157
3157
|
}
|
|
@@ -3162,7 +3162,7 @@ function editCommentInSlide(slides, slideIndex, commentId, newText) {
|
|
|
3162
3162
|
if (!slide) {
|
|
3163
3163
|
return { slides, didUpdate: false };
|
|
3164
3164
|
}
|
|
3165
|
-
const next =
|
|
3165
|
+
const next = chunkMH4VFSDL_js.editCommentInList(slide.comments || [], commentId, newText);
|
|
3166
3166
|
if (!next) {
|
|
3167
3167
|
return { slides, didUpdate: false };
|
|
3168
3168
|
}
|
|
@@ -3173,7 +3173,7 @@ function toggleResolvedInSlide(slides, slideIndex, commentId) {
|
|
|
3173
3173
|
if (!slide) {
|
|
3174
3174
|
return { slides, didUpdate: false };
|
|
3175
3175
|
}
|
|
3176
|
-
const next =
|
|
3176
|
+
const next = chunkMH4VFSDL_js.toggleCommentResolvedInList(slide.comments || [], commentId);
|
|
3177
3177
|
if (!next) {
|
|
3178
3178
|
return { slides, didUpdate: false };
|
|
3179
3179
|
}
|
|
@@ -3184,7 +3184,7 @@ function addReplyToSlide(slides, slideIndex, parentId, text, authorName, mention
|
|
|
3184
3184
|
if (!slide) {
|
|
3185
3185
|
return { slides, didAdd: false };
|
|
3186
3186
|
}
|
|
3187
|
-
const next =
|
|
3187
|
+
const next = chunkMH4VFSDL_js.replyToCommentInList(slide.comments || [], parentId, text, authorName);
|
|
3188
3188
|
if (!next) {
|
|
3189
3189
|
return { slides, didAdd: false };
|
|
3190
3190
|
}
|
|
@@ -3571,7 +3571,7 @@ function useDerivedElementState(input) {
|
|
|
3571
3571
|
return [];
|
|
3572
3572
|
}
|
|
3573
3573
|
return [
|
|
3574
|
-
...
|
|
3574
|
+
...chunkMH4VFSDL_js.visibleTemplateElements(activeSlide, templateElementsBySlideId[activeSlide.id] ?? [])
|
|
3575
3575
|
];
|
|
3576
3576
|
}, [activeSlide, templateElementsBySlideId]);
|
|
3577
3577
|
const activeMaster = slideMasters[activeMasterIndex];
|
|
@@ -3638,7 +3638,7 @@ function useViewerCoreState(_input) {
|
|
|
3638
3638
|
const marqueeStateRef = react.useRef(null);
|
|
3639
3639
|
const isDrawingRef = react.useRef(false);
|
|
3640
3640
|
const justInteractedRef = react.useRef(false);
|
|
3641
|
-
const livePatcher = react.useMemo(() =>
|
|
3641
|
+
const livePatcher = react.useMemo(() => chunkMH4VFSDL_js.createCollaborationLivePatcher(), []);
|
|
3642
3642
|
react.useEffect(() => () => livePatcher.dispose(), [livePatcher]);
|
|
3643
3643
|
const slidesRef = react.useRef([]);
|
|
3644
3644
|
const [mode, setMode] = react.useState("edit");
|
|
@@ -3647,8 +3647,8 @@ function useViewerCoreState(_input) {
|
|
|
3647
3647
|
const [slides, setSlides] = react.useState([]);
|
|
3648
3648
|
const [templateElementsBySlideId, setTemplateElementsBySlideId] = react.useState({});
|
|
3649
3649
|
const [canvasSize, setCanvasSize] = react.useState({
|
|
3650
|
-
width:
|
|
3651
|
-
height:
|
|
3650
|
+
width: chunkH4LMXJ2Z_js.DEFAULT_CANVAS_WIDTH,
|
|
3651
|
+
height: chunkH4LMXJ2Z_js.DEFAULT_CANVAS_HEIGHT
|
|
3652
3652
|
});
|
|
3653
3653
|
const [slideSizeEmu, setSlideSizeEmu] = react.useState();
|
|
3654
3654
|
const [activeSlideIndex, setActiveSlideIndex] = react.useState(0);
|
|
@@ -3669,7 +3669,7 @@ function useViewerCoreState(_input) {
|
|
|
3669
3669
|
const resolved = typeof value === "function" ? value(inlineEditingTextRef.current) : value;
|
|
3670
3670
|
inlineEditingTextRef.current = resolved;
|
|
3671
3671
|
setInlineEditingTextBase(value);
|
|
3672
|
-
|
|
3672
|
+
chunkMH4VFSDL_js.publishLiveInlineText(
|
|
3673
3673
|
livePatcher,
|
|
3674
3674
|
slidesRef.current[activeSlideIndexRef.current],
|
|
3675
3675
|
inlineEditingElementIdRef.current,
|
|
@@ -3962,6 +3962,12 @@ function useViewerState(input) {
|
|
|
3962
3962
|
const ui = useViewerUIState();
|
|
3963
3963
|
return { ...core, ...ui };
|
|
3964
3964
|
}
|
|
3965
|
+
|
|
3966
|
+
// src/viewer/utils/glyph-outline-cache.ts
|
|
3967
|
+
var glyphOutlineFontCache = new chunkMH4VFSDL_js.GlyphOutlineFontCache();
|
|
3968
|
+
var getGlyphOutline = chunkMH4VFSDL_js.createGlyphOutlineLookup(glyphOutlineFontCache);
|
|
3969
|
+
|
|
3970
|
+
// src/viewer/hooks/useLoadContent.ts
|
|
3965
3971
|
function useLoadContent({
|
|
3966
3972
|
content,
|
|
3967
3973
|
clearSelection,
|
|
@@ -4032,7 +4038,7 @@ function useLoadContent({
|
|
|
4032
4038
|
);
|
|
4033
4039
|
}
|
|
4034
4040
|
const previousHandler = handlerRef.current;
|
|
4035
|
-
const handler = new
|
|
4041
|
+
const handler = new chunkMH4VFSDL_js.PptxHandler();
|
|
4036
4042
|
const parsed = await handler.load(buffer, { allowExternalImages });
|
|
4037
4043
|
if (cancelled || token !== renderTokenRef.current) {
|
|
4038
4044
|
handler.dispose();
|
|
@@ -4044,7 +4050,7 @@ function useLoadContent({
|
|
|
4044
4050
|
handlerRef.current = null;
|
|
4045
4051
|
const mediaElements = [];
|
|
4046
4052
|
for (const slide of parsed.slides) {
|
|
4047
|
-
|
|
4053
|
+
chunkMH4VFSDL_js.collectMediaElements(slide.elements, mediaElements);
|
|
4048
4054
|
}
|
|
4049
4055
|
for (const url of mediaDataUrls.values()) {
|
|
4050
4056
|
if (url.startsWith("blob:")) {
|
|
@@ -4054,7 +4060,7 @@ function useLoadContent({
|
|
|
4054
4060
|
mediaDataUrls.clear();
|
|
4055
4061
|
await Promise.all(
|
|
4056
4062
|
mediaElements.map(async (mediaElement) => {
|
|
4057
|
-
const resolved = await
|
|
4063
|
+
const resolved = await chunkMH4VFSDL_js.resolveMediaElementSource(mediaElement, handler);
|
|
4058
4064
|
if (resolved.missing || !resolved.mediaPath || !resolved.url) {
|
|
4059
4065
|
mediaElement.mediaMissing = true;
|
|
4060
4066
|
return;
|
|
@@ -4065,7 +4071,7 @@ function useLoadContent({
|
|
|
4065
4071
|
}
|
|
4066
4072
|
})
|
|
4067
4073
|
);
|
|
4068
|
-
const { paths: imagePaths, refs: imageRefs } =
|
|
4074
|
+
const { paths: imagePaths, refs: imageRefs } = chunkMH4VFSDL_js.collectImagePaths(parsed.slides);
|
|
4069
4075
|
let nextSlides = parsed.slides;
|
|
4070
4076
|
if (imagePaths.size > 0) {
|
|
4071
4077
|
const resolvedMap = /* @__PURE__ */ new Map();
|
|
@@ -4081,25 +4087,25 @@ function useLoadContent({
|
|
|
4081
4087
|
})
|
|
4082
4088
|
);
|
|
4083
4089
|
nextSlides = parsed.slides.map((s) => {
|
|
4084
|
-
const newElements =
|
|
4090
|
+
const newElements = chunkMH4VFSDL_js.applyImagePathPatches(s.elements, resolvedMap, imageRefs);
|
|
4085
4091
|
return newElements === s.elements ? s : { ...s, elements: newElements };
|
|
4086
4092
|
});
|
|
4087
4093
|
}
|
|
4088
|
-
nextSlides = await
|
|
4094
|
+
nextSlides = await chunkMH4VFSDL_js.resolveTableCellImageUrls(
|
|
4089
4095
|
nextSlides,
|
|
4090
4096
|
(path) => handler.getImageData(path)
|
|
4091
4097
|
);
|
|
4092
|
-
const nextTableStyleMap = await
|
|
4098
|
+
const nextTableStyleMap = await chunkMH4VFSDL_js.resolveTableStyleImageUrls(
|
|
4093
4099
|
parsed.tableStyleMap,
|
|
4094
4100
|
(path) => handler.getImageData(path)
|
|
4095
4101
|
);
|
|
4096
4102
|
handlerRef.current = handler;
|
|
4097
|
-
const partition =
|
|
4103
|
+
const partition = chunkMH4VFSDL_js.partitionTemplateElements(nextSlides);
|
|
4098
4104
|
setSlides(partition.slides);
|
|
4099
4105
|
setTemplateElementsBySlideId(partition.templateElementsBySlideId);
|
|
4100
4106
|
setCanvasSize({
|
|
4101
|
-
width: parsed.width ??
|
|
4102
|
-
height: parsed.height ??
|
|
4107
|
+
width: parsed.width ?? chunkH4LMXJ2Z_js.DEFAULT_CANVAS_WIDTH,
|
|
4108
|
+
height: parsed.height ?? chunkH4LMXJ2Z_js.DEFAULT_CANVAS_HEIGHT
|
|
4103
4109
|
});
|
|
4104
4110
|
setSlideSizeEmu(
|
|
4105
4111
|
typeof parsed.widthEmu === "number" && typeof parsed.heightEmu === "number" && parsed.widthEmu > 0 && parsed.heightEmu > 0 ? {
|
|
@@ -4112,7 +4118,7 @@ function useLoadContent({
|
|
|
4112
4118
|
setLayoutOptions(parsed.layoutOptions ?? []);
|
|
4113
4119
|
setSlideMasters(parsed.slideMasters ?? []);
|
|
4114
4120
|
setModernCommentAuthors(parsed.modernCommentAuthors ?? []);
|
|
4115
|
-
setRecentColors(
|
|
4121
|
+
setRecentColors(chunkMH4VFSDL_js.seedRecentColors({ mruColors: parsed.mruColors }));
|
|
4116
4122
|
setTheme(parsed.theme);
|
|
4117
4123
|
setTableStyleMap(nextTableStyleMap);
|
|
4118
4124
|
setTableStylesDefaultId(parsed.tableStylesDefaultId);
|
|
@@ -4120,7 +4126,7 @@ function useLoadContent({
|
|
|
4120
4126
|
setThemeOptions(parsed.themeOptions ?? []);
|
|
4121
4127
|
setCustomShows(parsed.customShows ?? []);
|
|
4122
4128
|
setActiveCustomShowId(
|
|
4123
|
-
|
|
4129
|
+
chunkMH4VFSDL_js.resolveAuthoredCustomShowId(parsed.presentationProperties, parsed.customShows) ?? null
|
|
4124
4130
|
);
|
|
4125
4131
|
setSections(parsed.sections ?? []);
|
|
4126
4132
|
setPresentationProperties(parsed.presentationProperties ?? {});
|
|
@@ -4140,14 +4146,15 @@ function useLoadContent({
|
|
|
4140
4146
|
setCoreProperties(parsed.coreProperties);
|
|
4141
4147
|
setAppProperties(parsed.appProperties);
|
|
4142
4148
|
setEmbeddedFonts(parsed.embeddedFonts ?? []);
|
|
4149
|
+
glyphOutlineFontCache.registerEmbeddedFonts(parsed.embeddedFonts ?? []);
|
|
4143
4150
|
setHasMacros(parsed.hasMacros === true);
|
|
4144
4151
|
setHasDigitalSignatures(parsed.hasDigitalSignatures === true);
|
|
4145
4152
|
setDigitalSignatureCount(parsed.digitalSignatureCount ?? 0);
|
|
4146
|
-
setGuides(
|
|
4147
|
-
setReadOnlyRecommendation(
|
|
4153
|
+
setGuides(chunkMH4VFSDL_js.buildInitialGuides(parsed.presentationGuides, parsed.slides[0]?.guides));
|
|
4154
|
+
setReadOnlyRecommendation(chunkMH4VFSDL_js.readOnlyRecommendation(parsed));
|
|
4148
4155
|
setModifyVerifier(parsed.modifyVerifier ?? void 0);
|
|
4149
4156
|
setCompatToasts(
|
|
4150
|
-
|
|
4157
|
+
chunkMH4VFSDL_js.compatibilityWarningToasts([
|
|
4151
4158
|
...parsed.warnings ?? [],
|
|
4152
4159
|
...parsed.slides.flatMap((slide) => slide.warnings ?? [])
|
|
4153
4160
|
])
|
|
@@ -4159,7 +4166,7 @@ function useLoadContent({
|
|
|
4159
4166
|
onContentApplied?.();
|
|
4160
4167
|
} catch (err) {
|
|
4161
4168
|
if (!cancelled && token === renderTokenRef.current) {
|
|
4162
|
-
if (err instanceof
|
|
4169
|
+
if (err instanceof chunkMH4VFSDL_js.EncryptedFileError) {
|
|
4163
4170
|
setIsEncrypted(true);
|
|
4164
4171
|
} else {
|
|
4165
4172
|
console.error("[pptx] Failed to load presentation content:", err);
|
|
@@ -4187,7 +4194,7 @@ function useLoadContent({
|
|
|
4187
4194
|
}
|
|
4188
4195
|
function useAutosave(input) {
|
|
4189
4196
|
const { isDirty, filePath, serializeSlides, enabled = true, getChangeSources } = input;
|
|
4190
|
-
const intervalMs =
|
|
4197
|
+
const intervalMs = chunkMH4VFSDL_js.resolveAutosaveIntervalMs({
|
|
4191
4198
|
hostIntervalMs: input.intervalMs,
|
|
4192
4199
|
optionsIntervalSeconds: input.intervalSeconds
|
|
4193
4200
|
});
|
|
@@ -4218,7 +4225,7 @@ function useAutosave(input) {
|
|
|
4218
4225
|
return;
|
|
4219
4226
|
}
|
|
4220
4227
|
const sources = changeSourcesRef.current?.() ?? [];
|
|
4221
|
-
if (!
|
|
4228
|
+
if (!chunkMH4VFSDL_js.shouldWriteAutosaveSnapshot({
|
|
4222
4229
|
filePath: path,
|
|
4223
4230
|
isDirty: isDirtyRef.current,
|
|
4224
4231
|
saving: isSavingRef.current,
|
|
@@ -4236,8 +4243,8 @@ function useAutosave(input) {
|
|
|
4236
4243
|
isSavingRef.current = false;
|
|
4237
4244
|
return;
|
|
4238
4245
|
}
|
|
4239
|
-
await
|
|
4240
|
-
lastSnapshotRef.current =
|
|
4246
|
+
await chunkMH4VFSDL_js.saveAutosaveSnapshot(path, data);
|
|
4247
|
+
lastSnapshotRef.current = chunkMH4VFSDL_js.autosaveSnapshotMark(path, sources);
|
|
4241
4248
|
setAutosaveStatus({ state: "saved", timestamp: Date.now() });
|
|
4242
4249
|
} catch (err) {
|
|
4243
4250
|
setAutosaveStatus({
|
|
@@ -4291,13 +4298,13 @@ function useElementOperations(input) {
|
|
|
4291
4298
|
inlineEditingText
|
|
4292
4299
|
} = input;
|
|
4293
4300
|
const liveTextSegments = react.useCallback(() => {
|
|
4294
|
-
if (!selectedElement || !
|
|
4301
|
+
if (!selectedElement || !chunkMH4VFSDL_js.hasTextProperties(selectedElement)) {
|
|
4295
4302
|
return void 0;
|
|
4296
4303
|
}
|
|
4297
4304
|
if (selectedElement.id !== inlineEditingElementId) {
|
|
4298
4305
|
return selectedElement.textSegments;
|
|
4299
4306
|
}
|
|
4300
|
-
return
|
|
4307
|
+
return chunkMH4VFSDL_js.remapTextToSegments(
|
|
4301
4308
|
inlineEditingText,
|
|
4302
4309
|
selectedElement.textSegments,
|
|
4303
4310
|
selectedElement.textStyle
|
|
@@ -4338,11 +4345,11 @@ function useElementOperations(input) {
|
|
|
4338
4345
|
(elementId, updates) => {
|
|
4339
4346
|
if (masterView?.target) {
|
|
4340
4347
|
applyMasterViewWrite(
|
|
4341
|
-
|
|
4348
|
+
chunkMH4VFSDL_js.updateMasterViewElement(masterView, masterView.target, elementId, updates)
|
|
4342
4349
|
);
|
|
4343
4350
|
return;
|
|
4344
4351
|
}
|
|
4345
|
-
if (
|
|
4352
|
+
if (chunkMH4VFSDL_js.isTemplateElementId(elementId)) {
|
|
4346
4353
|
const slideId = activeSlide?.id;
|
|
4347
4354
|
if (slideId) {
|
|
4348
4355
|
setTemplateElementsBySlideId((prev) => ({
|
|
@@ -4353,7 +4360,7 @@ function useElementOperations(input) {
|
|
|
4353
4360
|
}));
|
|
4354
4361
|
}
|
|
4355
4362
|
} else {
|
|
4356
|
-
setSlides((prev) =>
|
|
4363
|
+
setSlides((prev) => chunkMH4VFSDL_js.updateElement(prev, activeSlideIndex, elementId, updates));
|
|
4357
4364
|
}
|
|
4358
4365
|
history.markDirty();
|
|
4359
4366
|
},
|
|
@@ -4378,7 +4385,7 @@ function useElementOperations(input) {
|
|
|
4378
4385
|
);
|
|
4379
4386
|
const updateSelectedShapeStyle = react.useCallback(
|
|
4380
4387
|
(updates) => {
|
|
4381
|
-
if (!selectedElement || !
|
|
4388
|
+
if (!selectedElement || !chunkMH4VFSDL_js.hasShapeProperties(selectedElement)) {
|
|
4382
4389
|
return;
|
|
4383
4390
|
}
|
|
4384
4391
|
updateSelectedElement({
|
|
@@ -4389,19 +4396,19 @@ function useElementOperations(input) {
|
|
|
4389
4396
|
);
|
|
4390
4397
|
const updateSelectedTextStyle = react.useCallback(
|
|
4391
4398
|
(updates) => {
|
|
4392
|
-
if (!selectedElement || !
|
|
4399
|
+
if (!selectedElement || !chunkMH4VFSDL_js.hasTextProperties(selectedElement)) {
|
|
4393
4400
|
return;
|
|
4394
4401
|
}
|
|
4395
4402
|
const isLiveEditing = selectedElement.id === inlineEditingElementId;
|
|
4396
4403
|
const currentSegments = liveTextSegments();
|
|
4397
|
-
const inlineSel =
|
|
4404
|
+
const inlineSel = chunkMH4VFSDL_js.getInlineEditorSelection(currentSegments);
|
|
4398
4405
|
if (inlineSel && currentSegments) {
|
|
4399
|
-
const { newSegments: newSegments2, newSelection } =
|
|
4406
|
+
const { newSegments: newSegments2, newSelection } = chunkMH4VFSDL_js.applyStyleToSelectedSegments(
|
|
4400
4407
|
currentSegments,
|
|
4401
4408
|
inlineSel,
|
|
4402
4409
|
updates
|
|
4403
4410
|
);
|
|
4404
|
-
|
|
4411
|
+
chunkMH4VFSDL_js.setPendingSelectionRestore(newSelection);
|
|
4405
4412
|
updateSelectedElement({
|
|
4406
4413
|
textSegments: newSegments2,
|
|
4407
4414
|
...isLiveEditing ? { text: inlineEditingText } : {}
|
|
@@ -4429,14 +4436,14 @@ function useElementOperations(input) {
|
|
|
4429
4436
|
);
|
|
4430
4437
|
const updateSelectedTextCase = react.useCallback(
|
|
4431
4438
|
(mode) => {
|
|
4432
|
-
if (!selectedElement || !
|
|
4439
|
+
if (!selectedElement || !chunkMH4VFSDL_js.hasTextProperties(selectedElement)) {
|
|
4433
4440
|
return;
|
|
4434
4441
|
}
|
|
4435
4442
|
const isLiveEditing = selectedElement.id === inlineEditingElementId;
|
|
4436
4443
|
const currentSegments = liveTextSegments();
|
|
4437
|
-
const inlineSel =
|
|
4444
|
+
const inlineSel = chunkMH4VFSDL_js.getInlineEditorSelection(currentSegments);
|
|
4438
4445
|
if (inlineSel && currentSegments) {
|
|
4439
|
-
const newSegments =
|
|
4446
|
+
const newSegments = chunkMH4VFSDL_js.applyCaseTransformToSegments(currentSegments, inlineSel, mode);
|
|
4440
4447
|
updateSelectedElement({
|
|
4441
4448
|
textSegments: newSegments,
|
|
4442
4449
|
...isLiveEditing ? { text: inlineEditingText } : {}
|
|
@@ -4445,7 +4452,7 @@ function useElementOperations(input) {
|
|
|
4445
4452
|
}
|
|
4446
4453
|
const updates = {};
|
|
4447
4454
|
if (currentSegments && currentSegments.length > 0) {
|
|
4448
|
-
updates.textSegments =
|
|
4455
|
+
updates.textSegments = chunkMH4VFSDL_js.applyCaseTransformToSegments(
|
|
4449
4456
|
currentSegments,
|
|
4450
4457
|
null,
|
|
4451
4458
|
mode
|
|
@@ -4453,7 +4460,7 @@ function useElementOperations(input) {
|
|
|
4453
4460
|
}
|
|
4454
4461
|
const baseText = isLiveEditing ? inlineEditingText : selectedElement.text;
|
|
4455
4462
|
if (typeof baseText === "string") {
|
|
4456
|
-
updates.text =
|
|
4463
|
+
updates.text = chunkMH4VFSDL_js.transformTextCase(baseText, mode);
|
|
4457
4464
|
}
|
|
4458
4465
|
updateSelectedElement(updates);
|
|
4459
4466
|
},
|
|
@@ -4472,15 +4479,15 @@ function useElementOperations(input) {
|
|
|
4472
4479
|
[setSlides]
|
|
4473
4480
|
);
|
|
4474
4481
|
const masterViewTarget = masterView?.target ?? null;
|
|
4475
|
-
const activeElements = masterViewTarget ?
|
|
4482
|
+
const activeElements = masterViewTarget ? chunkMH4VFSDL_js.masterViewElements(masterView, masterViewTarget) : editTemplateMode ? templateElements : activeSlide?.elements ?? [];
|
|
4476
4483
|
const updateActiveElements = react.useCallback(
|
|
4477
4484
|
(updater) => {
|
|
4478
4485
|
if (masterView?.target) {
|
|
4479
4486
|
applyMasterViewWrite(
|
|
4480
|
-
|
|
4487
|
+
chunkMH4VFSDL_js.replaceMasterViewElements(
|
|
4481
4488
|
masterView,
|
|
4482
4489
|
masterView.target,
|
|
4483
|
-
updater(
|
|
4490
|
+
updater(chunkMH4VFSDL_js.masterViewElements(masterView, masterView.target))
|
|
4484
4491
|
)
|
|
4485
4492
|
);
|
|
4486
4493
|
return;
|
|
@@ -4533,7 +4540,7 @@ function useSectionOperations(input) {
|
|
|
4533
4540
|
const { sections, setSections, slides, setSlides, markDirty } = input;
|
|
4534
4541
|
const addSection2 = react.useCallback(
|
|
4535
4542
|
(name, afterSlideIndex) => {
|
|
4536
|
-
const result =
|
|
4543
|
+
const result = chunkMH4VFSDL_js.addSection(sections, slides, name, afterSlideIndex);
|
|
4537
4544
|
setSlides(result.slides);
|
|
4538
4545
|
setSections(result.sections);
|
|
4539
4546
|
markDirty();
|
|
@@ -4542,7 +4549,7 @@ function useSectionOperations(input) {
|
|
|
4542
4549
|
);
|
|
4543
4550
|
const renameSection2 = react.useCallback(
|
|
4544
4551
|
(sectionId, newName) => {
|
|
4545
|
-
const result =
|
|
4552
|
+
const result = chunkMH4VFSDL_js.renameSection(sections, slides, sectionId, newName);
|
|
4546
4553
|
setSections(result.sections);
|
|
4547
4554
|
setSlides(result.slides);
|
|
4548
4555
|
markDirty();
|
|
@@ -4551,7 +4558,7 @@ function useSectionOperations(input) {
|
|
|
4551
4558
|
);
|
|
4552
4559
|
const deleteSection2 = react.useCallback(
|
|
4553
4560
|
(sectionId) => {
|
|
4554
|
-
const result =
|
|
4561
|
+
const result = chunkMH4VFSDL_js.deleteSection(sections, slides, sectionId);
|
|
4555
4562
|
setSections(result.sections);
|
|
4556
4563
|
setSlides(result.slides);
|
|
4557
4564
|
markDirty();
|
|
@@ -4560,21 +4567,21 @@ function useSectionOperations(input) {
|
|
|
4560
4567
|
);
|
|
4561
4568
|
const moveSectionUp2 = react.useCallback(
|
|
4562
4569
|
(sectionId) => {
|
|
4563
|
-
setSections(
|
|
4570
|
+
setSections(chunkMH4VFSDL_js.moveSectionUp(sections, sectionId));
|
|
4564
4571
|
markDirty();
|
|
4565
4572
|
},
|
|
4566
4573
|
[sections, setSections, markDirty]
|
|
4567
4574
|
);
|
|
4568
4575
|
const moveSectionDown2 = react.useCallback(
|
|
4569
4576
|
(sectionId) => {
|
|
4570
|
-
setSections(
|
|
4577
|
+
setSections(chunkMH4VFSDL_js.moveSectionDown(sections, sectionId));
|
|
4571
4578
|
markDirty();
|
|
4572
4579
|
},
|
|
4573
4580
|
[sections, setSections, markDirty]
|
|
4574
4581
|
);
|
|
4575
4582
|
const moveSlidesToSection2 = react.useCallback(
|
|
4576
4583
|
(slideIndexes, targetSectionId) => {
|
|
4577
|
-
const result =
|
|
4584
|
+
const result = chunkMH4VFSDL_js.moveSlidesToSection(sections, slides, slideIndexes, targetSectionId);
|
|
4578
4585
|
setSlides(result.slides);
|
|
4579
4586
|
setSections(result.sections);
|
|
4580
4587
|
markDirty();
|
|
@@ -4640,15 +4647,15 @@ function syncSelectionHandleOverlay(elementNode, elementId, geometry) {
|
|
|
4640
4647
|
// src/viewer/hooks/pointer-move-handlers.ts
|
|
4641
4648
|
function computeResizeGeometry(handle, startX, startY, startWidth, startHeight, dx, dy, snapToGrid, gridSpacingPx, lockAspect = false) {
|
|
4642
4649
|
const startBox = { x: startX, y: startY, width: startWidth, height: startHeight };
|
|
4643
|
-
let resized =
|
|
4650
|
+
let resized = chunkMH4VFSDL_js.applyResize(startBox, handle, dx, dy, 1, { minSize: chunkH4LMXJ2Z_js.MIN_ELEMENT_SIZE });
|
|
4644
4651
|
if (lockAspect) {
|
|
4645
|
-
resized =
|
|
4652
|
+
resized = chunkMH4VFSDL_js.lockResizeAspect(resized, startBox, handle, chunkH4LMXJ2Z_js.MIN_ELEMENT_SIZE);
|
|
4646
4653
|
}
|
|
4647
4654
|
const box = { x: resized.x, y: resized.y, width: resized.width, height: resized.height };
|
|
4648
4655
|
if (!snapToGrid) {
|
|
4649
4656
|
return box;
|
|
4650
4657
|
}
|
|
4651
|
-
return
|
|
4658
|
+
return chunkMH4VFSDL_js.snapBoxToGrid(box, handle, gridSpacingPx, chunkH4LMXJ2Z_js.MIN_ELEMENT_SIZE);
|
|
4652
4659
|
}
|
|
4653
4660
|
function resolveLiveTarget(input) {
|
|
4654
4661
|
const { livePatcher, editTemplateMode, activeSlide } = input;
|
|
@@ -4761,7 +4768,7 @@ function processDragMove(e, drag, editorScale, snapToGrid, snapToShape, gridSpac
|
|
|
4761
4768
|
width: el.width,
|
|
4762
4769
|
height: el.height
|
|
4763
4770
|
}));
|
|
4764
|
-
const snapResult =
|
|
4771
|
+
const snapResult = chunkMH4VFSDL_js.computeSnapToShape(
|
|
4765
4772
|
targetX,
|
|
4766
4773
|
targetY,
|
|
4767
4774
|
primaryEl.width,
|
|
@@ -4803,7 +4810,7 @@ function processDragMove(e, drag, editorScale, snapToGrid, snapToShape, gridSpac
|
|
|
4803
4810
|
if (live) {
|
|
4804
4811
|
for (const id of Object.keys(drag.startPositionsById)) {
|
|
4805
4812
|
const start = drag.startPositionsById[id];
|
|
4806
|
-
|
|
4813
|
+
chunkMH4VFSDL_js.publishLiveGeometry(live.patcher, live.slideId, id, {
|
|
4807
4814
|
x: start.x + appliedDx,
|
|
4808
4815
|
y: start.y + appliedDy
|
|
4809
4816
|
});
|
|
@@ -4835,8 +4842,8 @@ function processResizeMove(e, rs, editorScale, snapToGrid, gridSpacingPx, live)
|
|
|
4835
4842
|
rs.lastY = geo.y;
|
|
4836
4843
|
rs.lastWidth = geo.width;
|
|
4837
4844
|
rs.lastHeight = geo.height;
|
|
4838
|
-
const width = Math.max(geo.width,
|
|
4839
|
-
const height = Math.max(geo.height,
|
|
4845
|
+
const width = Math.max(geo.width, chunkH4LMXJ2Z_js.MIN_ELEMENT_SIZE);
|
|
4846
|
+
const height = Math.max(geo.height, chunkH4LMXJ2Z_js.MIN_ELEMENT_SIZE);
|
|
4840
4847
|
if (rs.domEl) {
|
|
4841
4848
|
rs.domEl.style.left = `${geo.x}px`;
|
|
4842
4849
|
rs.domEl.style.top = `${geo.y}px`;
|
|
@@ -4845,7 +4852,7 @@ function processResizeMove(e, rs, editorScale, snapToGrid, gridSpacingPx, live)
|
|
|
4845
4852
|
syncSelectionHandleOverlay(rs.domEl, rs.elementId, { x: geo.x, y: geo.y, width, height });
|
|
4846
4853
|
}
|
|
4847
4854
|
if (live) {
|
|
4848
|
-
|
|
4855
|
+
chunkMH4VFSDL_js.publishLiveGeometry(live.patcher, live.slideId, rs.elementId, {
|
|
4849
4856
|
x: geo.x,
|
|
4850
4857
|
y: geo.y,
|
|
4851
4858
|
width,
|
|
@@ -4856,7 +4863,7 @@ function processResizeMove(e, rs, editorScale, snapToGrid, gridSpacingPx, live)
|
|
|
4856
4863
|
function processAdjustmentMove(e, adj, editorScale, updateElementById) {
|
|
4857
4864
|
const dx = (e.clientX - adj.startClientX) / editorScale;
|
|
4858
4865
|
const dy = (e.clientY - adj.startClientY) / editorScale;
|
|
4859
|
-
const adjustments =
|
|
4866
|
+
const adjustments = chunkMH4VFSDL_js.getDraggedShapeAdjustments(adj, dx, dy);
|
|
4860
4867
|
if (!adj.moved && Math.hypot(dx, dy) > 2) {
|
|
4861
4868
|
adj.moved = true;
|
|
4862
4869
|
}
|
|
@@ -4931,13 +4938,13 @@ function processPointerUp(input) {
|
|
|
4931
4938
|
if (i !== activeSlideIndex) {
|
|
4932
4939
|
return s;
|
|
4933
4940
|
}
|
|
4934
|
-
const rerouted =
|
|
4941
|
+
const rerouted = chunkMH4VFSDL_js.rerouteConnectorsForMovedElements(s.elements, movedIds);
|
|
4935
4942
|
if (rerouted.length === 0) {
|
|
4936
4943
|
return s;
|
|
4937
4944
|
}
|
|
4938
4945
|
return {
|
|
4939
4946
|
...s,
|
|
4940
|
-
elements:
|
|
4947
|
+
elements: chunkMH4VFSDL_js.applyReroutedConnectors(s.elements, rerouted)
|
|
4941
4948
|
};
|
|
4942
4949
|
})
|
|
4943
4950
|
);
|
|
@@ -4962,9 +4969,9 @@ function processPointerUp(input) {
|
|
|
4962
4969
|
}
|
|
4963
4970
|
function commitMarquee(marquee, editTemplateMode, templateElements, activeSlide, applySelection, clearSelection) {
|
|
4964
4971
|
const sourceElements = editTemplateMode ? templateElements : activeSlide?.elements ?? [];
|
|
4965
|
-
const hitIds =
|
|
4972
|
+
const hitIds = chunkMH4VFSDL_js.computeMarqueeHitIds(marquee, sourceElements);
|
|
4966
4973
|
if (marquee.additive) {
|
|
4967
|
-
const merged =
|
|
4974
|
+
const merged = chunkMH4VFSDL_js.mergeAdditiveSelection(marquee.baseSelectionIds, hitIds);
|
|
4968
4975
|
if (merged.length > 0) {
|
|
4969
4976
|
applySelection(merged[0], merged);
|
|
4970
4977
|
} else {
|
|
@@ -4987,8 +4994,8 @@ function commitDrag(drag, editTemplateMode, activeSlide, activeSlideIndex, setTe
|
|
|
4987
4994
|
}
|
|
4988
4995
|
return { ...el, x: start.x + dx, y: start.y + dy };
|
|
4989
4996
|
});
|
|
4990
|
-
const rerouted =
|
|
4991
|
-
return
|
|
4997
|
+
const rerouted = chunkMH4VFSDL_js.rerouteConnectorsForMovedElements(movedElements, movedIds);
|
|
4998
|
+
return chunkMH4VFSDL_js.applyReroutedConnectors(movedElements, rerouted);
|
|
4992
4999
|
};
|
|
4993
5000
|
if (editTemplateMode) {
|
|
4994
5001
|
const slideId = activeSlide?.id;
|
|
@@ -5144,17 +5151,17 @@ function useCanvasInteractions(input) {
|
|
|
5144
5151
|
return;
|
|
5145
5152
|
}
|
|
5146
5153
|
const el = elementLookup.get(editId);
|
|
5147
|
-
if (el &&
|
|
5154
|
+
if (el && chunkMH4VFSDL_js.hasTextProperties(el)) {
|
|
5148
5155
|
const committedText = transformCommittedText ? transformCommittedText(inlineEditingText) : inlineEditingText;
|
|
5149
|
-
const textPatch =
|
|
5156
|
+
const textPatch = chunkMH4VFSDL_js.buildInlineTextCommitPatch(el, committedText);
|
|
5150
5157
|
if (!textPatch) {
|
|
5151
5158
|
setInlineEditingElementId(null);
|
|
5152
5159
|
setInlineEditingText("");
|
|
5153
5160
|
return;
|
|
5154
5161
|
}
|
|
5155
5162
|
const editorEl = document.querySelector("[data-inline-editor]");
|
|
5156
|
-
const newHeight =
|
|
5157
|
-
const shrink =
|
|
5163
|
+
const newHeight = chunkMH4VFSDL_js.resolveInlineEditAutoFitHeight(el.textStyle, el.height, editorEl);
|
|
5164
|
+
const shrink = chunkMH4VFSDL_js.resolveInlineEditNormAutofitShrink(el.textStyle, el.height, editorEl);
|
|
5158
5165
|
ops.updateElementById(editId, {
|
|
5159
5166
|
...textPatch,
|
|
5160
5167
|
...newHeight !== void 0 ? { height: newHeight } : {},
|
|
@@ -5172,7 +5179,7 @@ function useCanvasInteractions(input) {
|
|
|
5172
5179
|
setInlineEditingText("");
|
|
5173
5180
|
};
|
|
5174
5181
|
const openEquationEditorForElement = (el) => {
|
|
5175
|
-
if (!
|
|
5182
|
+
if (!chunkMH4VFSDL_js.hasTextProperties(el)) {
|
|
5176
5183
|
return false;
|
|
5177
5184
|
}
|
|
5178
5185
|
const eqSeg = el.textSegments?.find((seg) => seg.equationXml);
|
|
@@ -5202,7 +5209,7 @@ function useCanvasInteractions(input) {
|
|
|
5202
5209
|
justInteractedRef.current = false;
|
|
5203
5210
|
} else {
|
|
5204
5211
|
const el = elementLookup.get(elementId);
|
|
5205
|
-
if (el &&
|
|
5212
|
+
if (el && chunkMH4VFSDL_js.hasTextProperties(el) && chunkMH4VFSDL_js.canInteractWithElement(el, "textEdit")) {
|
|
5206
5213
|
if (!openEquationEditorForElement(el)) {
|
|
5207
5214
|
setInlineEditingElementId(elementId);
|
|
5208
5215
|
setInlineEditingText(el.text ?? "");
|
|
@@ -5221,7 +5228,7 @@ function useCanvasInteractions(input) {
|
|
|
5221
5228
|
if (openEquationEditorForElement(el)) {
|
|
5222
5229
|
return;
|
|
5223
5230
|
}
|
|
5224
|
-
if (
|
|
5231
|
+
if (chunkMH4VFSDL_js.hasTextProperties(el) && chunkMH4VFSDL_js.canInteractWithElement(el, "textEdit")) {
|
|
5225
5232
|
setInlineEditingElementId(elementId);
|
|
5226
5233
|
setInlineEditingText(el.text ?? "");
|
|
5227
5234
|
}
|
|
@@ -5244,7 +5251,7 @@ function useCanvasInteractions(input) {
|
|
|
5244
5251
|
justSelectedRef.current = false;
|
|
5245
5252
|
}
|
|
5246
5253
|
const ids = !wasSelected ? [elementId] : effectiveSelectedIds.length ? effectiveSelectedIds : [elementId];
|
|
5247
|
-
const movableIds =
|
|
5254
|
+
const movableIds = chunkMH4VFSDL_js.filterInteractableIds(ids, (id) => elementLookup.get(id), "move");
|
|
5248
5255
|
if (movableIds.length === 0) {
|
|
5249
5256
|
return;
|
|
5250
5257
|
}
|
|
@@ -5314,7 +5321,7 @@ function useCanvasInteractions(input) {
|
|
|
5314
5321
|
const handleResizePointerDown = (elementId, e, handle) => {
|
|
5315
5322
|
e.stopPropagation();
|
|
5316
5323
|
const el = elementLookup.get(elementId);
|
|
5317
|
-
if (!el || !
|
|
5324
|
+
if (!el || !chunkMH4VFSDL_js.canInteractWithElement(el, "resize")) {
|
|
5318
5325
|
return;
|
|
5319
5326
|
}
|
|
5320
5327
|
resizeStateRef.current = {
|
|
@@ -5336,7 +5343,7 @@ function useCanvasInteractions(input) {
|
|
|
5336
5343
|
};
|
|
5337
5344
|
const handleRotate = (elementId, rotationDeg) => {
|
|
5338
5345
|
const el = elementLookup.get(elementId);
|
|
5339
|
-
if (!el || !
|
|
5346
|
+
if (!el || !chunkMH4VFSDL_js.canInteractWithElement(el, "rotate")) {
|
|
5340
5347
|
return;
|
|
5341
5348
|
}
|
|
5342
5349
|
ops.updateElementById(elementId, { rotation: rotationDeg });
|
|
@@ -5356,10 +5363,10 @@ function useCanvasInteractions(input) {
|
|
|
5356
5363
|
const handleAdjustmentPointerDown = (elementId, e, descriptor) => {
|
|
5357
5364
|
e.stopPropagation();
|
|
5358
5365
|
const el = elementLookup.get(elementId);
|
|
5359
|
-
if (!el || !
|
|
5366
|
+
if (!el || !chunkMH4VFSDL_js.canInteractWithElement(el, "adjustHandle")) {
|
|
5360
5367
|
return;
|
|
5361
5368
|
}
|
|
5362
|
-
shapeAdjustmentDragStateRef.current =
|
|
5369
|
+
shapeAdjustmentDragStateRef.current = chunkMH4VFSDL_js.beginShapeAdjustment(
|
|
5363
5370
|
el,
|
|
5364
5371
|
descriptor,
|
|
5365
5372
|
e.clientX,
|
|
@@ -5406,7 +5413,7 @@ function createFileHandlers(deps) {
|
|
|
5406
5413
|
h = Math.round(h * scale);
|
|
5407
5414
|
}
|
|
5408
5415
|
addElement({
|
|
5409
|
-
id:
|
|
5416
|
+
id: chunkMH4VFSDL_js.generateElementId(),
|
|
5410
5417
|
type: "image",
|
|
5411
5418
|
x: Math.round((canvasSize.width - w) / 2),
|
|
5412
5419
|
y: Math.round((canvasSize.height - h) / 2),
|
|
@@ -5417,7 +5424,7 @@ function createFileHandlers(deps) {
|
|
|
5417
5424
|
};
|
|
5418
5425
|
img.onerror = () => {
|
|
5419
5426
|
addElement({
|
|
5420
|
-
id:
|
|
5427
|
+
id: chunkMH4VFSDL_js.generateElementId(),
|
|
5421
5428
|
type: "image",
|
|
5422
5429
|
x: 100,
|
|
5423
5430
|
y: 100,
|
|
@@ -5436,14 +5443,14 @@ function createFileHandlers(deps) {
|
|
|
5436
5443
|
return;
|
|
5437
5444
|
}
|
|
5438
5445
|
e.target.value = "";
|
|
5439
|
-
const mediaType =
|
|
5446
|
+
const mediaType = chunkMH4VFSDL_js.classifyMediaType(file.type);
|
|
5440
5447
|
if (!mediaType) {
|
|
5441
5448
|
return;
|
|
5442
5449
|
}
|
|
5443
5450
|
const elFilePath = file.path;
|
|
5444
5451
|
const insertMediaElement = (mediaSourceUrl, width, height) => {
|
|
5445
5452
|
addElement({
|
|
5446
|
-
id:
|
|
5453
|
+
id: chunkMH4VFSDL_js.generateElementId(),
|
|
5447
5454
|
type: "media",
|
|
5448
5455
|
mediaType,
|
|
5449
5456
|
mediaMimeType: file.type || void 0,
|
|
@@ -5618,13 +5625,13 @@ function createStructuredElementHandlers(deps) {
|
|
|
5618
5625
|
return;
|
|
5619
5626
|
}
|
|
5620
5627
|
addElement({
|
|
5621
|
-
id:
|
|
5628
|
+
id: chunkMH4VFSDL_js.generateElementId(),
|
|
5622
5629
|
type: "smartArt",
|
|
5623
5630
|
x: 100,
|
|
5624
5631
|
y: 120,
|
|
5625
5632
|
width: 600,
|
|
5626
5633
|
height: 340,
|
|
5627
|
-
smartArtData:
|
|
5634
|
+
smartArtData: chunkMH4VFSDL_js.buildSmartArtPresetData(
|
|
5628
5635
|
layout,
|
|
5629
5636
|
defaultItems,
|
|
5630
5637
|
(i) => `node-${Date.now()}-${i}-${Math.random().toString(36).slice(2, 8)}`
|
|
@@ -5636,7 +5643,7 @@ function createStructuredElementHandlers(deps) {
|
|
|
5636
5643
|
return;
|
|
5637
5644
|
}
|
|
5638
5645
|
addElement({
|
|
5639
|
-
id:
|
|
5646
|
+
id: chunkMH4VFSDL_js.generateElementId(),
|
|
5640
5647
|
type: "shape",
|
|
5641
5648
|
x: 120,
|
|
5642
5649
|
y: 200,
|
|
@@ -5674,7 +5681,7 @@ function createStructuredElementHandlers(deps) {
|
|
|
5674
5681
|
return;
|
|
5675
5682
|
}
|
|
5676
5683
|
const resolved = resolveHyperlinkEditResult(data);
|
|
5677
|
-
if (resolved.url && !
|
|
5684
|
+
if (resolved.url && !chunkMH4VFSDL_js.isUrlSafe(resolved.url)) {
|
|
5678
5685
|
return;
|
|
5679
5686
|
}
|
|
5680
5687
|
const actionClick = {
|
|
@@ -5698,7 +5705,7 @@ function createStructuredElementHandlers(deps) {
|
|
|
5698
5705
|
const displayText = value || fieldTexts[fieldType] || fieldType;
|
|
5699
5706
|
const fieldGuid = `{${crypto.randomUUID().toUpperCase()}}`;
|
|
5700
5707
|
addElement({
|
|
5701
|
-
id:
|
|
5708
|
+
id: chunkMH4VFSDL_js.generateElementId(),
|
|
5702
5709
|
type: "shape",
|
|
5703
5710
|
x: 120,
|
|
5704
5711
|
y: 200,
|
|
@@ -5720,11 +5727,11 @@ function createStructuredElementHandlers(deps) {
|
|
|
5720
5727
|
if (!activeSlide) {
|
|
5721
5728
|
return;
|
|
5722
5729
|
}
|
|
5723
|
-
const preset =
|
|
5730
|
+
const preset = chunkMH4VFSDL_js.ACTION_BUTTON_PRESETS.find((p) => p.shapeType === shapeType);
|
|
5724
5731
|
if (!preset) {
|
|
5725
5732
|
return;
|
|
5726
5733
|
}
|
|
5727
|
-
const defaultPptxAction =
|
|
5734
|
+
const defaultPptxAction = chunkMH4VFSDL_js.elementActionToPptxAction({
|
|
5728
5735
|
trigger: "click",
|
|
5729
5736
|
type: preset.defaultAction
|
|
5730
5737
|
});
|
|
@@ -5733,7 +5740,7 @@ function createStructuredElementHandlers(deps) {
|
|
|
5733
5740
|
defaultPptxAction.highlightClick = true;
|
|
5734
5741
|
}
|
|
5735
5742
|
addElement({
|
|
5736
|
-
id:
|
|
5743
|
+
id: chunkMH4VFSDL_js.generateElementId(),
|
|
5737
5744
|
type: "shape",
|
|
5738
5745
|
x: 150,
|
|
5739
5746
|
y: 150,
|
|
@@ -5800,14 +5807,14 @@ function useInsertElements(input) {
|
|
|
5800
5807
|
return;
|
|
5801
5808
|
}
|
|
5802
5809
|
addElement({
|
|
5803
|
-
id:
|
|
5810
|
+
id: chunkMH4VFSDL_js.generateElementId(),
|
|
5804
5811
|
type: "text",
|
|
5805
5812
|
x: 100,
|
|
5806
5813
|
y: 100,
|
|
5807
5814
|
width: 300,
|
|
5808
5815
|
height: 60,
|
|
5809
5816
|
text: "",
|
|
5810
|
-
textStyle: { fontSize:
|
|
5817
|
+
textStyle: { fontSize: chunkH4LMXJ2Z_js.DEFAULT_TEXT_FONT_SIZE }
|
|
5811
5818
|
});
|
|
5812
5819
|
};
|
|
5813
5820
|
const handleAddShape = () => {
|
|
@@ -5815,7 +5822,7 @@ function useInsertElements(input) {
|
|
|
5815
5822
|
return;
|
|
5816
5823
|
}
|
|
5817
5824
|
addElement({
|
|
5818
|
-
id:
|
|
5825
|
+
id: chunkMH4VFSDL_js.generateElementId(),
|
|
5819
5826
|
type: "shape",
|
|
5820
5827
|
x: 150,
|
|
5821
5828
|
y: 150,
|
|
@@ -5834,15 +5841,15 @@ function useInsertElements(input) {
|
|
|
5834
5841
|
return;
|
|
5835
5842
|
}
|
|
5836
5843
|
addElement({
|
|
5837
|
-
...
|
|
5838
|
-
id:
|
|
5844
|
+
...chunkMH4VFSDL_js.newTableElement(chunkH4LMXJ2Z_js.DEFAULT_TABLE_ROWS, chunkH4LMXJ2Z_js.DEFAULT_TABLE_COLUMNS, 100, 200),
|
|
5845
|
+
id: chunkMH4VFSDL_js.generateElementId()
|
|
5839
5846
|
});
|
|
5840
5847
|
};
|
|
5841
5848
|
const handleAddChart = (chartKind) => {
|
|
5842
5849
|
if (!activeSlide) {
|
|
5843
5850
|
return;
|
|
5844
5851
|
}
|
|
5845
|
-
addElement(
|
|
5852
|
+
addElement(chunkMH4VFSDL_js.createDefaultChartElement(chartKind));
|
|
5846
5853
|
};
|
|
5847
5854
|
const structured = createStructuredElementHandlers({
|
|
5848
5855
|
activeSlide,
|
|
@@ -5912,7 +5919,7 @@ function useClipboardHandlers(input) {
|
|
|
5912
5919
|
if (!selectedElement) {
|
|
5913
5920
|
return;
|
|
5914
5921
|
}
|
|
5915
|
-
setClipboardPayload(
|
|
5922
|
+
setClipboardPayload(chunkMH4VFSDL_js.buildElementClipboardPayload(selectedElement, editTemplateMode));
|
|
5916
5923
|
};
|
|
5917
5924
|
const handleDelete = () => {
|
|
5918
5925
|
const idsToDelete = effectiveSelectedIds;
|
|
@@ -5929,7 +5936,7 @@ function useClipboardHandlers(input) {
|
|
|
5929
5936
|
handleDelete();
|
|
5930
5937
|
};
|
|
5931
5938
|
const insertClone = (source) => {
|
|
5932
|
-
const clone =
|
|
5939
|
+
const clone = chunkMH4VFSDL_js.cloneElementForPaste(source, { intoTemplate: editTemplateMode });
|
|
5933
5940
|
ops.updateActiveElements((els) => [...els, clone]);
|
|
5934
5941
|
ops.applySelection(clone.id);
|
|
5935
5942
|
history.markDirty();
|
|
@@ -5964,7 +5971,7 @@ function resolveShapePath(el) {
|
|
|
5964
5971
|
return el.pathData;
|
|
5965
5972
|
}
|
|
5966
5973
|
if ("shapeType" in el && typeof el.shapeType === "string") {
|
|
5967
|
-
const clipPath =
|
|
5974
|
+
const clipPath = chunkMH4VFSDL_js.getPresetShapeClipPath(el.shapeType);
|
|
5968
5975
|
if (clipPath) {
|
|
5969
5976
|
const svgPath = clipPathToSvgPath(clipPath, el.width, el.height);
|
|
5970
5977
|
if (svgPath) {
|
|
@@ -6015,7 +6022,7 @@ function clipPathToSvgPath(clipPath, width, height) {
|
|
|
6015
6022
|
return parts.join(" ");
|
|
6016
6023
|
}
|
|
6017
6024
|
function transformPathToGlobal(pathData, el) {
|
|
6018
|
-
const polys =
|
|
6025
|
+
const polys = chunkMH4VFSDL_js.svgPathToPolygons(pathData);
|
|
6019
6026
|
if (polys.length === 0) {
|
|
6020
6027
|
return pathData;
|
|
6021
6028
|
}
|
|
@@ -6035,10 +6042,10 @@ function transformPathToGlobal(pathData, el) {
|
|
|
6035
6042
|
y: pt.y * scaleY + el.y
|
|
6036
6043
|
}))
|
|
6037
6044
|
);
|
|
6038
|
-
return
|
|
6045
|
+
return chunkMH4VFSDL_js.polygonsToSvgPath(transformed);
|
|
6039
6046
|
}
|
|
6040
6047
|
function transformPathToLocal(pathData, x, y, _width, _height) {
|
|
6041
|
-
const polys =
|
|
6048
|
+
const polys = chunkMH4VFSDL_js.svgPathToPolygons(pathData);
|
|
6042
6049
|
if (polys.length === 0) {
|
|
6043
6050
|
return pathData;
|
|
6044
6051
|
}
|
|
@@ -6048,10 +6055,10 @@ function transformPathToLocal(pathData, x, y, _width, _height) {
|
|
|
6048
6055
|
y: pt.y - y
|
|
6049
6056
|
}))
|
|
6050
6057
|
);
|
|
6051
|
-
return
|
|
6058
|
+
return chunkMH4VFSDL_js.polygonsToSvgPath(transformed);
|
|
6052
6059
|
}
|
|
6053
6060
|
function pathBounds(pathData) {
|
|
6054
|
-
const polys =
|
|
6061
|
+
const polys = chunkMH4VFSDL_js.svgPathToPolygons(pathData);
|
|
6055
6062
|
let minX = Infinity;
|
|
6056
6063
|
let minY = Infinity;
|
|
6057
6064
|
let maxX = -Infinity;
|
|
@@ -6110,7 +6117,7 @@ function useMergeShapesHandler(input) {
|
|
|
6110
6117
|
let allFragments = [];
|
|
6111
6118
|
let remaining = globalPaths[0];
|
|
6112
6119
|
for (let i = 1; i < globalPaths.length; i++) {
|
|
6113
|
-
const frags =
|
|
6120
|
+
const frags = chunkMH4VFSDL_js.mergeShapes("fragment", remaining, globalPaths[i]);
|
|
6114
6121
|
if (Array.isArray(frags)) {
|
|
6115
6122
|
allFragments = frags;
|
|
6116
6123
|
}
|
|
@@ -6139,7 +6146,7 @@ function useMergeShapesHandler(input) {
|
|
|
6139
6146
|
bounds.height
|
|
6140
6147
|
);
|
|
6141
6148
|
const newEl = {
|
|
6142
|
-
id:
|
|
6149
|
+
id: chunkMH4VFSDL_js.generateElementId(),
|
|
6143
6150
|
type: "shape",
|
|
6144
6151
|
x: bounds.x,
|
|
6145
6152
|
y: bounds.y,
|
|
@@ -6177,7 +6184,7 @@ function useMergeShapesHandler(input) {
|
|
|
6177
6184
|
} else {
|
|
6178
6185
|
let resultPath = globalPaths[0];
|
|
6179
6186
|
for (let i = 1; i < globalPaths.length; i++) {
|
|
6180
|
-
const result =
|
|
6187
|
+
const result = chunkMH4VFSDL_js.mergeShapes(operation, resultPath, globalPaths[i]);
|
|
6181
6188
|
if (typeof result === "string") {
|
|
6182
6189
|
resultPath = result;
|
|
6183
6190
|
}
|
|
@@ -6198,7 +6205,7 @@ function useMergeShapesHandler(input) {
|
|
|
6198
6205
|
);
|
|
6199
6206
|
const primary = targets[0];
|
|
6200
6207
|
const newEl = {
|
|
6201
|
-
id:
|
|
6208
|
+
id: chunkMH4VFSDL_js.generateElementId(),
|
|
6202
6209
|
type: "shape",
|
|
6203
6210
|
x: bounds.x,
|
|
6204
6211
|
y: bounds.y,
|
|
@@ -6261,10 +6268,10 @@ function useGroupAlignLayerHandlers(input) {
|
|
|
6261
6268
|
if (ids.length < 2 || !activeSlide) {
|
|
6262
6269
|
return;
|
|
6263
6270
|
}
|
|
6264
|
-
if (!selectedElements.every((el) =>
|
|
6271
|
+
if (!selectedElements.every((el) => chunkMH4VFSDL_js.canInteractWithElement(el, "group"))) {
|
|
6265
6272
|
return;
|
|
6266
6273
|
}
|
|
6267
|
-
const { elements, groupId } =
|
|
6274
|
+
const { elements, groupId } = chunkMH4VFSDL_js.groupElements(ops.activeElements, ids, chunkMH4VFSDL_js.generateElementId());
|
|
6268
6275
|
if (groupId === null) {
|
|
6269
6276
|
return;
|
|
6270
6277
|
}
|
|
@@ -6276,15 +6283,15 @@ function useGroupAlignLayerHandlers(input) {
|
|
|
6276
6283
|
if (!selectedElement || selectedElement.type !== "group" || !activeSlide) {
|
|
6277
6284
|
return;
|
|
6278
6285
|
}
|
|
6279
|
-
if (!
|
|
6286
|
+
if (!chunkMH4VFSDL_js.canInteractWithElement(selectedElement, "group")) {
|
|
6280
6287
|
return;
|
|
6281
6288
|
}
|
|
6282
6289
|
const group = selectedElement;
|
|
6283
|
-
const intoTemplate =
|
|
6290
|
+
const intoTemplate = chunkMH4VFSDL_js.isTemplateElementId(group.id);
|
|
6284
6291
|
const childIds = group.children.map(
|
|
6285
|
-
(child) => intoTemplate ?
|
|
6292
|
+
(child) => intoTemplate ? chunkMH4VFSDL_js.makeCloneId(true, child.id || group.id) : child.id || chunkMH4VFSDL_js.generateElementId()
|
|
6286
6293
|
);
|
|
6287
|
-
const { elements, childIds: usedIds } =
|
|
6294
|
+
const { elements, childIds: usedIds } = chunkMH4VFSDL_js.ungroupElements(
|
|
6288
6295
|
ops.activeElements,
|
|
6289
6296
|
group.id,
|
|
6290
6297
|
childIds,
|
|
@@ -6313,7 +6320,7 @@ function useGroupAlignLayerHandlers(input) {
|
|
|
6313
6320
|
if (!edge) {
|
|
6314
6321
|
return;
|
|
6315
6322
|
}
|
|
6316
|
-
const positions =
|
|
6323
|
+
const positions = chunkMH4VFSDL_js.alignElements(selectedElements, edge);
|
|
6317
6324
|
for (const [id, pos] of positions) {
|
|
6318
6325
|
const el = elementLookup.get(id);
|
|
6319
6326
|
if (!el) {
|
|
@@ -6331,7 +6338,7 @@ function useGroupAlignLayerHandlers(input) {
|
|
|
6331
6338
|
if (!distAxis) {
|
|
6332
6339
|
return;
|
|
6333
6340
|
}
|
|
6334
|
-
const positions =
|
|
6341
|
+
const positions = chunkMH4VFSDL_js.distributeElements(selectedElements, distAxis);
|
|
6335
6342
|
for (const [id, pos] of positions) {
|
|
6336
6343
|
const el = elementLookup.get(id);
|
|
6337
6344
|
if (!el) {
|
|
@@ -6342,14 +6349,14 @@ function useGroupAlignLayerHandlers(input) {
|
|
|
6342
6349
|
history.markDirty();
|
|
6343
6350
|
};
|
|
6344
6351
|
const canDistribute = selectedElements.length >= 3;
|
|
6345
|
-
const selectionGroupable = selectedElements.every((el) =>
|
|
6352
|
+
const selectionGroupable = selectedElements.every((el) => chunkMH4VFSDL_js.canInteractWithElement(el, "group"));
|
|
6346
6353
|
const handleMoveLayer = (direction) => {
|
|
6347
6354
|
if (!selectedElement || !activeSlide) {
|
|
6348
6355
|
return;
|
|
6349
6356
|
}
|
|
6350
6357
|
const id = selectedElement.id;
|
|
6351
6358
|
ops.updateActiveElements(
|
|
6352
|
-
(els) => direction === "forward" ?
|
|
6359
|
+
(els) => direction === "forward" ? chunkMH4VFSDL_js.bringForward(els, id) : direction === "backward" ? chunkMH4VFSDL_js.sendBackward(els, id) : els
|
|
6353
6360
|
);
|
|
6354
6361
|
history.markDirty();
|
|
6355
6362
|
};
|
|
@@ -6359,7 +6366,7 @@ function useGroupAlignLayerHandlers(input) {
|
|
|
6359
6366
|
}
|
|
6360
6367
|
const id = selectedElement.id;
|
|
6361
6368
|
ops.updateActiveElements(
|
|
6362
|
-
(els) => direction === "front" ?
|
|
6369
|
+
(els) => direction === "front" ? chunkMH4VFSDL_js.bringToFront(els, id) : chunkMH4VFSDL_js.sendToBack(els, id)
|
|
6363
6370
|
);
|
|
6364
6371
|
history.markDirty();
|
|
6365
6372
|
};
|
|
@@ -6493,7 +6500,7 @@ function useSlideManagement(input) {
|
|
|
6493
6500
|
theme
|
|
6494
6501
|
} = input;
|
|
6495
6502
|
const handleAddSlide = () => {
|
|
6496
|
-
const newSlide =
|
|
6503
|
+
const newSlide = chunkMH4VFSDL_js.createBlankSlide(slides.length + 1);
|
|
6497
6504
|
ops.updateSlides((prev) => {
|
|
6498
6505
|
const next = [...prev];
|
|
6499
6506
|
next.splice(activeSlideIndex + 1, 0, newSlide);
|
|
@@ -6556,7 +6563,7 @@ function useSlideManagement(input) {
|
|
|
6556
6563
|
}
|
|
6557
6564
|
const clone = {
|
|
6558
6565
|
...src,
|
|
6559
|
-
id:
|
|
6566
|
+
id: chunkMH4VFSDL_js.makeSlideId(),
|
|
6560
6567
|
elements: src.elements.map((el) => ({
|
|
6561
6568
|
...el,
|
|
6562
6569
|
id: `${el.id}-dup-${Math.random().toString(36).slice(2, 6)}`
|
|
@@ -6588,7 +6595,7 @@ function useSlideManagement(input) {
|
|
|
6588
6595
|
const handleInsertSlideFromLayout = (layoutPath, layoutName) => {
|
|
6589
6596
|
const insertAt = activeSlideIndex + 1;
|
|
6590
6597
|
const draft = {
|
|
6591
|
-
...
|
|
6598
|
+
...chunkMH4VFSDL_js.createBlankSlide(slides.length + 1),
|
|
6592
6599
|
layoutPath,
|
|
6593
6600
|
...layoutName ? { layoutName } : {}
|
|
6594
6601
|
};
|
|
@@ -6621,9 +6628,9 @@ function useSlideManagement(input) {
|
|
|
6621
6628
|
};
|
|
6622
6629
|
const handleInsertSlideFromTemplate = (templateId) => {
|
|
6623
6630
|
const insertAt = activeSlideIndex + 1;
|
|
6624
|
-
const draft =
|
|
6631
|
+
const draft = chunkMH4VFSDL_js.buildSlideTemplateSlide(templateId, chunkMH4VFSDL_js.makeSlideId(), slides.length + 1, {
|
|
6625
6632
|
...canvasSize ? { slideWidth: canvasSize.width, slideHeight: canvasSize.height } : {},
|
|
6626
|
-
scheme:
|
|
6633
|
+
scheme: chunkMH4VFSDL_js.templateSchemeFromTheme(theme?.colorScheme)
|
|
6627
6634
|
});
|
|
6628
6635
|
ops.updateSlides((prev) => insertSlideFromLayoutUpdater(prev, activeSlideIndex, draft));
|
|
6629
6636
|
setActiveSlideIndex(insertAt);
|
|
@@ -6660,7 +6667,7 @@ function createTableMergeHandlers(input) {
|
|
|
6660
6667
|
if (!nextCell || nextCell.hMerge || nextCell.vMerge) {
|
|
6661
6668
|
return;
|
|
6662
6669
|
}
|
|
6663
|
-
const newTableData =
|
|
6670
|
+
const newTableData = chunkMH4VFSDL_js.mergeCells(
|
|
6664
6671
|
[
|
|
6665
6672
|
{ row: rowIndex, col: columnIndex },
|
|
6666
6673
|
{ row: rowIndex, col: nextColIdx }
|
|
@@ -6668,7 +6675,7 @@ function createTableMergeHandlers(input) {
|
|
|
6668
6675
|
td
|
|
6669
6676
|
);
|
|
6670
6677
|
const updates = { tableData: newTableData };
|
|
6671
|
-
const newRawXml =
|
|
6678
|
+
const newRawXml = chunkMH4VFSDL_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
|
|
6672
6679
|
if (newRawXml) {
|
|
6673
6680
|
updates.rawXml = newRawXml;
|
|
6674
6681
|
}
|
|
@@ -6694,7 +6701,7 @@ function createTableMergeHandlers(input) {
|
|
|
6694
6701
|
if (!targetNextCell || targetNextCell.hMerge || targetNextCell.vMerge) {
|
|
6695
6702
|
return;
|
|
6696
6703
|
}
|
|
6697
|
-
const newTableData =
|
|
6704
|
+
const newTableData = chunkMH4VFSDL_js.mergeCells(
|
|
6698
6705
|
[
|
|
6699
6706
|
{ row: rowIndex, col: columnIndex },
|
|
6700
6707
|
{ row: targetNextRowIdx, col: columnIndex }
|
|
@@ -6702,7 +6709,7 @@ function createTableMergeHandlers(input) {
|
|
|
6702
6709
|
td
|
|
6703
6710
|
);
|
|
6704
6711
|
const updates = { tableData: newTableData };
|
|
6705
|
-
const newRawXml =
|
|
6712
|
+
const newRawXml = chunkMH4VFSDL_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
|
|
6706
6713
|
if (newRawXml) {
|
|
6707
6714
|
updates.rawXml = newRawXml;
|
|
6708
6715
|
}
|
|
@@ -6717,9 +6724,9 @@ function createTableMergeHandlers(input) {
|
|
|
6717
6724
|
return;
|
|
6718
6725
|
}
|
|
6719
6726
|
const td = selectedElement.tableData;
|
|
6720
|
-
const newTableData =
|
|
6727
|
+
const newTableData = chunkMH4VFSDL_js.mergeCells(ts.selectedCells, td);
|
|
6721
6728
|
const updates = { tableData: newTableData };
|
|
6722
|
-
const newRawXml =
|
|
6729
|
+
const newRawXml = chunkMH4VFSDL_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
|
|
6723
6730
|
if (newRawXml) {
|
|
6724
6731
|
updates.rawXml = newRawXml;
|
|
6725
6732
|
}
|
|
@@ -6736,9 +6743,9 @@ function createTableMergeHandlers(input) {
|
|
|
6736
6743
|
}
|
|
6737
6744
|
const { rowIndex, columnIndex } = ts;
|
|
6738
6745
|
const td = selectedElement.tableData;
|
|
6739
|
-
const newTableData =
|
|
6746
|
+
const newTableData = chunkMH4VFSDL_js.splitCell(rowIndex, columnIndex, td);
|
|
6740
6747
|
const updates = { tableData: newTableData };
|
|
6741
|
-
const newRawXml =
|
|
6748
|
+
const newRawXml = chunkMH4VFSDL_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
|
|
6742
6749
|
if (newRawXml) {
|
|
6743
6750
|
updates.rawXml = newRawXml;
|
|
6744
6751
|
}
|
|
@@ -6772,10 +6779,10 @@ function createTableStructHandlers(input) {
|
|
|
6772
6779
|
const text = transformCommittedText ? transformCommittedText(rawText) : rawText;
|
|
6773
6780
|
const updates = {};
|
|
6774
6781
|
if (el.tableData) {
|
|
6775
|
-
updates.tableData =
|
|
6782
|
+
updates.tableData = chunkMH4VFSDL_js.setCellText(el, rowIndex, colIndex, text).tableData;
|
|
6776
6783
|
}
|
|
6777
6784
|
if (el.rawXml) {
|
|
6778
|
-
const newRawXml =
|
|
6785
|
+
const newRawXml = chunkMH4VFSDL_js.updateCellTextInRawXml(el, rowIndex, colIndex, text);
|
|
6779
6786
|
if (newRawXml) {
|
|
6780
6787
|
updates.rawXml = newRawXml;
|
|
6781
6788
|
}
|
|
@@ -6799,7 +6806,7 @@ function createTableStructHandlers(input) {
|
|
|
6799
6806
|
const { rowIndex, columnIndex: colIndex } = ts;
|
|
6800
6807
|
const updates = {};
|
|
6801
6808
|
if (selectedElement.rawXml) {
|
|
6802
|
-
const newRawXml =
|
|
6809
|
+
const newRawXml = chunkMH4VFSDL_js.updateCellTextStyleInRawXml(
|
|
6803
6810
|
selectedElement,
|
|
6804
6811
|
rowIndex,
|
|
6805
6812
|
colIndex,
|
|
@@ -6863,9 +6870,9 @@ function createTableStructHandlers(input) {
|
|
|
6863
6870
|
return;
|
|
6864
6871
|
}
|
|
6865
6872
|
const rowIdx = ts?.rowIndex ?? 0;
|
|
6866
|
-
const newTableData =
|
|
6873
|
+
const newTableData = chunkMH4VFSDL_js.insertTableRow(selectedElement.tableData, rowIdx, position);
|
|
6867
6874
|
const updates = { tableData: newTableData };
|
|
6868
|
-
const newRawXml =
|
|
6875
|
+
const newRawXml = chunkMH4VFSDL_js.rebuildTableStructureInRawXml(selectedElement, newTableData);
|
|
6869
6876
|
if (newRawXml) {
|
|
6870
6877
|
updates.rawXml = newRawXml;
|
|
6871
6878
|
}
|
|
@@ -6878,12 +6885,12 @@ function createTableStructHandlers(input) {
|
|
|
6878
6885
|
}
|
|
6879
6886
|
const td = selectedElement.tableData;
|
|
6880
6887
|
const rowIdx = ts?.rowIndex ?? 0;
|
|
6881
|
-
const newTableData =
|
|
6888
|
+
const newTableData = chunkMH4VFSDL_js.deleteTableRow(td, rowIdx);
|
|
6882
6889
|
if (newTableData === td) {
|
|
6883
6890
|
return;
|
|
6884
6891
|
}
|
|
6885
6892
|
const updates = { tableData: newTableData };
|
|
6886
|
-
const newRawXml =
|
|
6893
|
+
const newRawXml = chunkMH4VFSDL_js.rebuildTableStructureInRawXml(selectedElement, newTableData);
|
|
6887
6894
|
if (newRawXml) {
|
|
6888
6895
|
updates.rawXml = newRawXml;
|
|
6889
6896
|
}
|
|
@@ -6895,9 +6902,9 @@ function createTableStructHandlers(input) {
|
|
|
6895
6902
|
return;
|
|
6896
6903
|
}
|
|
6897
6904
|
const colIdx = ts?.columnIndex ?? 0;
|
|
6898
|
-
const newTableData =
|
|
6905
|
+
const newTableData = chunkMH4VFSDL_js.insertTableColumn(selectedElement.tableData, colIdx, position);
|
|
6899
6906
|
const updates = { tableData: newTableData };
|
|
6900
|
-
const newRawXml =
|
|
6907
|
+
const newRawXml = chunkMH4VFSDL_js.rebuildTableStructureInRawXml(selectedElement, newTableData);
|
|
6901
6908
|
if (newRawXml) {
|
|
6902
6909
|
updates.rawXml = newRawXml;
|
|
6903
6910
|
}
|
|
@@ -6910,12 +6917,12 @@ function createTableStructHandlers(input) {
|
|
|
6910
6917
|
}
|
|
6911
6918
|
const td = selectedElement.tableData;
|
|
6912
6919
|
const colIdx = ts?.columnIndex ?? 0;
|
|
6913
|
-
const newTableData =
|
|
6920
|
+
const newTableData = chunkMH4VFSDL_js.deleteTableColumn(td, colIdx);
|
|
6914
6921
|
if (newTableData === td) {
|
|
6915
6922
|
return;
|
|
6916
6923
|
}
|
|
6917
6924
|
const updates = { tableData: newTableData };
|
|
6918
|
-
const newRawXml =
|
|
6925
|
+
const newRawXml = chunkMH4VFSDL_js.rebuildTableStructureInRawXml(selectedElement, newTableData);
|
|
6919
6926
|
if (newRawXml) {
|
|
6920
6927
|
updates.rawXml = newRawXml;
|
|
6921
6928
|
}
|
|
@@ -6951,8 +6958,8 @@ async function renderToCanvas(element, options = {}) {
|
|
|
6951
6958
|
return html2canvasPro(element, {
|
|
6952
6959
|
...options,
|
|
6953
6960
|
onclone: async (doc, clonedEl) => {
|
|
6954
|
-
await
|
|
6955
|
-
|
|
6961
|
+
await chunkMH4VFSDL_js.normalizeColorsForCapture(doc, clonedEl);
|
|
6962
|
+
chunkMH4VFSDL_js.preprocessCssForCapture(clonedEl);
|
|
6956
6963
|
if (typeof userOnClone === "function") {
|
|
6957
6964
|
userOnClone(doc, clonedEl);
|
|
6958
6965
|
}
|
|
@@ -6982,7 +6989,7 @@ function useExportSaveAs(input) {
|
|
|
6982
6989
|
slideSizeEmu
|
|
6983
6990
|
} = input;
|
|
6984
6991
|
const handleSaveAsFormat = async (format) => {
|
|
6985
|
-
const downloadName =
|
|
6992
|
+
const downloadName = chunkMH4VFSDL_js.savedPresentationFileName(filePath, format);
|
|
6986
6993
|
try {
|
|
6987
6994
|
const data = await serializeSlides(format);
|
|
6988
6995
|
if (!data) {
|
|
@@ -6990,16 +6997,16 @@ function useExportSaveAs(input) {
|
|
|
6990
6997
|
}
|
|
6991
6998
|
const mimeType = format === "ppt" ? "application/vnd.ms-powerpoint" : "application/vnd.openxmlformats-officedocument.presentationml.presentation";
|
|
6992
6999
|
const blob = new Blob([data], { type: mimeType });
|
|
6993
|
-
|
|
7000
|
+
chunkMH4VFSDL_js.downloadBlob(blob, downloadName);
|
|
6994
7001
|
} catch (err) {
|
|
6995
7002
|
console.error(`[PowerPointViewer] Save as .${format} failed:`, err);
|
|
6996
7003
|
}
|
|
6997
7004
|
};
|
|
6998
7005
|
const handleExportJson = () => {
|
|
6999
7006
|
const sourceName = filePath ? filePath.replace(/\\/gu, "/").split("/").pop() : void 0;
|
|
7000
|
-
const slideSize =
|
|
7007
|
+
const slideSize = chunkMH4VFSDL_js.resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size;
|
|
7001
7008
|
const data = {
|
|
7002
|
-
slides:
|
|
7009
|
+
slides: chunkMH4VFSDL_js.buildSaveSlides(slides, templateElementsBySlideId),
|
|
7003
7010
|
width: canvasSize.width,
|
|
7004
7011
|
height: canvasSize.height,
|
|
7005
7012
|
widthEmu: slideSize.widthEmu,
|
|
@@ -7018,7 +7025,7 @@ function useExportSaveAs(input) {
|
|
|
7018
7025
|
handoutMaster
|
|
7019
7026
|
};
|
|
7020
7027
|
try {
|
|
7021
|
-
|
|
7028
|
+
chunkMH4VFSDL_js.exportDeckJson(data, sourceName);
|
|
7022
7029
|
} catch (err) {
|
|
7023
7030
|
console.error("[PowerPointViewer] JSON export failed:", err);
|
|
7024
7031
|
}
|
|
@@ -7045,22 +7052,6 @@ function useExportSaveAs(input) {
|
|
|
7045
7052
|
};
|
|
7046
7053
|
}
|
|
7047
7054
|
|
|
7048
|
-
// src/viewer/utils/dom-helpers.ts
|
|
7049
|
-
function safePrompt(message, defaultValue) {
|
|
7050
|
-
try {
|
|
7051
|
-
return window.prompt(message, defaultValue);
|
|
7052
|
-
} catch {
|
|
7053
|
-
return null;
|
|
7054
|
-
}
|
|
7055
|
-
}
|
|
7056
|
-
function safeConfirm(message) {
|
|
7057
|
-
try {
|
|
7058
|
-
return window.confirm(message);
|
|
7059
|
-
} catch {
|
|
7060
|
-
return false;
|
|
7061
|
-
}
|
|
7062
|
-
}
|
|
7063
|
-
|
|
7064
7055
|
// src/viewer/utils/export-helpers.ts
|
|
7065
7056
|
function ignoreExportOverlayElements(el) {
|
|
7066
7057
|
const htmlEl = el;
|
|
@@ -7099,7 +7090,7 @@ function buildRasterOptions(element, scale, backgroundColor, mode) {
|
|
|
7099
7090
|
}
|
|
7100
7091
|
async function renderElementToRaster(element, scale = 2, backgroundColor, mode = "auto") {
|
|
7101
7092
|
const { width, height } = measureNaturalSize(element);
|
|
7102
|
-
return
|
|
7093
|
+
return chunkMH4VFSDL_js.rasterizeElement(
|
|
7103
7094
|
element,
|
|
7104
7095
|
width,
|
|
7105
7096
|
height,
|
|
@@ -7109,7 +7100,7 @@ async function renderElementToRaster(element, scale = 2, backgroundColor, mode =
|
|
|
7109
7100
|
}
|
|
7110
7101
|
async function renderElementToTiles(element, scale = 2, backgroundColor, mode = "auto") {
|
|
7111
7102
|
const { width, height } = measureNaturalSize(element);
|
|
7112
|
-
return
|
|
7103
|
+
return chunkMH4VFSDL_js.rasterizeElementTiles(
|
|
7113
7104
|
element,
|
|
7114
7105
|
width,
|
|
7115
7106
|
height,
|
|
@@ -7117,9 +7108,9 @@ async function renderElementToTiles(element, scale = 2, backgroundColor, mode =
|
|
|
7117
7108
|
buildRasterOptions(element, scale, backgroundColor, mode)
|
|
7118
7109
|
);
|
|
7119
7110
|
}
|
|
7120
|
-
async function
|
|
7111
|
+
async function renderElementToTiledCanvas(element, scale = 2, backgroundColor, mode = "auto") {
|
|
7121
7112
|
const { width, height } = measureNaturalSize(element);
|
|
7122
|
-
return
|
|
7113
|
+
return chunkMH4VFSDL_js.rasterizeElementTiledToCanvas(
|
|
7123
7114
|
element,
|
|
7124
7115
|
width,
|
|
7125
7116
|
height,
|
|
@@ -7141,11 +7132,11 @@ function waitForRender(ms = 100) {
|
|
|
7141
7132
|
async function exportSlideToPngBlob(slideElement, options = {}) {
|
|
7142
7133
|
const { scale = 2, backgroundColor } = options;
|
|
7143
7134
|
const result = await renderElementToRaster(slideElement, scale, backgroundColor);
|
|
7144
|
-
return
|
|
7135
|
+
return chunkMH4VFSDL_js.rasterResultToPngBlob(result);
|
|
7145
7136
|
}
|
|
7146
7137
|
async function exportSlideAsPng(slideElement, slideIndex, options = {}) {
|
|
7147
7138
|
const blob = await exportSlideToPngBlob(slideElement, options);
|
|
7148
|
-
|
|
7139
|
+
chunkMH4VFSDL_js.downloadBlob(blob, `slide-${slideIndex + 1}.png`);
|
|
7149
7140
|
}
|
|
7150
7141
|
async function copySlideToClipboard(slideElement, options = {}) {
|
|
7151
7142
|
const blob = await exportSlideToPngBlob(slideElement, options);
|
|
@@ -7163,7 +7154,7 @@ async function captureAllSlidesAsPngDataUrls(slideStageRef, totalSlides, setActi
|
|
|
7163
7154
|
console.warn(`[export] Could not find slide stage element for slide ${i}`);
|
|
7164
7155
|
continue;
|
|
7165
7156
|
}
|
|
7166
|
-
const { canvas } = await
|
|
7157
|
+
const { canvas } = await renderElementToTiledCanvas(stageEl, scale);
|
|
7167
7158
|
dataUrls.push(canvas.toDataURL("image/png"));
|
|
7168
7159
|
}
|
|
7169
7160
|
onProgress?.(totalSlides, totalSlides);
|
|
@@ -7174,13 +7165,13 @@ async function captureAllSlidesAsPngDataUrls(slideStageRef, totalSlides, setActi
|
|
|
7174
7165
|
// src/viewer/utils/export-pdf.ts
|
|
7175
7166
|
function tilesToPdfPage(tilesResult) {
|
|
7176
7167
|
return tilesResult.tiles.map((tile) => ({
|
|
7177
|
-
image:
|
|
7178
|
-
placement:
|
|
7168
|
+
image: chunkMH4VFSDL_js.canvasToJpegData(tile.canvas),
|
|
7169
|
+
placement: chunkMH4VFSDL_js.placeTileOnPage(
|
|
7179
7170
|
tile,
|
|
7180
7171
|
tilesResult.fullWidth,
|
|
7181
7172
|
tilesResult.fullHeight,
|
|
7182
|
-
|
|
7183
|
-
|
|
7173
|
+
chunkMH4VFSDL_js.PDF_SLIDES_PAGE_WIDTH_PT,
|
|
7174
|
+
chunkMH4VFSDL_js.PDF_SLIDES_PAGE_HEIGHT_PT
|
|
7184
7175
|
)
|
|
7185
7176
|
}));
|
|
7186
7177
|
}
|
|
@@ -7207,8 +7198,8 @@ async function exportAllSlidesAsPdf(slideStageRef, totalSlides, setActiveSlide,
|
|
|
7207
7198
|
if (pages.length === 0) {
|
|
7208
7199
|
throw new Error(chunk3AJ54EAB_js.translationsEn["pptx.export.errorNoSlidesPdf"]);
|
|
7209
7200
|
}
|
|
7210
|
-
const pdfBlobUrl =
|
|
7211
|
-
|
|
7201
|
+
const pdfBlobUrl = chunkH4LMXJ2Z_js.buildPdfFromTiledImageData(pages);
|
|
7202
|
+
chunkMH4VFSDL_js.downloadDataUrl(pdfBlobUrl, filename);
|
|
7212
7203
|
}
|
|
7213
7204
|
async function exportAllSlidesAsNotesPdf(slideStageRef, totalSlides, setActiveSlide, currentSlideIndex, slideNotes, filename = "presentation-notes.pdf", options = {}) {
|
|
7214
7205
|
const { scale = 2, onProgress, signal } = options;
|
|
@@ -7225,7 +7216,7 @@ async function exportAllSlidesAsNotesPdf(slideStageRef, totalSlides, setActiveSl
|
|
|
7225
7216
|
console.warn(`[export] Could not find slide stage element for slide ${i}`);
|
|
7226
7217
|
continue;
|
|
7227
7218
|
}
|
|
7228
|
-
const { canvas } = await
|
|
7219
|
+
const { canvas } = await renderElementToTiledCanvas(stageEl, scale);
|
|
7229
7220
|
pages.push({
|
|
7230
7221
|
canvas,
|
|
7231
7222
|
notes: slideNotes[i],
|
|
@@ -7237,8 +7228,8 @@ async function exportAllSlidesAsNotesPdf(slideStageRef, totalSlides, setActiveSl
|
|
|
7237
7228
|
if (pages.length === 0) {
|
|
7238
7229
|
throw new Error(chunk3AJ54EAB_js.translationsEn["pptx.export.errorNoSlidesNotesPdf"]);
|
|
7239
7230
|
}
|
|
7240
|
-
const pdfDataUrl =
|
|
7241
|
-
|
|
7231
|
+
const pdfDataUrl = chunkH4LMXJ2Z_js.buildNotesPdf(pages);
|
|
7232
|
+
chunkMH4VFSDL_js.downloadDataUrl(pdfDataUrl, filename);
|
|
7242
7233
|
}
|
|
7243
7234
|
|
|
7244
7235
|
// src/viewer/utils/export-video.ts
|
|
@@ -7264,7 +7255,7 @@ async function exportAllSlidesAsVideo(slideStageRef, totalSlides, setActiveSlide
|
|
|
7264
7255
|
console.warn(`[export] Could not find slide stage element for slide ${i}`);
|
|
7265
7256
|
continue;
|
|
7266
7257
|
}
|
|
7267
|
-
const { canvas } = await
|
|
7258
|
+
const { canvas } = await renderElementToTiledCanvas(stageEl, scale);
|
|
7268
7259
|
slideCanvases.push(canvas);
|
|
7269
7260
|
}
|
|
7270
7261
|
setActiveSlide(currentSlideIndex);
|
|
@@ -7282,7 +7273,7 @@ async function exportAllSlidesAsVideo(slideStageRef, totalSlides, setActiveSlide
|
|
|
7282
7273
|
const fps = 30;
|
|
7283
7274
|
const stream = recordingCanvas.captureStream(fps);
|
|
7284
7275
|
const recorder = new MediaRecorder(stream, {
|
|
7285
|
-
mimeType:
|
|
7276
|
+
mimeType: chunkMH4VFSDL_js.pickSupportedMimeType([...chunkMH4VFSDL_js.WEBM_MIME_CANDIDATES]),
|
|
7286
7277
|
videoBitsPerSecond: 5e6
|
|
7287
7278
|
});
|
|
7288
7279
|
const chunks = [];
|
|
@@ -7305,8 +7296,8 @@ async function exportAllSlidesAsVideo(slideStageRef, totalSlides, setActiveSlide
|
|
|
7305
7296
|
const duration = slideTimingsMs?.[i] ?? slideDurationMs;
|
|
7306
7297
|
ctx.clearRect(0, 0, recordingCanvas.width, recordingCanvas.height);
|
|
7307
7298
|
ctx.drawImage(slideCanvases[i], 0, 0);
|
|
7308
|
-
const frameInterval =
|
|
7309
|
-
const framesNeeded =
|
|
7299
|
+
const frameInterval = chunkMH4VFSDL_js.fpsToFrameIntervalMs(fps);
|
|
7300
|
+
const framesNeeded = chunkMH4VFSDL_js.segmentFrameCount(duration, fps);
|
|
7310
7301
|
for (let f = 0; f < framesNeeded; f++) {
|
|
7311
7302
|
if (signal?.aborted) {
|
|
7312
7303
|
recorder.stop();
|
|
@@ -7325,8 +7316,34 @@ async function exportAllSlidesAsVideo(slideStageRef, totalSlides, setActiveSlide
|
|
|
7325
7316
|
}
|
|
7326
7317
|
|
|
7327
7318
|
// src/viewer/utils/export-gif.ts
|
|
7319
|
+
function frameFromCanvas(canvas, maxSide) {
|
|
7320
|
+
const { width, height } = chunkMH4VFSDL_js.clampGifDimensions(canvas.width, canvas.height, maxSide);
|
|
7321
|
+
let source = canvas;
|
|
7322
|
+
if (width !== canvas.width || height !== canvas.height) {
|
|
7323
|
+
const scaled = canvas.ownerDocument.createElement("canvas");
|
|
7324
|
+
scaled.width = width;
|
|
7325
|
+
scaled.height = height;
|
|
7326
|
+
const scaledCtx = scaled.getContext("2d");
|
|
7327
|
+
if (!scaledCtx) {
|
|
7328
|
+
return void 0;
|
|
7329
|
+
}
|
|
7330
|
+
scaledCtx.drawImage(canvas, 0, 0, width, height);
|
|
7331
|
+
source = scaled;
|
|
7332
|
+
}
|
|
7333
|
+
const ctx = source.getContext("2d");
|
|
7334
|
+
if (!ctx) {
|
|
7335
|
+
return void 0;
|
|
7336
|
+
}
|
|
7337
|
+
return { imageData: ctx.getImageData(0, 0, width, height), width, height };
|
|
7338
|
+
}
|
|
7328
7339
|
async function exportAllSlidesAsGif(slideStageRef, totalSlides, setActiveSlide, currentSlideIndex, options = {}) {
|
|
7329
|
-
const {
|
|
7340
|
+
const {
|
|
7341
|
+
scale = 0.5,
|
|
7342
|
+
slideDurationMs = 2e3,
|
|
7343
|
+
maxSide = chunkMH4VFSDL_js.GIF_POST_CAPTURE_MAX_SIDE,
|
|
7344
|
+
onProgress,
|
|
7345
|
+
signal
|
|
7346
|
+
} = options;
|
|
7330
7347
|
const frames = [];
|
|
7331
7348
|
for (let i = 0; i < totalSlides; i++) {
|
|
7332
7349
|
if (signal?.aborted) {
|
|
@@ -7339,23 +7356,18 @@ async function exportAllSlidesAsGif(slideStageRef, totalSlides, setActiveSlide,
|
|
|
7339
7356
|
if (!stageEl) {
|
|
7340
7357
|
continue;
|
|
7341
7358
|
}
|
|
7342
|
-
const { canvas } = await
|
|
7343
|
-
const
|
|
7344
|
-
if (!
|
|
7359
|
+
const { canvas } = await renderElementToTiledCanvas(stageEl, scale);
|
|
7360
|
+
const frame = frameFromCanvas(canvas, maxSide);
|
|
7361
|
+
if (!frame) {
|
|
7345
7362
|
continue;
|
|
7346
7363
|
}
|
|
7347
|
-
|
|
7348
|
-
frames.push({
|
|
7349
|
-
imageData,
|
|
7350
|
-
width: canvas.width,
|
|
7351
|
-
height: canvas.height
|
|
7352
|
-
});
|
|
7364
|
+
frames.push(frame);
|
|
7353
7365
|
}
|
|
7354
7366
|
setActiveSlide(currentSlideIndex);
|
|
7355
7367
|
if (frames.length === 0) {
|
|
7356
7368
|
throw new Error(chunk3AJ54EAB_js.translationsEn["pptx.export.errorNoSlidesGif"]);
|
|
7357
7369
|
}
|
|
7358
|
-
const gifBytes =
|
|
7370
|
+
const gifBytes = chunkMH4VFSDL_js.encodeGif(frames, Math.round(slideDurationMs / 10));
|
|
7359
7371
|
onProgress?.(totalSlides, totalSlides);
|
|
7360
7372
|
const buf = new ArrayBuffer(gifBytes.length);
|
|
7361
7373
|
new Uint8Array(buf).set(gifBytes);
|
|
@@ -7409,7 +7421,7 @@ function exportAllSlidesToSvg(data, options = {}) {
|
|
|
7409
7421
|
continue;
|
|
7410
7422
|
}
|
|
7411
7423
|
onProgress?.(processedCount, data.slides.length);
|
|
7412
|
-
let svg =
|
|
7424
|
+
let svg = chunkMH4VFSDL_js.SvgExporter.exportSlide(slide, data.width, data.height, svgOptions);
|
|
7413
7425
|
if (embedFonts && fontFaces?.length) {
|
|
7414
7426
|
svg = injectFontFaces(svg, fontFaces);
|
|
7415
7427
|
}
|
|
@@ -7420,6 +7432,149 @@ function exportAllSlidesToSvg(data, options = {}) {
|
|
|
7420
7432
|
return results;
|
|
7421
7433
|
}
|
|
7422
7434
|
|
|
7435
|
+
// src/viewer/utils/dom-helpers.ts
|
|
7436
|
+
function safePrompt(message, defaultValue) {
|
|
7437
|
+
try {
|
|
7438
|
+
return window.prompt(message, defaultValue);
|
|
7439
|
+
} catch {
|
|
7440
|
+
return null;
|
|
7441
|
+
}
|
|
7442
|
+
}
|
|
7443
|
+
function safeConfirm(message) {
|
|
7444
|
+
try {
|
|
7445
|
+
return window.confirm(message);
|
|
7446
|
+
} catch {
|
|
7447
|
+
return false;
|
|
7448
|
+
}
|
|
7449
|
+
}
|
|
7450
|
+
|
|
7451
|
+
// src/viewer/hooks/useExportMediaHandlers.ts
|
|
7452
|
+
function useExportMediaHandlers(input) {
|
|
7453
|
+
const {
|
|
7454
|
+
slides,
|
|
7455
|
+
activeSlideIndex,
|
|
7456
|
+
canvasStageRef,
|
|
7457
|
+
setActiveSlideIndex,
|
|
7458
|
+
imageResolutionScale = 1,
|
|
7459
|
+
exportAbortRef,
|
|
7460
|
+
setExportModalOpen,
|
|
7461
|
+
setExportModalTitle,
|
|
7462
|
+
setExportProgress,
|
|
7463
|
+
setExportStatusMessage
|
|
7464
|
+
} = input;
|
|
7465
|
+
const handleExportVideo = react.useCallback(async () => {
|
|
7466
|
+
if (!canvasStageRef.current) {
|
|
7467
|
+
return;
|
|
7468
|
+
}
|
|
7469
|
+
const abortCtrl = new AbortController();
|
|
7470
|
+
exportAbortRef.current = abortCtrl;
|
|
7471
|
+
setExportModalTitle("Export as Video");
|
|
7472
|
+
setExportStatusMessage("Capturing slides...");
|
|
7473
|
+
setExportProgress(0);
|
|
7474
|
+
setExportModalOpen(true);
|
|
7475
|
+
try {
|
|
7476
|
+
const { scale } = chunkMH4VFSDL_js.resolveExportCaptureDecision(imageResolutionScale, "video");
|
|
7477
|
+
const blob = await exportAllSlidesAsVideo(
|
|
7478
|
+
canvasStageRef,
|
|
7479
|
+
slides.length,
|
|
7480
|
+
setActiveSlideIndex,
|
|
7481
|
+
activeSlideIndex,
|
|
7482
|
+
{
|
|
7483
|
+
scale,
|
|
7484
|
+
slideDurationMs: 3e3,
|
|
7485
|
+
onProgress: (current, total) => {
|
|
7486
|
+
setExportProgress(chunkMH4VFSDL_js.slideProgressPercent(current, total, 45));
|
|
7487
|
+
setExportStatusMessage(chunkMH4VFSDL_js.slideStatusLabel("Capturing", current, total));
|
|
7488
|
+
},
|
|
7489
|
+
onRecordProgress: (current, total) => {
|
|
7490
|
+
setExportProgress(chunkMH4VFSDL_js.recordProgressPercent(current, total));
|
|
7491
|
+
setExportStatusMessage(chunkMH4VFSDL_js.slideStatusLabel("Recording", current, total));
|
|
7492
|
+
},
|
|
7493
|
+
signal: abortCtrl.signal
|
|
7494
|
+
}
|
|
7495
|
+
);
|
|
7496
|
+
setExportProgress(chunkMH4VFSDL_js.EXPORT_ASSEMBLING_PERCENT);
|
|
7497
|
+
setExportStatusMessage("Saving file...");
|
|
7498
|
+
chunkMH4VFSDL_js.downloadBlob(blob, "presentation.webm");
|
|
7499
|
+
setExportProgress(chunkMH4VFSDL_js.EXPORT_DONE_PERCENT);
|
|
7500
|
+
} catch (err) {
|
|
7501
|
+
if (!chunkMH4VFSDL_js.isExportAbortError(err)) {
|
|
7502
|
+
console.error("[PowerPointViewer] Video export failed:", err);
|
|
7503
|
+
}
|
|
7504
|
+
} finally {
|
|
7505
|
+
exportAbortRef.current = null;
|
|
7506
|
+
setExportModalOpen(false);
|
|
7507
|
+
}
|
|
7508
|
+
}, [
|
|
7509
|
+
canvasStageRef,
|
|
7510
|
+
slides.length,
|
|
7511
|
+
setActiveSlideIndex,
|
|
7512
|
+
activeSlideIndex,
|
|
7513
|
+
imageResolutionScale,
|
|
7514
|
+
exportAbortRef,
|
|
7515
|
+
setExportModalOpen,
|
|
7516
|
+
setExportModalTitle,
|
|
7517
|
+
setExportProgress,
|
|
7518
|
+
setExportStatusMessage
|
|
7519
|
+
]);
|
|
7520
|
+
const handleExportGif = react.useCallback(async () => {
|
|
7521
|
+
if (!canvasStageRef.current) {
|
|
7522
|
+
return;
|
|
7523
|
+
}
|
|
7524
|
+
const abortCtrl = new AbortController();
|
|
7525
|
+
exportAbortRef.current = abortCtrl;
|
|
7526
|
+
setExportModalTitle("Export as GIF");
|
|
7527
|
+
setExportStatusMessage("Capturing slides...");
|
|
7528
|
+
setExportProgress(0);
|
|
7529
|
+
setExportModalOpen(true);
|
|
7530
|
+
try {
|
|
7531
|
+
const { scale, postCaptureMaxSide } = chunkMH4VFSDL_js.resolveExportCaptureDecision(
|
|
7532
|
+
imageResolutionScale,
|
|
7533
|
+
"gif"
|
|
7534
|
+
);
|
|
7535
|
+
const blob = await exportAllSlidesAsGif(
|
|
7536
|
+
canvasStageRef,
|
|
7537
|
+
slides.length,
|
|
7538
|
+
setActiveSlideIndex,
|
|
7539
|
+
activeSlideIndex,
|
|
7540
|
+
{
|
|
7541
|
+
scale,
|
|
7542
|
+
maxSide: postCaptureMaxSide,
|
|
7543
|
+
slideDurationMs: 2e3,
|
|
7544
|
+
onProgress: (current, total) => {
|
|
7545
|
+
setExportProgress(chunkMH4VFSDL_js.slideProgressPercent(current, total));
|
|
7546
|
+
setExportStatusMessage(chunkMH4VFSDL_js.slideStatusLabel("Encoding", current, total));
|
|
7547
|
+
},
|
|
7548
|
+
signal: abortCtrl.signal
|
|
7549
|
+
}
|
|
7550
|
+
);
|
|
7551
|
+
setExportProgress(chunkMH4VFSDL_js.EXPORT_ASSEMBLING_PERCENT);
|
|
7552
|
+
setExportStatusMessage("Saving file...");
|
|
7553
|
+
chunkMH4VFSDL_js.downloadBlob(blob, "presentation.gif");
|
|
7554
|
+
setExportProgress(chunkMH4VFSDL_js.EXPORT_DONE_PERCENT);
|
|
7555
|
+
} catch (err) {
|
|
7556
|
+
if (!chunkMH4VFSDL_js.isExportAbortError(err)) {
|
|
7557
|
+
console.error("[PowerPointViewer] GIF export failed:", err);
|
|
7558
|
+
}
|
|
7559
|
+
} finally {
|
|
7560
|
+
exportAbortRef.current = null;
|
|
7561
|
+
setExportModalOpen(false);
|
|
7562
|
+
}
|
|
7563
|
+
}, [
|
|
7564
|
+
canvasStageRef,
|
|
7565
|
+
slides.length,
|
|
7566
|
+
setActiveSlideIndex,
|
|
7567
|
+
activeSlideIndex,
|
|
7568
|
+
imageResolutionScale,
|
|
7569
|
+
exportAbortRef,
|
|
7570
|
+
setExportModalOpen,
|
|
7571
|
+
setExportModalTitle,
|
|
7572
|
+
setExportProgress,
|
|
7573
|
+
setExportStatusMessage
|
|
7574
|
+
]);
|
|
7575
|
+
return { handleExportVideo, handleExportGif };
|
|
7576
|
+
}
|
|
7577
|
+
|
|
7423
7578
|
// src/viewer/hooks/useExportHandlers.ts
|
|
7424
7579
|
function useExportHandlers(input) {
|
|
7425
7580
|
const {
|
|
@@ -7444,13 +7599,26 @@ function useExportHandlers(input) {
|
|
|
7444
7599
|
theme,
|
|
7445
7600
|
canvasSize,
|
|
7446
7601
|
slideSizeEmu,
|
|
7447
|
-
imageExportScale
|
|
7602
|
+
imageExportScale,
|
|
7603
|
+
imageResolutionScale
|
|
7448
7604
|
} = input;
|
|
7449
7605
|
const [exportModalOpen, setExportModalOpen] = react.useState(false);
|
|
7450
7606
|
const [exportModalTitle, setExportModalTitle] = react.useState("");
|
|
7451
7607
|
const [exportProgress, setExportProgress] = react.useState(0);
|
|
7452
7608
|
const [exportStatusMessage, setExportStatusMessage] = react.useState("");
|
|
7453
7609
|
const exportAbortRef = react.useRef(null);
|
|
7610
|
+
const { handleExportVideo, handleExportGif } = useExportMediaHandlers({
|
|
7611
|
+
slides,
|
|
7612
|
+
activeSlideIndex,
|
|
7613
|
+
canvasStageRef,
|
|
7614
|
+
setActiveSlideIndex,
|
|
7615
|
+
imageResolutionScale,
|
|
7616
|
+
exportAbortRef,
|
|
7617
|
+
setExportModalOpen,
|
|
7618
|
+
setExportModalTitle,
|
|
7619
|
+
setExportProgress,
|
|
7620
|
+
setExportStatusMessage
|
|
7621
|
+
});
|
|
7454
7622
|
const {
|
|
7455
7623
|
handleExportJson,
|
|
7456
7624
|
handleSaveAsFormat,
|
|
@@ -7511,21 +7679,21 @@ function useExportHandlers(input) {
|
|
|
7511
7679
|
{
|
|
7512
7680
|
scale: imageExportScale,
|
|
7513
7681
|
onProgress: (current, total) => {
|
|
7514
|
-
setExportProgress(
|
|
7515
|
-
setExportStatusMessage(
|
|
7682
|
+
setExportProgress(chunkMH4VFSDL_js.slideProgressPercent(current, total));
|
|
7683
|
+
setExportStatusMessage(chunkMH4VFSDL_js.slideStatusLabel("Rendering", current, total));
|
|
7516
7684
|
},
|
|
7517
7685
|
signal: abortCtrl.signal
|
|
7518
7686
|
}
|
|
7519
7687
|
);
|
|
7520
|
-
setExportProgress(
|
|
7688
|
+
setExportProgress(chunkMH4VFSDL_js.EXPORT_ASSEMBLING_PERCENT);
|
|
7521
7689
|
setExportStatusMessage("Building PDF...");
|
|
7522
7690
|
await new Promise((r) => {
|
|
7523
7691
|
setTimeout(r, 100);
|
|
7524
7692
|
});
|
|
7525
|
-
setExportProgress(
|
|
7693
|
+
setExportProgress(chunkMH4VFSDL_js.EXPORT_DONE_PERCENT);
|
|
7526
7694
|
setExportStatusMessage("Done!");
|
|
7527
7695
|
} catch (err) {
|
|
7528
|
-
if (!
|
|
7696
|
+
if (!chunkMH4VFSDL_js.isExportAbortError(err)) {
|
|
7529
7697
|
console.error("[PowerPointViewer] PDF export failed:", err);
|
|
7530
7698
|
}
|
|
7531
7699
|
} finally {
|
|
@@ -7555,21 +7723,21 @@ function useExportHandlers(input) {
|
|
|
7555
7723
|
{
|
|
7556
7724
|
scale: imageExportScale,
|
|
7557
7725
|
onProgress: (current, total) => {
|
|
7558
|
-
setExportProgress(
|
|
7559
|
-
setExportStatusMessage(
|
|
7726
|
+
setExportProgress(chunkMH4VFSDL_js.slideProgressPercent(current, total));
|
|
7727
|
+
setExportStatusMessage(chunkMH4VFSDL_js.slideStatusLabel("Rendering", current, total));
|
|
7560
7728
|
},
|
|
7561
7729
|
signal: abortCtrl.signal
|
|
7562
7730
|
}
|
|
7563
7731
|
);
|
|
7564
|
-
setExportProgress(
|
|
7732
|
+
setExportProgress(chunkMH4VFSDL_js.EXPORT_ASSEMBLING_PERCENT);
|
|
7565
7733
|
setExportStatusMessage("Building PDF...");
|
|
7566
7734
|
await new Promise((r) => {
|
|
7567
7735
|
setTimeout(r, 100);
|
|
7568
7736
|
});
|
|
7569
|
-
setExportProgress(
|
|
7737
|
+
setExportProgress(chunkMH4VFSDL_js.EXPORT_DONE_PERCENT);
|
|
7570
7738
|
setExportStatusMessage("Done!");
|
|
7571
7739
|
} catch (err) {
|
|
7572
|
-
if (!
|
|
7740
|
+
if (!chunkMH4VFSDL_js.isExportAbortError(err)) {
|
|
7573
7741
|
console.error("[PowerPointViewer] Notes PDF export failed:", err);
|
|
7574
7742
|
}
|
|
7575
7743
|
} finally {
|
|
@@ -7591,88 +7759,6 @@ function useExportHandlers(input) {
|
|
|
7591
7759
|
console.error("[PowerPointViewer] Copy slide as image failed:", err);
|
|
7592
7760
|
}
|
|
7593
7761
|
}, [canvasStageRef, activeSlide?.backgroundColor, imageExportScale]);
|
|
7594
|
-
const handleExportVideo = react.useCallback(async () => {
|
|
7595
|
-
if (!canvasStageRef.current) {
|
|
7596
|
-
return;
|
|
7597
|
-
}
|
|
7598
|
-
const abortCtrl = new AbortController();
|
|
7599
|
-
exportAbortRef.current = abortCtrl;
|
|
7600
|
-
setExportModalTitle("Export as Video");
|
|
7601
|
-
setExportStatusMessage("Capturing slides...");
|
|
7602
|
-
setExportProgress(0);
|
|
7603
|
-
setExportModalOpen(true);
|
|
7604
|
-
try {
|
|
7605
|
-
const blob = await exportAllSlidesAsVideo(
|
|
7606
|
-
canvasStageRef,
|
|
7607
|
-
slides.length,
|
|
7608
|
-
setActiveSlideIndex,
|
|
7609
|
-
activeSlideIndex,
|
|
7610
|
-
{
|
|
7611
|
-
scale: 1,
|
|
7612
|
-
slideDurationMs: 3e3,
|
|
7613
|
-
onProgress: (current, total) => {
|
|
7614
|
-
setExportProgress(chunkTWUAZRCG_js.slideProgressPercent(current, total, 45));
|
|
7615
|
-
setExportStatusMessage(chunkTWUAZRCG_js.slideStatusLabel("Capturing", current, total));
|
|
7616
|
-
},
|
|
7617
|
-
onRecordProgress: (current, total) => {
|
|
7618
|
-
setExportProgress(chunkTWUAZRCG_js.recordProgressPercent(current, total));
|
|
7619
|
-
setExportStatusMessage(chunkTWUAZRCG_js.slideStatusLabel("Recording", current, total));
|
|
7620
|
-
},
|
|
7621
|
-
signal: abortCtrl.signal
|
|
7622
|
-
}
|
|
7623
|
-
);
|
|
7624
|
-
setExportProgress(chunkTWUAZRCG_js.EXPORT_ASSEMBLING_PERCENT);
|
|
7625
|
-
setExportStatusMessage("Saving file...");
|
|
7626
|
-
chunkTWUAZRCG_js.downloadBlob(blob, "presentation.webm");
|
|
7627
|
-
setExportProgress(chunkTWUAZRCG_js.EXPORT_DONE_PERCENT);
|
|
7628
|
-
} catch (err) {
|
|
7629
|
-
if (!chunkTWUAZRCG_js.isExportAbortError(err)) {
|
|
7630
|
-
console.error("[PowerPointViewer] Video export failed:", err);
|
|
7631
|
-
}
|
|
7632
|
-
} finally {
|
|
7633
|
-
exportAbortRef.current = null;
|
|
7634
|
-
setExportModalOpen(false);
|
|
7635
|
-
}
|
|
7636
|
-
}, [canvasStageRef, slides.length, setActiveSlideIndex, activeSlideIndex]);
|
|
7637
|
-
const handleExportGif = react.useCallback(async () => {
|
|
7638
|
-
if (!canvasStageRef.current) {
|
|
7639
|
-
return;
|
|
7640
|
-
}
|
|
7641
|
-
const abortCtrl = new AbortController();
|
|
7642
|
-
exportAbortRef.current = abortCtrl;
|
|
7643
|
-
setExportModalTitle("Export as GIF");
|
|
7644
|
-
setExportStatusMessage("Capturing slides...");
|
|
7645
|
-
setExportProgress(0);
|
|
7646
|
-
setExportModalOpen(true);
|
|
7647
|
-
try {
|
|
7648
|
-
const blob = await exportAllSlidesAsGif(
|
|
7649
|
-
canvasStageRef,
|
|
7650
|
-
slides.length,
|
|
7651
|
-
setActiveSlideIndex,
|
|
7652
|
-
activeSlideIndex,
|
|
7653
|
-
{
|
|
7654
|
-
scale: 0.5,
|
|
7655
|
-
slideDurationMs: 2e3,
|
|
7656
|
-
onProgress: (current, total) => {
|
|
7657
|
-
setExportProgress(chunkTWUAZRCG_js.slideProgressPercent(current, total));
|
|
7658
|
-
setExportStatusMessage(chunkTWUAZRCG_js.slideStatusLabel("Encoding", current, total));
|
|
7659
|
-
},
|
|
7660
|
-
signal: abortCtrl.signal
|
|
7661
|
-
}
|
|
7662
|
-
);
|
|
7663
|
-
setExportProgress(chunkTWUAZRCG_js.EXPORT_ASSEMBLING_PERCENT);
|
|
7664
|
-
setExportStatusMessage("Saving file...");
|
|
7665
|
-
chunkTWUAZRCG_js.downloadBlob(blob, "presentation.gif");
|
|
7666
|
-
setExportProgress(chunkTWUAZRCG_js.EXPORT_DONE_PERCENT);
|
|
7667
|
-
} catch (err) {
|
|
7668
|
-
if (!chunkTWUAZRCG_js.isExportAbortError(err)) {
|
|
7669
|
-
console.error("[PowerPointViewer] GIF export failed:", err);
|
|
7670
|
-
}
|
|
7671
|
-
} finally {
|
|
7672
|
-
exportAbortRef.current = null;
|
|
7673
|
-
setExportModalOpen(false);
|
|
7674
|
-
}
|
|
7675
|
-
}, [canvasStageRef, slides.length, setActiveSlideIndex, activeSlideIndex]);
|
|
7676
7762
|
const handleCancelExport = react.useCallback(() => {
|
|
7677
7763
|
exportAbortRef.current?.abort();
|
|
7678
7764
|
exportAbortRef.current = null;
|
|
@@ -7699,7 +7785,7 @@ function useExportHandlers(input) {
|
|
|
7699
7785
|
exportStatusMessage
|
|
7700
7786
|
};
|
|
7701
7787
|
}
|
|
7702
|
-
var ViewerOptionsContext = react.createContext(
|
|
7788
|
+
var ViewerOptionsContext = react.createContext(chunkMH4VFSDL_js.DEFAULT_VIEWER_OPTIONS);
|
|
7703
7789
|
function useViewerOptionsContext() {
|
|
7704
7790
|
return react.useContext(ViewerOptionsContext);
|
|
7705
7791
|
}
|
|
@@ -7711,13 +7797,13 @@ function usePrintHandlers(input) {
|
|
|
7711
7797
|
const { t } = reactI18next.useTranslation();
|
|
7712
7798
|
const viewerOptions = useViewerOptionsContext();
|
|
7713
7799
|
const includeHiddenSlides = viewerOptions.advanced.printHiddenSlides;
|
|
7714
|
-
const printRasterScale = (viewerOptions.advanced.printHighQuality ? 4 : 3) *
|
|
7800
|
+
const printRasterScale = (viewerOptions.advanced.printHighQuality ? 4 : 3) * chunkMH4VFSDL_js.resolveImageResolutionScale(viewerOptions);
|
|
7715
7801
|
const handlePrint = () => {
|
|
7716
7802
|
setIsPrintDialogOpen(true);
|
|
7717
7803
|
};
|
|
7718
7804
|
const handlePrintSvg = async (settings) => {
|
|
7719
7805
|
setIsPrintDialogOpen(false);
|
|
7720
|
-
const printWindow =
|
|
7806
|
+
const printWindow = chunkMH4VFSDL_js.openPendingPrintWindow(t("pptx.print.preparingToPrint"));
|
|
7721
7807
|
if (!printWindow) {
|
|
7722
7808
|
console.warn(
|
|
7723
7809
|
"[PowerPointViewer] Print window was blocked by the browser. Allow popups for this site to print."
|
|
@@ -7727,9 +7813,9 @@ function usePrintHandlers(input) {
|
|
|
7727
7813
|
if (!pptxData || settings.printWhat !== "slides") {
|
|
7728
7814
|
return runRasterPrint(printWindow, settings);
|
|
7729
7815
|
}
|
|
7730
|
-
const colorFilter =
|
|
7731
|
-
const slideIndices =
|
|
7732
|
-
|
|
7816
|
+
const colorFilter = chunkMH4VFSDL_js.computeColorFilter(settings.colorMode);
|
|
7817
|
+
const slideIndices = chunkMH4VFSDL_js.filterHiddenSlideIndices(
|
|
7818
|
+
chunkMH4VFSDL_js.computeSlideIndices(
|
|
7733
7819
|
settings.slideRange,
|
|
7734
7820
|
activeSlideIndex,
|
|
7735
7821
|
slides.length,
|
|
@@ -7747,22 +7833,22 @@ function usePrintHandlers(input) {
|
|
|
7747
7833
|
printWindow.close();
|
|
7748
7834
|
return;
|
|
7749
7835
|
}
|
|
7750
|
-
const printDoc =
|
|
7836
|
+
const printDoc = chunkMH4VFSDL_js.buildPrintDocument(svgs, pptxData.width, pptxData.height, {
|
|
7751
7837
|
title: "Slides (Vector)",
|
|
7752
7838
|
orientation: settings.orientation,
|
|
7753
7839
|
colorFilter,
|
|
7754
7840
|
scaleToFit: settings.scaleToFit
|
|
7755
7841
|
});
|
|
7756
|
-
|
|
7842
|
+
chunkMH4VFSDL_js.finishPrintWindow(printWindow, printDoc);
|
|
7757
7843
|
} catch (err) {
|
|
7758
7844
|
console.warn("[PowerPointViewer] SVG print path failed, falling back to raster:", err);
|
|
7759
7845
|
return runRasterPrint(printWindow, settings);
|
|
7760
7846
|
}
|
|
7761
7847
|
};
|
|
7762
7848
|
const runRasterPrint = async (printWindow, settings) => {
|
|
7763
|
-
const colorFilter =
|
|
7764
|
-
const slideIndices =
|
|
7765
|
-
|
|
7849
|
+
const colorFilter = chunkMH4VFSDL_js.computeColorFilter(settings.colorMode);
|
|
7850
|
+
const slideIndices = chunkMH4VFSDL_js.filterHiddenSlideIndices(
|
|
7851
|
+
chunkMH4VFSDL_js.computeSlideIndices(
|
|
7766
7852
|
settings.slideRange,
|
|
7767
7853
|
activeSlideIndex,
|
|
7768
7854
|
slides.length,
|
|
@@ -7773,11 +7859,11 @@ function usePrintHandlers(input) {
|
|
|
7773
7859
|
includeHiddenSlides
|
|
7774
7860
|
);
|
|
7775
7861
|
if (settings.printWhat === "outline") {
|
|
7776
|
-
|
|
7862
|
+
chunkMH4VFSDL_js.finishPrintWindow(
|
|
7777
7863
|
printWindow,
|
|
7778
|
-
|
|
7864
|
+
chunkMH4VFSDL_js.buildPrintHtmlDocument({
|
|
7779
7865
|
title: "Outline",
|
|
7780
|
-
bodyHtml: `<div class="outline-page">${
|
|
7866
|
+
bodyHtml: `<div class="outline-page">${chunkMH4VFSDL_js.buildOutlineHtml(slideIndices, slides)}</div>`,
|
|
7781
7867
|
orientation: settings.orientation,
|
|
7782
7868
|
colorFilter,
|
|
7783
7869
|
frameSlides: settings.frameSlides,
|
|
@@ -7804,11 +7890,11 @@ function usePrintHandlers(input) {
|
|
|
7804
7890
|
}
|
|
7805
7891
|
const slideImages = slideIndices.map((idx) => allImages[idx]).filter(Boolean);
|
|
7806
7892
|
if (settings.printWhat === "slides") {
|
|
7807
|
-
|
|
7893
|
+
chunkMH4VFSDL_js.finishPrintWindow(
|
|
7808
7894
|
printWindow,
|
|
7809
|
-
|
|
7895
|
+
chunkMH4VFSDL_js.buildPrintHtmlDocument({
|
|
7810
7896
|
title: "Slides",
|
|
7811
|
-
bodyHtml:
|
|
7897
|
+
bodyHtml: chunkMH4VFSDL_js.buildSlidesHtml(slideImages, slideIndices),
|
|
7812
7898
|
orientation: settings.orientation,
|
|
7813
7899
|
colorFilter,
|
|
7814
7900
|
frameSlides: settings.frameSlides,
|
|
@@ -7818,11 +7904,11 @@ function usePrintHandlers(input) {
|
|
|
7818
7904
|
return;
|
|
7819
7905
|
}
|
|
7820
7906
|
if (settings.printWhat === "notes") {
|
|
7821
|
-
|
|
7907
|
+
chunkMH4VFSDL_js.finishPrintWindow(
|
|
7822
7908
|
printWindow,
|
|
7823
|
-
|
|
7909
|
+
chunkMH4VFSDL_js.buildPrintHtmlDocument({
|
|
7824
7910
|
title: "Notes Pages",
|
|
7825
|
-
bodyHtml:
|
|
7911
|
+
bodyHtml: chunkMH4VFSDL_js.buildNotesHtml(slideImages, slideIndices, slides),
|
|
7826
7912
|
orientation: "portrait",
|
|
7827
7913
|
colorFilter,
|
|
7828
7914
|
frameSlides: settings.frameSlides,
|
|
@@ -7833,11 +7919,11 @@ function usePrintHandlers(input) {
|
|
|
7833
7919
|
}
|
|
7834
7920
|
if (settings.printWhat === "handouts") {
|
|
7835
7921
|
const spp = settings.slidesPerPage;
|
|
7836
|
-
|
|
7922
|
+
chunkMH4VFSDL_js.finishPrintWindow(
|
|
7837
7923
|
printWindow,
|
|
7838
|
-
|
|
7924
|
+
chunkMH4VFSDL_js.buildPrintHtmlDocument({
|
|
7839
7925
|
title: `Handout ${spp} per page`,
|
|
7840
|
-
bodyHtml:
|
|
7926
|
+
bodyHtml: chunkMH4VFSDL_js.buildHandoutsHtml(slideImages, slideIndices, spp, pptxData?.handoutMaster),
|
|
7841
7927
|
orientation: "portrait",
|
|
7842
7928
|
colorFilter,
|
|
7843
7929
|
frameSlides: settings.frameSlides,
|
|
@@ -7851,7 +7937,7 @@ function usePrintHandlers(input) {
|
|
|
7851
7937
|
};
|
|
7852
7938
|
const handlePrintWithSettings = async (settings) => {
|
|
7853
7939
|
setIsPrintDialogOpen(false);
|
|
7854
|
-
const printWindow =
|
|
7940
|
+
const printWindow = chunkMH4VFSDL_js.openPendingPrintWindow(t("pptx.print.preparingToPrint"));
|
|
7855
7941
|
if (!printWindow) {
|
|
7856
7942
|
console.warn(
|
|
7857
7943
|
"[PowerPointViewer] Print window was blocked by the browser. Allow popups for this site to print."
|
|
@@ -7916,13 +8002,13 @@ function useThemeHandlers(input) {
|
|
|
7916
8002
|
return;
|
|
7917
8003
|
}
|
|
7918
8004
|
await handler.updateThemeColorScheme(colorScheme);
|
|
7919
|
-
const previousMap = theme?.colorScheme ?
|
|
7920
|
-
setSlides((prev) =>
|
|
8005
|
+
const previousMap = theme?.colorScheme ? chunkMH4VFSDL_js.buildThemeColorMap(theme.colorScheme) : {};
|
|
8006
|
+
setSlides((prev) => chunkMH4VFSDL_js.reResolveSlideColors(prev, previousMap, colorScheme));
|
|
7921
8007
|
if (Object.keys(templateElementsBySlideId).length > 0) {
|
|
7922
8008
|
setTemplateElementsBySlideId((prev) => {
|
|
7923
8009
|
const next = {};
|
|
7924
8010
|
for (const [slideId, elements] of Object.entries(prev)) {
|
|
7925
|
-
next[slideId] =
|
|
8011
|
+
next[slideId] = chunkMH4VFSDL_js.reResolveElementColors(elements, previousMap, colorScheme);
|
|
7926
8012
|
}
|
|
7927
8013
|
return next;
|
|
7928
8014
|
});
|
|
@@ -8031,7 +8117,7 @@ function useThemeSwitching(input) {
|
|
|
8031
8117
|
}
|
|
8032
8118
|
try {
|
|
8033
8119
|
await handler.applyTheme(preset.colorScheme, preset.fontScheme, preset.name);
|
|
8034
|
-
const newData =
|
|
8120
|
+
const newData = chunkMH4VFSDL_js.applyThemeToData(data, preset.colorScheme, preset.fontScheme, preset.name);
|
|
8035
8121
|
onDataChange(newData);
|
|
8036
8122
|
onThemeChanged?.(preset);
|
|
8037
8123
|
} catch (error) {
|
|
@@ -8048,7 +8134,7 @@ function useThemeSwitching(input) {
|
|
|
8048
8134
|
}
|
|
8049
8135
|
try {
|
|
8050
8136
|
await handler.applyTheme(colorScheme, fontScheme ?? {}, themeName);
|
|
8051
|
-
const newData =
|
|
8137
|
+
const newData = chunkMH4VFSDL_js.applyThemeToData(data, colorScheme, fontScheme, themeName);
|
|
8052
8138
|
onDataChange(newData);
|
|
8053
8139
|
} catch (error) {
|
|
8054
8140
|
console.error("Failed to switch to custom theme:", error);
|
|
@@ -8060,12 +8146,12 @@ function useThemeSwitching(input) {
|
|
|
8060
8146
|
if (!data?.theme?.colorScheme) {
|
|
8061
8147
|
return void 0;
|
|
8062
8148
|
}
|
|
8063
|
-
return
|
|
8064
|
-
(p) =>
|
|
8149
|
+
return chunkMH4VFSDL_js.THEME_PRESETS.find(
|
|
8150
|
+
(p) => chunkMH4VFSDL_js.themeColorSchemesEqual(data.theme?.colorScheme, p.colorScheme)
|
|
8065
8151
|
);
|
|
8066
8152
|
}, [data?.theme?.colorScheme]);
|
|
8067
8153
|
return {
|
|
8068
|
-
presets:
|
|
8154
|
+
presets: chunkMH4VFSDL_js.THEME_PRESETS,
|
|
8069
8155
|
switchToPreset,
|
|
8070
8156
|
switchToCustom,
|
|
8071
8157
|
currentPreset
|
|
@@ -8140,7 +8226,7 @@ function usePropertyHandlers(input) {
|
|
|
8140
8226
|
}
|
|
8141
8227
|
try {
|
|
8142
8228
|
const ab = await file.arrayBuffer();
|
|
8143
|
-
const h = new
|
|
8229
|
+
const h = new chunkMH4VFSDL_js.PptxHandler();
|
|
8144
8230
|
const other = await h.load(ab);
|
|
8145
8231
|
if (!other) {
|
|
8146
8232
|
return;
|
|
@@ -8150,7 +8236,7 @@ function usePropertyHandlers(input) {
|
|
|
8150
8236
|
width: canvasSize.width,
|
|
8151
8237
|
height: canvasSize.height
|
|
8152
8238
|
};
|
|
8153
|
-
setCompareResult(
|
|
8239
|
+
setCompareResult(chunkMH4VFSDL_js.comparePresentation(cur, other));
|
|
8154
8240
|
setIsComparePanelOpen(true);
|
|
8155
8241
|
} catch (err) {
|
|
8156
8242
|
console.warn("Compare failed:", err);
|
|
@@ -8167,7 +8253,7 @@ function usePropertyHandlers(input) {
|
|
|
8167
8253
|
if (!diff || diff.status === "unchanged") {
|
|
8168
8254
|
return;
|
|
8169
8255
|
}
|
|
8170
|
-
setSlides((prev) =>
|
|
8256
|
+
setSlides((prev) => chunkMH4VFSDL_js.applyAcceptSlide(prev, diff));
|
|
8171
8257
|
setIsDirty(true);
|
|
8172
8258
|
},
|
|
8173
8259
|
[compareResult, setSlides, setIsDirty]
|
|
@@ -8178,10 +8264,10 @@ function usePropertyHandlers(input) {
|
|
|
8178
8264
|
if (!compareResult) {
|
|
8179
8265
|
return;
|
|
8180
8266
|
}
|
|
8181
|
-
setSlides((prev) =>
|
|
8267
|
+
setSlides((prev) => chunkMH4VFSDL_js.applyAcceptAllSlides(prev, compareResult));
|
|
8182
8268
|
setIsDirty(true);
|
|
8183
8269
|
}, [compareResult, setSlides, setIsDirty]);
|
|
8184
|
-
const usedFontFamilies = react.useMemo(() =>
|
|
8270
|
+
const usedFontFamilies = react.useMemo(() => chunkMH4VFSDL_js.collectUsedFonts(slides), [slides]);
|
|
8185
8271
|
return {
|
|
8186
8272
|
handleUpdateNotes,
|
|
8187
8273
|
handleUpdateSlide,
|
|
@@ -8336,7 +8422,7 @@ function useViewerDialogs(input) {
|
|
|
8336
8422
|
);
|
|
8337
8423
|
const embeddedFontKey = (embeddedFontFamilies ?? []).join("\0");
|
|
8338
8424
|
const fontEmbedding = react.useMemo(
|
|
8339
|
-
() =>
|
|
8425
|
+
() => chunkMH4VFSDL_js.describeFontEmbedding(embeddedFontKey ? embeddedFontKey.split("\0") : []),
|
|
8340
8426
|
[embeddedFontKey]
|
|
8341
8427
|
);
|
|
8342
8428
|
const [embedFontsEnabled, setEmbedFontsEnabled] = react.useState(fontEmbedding.initialEnabled);
|
|
@@ -8346,11 +8432,11 @@ function useViewerDialogs(input) {
|
|
|
8346
8432
|
setEmbedFontsEnabled(fontEmbedding.initialEnabled);
|
|
8347
8433
|
}
|
|
8348
8434
|
const [isNarrowViewport, setIsNarrowViewport] = react.useState(
|
|
8349
|
-
() => typeof window !== "undefined" ?
|
|
8435
|
+
() => typeof window !== "undefined" ? chunkMH4VFSDL_js.isMobileViewport(window.innerWidth, window.innerHeight, viewportIsTouch()) : false
|
|
8350
8436
|
);
|
|
8351
8437
|
react.useEffect(() => {
|
|
8352
8438
|
const handleWindow = () => setIsNarrowViewport(
|
|
8353
|
-
|
|
8439
|
+
chunkMH4VFSDL_js.isMobileViewport(window.innerWidth, window.innerHeight, viewportIsTouch())
|
|
8354
8440
|
);
|
|
8355
8441
|
window.addEventListener("resize", handleWindow);
|
|
8356
8442
|
return () => window.removeEventListener("resize", handleWindow);
|
|
@@ -8503,16 +8589,16 @@ function useViewerDialogs(input) {
|
|
|
8503
8589
|
};
|
|
8504
8590
|
}
|
|
8505
8591
|
function computeGridSpacingPx2(documentGridSpacing) {
|
|
8506
|
-
return
|
|
8592
|
+
return chunkMH4VFSDL_js.computeGridSpacingPx(documentGridSpacing, chunkH4LMXJ2Z_js.GRID_SIZE);
|
|
8507
8593
|
}
|
|
8508
8594
|
function computeVisibleSlideIndexes(slides, activeCustomShowId, customShows, presentationProperties) {
|
|
8509
8595
|
const activeShow = activeCustomShowId ? customShows.find((show) => show.id === activeCustomShowId) : void 0;
|
|
8510
|
-
const authoredRange =
|
|
8511
|
-
return
|
|
8596
|
+
const authoredRange = chunkMH4VFSDL_js.resolveAuthoredSlideRange(presentationProperties, slides.length);
|
|
8597
|
+
return chunkMH4VFSDL_js.resolveShowSlideIndexes(slides, activeShow, authoredRange);
|
|
8512
8598
|
}
|
|
8513
8599
|
function computeSlideSectionGroups(slides, sections) {
|
|
8514
|
-
return
|
|
8515
|
-
id: group.section?.id ?? (sections.length > 0 ?
|
|
8600
|
+
return chunkMH4VFSDL_js.groupSlidesBySection(sections, slides).map((group) => ({
|
|
8601
|
+
id: group.section?.id ?? (sections.length > 0 ? chunkH4LMXJ2Z_js.UNGROUPED_SECTION_ID : chunkH4LMXJ2Z_js.DEFAULT_SECTION_GROUP_ID),
|
|
8516
8602
|
label: group.section?.name ?? (sections.length > 0 ? "Ungrouped Slides" : "Slides"),
|
|
8517
8603
|
slideIndexes: group.slideIndexes,
|
|
8518
8604
|
...group.section?.color !== void 0 ? { color: group.section.color } : {},
|
|
@@ -8524,7 +8610,7 @@ function computeMasterPseudoSlide(mode, activeLayout, activeMaster) {
|
|
|
8524
8610
|
return void 0;
|
|
8525
8611
|
}
|
|
8526
8612
|
const document2 = activeLayout ? { slideMasters: [{ ...activeMaster, layouts: [activeLayout] }] } : { slideMasters: [activeMaster] };
|
|
8527
|
-
return
|
|
8613
|
+
return chunkMH4VFSDL_js.masterViewPseudoSlide(document2, {
|
|
8528
8614
|
tab: "slides",
|
|
8529
8615
|
masterIndex: 0,
|
|
8530
8616
|
layoutIndex: activeLayout ? 0 : null
|
|
@@ -8552,15 +8638,15 @@ function useDerivedSlideState(input) {
|
|
|
8552
8638
|
[slides, activeCustomShowId, customShows, presentationProperties]
|
|
8553
8639
|
);
|
|
8554
8640
|
const authoredRange = react.useMemo(
|
|
8555
|
-
() =>
|
|
8641
|
+
() => chunkMH4VFSDL_js.resolveAuthoredSlideRange(presentationProperties, slides.length),
|
|
8556
8642
|
[presentationProperties, slides.length]
|
|
8557
8643
|
);
|
|
8558
8644
|
const slideSectionGroups = react.useMemo(
|
|
8559
8645
|
() => computeSlideSectionGroups(slides, sections).map((group) => {
|
|
8560
|
-
if (group.id ===
|
|
8646
|
+
if (group.id === chunkH4LMXJ2Z_js.UNGROUPED_SECTION_ID && group.label === "Ungrouped Slides") {
|
|
8561
8647
|
return { ...group, label: t("pptx.slides.ungroupedSlides") };
|
|
8562
8648
|
}
|
|
8563
|
-
if (group.id ===
|
|
8649
|
+
if (group.id === chunkH4LMXJ2Z_js.DEFAULT_SECTION_GROUP_ID && group.label === "Slides") {
|
|
8564
8650
|
return { ...group, label: t("pptx.sections.slides") };
|
|
8565
8651
|
}
|
|
8566
8652
|
return group;
|
|
@@ -8661,13 +8747,13 @@ function useAnnotationHandlers(input) {
|
|
|
8661
8747
|
}, [annotations, setMode, setSlides, history]);
|
|
8662
8748
|
const handleSetMode = react.useCallback(
|
|
8663
8749
|
(nextMode) => {
|
|
8664
|
-
if (mode === "present" && nextMode !== "present" && !
|
|
8750
|
+
if (mode === "present" && nextMode !== "present" && !chunkMH4VFSDL_js.mayLeaveSlideShow()) {
|
|
8665
8751
|
return;
|
|
8666
8752
|
}
|
|
8667
8753
|
if (nextMode === "present") {
|
|
8668
8754
|
presentation.enterPresentMode();
|
|
8669
8755
|
} else if (mode === "present" && annotations.hasAnyAnnotations) {
|
|
8670
|
-
|
|
8756
|
+
chunkMH4VFSDL_js.stopAllPersistentAudio();
|
|
8671
8757
|
if (promptKeepInkAnnotations) {
|
|
8672
8758
|
pendingModeAfterAnnotationsRef.current = nextMode;
|
|
8673
8759
|
setShowKeepAnnotationsDialog(true);
|
|
@@ -8677,7 +8763,7 @@ function useAnnotationHandlers(input) {
|
|
|
8677
8763
|
}
|
|
8678
8764
|
} else {
|
|
8679
8765
|
if (mode === "present") {
|
|
8680
|
-
|
|
8766
|
+
chunkMH4VFSDL_js.stopAllPersistentAudio();
|
|
8681
8767
|
}
|
|
8682
8768
|
setMode(nextMode);
|
|
8683
8769
|
}
|
|
@@ -8746,13 +8832,13 @@ function useSerialize(input) {
|
|
|
8746
8832
|
let processedSlide = slide;
|
|
8747
8833
|
if (pendingEditId) {
|
|
8748
8834
|
const updatedElements = slide.elements.map((el) => {
|
|
8749
|
-
if (el.id !== pendingEditId || !
|
|
8835
|
+
if (el.id !== pendingEditId || !chunkMH4VFSDL_js.hasTextProperties(el)) {
|
|
8750
8836
|
return el;
|
|
8751
8837
|
}
|
|
8752
8838
|
return {
|
|
8753
8839
|
...el,
|
|
8754
8840
|
text: pendingEditText,
|
|
8755
|
-
textSegments:
|
|
8841
|
+
textSegments: chunkMH4VFSDL_js.remapTextToSegments(pendingEditText, el.textSegments, el.textStyle)
|
|
8756
8842
|
};
|
|
8757
8843
|
});
|
|
8758
8844
|
if (updatedElements.some((el, i) => el !== slide.elements[i])) {
|
|
@@ -8765,19 +8851,19 @@ function useSerialize(input) {
|
|
|
8765
8851
|
const pptxGuides = guides.map((g) => ({
|
|
8766
8852
|
id: g.id,
|
|
8767
8853
|
orientation: g.axis === "h" ? "horz" : "vert",
|
|
8768
|
-
positionEmu:
|
|
8854
|
+
positionEmu: chunkMH4VFSDL_js.guidePxToEmu(g.position)
|
|
8769
8855
|
}));
|
|
8770
8856
|
return {
|
|
8771
8857
|
...processedSlide,
|
|
8772
8858
|
guides: pptxGuides.length > 0 ? pptxGuides : void 0
|
|
8773
8859
|
};
|
|
8774
8860
|
});
|
|
8775
|
-
const slidesToSave =
|
|
8776
|
-
const saveOptions =
|
|
8861
|
+
const slidesToSave = chunkMH4VFSDL_js.buildSaveSlides(slidesWithGuides, templateElementsBySlideId);
|
|
8862
|
+
const saveOptions = chunkMH4VFSDL_js.buildDeckSaveOptions({
|
|
8777
8863
|
// Without this the Slide Size card edited a viewer-only pixel value and
|
|
8778
8864
|
// the saved `p:sldSz` never moved: passing `slideSize` is the only way a
|
|
8779
8865
|
// slide-size edit reaches the file.
|
|
8780
|
-
slideSize:
|
|
8866
|
+
slideSize: chunkMH4VFSDL_js.resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size,
|
|
8781
8867
|
headerFooter,
|
|
8782
8868
|
presentationProperties,
|
|
8783
8869
|
viewProperties,
|
|
@@ -8796,7 +8882,7 @@ function useSerialize(input) {
|
|
|
8796
8882
|
embedFonts,
|
|
8797
8883
|
outputFormat: format
|
|
8798
8884
|
});
|
|
8799
|
-
return
|
|
8885
|
+
return chunkMH4VFSDL_js.saveDeckWithPassword(handler, slidesToSave, saveOptions, { password, purpose });
|
|
8800
8886
|
},
|
|
8801
8887
|
[
|
|
8802
8888
|
slides,
|
|
@@ -8837,7 +8923,7 @@ function useRecoveryDetection(input) {
|
|
|
8837
8923
|
const onRestore = input.onRestore;
|
|
8838
8924
|
const openVersionHistory = input.openVersionHistory;
|
|
8839
8925
|
react.useEffect(() => {
|
|
8840
|
-
if (!
|
|
8926
|
+
if (!chunkMH4VFSDL_js.shouldProbeAutosaveRecovery({
|
|
8841
8927
|
alreadyChecked: recoveryCheckedRef.current,
|
|
8842
8928
|
filePath,
|
|
8843
8929
|
loading,
|
|
@@ -8849,7 +8935,7 @@ function useRecoveryDetection(input) {
|
|
|
8849
8935
|
}
|
|
8850
8936
|
recoveryCheckedRef.current = true;
|
|
8851
8937
|
void (async () => {
|
|
8852
|
-
const offer = await
|
|
8938
|
+
const offer = await chunkMH4VFSDL_js.probeAutosaveRecovery(filePath);
|
|
8853
8939
|
if (!offer) {
|
|
8854
8940
|
return;
|
|
8855
8941
|
}
|
|
@@ -8862,7 +8948,7 @@ function useRecoveryDetection(input) {
|
|
|
8862
8948
|
const record = recordRef.current;
|
|
8863
8949
|
setPrompt(null);
|
|
8864
8950
|
if (record && onRestore) {
|
|
8865
|
-
onRestore(
|
|
8951
|
+
onRestore(chunkMH4VFSDL_js.acceptAutosaveRecovery(record));
|
|
8866
8952
|
}
|
|
8867
8953
|
recordRef.current = null;
|
|
8868
8954
|
}, [onRestore]);
|
|
@@ -8871,7 +8957,7 @@ function useRecoveryDetection(input) {
|
|
|
8871
8957
|
setPrompt(null);
|
|
8872
8958
|
recordRef.current = null;
|
|
8873
8959
|
if (record) {
|
|
8874
|
-
void
|
|
8960
|
+
void chunkMH4VFSDL_js.discardAutosaveRecovery(record);
|
|
8875
8961
|
}
|
|
8876
8962
|
}, []);
|
|
8877
8963
|
return { prompt, restore, discard };
|
|
@@ -8922,11 +9008,11 @@ function usePresentationSetup(input) {
|
|
|
8922
9008
|
containerRef,
|
|
8923
9009
|
content,
|
|
8924
9010
|
onSetMode: (nextMode) => {
|
|
8925
|
-
if (mode === "present" && nextMode !== "present" && !
|
|
9011
|
+
if (mode === "present" && nextMode !== "present" && !chunkMH4VFSDL_js.mayLeaveSlideShow()) {
|
|
8926
9012
|
return;
|
|
8927
9013
|
}
|
|
8928
9014
|
if (mode === "present" && nextMode !== "present") {
|
|
8929
|
-
|
|
9015
|
+
chunkMH4VFSDL_js.stopAllPersistentAudio();
|
|
8930
9016
|
stopAnimationSound();
|
|
8931
9017
|
const exitHandler = exitModeHandlerRef.current;
|
|
8932
9018
|
if (exitHandler) {
|
|
@@ -8994,10 +9080,10 @@ function usePresentationSetup(input) {
|
|
|
8994
9080
|
onToggleToolbar: () => annotations.setToolbarVisible(!annotations.toolbarVisible),
|
|
8995
9081
|
onToggleSubtitles,
|
|
8996
9082
|
onSaveRehearsalTimings: (timings) => {
|
|
8997
|
-
setSlides((prev) =>
|
|
9083
|
+
setSlides((prev) => chunkMH4VFSDL_js.applyRehearsalTimings(prev, timings));
|
|
8998
9084
|
history.markDirty();
|
|
8999
9085
|
},
|
|
9000
|
-
loopContinuously:
|
|
9086
|
+
loopContinuously: chunkMH4VFSDL_js.shouldLoopContinuously(presentationProperties),
|
|
9001
9087
|
showWithAnimation: presentationProperties.showWithAnimation,
|
|
9002
9088
|
useTimings: presentationProperties.advanceMode !== "manual",
|
|
9003
9089
|
endWithBlackSlide,
|
|
@@ -9204,7 +9290,7 @@ function useEditorOperations(input) {
|
|
|
9204
9290
|
const { formatPainterActive, setFormatPainterActive, elementLookup } = state;
|
|
9205
9291
|
react.useEffect(() => {
|
|
9206
9292
|
if (formatPainterActive && !prevFormatPainterRef.current && selectedElement) {
|
|
9207
|
-
copiedFormatRef.current =
|
|
9293
|
+
copiedFormatRef.current = chunkMH4VFSDL_js.copyFormatFromElement(selectedElement);
|
|
9208
9294
|
} else if (!formatPainterActive) {
|
|
9209
9295
|
copiedFormatRef.current = null;
|
|
9210
9296
|
}
|
|
@@ -9230,12 +9316,12 @@ function useEditorOperations(input) {
|
|
|
9230
9316
|
e.stopPropagation();
|
|
9231
9317
|
const element = elementLookup.get(elementId);
|
|
9232
9318
|
if (element) {
|
|
9233
|
-
const updated =
|
|
9319
|
+
const updated = chunkMH4VFSDL_js.applyFormatToElement(element, copiedFormatRef.current);
|
|
9234
9320
|
const updates = {};
|
|
9235
|
-
if (
|
|
9321
|
+
if (chunkMH4VFSDL_js.hasShapeProperties(updated)) {
|
|
9236
9322
|
updates.shapeStyle = updated.shapeStyle;
|
|
9237
9323
|
}
|
|
9238
|
-
if (
|
|
9324
|
+
if (chunkMH4VFSDL_js.hasTextProperties(updated)) {
|
|
9239
9325
|
updates.textStyle = updated.textStyle;
|
|
9240
9326
|
}
|
|
9241
9327
|
ops.updateElementById(elementId, updates);
|
|
@@ -9286,7 +9372,8 @@ function useIOHandlers(input) {
|
|
|
9286
9372
|
serializeForRecovery,
|
|
9287
9373
|
setContent,
|
|
9288
9374
|
onContentChange,
|
|
9289
|
-
imageExportScale
|
|
9375
|
+
imageExportScale,
|
|
9376
|
+
imageResolutionScale
|
|
9290
9377
|
} = input;
|
|
9291
9378
|
const exportHandlers = useExportHandlers({
|
|
9292
9379
|
slides,
|
|
@@ -9310,7 +9397,8 @@ function useIOHandlers(input) {
|
|
|
9310
9397
|
theme: state.theme,
|
|
9311
9398
|
canvasSize,
|
|
9312
9399
|
slideSizeEmu: state.slideSizeEmu,
|
|
9313
|
-
imageExportScale
|
|
9400
|
+
imageExportScale,
|
|
9401
|
+
imageResolutionScale
|
|
9314
9402
|
});
|
|
9315
9403
|
const printHandlers = usePrintHandlers({
|
|
9316
9404
|
slides,
|
|
@@ -9419,10 +9507,10 @@ function useFontInjection({ embeddedFonts, slides }) {
|
|
|
9419
9507
|
}
|
|
9420
9508
|
};
|
|
9421
9509
|
}, [embeddedFonts]);
|
|
9422
|
-
const referencedFamilies = react.useMemo(() =>
|
|
9510
|
+
const referencedFamilies = react.useMemo(() => chunkMH4VFSDL_js.collectReferencedFontFamilies(slides), [slides]);
|
|
9423
9511
|
react.useEffect(() => {
|
|
9424
9512
|
let cancelled = false;
|
|
9425
|
-
void
|
|
9513
|
+
void chunkMH4VFSDL_js.resolveGoogleWebfontHref(slides, embeddedFonts).then((href) => {
|
|
9426
9514
|
if (cancelled) {
|
|
9427
9515
|
return null;
|
|
9428
9516
|
}
|
|
@@ -9444,6 +9532,52 @@ function useFontInjection({ embeddedFonts, slides }) {
|
|
|
9444
9532
|
}
|
|
9445
9533
|
};
|
|
9446
9534
|
}, [embeddedFonts, slides]);
|
|
9535
|
+
const [, setOutlineFontsTick] = react.useState(0);
|
|
9536
|
+
react.useEffect(() => {
|
|
9537
|
+
let cancelled = false;
|
|
9538
|
+
const referenced = chunkMH4VFSDL_js.collectReferencedFontFamilies(slides);
|
|
9539
|
+
const candidates = chunkMH4VFSDL_js.selectGoogleWebfontFamilies(
|
|
9540
|
+
referenced,
|
|
9541
|
+
embeddedFonts.map((font) => font.name)
|
|
9542
|
+
);
|
|
9543
|
+
if (candidates.length === 0) {
|
|
9544
|
+
return;
|
|
9545
|
+
}
|
|
9546
|
+
void chunkMH4VFSDL_js.resolveGoogleWebfontHref(slides, embeddedFonts).then(async (href) => {
|
|
9547
|
+
if (cancelled || !href) {
|
|
9548
|
+
return;
|
|
9549
|
+
}
|
|
9550
|
+
const boldItalicVariants = [
|
|
9551
|
+
{ bold: false, italic: false },
|
|
9552
|
+
{ bold: true, italic: false }
|
|
9553
|
+
];
|
|
9554
|
+
let registeredAny = false;
|
|
9555
|
+
for (const family of candidates) {
|
|
9556
|
+
for (const variant of boldItalicVariants) {
|
|
9557
|
+
if (cancelled) {
|
|
9558
|
+
return;
|
|
9559
|
+
}
|
|
9560
|
+
const bytes = await chunkMH4VFSDL_js.fetchGoogleWebfontOutlineBytes(
|
|
9561
|
+
href,
|
|
9562
|
+
family,
|
|
9563
|
+
variant.bold,
|
|
9564
|
+
variant.italic,
|
|
9565
|
+
fetch
|
|
9566
|
+
);
|
|
9567
|
+
if (bytes && glyphOutlineFontCache.registerFontBytes(family, variant.bold, variant.italic, bytes)) {
|
|
9568
|
+
registeredAny = true;
|
|
9569
|
+
}
|
|
9570
|
+
}
|
|
9571
|
+
}
|
|
9572
|
+
if (registeredAny && !cancelled) {
|
|
9573
|
+
setOutlineFontsTick((tick) => tick + 1);
|
|
9574
|
+
}
|
|
9575
|
+
return void 0;
|
|
9576
|
+
});
|
|
9577
|
+
return () => {
|
|
9578
|
+
cancelled = true;
|
|
9579
|
+
};
|
|
9580
|
+
}, [embeddedFonts, slides]);
|
|
9447
9581
|
react.useEffect(() => {
|
|
9448
9582
|
const neededSymbolFonts = SYMBOL_FONT_FAMILIES.filter((f) => referencedFamilies.has(f));
|
|
9449
9583
|
if (neededSymbolFonts.length === 0) {
|
|
@@ -9612,7 +9746,7 @@ function useKeyboardShortcuts(input) {
|
|
|
9612
9746
|
inputRef.current = input;
|
|
9613
9747
|
const handleKeyDown = react.useCallback((e) => {
|
|
9614
9748
|
const current = inputRef.current;
|
|
9615
|
-
const startAction =
|
|
9749
|
+
const startAction = chunkMH4VFSDL_js.mapSlideShowStartKey(e, { isPresenting: current.mode === "present" });
|
|
9616
9750
|
if (startAction !== null) {
|
|
9617
9751
|
e.preventDefault();
|
|
9618
9752
|
if (startAction === "fromBeginning") {
|
|
@@ -9622,7 +9756,7 @@ function useKeyboardShortcuts(input) {
|
|
|
9622
9756
|
}
|
|
9623
9757
|
return;
|
|
9624
9758
|
}
|
|
9625
|
-
const { action, dx, dy } =
|
|
9759
|
+
const { action, dx, dy } = chunkMH4VFSDL_js.mapEditorKey(e, {
|
|
9626
9760
|
canEdit: current.canEdit,
|
|
9627
9761
|
// The Slide Master view is an editing surface, not a viewing one.
|
|
9628
9762
|
// Gating on `mode !== 'edit'` alone made `mapEditorKey` return
|
|
@@ -9635,7 +9769,7 @@ function useKeyboardShortcuts(input) {
|
|
|
9635
9769
|
hasSelection: current.hasSelection,
|
|
9636
9770
|
isEditingText: Boolean(current.inlineEditingElementId || current.tableEditorState?.isEditing),
|
|
9637
9771
|
isDrawing: current.activeTool !== "select",
|
|
9638
|
-
isTextInputTarget:
|
|
9772
|
+
isTextInputTarget: chunkMH4VFSDL_js.isEditorTextInputTarget(e.target)
|
|
9639
9773
|
});
|
|
9640
9774
|
if (action === null) {
|
|
9641
9775
|
return;
|
|
@@ -9811,6 +9945,7 @@ function useViewerIntegration(input) {
|
|
|
9811
9945
|
canEdit,
|
|
9812
9946
|
promptKeepInkAnnotations,
|
|
9813
9947
|
imageExportScale,
|
|
9948
|
+
imageResolutionScale,
|
|
9814
9949
|
mode,
|
|
9815
9950
|
slides,
|
|
9816
9951
|
activeSlide,
|
|
@@ -9896,7 +10031,8 @@ function useViewerIntegration(input) {
|
|
|
9896
10031
|
serializeForRecovery,
|
|
9897
10032
|
setContent,
|
|
9898
10033
|
onContentChange,
|
|
9899
|
-
imageExportScale
|
|
10034
|
+
imageExportScale,
|
|
10035
|
+
imageResolutionScale
|
|
9900
10036
|
});
|
|
9901
10037
|
const {
|
|
9902
10038
|
showKeepAnnotationsDialog,
|
|
@@ -9965,7 +10101,7 @@ function useViewerIntegration(input) {
|
|
|
9965
10101
|
return zoom.scale;
|
|
9966
10102
|
},
|
|
9967
10103
|
setZoom(level) {
|
|
9968
|
-
zoom.setScale(
|
|
10104
|
+
zoom.setScale(chunkMH4VFSDL_js.clampZoomScale(level));
|
|
9969
10105
|
},
|
|
9970
10106
|
zoomIn() {
|
|
9971
10107
|
zoom.handleZoomIn();
|
|
@@ -10183,7 +10319,7 @@ function useReducedMotion() {
|
|
|
10183
10319
|
}
|
|
10184
10320
|
function useViewerOptions() {
|
|
10185
10321
|
const storeRef = react.useRef(null);
|
|
10186
|
-
storeRef.current ??=
|
|
10322
|
+
storeRef.current ??= chunkMH4VFSDL_js.createViewerOptionsStore();
|
|
10187
10323
|
const store = storeRef.current;
|
|
10188
10324
|
const options = react.useSyncExternalStore(
|
|
10189
10325
|
(onStoreChange) => store.subscribe(onStoreChange),
|
|
@@ -10192,9 +10328,9 @@ function useViewerOptions() {
|
|
|
10192
10328
|
);
|
|
10193
10329
|
return { optionsStore: store, options };
|
|
10194
10330
|
}
|
|
10195
|
-
var KNOWN_TAB_IDS = new Set(
|
|
10331
|
+
var KNOWN_TAB_IDS = new Set(chunkMH4VFSDL_js.TOOLBAR_TABS.map((tab) => tab.id));
|
|
10196
10332
|
function computeToolbarVisibility(hiddenActions, hiddenTabIds = []) {
|
|
10197
|
-
const isHidden = (id) =>
|
|
10333
|
+
const isHidden = (id) => chunkMH4VFSDL_js.isActionHidden(id, hiddenActions);
|
|
10198
10334
|
const userHidden = new Set(hiddenTabIds);
|
|
10199
10335
|
userHidden.delete("file");
|
|
10200
10336
|
const isTabVisible = (id) => !KNOWN_TAB_IDS.has(id) || !isHidden(id) && !userHidden.has(id);
|
|
@@ -10287,12 +10423,12 @@ function useYjsDocumentSync({
|
|
|
10287
10423
|
return;
|
|
10288
10424
|
}
|
|
10289
10425
|
try {
|
|
10290
|
-
const handler = new
|
|
10426
|
+
const handler = new chunkMH4VFSDL_js.PptxHandler();
|
|
10291
10427
|
await handler.load(sourceBytes.buffer);
|
|
10292
|
-
const currentSlides =
|
|
10428
|
+
const currentSlides = chunkMH4VFSDL_js.readSlidesFromYDoc(
|
|
10293
10429
|
doc
|
|
10294
10430
|
);
|
|
10295
|
-
const slidesToSave =
|
|
10431
|
+
const slidesToSave = chunkMH4VFSDL_js.buildSaveSlides(currentSlides, templateElementsBySlideId);
|
|
10296
10432
|
const bytes = await handler.save(slidesToSave, getSaveOptions?.());
|
|
10297
10433
|
config.onWriteBack(bytes);
|
|
10298
10434
|
} catch {
|
|
@@ -10307,10 +10443,10 @@ function useYjsDocumentSync({
|
|
|
10307
10443
|
if (!doc || !isConnected) {
|
|
10308
10444
|
return;
|
|
10309
10445
|
}
|
|
10310
|
-
const docSlides =
|
|
10446
|
+
const docSlides = chunkMH4VFSDL_js.readSlidesFromYDoc(
|
|
10311
10447
|
doc
|
|
10312
10448
|
);
|
|
10313
|
-
if (!
|
|
10449
|
+
if (!chunkMH4VFSDL_js.shouldRoomSlidesReplaceLoad(loadOrigin, docSlides.length)) {
|
|
10314
10450
|
return;
|
|
10315
10451
|
}
|
|
10316
10452
|
lastSyncedRef.current = JSON.stringify(docSlides);
|
|
@@ -10329,11 +10465,11 @@ function useYjsDocumentSync({
|
|
|
10329
10465
|
lastSyncedRef.current = serialized;
|
|
10330
10466
|
void (async () => {
|
|
10331
10467
|
const factories = await getFactories();
|
|
10332
|
-
|
|
10468
|
+
chunkMH4VFSDL_js.reconcileSlidesInYDoc(
|
|
10333
10469
|
slides,
|
|
10334
10470
|
doc,
|
|
10335
10471
|
factories,
|
|
10336
|
-
|
|
10472
|
+
chunkMH4VFSDL_js.LOCAL_SYNC_ORIGIN
|
|
10337
10473
|
);
|
|
10338
10474
|
scheduleWriteBack();
|
|
10339
10475
|
})();
|
|
@@ -10347,10 +10483,10 @@ function useYjsDocumentSync({
|
|
|
10347
10483
|
return;
|
|
10348
10484
|
}
|
|
10349
10485
|
const handleChange = (_events, transaction) => {
|
|
10350
|
-
if (transaction?.origin ===
|
|
10486
|
+
if (transaction?.origin === chunkMH4VFSDL_js.LOCAL_SYNC_ORIGIN) {
|
|
10351
10487
|
return;
|
|
10352
10488
|
}
|
|
10353
|
-
const remoteSlides =
|
|
10489
|
+
const remoteSlides = chunkMH4VFSDL_js.readSlidesFromYDoc(
|
|
10354
10490
|
doc
|
|
10355
10491
|
);
|
|
10356
10492
|
if (remoteSlides.length === 0) {
|
|
@@ -10366,7 +10502,7 @@ function useYjsDocumentSync({
|
|
|
10366
10502
|
isApplyingRemoteRef.current = false;
|
|
10367
10503
|
scheduleWriteBack();
|
|
10368
10504
|
};
|
|
10369
|
-
const unobserve =
|
|
10505
|
+
const unobserve = chunkMH4VFSDL_js.observeYDocSlides(
|
|
10370
10506
|
doc,
|
|
10371
10507
|
handleChange
|
|
10372
10508
|
);
|
|
@@ -10404,7 +10540,7 @@ function useBroadcastFollower({
|
|
|
10404
10540
|
if (!broadcaster) {
|
|
10405
10541
|
return;
|
|
10406
10542
|
}
|
|
10407
|
-
if (!
|
|
10543
|
+
if (!chunkMH4VFSDL_js.shouldAutoFollowBroadcaster({
|
|
10408
10544
|
localRole: collab.config.role,
|
|
10409
10545
|
broadcasterRole: broadcaster.role
|
|
10410
10546
|
})) {
|
|
@@ -10562,7 +10698,7 @@ function useLayoutSwitching(input) {
|
|
|
10562
10698
|
currentLayoutPath
|
|
10563
10699
|
};
|
|
10564
10700
|
}
|
|
10565
|
-
var MIN_TOUCH_TARGET =
|
|
10701
|
+
var MIN_TOUCH_TARGET = chunkMH4VFSDL_js.MIN_TOUCH_TARGET_PX;
|
|
10566
10702
|
function subscribeTouchCapability(callback) {
|
|
10567
10703
|
if (typeof window === "undefined") {
|
|
10568
10704
|
return () => {
|
|
@@ -10575,7 +10711,7 @@ function subscribeTouchCapability(callback) {
|
|
|
10575
10711
|
function useIsMobile() {
|
|
10576
10712
|
const isTouchDevice = react.useSyncExternalStore(
|
|
10577
10713
|
subscribeTouchCapability,
|
|
10578
|
-
|
|
10714
|
+
chunkMH4VFSDL_js.detectTouchDevice,
|
|
10579
10715
|
() => false
|
|
10580
10716
|
// server snapshot
|
|
10581
10717
|
);
|
|
@@ -10585,7 +10721,7 @@ function useIsMobile() {
|
|
|
10585
10721
|
const [viewportHeight, setViewportHeight] = react.useState(
|
|
10586
10722
|
() => typeof window === "undefined" ? 768 : window.innerHeight
|
|
10587
10723
|
);
|
|
10588
|
-
const [orientation, setOrientation] = react.useState(
|
|
10724
|
+
const [orientation, setOrientation] = react.useState(chunkMH4VFSDL_js.detectOrientation);
|
|
10589
10725
|
const [isVirtualKeyboardOpen, setIsVirtualKeyboardOpen] = react.useState(false);
|
|
10590
10726
|
const [initialViewportHeight] = react.useState(
|
|
10591
10727
|
() => typeof window !== "undefined" ? window.innerHeight : 800
|
|
@@ -10606,7 +10742,7 @@ function useIsMobile() {
|
|
|
10606
10742
|
return;
|
|
10607
10743
|
}
|
|
10608
10744
|
const handleOrientationChange = () => {
|
|
10609
|
-
setOrientation(
|
|
10745
|
+
setOrientation(chunkMH4VFSDL_js.detectOrientation());
|
|
10610
10746
|
};
|
|
10611
10747
|
if (screen.orientation) {
|
|
10612
10748
|
screen.orientation.addEventListener("change", handleOrientationChange);
|
|
@@ -10636,7 +10772,7 @@ function useIsMobile() {
|
|
|
10636
10772
|
window.addEventListener("resize", handleResize);
|
|
10637
10773
|
return () => window.removeEventListener("resize", handleResize);
|
|
10638
10774
|
}, [isTouchDevice, initialViewportHeight]);
|
|
10639
|
-
const { isMobile, isTablet, isDesktop } =
|
|
10775
|
+
const { isMobile, isTablet, isDesktop } = chunkMH4VFSDL_js.deriveViewportBreakpoints(
|
|
10640
10776
|
viewportWidth,
|
|
10641
10777
|
viewportHeight,
|
|
10642
10778
|
isTouchDevice
|
|
@@ -10647,7 +10783,9 @@ function useIsMobile() {
|
|
|
10647
10783
|
isDesktop,
|
|
10648
10784
|
isTouchDevice,
|
|
10649
10785
|
orientation,
|
|
10650
|
-
isVirtualKeyboardOpen
|
|
10786
|
+
isVirtualKeyboardOpen,
|
|
10787
|
+
viewportWidth,
|
|
10788
|
+
viewportHeight
|
|
10651
10789
|
};
|
|
10652
10790
|
}
|
|
10653
10791
|
function useTouchGestures(input) {
|
|
@@ -10667,10 +10805,10 @@ function useTouchGestures(input) {
|
|
|
10667
10805
|
if (!el || !enabled) {
|
|
10668
10806
|
return;
|
|
10669
10807
|
}
|
|
10670
|
-
const recognizer =
|
|
10808
|
+
const recognizer = chunkMH4VFSDL_js.createTouchGestureRecognizer({
|
|
10671
10809
|
getScale: () => scaleRef.current,
|
|
10672
|
-
minScale:
|
|
10673
|
-
maxScale:
|
|
10810
|
+
minScale: chunkMH4VFSDL_js.MIN_ZOOM_SCALE,
|
|
10811
|
+
maxScale: chunkMH4VFSDL_js.MAX_ZOOM_SCALE,
|
|
10674
10812
|
callbacks: {
|
|
10675
10813
|
onPinchZoom: (newScale) => callbacksRef.current.onPinchZoom?.(newScale),
|
|
10676
10814
|
onSwipe: (direction) => callbacksRef.current.onSwipe?.(direction),
|
|
@@ -10710,7 +10848,7 @@ function scrollFocusedIntoView(keyboardInset) {
|
|
|
10710
10848
|
return;
|
|
10711
10849
|
}
|
|
10712
10850
|
const rect = active.getBoundingClientRect();
|
|
10713
|
-
const delta =
|
|
10851
|
+
const delta = chunkMH4VFSDL_js.computeScrollDelta(
|
|
10714
10852
|
{ top: rect.top, bottom: rect.bottom },
|
|
10715
10853
|
window.innerHeight,
|
|
10716
10854
|
keyboardInset
|
|
@@ -10730,8 +10868,8 @@ function useKeyboardInsets(enabled = true) {
|
|
|
10730
10868
|
return;
|
|
10731
10869
|
}
|
|
10732
10870
|
const update = () => {
|
|
10733
|
-
const metrics =
|
|
10734
|
-
const inset = metrics ?
|
|
10871
|
+
const metrics = chunkMH4VFSDL_js.readViewportMetrics(window);
|
|
10872
|
+
const inset = metrics ? chunkMH4VFSDL_js.computeKeyboardInset(metrics) : 0;
|
|
10735
10873
|
setKeyboardInset(inset);
|
|
10736
10874
|
if (inset > 0) {
|
|
10737
10875
|
window.requestAnimationFrame(() => scrollFocusedIntoView(inset));
|
|
@@ -10742,8 +10880,8 @@ function useKeyboardInsets(enabled = true) {
|
|
|
10742
10880
|
vv.addEventListener("scroll", update);
|
|
10743
10881
|
const onFocusIn = () => {
|
|
10744
10882
|
window.requestAnimationFrame(() => {
|
|
10745
|
-
const metrics =
|
|
10746
|
-
const inset = metrics ?
|
|
10883
|
+
const metrics = chunkMH4VFSDL_js.readViewportMetrics(window);
|
|
10884
|
+
const inset = metrics ? chunkMH4VFSDL_js.computeKeyboardInset(metrics) : 0;
|
|
10747
10885
|
if (inset > 0) {
|
|
10748
10886
|
scrollFocusedIntoView(inset);
|
|
10749
10887
|
}
|
|
@@ -10756,7 +10894,7 @@ function useKeyboardInsets(enabled = true) {
|
|
|
10756
10894
|
document.removeEventListener("focusin", onFocusIn);
|
|
10757
10895
|
};
|
|
10758
10896
|
}, [enabled]);
|
|
10759
|
-
return { keyboardInset, isKeyboardOpen:
|
|
10897
|
+
return { keyboardInset, isKeyboardOpen: chunkMH4VFSDL_js.isKeyboardOpen(keyboardInset) };
|
|
10760
10898
|
}
|
|
10761
10899
|
|
|
10762
10900
|
// src/viewer/hooks/useViewerBuildingBlocks-canvas-props.ts
|
|
@@ -10785,21 +10923,21 @@ function buildCanvasProps(input) {
|
|
|
10785
10923
|
} = input;
|
|
10786
10924
|
const effectiveSlide = mode === "master" ? masterPseudoSlide : activeSlide;
|
|
10787
10925
|
const effectiveTemplateElements = mode === "master" ? s.activeLayout ? s.activeMaster?.elements ?? [] : [] : templateElements;
|
|
10788
|
-
const fieldContext =
|
|
10926
|
+
const fieldContext = chunkMH4VFSDL_js.buildFieldSubstitutionContext({
|
|
10789
10927
|
headerFooter: s.headerFooter,
|
|
10790
10928
|
customProperties: s.customProperties,
|
|
10791
10929
|
slide: activeSlide
|
|
10792
10930
|
});
|
|
10793
10931
|
const tableStyleContext = s.theme || s.tableStyleMap ? { theme: s.theme, tableStyleMap: s.tableStyleMap } : void 0;
|
|
10794
10932
|
const openExternalUrl = (url, target) => {
|
|
10795
|
-
if (
|
|
10933
|
+
if (chunkMH4VFSDL_js.shouldConfirmExternalHyperlink(viewerOptions, url) && !window.confirm(buildHyperlinkConfirmMessage(url))) {
|
|
10796
10934
|
return;
|
|
10797
10935
|
}
|
|
10798
|
-
|
|
10936
|
+
chunkMH4VFSDL_js.safeOpenUrl(url, target);
|
|
10799
10937
|
};
|
|
10800
10938
|
const handleActionClick = (elementId, action) => {
|
|
10801
10939
|
if (mode === "present") {
|
|
10802
|
-
const resolved =
|
|
10940
|
+
const resolved = chunkMH4VFSDL_js.resolvePresentationAction(action, { slideCount: slides.length });
|
|
10803
10941
|
if (resolved.intent.kind === "openUrl") {
|
|
10804
10942
|
openExternalUrl(resolved.intent.url);
|
|
10805
10943
|
return;
|
|
@@ -10810,9 +10948,9 @@ function buildCanvasProps(input) {
|
|
|
10810
10948
|
}
|
|
10811
10949
|
};
|
|
10812
10950
|
const handleHyperlinkClick = (url, target) => {
|
|
10813
|
-
if (
|
|
10951
|
+
if (chunkMH4VFSDL_js.isPpactionUrl(url)) {
|
|
10814
10952
|
if (mode === "present") {
|
|
10815
|
-
const parsed =
|
|
10953
|
+
const parsed = chunkMH4VFSDL_js.parsePpactionUrl(url);
|
|
10816
10954
|
if (parsed) {
|
|
10817
10955
|
presentation.handlePresentationAction({
|
|
10818
10956
|
action: parsed.action,
|
|
@@ -10918,7 +11056,7 @@ function buildCanvasProps(input) {
|
|
|
10918
11056
|
|
|
10919
11057
|
// src/viewer/hooks/useScopedLayoutOptions.ts
|
|
10920
11058
|
function scopeLayoutOptionsToActiveSlide(options, activeSlide) {
|
|
10921
|
-
return
|
|
11059
|
+
return chunkMH4VFSDL_js.scopeLayoutOptionsToSlide(options, activeSlide?.layoutPath);
|
|
10922
11060
|
}
|
|
10923
11061
|
|
|
10924
11062
|
// src/viewer/hooks/useViewerBuildingBlocks-toolbar-handlers.ts
|
|
@@ -10931,7 +11069,7 @@ function buildToolbarAnimationHandlers(input) {
|
|
|
10931
11069
|
const current = activeSlide.animations ?? [];
|
|
10932
11070
|
if (group === "motionPath") {
|
|
10933
11071
|
propertyHandlers.handleUpdateSlide({
|
|
10934
|
-
animations:
|
|
11072
|
+
animations: chunkMH4VFSDL_js.applyMotionPathPreset(current, selectedElement.id, preset)
|
|
10935
11073
|
});
|
|
10936
11074
|
return;
|
|
10937
11075
|
}
|
|
@@ -11127,7 +11265,7 @@ function buildToolbarProps(input) {
|
|
|
11127
11265
|
onOpenFile,
|
|
11128
11266
|
onOpenRecentFile,
|
|
11129
11267
|
onCreatePresentation: (templateId) => {
|
|
11130
|
-
s.setSlides(
|
|
11268
|
+
s.setSlides(chunkMH4VFSDL_js.createBackstagePresentation(templateId));
|
|
11131
11269
|
s.setActiveSlideIndex(0);
|
|
11132
11270
|
s.setSelectedElementId(null);
|
|
11133
11271
|
s.setSelectedElementIds([]);
|
|
@@ -11157,7 +11295,7 @@ function buildToolbarProps(input) {
|
|
|
11157
11295
|
loadLayoutPreviews: input.loadLayoutPreviews,
|
|
11158
11296
|
onInsertSlideFromLayout: slideOps.handleInsertSlideFromLayout,
|
|
11159
11297
|
onInsertSlideFromTemplate: slideOps.handleInsertSlideFromTemplate,
|
|
11160
|
-
templateScheme:
|
|
11298
|
+
templateScheme: chunkMH4VFSDL_js.templateSchemeFromTheme(s.theme?.colorScheme),
|
|
11161
11299
|
customShows: s.customShows,
|
|
11162
11300
|
activeCustomShowId: s.activeCustomShowId,
|
|
11163
11301
|
onSetActiveCustomShowId: s.setActiveCustomShowId,
|
|
@@ -11198,7 +11336,7 @@ function buildToolbarProps(input) {
|
|
|
11198
11336
|
isCommentsPanelOpen: s.isInspectorPaneOpen,
|
|
11199
11337
|
slideCommentCount: activeSlide?.comments?.length ?? 0,
|
|
11200
11338
|
formatPainterActive: s.formatPainterActive,
|
|
11201
|
-
canActivateFormatPainter:
|
|
11339
|
+
canActivateFormatPainter: chunkMH4VFSDL_js.hasCopyableFormat(selectedElement),
|
|
11202
11340
|
onToggleFormatPainter: () => s.setFormatPainterActive((p) => !p),
|
|
11203
11341
|
isSelectionPaneOpen: s.isSelectionPaneOpen,
|
|
11204
11342
|
onToggleSelectionPane: () => s.setIsSelectionPaneOpen((p) => !p),
|
|
@@ -11276,7 +11414,7 @@ function useViewerBuildingBlocksCore(input) {
|
|
|
11276
11414
|
headerFooter: state.headerFooter,
|
|
11277
11415
|
loading,
|
|
11278
11416
|
error,
|
|
11279
|
-
maxHistoryEntries:
|
|
11417
|
+
maxHistoryEntries: chunkMH4VFSDL_js.resolveHistoryDepth(viewerOptions),
|
|
11280
11418
|
hasActivePointerInteraction,
|
|
11281
11419
|
pointerCommitNonce: state.pointerCommitNonce,
|
|
11282
11420
|
onDirty: markDocumentDirty,
|
|
@@ -11301,7 +11439,7 @@ function useViewerBuildingBlocksCore(input) {
|
|
|
11301
11439
|
documentGridSpacing: state.viewProperties?.gridSpacing
|
|
11302
11440
|
});
|
|
11303
11441
|
const themeColorMap = react.useMemo(
|
|
11304
|
-
() => state.theme?.colorScheme ?
|
|
11442
|
+
() => state.theme?.colorScheme ? chunkMH4VFSDL_js.buildThemeColorMap(state.theme.colorScheme) : void 0,
|
|
11305
11443
|
[state.theme?.colorScheme]
|
|
11306
11444
|
);
|
|
11307
11445
|
const { presentation, annotations, actionSoundHandlerRef, setExitModeHandler } = usePresentationSetup({
|
|
@@ -11350,7 +11488,8 @@ function useViewerBuildingBlocksCore(input) {
|
|
|
11350
11488
|
gridSpacingPx,
|
|
11351
11489
|
// Multiplied against the pre-existing 2x baseline; see the matching
|
|
11352
11490
|
// comment in `PowerPointViewer.tsx`.
|
|
11353
|
-
imageExportScale: 2 *
|
|
11491
|
+
imageExportScale: 2 * chunkMH4VFSDL_js.resolveImageResolutionScale(viewerOptions),
|
|
11492
|
+
imageResolutionScale: chunkMH4VFSDL_js.resolveImageResolutionScale(viewerOptions),
|
|
11354
11493
|
viewerOptions
|
|
11355
11494
|
};
|
|
11356
11495
|
}
|
|
@@ -11366,7 +11505,7 @@ function useCompatibilityToastsState() {
|
|
|
11366
11505
|
}
|
|
11367
11506
|
function useReadOnlyRecommendationState(content) {
|
|
11368
11507
|
const [recommendation, setRecommendation] = react.useState(
|
|
11369
|
-
() =>
|
|
11508
|
+
() => chunkMH4VFSDL_js.readOnlyRecommendation(void 0)
|
|
11370
11509
|
);
|
|
11371
11510
|
const [modifyVerifier, setModifyVerifier] = react.useState(void 0);
|
|
11372
11511
|
const [bannerHidden, setBannerHidden] = react.useState(false);
|
|
@@ -11406,7 +11545,7 @@ function useReadOnlyRecommendationState(content) {
|
|
|
11406
11545
|
async (password) => {
|
|
11407
11546
|
setCheckingPassword(true);
|
|
11408
11547
|
try {
|
|
11409
|
-
const result = await
|
|
11548
|
+
const result = await chunkMH4VFSDL_js.checkModifyPassword(modifyVerifier, password);
|
|
11410
11549
|
if (result.ok) {
|
|
11411
11550
|
unlock();
|
|
11412
11551
|
} else {
|
|
@@ -11451,9 +11590,9 @@ function useViewPreferencesSync(input) {
|
|
|
11451
11590
|
setShowGuides
|
|
11452
11591
|
} = input;
|
|
11453
11592
|
react.useEffect(() => {
|
|
11454
|
-
const seeded =
|
|
11593
|
+
const seeded = chunkMH4VFSDL_js.viewerPreferencesFromViewProperties(
|
|
11455
11594
|
{ viewProperties },
|
|
11456
|
-
{ ...
|
|
11595
|
+
{ ...chunkMH4VFSDL_js.DEFAULT_VIEWER_PREFERENCES, snapToGrid, snapToObjects: snapToShape, showGuides }
|
|
11457
11596
|
);
|
|
11458
11597
|
setSnapToGrid(seeded.snapToGrid);
|
|
11459
11598
|
setSnapToShape(seeded.snapToObjects ?? snapToShape);
|
|
@@ -11463,7 +11602,7 @@ function useViewPreferencesSync(input) {
|
|
|
11463
11602
|
(prefsOverride) => {
|
|
11464
11603
|
setViewProperties((prev) => {
|
|
11465
11604
|
const merged = {
|
|
11466
|
-
...
|
|
11605
|
+
...chunkMH4VFSDL_js.DEFAULT_VIEWER_PREFERENCES,
|
|
11467
11606
|
snapToGrid,
|
|
11468
11607
|
snapToObjects: snapToShape,
|
|
11469
11608
|
showGuides,
|
|
@@ -11471,7 +11610,7 @@ function useViewPreferencesSync(input) {
|
|
|
11471
11610
|
gridSpacingCy: prev?.gridSpacing?.cy,
|
|
11472
11611
|
...prefsOverride
|
|
11473
11612
|
};
|
|
11474
|
-
const patch =
|
|
11613
|
+
const patch = chunkMH4VFSDL_js.viewPropertiesPatchFromPreferences(merged);
|
|
11475
11614
|
return {
|
|
11476
11615
|
...prev,
|
|
11477
11616
|
slideViewPr: { ...prev?.slideViewPr, ...patch.slideViewPr },
|
|
@@ -11533,6 +11672,7 @@ function useViewerBuildingBlocksState(input) {
|
|
|
11533
11672
|
actionSoundHandlerRef,
|
|
11534
11673
|
gridSpacingPx,
|
|
11535
11674
|
imageExportScale,
|
|
11675
|
+
imageResolutionScale,
|
|
11536
11676
|
setExitModeHandler,
|
|
11537
11677
|
viewerOptions
|
|
11538
11678
|
} = core;
|
|
@@ -11618,6 +11758,7 @@ function useViewerBuildingBlocksState(input) {
|
|
|
11618
11758
|
canEdit,
|
|
11619
11759
|
promptKeepInkAnnotations: viewerOptions.advanced.slideShowPromptKeepInkAnnotations,
|
|
11620
11760
|
imageExportScale,
|
|
11761
|
+
imageResolutionScale,
|
|
11621
11762
|
mode,
|
|
11622
11763
|
slides,
|
|
11623
11764
|
activeSlide,
|
|
@@ -11690,7 +11831,7 @@ function useViewerBuildingBlocks(input) {
|
|
|
11690
11831
|
}, [incomingContent]);
|
|
11691
11832
|
const onOpenFile = react.useCallback(() => {
|
|
11692
11833
|
void (async () => {
|
|
11693
|
-
const picked = await
|
|
11834
|
+
const picked = await chunkMH4VFSDL_js.openPptxFile();
|
|
11694
11835
|
if (picked) {
|
|
11695
11836
|
setContent(picked.buffer);
|
|
11696
11837
|
}
|
|
@@ -11698,7 +11839,7 @@ function useViewerBuildingBlocks(input) {
|
|
|
11698
11839
|
}, []);
|
|
11699
11840
|
const onOpenRecentFile = react.useCallback((key) => {
|
|
11700
11841
|
void (async () => {
|
|
11701
|
-
const bytes = await
|
|
11842
|
+
const bytes = await chunkMH4VFSDL_js.readBackstageRecentFile(key);
|
|
11702
11843
|
if (bytes) {
|
|
11703
11844
|
setContent(bytes);
|
|
11704
11845
|
}
|
|
@@ -11880,6 +12021,7 @@ exports.MIN_TOUCH_TARGET = MIN_TOUCH_TARGET;
|
|
|
11880
12021
|
exports.ViewerOptionsContext = ViewerOptionsContext;
|
|
11881
12022
|
exports.computeToolbarVisibility = computeToolbarVisibility;
|
|
11882
12023
|
exports.detectTargetType = detectTargetType;
|
|
12024
|
+
exports.getGlyphOutline = getGlyphOutline;
|
|
11883
12025
|
exports.isAudienceTab = isAudienceTab;
|
|
11884
12026
|
exports.parseAudienceNonce = parseAudienceNonce;
|
|
11885
12027
|
exports.parseEmailUrl = parseEmailUrl;
|