pptx-react-viewer 2.16.10 → 2.18.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 +4 -0
- package/README.md +14 -14
- package/dist/{AiChatPanel-XHKYPYPH.mjs → AiChatPanel-SSSBERWJ.mjs} +4 -4
- package/dist/AiChatPanel-SSSBERWJ.mjs.br +0 -0
- package/dist/AiChatPanel-SSSBERWJ.mjs.gz +0 -0
- package/dist/{AiChatPanel-EPMBL6EA.js → AiChatPanel-UN5DHPZY.js} +24 -24
- package/dist/AiChatPanel-UN5DHPZY.js.br +0 -0
- package/dist/AiChatPanel-UN5DHPZY.js.gz +0 -0
- package/dist/{Model3DScene-DUJOZA2B.js → Model3DScene-4RPYKC2I.js} +2 -2
- package/dist/Model3DScene-4RPYKC2I.js.br +0 -0
- package/dist/Model3DScene-4RPYKC2I.js.gz +0 -0
- package/dist/{Model3DScene-YMIAGRPG.mjs → Model3DScene-LYEESYAI.mjs} +1 -1
- package/dist/Model3DScene-LYEESYAI.mjs.br +0 -0
- package/dist/Model3DScene-LYEESYAI.mjs.gz +0 -0
- package/dist/{PowerPointViewer-Du7u4INi.d.ts → PowerPointViewer-Cf4YHjdF.d.ts} +2 -2
- package/dist/PowerPointViewer-Cf4YHjdF.d.ts.map +1 -0
- package/dist/{SurfaceChart3DScene-TNCHWQAK.js → SurfaceChart3DScene-ACPKCWLJ.js} +2 -2
- package/dist/SurfaceChart3DScene-ACPKCWLJ.js.br +0 -0
- package/dist/SurfaceChart3DScene-ACPKCWLJ.js.gz +0 -0
- package/dist/{SurfaceChart3DScene-Q47OEJXS.mjs → SurfaceChart3DScene-JR62SOYO.mjs} +1 -1
- package/dist/SurfaceChart3DScene-JR62SOYO.mjs.br +0 -0
- package/dist/SurfaceChart3DScene-JR62SOYO.mjs.gz +0 -0
- package/dist/{audience-content-store-BvqKy7Hf.d.ts → audience-content-store-CyS0oP6t.d.ts} +2 -2
- package/dist/{audience-content-store-BvqKy7Hf.d.ts.map → audience-content-store-CyS0oP6t.d.ts.map} +1 -1
- package/dist/{chunk-WK22Z7PK.js → chunk-4LWGAVAP.js} +526 -928
- package/dist/chunk-4LWGAVAP.js.br +0 -0
- package/dist/chunk-4LWGAVAP.js.gz +0 -0
- package/dist/{chunk-EL2YF26P.mjs → chunk-7XF6S4AM.mjs} +1 -1
- package/dist/chunk-7XF6S4AM.mjs.br +0 -0
- package/dist/chunk-7XF6S4AM.mjs.gz +0 -0
- package/dist/{chunk-FSVE6WUY.js → chunk-ASKYZ5ZY.js} +728 -523
- package/dist/chunk-ASKYZ5ZY.js.br +0 -0
- package/dist/chunk-ASKYZ5ZY.js.gz +0 -0
- package/dist/{chunk-VHME5BE6.mjs → chunk-BZOL6FXF.mjs} +326 -728
- package/dist/chunk-BZOL6FXF.mjs.br +0 -0
- package/dist/chunk-BZOL6FXF.mjs.gz +0 -0
- package/dist/{chunk-YWKUIUQX.mjs → chunk-GODW6RNR.mjs} +87648 -78804
- package/dist/chunk-GODW6RNR.mjs.br +0 -0
- package/dist/chunk-GODW6RNR.mjs.gz +0 -0
- package/dist/{chunk-ESC6IB2F.js → chunk-ICZDMFF2.js} +2147 -3399
- package/dist/chunk-ICZDMFF2.js.br +0 -0
- package/dist/chunk-ICZDMFF2.js.gz +0 -0
- package/dist/{chunk-PI5SFTDC.js → chunk-MAVLV56S.js} +3 -3
- package/dist/chunk-MAVLV56S.js.br +0 -0
- package/dist/chunk-MAVLV56S.js.gz +0 -0
- package/dist/{chunk-G3VAE7ZF.mjs → chunk-O7FTUUXP.mjs} +1212 -2464
- package/dist/chunk-O7FTUUXP.mjs.br +0 -0
- package/dist/chunk-O7FTUUXP.mjs.gz +0 -0
- package/dist/{chunk-J7EFC3GS.mjs → chunk-QUB5OSKY.mjs} +394 -189
- package/dist/chunk-QUB5OSKY.mjs.br +0 -0
- package/dist/chunk-QUB5OSKY.mjs.gz +0 -0
- package/dist/{chunk-DVZF4ARG.js → chunk-RTUGI4HQ.js} +49 -4
- package/dist/chunk-RTUGI4HQ.js.br +0 -0
- package/dist/chunk-RTUGI4HQ.js.gz +0 -0
- package/dist/{chunk-5IUEPQTK.mjs → chunk-SNL6LBRX.mjs} +49 -4
- package/dist/chunk-SNL6LBRX.mjs.br +0 -0
- package/dist/chunk-SNL6LBRX.mjs.gz +0 -0
- package/dist/{chunk-Y2KIB3QH.js → chunk-WVDM36ZM.js} +87730 -78843
- package/dist/chunk-WVDM36ZM.js.br +0 -0
- package/dist/chunk-WVDM36ZM.js.gz +0 -0
- package/dist/i18n.js +4 -4
- package/dist/i18n.js.br +0 -0
- package/dist/i18n.js.gz +0 -0
- package/dist/i18n.mjs +1 -1
- package/dist/i18n.mjs.br +0 -0
- package/dist/i18n.mjs.gz +0 -0
- package/dist/index.d.ts +702 -37
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +65 -41
- package/dist/index.js.br +0 -0
- package/dist/index.js.gz +0 -0
- package/dist/index.mjs +6 -6
- package/dist/index.mjs.br +0 -0
- package/dist/index.mjs.gz +0 -0
- package/dist/internals.d.ts +923 -54
- package/dist/internals.d.ts.map +1 -1
- package/dist/internals.js +79 -79
- package/dist/internals.js.br +0 -0
- package/dist/internals.js.gz +0 -0
- package/dist/internals.mjs +4 -4
- 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/{types-DU35aAJK.d.ts → types-C_CTI-QE.d.ts} +3 -31
- package/dist/types-C_CTI-QE.d.ts.map +1 -0
- package/dist/{useViewerBuildingBlocks-Xddn6SFj.d.ts → useViewerBuildingBlocks-DItilDbP.d.ts} +47 -8
- package/dist/useViewerBuildingBlocks-DItilDbP.d.ts.map +1 -0
- package/dist/viewer/index.d.ts +593 -56
- package/dist/viewer/index.js +27 -27
- package/dist/viewer/index.js.br +0 -0
- package/dist/viewer/index.js.gz +0 -0
- package/dist/viewer/index.mjs +6 -6
- package/dist/viewer/index.mjs.br +0 -0
- package/dist/viewer/index.mjs.gz +0 -0
- package/package.json +2 -2
- package/dist/AiChatPanel-EPMBL6EA.js.br +0 -0
- package/dist/AiChatPanel-EPMBL6EA.js.gz +0 -0
- package/dist/AiChatPanel-XHKYPYPH.mjs.br +0 -0
- package/dist/AiChatPanel-XHKYPYPH.mjs.gz +0 -0
- package/dist/Model3DScene-DUJOZA2B.js.br +0 -0
- package/dist/Model3DScene-DUJOZA2B.js.gz +0 -0
- package/dist/Model3DScene-YMIAGRPG.mjs.br +0 -0
- package/dist/Model3DScene-YMIAGRPG.mjs.gz +0 -0
- package/dist/PowerPointViewer-Du7u4INi.d.ts.map +0 -1
- package/dist/SurfaceChart3DScene-Q47OEJXS.mjs.br +0 -0
- package/dist/SurfaceChart3DScene-Q47OEJXS.mjs.gz +0 -0
- package/dist/SurfaceChart3DScene-TNCHWQAK.js.br +0 -0
- package/dist/SurfaceChart3DScene-TNCHWQAK.js.gz +0 -0
- package/dist/chunk-5IUEPQTK.mjs.br +0 -0
- package/dist/chunk-5IUEPQTK.mjs.gz +0 -0
- package/dist/chunk-DVZF4ARG.js.br +0 -0
- package/dist/chunk-DVZF4ARG.js.gz +0 -0
- package/dist/chunk-EL2YF26P.mjs.br +0 -0
- package/dist/chunk-EL2YF26P.mjs.gz +0 -0
- package/dist/chunk-ESC6IB2F.js.br +0 -0
- package/dist/chunk-ESC6IB2F.js.gz +0 -0
- package/dist/chunk-FSVE6WUY.js.br +0 -0
- package/dist/chunk-FSVE6WUY.js.gz +0 -0
- package/dist/chunk-G3VAE7ZF.mjs.br +0 -0
- package/dist/chunk-G3VAE7ZF.mjs.gz +0 -0
- package/dist/chunk-J7EFC3GS.mjs.br +0 -0
- package/dist/chunk-J7EFC3GS.mjs.gz +0 -0
- package/dist/chunk-PI5SFTDC.js.br +0 -0
- package/dist/chunk-PI5SFTDC.js.gz +0 -0
- package/dist/chunk-VHME5BE6.mjs.br +0 -0
- package/dist/chunk-VHME5BE6.mjs.gz +0 -0
- package/dist/chunk-WK22Z7PK.js.br +0 -0
- package/dist/chunk-WK22Z7PK.js.gz +0 -0
- package/dist/chunk-Y2KIB3QH.js.br +0 -0
- package/dist/chunk-Y2KIB3QH.js.gz +0 -0
- package/dist/chunk-YWKUIUQX.mjs.br +0 -0
- package/dist/chunk-YWKUIUQX.mjs.gz +0 -0
- package/dist/types-DU35aAJK.d.ts.map +0 -1
- package/dist/useViewerBuildingBlocks-Xddn6SFj.d.ts.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
3
|
+
var chunk4LWGAVAP_js = require('./chunk-4LWGAVAP.js');
|
|
4
|
+
var chunkRTUGI4HQ_js = require('./chunk-RTUGI4HQ.js');
|
|
5
|
+
var chunkWVDM36ZM_js = require('./chunk-WVDM36ZM.js');
|
|
6
6
|
var react = require('react');
|
|
7
7
|
var JSZip = require('jszip');
|
|
8
8
|
var reactI18next = require('react-i18next');
|
|
@@ -14,7 +14,7 @@ var JSZip__default = /*#__PURE__*/_interopDefault(JSZip);
|
|
|
14
14
|
function useVirtualizedSlides({
|
|
15
15
|
totalItems,
|
|
16
16
|
itemHeight,
|
|
17
|
-
overscan =
|
|
17
|
+
overscan = chunkWVDM36ZM_js.DEFAULT_VIRTUAL_OVERSCAN
|
|
18
18
|
}) {
|
|
19
19
|
const scrollContainerRef = react.useRef(null);
|
|
20
20
|
const [scrollTop, setScrollTop] = react.useState(0);
|
|
@@ -44,7 +44,7 @@ function useVirtualizedSlides({
|
|
|
44
44
|
resizeObserver?.disconnect();
|
|
45
45
|
};
|
|
46
46
|
}, []);
|
|
47
|
-
const range =
|
|
47
|
+
const range = chunkWVDM36ZM_js.computeVirtualRange(totalItems, itemHeight, scrollTop, viewportHeight, overscan);
|
|
48
48
|
const safeItemHeight = Math.max(itemHeight, 1);
|
|
49
49
|
const scrollToIndex = react.useCallback(
|
|
50
50
|
(index, behavior = "smooth") => {
|
|
@@ -85,7 +85,7 @@ function usePresenceTracking({
|
|
|
85
85
|
}) {
|
|
86
86
|
const [remoteUsers, setRemoteUsers] = react.useState([]);
|
|
87
87
|
const projectorRef = react.useRef(null);
|
|
88
|
-
projectorRef.current ??=
|
|
88
|
+
projectorRef.current ??= chunkWVDM36ZM_js.createPresenceProjector();
|
|
89
89
|
const projector = projectorRef.current;
|
|
90
90
|
const lastBroadcastRef = react.useRef(0);
|
|
91
91
|
const pendingBroadcastRef = react.useRef(null);
|
|
@@ -110,7 +110,7 @@ function usePresenceTracking({
|
|
|
110
110
|
awareness.setLocalStateField("presence", state);
|
|
111
111
|
lastBroadcastRef.current = Date.now();
|
|
112
112
|
};
|
|
113
|
-
if (elapsed >=
|
|
113
|
+
if (elapsed >= chunkWVDM36ZM_js.BROADCAST_THROTTLE_MS) {
|
|
114
114
|
if (pendingBroadcastRef.current) {
|
|
115
115
|
clearTimeout(pendingBroadcastRef.current);
|
|
116
116
|
pendingBroadcastRef.current = null;
|
|
@@ -120,7 +120,7 @@ function usePresenceTracking({
|
|
|
120
120
|
pendingBroadcastRef.current = setTimeout(() => {
|
|
121
121
|
pendingBroadcastRef.current = null;
|
|
122
122
|
flush();
|
|
123
|
-
},
|
|
123
|
+
}, chunkWVDM36ZM_js.BROADCAST_THROTTLE_MS - elapsed);
|
|
124
124
|
}
|
|
125
125
|
},
|
|
126
126
|
[awareness, userName, userColor, userAvatar, role]
|
|
@@ -200,7 +200,7 @@ function useYjsProvider({ config }) {
|
|
|
200
200
|
const departureRef = react.useRef(null);
|
|
201
201
|
const gateRef = react.useRef(null);
|
|
202
202
|
if (!gateRef.current) {
|
|
203
|
-
gateRef.current =
|
|
203
|
+
gateRef.current = chunkWVDM36ZM_js.createSyncGate(() => setSynced(true));
|
|
204
204
|
}
|
|
205
205
|
const teardown = react.useCallback(() => {
|
|
206
206
|
if (timeoutRef.current) {
|
|
@@ -220,7 +220,7 @@ function useYjsProvider({ config }) {
|
|
|
220
220
|
const buildCleanup = react.useCallback(
|
|
221
221
|
(provider, yDoc) => () => {
|
|
222
222
|
announceDeparture();
|
|
223
|
-
|
|
223
|
+
chunkWVDM36ZM_js.clearLocalAwareness(provider.awareness);
|
|
224
224
|
provider.destroy();
|
|
225
225
|
yDoc.destroy();
|
|
226
226
|
setDoc(null);
|
|
@@ -245,9 +245,9 @@ function useYjsProvider({ config }) {
|
|
|
245
245
|
if (config.authToken) {
|
|
246
246
|
opts.password = config.authToken;
|
|
247
247
|
}
|
|
248
|
-
const roomId =
|
|
248
|
+
const roomId = chunkWVDM36ZM_js.validateRoomId(config.roomId);
|
|
249
249
|
const provider = new WebrtcProvider(roomId, yDoc, opts);
|
|
250
|
-
departureRef.current =
|
|
250
|
+
departureRef.current = chunkWVDM36ZM_js.createDepartureChannel(roomId, provider.awareness);
|
|
251
251
|
setDoc(yDoc);
|
|
252
252
|
setAwareness(provider.awareness);
|
|
253
253
|
setClientId(provider.awareness.clientID);
|
|
@@ -289,13 +289,13 @@ function useYjsProvider({ config }) {
|
|
|
289
289
|
if (!config) {
|
|
290
290
|
return;
|
|
291
291
|
}
|
|
292
|
-
const roomId =
|
|
293
|
-
const transport = config.transport ??
|
|
292
|
+
const roomId = chunkWVDM36ZM_js.validateRoomId(config.roomId);
|
|
293
|
+
const transport = config.transport ?? chunkWVDM36ZM_js.resolveTransportForServerUrl(config.serverUrl);
|
|
294
294
|
if (transport === "webrtc") {
|
|
295
295
|
await initWebrtc();
|
|
296
296
|
return;
|
|
297
297
|
}
|
|
298
|
-
if (
|
|
298
|
+
if (chunkWVDM36ZM_js.isMixedContentBlocked(config.serverUrl)) {
|
|
299
299
|
console.warn(
|
|
300
300
|
`[pptx-viewer] Refusing to connect: insecure ws:// server "${config.serverUrl}" is blocked from a secure (https) page. Use a wss:// URL.`
|
|
301
301
|
);
|
|
@@ -309,7 +309,7 @@ function useYjsProvider({ config }) {
|
|
|
309
309
|
const provider = new WebsocketProvider(config.serverUrl, roomId, yDoc, {
|
|
310
310
|
params: config.authToken ? { token: config.authToken } : void 0
|
|
311
311
|
});
|
|
312
|
-
departureRef.current =
|
|
312
|
+
departureRef.current = chunkWVDM36ZM_js.createDepartureChannel(roomId, provider.awareness);
|
|
313
313
|
let connected = false;
|
|
314
314
|
const handleStatus = (event) => {
|
|
315
315
|
if (event.status === "connected") {
|
|
@@ -349,7 +349,7 @@ function useYjsProvider({ config }) {
|
|
|
349
349
|
provider.off("status", handleStatus);
|
|
350
350
|
provider.off("sync", handleSynced);
|
|
351
351
|
announceDeparture();
|
|
352
|
-
|
|
352
|
+
chunkWVDM36ZM_js.clearLocalAwareness(provider.awareness);
|
|
353
353
|
provider.destroy();
|
|
354
354
|
yDoc.destroy();
|
|
355
355
|
setDoc(null);
|
|
@@ -358,7 +358,7 @@ function useYjsProvider({ config }) {
|
|
|
358
358
|
cleanupRef.current = null;
|
|
359
359
|
setStatus("error");
|
|
360
360
|
}
|
|
361
|
-
},
|
|
361
|
+
}, chunkWVDM36ZM_js.CONNECTION_TIMEOUT_MS);
|
|
362
362
|
}
|
|
363
363
|
setDoc(yDoc);
|
|
364
364
|
setAwareness(provider.awareness);
|
|
@@ -367,7 +367,7 @@ function useYjsProvider({ config }) {
|
|
|
367
367
|
provider.off("status", handleStatus);
|
|
368
368
|
provider.off("sync", handleSynced);
|
|
369
369
|
announceDeparture();
|
|
370
|
-
|
|
370
|
+
chunkWVDM36ZM_js.clearLocalAwareness(provider.awareness);
|
|
371
371
|
provider.destroy();
|
|
372
372
|
yDoc.destroy();
|
|
373
373
|
setDoc(null);
|
|
@@ -393,7 +393,7 @@ function useYjsProvider({ config }) {
|
|
|
393
393
|
]);
|
|
394
394
|
react.useEffect(() => {
|
|
395
395
|
init();
|
|
396
|
-
const disposeTeardown =
|
|
396
|
+
const disposeTeardown = chunkWVDM36ZM_js.registerCollaborationTeardown({
|
|
397
397
|
leave: teardown,
|
|
398
398
|
rejoin: init
|
|
399
399
|
});
|
|
@@ -414,7 +414,7 @@ function useCollaborativeState({
|
|
|
414
414
|
canvasWidth,
|
|
415
415
|
canvasHeight
|
|
416
416
|
}) {
|
|
417
|
-
const userColor =
|
|
417
|
+
const userColor = chunkWVDM36ZM_js.sanitizeColor(config?.userColor, "#6366f1");
|
|
418
418
|
const { status, awareness, doc, clientId, synced, retry } = useYjsProvider({ config });
|
|
419
419
|
const { remoteUsers, broadcastPresence } = usePresenceTracking({
|
|
420
420
|
awareness,
|
|
@@ -490,6 +490,7 @@ function useEditorHistory(input) {
|
|
|
490
490
|
maxHistoryEntries = DEFAULT_MAX_HISTORY_ENTRIES,
|
|
491
491
|
hasActivePointerInteraction,
|
|
492
492
|
pointerCommitNonce,
|
|
493
|
+
onDirty,
|
|
493
494
|
setSlides,
|
|
494
495
|
setCanvasSize,
|
|
495
496
|
setActiveSlideIndex,
|
|
@@ -523,8 +524,8 @@ function useEditorHistory(input) {
|
|
|
523
524
|
width: canvasSize.width,
|
|
524
525
|
height: canvasSize.height,
|
|
525
526
|
activeSlideIndex,
|
|
526
|
-
slides: slides.map(
|
|
527
|
-
templateElementsBySlideId:
|
|
527
|
+
slides: slides.map(chunkWVDM36ZM_js.cloneSlide),
|
|
528
|
+
templateElementsBySlideId: chunkWVDM36ZM_js.cloneTemplateElementsBySlideId(templateElementsBySlideId),
|
|
528
529
|
...actionLabel ? { actionLabel } : {}
|
|
529
530
|
};
|
|
530
531
|
},
|
|
@@ -537,9 +538,9 @@ function useEditorHistory(input) {
|
|
|
537
538
|
width: snapshot.width,
|
|
538
539
|
height: snapshot.height
|
|
539
540
|
});
|
|
540
|
-
setSlides(snapshot.slides.map(
|
|
541
|
+
setSlides(snapshot.slides.map(chunkWVDM36ZM_js.cloneSlide));
|
|
541
542
|
setTemplateElementsBySlideId(
|
|
542
|
-
|
|
543
|
+
chunkWVDM36ZM_js.cloneTemplateElementsBySlideId(snapshot.templateElementsBySlideId)
|
|
543
544
|
);
|
|
544
545
|
setActiveSlideIndex(Math.min(snapshot.activeSlideIndex, maxSlideIndex));
|
|
545
546
|
setSelectedElementIds([]);
|
|
@@ -562,8 +563,13 @@ function useEditorHistory(input) {
|
|
|
562
563
|
isApplyingHistoryRef.current = false;
|
|
563
564
|
}, 0);
|
|
564
565
|
}, []);
|
|
566
|
+
const onDirtyRef = react.useRef(onDirty);
|
|
567
|
+
react.useEffect(() => {
|
|
568
|
+
onDirtyRef.current = onDirty;
|
|
569
|
+
}, [onDirty]);
|
|
565
570
|
const markDirty = react.useCallback(() => {
|
|
566
571
|
setEditCommitNonce((previous) => previous + 1);
|
|
572
|
+
onDirtyRef.current?.();
|
|
567
573
|
}, []);
|
|
568
574
|
const handleUndo = react.useCallback(() => {
|
|
569
575
|
const previousSnapshot = historyPastRef.current.pop();
|
|
@@ -573,8 +579,8 @@ function useEditorHistory(input) {
|
|
|
573
579
|
const currentSnapshot = buildHistorySnapshot();
|
|
574
580
|
historyFutureRef.current.push(currentSnapshot);
|
|
575
581
|
isApplyingHistoryRef.current = true;
|
|
576
|
-
const nextSnapshot =
|
|
577
|
-
lastHistorySnapshotRef.current =
|
|
582
|
+
const nextSnapshot = chunk4LWGAVAP_js.cloneHistorySnapshot(previousSnapshot);
|
|
583
|
+
lastHistorySnapshotRef.current = chunk4LWGAVAP_js.cloneHistorySnapshot(nextSnapshot);
|
|
578
584
|
lastHistorySerializedRef.current = JSON.stringify(nextSnapshot);
|
|
579
585
|
applyHistorySnapshot(nextSnapshot);
|
|
580
586
|
updateHistoryAvailability();
|
|
@@ -595,8 +601,8 @@ function useEditorHistory(input) {
|
|
|
595
601
|
const currentSnapshot = buildHistorySnapshot();
|
|
596
602
|
historyPastRef.current.push(currentSnapshot);
|
|
597
603
|
isApplyingHistoryRef.current = true;
|
|
598
|
-
const targetSnapshot =
|
|
599
|
-
lastHistorySnapshotRef.current =
|
|
604
|
+
const targetSnapshot = chunk4LWGAVAP_js.cloneHistorySnapshot(nextSnapshot);
|
|
605
|
+
lastHistorySnapshotRef.current = chunk4LWGAVAP_js.cloneHistorySnapshot(targetSnapshot);
|
|
600
606
|
lastHistorySerializedRef.current = JSON.stringify(targetSnapshot);
|
|
601
607
|
applyHistorySnapshot(targetSnapshot);
|
|
602
608
|
updateHistoryAvailability();
|
|
@@ -614,7 +620,7 @@ function useEditorHistory(input) {
|
|
|
614
620
|
historyPastRef.current = [];
|
|
615
621
|
historyFutureRef.current = [];
|
|
616
622
|
if (initialSnapshot) {
|
|
617
|
-
const clonedInitial =
|
|
623
|
+
const clonedInitial = chunk4LWGAVAP_js.cloneHistorySnapshot(initialSnapshot);
|
|
618
624
|
lastHistorySnapshotRef.current = clonedInitial;
|
|
619
625
|
lastHistorySerializedRef.current = JSON.stringify(clonedInitial);
|
|
620
626
|
} else {
|
|
@@ -655,18 +661,19 @@ function useEditorHistory(input) {
|
|
|
655
661
|
}
|
|
656
662
|
const previousSnapshot = lastHistorySnapshotRef.current;
|
|
657
663
|
if (!previousSnapshot) {
|
|
658
|
-
lastHistorySnapshotRef.current =
|
|
664
|
+
lastHistorySnapshotRef.current = chunk4LWGAVAP_js.cloneHistorySnapshot(snapshot);
|
|
659
665
|
lastHistorySerializedRef.current = serialized;
|
|
660
666
|
lastCheapHashRef.current = cheapHash;
|
|
661
667
|
updateHistoryAvailability();
|
|
662
668
|
return;
|
|
663
669
|
}
|
|
664
|
-
|
|
670
|
+
onDirtyRef.current?.();
|
|
671
|
+
historyPastRef.current.push(chunk4LWGAVAP_js.cloneHistorySnapshot(previousSnapshot));
|
|
665
672
|
while (historyPastRef.current.length > Math.max(1, maxHistoryEntries)) {
|
|
666
673
|
historyPastRef.current.shift();
|
|
667
674
|
}
|
|
668
675
|
historyFutureRef.current = [];
|
|
669
|
-
lastHistorySnapshotRef.current =
|
|
676
|
+
lastHistorySnapshotRef.current = chunk4LWGAVAP_js.cloneHistorySnapshot(snapshot);
|
|
670
677
|
lastHistorySerializedRef.current = serialized;
|
|
671
678
|
lastCheapHashRef.current = cheapHash;
|
|
672
679
|
updateHistoryAvailability();
|
|
@@ -726,9 +733,9 @@ function useZoomViewport({
|
|
|
726
733
|
const canvasStageRef = react.useRef(null);
|
|
727
734
|
const canvasViewportRef = react.useRef(null);
|
|
728
735
|
const renderScaleRef = react.useRef(1);
|
|
729
|
-
const wheelBufferRef = react.useRef(
|
|
736
|
+
const wheelBufferRef = react.useRef(chunkWVDM36ZM_js.createWheelStepBuffer());
|
|
730
737
|
const storeRef = react.useRef(null);
|
|
731
|
-
storeRef.current ??=
|
|
738
|
+
storeRef.current ??= chunkWVDM36ZM_js.createViewerZoomStore();
|
|
732
739
|
const store = storeRef.current;
|
|
733
740
|
const scale = useViewerStore(store, selectZoom);
|
|
734
741
|
const setScale = react.useCallback(
|
|
@@ -789,7 +796,7 @@ function useZoomViewport({
|
|
|
789
796
|
if (!wrapper || !canvasViewport) {
|
|
790
797
|
return;
|
|
791
798
|
}
|
|
792
|
-
const boundedScale =
|
|
799
|
+
const boundedScale = chunkWVDM36ZM_js.clampZoomScale(nextScale);
|
|
793
800
|
const nextEditorScale = fitScale * boundedScale;
|
|
794
801
|
const centerX = (bounds.minX + bounds.maxX) / 2;
|
|
795
802
|
const centerY = (bounds.minY + bounds.maxY) / 2;
|
|
@@ -826,29 +833,29 @@ function useZoomViewport({
|
|
|
826
833
|
selectedElements.forEach((element) => {
|
|
827
834
|
minX = Math.min(minX, element.x);
|
|
828
835
|
minY = Math.min(minY, element.y);
|
|
829
|
-
maxX = Math.max(maxX, element.x + Math.max(element.width,
|
|
830
|
-
maxY = Math.max(maxY, element.y + Math.max(element.height,
|
|
836
|
+
maxX = Math.max(maxX, element.x + Math.max(element.width, chunk4LWGAVAP_js.MIN_ELEMENT_SIZE));
|
|
837
|
+
maxY = Math.max(maxY, element.y + Math.max(element.height, chunk4LWGAVAP_js.MIN_ELEMENT_SIZE));
|
|
831
838
|
});
|
|
832
839
|
if (!Number.isFinite(minX) || !Number.isFinite(minY) || !Number.isFinite(maxX) || !Number.isFinite(maxY)) {
|
|
833
840
|
return;
|
|
834
841
|
}
|
|
835
842
|
const selectionBounds = { minX, minY, maxX, maxY };
|
|
836
|
-
const boundsWidth = Math.max(selectionBounds.maxX - selectionBounds.minX,
|
|
837
|
-
const boundsHeight = Math.max(selectionBounds.maxY - selectionBounds.minY,
|
|
843
|
+
const boundsWidth = Math.max(selectionBounds.maxX - selectionBounds.minX, chunk4LWGAVAP_js.MIN_ELEMENT_SIZE);
|
|
844
|
+
const boundsHeight = Math.max(selectionBounds.maxY - selectionBounds.minY, chunk4LWGAVAP_js.MIN_ELEMENT_SIZE);
|
|
838
845
|
const availableWidth = Math.max(
|
|
839
|
-
effectiveEditorDimensions.width -
|
|
840
|
-
|
|
846
|
+
effectiveEditorDimensions.width - chunk4LWGAVAP_js.ZOOM_TO_SELECTION_PADDING,
|
|
847
|
+
chunk4LWGAVAP_js.MIN_ELEMENT_SIZE
|
|
841
848
|
);
|
|
842
849
|
const availableHeight = Math.max(
|
|
843
|
-
effectiveEditorDimensions.height -
|
|
844
|
-
|
|
850
|
+
effectiveEditorDimensions.height - chunk4LWGAVAP_js.ZOOM_TO_SELECTION_PADDING,
|
|
851
|
+
chunk4LWGAVAP_js.MIN_ELEMENT_SIZE
|
|
845
852
|
);
|
|
846
853
|
const targetEditorScale = Math.min(
|
|
847
854
|
availableWidth / boundsWidth,
|
|
848
855
|
availableHeight / boundsHeight
|
|
849
856
|
);
|
|
850
857
|
const safeFitScale = fitScale > Number.EPSILON ? fitScale : Number.EPSILON;
|
|
851
|
-
const nextScale =
|
|
858
|
+
const nextScale = chunkWVDM36ZM_js.clampZoomScale(targetEditorScale / safeFitScale);
|
|
852
859
|
setScale(nextScale);
|
|
853
860
|
window.requestAnimationFrame(() => {
|
|
854
861
|
window.requestAnimationFrame(() => {
|
|
@@ -865,14 +872,14 @@ function useZoomViewport({
|
|
|
865
872
|
]);
|
|
866
873
|
const handleWheel = react.useCallback(
|
|
867
874
|
(event) => {
|
|
868
|
-
const mapped =
|
|
875
|
+
const mapped = chunkWVDM36ZM_js.mapEditingWheel(event, wheelBufferRef.current, true);
|
|
869
876
|
if (mapped.intent !== "zoom") {
|
|
870
877
|
return;
|
|
871
878
|
}
|
|
872
879
|
event.preventDefault();
|
|
873
880
|
store.dispatch({
|
|
874
881
|
type: "set-zoom",
|
|
875
|
-
zoom:
|
|
882
|
+
zoom: chunkWVDM36ZM_js.clampZoomScale(store.getState().zoom + mapped.deltaScale)
|
|
876
883
|
});
|
|
877
884
|
},
|
|
878
885
|
[store]
|
|
@@ -960,7 +967,7 @@ function applyAnimationGroupSteps(group, onPlayActionSound, setPresentationEleme
|
|
|
960
967
|
const command = step.command;
|
|
961
968
|
const timer = window.setTimeout(
|
|
962
969
|
() => {
|
|
963
|
-
|
|
970
|
+
chunk4LWGAVAP_js.executeMediaCommand(command);
|
|
964
971
|
},
|
|
965
972
|
Math.max(0, step.delayMs)
|
|
966
973
|
);
|
|
@@ -1097,7 +1104,7 @@ function scheduleEntranceAnimationTimers(slide, setPresentationAnimations, prese
|
|
|
1097
1104
|
}))
|
|
1098
1105
|
);
|
|
1099
1106
|
entranceAnimations.forEach((animation, animationIndex) => {
|
|
1100
|
-
const delay =
|
|
1107
|
+
const delay = chunkWVDM36ZM_js.computeEntranceAnimationDelay(animation.delayMs, animationIndex);
|
|
1101
1108
|
const timer = window.setTimeout(() => {
|
|
1102
1109
|
setPresentationAnimations(
|
|
1103
1110
|
(previousAnimations) => previousAnimations.map(
|
|
@@ -1129,7 +1136,7 @@ function useAnimationPlayback(input) {
|
|
|
1129
1136
|
(controller, group) => {
|
|
1130
1137
|
driveBuildReveal(
|
|
1131
1138
|
controller,
|
|
1132
|
-
|
|
1139
|
+
chunkWVDM36ZM_js.PresentationAnimationController.collectBuildStepIds(group),
|
|
1133
1140
|
setPresentationElementStates,
|
|
1134
1141
|
buildRafRef
|
|
1135
1142
|
);
|
|
@@ -1192,7 +1199,7 @@ function useAnimationPlayback(input) {
|
|
|
1192
1199
|
setHoverTriggerShapeIds(/* @__PURE__ */ new Set());
|
|
1193
1200
|
return;
|
|
1194
1201
|
}
|
|
1195
|
-
const controller =
|
|
1202
|
+
const controller = chunkWVDM36ZM_js.PresentationAnimationController.fromSlide(slide);
|
|
1196
1203
|
controllerRef.current = controller;
|
|
1197
1204
|
setPresentationKeyframesCss(controller.keyframesCss);
|
|
1198
1205
|
setInteractiveTriggerShapeIds(controller.interactiveTriggerShapeIds);
|
|
@@ -1350,12 +1357,12 @@ function useAnimationPlayback(input) {
|
|
|
1350
1357
|
presentationTimersRef
|
|
1351
1358
|
};
|
|
1352
1359
|
}
|
|
1353
|
-
var PRESENTER_CHANNEL_NAME =
|
|
1354
|
-
var AUDIENCE_HASH =
|
|
1355
|
-
var PRESENTER_MSG_ORIGIN =
|
|
1356
|
-
var AUDIENCE_NONCE_KEY =
|
|
1360
|
+
var PRESENTER_CHANNEL_NAME = chunkWVDM36ZM_js.PRESENTATION_CHANNEL_NAME;
|
|
1361
|
+
var AUDIENCE_HASH = chunkWVDM36ZM_js.PRESENTATION_HASH;
|
|
1362
|
+
var PRESENTER_MSG_ORIGIN = chunkWVDM36ZM_js.PRESENTATION_MESSAGE_ORIGIN;
|
|
1363
|
+
var AUDIENCE_NONCE_KEY = chunkWVDM36ZM_js.PRESENTATION_NONCE_KEY;
|
|
1357
1364
|
function generateSessionId() {
|
|
1358
|
-
return
|
|
1365
|
+
return chunkWVDM36ZM_js.createPresentationSessionId();
|
|
1359
1366
|
}
|
|
1360
1367
|
function parseAudienceNonce() {
|
|
1361
1368
|
const hash = window.location.hash;
|
|
@@ -1391,7 +1398,7 @@ function usePresenterWindow(input) {
|
|
|
1391
1398
|
}, []);
|
|
1392
1399
|
const swapDisplays = react.useCallback(async () => {
|
|
1393
1400
|
const audience = audienceWindowRef.current;
|
|
1394
|
-
return audience && !audience.closed ?
|
|
1401
|
+
return audience && !audience.closed ? chunkWVDM36ZM_js.swapPresentationWindows(window, audience) : false;
|
|
1395
1402
|
}, []);
|
|
1396
1403
|
const syncSlideToAudience = react.useCallback(
|
|
1397
1404
|
(slideIndex) => {
|
|
@@ -1455,7 +1462,7 @@ function usePresenterWindow(input) {
|
|
|
1455
1462
|
pollTimerRef.current = null;
|
|
1456
1463
|
}
|
|
1457
1464
|
if (closingSessionId) {
|
|
1458
|
-
void
|
|
1465
|
+
void chunkWVDM36ZM_js.clearAudienceContent(closingSessionId);
|
|
1459
1466
|
}
|
|
1460
1467
|
}, [getChannel]);
|
|
1461
1468
|
const openAudienceWindow = react.useCallback(() => {
|
|
@@ -1473,10 +1480,10 @@ function usePresenterWindow(input) {
|
|
|
1473
1480
|
audienceWindowRef.current = blankWin;
|
|
1474
1481
|
const sessionId = generateSessionId();
|
|
1475
1482
|
sessionIdRef.current = sessionId;
|
|
1476
|
-
const audienceUrl =
|
|
1477
|
-
void
|
|
1483
|
+
const audienceUrl = chunkWVDM36ZM_js.buildPresentationAudienceUrl(window.location.href, sessionId);
|
|
1484
|
+
void chunkWVDM36ZM_js.resolveAudienceScreenPlacement(window).then((placement) => {
|
|
1478
1485
|
if (placement && audienceWindowRef.current === blankWin && !blankWin.closed) {
|
|
1479
|
-
|
|
1486
|
+
chunkWVDM36ZM_js.placeAudienceWindow(blankWin, placement);
|
|
1480
1487
|
}
|
|
1481
1488
|
return void 0;
|
|
1482
1489
|
});
|
|
@@ -1506,7 +1513,7 @@ function usePresenterWindow(input) {
|
|
|
1506
1513
|
}
|
|
1507
1514
|
};
|
|
1508
1515
|
if (content) {
|
|
1509
|
-
void
|
|
1516
|
+
void chunkWVDM36ZM_js.storeAudienceContent(content, sessionId).then(() => navigateOrClose(true)).catch(() => navigateOrClose(false));
|
|
1510
1517
|
} else {
|
|
1511
1518
|
navigateOrClose(true);
|
|
1512
1519
|
}
|
|
@@ -1532,7 +1539,7 @@ function usePresenterWindow(input) {
|
|
|
1532
1539
|
}
|
|
1533
1540
|
const handleMessage = (event) => {
|
|
1534
1541
|
const message = event.data;
|
|
1535
|
-
if (
|
|
1542
|
+
if (chunkWVDM36ZM_js.isPresentationSessionMessage(message) && message.type === "audience-ready" && message.sessionId === sessionIdRef.current) {
|
|
1536
1543
|
syncStateToAudience(snapshotRef.current);
|
|
1537
1544
|
}
|
|
1538
1545
|
};
|
|
@@ -1561,7 +1568,7 @@ function usePresenterWindow(input) {
|
|
|
1561
1568
|
react.useEffect(() => {
|
|
1562
1569
|
const handleBeforeUnload = () => {
|
|
1563
1570
|
if (sessionIdRef.current) {
|
|
1564
|
-
void
|
|
1571
|
+
void chunkWVDM36ZM_js.clearAudienceContent(sessionIdRef.current);
|
|
1565
1572
|
}
|
|
1566
1573
|
};
|
|
1567
1574
|
window.addEventListener("beforeunload", handleBeforeUnload);
|
|
@@ -1623,7 +1630,7 @@ function useAudienceMode(input) {
|
|
|
1623
1630
|
}
|
|
1624
1631
|
channel.onmessage = (event) => {
|
|
1625
1632
|
const data = event.data;
|
|
1626
|
-
if (!
|
|
1633
|
+
if (!chunkWVDM36ZM_js.isPresentationSessionMessage(data) || data.origin !== PRESENTER_MSG_ORIGIN) {
|
|
1627
1634
|
return;
|
|
1628
1635
|
}
|
|
1629
1636
|
if (expectedSessionId && data.sessionId !== expectedSessionId) {
|
|
@@ -1639,16 +1646,16 @@ function useAudienceMode(input) {
|
|
|
1639
1646
|
}
|
|
1640
1647
|
if (data.type === "presenter-exit") {
|
|
1641
1648
|
if (expectedSessionId) {
|
|
1642
|
-
void
|
|
1649
|
+
void chunkWVDM36ZM_js.clearAudienceContent(expectedSessionId);
|
|
1643
1650
|
}
|
|
1644
|
-
if (
|
|
1651
|
+
if (chunkWVDM36ZM_js.endAudienceDisplay(window)) {
|
|
1645
1652
|
handlers.onPresenterEnded?.();
|
|
1646
1653
|
}
|
|
1647
1654
|
}
|
|
1648
1655
|
};
|
|
1649
1656
|
if (expectedSessionId) {
|
|
1650
1657
|
channel.postMessage({
|
|
1651
|
-
origin:
|
|
1658
|
+
origin: chunkWVDM36ZM_js.PRESENTATION_MESSAGE_ORIGIN,
|
|
1652
1659
|
type: "audience-ready",
|
|
1653
1660
|
sessionId: expectedSessionId
|
|
1654
1661
|
});
|
|
@@ -1662,7 +1669,7 @@ function useAudienceMode(input) {
|
|
|
1662
1669
|
}, []);
|
|
1663
1670
|
}
|
|
1664
1671
|
function usePresentationKeyboard(input) {
|
|
1665
|
-
const wheelBufferRef = react.useRef(
|
|
1672
|
+
const wheelBufferRef = react.useRef(chunkWVDM36ZM_js.createWheelStepBuffer());
|
|
1666
1673
|
const {
|
|
1667
1674
|
mode,
|
|
1668
1675
|
movePresentationSlide,
|
|
@@ -1675,6 +1682,7 @@ function usePresentationKeyboard(input) {
|
|
|
1675
1682
|
onToggleInkMarkup,
|
|
1676
1683
|
onToggleToolbar,
|
|
1677
1684
|
onShowAllSlides,
|
|
1685
|
+
onToggleSubtitles,
|
|
1678
1686
|
onToggleBlackScreen,
|
|
1679
1687
|
onToggleWhiteScreen,
|
|
1680
1688
|
rehearsing,
|
|
@@ -1682,14 +1690,14 @@ function usePresentationKeyboard(input) {
|
|
|
1682
1690
|
presentationSlideIndex,
|
|
1683
1691
|
setShowRehearsalSummary
|
|
1684
1692
|
} = input;
|
|
1685
|
-
const keyBufferRef = react.useRef(
|
|
1693
|
+
const keyBufferRef = react.useRef(chunkWVDM36ZM_js.createPresentationKeyBuffer());
|
|
1686
1694
|
react.useEffect(() => {
|
|
1687
|
-
if (mode !== "present" || !
|
|
1688
|
-
keyBufferRef.current =
|
|
1695
|
+
if (mode !== "present" || !chunkWVDM36ZM_js.acceptsPresentationInput()) {
|
|
1696
|
+
keyBufferRef.current = chunkWVDM36ZM_js.createPresentationKeyBuffer();
|
|
1689
1697
|
return;
|
|
1690
1698
|
}
|
|
1691
1699
|
const handleKeyDown = (event) => {
|
|
1692
|
-
const mapped =
|
|
1700
|
+
const mapped = chunkWVDM36ZM_js.mapPresentationKey(event, keyBufferRef.current);
|
|
1693
1701
|
if (mapped.action === "none") {
|
|
1694
1702
|
return;
|
|
1695
1703
|
}
|
|
@@ -1709,12 +1717,12 @@ function usePresentationKeyboard(input) {
|
|
|
1709
1717
|
movePresentationSlide(-1);
|
|
1710
1718
|
return;
|
|
1711
1719
|
case "first": {
|
|
1712
|
-
const first =
|
|
1720
|
+
const first = chunkWVDM36ZM_js.firstShowSlideIndex(showSlideIndexes);
|
|
1713
1721
|
navigateToSlide(first ?? 0);
|
|
1714
1722
|
return;
|
|
1715
1723
|
}
|
|
1716
1724
|
case "last": {
|
|
1717
|
-
const last =
|
|
1725
|
+
const last = chunkWVDM36ZM_js.lastShowSlideIndex(showSlideIndexes);
|
|
1718
1726
|
navigateToSlide(last ?? Math.max(0, slideCount - 1));
|
|
1719
1727
|
return;
|
|
1720
1728
|
}
|
|
@@ -1740,6 +1748,9 @@ function usePresentationKeyboard(input) {
|
|
|
1740
1748
|
case "showAllSlides":
|
|
1741
1749
|
onShowAllSlides?.();
|
|
1742
1750
|
return;
|
|
1751
|
+
case "toggleSubtitles":
|
|
1752
|
+
onToggleSubtitles?.();
|
|
1753
|
+
return;
|
|
1743
1754
|
case "toggleBlackScreen":
|
|
1744
1755
|
onToggleBlackScreen?.();
|
|
1745
1756
|
return;
|
|
@@ -1749,10 +1760,10 @@ function usePresentationKeyboard(input) {
|
|
|
1749
1760
|
}
|
|
1750
1761
|
};
|
|
1751
1762
|
const handleWheel = (event) => {
|
|
1752
|
-
if (mode !== "present" || !
|
|
1763
|
+
if (mode !== "present" || !chunkWVDM36ZM_js.acceptsPresentationInput()) {
|
|
1753
1764
|
return;
|
|
1754
1765
|
}
|
|
1755
|
-
const mapped =
|
|
1766
|
+
const mapped = chunkWVDM36ZM_js.mapPresentationWheel(event, wheelBufferRef.current);
|
|
1756
1767
|
if (mapped.intent === "next-slide") {
|
|
1757
1768
|
event.preventDefault();
|
|
1758
1769
|
movePresentationSlide(1);
|
|
@@ -1779,6 +1790,7 @@ function usePresentationKeyboard(input) {
|
|
|
1779
1790
|
onToggleInkMarkup,
|
|
1780
1791
|
onToggleToolbar,
|
|
1781
1792
|
onShowAllSlides,
|
|
1793
|
+
onToggleSubtitles,
|
|
1782
1794
|
onToggleBlackScreen,
|
|
1783
1795
|
onToggleWhiteScreen,
|
|
1784
1796
|
rehearsing,
|
|
@@ -1884,7 +1896,7 @@ function useRehearsalTimings(input) {
|
|
|
1884
1896
|
|
|
1885
1897
|
// src/viewer/hooks/presentation-mode/presentation-actions.ts
|
|
1886
1898
|
function handlePresentationActionImpl(action, deps) {
|
|
1887
|
-
|
|
1899
|
+
chunkWVDM36ZM_js.runPresentationAction(
|
|
1888
1900
|
action,
|
|
1889
1901
|
{ slideCount: deps.slidesLength },
|
|
1890
1902
|
{
|
|
@@ -1906,7 +1918,7 @@ function handlePresentationActionImpl(action, deps) {
|
|
|
1906
1918
|
function executeSlideTransition(nextSlideIndex, deps) {
|
|
1907
1919
|
const incomingSlide = deps.slides[nextSlideIndex];
|
|
1908
1920
|
const transition = incomingSlide?.transition;
|
|
1909
|
-
const durationMs = deps.playTransition ?
|
|
1921
|
+
const durationMs = deps.playTransition ? chunkWVDM36ZM_js.resolveTransitionDurationMs(transition) : 0;
|
|
1910
1922
|
deps.clearPresentationTimers();
|
|
1911
1923
|
deps.setPresentationSlideIndex(nextSlideIndex);
|
|
1912
1924
|
deps.onSetActiveSlideIndex(nextSlideIndex);
|
|
@@ -1965,7 +1977,7 @@ function useSlideNavigation(input) {
|
|
|
1965
1977
|
});
|
|
1966
1978
|
const scheduleAutoAdvanceForSlide = react.useCallback(
|
|
1967
1979
|
(slideIndex) => {
|
|
1968
|
-
const delayMs =
|
|
1980
|
+
const delayMs = chunkWVDM36ZM_js.resolveAutoAdvanceDelayMs(slides[slideIndex], { useTimings });
|
|
1969
1981
|
if (delayMs === void 0) {
|
|
1970
1982
|
return;
|
|
1971
1983
|
}
|
|
@@ -1988,7 +2000,7 @@ function useSlideNavigation(input) {
|
|
|
1988
2000
|
if (availableSlideIndexes.length === 0) {
|
|
1989
2001
|
return;
|
|
1990
2002
|
}
|
|
1991
|
-
const pastLastSlide = direction === 1 && !
|
|
2003
|
+
const pastLastSlide = direction === 1 && !chunkWVDM36ZM_js.hasShowSlideAfter(presentationSlideIndex, availableSlideIndexes);
|
|
1992
2004
|
if (rehearsing && pastLastSlide) {
|
|
1993
2005
|
recordCurrentSlideTime(presentationSlideIndex);
|
|
1994
2006
|
try {
|
|
@@ -2006,9 +2018,9 @@ function useSlideNavigation(input) {
|
|
|
2006
2018
|
onAdvancePastLastSlide();
|
|
2007
2019
|
return;
|
|
2008
2020
|
}
|
|
2009
|
-
const nextSlideIndex = direction === 1 ?
|
|
2021
|
+
const nextSlideIndex = direction === 1 ? chunkWVDM36ZM_js.nextShowSlideIndex(presentationSlideIndex, availableSlideIndexes, {
|
|
2010
2022
|
loop: Boolean(loopContinuously) && !rehearsing
|
|
2011
|
-
}) :
|
|
2023
|
+
}) : chunkWVDM36ZM_js.previousShowSlideIndex(presentationSlideIndex, availableSlideIndexes);
|
|
2012
2024
|
if (nextSlideIndex === void 0 || nextSlideIndex === presentationSlideIndex) {
|
|
2013
2025
|
return;
|
|
2014
2026
|
}
|
|
@@ -2153,22 +2165,22 @@ function useZoomNavigation(input) {
|
|
|
2153
2165
|
};
|
|
2154
2166
|
}
|
|
2155
2167
|
function usePresenterConsole(slideIndex, active) {
|
|
2156
|
-
const timerRef = react.useRef(
|
|
2157
|
-
const [snapshot, setSnapshot] = react.useState(() =>
|
|
2168
|
+
const timerRef = react.useRef(chunkWVDM36ZM_js.createPresenterTimer());
|
|
2169
|
+
const [snapshot, setSnapshot] = react.useState(() => chunkWVDM36ZM_js.createInitialPresentationSnapshot(slideIndex));
|
|
2158
2170
|
const patch = react.useCallback((value) => {
|
|
2159
|
-
setSnapshot((current) =>
|
|
2171
|
+
setSnapshot((current) => chunkWVDM36ZM_js.mergePresentationSnapshot(current, value));
|
|
2160
2172
|
}, []);
|
|
2161
2173
|
react.useEffect(() => patch({ slideIndex }), [patch, slideIndex]);
|
|
2162
2174
|
react.useEffect(() => {
|
|
2163
2175
|
if (!active) {
|
|
2164
2176
|
return;
|
|
2165
2177
|
}
|
|
2166
|
-
timerRef.current =
|
|
2178
|
+
timerRef.current = chunkWVDM36ZM_js.resetPresenterTimer();
|
|
2167
2179
|
patch({ paused: false, elapsedMs: 0 });
|
|
2168
2180
|
const timer = window.setInterval(() => {
|
|
2169
2181
|
patch({
|
|
2170
2182
|
paused: timerRef.current.paused,
|
|
2171
|
-
elapsedMs:
|
|
2183
|
+
elapsedMs: chunkWVDM36ZM_js.presenterElapsed(timerRef.current)
|
|
2172
2184
|
});
|
|
2173
2185
|
}, 1e3);
|
|
2174
2186
|
return () => window.clearInterval(timer);
|
|
@@ -2178,19 +2190,19 @@ function usePresenterConsole(slideIndex, active) {
|
|
|
2178
2190
|
applyAudienceSnapshot: setSnapshot,
|
|
2179
2191
|
setBlackout: (blackout) => patch({ blackout }),
|
|
2180
2192
|
toggleTimer: () => {
|
|
2181
|
-
timerRef.current =
|
|
2193
|
+
timerRef.current = chunkWVDM36ZM_js.togglePresenterTimer(timerRef.current);
|
|
2182
2194
|
patch({
|
|
2183
2195
|
paused: timerRef.current.paused,
|
|
2184
|
-
elapsedMs:
|
|
2196
|
+
elapsedMs: chunkWVDM36ZM_js.presenterElapsed(timerRef.current)
|
|
2185
2197
|
});
|
|
2186
2198
|
},
|
|
2187
2199
|
resetTimer: () => {
|
|
2188
|
-
timerRef.current =
|
|
2200
|
+
timerRef.current = chunkWVDM36ZM_js.resetPresenterTimer();
|
|
2189
2201
|
patch({ paused: false, elapsedMs: 0 });
|
|
2190
2202
|
},
|
|
2191
2203
|
stepZoom: (direction) => setSnapshot(
|
|
2192
|
-
(current) =>
|
|
2193
|
-
zoom:
|
|
2204
|
+
(current) => chunkWVDM36ZM_js.mergePresentationSnapshot(current, {
|
|
2205
|
+
zoom: chunkWVDM36ZM_js.stepPresenterZoom(
|
|
2194
2206
|
current.zoom ?? { scale: 1, originX: 0.5, originY: 0.5 },
|
|
2195
2207
|
direction
|
|
2196
2208
|
)
|
|
@@ -2219,6 +2231,7 @@ function usePresentationMode(input) {
|
|
|
2219
2231
|
onEraseAnnotations,
|
|
2220
2232
|
onToggleInkMarkup,
|
|
2221
2233
|
onToggleToolbar,
|
|
2234
|
+
onToggleSubtitles,
|
|
2222
2235
|
onSaveRehearsalTimings,
|
|
2223
2236
|
loopContinuously,
|
|
2224
2237
|
showWithAnimation,
|
|
@@ -2235,7 +2248,7 @@ function usePresentationMode(input) {
|
|
|
2235
2248
|
const [allSlidesOpen, setAllSlidesOpen] = react.useState(false);
|
|
2236
2249
|
const [endOfShowVisible, setEndOfShowVisible] = react.useState(false);
|
|
2237
2250
|
const [presentationStartTime, setPresentationStartTime] = react.useState(null);
|
|
2238
|
-
const showGuard = react.useMemo(() =>
|
|
2251
|
+
const showGuard = react.useMemo(() => chunkWVDM36ZM_js.createPresenterShowGuard(), []);
|
|
2239
2252
|
const {
|
|
2240
2253
|
presentationAnimations,
|
|
2241
2254
|
presentationElementStates,
|
|
@@ -2314,7 +2327,7 @@ function usePresentationMode(input) {
|
|
|
2314
2327
|
});
|
|
2315
2328
|
const movePresentationSlide = react.useCallback(
|
|
2316
2329
|
(direction, trigger = "explicit") => {
|
|
2317
|
-
if (!
|
|
2330
|
+
if (!chunkWVDM36ZM_js.acceptsPresentationInput()) {
|
|
2318
2331
|
return;
|
|
2319
2332
|
}
|
|
2320
2333
|
if (endOfShowVisible) {
|
|
@@ -2426,6 +2439,7 @@ function usePresentationMode(input) {
|
|
|
2426
2439
|
onToggleInkMarkup,
|
|
2427
2440
|
onToggleToolbar,
|
|
2428
2441
|
onShowAllSlides: openAllSlides,
|
|
2442
|
+
onToggleSubtitles,
|
|
2429
2443
|
onToggleBlackScreen: () => presenterConsole.setBlackout(
|
|
2430
2444
|
presenterConsole.snapshot.blackout === "black" ? "none" : "black"
|
|
2431
2445
|
),
|
|
@@ -2451,7 +2465,7 @@ function usePresentationMode(input) {
|
|
|
2451
2465
|
if (mode !== "present") {
|
|
2452
2466
|
return;
|
|
2453
2467
|
}
|
|
2454
|
-
return
|
|
2468
|
+
return chunkWVDM36ZM_js.attachPresentationVisibilityPause({
|
|
2455
2469
|
root: containerRef.current ?? void 0,
|
|
2456
2470
|
onHidden: () => clearPresentationTimersRef.current(),
|
|
2457
2471
|
onVisible: () => scheduleAutoAdvanceRef.current(presentationSlideIndexRef.current)
|
|
@@ -2531,11 +2545,11 @@ function usePresentationMode(input) {
|
|
|
2531
2545
|
if (!transitionOverlay || transitionOverlay.transition.type !== "morph") {
|
|
2532
2546
|
return void 0;
|
|
2533
2547
|
}
|
|
2534
|
-
return
|
|
2548
|
+
return chunkWVDM36ZM_js.buildMorphTransitionPlan(
|
|
2535
2549
|
slides[transitionOverlay.outgoingSlideIndex],
|
|
2536
2550
|
slides[transitionOverlay.incomingSlideIndex],
|
|
2537
2551
|
transitionOverlay.durationMs,
|
|
2538
|
-
|
|
2552
|
+
chunkWVDM36ZM_js.morphOptionToMode(transitionOverlay.transition.morphOption)
|
|
2539
2553
|
);
|
|
2540
2554
|
}, [transitionOverlay, slides]);
|
|
2541
2555
|
const morphedElementStates = react.useMemo(() => {
|
|
@@ -2556,7 +2570,7 @@ function usePresentationMode(input) {
|
|
|
2556
2570
|
if (!morphPlan) {
|
|
2557
2571
|
return presentationKeyframesCss;
|
|
2558
2572
|
}
|
|
2559
|
-
const imageRules =
|
|
2573
|
+
const imageRules = chunkWVDM36ZM_js.buildMorphAnimationRules(morphPlan, "", "incoming", "image");
|
|
2560
2574
|
return `${presentationKeyframesCss ?? ""}
|
|
2561
2575
|
${morphPlan.keyframesCss}
|
|
2562
2576
|
${imageRules}`;
|
|
@@ -2852,7 +2866,7 @@ function useFindReplace({
|
|
|
2852
2866
|
const [findResults, setFindResults] = react.useState([]);
|
|
2853
2867
|
const [findResultIndex, setFindResultIndex] = react.useState(-1);
|
|
2854
2868
|
const performFind = react.useCallback(() => {
|
|
2855
|
-
const results =
|
|
2869
|
+
const results = chunkWVDM36ZM_js.findInSlides(slides, findQuery, { matchCase: findMatchCase });
|
|
2856
2870
|
if (!findQuery) {
|
|
2857
2871
|
setFindResults([]);
|
|
2858
2872
|
setFindResultIndex(-1);
|
|
@@ -2886,7 +2900,7 @@ function useFindReplace({
|
|
|
2886
2900
|
return;
|
|
2887
2901
|
}
|
|
2888
2902
|
onUpdateSlides(
|
|
2889
|
-
(prevSlides) =>
|
|
2903
|
+
(prevSlides) => chunkWVDM36ZM_js.applyFindReplacements(prevSlides, toReplace, replaceQuery).slides
|
|
2890
2904
|
);
|
|
2891
2905
|
onMarkDirty();
|
|
2892
2906
|
},
|
|
@@ -2908,13 +2922,15 @@ function useFindReplace({
|
|
|
2908
2922
|
}, [findResults, applyReplacements, performFind]);
|
|
2909
2923
|
react.useEffect(() => {
|
|
2910
2924
|
const handler = (event) => {
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2925
|
+
const { action } = chunkWVDM36ZM_js.mapEditorKey(event, {
|
|
2926
|
+
canEdit: mode === "edit",
|
|
2927
|
+
isTextInputTarget: chunkWVDM36ZM_js.isEditorTextInputTarget(event.target)
|
|
2928
|
+
});
|
|
2929
|
+
if (action !== "find") {
|
|
2930
|
+
return;
|
|
2917
2931
|
}
|
|
2932
|
+
event.preventDefault();
|
|
2933
|
+
setFindReplaceOpen((prev) => !prev);
|
|
2918
2934
|
};
|
|
2919
2935
|
window.addEventListener("keydown", handler);
|
|
2920
2936
|
return () => window.removeEventListener("keydown", handler);
|
|
@@ -3354,9 +3370,28 @@ function useDerivedElementState(input) {
|
|
|
3354
3370
|
}
|
|
3355
3371
|
return templateElementsBySlideId[activeSlide.id] ?? [];
|
|
3356
3372
|
}, [activeSlide, templateElementsBySlideId]);
|
|
3373
|
+
const activeMaster = slideMasters[activeMasterIndex];
|
|
3374
|
+
const activeLayout = react.useMemo(
|
|
3375
|
+
() => resolveActiveLayout(activeMaster, activeLayoutIndex),
|
|
3376
|
+
[activeMaster, activeLayoutIndex]
|
|
3377
|
+
);
|
|
3378
|
+
const masterViewElements2 = react.useMemo(
|
|
3379
|
+
() => computeMasterViewElements(activeMaster, activeLayout),
|
|
3380
|
+
[activeMaster, activeLayout]
|
|
3381
|
+
);
|
|
3382
|
+
const notesMasterElements = react.useMemo(() => notesMaster?.elements ?? [], [notesMaster]);
|
|
3383
|
+
const handoutMasterElements = react.useMemo(() => handoutMaster?.elements ?? [], [handoutMaster]);
|
|
3357
3384
|
const elementLookup = react.useMemo(
|
|
3358
|
-
() => buildElementLookup(
|
|
3359
|
-
|
|
3385
|
+
() => buildElementLookup(
|
|
3386
|
+
[
|
|
3387
|
+
...templateElements,
|
|
3388
|
+
...masterViewElements2,
|
|
3389
|
+
...notesMasterElements,
|
|
3390
|
+
...handoutMasterElements
|
|
3391
|
+
],
|
|
3392
|
+
activeSlide?.elements ?? []
|
|
3393
|
+
),
|
|
3394
|
+
[activeSlide, templateElements, masterViewElements2, notesMasterElements, handoutMasterElements]
|
|
3360
3395
|
);
|
|
3361
3396
|
const selectedElement = react.useMemo(() => {
|
|
3362
3397
|
if (!selectedElementId) {
|
|
@@ -3373,17 +3408,6 @@ function useDerivedElementState(input) {
|
|
|
3373
3408
|
() => effectiveSelectedIds.map((id) => elementLookup.get(id)).filter(Boolean),
|
|
3374
3409
|
[effectiveSelectedIds, elementLookup]
|
|
3375
3410
|
);
|
|
3376
|
-
const activeMaster = slideMasters[activeMasterIndex];
|
|
3377
|
-
const activeLayout = react.useMemo(
|
|
3378
|
-
() => resolveActiveLayout(activeMaster, activeLayoutIndex),
|
|
3379
|
-
[activeMaster, activeLayoutIndex]
|
|
3380
|
-
);
|
|
3381
|
-
const masterViewElements = react.useMemo(
|
|
3382
|
-
() => computeMasterViewElements(activeMaster, activeLayout),
|
|
3383
|
-
[activeMaster, activeLayout]
|
|
3384
|
-
);
|
|
3385
|
-
const notesMasterElements = react.useMemo(() => notesMaster?.elements ?? [], [notesMaster]);
|
|
3386
|
-
const handoutMasterElements = react.useMemo(() => handoutMaster?.elements ?? [], [handoutMaster]);
|
|
3387
3411
|
return {
|
|
3388
3412
|
activeSlide,
|
|
3389
3413
|
templateElements,
|
|
@@ -3394,7 +3418,7 @@ function useDerivedElementState(input) {
|
|
|
3394
3418
|
selectedElements,
|
|
3395
3419
|
activeMaster,
|
|
3396
3420
|
activeLayout,
|
|
3397
|
-
masterViewElements,
|
|
3421
|
+
masterViewElements: masterViewElements2,
|
|
3398
3422
|
notesMasterElements,
|
|
3399
3423
|
handoutMasterElements
|
|
3400
3424
|
};
|
|
@@ -3410,7 +3434,7 @@ function useViewerCoreState(_input) {
|
|
|
3410
3434
|
const marqueeStateRef = react.useRef(null);
|
|
3411
3435
|
const isDrawingRef = react.useRef(false);
|
|
3412
3436
|
const justInteractedRef = react.useRef(false);
|
|
3413
|
-
const livePatcher = react.useMemo(() =>
|
|
3437
|
+
const livePatcher = react.useMemo(() => chunkWVDM36ZM_js.createCollaborationLivePatcher(), []);
|
|
3414
3438
|
react.useEffect(() => () => livePatcher.dispose(), [livePatcher]);
|
|
3415
3439
|
const slidesRef = react.useRef([]);
|
|
3416
3440
|
const [mode, setMode] = react.useState("edit");
|
|
@@ -3419,9 +3443,10 @@ function useViewerCoreState(_input) {
|
|
|
3419
3443
|
const [slides, setSlides] = react.useState([]);
|
|
3420
3444
|
const [templateElementsBySlideId, setTemplateElementsBySlideId] = react.useState({});
|
|
3421
3445
|
const [canvasSize, setCanvasSize] = react.useState({
|
|
3422
|
-
width:
|
|
3423
|
-
height:
|
|
3446
|
+
width: chunk4LWGAVAP_js.DEFAULT_CANVAS_WIDTH,
|
|
3447
|
+
height: chunk4LWGAVAP_js.DEFAULT_CANVAS_HEIGHT
|
|
3424
3448
|
});
|
|
3449
|
+
const [slideSizeEmu, setSlideSizeEmu] = react.useState();
|
|
3425
3450
|
const [activeSlideIndex, setActiveSlideIndex] = react.useState(0);
|
|
3426
3451
|
const [selectedElementId, setSelectedElementId] = react.useState(null);
|
|
3427
3452
|
const [selectedElementIds, setSelectedElementIds] = react.useState([]);
|
|
@@ -3440,7 +3465,7 @@ function useViewerCoreState(_input) {
|
|
|
3440
3465
|
const resolved = typeof value === "function" ? value(inlineEditingTextRef.current) : value;
|
|
3441
3466
|
inlineEditingTextRef.current = resolved;
|
|
3442
3467
|
setInlineEditingTextBase(value);
|
|
3443
|
-
|
|
3468
|
+
chunkWVDM36ZM_js.publishLiveInlineText(
|
|
3444
3469
|
livePatcher,
|
|
3445
3470
|
slidesRef.current[activeSlideIndexRef.current],
|
|
3446
3471
|
inlineEditingElementIdRef.current,
|
|
@@ -3520,6 +3545,8 @@ function useViewerCoreState(_input) {
|
|
|
3520
3545
|
setTemplateElementsBySlideId,
|
|
3521
3546
|
canvasSize,
|
|
3522
3547
|
setCanvasSize,
|
|
3548
|
+
slideSizeEmu,
|
|
3549
|
+
setSlideSizeEmu,
|
|
3523
3550
|
activeSlideIndex,
|
|
3524
3551
|
setActiveSlideIndex,
|
|
3525
3552
|
selectedElementId,
|
|
@@ -3724,6 +3751,7 @@ function useLoadContent({
|
|
|
3724
3751
|
setTemplateElementsBySlideId,
|
|
3725
3752
|
mediaDataUrls,
|
|
3726
3753
|
setCanvasSize,
|
|
3754
|
+
setSlideSizeEmu,
|
|
3727
3755
|
setHeaderFooter,
|
|
3728
3756
|
setLayoutOptions,
|
|
3729
3757
|
setSlideMasters,
|
|
@@ -3731,6 +3759,7 @@ function useLoadContent({
|
|
|
3731
3759
|
setTableStyleMap,
|
|
3732
3760
|
setThemeOptions,
|
|
3733
3761
|
setCustomShows,
|
|
3762
|
+
setActiveCustomShowId,
|
|
3734
3763
|
setSections,
|
|
3735
3764
|
setPresentationProperties,
|
|
3736
3765
|
setNotesMaster,
|
|
@@ -3775,7 +3804,7 @@ function useLoadContent({
|
|
|
3775
3804
|
);
|
|
3776
3805
|
}
|
|
3777
3806
|
const previousHandler = handlerRef.current;
|
|
3778
|
-
const handler = new
|
|
3807
|
+
const handler = new chunkWVDM36ZM_js.PptxHandler();
|
|
3779
3808
|
const parsed = await handler.load(buffer);
|
|
3780
3809
|
if (cancelled || token !== renderTokenRef.current) {
|
|
3781
3810
|
handler.dispose();
|
|
@@ -3787,7 +3816,7 @@ function useLoadContent({
|
|
|
3787
3816
|
handlerRef.current = null;
|
|
3788
3817
|
const mediaElements = [];
|
|
3789
3818
|
for (const slide of parsed.slides) {
|
|
3790
|
-
|
|
3819
|
+
chunkWVDM36ZM_js.collectMediaElements(slide.elements, mediaElements);
|
|
3791
3820
|
}
|
|
3792
3821
|
for (const url of mediaDataUrls.values()) {
|
|
3793
3822
|
if (url.startsWith("blob:")) {
|
|
@@ -3828,7 +3857,7 @@ function useLoadContent({
|
|
|
3828
3857
|
}
|
|
3829
3858
|
})
|
|
3830
3859
|
);
|
|
3831
|
-
const { paths: imagePaths, refs: imageRefs } =
|
|
3860
|
+
const { paths: imagePaths, refs: imageRefs } = chunkWVDM36ZM_js.collectImagePaths(parsed.slides);
|
|
3832
3861
|
let nextSlides = parsed.slides;
|
|
3833
3862
|
if (imagePaths.size > 0) {
|
|
3834
3863
|
const resolvedMap = /* @__PURE__ */ new Map();
|
|
@@ -3883,13 +3912,20 @@ function useLoadContent({
|
|
|
3883
3912
|
}
|
|
3884
3913
|
}
|
|
3885
3914
|
handlerRef.current = handler;
|
|
3886
|
-
const partition =
|
|
3915
|
+
const partition = chunkWVDM36ZM_js.partitionTemplateElements(nextSlides);
|
|
3887
3916
|
setSlides(partition.slides);
|
|
3888
3917
|
setTemplateElementsBySlideId(partition.templateElementsBySlideId);
|
|
3889
3918
|
setCanvasSize({
|
|
3890
|
-
width: parsed.width ??
|
|
3891
|
-
height: parsed.height ??
|
|
3919
|
+
width: parsed.width ?? chunk4LWGAVAP_js.DEFAULT_CANVAS_WIDTH,
|
|
3920
|
+
height: parsed.height ?? chunk4LWGAVAP_js.DEFAULT_CANVAS_HEIGHT
|
|
3892
3921
|
});
|
|
3922
|
+
setSlideSizeEmu(
|
|
3923
|
+
typeof parsed.widthEmu === "number" && typeof parsed.heightEmu === "number" && parsed.widthEmu > 0 && parsed.heightEmu > 0 ? {
|
|
3924
|
+
widthEmu: parsed.widthEmu,
|
|
3925
|
+
heightEmu: parsed.heightEmu,
|
|
3926
|
+
type: parsed.slideSizeType ?? ""
|
|
3927
|
+
} : void 0
|
|
3928
|
+
);
|
|
3893
3929
|
setHeaderFooter(parsed.headerFooter ?? {});
|
|
3894
3930
|
setLayoutOptions(parsed.layoutOptions ?? []);
|
|
3895
3931
|
setSlideMasters(parsed.slideMasters ?? []);
|
|
@@ -3897,6 +3933,9 @@ function useLoadContent({
|
|
|
3897
3933
|
setTableStyleMap(parsed.tableStyleMap);
|
|
3898
3934
|
setThemeOptions(parsed.themeOptions ?? []);
|
|
3899
3935
|
setCustomShows(parsed.customShows ?? []);
|
|
3936
|
+
setActiveCustomShowId(
|
|
3937
|
+
chunkWVDM36ZM_js.resolveAuthoredCustomShowId(parsed.presentationProperties, parsed.customShows) ?? null
|
|
3938
|
+
);
|
|
3900
3939
|
setSections(parsed.sections ?? []);
|
|
3901
3940
|
setPresentationProperties(parsed.presentationProperties ?? {});
|
|
3902
3941
|
setNotesMaster(parsed.notesMaster);
|
|
@@ -3917,7 +3956,7 @@ function useLoadContent({
|
|
|
3917
3956
|
setHasMacros(parsed.hasMacros === true);
|
|
3918
3957
|
setHasDigitalSignatures(parsed.hasDigitalSignatures === true);
|
|
3919
3958
|
setDigitalSignatureCount(parsed.digitalSignatureCount ?? 0);
|
|
3920
|
-
setGuides(
|
|
3959
|
+
setGuides(chunkWVDM36ZM_js.buildInitialGuides(parsed.presentationGuides, parsed.slides[0]?.guides));
|
|
3921
3960
|
setActiveSlideIndex(0);
|
|
3922
3961
|
clearSelection();
|
|
3923
3962
|
setIsDirty(false);
|
|
@@ -3925,7 +3964,7 @@ function useLoadContent({
|
|
|
3925
3964
|
onContentApplied?.();
|
|
3926
3965
|
} catch (err) {
|
|
3927
3966
|
if (!cancelled && token === renderTokenRef.current) {
|
|
3928
|
-
if (err instanceof
|
|
3967
|
+
if (err instanceof chunkWVDM36ZM_js.EncryptedFileError) {
|
|
3929
3968
|
setIsEncrypted(true);
|
|
3930
3969
|
} else {
|
|
3931
3970
|
setError(err instanceof Error ? err.message : String(err));
|
|
@@ -3965,7 +4004,8 @@ function useAutosave(input) {
|
|
|
3965
4004
|
filePath,
|
|
3966
4005
|
serializeSlides,
|
|
3967
4006
|
intervalSeconds = DEFAULT_AUTOSAVE_INTERVAL_SECONDS,
|
|
3968
|
-
enabled = true
|
|
4007
|
+
enabled = true,
|
|
4008
|
+
getChangeSources
|
|
3969
4009
|
} = input;
|
|
3970
4010
|
const [autosaveStatus, setAutosaveStatus] = react.useState({
|
|
3971
4011
|
state: "idle"
|
|
@@ -3974,6 +4014,8 @@ function useAutosave(input) {
|
|
|
3974
4014
|
const filePathRef = react.useRef(filePath);
|
|
3975
4015
|
const serializeRef = react.useRef(serializeSlides);
|
|
3976
4016
|
const isSavingRef = react.useRef(false);
|
|
4017
|
+
const changeSourcesRef = react.useRef(getChangeSources);
|
|
4018
|
+
const lastSnapshotRef = react.useRef(void 0);
|
|
3977
4019
|
react.useEffect(() => {
|
|
3978
4020
|
isDirtyRef.current = isDirty;
|
|
3979
4021
|
}, [isDirty]);
|
|
@@ -3983,14 +4025,22 @@ function useAutosave(input) {
|
|
|
3983
4025
|
react.useEffect(() => {
|
|
3984
4026
|
serializeRef.current = serializeSlides;
|
|
3985
4027
|
}, [serializeSlides]);
|
|
3986
|
-
|
|
3987
|
-
|
|
3988
|
-
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
4028
|
+
react.useEffect(() => {
|
|
4029
|
+
changeSourcesRef.current = getChangeSources;
|
|
4030
|
+
}, [getChangeSources]);
|
|
4031
|
+
const doAutosave = react.useCallback(async (options) => {
|
|
4032
|
+
const path = filePathRef.current;
|
|
4033
|
+
if (!path) {
|
|
4034
|
+
return;
|
|
4035
|
+
}
|
|
4036
|
+
const sources = changeSourcesRef.current?.() ?? [];
|
|
4037
|
+
if (!chunkWVDM36ZM_js.shouldWriteAutosaveSnapshot({
|
|
4038
|
+
filePath: path,
|
|
4039
|
+
isDirty: isDirtyRef.current,
|
|
4040
|
+
saving: isSavingRef.current,
|
|
4041
|
+
sources: options?.polled === true ? sources : [],
|
|
4042
|
+
lastSnapshot: lastSnapshotRef.current
|
|
4043
|
+
})) {
|
|
3994
4044
|
return;
|
|
3995
4045
|
}
|
|
3996
4046
|
isSavingRef.current = true;
|
|
@@ -4002,7 +4052,8 @@ function useAutosave(input) {
|
|
|
4002
4052
|
isSavingRef.current = false;
|
|
4003
4053
|
return;
|
|
4004
4054
|
}
|
|
4005
|
-
await
|
|
4055
|
+
await chunkWVDM36ZM_js.saveAutosaveSnapshot(path, data);
|
|
4056
|
+
lastSnapshotRef.current = chunkWVDM36ZM_js.autosaveSnapshotMark(path, sources);
|
|
4006
4057
|
setAutosaveStatus({ state: "saved", timestamp: Date.now() });
|
|
4007
4058
|
} catch (err) {
|
|
4008
4059
|
setAutosaveStatus({
|
|
@@ -4028,13 +4079,13 @@ function useAutosave(input) {
|
|
|
4028
4079
|
setAutosaveStatus((prev) => prev.state === "disabled" ? { state: "idle" } : prev);
|
|
4029
4080
|
const ms = computeAutosaveIntervalMs(intervalSeconds);
|
|
4030
4081
|
const id = setInterval(() => {
|
|
4031
|
-
void doAutosave();
|
|
4082
|
+
void doAutosave({ polled: true });
|
|
4032
4083
|
}, ms);
|
|
4033
4084
|
return () => clearInterval(id);
|
|
4034
4085
|
}, [enabled, filePath, intervalSeconds, doAutosave]);
|
|
4035
4086
|
return {
|
|
4036
4087
|
autosaveStatus,
|
|
4037
|
-
triggerAutosave: doAutosave
|
|
4088
|
+
triggerAutosave: () => doAutosave()
|
|
4038
4089
|
};
|
|
4039
4090
|
}
|
|
4040
4091
|
function useElementOperations(input) {
|
|
@@ -4045,6 +4096,7 @@ function useElementOperations(input) {
|
|
|
4045
4096
|
selectedElementId,
|
|
4046
4097
|
editTemplateMode,
|
|
4047
4098
|
templateElements,
|
|
4099
|
+
masterView,
|
|
4048
4100
|
history,
|
|
4049
4101
|
setSlides,
|
|
4050
4102
|
setTemplateElementsBySlideId,
|
|
@@ -4065,9 +4117,34 @@ function useElementOperations(input) {
|
|
|
4065
4117
|
setInlineEditingElementId(null);
|
|
4066
4118
|
setContextMenuState(null);
|
|
4067
4119
|
}, [applySelection, setInlineEditingElementId, setContextMenuState]);
|
|
4120
|
+
const applyMasterViewWrite = react.useCallback(
|
|
4121
|
+
(write) => {
|
|
4122
|
+
if (!write || !masterView) {
|
|
4123
|
+
return false;
|
|
4124
|
+
}
|
|
4125
|
+
if (write.slideMasters) {
|
|
4126
|
+
masterView.setSlideMasters(write.slideMasters);
|
|
4127
|
+
}
|
|
4128
|
+
if (write.notesMaster) {
|
|
4129
|
+
masterView.setNotesMaster(write.notesMaster);
|
|
4130
|
+
}
|
|
4131
|
+
if (write.handoutMaster) {
|
|
4132
|
+
masterView.setHandoutMaster(write.handoutMaster);
|
|
4133
|
+
}
|
|
4134
|
+
history.markDirty();
|
|
4135
|
+
return true;
|
|
4136
|
+
},
|
|
4137
|
+
[history, masterView]
|
|
4138
|
+
);
|
|
4068
4139
|
const updateElementById = react.useCallback(
|
|
4069
4140
|
(elementId, updates) => {
|
|
4070
|
-
if (
|
|
4141
|
+
if (masterView?.target) {
|
|
4142
|
+
applyMasterViewWrite(
|
|
4143
|
+
chunkWVDM36ZM_js.updateMasterViewElement(masterView, masterView.target, elementId, updates)
|
|
4144
|
+
);
|
|
4145
|
+
return;
|
|
4146
|
+
}
|
|
4147
|
+
if (chunkWVDM36ZM_js.isTemplateElementId(elementId)) {
|
|
4071
4148
|
const slideId = activeSlide?.id;
|
|
4072
4149
|
if (slideId) {
|
|
4073
4150
|
setTemplateElementsBySlideId((prev) => ({
|
|
@@ -4094,7 +4171,15 @@ function useElementOperations(input) {
|
|
|
4094
4171
|
}
|
|
4095
4172
|
history.markDirty();
|
|
4096
4173
|
},
|
|
4097
|
-
[
|
|
4174
|
+
[
|
|
4175
|
+
activeSlide?.id,
|
|
4176
|
+
activeSlideIndex,
|
|
4177
|
+
applyMasterViewWrite,
|
|
4178
|
+
history,
|
|
4179
|
+
masterView,
|
|
4180
|
+
setSlides,
|
|
4181
|
+
setTemplateElementsBySlideId
|
|
4182
|
+
]
|
|
4098
4183
|
);
|
|
4099
4184
|
const updateSelectedElement = react.useCallback(
|
|
4100
4185
|
(updates) => {
|
|
@@ -4107,7 +4192,7 @@ function useElementOperations(input) {
|
|
|
4107
4192
|
);
|
|
4108
4193
|
const updateSelectedShapeStyle = react.useCallback(
|
|
4109
4194
|
(updates) => {
|
|
4110
|
-
if (!selectedElement || !
|
|
4195
|
+
if (!selectedElement || !chunkWVDM36ZM_js.hasShapeProperties(selectedElement)) {
|
|
4111
4196
|
return;
|
|
4112
4197
|
}
|
|
4113
4198
|
updateSelectedElement({
|
|
@@ -4118,17 +4203,17 @@ function useElementOperations(input) {
|
|
|
4118
4203
|
);
|
|
4119
4204
|
const updateSelectedTextStyle = react.useCallback(
|
|
4120
4205
|
(updates) => {
|
|
4121
|
-
if (!selectedElement || !
|
|
4206
|
+
if (!selectedElement || !chunkWVDM36ZM_js.hasTextProperties(selectedElement)) {
|
|
4122
4207
|
return;
|
|
4123
4208
|
}
|
|
4124
|
-
const inlineSel =
|
|
4209
|
+
const inlineSel = chunkWVDM36ZM_js.getInlineEditorSelection(selectedElement.textSegments);
|
|
4125
4210
|
if (inlineSel && selectedElement.textSegments) {
|
|
4126
|
-
const { newSegments: newSegments2, newSelection } =
|
|
4211
|
+
const { newSegments: newSegments2, newSelection } = chunkWVDM36ZM_js.applyStyleToSelectedSegments(
|
|
4127
4212
|
selectedElement.textSegments,
|
|
4128
4213
|
inlineSel,
|
|
4129
4214
|
updates
|
|
4130
4215
|
);
|
|
4131
|
-
|
|
4216
|
+
chunkWVDM36ZM_js.setPendingSelectionRestore(newSelection);
|
|
4132
4217
|
updateSelectedElement({
|
|
4133
4218
|
textSegments: newSegments2
|
|
4134
4219
|
});
|
|
@@ -4148,12 +4233,12 @@ function useElementOperations(input) {
|
|
|
4148
4233
|
);
|
|
4149
4234
|
const updateSelectedTextCase = react.useCallback(
|
|
4150
4235
|
(mode) => {
|
|
4151
|
-
if (!selectedElement || !
|
|
4236
|
+
if (!selectedElement || !chunkWVDM36ZM_js.hasTextProperties(selectedElement)) {
|
|
4152
4237
|
return;
|
|
4153
4238
|
}
|
|
4154
|
-
const inlineSel =
|
|
4239
|
+
const inlineSel = chunkWVDM36ZM_js.getInlineEditorSelection(selectedElement.textSegments);
|
|
4155
4240
|
if (inlineSel && selectedElement.textSegments) {
|
|
4156
|
-
const newSegments =
|
|
4241
|
+
const newSegments = chunkWVDM36ZM_js.applyCaseTransformToSegments(
|
|
4157
4242
|
selectedElement.textSegments,
|
|
4158
4243
|
inlineSel,
|
|
4159
4244
|
mode
|
|
@@ -4163,14 +4248,14 @@ function useElementOperations(input) {
|
|
|
4163
4248
|
}
|
|
4164
4249
|
const updates = {};
|
|
4165
4250
|
if (selectedElement.textSegments && selectedElement.textSegments.length > 0) {
|
|
4166
|
-
updates.textSegments =
|
|
4251
|
+
updates.textSegments = chunkWVDM36ZM_js.applyCaseTransformToSegments(
|
|
4167
4252
|
selectedElement.textSegments,
|
|
4168
4253
|
null,
|
|
4169
4254
|
mode
|
|
4170
4255
|
);
|
|
4171
4256
|
}
|
|
4172
4257
|
if (typeof selectedElement.text === "string") {
|
|
4173
|
-
updates.text =
|
|
4258
|
+
updates.text = chunkWVDM36ZM_js.transformTextCase(selectedElement.text, mode);
|
|
4174
4259
|
}
|
|
4175
4260
|
updateSelectedElement(updates);
|
|
4176
4261
|
},
|
|
@@ -4182,9 +4267,20 @@ function useElementOperations(input) {
|
|
|
4182
4267
|
},
|
|
4183
4268
|
[setSlides]
|
|
4184
4269
|
);
|
|
4185
|
-
const
|
|
4270
|
+
const masterViewTarget = masterView?.target ?? null;
|
|
4271
|
+
const activeElements = masterViewTarget ? chunkWVDM36ZM_js.masterViewElements(masterView, masterViewTarget) : editTemplateMode ? templateElements : activeSlide?.elements ?? [];
|
|
4186
4272
|
const updateActiveElements = react.useCallback(
|
|
4187
4273
|
(updater) => {
|
|
4274
|
+
if (masterView?.target) {
|
|
4275
|
+
applyMasterViewWrite(
|
|
4276
|
+
chunkWVDM36ZM_js.replaceMasterViewElements(
|
|
4277
|
+
masterView,
|
|
4278
|
+
masterView.target,
|
|
4279
|
+
updater(chunkWVDM36ZM_js.masterViewElements(masterView, masterView.target))
|
|
4280
|
+
)
|
|
4281
|
+
);
|
|
4282
|
+
return;
|
|
4283
|
+
}
|
|
4188
4284
|
if (editTemplateMode) {
|
|
4189
4285
|
const slideId = activeSlide?.id;
|
|
4190
4286
|
if (!slideId) {
|
|
@@ -4202,7 +4298,15 @@ function useElementOperations(input) {
|
|
|
4202
4298
|
);
|
|
4203
4299
|
}
|
|
4204
4300
|
},
|
|
4205
|
-
[
|
|
4301
|
+
[
|
|
4302
|
+
applyMasterViewWrite,
|
|
4303
|
+
editTemplateMode,
|
|
4304
|
+
masterView,
|
|
4305
|
+
activeSlide?.id,
|
|
4306
|
+
activeSlideIndex,
|
|
4307
|
+
setSlides,
|
|
4308
|
+
setTemplateElementsBySlideId
|
|
4309
|
+
]
|
|
4206
4310
|
);
|
|
4207
4311
|
const serializeSlides = react.useCallback(async () => {
|
|
4208
4312
|
return null;
|
|
@@ -4225,7 +4329,7 @@ function useSectionOperations(input) {
|
|
|
4225
4329
|
const { sections, setSections, slides, setSlides, markDirty } = input;
|
|
4226
4330
|
const addSection2 = react.useCallback(
|
|
4227
4331
|
(name, afterSlideIndex) => {
|
|
4228
|
-
const result =
|
|
4332
|
+
const result = chunkWVDM36ZM_js.addSection(sections, slides, name, afterSlideIndex);
|
|
4229
4333
|
setSlides(result.slides);
|
|
4230
4334
|
setSections(result.sections);
|
|
4231
4335
|
markDirty();
|
|
@@ -4234,7 +4338,7 @@ function useSectionOperations(input) {
|
|
|
4234
4338
|
);
|
|
4235
4339
|
const renameSection2 = react.useCallback(
|
|
4236
4340
|
(sectionId, newName) => {
|
|
4237
|
-
const result =
|
|
4341
|
+
const result = chunkWVDM36ZM_js.renameSection(sections, slides, sectionId, newName);
|
|
4238
4342
|
setSections(result.sections);
|
|
4239
4343
|
setSlides(result.slides);
|
|
4240
4344
|
markDirty();
|
|
@@ -4243,7 +4347,7 @@ function useSectionOperations(input) {
|
|
|
4243
4347
|
);
|
|
4244
4348
|
const deleteSection2 = react.useCallback(
|
|
4245
4349
|
(sectionId) => {
|
|
4246
|
-
const result =
|
|
4350
|
+
const result = chunkWVDM36ZM_js.deleteSection(sections, slides, sectionId);
|
|
4247
4351
|
setSections(result.sections);
|
|
4248
4352
|
setSlides(result.slides);
|
|
4249
4353
|
markDirty();
|
|
@@ -4252,57 +4356,62 @@ function useSectionOperations(input) {
|
|
|
4252
4356
|
);
|
|
4253
4357
|
const moveSectionUp2 = react.useCallback(
|
|
4254
4358
|
(sectionId) => {
|
|
4255
|
-
setSections(
|
|
4359
|
+
setSections(chunkWVDM36ZM_js.moveSectionUp(sections, sectionId));
|
|
4256
4360
|
markDirty();
|
|
4257
4361
|
},
|
|
4258
4362
|
[sections, setSections, markDirty]
|
|
4259
4363
|
);
|
|
4260
4364
|
const moveSectionDown2 = react.useCallback(
|
|
4261
4365
|
(sectionId) => {
|
|
4262
|
-
setSections(
|
|
4366
|
+
setSections(chunkWVDM36ZM_js.moveSectionDown(sections, sectionId));
|
|
4263
4367
|
markDirty();
|
|
4264
4368
|
},
|
|
4265
4369
|
[sections, setSections, markDirty]
|
|
4266
4370
|
);
|
|
4267
4371
|
const moveSlidesToSection2 = react.useCallback(
|
|
4268
4372
|
(slideIndexes, targetSectionId) => {
|
|
4269
|
-
const result =
|
|
4373
|
+
const result = chunkWVDM36ZM_js.moveSlidesToSection(sections, slides, slideIndexes, targetSectionId);
|
|
4270
4374
|
setSlides(result.slides);
|
|
4271
4375
|
setSections(result.sections);
|
|
4272
4376
|
markDirty();
|
|
4273
4377
|
},
|
|
4274
4378
|
[sections, slides, setSlides, setSections, markDirty]
|
|
4275
4379
|
);
|
|
4380
|
+
const toggleSectionCollapse = react.useCallback(
|
|
4381
|
+
(sectionId) => {
|
|
4382
|
+
setSections(
|
|
4383
|
+
(prev) => prev.map((sec) => sec.id === sectionId ? { ...sec, collapsed: !sec.collapsed } : sec)
|
|
4384
|
+
);
|
|
4385
|
+
markDirty();
|
|
4386
|
+
},
|
|
4387
|
+
[setSections, markDirty]
|
|
4388
|
+
);
|
|
4276
4389
|
return {
|
|
4277
4390
|
addSection: addSection2,
|
|
4278
4391
|
renameSection: renameSection2,
|
|
4279
4392
|
deleteSection: deleteSection2,
|
|
4280
4393
|
moveSectionUp: moveSectionUp2,
|
|
4281
4394
|
moveSectionDown: moveSectionDown2,
|
|
4282
|
-
moveSlidesToSection: moveSlidesToSection2
|
|
4395
|
+
moveSlidesToSection: moveSlidesToSection2,
|
|
4396
|
+
toggleSectionCollapse
|
|
4283
4397
|
};
|
|
4284
4398
|
}
|
|
4285
4399
|
|
|
4286
4400
|
// src/viewer/hooks/pointer-move-handlers.ts
|
|
4287
4401
|
function computeResizeGeometry(handle, startX, startY, startWidth, startHeight, dx, dy, snapToGrid, gridSpacingPx) {
|
|
4288
|
-
const resized =
|
|
4402
|
+
const resized = chunkWVDM36ZM_js.applyResize(
|
|
4289
4403
|
{ x: startX, y: startY, width: startWidth, height: startHeight },
|
|
4290
4404
|
handle,
|
|
4291
4405
|
dx,
|
|
4292
4406
|
dy,
|
|
4293
4407
|
1,
|
|
4294
|
-
{ minSize:
|
|
4408
|
+
{ minSize: chunk4LWGAVAP_js.MIN_ELEMENT_SIZE }
|
|
4295
4409
|
);
|
|
4296
4410
|
const box = { x: resized.x, y: resized.y, width: resized.width, height: resized.height };
|
|
4297
4411
|
if (!snapToGrid) {
|
|
4298
4412
|
return box;
|
|
4299
4413
|
}
|
|
4300
|
-
return
|
|
4301
|
-
}
|
|
4302
|
-
function computeAdjustmentValue(startAdjustment, dx, startWidth) {
|
|
4303
|
-
const range = startWidth || 200;
|
|
4304
|
-
const delta = dx / range;
|
|
4305
|
-
return Math.max(0, Math.min(1, startAdjustment + delta));
|
|
4414
|
+
return chunkWVDM36ZM_js.snapBoxToGrid(box, handle, gridSpacingPx, chunk4LWGAVAP_js.MIN_ELEMENT_SIZE);
|
|
4306
4415
|
}
|
|
4307
4416
|
function resolveLiveTarget(input) {
|
|
4308
4417
|
const { livePatcher, editTemplateMode, activeSlide } = input;
|
|
@@ -4415,7 +4524,7 @@ function processDragMove(e, drag, editorScale, snapToGrid, snapToShape, gridSpac
|
|
|
4415
4524
|
width: el.width,
|
|
4416
4525
|
height: el.height
|
|
4417
4526
|
}));
|
|
4418
|
-
const snapResult =
|
|
4527
|
+
const snapResult = chunkWVDM36ZM_js.computeSnapToShape(
|
|
4419
4528
|
targetX,
|
|
4420
4529
|
targetY,
|
|
4421
4530
|
primaryEl.width,
|
|
@@ -4454,7 +4563,7 @@ function processDragMove(e, drag, editorScale, snapToGrid, snapToShape, gridSpac
|
|
|
4454
4563
|
if (live) {
|
|
4455
4564
|
for (const id of Object.keys(drag.startPositionsById)) {
|
|
4456
4565
|
const start = drag.startPositionsById[id];
|
|
4457
|
-
|
|
4566
|
+
chunkWVDM36ZM_js.publishLiveGeometry(live.patcher, live.slideId, id, {
|
|
4458
4567
|
x: start.x + appliedDx,
|
|
4459
4568
|
y: start.y + appliedDy
|
|
4460
4569
|
});
|
|
@@ -4488,27 +4597,28 @@ function processResizeMove(e, rs, editorScale, snapToGrid, gridSpacingPx, live)
|
|
|
4488
4597
|
if (rs.domEl) {
|
|
4489
4598
|
rs.domEl.style.left = `${geo.x}px`;
|
|
4490
4599
|
rs.domEl.style.top = `${geo.y}px`;
|
|
4491
|
-
rs.domEl.style.width = `${Math.max(geo.width,
|
|
4492
|
-
rs.domEl.style.height = `${Math.max(geo.height,
|
|
4600
|
+
rs.domEl.style.width = `${Math.max(geo.width, chunk4LWGAVAP_js.MIN_ELEMENT_SIZE)}px`;
|
|
4601
|
+
rs.domEl.style.height = `${Math.max(geo.height, chunk4LWGAVAP_js.MIN_ELEMENT_SIZE)}px`;
|
|
4493
4602
|
}
|
|
4494
4603
|
if (live) {
|
|
4495
|
-
|
|
4604
|
+
chunkWVDM36ZM_js.publishLiveGeometry(live.patcher, live.slideId, rs.elementId, {
|
|
4496
4605
|
x: geo.x,
|
|
4497
4606
|
y: geo.y,
|
|
4498
|
-
width: Math.max(geo.width,
|
|
4499
|
-
height: Math.max(geo.height,
|
|
4607
|
+
width: Math.max(geo.width, chunk4LWGAVAP_js.MIN_ELEMENT_SIZE),
|
|
4608
|
+
height: Math.max(geo.height, chunk4LWGAVAP_js.MIN_ELEMENT_SIZE)
|
|
4500
4609
|
});
|
|
4501
4610
|
}
|
|
4502
4611
|
}
|
|
4503
4612
|
function processAdjustmentMove(e, adj, editorScale, updateElementById) {
|
|
4504
4613
|
const dx = (e.clientX - adj.startClientX) / editorScale;
|
|
4505
|
-
const
|
|
4506
|
-
|
|
4614
|
+
const dy = (e.clientY - adj.startClientY) / editorScale;
|
|
4615
|
+
const adjustments = chunkWVDM36ZM_js.getDraggedShapeAdjustments(adj, dx, dy);
|
|
4616
|
+
if (!adj.moved && Math.hypot(dx, dy) > 2) {
|
|
4507
4617
|
adj.moved = true;
|
|
4508
4618
|
}
|
|
4509
4619
|
if (adj.moved) {
|
|
4510
4620
|
updateElementById(adj.elementId, {
|
|
4511
|
-
shapeAdjustments:
|
|
4621
|
+
shapeAdjustments: adjustments
|
|
4512
4622
|
});
|
|
4513
4623
|
}
|
|
4514
4624
|
}
|
|
@@ -4577,13 +4687,13 @@ function processPointerUp(input) {
|
|
|
4577
4687
|
if (i !== activeSlideIndex) {
|
|
4578
4688
|
return s;
|
|
4579
4689
|
}
|
|
4580
|
-
const rerouted =
|
|
4690
|
+
const rerouted = chunkWVDM36ZM_js.rerouteConnectorsForMovedElements(s.elements, movedIds);
|
|
4581
4691
|
if (rerouted.length === 0) {
|
|
4582
4692
|
return s;
|
|
4583
4693
|
}
|
|
4584
4694
|
return {
|
|
4585
4695
|
...s,
|
|
4586
|
-
elements:
|
|
4696
|
+
elements: chunkWVDM36ZM_js.applyReroutedConnectors(s.elements, rerouted)
|
|
4587
4697
|
};
|
|
4588
4698
|
})
|
|
4589
4699
|
);
|
|
@@ -4608,9 +4718,9 @@ function processPointerUp(input) {
|
|
|
4608
4718
|
}
|
|
4609
4719
|
function commitMarquee(marquee, editTemplateMode, templateElements, activeSlide, applySelection, clearSelection) {
|
|
4610
4720
|
const sourceElements = editTemplateMode ? templateElements : activeSlide?.elements ?? [];
|
|
4611
|
-
const hitIds =
|
|
4721
|
+
const hitIds = chunkWVDM36ZM_js.computeMarqueeHitIds(marquee, sourceElements);
|
|
4612
4722
|
if (marquee.additive) {
|
|
4613
|
-
const merged =
|
|
4723
|
+
const merged = chunkWVDM36ZM_js.mergeAdditiveSelection(marquee.baseSelectionIds, hitIds);
|
|
4614
4724
|
if (merged.length > 0) {
|
|
4615
4725
|
applySelection(merged[0], merged);
|
|
4616
4726
|
} else {
|
|
@@ -4633,8 +4743,8 @@ function commitDrag(drag, editTemplateMode, activeSlide, activeSlideIndex, setTe
|
|
|
4633
4743
|
}
|
|
4634
4744
|
return { ...el, x: start.x + dx, y: start.y + dy };
|
|
4635
4745
|
});
|
|
4636
|
-
const rerouted =
|
|
4637
|
-
return
|
|
4746
|
+
const rerouted = chunkWVDM36ZM_js.rerouteConnectorsForMovedElements(movedElements, movedIds);
|
|
4747
|
+
return chunkWVDM36ZM_js.applyReroutedConnectors(movedElements, rerouted);
|
|
4638
4748
|
};
|
|
4639
4749
|
if (editTemplateMode) {
|
|
4640
4750
|
const slideId = activeSlide?.id;
|
|
@@ -4791,9 +4901,9 @@ function useCanvasInteractions(input) {
|
|
|
4791
4901
|
return;
|
|
4792
4902
|
}
|
|
4793
4903
|
const el = elementLookup.get(editId);
|
|
4794
|
-
if (el &&
|
|
4904
|
+
if (el && chunkWVDM36ZM_js.hasTextProperties(el)) {
|
|
4795
4905
|
const committedText = transformCommittedText ? transformCommittedText(inlineEditingText) : inlineEditingText;
|
|
4796
|
-
const newSegments =
|
|
4906
|
+
const newSegments = chunkWVDM36ZM_js.remapTextToSegments(committedText, el.textSegments, el.textStyle);
|
|
4797
4907
|
ops.updateElementById(editId, {
|
|
4798
4908
|
text: committedText,
|
|
4799
4909
|
textSegments: newSegments
|
|
@@ -4804,7 +4914,7 @@ function useCanvasInteractions(input) {
|
|
|
4804
4914
|
setInlineEditingText("");
|
|
4805
4915
|
};
|
|
4806
4916
|
const openEquationEditorForElement = (el) => {
|
|
4807
|
-
if (!
|
|
4917
|
+
if (!chunkWVDM36ZM_js.hasTextProperties(el)) {
|
|
4808
4918
|
return false;
|
|
4809
4919
|
}
|
|
4810
4920
|
const eqSeg = el.textSegments?.find((seg) => seg.equationXml);
|
|
@@ -4834,7 +4944,7 @@ function useCanvasInteractions(input) {
|
|
|
4834
4944
|
justInteractedRef.current = false;
|
|
4835
4945
|
} else {
|
|
4836
4946
|
const el = elementLookup.get(elementId);
|
|
4837
|
-
if (el &&
|
|
4947
|
+
if (el && chunkWVDM36ZM_js.hasTextProperties(el) && chunkWVDM36ZM_js.canInteractWithElement(el, "textEdit")) {
|
|
4838
4948
|
if (!openEquationEditorForElement(el)) {
|
|
4839
4949
|
setInlineEditingElementId(elementId);
|
|
4840
4950
|
setInlineEditingText(el.text ?? "");
|
|
@@ -4853,7 +4963,7 @@ function useCanvasInteractions(input) {
|
|
|
4853
4963
|
if (openEquationEditorForElement(el)) {
|
|
4854
4964
|
return;
|
|
4855
4965
|
}
|
|
4856
|
-
if (
|
|
4966
|
+
if (chunkWVDM36ZM_js.hasTextProperties(el) && chunkWVDM36ZM_js.canInteractWithElement(el, "textEdit")) {
|
|
4857
4967
|
setInlineEditingElementId(elementId);
|
|
4858
4968
|
setInlineEditingText(el.text ?? "");
|
|
4859
4969
|
}
|
|
@@ -4876,9 +4986,13 @@ function useCanvasInteractions(input) {
|
|
|
4876
4986
|
justSelectedRef.current = false;
|
|
4877
4987
|
}
|
|
4878
4988
|
const ids = !wasSelected ? [elementId] : effectiveSelectedIds.length ? effectiveSelectedIds : [elementId];
|
|
4989
|
+
const movableIds = chunkWVDM36ZM_js.filterInteractableIds(ids, (id) => elementLookup.get(id), "move");
|
|
4990
|
+
if (movableIds.length === 0) {
|
|
4991
|
+
return;
|
|
4992
|
+
}
|
|
4879
4993
|
const startPositions = {};
|
|
4880
4994
|
const domEls = /* @__PURE__ */ new Map();
|
|
4881
|
-
for (const id of
|
|
4995
|
+
for (const id of movableIds) {
|
|
4882
4996
|
const el = elementLookup.get(id);
|
|
4883
4997
|
if (el) {
|
|
4884
4998
|
startPositions[id] = { x: el.x, y: el.y };
|
|
@@ -4942,7 +5056,7 @@ function useCanvasInteractions(input) {
|
|
|
4942
5056
|
const handleResizePointerDown = (elementId, e, handle) => {
|
|
4943
5057
|
e.stopPropagation();
|
|
4944
5058
|
const el = elementLookup.get(elementId);
|
|
4945
|
-
if (!el) {
|
|
5059
|
+
if (!el || !chunkWVDM36ZM_js.canInteractWithElement(el, "resize")) {
|
|
4946
5060
|
return;
|
|
4947
5061
|
}
|
|
4948
5062
|
resizeStateRef.current = {
|
|
@@ -4964,7 +5078,7 @@ function useCanvasInteractions(input) {
|
|
|
4964
5078
|
};
|
|
4965
5079
|
const handleRotate = (elementId, rotationDeg) => {
|
|
4966
5080
|
const el = elementLookup.get(elementId);
|
|
4967
|
-
if (!el || el
|
|
5081
|
+
if (!el || !chunkWVDM36ZM_js.canInteractWithElement(el, "rotate")) {
|
|
4968
5082
|
return;
|
|
4969
5083
|
}
|
|
4970
5084
|
ops.updateElementById(elementId, { rotation: rotationDeg });
|
|
@@ -4981,30 +5095,18 @@ function useCanvasInteractions(input) {
|
|
|
4981
5095
|
const handleFormatText = (updates) => {
|
|
4982
5096
|
ops.updateSelectedTextStyle(updates);
|
|
4983
5097
|
};
|
|
4984
|
-
const handleAdjustmentPointerDown = (elementId, e) => {
|
|
5098
|
+
const handleAdjustmentPointerDown = (elementId, e, descriptor) => {
|
|
4985
5099
|
e.stopPropagation();
|
|
4986
5100
|
const el = elementLookup.get(elementId);
|
|
4987
|
-
if (!el || !(
|
|
5101
|
+
if (!el || !chunkWVDM36ZM_js.canInteractWithElement(el, "adjustHandle")) {
|
|
4988
5102
|
return;
|
|
4989
5103
|
}
|
|
4990
|
-
|
|
4991
|
-
el
|
|
5104
|
+
shapeAdjustmentDragStateRef.current = chunkWVDM36ZM_js.beginShapeAdjustment(
|
|
5105
|
+
el,
|
|
5106
|
+
descriptor,
|
|
5107
|
+
e.clientX,
|
|
5108
|
+
e.clientY
|
|
4992
5109
|
);
|
|
4993
|
-
if (!adjEntries.length) {
|
|
4994
|
-
return;
|
|
4995
|
-
}
|
|
4996
|
-
const [key, value] = adjEntries[0];
|
|
4997
|
-
shapeAdjustmentDragStateRef.current = {
|
|
4998
|
-
elementId,
|
|
4999
|
-
key,
|
|
5000
|
-
shapeType: el.shapeType ?? "rect",
|
|
5001
|
-
startClientX: e.clientX,
|
|
5002
|
-
startClientY: e.clientY,
|
|
5003
|
-
startAdjustment: value,
|
|
5004
|
-
startWidth: el.width,
|
|
5005
|
-
startHeight: el.height,
|
|
5006
|
-
moved: false
|
|
5007
|
-
};
|
|
5008
5110
|
};
|
|
5009
5111
|
return {
|
|
5010
5112
|
handleElementClick,
|
|
@@ -5046,7 +5148,7 @@ function createFileHandlers(deps) {
|
|
|
5046
5148
|
h = Math.round(h * scale);
|
|
5047
5149
|
}
|
|
5048
5150
|
addElement({
|
|
5049
|
-
id:
|
|
5151
|
+
id: chunkWVDM36ZM_js.generateElementId(),
|
|
5050
5152
|
type: "image",
|
|
5051
5153
|
x: Math.round((canvasSize.width - w) / 2),
|
|
5052
5154
|
y: Math.round((canvasSize.height - h) / 2),
|
|
@@ -5057,7 +5159,7 @@ function createFileHandlers(deps) {
|
|
|
5057
5159
|
};
|
|
5058
5160
|
img.onerror = () => {
|
|
5059
5161
|
addElement({
|
|
5060
|
-
id:
|
|
5162
|
+
id: chunkWVDM36ZM_js.generateElementId(),
|
|
5061
5163
|
type: "image",
|
|
5062
5164
|
x: 100,
|
|
5063
5165
|
y: 100,
|
|
@@ -5083,7 +5185,7 @@ function createFileHandlers(deps) {
|
|
|
5083
5185
|
const elFilePath = file.path;
|
|
5084
5186
|
const insertMediaElement = (mediaSourceUrl, width, height) => {
|
|
5085
5187
|
addElement({
|
|
5086
|
-
id:
|
|
5188
|
+
id: chunkWVDM36ZM_js.generateElementId(),
|
|
5087
5189
|
type: "media",
|
|
5088
5190
|
mediaType,
|
|
5089
5191
|
mediaMimeType: file.type || void 0,
|
|
@@ -5258,13 +5360,13 @@ function createStructuredElementHandlers(deps) {
|
|
|
5258
5360
|
return;
|
|
5259
5361
|
}
|
|
5260
5362
|
addElement({
|
|
5261
|
-
id:
|
|
5363
|
+
id: chunkWVDM36ZM_js.generateElementId(),
|
|
5262
5364
|
type: "smartArt",
|
|
5263
5365
|
x: 100,
|
|
5264
5366
|
y: 120,
|
|
5265
5367
|
width: 600,
|
|
5266
5368
|
height: 340,
|
|
5267
|
-
smartArtData:
|
|
5369
|
+
smartArtData: chunkWVDM36ZM_js.buildSmartArtPresetData(
|
|
5268
5370
|
layout,
|
|
5269
5371
|
defaultItems,
|
|
5270
5372
|
(i) => `node-${Date.now()}-${i}-${Math.random().toString(36).slice(2, 8)}`
|
|
@@ -5276,7 +5378,7 @@ function createStructuredElementHandlers(deps) {
|
|
|
5276
5378
|
return;
|
|
5277
5379
|
}
|
|
5278
5380
|
addElement({
|
|
5279
|
-
id:
|
|
5381
|
+
id: chunkWVDM36ZM_js.generateElementId(),
|
|
5280
5382
|
type: "shape",
|
|
5281
5383
|
x: 120,
|
|
5282
5384
|
y: 200,
|
|
@@ -5335,7 +5437,7 @@ function createStructuredElementHandlers(deps) {
|
|
|
5335
5437
|
const displayText = value || fieldTexts[fieldType] || fieldType;
|
|
5336
5438
|
const fieldGuid = `{${crypto.randomUUID().toUpperCase()}}`;
|
|
5337
5439
|
addElement({
|
|
5338
|
-
id:
|
|
5440
|
+
id: chunkWVDM36ZM_js.generateElementId(),
|
|
5339
5441
|
type: "shape",
|
|
5340
5442
|
x: 120,
|
|
5341
5443
|
y: 200,
|
|
@@ -5357,11 +5459,11 @@ function createStructuredElementHandlers(deps) {
|
|
|
5357
5459
|
if (!activeSlide) {
|
|
5358
5460
|
return;
|
|
5359
5461
|
}
|
|
5360
|
-
const preset =
|
|
5462
|
+
const preset = chunkWVDM36ZM_js.ACTION_BUTTON_PRESETS.find((p) => p.shapeType === shapeType);
|
|
5361
5463
|
if (!preset) {
|
|
5362
5464
|
return;
|
|
5363
5465
|
}
|
|
5364
|
-
const defaultPptxAction =
|
|
5466
|
+
const defaultPptxAction = chunkWVDM36ZM_js.elementActionToPptxAction({
|
|
5365
5467
|
trigger: "click",
|
|
5366
5468
|
type: preset.defaultAction
|
|
5367
5469
|
});
|
|
@@ -5370,7 +5472,7 @@ function createStructuredElementHandlers(deps) {
|
|
|
5370
5472
|
defaultPptxAction.highlightClick = true;
|
|
5371
5473
|
}
|
|
5372
5474
|
addElement({
|
|
5373
|
-
id:
|
|
5475
|
+
id: chunkWVDM36ZM_js.generateElementId(),
|
|
5374
5476
|
type: "shape",
|
|
5375
5477
|
x: 150,
|
|
5376
5478
|
y: 150,
|
|
@@ -5437,14 +5539,14 @@ function useInsertElements(input) {
|
|
|
5437
5539
|
return;
|
|
5438
5540
|
}
|
|
5439
5541
|
addElement({
|
|
5440
|
-
id:
|
|
5542
|
+
id: chunkWVDM36ZM_js.generateElementId(),
|
|
5441
5543
|
type: "text",
|
|
5442
5544
|
x: 100,
|
|
5443
5545
|
y: 100,
|
|
5444
5546
|
width: 300,
|
|
5445
5547
|
height: 60,
|
|
5446
5548
|
text: "",
|
|
5447
|
-
textStyle: { fontSize:
|
|
5549
|
+
textStyle: { fontSize: chunk4LWGAVAP_js.DEFAULT_TEXT_FONT_SIZE }
|
|
5448
5550
|
});
|
|
5449
5551
|
};
|
|
5450
5552
|
const handleAddShape = () => {
|
|
@@ -5452,7 +5554,7 @@ function useInsertElements(input) {
|
|
|
5452
5554
|
return;
|
|
5453
5555
|
}
|
|
5454
5556
|
addElement({
|
|
5455
|
-
id:
|
|
5557
|
+
id: chunkWVDM36ZM_js.generateElementId(),
|
|
5456
5558
|
type: "shape",
|
|
5457
5559
|
x: 150,
|
|
5458
5560
|
y: 150,
|
|
@@ -5471,15 +5573,15 @@ function useInsertElements(input) {
|
|
|
5471
5573
|
return;
|
|
5472
5574
|
}
|
|
5473
5575
|
addElement({
|
|
5474
|
-
...
|
|
5475
|
-
id:
|
|
5576
|
+
...chunkWVDM36ZM_js.newTableElement(chunk4LWGAVAP_js.DEFAULT_TABLE_ROWS, chunk4LWGAVAP_js.DEFAULT_TABLE_COLUMNS, 100, 200),
|
|
5577
|
+
id: chunkWVDM36ZM_js.generateElementId()
|
|
5476
5578
|
});
|
|
5477
5579
|
};
|
|
5478
5580
|
const handleAddChart = (chartKind) => {
|
|
5479
5581
|
if (!activeSlide) {
|
|
5480
5582
|
return;
|
|
5481
5583
|
}
|
|
5482
|
-
addElement(
|
|
5584
|
+
addElement(chunkWVDM36ZM_js.createDefaultChartElement(chartKind));
|
|
5483
5585
|
};
|
|
5484
5586
|
const structured = createStructuredElementHandlers({
|
|
5485
5587
|
activeSlide,
|
|
@@ -5549,7 +5651,7 @@ function useClipboardHandlers(input) {
|
|
|
5549
5651
|
if (!selectedElement) {
|
|
5550
5652
|
return;
|
|
5551
5653
|
}
|
|
5552
|
-
setClipboardPayload(
|
|
5654
|
+
setClipboardPayload(chunkWVDM36ZM_js.buildElementClipboardPayload(selectedElement, editTemplateMode));
|
|
5553
5655
|
};
|
|
5554
5656
|
const handleDelete = () => {
|
|
5555
5657
|
const idsToDelete = effectiveSelectedIds;
|
|
@@ -5566,7 +5668,7 @@ function useClipboardHandlers(input) {
|
|
|
5566
5668
|
handleDelete();
|
|
5567
5669
|
};
|
|
5568
5670
|
const insertClone = (source) => {
|
|
5569
|
-
const clone =
|
|
5671
|
+
const clone = chunkWVDM36ZM_js.cloneElementForPaste(source, { intoTemplate: editTemplateMode });
|
|
5570
5672
|
ops.updateActiveElements((els) => [...els, clone]);
|
|
5571
5673
|
ops.applySelection(clone.id);
|
|
5572
5674
|
history.markDirty();
|
|
@@ -5601,7 +5703,7 @@ function resolveShapePath(el) {
|
|
|
5601
5703
|
return el.pathData;
|
|
5602
5704
|
}
|
|
5603
5705
|
if ("shapeType" in el && typeof el.shapeType === "string") {
|
|
5604
|
-
const clipPath =
|
|
5706
|
+
const clipPath = chunkWVDM36ZM_js.getPresetShapeClipPath(el.shapeType);
|
|
5605
5707
|
if (clipPath) {
|
|
5606
5708
|
const svgPath = clipPathToSvgPath(clipPath, el.width, el.height);
|
|
5607
5709
|
if (svgPath) {
|
|
@@ -5652,7 +5754,7 @@ function clipPathToSvgPath(clipPath, width, height) {
|
|
|
5652
5754
|
return parts.join(" ");
|
|
5653
5755
|
}
|
|
5654
5756
|
function transformPathToGlobal(pathData, el) {
|
|
5655
|
-
const polys =
|
|
5757
|
+
const polys = chunkWVDM36ZM_js.svgPathToPolygons(pathData);
|
|
5656
5758
|
if (polys.length === 0) {
|
|
5657
5759
|
return pathData;
|
|
5658
5760
|
}
|
|
@@ -5672,10 +5774,10 @@ function transformPathToGlobal(pathData, el) {
|
|
|
5672
5774
|
y: pt.y * scaleY + el.y
|
|
5673
5775
|
}))
|
|
5674
5776
|
);
|
|
5675
|
-
return
|
|
5777
|
+
return chunkWVDM36ZM_js.polygonsToSvgPath(transformed);
|
|
5676
5778
|
}
|
|
5677
5779
|
function transformPathToLocal(pathData, x, y, _width, _height) {
|
|
5678
|
-
const polys =
|
|
5780
|
+
const polys = chunkWVDM36ZM_js.svgPathToPolygons(pathData);
|
|
5679
5781
|
if (polys.length === 0) {
|
|
5680
5782
|
return pathData;
|
|
5681
5783
|
}
|
|
@@ -5685,10 +5787,10 @@ function transformPathToLocal(pathData, x, y, _width, _height) {
|
|
|
5685
5787
|
y: pt.y - y
|
|
5686
5788
|
}))
|
|
5687
5789
|
);
|
|
5688
|
-
return
|
|
5790
|
+
return chunkWVDM36ZM_js.polygonsToSvgPath(transformed);
|
|
5689
5791
|
}
|
|
5690
5792
|
function pathBounds(pathData) {
|
|
5691
|
-
const polys =
|
|
5793
|
+
const polys = chunkWVDM36ZM_js.svgPathToPolygons(pathData);
|
|
5692
5794
|
let minX = Infinity;
|
|
5693
5795
|
let minY = Infinity;
|
|
5694
5796
|
let maxX = -Infinity;
|
|
@@ -5747,7 +5849,7 @@ function useMergeShapesHandler(input) {
|
|
|
5747
5849
|
let allFragments = [];
|
|
5748
5850
|
let remaining = globalPaths[0];
|
|
5749
5851
|
for (let i = 1; i < globalPaths.length; i++) {
|
|
5750
|
-
const frags =
|
|
5852
|
+
const frags = chunkWVDM36ZM_js.mergeShapes("fragment", remaining, globalPaths[i]);
|
|
5751
5853
|
if (Array.isArray(frags)) {
|
|
5752
5854
|
allFragments = frags;
|
|
5753
5855
|
}
|
|
@@ -5776,7 +5878,7 @@ function useMergeShapesHandler(input) {
|
|
|
5776
5878
|
bounds.height
|
|
5777
5879
|
);
|
|
5778
5880
|
const newEl = {
|
|
5779
|
-
id:
|
|
5881
|
+
id: chunkWVDM36ZM_js.generateElementId(),
|
|
5780
5882
|
type: "shape",
|
|
5781
5883
|
x: bounds.x,
|
|
5782
5884
|
y: bounds.y,
|
|
@@ -5814,7 +5916,7 @@ function useMergeShapesHandler(input) {
|
|
|
5814
5916
|
} else {
|
|
5815
5917
|
let resultPath = globalPaths[0];
|
|
5816
5918
|
for (let i = 1; i < globalPaths.length; i++) {
|
|
5817
|
-
const result =
|
|
5919
|
+
const result = chunkWVDM36ZM_js.mergeShapes(operation, resultPath, globalPaths[i]);
|
|
5818
5920
|
if (typeof result === "string") {
|
|
5819
5921
|
resultPath = result;
|
|
5820
5922
|
}
|
|
@@ -5835,7 +5937,7 @@ function useMergeShapesHandler(input) {
|
|
|
5835
5937
|
);
|
|
5836
5938
|
const primary = targets[0];
|
|
5837
5939
|
const newEl = {
|
|
5838
|
-
id:
|
|
5940
|
+
id: chunkWVDM36ZM_js.generateElementId(),
|
|
5839
5941
|
type: "shape",
|
|
5840
5942
|
x: bounds.x,
|
|
5841
5943
|
y: bounds.y,
|
|
@@ -5898,7 +6000,7 @@ function useGroupAlignLayerHandlers(input) {
|
|
|
5898
6000
|
if (ids.length < 2 || !activeSlide) {
|
|
5899
6001
|
return;
|
|
5900
6002
|
}
|
|
5901
|
-
const { elements, groupId } =
|
|
6003
|
+
const { elements, groupId } = chunkWVDM36ZM_js.groupElements(ops.activeElements, ids, chunkWVDM36ZM_js.generateElementId());
|
|
5902
6004
|
if (groupId === null) {
|
|
5903
6005
|
return;
|
|
5904
6006
|
}
|
|
@@ -5911,17 +6013,21 @@ function useGroupAlignLayerHandlers(input) {
|
|
|
5911
6013
|
return;
|
|
5912
6014
|
}
|
|
5913
6015
|
const group = selectedElement;
|
|
5914
|
-
const intoTemplate =
|
|
5915
|
-
const
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
|
|
6016
|
+
const intoTemplate = chunkWVDM36ZM_js.isTemplateElementId(group.id);
|
|
6017
|
+
const childIds = group.children.map(
|
|
6018
|
+
(child) => intoTemplate ? chunkWVDM36ZM_js.makeCloneId(true, child.id || group.id) : child.id || chunkWVDM36ZM_js.generateElementId()
|
|
6019
|
+
);
|
|
6020
|
+
const { elements, childIds: usedIds } = chunkWVDM36ZM_js.ungroupElements(
|
|
6021
|
+
ops.activeElements,
|
|
6022
|
+
group.id,
|
|
6023
|
+
childIds,
|
|
6024
|
+
{ intoTemplate }
|
|
6025
|
+
);
|
|
6026
|
+
if (usedIds.length === 0) {
|
|
6027
|
+
return;
|
|
6028
|
+
}
|
|
6029
|
+
ops.updateActiveElements(() => elements);
|
|
6030
|
+
setSelectedElementIds(usedIds);
|
|
5925
6031
|
history.markDirty();
|
|
5926
6032
|
};
|
|
5927
6033
|
const handleFlip = (direction) => {
|
|
@@ -5940,7 +6046,7 @@ function useGroupAlignLayerHandlers(input) {
|
|
|
5940
6046
|
if (!edge) {
|
|
5941
6047
|
return;
|
|
5942
6048
|
}
|
|
5943
|
-
const positions =
|
|
6049
|
+
const positions = chunkWVDM36ZM_js.alignElements(selectedElements, edge);
|
|
5944
6050
|
for (const [id, pos] of positions) {
|
|
5945
6051
|
const el = elementLookup.get(id);
|
|
5946
6052
|
if (!el) {
|
|
@@ -5958,7 +6064,7 @@ function useGroupAlignLayerHandlers(input) {
|
|
|
5958
6064
|
if (!distAxis) {
|
|
5959
6065
|
return;
|
|
5960
6066
|
}
|
|
5961
|
-
const positions =
|
|
6067
|
+
const positions = chunkWVDM36ZM_js.distributeElements(selectedElements, distAxis);
|
|
5962
6068
|
for (const [id, pos] of positions) {
|
|
5963
6069
|
const el = elementLookup.get(id);
|
|
5964
6070
|
if (!el) {
|
|
@@ -5975,7 +6081,7 @@ function useGroupAlignLayerHandlers(input) {
|
|
|
5975
6081
|
}
|
|
5976
6082
|
const id = selectedElement.id;
|
|
5977
6083
|
ops.updateActiveElements(
|
|
5978
|
-
(els) => direction === "forward" ?
|
|
6084
|
+
(els) => direction === "forward" ? chunkWVDM36ZM_js.bringForward(els, id) : direction === "backward" ? chunkWVDM36ZM_js.sendBackward(els, id) : els
|
|
5979
6085
|
);
|
|
5980
6086
|
history.markDirty();
|
|
5981
6087
|
};
|
|
@@ -5985,7 +6091,7 @@ function useGroupAlignLayerHandlers(input) {
|
|
|
5985
6091
|
}
|
|
5986
6092
|
const id = selectedElement.id;
|
|
5987
6093
|
ops.updateActiveElements(
|
|
5988
|
-
(els) => direction === "front" ?
|
|
6094
|
+
(els) => direction === "front" ? chunkWVDM36ZM_js.bringToFront(els, id) : chunkWVDM36ZM_js.sendToBack(els, id)
|
|
5989
6095
|
);
|
|
5990
6096
|
history.markDirty();
|
|
5991
6097
|
};
|
|
@@ -6116,7 +6222,7 @@ function useSlideManagement(input) {
|
|
|
6116
6222
|
theme
|
|
6117
6223
|
} = input;
|
|
6118
6224
|
const handleAddSlide = () => {
|
|
6119
|
-
const newSlide =
|
|
6225
|
+
const newSlide = chunkWVDM36ZM_js.createBlankSlide(slides.length + 1);
|
|
6120
6226
|
ops.updateSlides((prev) => {
|
|
6121
6227
|
const next = [...prev];
|
|
6122
6228
|
next.splice(activeSlideIndex + 1, 0, newSlide);
|
|
@@ -6179,7 +6285,7 @@ function useSlideManagement(input) {
|
|
|
6179
6285
|
}
|
|
6180
6286
|
const clone = {
|
|
6181
6287
|
...src,
|
|
6182
|
-
id:
|
|
6288
|
+
id: chunkWVDM36ZM_js.makeSlideId(),
|
|
6183
6289
|
elements: src.elements.map((el) => ({
|
|
6184
6290
|
...el,
|
|
6185
6291
|
id: `${el.id}-dup-${Math.random().toString(36).slice(2, 6)}`
|
|
@@ -6211,7 +6317,7 @@ function useSlideManagement(input) {
|
|
|
6211
6317
|
const handleInsertSlideFromLayout = (layoutPath, layoutName) => {
|
|
6212
6318
|
const insertAt = activeSlideIndex + 1;
|
|
6213
6319
|
const draft = {
|
|
6214
|
-
...
|
|
6320
|
+
...chunkWVDM36ZM_js.createBlankSlide(slides.length + 1),
|
|
6215
6321
|
layoutPath,
|
|
6216
6322
|
...layoutName ? { layoutName } : {}
|
|
6217
6323
|
};
|
|
@@ -6244,9 +6350,9 @@ function useSlideManagement(input) {
|
|
|
6244
6350
|
};
|
|
6245
6351
|
const handleInsertSlideFromTemplate = (templateId) => {
|
|
6246
6352
|
const insertAt = activeSlideIndex + 1;
|
|
6247
|
-
const draft =
|
|
6353
|
+
const draft = chunkWVDM36ZM_js.buildSlideTemplateSlide(templateId, chunkWVDM36ZM_js.makeSlideId(), slides.length + 1, {
|
|
6248
6354
|
...canvasSize ? { slideWidth: canvasSize.width, slideHeight: canvasSize.height } : {},
|
|
6249
|
-
scheme:
|
|
6355
|
+
scheme: chunkWVDM36ZM_js.templateSchemeFromTheme(theme?.colorScheme)
|
|
6250
6356
|
});
|
|
6251
6357
|
ops.updateSlides((prev) => insertSlideFromLayoutUpdater(prev, activeSlideIndex, draft));
|
|
6252
6358
|
setActiveSlideIndex(insertAt);
|
|
@@ -6283,7 +6389,7 @@ function createTableMergeHandlers(input) {
|
|
|
6283
6389
|
if (!nextCell || nextCell.hMerge || nextCell.vMerge) {
|
|
6284
6390
|
return;
|
|
6285
6391
|
}
|
|
6286
|
-
const newTableData =
|
|
6392
|
+
const newTableData = chunkWVDM36ZM_js.mergeCells(
|
|
6287
6393
|
[
|
|
6288
6394
|
{ row: rowIndex, col: columnIndex },
|
|
6289
6395
|
{ row: rowIndex, col: nextColIdx }
|
|
@@ -6291,7 +6397,7 @@ function createTableMergeHandlers(input) {
|
|
|
6291
6397
|
td
|
|
6292
6398
|
);
|
|
6293
6399
|
const updates = { tableData: newTableData };
|
|
6294
|
-
const newRawXml =
|
|
6400
|
+
const newRawXml = chunkWVDM36ZM_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
|
|
6295
6401
|
if (newRawXml) {
|
|
6296
6402
|
updates.rawXml = newRawXml;
|
|
6297
6403
|
}
|
|
@@ -6317,7 +6423,7 @@ function createTableMergeHandlers(input) {
|
|
|
6317
6423
|
if (!targetNextCell || targetNextCell.hMerge || targetNextCell.vMerge) {
|
|
6318
6424
|
return;
|
|
6319
6425
|
}
|
|
6320
|
-
const newTableData =
|
|
6426
|
+
const newTableData = chunkWVDM36ZM_js.mergeCells(
|
|
6321
6427
|
[
|
|
6322
6428
|
{ row: rowIndex, col: columnIndex },
|
|
6323
6429
|
{ row: targetNextRowIdx, col: columnIndex }
|
|
@@ -6325,7 +6431,7 @@ function createTableMergeHandlers(input) {
|
|
|
6325
6431
|
td
|
|
6326
6432
|
);
|
|
6327
6433
|
const updates = { tableData: newTableData };
|
|
6328
|
-
const newRawXml =
|
|
6434
|
+
const newRawXml = chunkWVDM36ZM_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
|
|
6329
6435
|
if (newRawXml) {
|
|
6330
6436
|
updates.rawXml = newRawXml;
|
|
6331
6437
|
}
|
|
@@ -6340,9 +6446,9 @@ function createTableMergeHandlers(input) {
|
|
|
6340
6446
|
return;
|
|
6341
6447
|
}
|
|
6342
6448
|
const td = selectedElement.tableData;
|
|
6343
|
-
const newTableData =
|
|
6449
|
+
const newTableData = chunkWVDM36ZM_js.mergeCells(ts.selectedCells, td);
|
|
6344
6450
|
const updates = { tableData: newTableData };
|
|
6345
|
-
const newRawXml =
|
|
6451
|
+
const newRawXml = chunkWVDM36ZM_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
|
|
6346
6452
|
if (newRawXml) {
|
|
6347
6453
|
updates.rawXml = newRawXml;
|
|
6348
6454
|
}
|
|
@@ -6359,9 +6465,9 @@ function createTableMergeHandlers(input) {
|
|
|
6359
6465
|
}
|
|
6360
6466
|
const { rowIndex, columnIndex } = ts;
|
|
6361
6467
|
const td = selectedElement.tableData;
|
|
6362
|
-
const newTableData =
|
|
6468
|
+
const newTableData = chunkWVDM36ZM_js.splitCell(rowIndex, columnIndex, td);
|
|
6363
6469
|
const updates = { tableData: newTableData };
|
|
6364
|
-
const newRawXml =
|
|
6470
|
+
const newRawXml = chunkWVDM36ZM_js.updateMergeAttrsInRawXml(selectedElement, newTableData);
|
|
6365
6471
|
if (newRawXml) {
|
|
6366
6472
|
updates.rawXml = newRawXml;
|
|
6367
6473
|
}
|
|
@@ -6405,7 +6511,7 @@ function createTableStructHandlers(input) {
|
|
|
6405
6511
|
updates.tableData = { ...el.tableData, rows: newRows };
|
|
6406
6512
|
}
|
|
6407
6513
|
if (el.rawXml) {
|
|
6408
|
-
const newRawXml =
|
|
6514
|
+
const newRawXml = chunkWVDM36ZM_js.updateCellTextInRawXml(el, rowIndex, colIndex, text);
|
|
6409
6515
|
if (newRawXml) {
|
|
6410
6516
|
updates.rawXml = newRawXml;
|
|
6411
6517
|
}
|
|
@@ -6429,7 +6535,7 @@ function createTableStructHandlers(input) {
|
|
|
6429
6535
|
const { rowIndex, columnIndex: colIndex } = ts;
|
|
6430
6536
|
const updates = {};
|
|
6431
6537
|
if (selectedElement.rawXml) {
|
|
6432
|
-
const newRawXml =
|
|
6538
|
+
const newRawXml = chunkWVDM36ZM_js.updateCellTextStyleInRawXml(
|
|
6433
6539
|
selectedElement,
|
|
6434
6540
|
rowIndex,
|
|
6435
6541
|
colIndex,
|
|
@@ -6493,9 +6599,9 @@ function createTableStructHandlers(input) {
|
|
|
6493
6599
|
return;
|
|
6494
6600
|
}
|
|
6495
6601
|
const rowIdx = ts?.rowIndex ?? 0;
|
|
6496
|
-
const newTableData =
|
|
6602
|
+
const newTableData = chunkWVDM36ZM_js.insertTableRow(selectedElement.tableData, rowIdx, position);
|
|
6497
6603
|
const updates = { tableData: newTableData };
|
|
6498
|
-
const newRawXml =
|
|
6604
|
+
const newRawXml = chunkWVDM36ZM_js.rebuildTableStructureInRawXml(selectedElement, newTableData);
|
|
6499
6605
|
if (newRawXml) {
|
|
6500
6606
|
updates.rawXml = newRawXml;
|
|
6501
6607
|
}
|
|
@@ -6508,12 +6614,12 @@ function createTableStructHandlers(input) {
|
|
|
6508
6614
|
}
|
|
6509
6615
|
const td = selectedElement.tableData;
|
|
6510
6616
|
const rowIdx = ts?.rowIndex ?? 0;
|
|
6511
|
-
const newTableData =
|
|
6617
|
+
const newTableData = chunkWVDM36ZM_js.deleteTableRow(td, rowIdx);
|
|
6512
6618
|
if (newTableData === td) {
|
|
6513
6619
|
return;
|
|
6514
6620
|
}
|
|
6515
6621
|
const updates = { tableData: newTableData };
|
|
6516
|
-
const newRawXml =
|
|
6622
|
+
const newRawXml = chunkWVDM36ZM_js.rebuildTableStructureInRawXml(selectedElement, newTableData);
|
|
6517
6623
|
if (newRawXml) {
|
|
6518
6624
|
updates.rawXml = newRawXml;
|
|
6519
6625
|
}
|
|
@@ -6525,9 +6631,9 @@ function createTableStructHandlers(input) {
|
|
|
6525
6631
|
return;
|
|
6526
6632
|
}
|
|
6527
6633
|
const colIdx = ts?.columnIndex ?? 0;
|
|
6528
|
-
const newTableData =
|
|
6634
|
+
const newTableData = chunkWVDM36ZM_js.insertTableColumn(selectedElement.tableData, colIdx, position);
|
|
6529
6635
|
const updates = { tableData: newTableData };
|
|
6530
|
-
const newRawXml =
|
|
6636
|
+
const newRawXml = chunkWVDM36ZM_js.rebuildTableStructureInRawXml(selectedElement, newTableData);
|
|
6531
6637
|
if (newRawXml) {
|
|
6532
6638
|
updates.rawXml = newRawXml;
|
|
6533
6639
|
}
|
|
@@ -6540,12 +6646,12 @@ function createTableStructHandlers(input) {
|
|
|
6540
6646
|
}
|
|
6541
6647
|
const td = selectedElement.tableData;
|
|
6542
6648
|
const colIdx = ts?.columnIndex ?? 0;
|
|
6543
|
-
const newTableData =
|
|
6649
|
+
const newTableData = chunkWVDM36ZM_js.deleteTableColumn(td, colIdx);
|
|
6544
6650
|
if (newTableData === td) {
|
|
6545
6651
|
return;
|
|
6546
6652
|
}
|
|
6547
6653
|
const updates = { tableData: newTableData };
|
|
6548
|
-
const newRawXml =
|
|
6654
|
+
const newRawXml = chunkWVDM36ZM_js.rebuildTableStructureInRawXml(selectedElement, newTableData);
|
|
6549
6655
|
if (newRawXml) {
|
|
6550
6656
|
updates.rawXml = newRawXml;
|
|
6551
6657
|
}
|
|
@@ -6581,8 +6687,8 @@ async function renderToCanvas(element, options = {}) {
|
|
|
6581
6687
|
return html2canvasPro(element, {
|
|
6582
6688
|
...options,
|
|
6583
6689
|
onclone: async (doc, clonedEl) => {
|
|
6584
|
-
await
|
|
6585
|
-
|
|
6690
|
+
await chunkWVDM36ZM_js.normalizeColorsForCapture(doc, clonedEl);
|
|
6691
|
+
chunkWVDM36ZM_js.preprocessCssForCapture(clonedEl);
|
|
6586
6692
|
if (typeof userOnClone === "function") {
|
|
6587
6693
|
userOnClone(doc, clonedEl);
|
|
6588
6694
|
}
|
|
@@ -6638,7 +6744,7 @@ async function exportSlideToPngBlob(slideElement, options = {}) {
|
|
|
6638
6744
|
}
|
|
6639
6745
|
async function exportSlideAsPng(slideElement, slideIndex, options = {}) {
|
|
6640
6746
|
const blob = await exportSlideToPngBlob(slideElement, options);
|
|
6641
|
-
|
|
6747
|
+
chunkWVDM36ZM_js.downloadBlob(blob, `slide-${slideIndex + 1}.png`);
|
|
6642
6748
|
}
|
|
6643
6749
|
async function copySlideToClipboard(slideElement, options = {}) {
|
|
6644
6750
|
const blob = await exportSlideToPngBlob(slideElement, options);
|
|
@@ -6660,15 +6766,15 @@ async function exportAllSlidesAsPdf(slideStageRef, totalSlides, setActiveSlide,
|
|
|
6660
6766
|
continue;
|
|
6661
6767
|
}
|
|
6662
6768
|
const canvas = await renderElementToCanvas(stageEl, scale);
|
|
6663
|
-
images.push(
|
|
6769
|
+
images.push(chunkWVDM36ZM_js.canvasToJpegData(canvas));
|
|
6664
6770
|
}
|
|
6665
6771
|
onProgress?.(totalSlides, totalSlides);
|
|
6666
6772
|
setActiveSlide(currentSlideIndex);
|
|
6667
6773
|
if (images.length === 0) {
|
|
6668
|
-
throw new Error(
|
|
6774
|
+
throw new Error(chunkRTUGI4HQ_js.translationsEn["pptx.export.errorNoSlidesPdf"]);
|
|
6669
6775
|
}
|
|
6670
|
-
const pdfBlobUrl =
|
|
6671
|
-
|
|
6776
|
+
const pdfBlobUrl = chunk4LWGAVAP_js.buildPdfFromImageData(images);
|
|
6777
|
+
chunkWVDM36ZM_js.downloadDataUrl(pdfBlobUrl, filename);
|
|
6672
6778
|
}
|
|
6673
6779
|
async function captureAllSlidesAsPngDataUrls(slideStageRef, totalSlides, setActiveSlide, currentSlideIndex, options = {}) {
|
|
6674
6780
|
const { scale = 2, onProgress } = options;
|
|
@@ -6714,10 +6820,10 @@ async function exportAllSlidesAsNotesPdf(slideStageRef, totalSlides, setActiveSl
|
|
|
6714
6820
|
onProgress?.(totalSlides, totalSlides);
|
|
6715
6821
|
setActiveSlide(currentSlideIndex);
|
|
6716
6822
|
if (pages.length === 0) {
|
|
6717
|
-
throw new Error(
|
|
6823
|
+
throw new Error(chunkRTUGI4HQ_js.translationsEn["pptx.export.errorNoSlidesNotesPdf"]);
|
|
6718
6824
|
}
|
|
6719
|
-
const pdfDataUrl =
|
|
6720
|
-
|
|
6825
|
+
const pdfDataUrl = chunk4LWGAVAP_js.buildNotesPdf(pages);
|
|
6826
|
+
chunkWVDM36ZM_js.downloadDataUrl(pdfDataUrl, filename);
|
|
6721
6827
|
}
|
|
6722
6828
|
|
|
6723
6829
|
// src/viewer/utils/export-video.ts
|
|
@@ -6748,7 +6854,7 @@ async function exportAllSlidesAsVideo(slideStageRef, totalSlides, setActiveSlide
|
|
|
6748
6854
|
}
|
|
6749
6855
|
setActiveSlide(currentSlideIndex);
|
|
6750
6856
|
if (slideCanvases.length === 0) {
|
|
6751
|
-
throw new Error(
|
|
6857
|
+
throw new Error(chunkRTUGI4HQ_js.translationsEn["pptx.export.errorNoSlidesVideo"]);
|
|
6752
6858
|
}
|
|
6753
6859
|
const firstCanvas = slideCanvases[0];
|
|
6754
6860
|
const recordingCanvas = document.createElement("canvas");
|
|
@@ -6756,12 +6862,12 @@ async function exportAllSlidesAsVideo(slideStageRef, totalSlides, setActiveSlide
|
|
|
6756
6862
|
recordingCanvas.height = firstCanvas.height;
|
|
6757
6863
|
const ctx = recordingCanvas.getContext("2d");
|
|
6758
6864
|
if (!ctx) {
|
|
6759
|
-
throw new Error(
|
|
6865
|
+
throw new Error(chunkRTUGI4HQ_js.translationsEn["pptx.export.errorNo2dContext"]);
|
|
6760
6866
|
}
|
|
6761
6867
|
const fps = 30;
|
|
6762
6868
|
const stream = recordingCanvas.captureStream(fps);
|
|
6763
6869
|
const recorder = new MediaRecorder(stream, {
|
|
6764
|
-
mimeType:
|
|
6870
|
+
mimeType: chunkWVDM36ZM_js.pickSupportedMimeType([...chunkWVDM36ZM_js.WEBM_MIME_CANDIDATES]),
|
|
6765
6871
|
videoBitsPerSecond: 5e6
|
|
6766
6872
|
});
|
|
6767
6873
|
const chunks = [];
|
|
@@ -6784,8 +6890,8 @@ async function exportAllSlidesAsVideo(slideStageRef, totalSlides, setActiveSlide
|
|
|
6784
6890
|
const duration = slideTimingsMs?.[i] ?? slideDurationMs;
|
|
6785
6891
|
ctx.clearRect(0, 0, recordingCanvas.width, recordingCanvas.height);
|
|
6786
6892
|
ctx.drawImage(slideCanvases[i], 0, 0);
|
|
6787
|
-
const frameInterval =
|
|
6788
|
-
const framesNeeded =
|
|
6893
|
+
const frameInterval = chunkWVDM36ZM_js.fpsToFrameIntervalMs(fps);
|
|
6894
|
+
const framesNeeded = chunkWVDM36ZM_js.segmentFrameCount(duration, fps);
|
|
6789
6895
|
for (let f = 0; f < framesNeeded; f++) {
|
|
6790
6896
|
if (signal?.aborted) {
|
|
6791
6897
|
recorder.stop();
|
|
@@ -6832,9 +6938,9 @@ async function exportAllSlidesAsGif(slideStageRef, totalSlides, setActiveSlide,
|
|
|
6832
6938
|
}
|
|
6833
6939
|
setActiveSlide(currentSlideIndex);
|
|
6834
6940
|
if (frames.length === 0) {
|
|
6835
|
-
throw new Error(
|
|
6941
|
+
throw new Error(chunkRTUGI4HQ_js.translationsEn["pptx.export.errorNoSlidesGif"]);
|
|
6836
6942
|
}
|
|
6837
|
-
const gifBytes =
|
|
6943
|
+
const gifBytes = chunkWVDM36ZM_js.encodeGif(frames, Math.round(slideDurationMs / 10));
|
|
6838
6944
|
onProgress?.(totalSlides, totalSlides);
|
|
6839
6945
|
const buf = new ArrayBuffer(gifBytes.length);
|
|
6840
6946
|
new Uint8Array(buf).set(gifBytes);
|
|
@@ -6888,7 +6994,7 @@ function exportAllSlidesToSvg(data, options = {}) {
|
|
|
6888
6994
|
continue;
|
|
6889
6995
|
}
|
|
6890
6996
|
onProgress?.(processedCount, data.slides.length);
|
|
6891
|
-
let svg =
|
|
6997
|
+
let svg = chunkWVDM36ZM_js.SvgExporter.exportSlide(slide, data.width, data.height, svgOptions);
|
|
6892
6998
|
if (embedFonts && fontFaces?.length) {
|
|
6893
6999
|
svg = injectFontFaces(svg, fontFaces);
|
|
6894
7000
|
}
|
|
@@ -6915,12 +7021,14 @@ function useExportSaveAs(input) {
|
|
|
6915
7021
|
appProperties,
|
|
6916
7022
|
customProperties,
|
|
6917
7023
|
tagCollections,
|
|
7024
|
+
slideMasters,
|
|
6918
7025
|
notesMaster,
|
|
6919
7026
|
handoutMaster,
|
|
6920
7027
|
guides,
|
|
6921
7028
|
activeSlideIndexForGuides,
|
|
6922
7029
|
theme,
|
|
6923
7030
|
canvasSize,
|
|
7031
|
+
slideSizeEmu,
|
|
6924
7032
|
modalControls,
|
|
6925
7033
|
password
|
|
6926
7034
|
} = input;
|
|
@@ -6944,13 +7052,13 @@ function useExportSaveAs(input) {
|
|
|
6944
7052
|
setExportProgress(10);
|
|
6945
7053
|
setExportStatusMessage("Adding presentation...");
|
|
6946
7054
|
const pptxData = await serializeSlides();
|
|
6947
|
-
const pptxFilename =
|
|
7055
|
+
const pptxFilename = chunkWVDM36ZM_js.savedPresentationFileName(filePath);
|
|
6948
7056
|
if (pptxData) {
|
|
6949
7057
|
pkgFolder.file(pptxFilename, pptxData);
|
|
6950
7058
|
}
|
|
6951
7059
|
setExportProgress(70);
|
|
6952
7060
|
setExportStatusMessage("Writing README...");
|
|
6953
|
-
const readme =
|
|
7061
|
+
const readme = chunkWVDM36ZM_js.generatePackageReadme(pptxFilename);
|
|
6954
7062
|
pkgFolder.file("README.txt", readme);
|
|
6955
7063
|
if (abortCtrl.signal.aborted) {
|
|
6956
7064
|
throw new DOMException("Export cancelled", "AbortError");
|
|
@@ -6960,8 +7068,7 @@ function useExportSaveAs(input) {
|
|
|
6960
7068
|
const zipBlob = await zip.generateAsync({ type: "blob" });
|
|
6961
7069
|
setExportProgress(95);
|
|
6962
7070
|
setExportStatusMessage("Downloading...");
|
|
6963
|
-
|
|
6964
|
-
chunkY2KIB3QH_js.downloadBlob(zipBlob, `${baseName}-package.zip`);
|
|
7071
|
+
chunkWVDM36ZM_js.downloadBlob(zipBlob, `${chunkWVDM36ZM_js.presentationBaseName(pptxFilename)}-package.zip`);
|
|
6965
7072
|
setExportProgress(100);
|
|
6966
7073
|
} catch (err) {
|
|
6967
7074
|
if (err.name !== "AbortError") {
|
|
@@ -6977,16 +7084,15 @@ function useExportSaveAs(input) {
|
|
|
6977
7084
|
if (!handler) {
|
|
6978
7085
|
return;
|
|
6979
7086
|
}
|
|
6980
|
-
const
|
|
6981
|
-
const baseName = filePath ? filePath.replace(/\\/gu, "/").split("/").pop()?.replace(/\.[^.]+$/u, "") ?? "presentation" : "presentation";
|
|
7087
|
+
const downloadName = chunkWVDM36ZM_js.savedPresentationFileName(filePath, format);
|
|
6982
7088
|
try {
|
|
6983
7089
|
const data = await buildSaveAsData(handler, format);
|
|
6984
7090
|
const blob = new Blob([data], {
|
|
6985
7091
|
type: "application/vnd.openxmlformats-officedocument.presentationml.presentation"
|
|
6986
7092
|
});
|
|
6987
|
-
|
|
7093
|
+
chunkWVDM36ZM_js.downloadBlob(blob, downloadName);
|
|
6988
7094
|
} catch (err) {
|
|
6989
|
-
console.error(`[PowerPointViewer] Save as .${
|
|
7095
|
+
console.error(`[PowerPointViewer] Save as .${format} failed:`, err);
|
|
6990
7096
|
}
|
|
6991
7097
|
};
|
|
6992
7098
|
const buildSaveAsData = async (handler, format) => {
|
|
@@ -6997,15 +7103,18 @@ function useExportSaveAs(input) {
|
|
|
6997
7103
|
const pptxGuides = guides.map((g) => ({
|
|
6998
7104
|
id: g.id,
|
|
6999
7105
|
orientation: g.axis === "h" ? "horz" : "vert",
|
|
7000
|
-
positionEmu:
|
|
7106
|
+
positionEmu: chunkWVDM36ZM_js.guidePxToEmu(g.position)
|
|
7001
7107
|
}));
|
|
7002
7108
|
return {
|
|
7003
7109
|
...slide,
|
|
7004
7110
|
guides: pptxGuides.length > 0 ? pptxGuides : void 0
|
|
7005
7111
|
};
|
|
7006
7112
|
});
|
|
7007
|
-
const slidesToSave =
|
|
7113
|
+
const slidesToSave = chunkWVDM36ZM_js.buildSaveSlides(slidesWithGuides, templateElementsBySlideId);
|
|
7008
7114
|
const saveOptions = {
|
|
7115
|
+
// Save As shares Save's slide-size decision; leaving it out here is how
|
|
7116
|
+
// a preset picked in the inspector reached one save path and not the other.
|
|
7117
|
+
slideSize: chunkWVDM36ZM_js.resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size,
|
|
7009
7118
|
headerFooter,
|
|
7010
7119
|
presentationProperties,
|
|
7011
7120
|
customShows: customShows.length > 0 ? customShows : void 0,
|
|
@@ -7014,27 +7123,23 @@ function useExportSaveAs(input) {
|
|
|
7014
7123
|
appProperties: appProperties ?? void 0,
|
|
7015
7124
|
customProperties: customProperties.length > 0 ? customProperties : void 0,
|
|
7016
7125
|
tags: tagCollections.length > 0 ? tagCollections : void 0,
|
|
7126
|
+
slideMasters,
|
|
7017
7127
|
notesMaster,
|
|
7018
7128
|
handoutMaster,
|
|
7019
7129
|
outputFormat: format
|
|
7020
7130
|
};
|
|
7021
|
-
|
|
7022
|
-
return handler.saveEncrypted(
|
|
7023
|
-
slidesToSave,
|
|
7024
|
-
password,
|
|
7025
|
-
saveOptions
|
|
7026
|
-
);
|
|
7027
|
-
}
|
|
7028
|
-
return handler.save(slidesToSave, saveOptions);
|
|
7131
|
+
return chunkWVDM36ZM_js.saveDeckWithPassword(handler, slidesToSave, saveOptions, password);
|
|
7029
7132
|
};
|
|
7030
7133
|
const handleExportJson = () => {
|
|
7031
7134
|
const sourceName = filePath ? filePath.replace(/\\/gu, "/").split("/").pop() : void 0;
|
|
7135
|
+
const slideSize = chunkWVDM36ZM_js.resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size;
|
|
7032
7136
|
const data = {
|
|
7033
|
-
slides:
|
|
7137
|
+
slides: chunkWVDM36ZM_js.buildSaveSlides(slides, templateElementsBySlideId),
|
|
7034
7138
|
width: canvasSize.width,
|
|
7035
7139
|
height: canvasSize.height,
|
|
7036
|
-
widthEmu:
|
|
7037
|
-
heightEmu:
|
|
7140
|
+
widthEmu: slideSize.widthEmu,
|
|
7141
|
+
heightEmu: slideSize.heightEmu,
|
|
7142
|
+
slideSizeType: slideSize.type === "" ? void 0 : slideSize.type,
|
|
7038
7143
|
theme,
|
|
7039
7144
|
headerFooter,
|
|
7040
7145
|
presentationProperties,
|
|
@@ -7048,7 +7153,7 @@ function useExportSaveAs(input) {
|
|
|
7048
7153
|
handoutMaster
|
|
7049
7154
|
};
|
|
7050
7155
|
try {
|
|
7051
|
-
|
|
7156
|
+
chunkWVDM36ZM_js.exportDeckJson(data, sourceName);
|
|
7052
7157
|
} catch (err) {
|
|
7053
7158
|
console.error("[PowerPointViewer] JSON export failed:", err);
|
|
7054
7159
|
}
|
|
@@ -7088,7 +7193,7 @@ function safeConfirm(message) {
|
|
|
7088
7193
|
}
|
|
7089
7194
|
}
|
|
7090
7195
|
function downloadBlob2(blob, filename) {
|
|
7091
|
-
|
|
7196
|
+
chunkWVDM36ZM_js.downloadBlob(blob, chunkWVDM36ZM_js.sanitizeDownloadFilename(filename));
|
|
7092
7197
|
}
|
|
7093
7198
|
|
|
7094
7199
|
// src/viewer/hooks/useExportHandlers.ts
|
|
@@ -7111,12 +7216,14 @@ function useExportHandlers(input) {
|
|
|
7111
7216
|
appProperties,
|
|
7112
7217
|
customProperties,
|
|
7113
7218
|
tagCollections,
|
|
7219
|
+
slideMasters,
|
|
7114
7220
|
notesMaster,
|
|
7115
7221
|
handoutMaster,
|
|
7116
7222
|
guides,
|
|
7117
7223
|
activeSlideIndexForGuides,
|
|
7118
7224
|
theme,
|
|
7119
7225
|
canvasSize,
|
|
7226
|
+
slideSizeEmu,
|
|
7120
7227
|
password
|
|
7121
7228
|
} = input;
|
|
7122
7229
|
const [exportModalOpen, setExportModalOpen] = react.useState(false);
|
|
@@ -7152,12 +7259,14 @@ function useExportHandlers(input) {
|
|
|
7152
7259
|
appProperties,
|
|
7153
7260
|
customProperties,
|
|
7154
7261
|
tagCollections,
|
|
7262
|
+
slideMasters,
|
|
7155
7263
|
notesMaster,
|
|
7156
7264
|
handoutMaster,
|
|
7157
7265
|
guides,
|
|
7158
7266
|
activeSlideIndexForGuides,
|
|
7159
7267
|
theme,
|
|
7160
7268
|
canvasSize,
|
|
7269
|
+
slideSizeEmu,
|
|
7161
7270
|
modalControls,
|
|
7162
7271
|
password
|
|
7163
7272
|
});
|
|
@@ -7194,21 +7303,21 @@ function useExportHandlers(input) {
|
|
|
7194
7303
|
{
|
|
7195
7304
|
scale: 2,
|
|
7196
7305
|
onProgress: (current, total) => {
|
|
7197
|
-
setExportProgress(
|
|
7198
|
-
setExportStatusMessage(
|
|
7306
|
+
setExportProgress(chunkWVDM36ZM_js.slideProgressPercent(current, total));
|
|
7307
|
+
setExportStatusMessage(chunkWVDM36ZM_js.slideStatusLabel("Rendering", current, total));
|
|
7199
7308
|
},
|
|
7200
7309
|
signal: abortCtrl.signal
|
|
7201
7310
|
}
|
|
7202
7311
|
);
|
|
7203
|
-
setExportProgress(
|
|
7312
|
+
setExportProgress(chunkWVDM36ZM_js.EXPORT_ASSEMBLING_PERCENT);
|
|
7204
7313
|
setExportStatusMessage("Building PDF...");
|
|
7205
7314
|
await new Promise((r) => {
|
|
7206
7315
|
setTimeout(r, 100);
|
|
7207
7316
|
});
|
|
7208
|
-
setExportProgress(
|
|
7317
|
+
setExportProgress(chunkWVDM36ZM_js.EXPORT_DONE_PERCENT);
|
|
7209
7318
|
setExportStatusMessage("Done!");
|
|
7210
7319
|
} catch (err) {
|
|
7211
|
-
if (!
|
|
7320
|
+
if (!chunkWVDM36ZM_js.isExportAbortError(err)) {
|
|
7212
7321
|
console.error("[PowerPointViewer] PDF export failed:", err);
|
|
7213
7322
|
}
|
|
7214
7323
|
} finally {
|
|
@@ -7238,21 +7347,21 @@ function useExportHandlers(input) {
|
|
|
7238
7347
|
{
|
|
7239
7348
|
scale: 2,
|
|
7240
7349
|
onProgress: (current, total) => {
|
|
7241
|
-
setExportProgress(
|
|
7242
|
-
setExportStatusMessage(
|
|
7350
|
+
setExportProgress(chunkWVDM36ZM_js.slideProgressPercent(current, total));
|
|
7351
|
+
setExportStatusMessage(chunkWVDM36ZM_js.slideStatusLabel("Rendering", current, total));
|
|
7243
7352
|
},
|
|
7244
7353
|
signal: abortCtrl.signal
|
|
7245
7354
|
}
|
|
7246
7355
|
);
|
|
7247
|
-
setExportProgress(
|
|
7356
|
+
setExportProgress(chunkWVDM36ZM_js.EXPORT_ASSEMBLING_PERCENT);
|
|
7248
7357
|
setExportStatusMessage("Building PDF...");
|
|
7249
7358
|
await new Promise((r) => {
|
|
7250
7359
|
setTimeout(r, 100);
|
|
7251
7360
|
});
|
|
7252
|
-
setExportProgress(
|
|
7361
|
+
setExportProgress(chunkWVDM36ZM_js.EXPORT_DONE_PERCENT);
|
|
7253
7362
|
setExportStatusMessage("Done!");
|
|
7254
7363
|
} catch (err) {
|
|
7255
|
-
if (!
|
|
7364
|
+
if (!chunkWVDM36ZM_js.isExportAbortError(err)) {
|
|
7256
7365
|
console.error("[PowerPointViewer] Notes PDF export failed:", err);
|
|
7257
7366
|
}
|
|
7258
7367
|
} finally {
|
|
@@ -7293,22 +7402,22 @@ function useExportHandlers(input) {
|
|
|
7293
7402
|
scale: 1,
|
|
7294
7403
|
slideDurationMs: 3e3,
|
|
7295
7404
|
onProgress: (current, total) => {
|
|
7296
|
-
setExportProgress(
|
|
7297
|
-
setExportStatusMessage(
|
|
7405
|
+
setExportProgress(chunkWVDM36ZM_js.slideProgressPercent(current, total, 45));
|
|
7406
|
+
setExportStatusMessage(chunkWVDM36ZM_js.slideStatusLabel("Capturing", current, total));
|
|
7298
7407
|
},
|
|
7299
7408
|
onRecordProgress: (current, total) => {
|
|
7300
|
-
setExportProgress(
|
|
7301
|
-
setExportStatusMessage(
|
|
7409
|
+
setExportProgress(chunkWVDM36ZM_js.recordProgressPercent(current, total));
|
|
7410
|
+
setExportStatusMessage(chunkWVDM36ZM_js.slideStatusLabel("Recording", current, total));
|
|
7302
7411
|
},
|
|
7303
7412
|
signal: abortCtrl.signal
|
|
7304
7413
|
}
|
|
7305
7414
|
);
|
|
7306
|
-
setExportProgress(
|
|
7415
|
+
setExportProgress(chunkWVDM36ZM_js.EXPORT_ASSEMBLING_PERCENT);
|
|
7307
7416
|
setExportStatusMessage("Saving file...");
|
|
7308
7417
|
downloadBlob2(blob, "presentation.webm");
|
|
7309
|
-
setExportProgress(
|
|
7418
|
+
setExportProgress(chunkWVDM36ZM_js.EXPORT_DONE_PERCENT);
|
|
7310
7419
|
} catch (err) {
|
|
7311
|
-
if (!
|
|
7420
|
+
if (!chunkWVDM36ZM_js.isExportAbortError(err)) {
|
|
7312
7421
|
console.error("[PowerPointViewer] Video export failed:", err);
|
|
7313
7422
|
}
|
|
7314
7423
|
} finally {
|
|
@@ -7336,18 +7445,18 @@ function useExportHandlers(input) {
|
|
|
7336
7445
|
scale: 0.5,
|
|
7337
7446
|
slideDurationMs: 2e3,
|
|
7338
7447
|
onProgress: (current, total) => {
|
|
7339
|
-
setExportProgress(
|
|
7340
|
-
setExportStatusMessage(
|
|
7448
|
+
setExportProgress(chunkWVDM36ZM_js.slideProgressPercent(current, total));
|
|
7449
|
+
setExportStatusMessage(chunkWVDM36ZM_js.slideStatusLabel("Encoding", current, total));
|
|
7341
7450
|
},
|
|
7342
7451
|
signal: abortCtrl.signal
|
|
7343
7452
|
}
|
|
7344
7453
|
);
|
|
7345
|
-
setExportProgress(
|
|
7454
|
+
setExportProgress(chunkWVDM36ZM_js.EXPORT_ASSEMBLING_PERCENT);
|
|
7346
7455
|
setExportStatusMessage("Saving file...");
|
|
7347
7456
|
downloadBlob2(blob, "presentation.gif");
|
|
7348
|
-
setExportProgress(
|
|
7457
|
+
setExportProgress(chunkWVDM36ZM_js.EXPORT_DONE_PERCENT);
|
|
7349
7458
|
} catch (err) {
|
|
7350
|
-
if (!
|
|
7459
|
+
if (!chunkWVDM36ZM_js.isExportAbortError(err)) {
|
|
7351
7460
|
console.error("[PowerPointViewer] GIF export failed:", err);
|
|
7352
7461
|
}
|
|
7353
7462
|
} finally {
|
|
@@ -7388,7 +7497,7 @@ function openPrintWindow(title, bodyHtml, orientation, colorFilter, frameSlides)
|
|
|
7388
7497
|
}
|
|
7389
7498
|
printWindow.document.open();
|
|
7390
7499
|
printWindow.document.write(
|
|
7391
|
-
|
|
7500
|
+
chunkWVDM36ZM_js.buildPrintHtmlDocument({ title, bodyHtml, orientation, colorFilter, frameSlides })
|
|
7392
7501
|
);
|
|
7393
7502
|
printWindow.document.close();
|
|
7394
7503
|
printWindow.focus();
|
|
@@ -7449,7 +7558,7 @@ function usePrintHandlers(input) {
|
|
|
7449
7558
|
if (svgs.length === 0) {
|
|
7450
7559
|
return;
|
|
7451
7560
|
}
|
|
7452
|
-
const printDoc =
|
|
7561
|
+
const printDoc = chunkWVDM36ZM_js.buildPrintDocument(svgs, pptxData.width, pptxData.height, {
|
|
7453
7562
|
title: "Slides (Vector)",
|
|
7454
7563
|
orientation: settings.orientation,
|
|
7455
7564
|
colorFilter
|
|
@@ -7485,7 +7594,7 @@ function usePrintHandlers(input) {
|
|
|
7485
7594
|
if (settings.printWhat === "outline") {
|
|
7486
7595
|
openPrintWindow(
|
|
7487
7596
|
"Outline",
|
|
7488
|
-
`<div class="outline-page">${
|
|
7597
|
+
`<div class="outline-page">${chunkWVDM36ZM_js.buildOutlineHtml(slideIndices, slides)}</div>`,
|
|
7489
7598
|
settings.orientation,
|
|
7490
7599
|
colorFilter,
|
|
7491
7600
|
settings.frameSlides
|
|
@@ -7510,7 +7619,7 @@ function usePrintHandlers(input) {
|
|
|
7510
7619
|
if (settings.printWhat === "slides") {
|
|
7511
7620
|
openPrintWindow(
|
|
7512
7621
|
"Slides",
|
|
7513
|
-
|
|
7622
|
+
chunkWVDM36ZM_js.buildSlidesHtml(slideImages, slideIndices),
|
|
7514
7623
|
settings.orientation,
|
|
7515
7624
|
colorFilter,
|
|
7516
7625
|
settings.frameSlides
|
|
@@ -7520,7 +7629,7 @@ function usePrintHandlers(input) {
|
|
|
7520
7629
|
if (settings.printWhat === "notes") {
|
|
7521
7630
|
openPrintWindow(
|
|
7522
7631
|
"Notes Pages",
|
|
7523
|
-
|
|
7632
|
+
chunkWVDM36ZM_js.buildNotesHtml(slideImages, slideIndices, slides),
|
|
7524
7633
|
"portrait",
|
|
7525
7634
|
colorFilter,
|
|
7526
7635
|
settings.frameSlides
|
|
@@ -7531,7 +7640,7 @@ function usePrintHandlers(input) {
|
|
|
7531
7640
|
const spp = settings.slidesPerPage;
|
|
7532
7641
|
openPrintWindow(
|
|
7533
7642
|
`Handout ${spp} per page`,
|
|
7534
|
-
|
|
7643
|
+
chunkWVDM36ZM_js.buildHandoutsHtml(slideImages, slideIndices, spp),
|
|
7535
7644
|
"portrait",
|
|
7536
7645
|
colorFilter,
|
|
7537
7646
|
settings.frameSlides
|
|
@@ -7595,8 +7704,8 @@ function useThemeHandlers(input) {
|
|
|
7595
7704
|
return;
|
|
7596
7705
|
}
|
|
7597
7706
|
await handler.updateThemeColorScheme(colorScheme);
|
|
7598
|
-
const previousMap = theme?.colorScheme ?
|
|
7599
|
-
setSlides((prev) =>
|
|
7707
|
+
const previousMap = theme?.colorScheme ? chunkWVDM36ZM_js.buildThemeColorMap(theme.colorScheme) : {};
|
|
7708
|
+
setSlides((prev) => chunkWVDM36ZM_js.reResolveSlideColors(prev, previousMap, colorScheme));
|
|
7600
7709
|
setTheme((prev) => prev ? { ...prev, colorScheme } : { colorScheme });
|
|
7601
7710
|
bumpHistory();
|
|
7602
7711
|
history.markDirty();
|
|
@@ -7701,7 +7810,7 @@ function useThemeSwitching(input) {
|
|
|
7701
7810
|
}
|
|
7702
7811
|
try {
|
|
7703
7812
|
await handler.applyTheme(preset.colorScheme, preset.fontScheme, preset.name);
|
|
7704
|
-
const newData =
|
|
7813
|
+
const newData = chunkWVDM36ZM_js.applyThemeToData(data, preset.colorScheme, preset.fontScheme, preset.name);
|
|
7705
7814
|
onDataChange(newData);
|
|
7706
7815
|
onThemeChanged?.(preset);
|
|
7707
7816
|
} catch (error) {
|
|
@@ -7718,7 +7827,7 @@ function useThemeSwitching(input) {
|
|
|
7718
7827
|
}
|
|
7719
7828
|
try {
|
|
7720
7829
|
await handler.applyTheme(colorScheme, fontScheme ?? {}, themeName);
|
|
7721
|
-
const newData =
|
|
7830
|
+
const newData = chunkWVDM36ZM_js.applyThemeToData(data, colorScheme, fontScheme, themeName);
|
|
7722
7831
|
onDataChange(newData);
|
|
7723
7832
|
} catch (error) {
|
|
7724
7833
|
console.error("Failed to switch to custom theme:", error);
|
|
@@ -7730,12 +7839,12 @@ function useThemeSwitching(input) {
|
|
|
7730
7839
|
if (!data?.theme?.colorScheme) {
|
|
7731
7840
|
return void 0;
|
|
7732
7841
|
}
|
|
7733
|
-
return
|
|
7734
|
-
(p) =>
|
|
7842
|
+
return chunkWVDM36ZM_js.THEME_PRESETS.find(
|
|
7843
|
+
(p) => chunkWVDM36ZM_js.themeColorSchemesEqual(data.theme?.colorScheme, p.colorScheme)
|
|
7735
7844
|
);
|
|
7736
7845
|
}, [data?.theme?.colorScheme]);
|
|
7737
7846
|
return {
|
|
7738
|
-
presets:
|
|
7847
|
+
presets: chunkWVDM36ZM_js.THEME_PRESETS,
|
|
7739
7848
|
switchToPreset,
|
|
7740
7849
|
switchToCustom,
|
|
7741
7850
|
currentPreset
|
|
@@ -7810,7 +7919,7 @@ function usePropertyHandlers(input) {
|
|
|
7810
7919
|
}
|
|
7811
7920
|
try {
|
|
7812
7921
|
const ab = await file.arrayBuffer();
|
|
7813
|
-
const h = new
|
|
7922
|
+
const h = new chunkWVDM36ZM_js.PptxHandler();
|
|
7814
7923
|
const other = await h.load(ab);
|
|
7815
7924
|
if (!other) {
|
|
7816
7925
|
return;
|
|
@@ -7820,7 +7929,7 @@ function usePropertyHandlers(input) {
|
|
|
7820
7929
|
width: canvasSize.width,
|
|
7821
7930
|
height: canvasSize.height
|
|
7822
7931
|
};
|
|
7823
|
-
setCompareResult(
|
|
7932
|
+
setCompareResult(chunkWVDM36ZM_js.comparePresentation(cur, other));
|
|
7824
7933
|
setIsComparePanelOpen(true);
|
|
7825
7934
|
} catch (err) {
|
|
7826
7935
|
console.warn("Compare failed:", err);
|
|
@@ -7837,7 +7946,7 @@ function usePropertyHandlers(input) {
|
|
|
7837
7946
|
if (!diff || diff.status === "unchanged") {
|
|
7838
7947
|
return;
|
|
7839
7948
|
}
|
|
7840
|
-
setSlides((prev) =>
|
|
7949
|
+
setSlides((prev) => chunkWVDM36ZM_js.applyAcceptSlide(prev, diff));
|
|
7841
7950
|
setIsDirty(true);
|
|
7842
7951
|
},
|
|
7843
7952
|
[compareResult, setSlides, setIsDirty]
|
|
@@ -7848,10 +7957,10 @@ function usePropertyHandlers(input) {
|
|
|
7848
7957
|
if (!compareResult) {
|
|
7849
7958
|
return;
|
|
7850
7959
|
}
|
|
7851
|
-
setSlides((prev) =>
|
|
7960
|
+
setSlides((prev) => chunkWVDM36ZM_js.applyAcceptAllSlides(prev, compareResult));
|
|
7852
7961
|
setIsDirty(true);
|
|
7853
7962
|
}, [compareResult, setSlides, setIsDirty]);
|
|
7854
|
-
const usedFontFamilies = react.useMemo(() =>
|
|
7963
|
+
const usedFontFamilies = react.useMemo(() => chunkWVDM36ZM_js.collectUsedFonts(slides), [slides]);
|
|
7855
7964
|
return {
|
|
7856
7965
|
handleUpdateNotes,
|
|
7857
7966
|
handleUpdateSlide,
|
|
@@ -7970,7 +8079,7 @@ function useIsMobile(input) {
|
|
|
7970
8079
|
const containerRef = input?.containerRef;
|
|
7971
8080
|
const isTouchDevice = react.useSyncExternalStore(
|
|
7972
8081
|
subscribeTouchCapability,
|
|
7973
|
-
|
|
8082
|
+
chunkWVDM36ZM_js.detectTouchDevice,
|
|
7974
8083
|
() => false
|
|
7975
8084
|
// server snapshot
|
|
7976
8085
|
);
|
|
@@ -7986,7 +8095,7 @@ function useIsMobile(input) {
|
|
|
7986
8095
|
}
|
|
7987
8096
|
return containerRef?.current?.clientHeight ?? window.innerHeight;
|
|
7988
8097
|
});
|
|
7989
|
-
const [orientation, setOrientation] = react.useState(
|
|
8098
|
+
const [orientation, setOrientation] = react.useState(chunkWVDM36ZM_js.detectOrientation);
|
|
7990
8099
|
const [isVirtualKeyboardOpen, setIsVirtualKeyboardOpen] = react.useState(false);
|
|
7991
8100
|
const [initialViewportHeight] = react.useState(
|
|
7992
8101
|
() => typeof window !== "undefined" ? window.innerHeight : 800
|
|
@@ -8030,7 +8139,7 @@ function useIsMobile(input) {
|
|
|
8030
8139
|
return;
|
|
8031
8140
|
}
|
|
8032
8141
|
const handleOrientationChange = () => {
|
|
8033
|
-
setOrientation(
|
|
8142
|
+
setOrientation(chunkWVDM36ZM_js.detectOrientation());
|
|
8034
8143
|
};
|
|
8035
8144
|
if (screen.orientation) {
|
|
8036
8145
|
screen.orientation.addEventListener("change", handleOrientationChange);
|
|
@@ -8060,9 +8169,9 @@ function useIsMobile(input) {
|
|
|
8060
8169
|
window.addEventListener("resize", handleResize);
|
|
8061
8170
|
return () => window.removeEventListener("resize", handleResize);
|
|
8062
8171
|
}, [isTouchDevice, initialViewportHeight]);
|
|
8063
|
-
const isMobile =
|
|
8064
|
-
const isTablet = !isMobile && containerWidth >=
|
|
8065
|
-
const isDesktop = !isMobile && containerWidth >=
|
|
8172
|
+
const isMobile = chunkWVDM36ZM_js.isMobileViewport(containerWidth, containerHeight, isTouchDevice);
|
|
8173
|
+
const isTablet = !isMobile && containerWidth >= chunkWVDM36ZM_js.MOBILE_BREAKPOINT && containerWidth < chunkWVDM36ZM_js.TABLET_BREAKPOINT;
|
|
8174
|
+
const isDesktop = !isMobile && containerWidth >= chunkWVDM36ZM_js.TABLET_BREAKPOINT;
|
|
8066
8175
|
return {
|
|
8067
8176
|
isMobile,
|
|
8068
8177
|
isTablet,
|
|
@@ -8103,7 +8212,8 @@ function useViewerDialogs(input) {
|
|
|
8103
8212
|
preMasterMode,
|
|
8104
8213
|
hasDigitalSignatures,
|
|
8105
8214
|
isDirty,
|
|
8106
|
-
history
|
|
8215
|
+
history,
|
|
8216
|
+
embeddedFontFamilies
|
|
8107
8217
|
} = input;
|
|
8108
8218
|
const [isSmartArtDialogOpen, setIsSmartArtDialogOpen] = react.useState(false);
|
|
8109
8219
|
const [isEquationDialogOpen, setIsEquationDialogOpen] = react.useState(false);
|
|
@@ -8121,13 +8231,21 @@ function useViewerDialogs(input) {
|
|
|
8121
8231
|
const [editingEquationOmml, setEditingEquationOmml] = react.useState(
|
|
8122
8232
|
null
|
|
8123
8233
|
);
|
|
8124
|
-
const
|
|
8234
|
+
const embeddedFontKey = (embeddedFontFamilies ?? []).join("\0");
|
|
8235
|
+
const fontEmbedding = react.useMemo(
|
|
8236
|
+
() => chunkWVDM36ZM_js.describeFontEmbedding(embeddedFontKey ? embeddedFontKey.split("\0") : []),
|
|
8237
|
+
[embeddedFontKey]
|
|
8238
|
+
);
|
|
8239
|
+
const [embedFontsEnabled, setEmbedFontsEnabled] = react.useState(fontEmbedding.initialEnabled);
|
|
8240
|
+
react.useEffect(() => {
|
|
8241
|
+
setEmbedFontsEnabled(fontEmbedding.initialEnabled);
|
|
8242
|
+
}, [fontEmbedding]);
|
|
8125
8243
|
const [isNarrowViewport, setIsNarrowViewport] = react.useState(
|
|
8126
|
-
() => typeof window !== "undefined" ?
|
|
8244
|
+
() => typeof window !== "undefined" ? chunkWVDM36ZM_js.isMobileViewport(window.innerWidth, window.innerHeight, viewportIsTouch()) : false
|
|
8127
8245
|
);
|
|
8128
8246
|
react.useEffect(() => {
|
|
8129
8247
|
const handleWindow = () => setIsNarrowViewport(
|
|
8130
|
-
|
|
8248
|
+
chunkWVDM36ZM_js.isMobileViewport(window.innerWidth, window.innerHeight, viewportIsTouch())
|
|
8131
8249
|
);
|
|
8132
8250
|
let observer = null;
|
|
8133
8251
|
let raf = 0;
|
|
@@ -8141,12 +8259,12 @@ function useViewerDialogs(input) {
|
|
|
8141
8259
|
const entry = entries[0];
|
|
8142
8260
|
if (entry) {
|
|
8143
8261
|
setIsNarrowViewport(
|
|
8144
|
-
|
|
8262
|
+
chunkWVDM36ZM_js.isMobileViewport(entry.contentRect.width, entry.contentRect.height, viewportIsTouch())
|
|
8145
8263
|
);
|
|
8146
8264
|
}
|
|
8147
8265
|
});
|
|
8148
8266
|
observer.observe(el);
|
|
8149
|
-
setIsNarrowViewport(
|
|
8267
|
+
setIsNarrowViewport(chunkWVDM36ZM_js.isMobileViewport(el.clientWidth, el.clientHeight, viewportIsTouch()));
|
|
8150
8268
|
};
|
|
8151
8269
|
attach();
|
|
8152
8270
|
window.addEventListener("resize", handleWindow);
|
|
@@ -8288,6 +8406,7 @@ function useViewerDialogs(input) {
|
|
|
8288
8406
|
setEditingEquationOmml,
|
|
8289
8407
|
embedFontsEnabled,
|
|
8290
8408
|
setEmbedFontsEnabled,
|
|
8409
|
+
fontEmbedding,
|
|
8291
8410
|
isNarrowViewport,
|
|
8292
8411
|
handleEnterMasterView,
|
|
8293
8412
|
handleCloseMasterView,
|
|
@@ -8304,20 +8423,20 @@ function useViewerDialogs(input) {
|
|
|
8304
8423
|
}
|
|
8305
8424
|
function computeGridSpacingPx(presentationGridSpacing) {
|
|
8306
8425
|
if (presentationGridSpacing) {
|
|
8307
|
-
const px = Math.round(presentationGridSpacing.cx /
|
|
8426
|
+
const px = Math.round(presentationGridSpacing.cx / chunk4LWGAVAP_js.EMU_PER_PX);
|
|
8308
8427
|
if (px > 0) {
|
|
8309
8428
|
return px;
|
|
8310
8429
|
}
|
|
8311
8430
|
}
|
|
8312
|
-
return
|
|
8431
|
+
return chunk4LWGAVAP_js.GRID_SIZE;
|
|
8313
8432
|
}
|
|
8314
8433
|
function computeVisibleSlideIndexes(slides, activeCustomShowId, customShows) {
|
|
8315
8434
|
const activeShow = activeCustomShowId ? customShows.find((show) => show.id === activeCustomShowId) : void 0;
|
|
8316
|
-
return
|
|
8435
|
+
return chunkWVDM36ZM_js.resolveShowSlideIndexes(slides, activeShow);
|
|
8317
8436
|
}
|
|
8318
8437
|
function computeSlideSectionGroups(slides, sections) {
|
|
8319
|
-
return
|
|
8320
|
-
id: group.section?.id ?? (sections.length > 0 ?
|
|
8438
|
+
return chunkWVDM36ZM_js.groupSlidesBySection(sections, slides).map((group) => ({
|
|
8439
|
+
id: group.section?.id ?? (sections.length > 0 ? chunk4LWGAVAP_js.UNGROUPED_SECTION_ID : chunk4LWGAVAP_js.DEFAULT_SECTION_GROUP_ID),
|
|
8321
8440
|
label: group.section?.name ?? (sections.length > 0 ? "Ungrouped Slides" : "Slides"),
|
|
8322
8441
|
slideIndexes: group.slideIndexes,
|
|
8323
8442
|
...group.section?.color !== void 0 ? { color: group.section.color } : {},
|
|
@@ -8325,30 +8444,15 @@ function computeSlideSectionGroups(slides, sections) {
|
|
|
8325
8444
|
}));
|
|
8326
8445
|
}
|
|
8327
8446
|
function computeMasterPseudoSlide(mode, activeLayout, activeMaster) {
|
|
8328
|
-
if (mode !== "master") {
|
|
8447
|
+
if (mode !== "master" || !activeMaster) {
|
|
8329
8448
|
return void 0;
|
|
8330
8449
|
}
|
|
8331
|
-
|
|
8332
|
-
|
|
8333
|
-
|
|
8334
|
-
|
|
8335
|
-
|
|
8336
|
-
|
|
8337
|
-
backgroundColor: activeLayout.backgroundColor ?? activeMaster?.backgroundColor,
|
|
8338
|
-
backgroundImage: activeLayout.backgroundImage ?? activeMaster?.backgroundImage
|
|
8339
|
-
};
|
|
8340
|
-
}
|
|
8341
|
-
if (activeMaster) {
|
|
8342
|
-
return {
|
|
8343
|
-
id: activeMaster.path,
|
|
8344
|
-
rId: "",
|
|
8345
|
-
slideNumber: 0,
|
|
8346
|
-
elements: activeMaster.elements ?? [],
|
|
8347
|
-
backgroundColor: activeMaster.backgroundColor,
|
|
8348
|
-
backgroundImage: activeMaster.backgroundImage
|
|
8349
|
-
};
|
|
8350
|
-
}
|
|
8351
|
-
return void 0;
|
|
8450
|
+
const document2 = activeLayout ? { slideMasters: [{ ...activeMaster, layouts: [activeLayout] }] } : { slideMasters: [activeMaster] };
|
|
8451
|
+
return chunkWVDM36ZM_js.masterViewPseudoSlide(document2, {
|
|
8452
|
+
tab: "slides",
|
|
8453
|
+
masterIndex: 0,
|
|
8454
|
+
layoutIndex: activeLayout ? 0 : null
|
|
8455
|
+
});
|
|
8352
8456
|
}
|
|
8353
8457
|
function useDerivedSlideState(input) {
|
|
8354
8458
|
const { t } = reactI18next.useTranslation();
|
|
@@ -8372,10 +8476,10 @@ function useDerivedSlideState(input) {
|
|
|
8372
8476
|
);
|
|
8373
8477
|
const slideSectionGroups = react.useMemo(
|
|
8374
8478
|
() => computeSlideSectionGroups(slides, sections).map((group) => {
|
|
8375
|
-
if (group.id ===
|
|
8479
|
+
if (group.id === chunk4LWGAVAP_js.UNGROUPED_SECTION_ID && group.label === "Ungrouped Slides") {
|
|
8376
8480
|
return { ...group, label: t("pptx.slides.ungroupedSlides") };
|
|
8377
8481
|
}
|
|
8378
|
-
if (group.id ===
|
|
8482
|
+
if (group.id === chunk4LWGAVAP_js.DEFAULT_SECTION_GROUP_ID && group.label === "Slides") {
|
|
8379
8483
|
return { ...group, label: t("pptx.sections.slides") };
|
|
8380
8484
|
}
|
|
8381
8485
|
return group;
|
|
@@ -8475,13 +8579,13 @@ function useAnnotationHandlers(input) {
|
|
|
8475
8579
|
}, [annotations, setMode, setSlides, history]);
|
|
8476
8580
|
const handleSetMode = react.useCallback(
|
|
8477
8581
|
(nextMode) => {
|
|
8478
|
-
if (mode === "present" && nextMode !== "present" && !
|
|
8582
|
+
if (mode === "present" && nextMode !== "present" && !chunkWVDM36ZM_js.mayLeaveSlideShow()) {
|
|
8479
8583
|
return;
|
|
8480
8584
|
}
|
|
8481
8585
|
if (nextMode === "present") {
|
|
8482
8586
|
presentation.enterPresentMode();
|
|
8483
8587
|
} else if (mode === "present" && annotations.hasAnyAnnotations) {
|
|
8484
|
-
|
|
8588
|
+
chunkWVDM36ZM_js.stopAllPersistentAudio();
|
|
8485
8589
|
pendingModeAfterAnnotationsRef.current = nextMode;
|
|
8486
8590
|
if (promptKeepInkAnnotations) {
|
|
8487
8591
|
setShowKeepAnnotationsDialog(true);
|
|
@@ -8490,7 +8594,7 @@ function useAnnotationHandlers(input) {
|
|
|
8490
8594
|
}
|
|
8491
8595
|
} else {
|
|
8492
8596
|
if (mode === "present") {
|
|
8493
|
-
|
|
8597
|
+
chunkWVDM36ZM_js.stopAllPersistentAudio();
|
|
8494
8598
|
}
|
|
8495
8599
|
setMode(nextMode);
|
|
8496
8600
|
}
|
|
@@ -8529,6 +8633,8 @@ function useSerialize(input) {
|
|
|
8529
8633
|
slides,
|
|
8530
8634
|
templateElementsBySlideId,
|
|
8531
8635
|
activeSlideIndex,
|
|
8636
|
+
canvasSize,
|
|
8637
|
+
slideSizeEmu,
|
|
8532
8638
|
guides,
|
|
8533
8639
|
headerFooter,
|
|
8534
8640
|
presentationProperties,
|
|
@@ -8538,12 +8644,15 @@ function useSerialize(input) {
|
|
|
8538
8644
|
appProperties,
|
|
8539
8645
|
customProperties,
|
|
8540
8646
|
tagCollections,
|
|
8647
|
+
slideMasters,
|
|
8541
8648
|
notesMaster,
|
|
8542
8649
|
handoutMaster,
|
|
8543
8650
|
handlerRef,
|
|
8544
8651
|
inlineEditingElementIdRef,
|
|
8545
8652
|
inlineEditingTextRef,
|
|
8546
|
-
password
|
|
8653
|
+
password,
|
|
8654
|
+
embedFonts = true,
|
|
8655
|
+
purpose
|
|
8547
8656
|
} = input;
|
|
8548
8657
|
return react.useCallback(async () => {
|
|
8549
8658
|
const handler = handlerRef.current;
|
|
@@ -8556,13 +8665,13 @@ function useSerialize(input) {
|
|
|
8556
8665
|
let processedSlide = slide;
|
|
8557
8666
|
if (pendingEditId) {
|
|
8558
8667
|
const updatedElements = slide.elements.map((el) => {
|
|
8559
|
-
if (el.id !== pendingEditId || !
|
|
8668
|
+
if (el.id !== pendingEditId || !chunkWVDM36ZM_js.hasTextProperties(el)) {
|
|
8560
8669
|
return el;
|
|
8561
8670
|
}
|
|
8562
8671
|
return {
|
|
8563
8672
|
...el,
|
|
8564
8673
|
text: pendingEditText,
|
|
8565
|
-
textSegments:
|
|
8674
|
+
textSegments: chunkWVDM36ZM_js.remapTextToSegments(pendingEditText, el.textSegments, el.textStyle)
|
|
8566
8675
|
};
|
|
8567
8676
|
});
|
|
8568
8677
|
if (updatedElements.some((el, i) => el !== slide.elements[i])) {
|
|
@@ -8575,15 +8684,19 @@ function useSerialize(input) {
|
|
|
8575
8684
|
const pptxGuides = guides.map((g) => ({
|
|
8576
8685
|
id: g.id,
|
|
8577
8686
|
orientation: g.axis === "h" ? "horz" : "vert",
|
|
8578
|
-
positionEmu:
|
|
8687
|
+
positionEmu: chunkWVDM36ZM_js.guidePxToEmu(g.position)
|
|
8579
8688
|
}));
|
|
8580
8689
|
return {
|
|
8581
8690
|
...processedSlide,
|
|
8582
8691
|
guides: pptxGuides.length > 0 ? pptxGuides : void 0
|
|
8583
8692
|
};
|
|
8584
8693
|
});
|
|
8585
|
-
const slidesToSave =
|
|
8694
|
+
const slidesToSave = chunkWVDM36ZM_js.buildSaveSlides(slidesWithGuides, templateElementsBySlideId);
|
|
8586
8695
|
const saveOptions = {
|
|
8696
|
+
// Without this the Slide Size card edited a viewer-only pixel value and
|
|
8697
|
+
// the saved `p:sldSz` never moved: passing `slideSize` is the only way a
|
|
8698
|
+
// slide-size edit reaches the file.
|
|
8699
|
+
slideSize: chunkWVDM36ZM_js.resolveSlideSizeSelection({ current: slideSizeEmu, canvas: canvasSize }).size,
|
|
8587
8700
|
headerFooter,
|
|
8588
8701
|
presentationProperties,
|
|
8589
8702
|
customShows: customShows.length > 0 ? customShows : void 0,
|
|
@@ -8592,16 +8705,17 @@ function useSerialize(input) {
|
|
|
8592
8705
|
appProperties,
|
|
8593
8706
|
customProperties: customProperties.length > 0 ? customProperties : void 0,
|
|
8594
8707
|
tags: tagCollections.length > 0 ? tagCollections : void 0,
|
|
8708
|
+
slideMasters,
|
|
8595
8709
|
notesMaster,
|
|
8596
|
-
handoutMaster
|
|
8710
|
+
handoutMaster,
|
|
8711
|
+
...chunkWVDM36ZM_js.embeddedFontSaveOptions(embedFonts)
|
|
8597
8712
|
};
|
|
8598
|
-
|
|
8599
|
-
return handler.saveEncrypted(slidesToSave, password, saveOptions);
|
|
8600
|
-
}
|
|
8601
|
-
return handler.save(slidesToSave, saveOptions);
|
|
8713
|
+
return chunkWVDM36ZM_js.saveDeckWithPassword(handler, slidesToSave, saveOptions, { password, purpose });
|
|
8602
8714
|
}, [
|
|
8603
8715
|
slides,
|
|
8604
8716
|
templateElementsBySlideId,
|
|
8717
|
+
canvasSize,
|
|
8718
|
+
slideSizeEmu,
|
|
8605
8719
|
headerFooter,
|
|
8606
8720
|
presentationProperties,
|
|
8607
8721
|
customShows,
|
|
@@ -8610,6 +8724,7 @@ function useSerialize(input) {
|
|
|
8610
8724
|
appProperties,
|
|
8611
8725
|
customProperties,
|
|
8612
8726
|
tagCollections,
|
|
8727
|
+
slideMasters,
|
|
8613
8728
|
notesMaster,
|
|
8614
8729
|
handoutMaster,
|
|
8615
8730
|
guides,
|
|
@@ -8617,7 +8732,9 @@ function useSerialize(input) {
|
|
|
8617
8732
|
handlerRef,
|
|
8618
8733
|
inlineEditingElementIdRef,
|
|
8619
8734
|
inlineEditingTextRef,
|
|
8620
|
-
password
|
|
8735
|
+
password,
|
|
8736
|
+
embedFonts,
|
|
8737
|
+
purpose
|
|
8621
8738
|
]);
|
|
8622
8739
|
}
|
|
8623
8740
|
|
|
@@ -8733,7 +8850,8 @@ function usePresentationSetup(input) {
|
|
|
8733
8850
|
history,
|
|
8734
8851
|
endWithBlackSlide = true,
|
|
8735
8852
|
promptKeepInkAnnotations = true,
|
|
8736
|
-
popupToolbarEnabled = true
|
|
8853
|
+
popupToolbarEnabled = true,
|
|
8854
|
+
onToggleSubtitles
|
|
8737
8855
|
} = input;
|
|
8738
8856
|
const actionSoundHandlerRef = react.useRef(null);
|
|
8739
8857
|
const [, setShowKeepAnnotationsDialog] = react.useState(false);
|
|
@@ -8751,7 +8869,7 @@ function usePresentationSetup(input) {
|
|
|
8751
8869
|
containerRef,
|
|
8752
8870
|
content,
|
|
8753
8871
|
onSetMode: (nextMode) => {
|
|
8754
|
-
if (mode === "present" && nextMode !== "present" && !
|
|
8872
|
+
if (mode === "present" && nextMode !== "present" && !chunkWVDM36ZM_js.mayLeaveSlideShow()) {
|
|
8755
8873
|
return;
|
|
8756
8874
|
}
|
|
8757
8875
|
if (mode === "present" && nextMode !== "present" && annotations.hasAnyAnnotations && promptKeepInkAnnotations) {
|
|
@@ -8759,7 +8877,7 @@ function usePresentationSetup(input) {
|
|
|
8759
8877
|
setShowKeepAnnotationsDialog(true);
|
|
8760
8878
|
} else {
|
|
8761
8879
|
if (mode === "present" && nextMode !== "present") {
|
|
8762
|
-
|
|
8880
|
+
chunkWVDM36ZM_js.stopAllPersistentAudio();
|
|
8763
8881
|
stopAnimationSound();
|
|
8764
8882
|
}
|
|
8765
8883
|
setMode(nextMode);
|
|
@@ -8812,11 +8930,12 @@ function usePresentationSetup(input) {
|
|
|
8812
8930
|
onEraseAnnotations: () => annotations.clearAnnotations(),
|
|
8813
8931
|
onToggleInkMarkup: () => annotations.setInkMarkupVisible(!annotations.inkMarkupVisible),
|
|
8814
8932
|
onToggleToolbar: () => annotations.setToolbarVisible(!annotations.toolbarVisible),
|
|
8933
|
+
onToggleSubtitles,
|
|
8815
8934
|
onSaveRehearsalTimings: (timings) => {
|
|
8816
|
-
setSlides((prev) =>
|
|
8935
|
+
setSlides((prev) => chunkWVDM36ZM_js.applyRehearsalTimings(prev, timings));
|
|
8817
8936
|
history.markDirty();
|
|
8818
8937
|
},
|
|
8819
|
-
loopContinuously:
|
|
8938
|
+
loopContinuously: chunkWVDM36ZM_js.shouldLoopContinuously(presentationProperties),
|
|
8820
8939
|
showWithAnimation: presentationProperties.showWithAnimation,
|
|
8821
8940
|
useTimings: presentationProperties.advanceMode !== "manual",
|
|
8822
8941
|
endWithBlackSlide
|
|
@@ -8843,6 +8962,33 @@ function useEditorOperations(input) {
|
|
|
8843
8962
|
handlerRef,
|
|
8844
8963
|
transformCommittedText
|
|
8845
8964
|
} = input;
|
|
8965
|
+
const masterView = react.useMemo(
|
|
8966
|
+
() => ({
|
|
8967
|
+
target: mode === "master" ? {
|
|
8968
|
+
tab: state.masterViewTab,
|
|
8969
|
+
masterIndex: state.activeMasterIndex,
|
|
8970
|
+
layoutIndex: state.activeLayoutIndex
|
|
8971
|
+
} : null,
|
|
8972
|
+
slideMasters: state.slideMasters,
|
|
8973
|
+
notesMaster: state.notesMaster,
|
|
8974
|
+
handoutMaster: state.handoutMaster,
|
|
8975
|
+
setSlideMasters: state.setSlideMasters,
|
|
8976
|
+
setNotesMaster: state.setNotesMaster,
|
|
8977
|
+
setHandoutMaster: state.setHandoutMaster
|
|
8978
|
+
}),
|
|
8979
|
+
[
|
|
8980
|
+
mode,
|
|
8981
|
+
state.masterViewTab,
|
|
8982
|
+
state.activeMasterIndex,
|
|
8983
|
+
state.activeLayoutIndex,
|
|
8984
|
+
state.slideMasters,
|
|
8985
|
+
state.notesMaster,
|
|
8986
|
+
state.handoutMaster,
|
|
8987
|
+
state.setSlideMasters,
|
|
8988
|
+
state.setNotesMaster,
|
|
8989
|
+
state.setHandoutMaster
|
|
8990
|
+
]
|
|
8991
|
+
);
|
|
8846
8992
|
const ops = useElementOperations({
|
|
8847
8993
|
activeSlide,
|
|
8848
8994
|
activeSlideIndex,
|
|
@@ -8850,6 +8996,7 @@ function useEditorOperations(input) {
|
|
|
8850
8996
|
selectedElementId,
|
|
8851
8997
|
editTemplateMode: state.editTemplateMode,
|
|
8852
8998
|
templateElements: state.templateElements,
|
|
8999
|
+
masterView,
|
|
8853
9000
|
history,
|
|
8854
9001
|
setSlides: state.setSlides,
|
|
8855
9002
|
setTemplateElementsBySlideId: state.setTemplateElementsBySlideId,
|
|
@@ -8981,7 +9128,7 @@ function useEditorOperations(input) {
|
|
|
8981
9128
|
const { formatPainterActive, setFormatPainterActive, elementLookup } = state;
|
|
8982
9129
|
react.useEffect(() => {
|
|
8983
9130
|
if (formatPainterActive && !prevFormatPainterRef.current && selectedElement) {
|
|
8984
|
-
copiedFormatRef.current =
|
|
9131
|
+
copiedFormatRef.current = chunkWVDM36ZM_js.copyFormatFromElement(selectedElement);
|
|
8985
9132
|
} else if (!formatPainterActive) {
|
|
8986
9133
|
copiedFormatRef.current = null;
|
|
8987
9134
|
}
|
|
@@ -9007,12 +9154,12 @@ function useEditorOperations(input) {
|
|
|
9007
9154
|
e.stopPropagation();
|
|
9008
9155
|
const element = elementLookup.get(elementId);
|
|
9009
9156
|
if (element) {
|
|
9010
|
-
const updated =
|
|
9157
|
+
const updated = chunkWVDM36ZM_js.applyFormatToElement(element, copiedFormatRef.current);
|
|
9011
9158
|
const updates = {};
|
|
9012
|
-
if (
|
|
9159
|
+
if (chunkWVDM36ZM_js.hasShapeProperties(updated)) {
|
|
9013
9160
|
updates.shapeStyle = updated.shapeStyle;
|
|
9014
9161
|
}
|
|
9015
|
-
if (
|
|
9162
|
+
if (chunkWVDM36ZM_js.hasTextProperties(updated)) {
|
|
9016
9163
|
updates.textStyle = updated.textStyle;
|
|
9017
9164
|
}
|
|
9018
9165
|
ops.updateElementById(elementId, updates);
|
|
@@ -9060,6 +9207,7 @@ function useIOHandlers(input) {
|
|
|
9060
9207
|
zoom,
|
|
9061
9208
|
handlerRef,
|
|
9062
9209
|
serializeSlides,
|
|
9210
|
+
serializeForRecovery,
|
|
9063
9211
|
setContent,
|
|
9064
9212
|
onContentChange,
|
|
9065
9213
|
password
|
|
@@ -9082,12 +9230,14 @@ function useIOHandlers(input) {
|
|
|
9082
9230
|
appProperties: state.appProperties ?? null,
|
|
9083
9231
|
customProperties: state.customProperties,
|
|
9084
9232
|
tagCollections: state.tagCollections,
|
|
9233
|
+
slideMasters: state.slideMasters,
|
|
9085
9234
|
notesMaster: state.notesMaster,
|
|
9086
9235
|
handoutMaster: state.handoutMaster,
|
|
9087
9236
|
guides: state.guides,
|
|
9088
9237
|
activeSlideIndexForGuides: state.activeSlideIndex,
|
|
9089
9238
|
theme: state.theme,
|
|
9090
9239
|
canvasSize,
|
|
9240
|
+
slideSizeEmu: state.slideSizeEmu,
|
|
9091
9241
|
password
|
|
9092
9242
|
});
|
|
9093
9243
|
const printHandlers = usePrintHandlers({
|
|
@@ -9098,7 +9248,9 @@ function useIOHandlers(input) {
|
|
|
9098
9248
|
});
|
|
9099
9249
|
const themeHandlers = useThemeHandlers({
|
|
9100
9250
|
handlerRef,
|
|
9101
|
-
|
|
9251
|
+
// Theme apply re-serialises and re-parses through `setContent`, so these
|
|
9252
|
+
// bytes go back into our own loader: plaintext, never the protected save.
|
|
9253
|
+
serializeSlides: serializeForRecovery,
|
|
9102
9254
|
setContent,
|
|
9103
9255
|
onContentChange,
|
|
9104
9256
|
setTheme: state.setTheme,
|
|
@@ -9161,7 +9313,7 @@ function collectReferencedFontFamilies(slides) {
|
|
|
9161
9313
|
const families = /* @__PURE__ */ new Set();
|
|
9162
9314
|
for (const slide of slides) {
|
|
9163
9315
|
for (const el of slide.elements) {
|
|
9164
|
-
if (
|
|
9316
|
+
if (chunkWVDM36ZM_js.hasTextProperties(el) && el.textSegments) {
|
|
9165
9317
|
for (const seg of el.textSegments) {
|
|
9166
9318
|
if (seg.style.fontFamily) {
|
|
9167
9319
|
families.add(seg.style.fontFamily);
|
|
@@ -9291,6 +9443,8 @@ function useContentLifecycle(input) {
|
|
|
9291
9443
|
content,
|
|
9292
9444
|
filePath,
|
|
9293
9445
|
autosaveEnabled = true,
|
|
9446
|
+
autosaveIntervalSeconds,
|
|
9447
|
+
embedFonts = true,
|
|
9294
9448
|
slides,
|
|
9295
9449
|
state,
|
|
9296
9450
|
history,
|
|
@@ -9308,6 +9462,7 @@ function useContentLifecycle(input) {
|
|
|
9308
9462
|
setTemplateElementsBySlideId: state.setTemplateElementsBySlideId,
|
|
9309
9463
|
mediaDataUrls: state.mediaDataUrls,
|
|
9310
9464
|
setCanvasSize: state.setCanvasSize,
|
|
9465
|
+
setSlideSizeEmu: state.setSlideSizeEmu,
|
|
9311
9466
|
setHeaderFooter: state.setHeaderFooter,
|
|
9312
9467
|
setLayoutOptions: state.setLayoutOptions,
|
|
9313
9468
|
setSlideMasters: state.setSlideMasters,
|
|
@@ -9315,6 +9470,7 @@ function useContentLifecycle(input) {
|
|
|
9315
9470
|
setTableStyleMap: state.setTableStyleMap,
|
|
9316
9471
|
setThemeOptions: state.setThemeOptions,
|
|
9317
9472
|
setCustomShows: state.setCustomShows,
|
|
9473
|
+
setActiveCustomShowId: state.setActiveCustomShowId,
|
|
9318
9474
|
setSections: state.setSections,
|
|
9319
9475
|
setPresentationProperties: state.setPresentationProperties,
|
|
9320
9476
|
setNotesMaster: state.setNotesMaster,
|
|
@@ -9340,10 +9496,12 @@ function useContentLifecycle(input) {
|
|
|
9340
9496
|
actionSoundHandlerRef.current = handlerRef.current;
|
|
9341
9497
|
}, [handlerRef, actionSoundHandlerRef, state.loading]);
|
|
9342
9498
|
useFontInjection({ embeddedFonts: state.embeddedFonts, slides });
|
|
9343
|
-
const
|
|
9499
|
+
const serializeInput = {
|
|
9344
9500
|
slides,
|
|
9345
9501
|
templateElementsBySlideId: state.templateElementsBySlideId,
|
|
9346
9502
|
activeSlideIndex: state.activeSlideIndex,
|
|
9503
|
+
canvasSize: state.canvasSize,
|
|
9504
|
+
slideSizeEmu: state.slideSizeEmu,
|
|
9347
9505
|
guides: state.guides,
|
|
9348
9506
|
headerFooter: state.headerFooter,
|
|
9349
9507
|
presentationProperties: state.presentationProperties,
|
|
@@ -9353,33 +9511,69 @@ function useContentLifecycle(input) {
|
|
|
9353
9511
|
appProperties: state.appProperties,
|
|
9354
9512
|
customProperties: state.customProperties,
|
|
9355
9513
|
tagCollections: state.tagCollections,
|
|
9514
|
+
slideMasters: state.slideMasters,
|
|
9356
9515
|
notesMaster: state.notesMaster,
|
|
9357
9516
|
handoutMaster: state.handoutMaster,
|
|
9358
9517
|
handlerRef,
|
|
9359
9518
|
inlineEditingElementIdRef: state.inlineEditingElementIdRef,
|
|
9360
9519
|
inlineEditingTextRef: state.inlineEditingTextRef,
|
|
9361
|
-
password
|
|
9362
|
-
|
|
9520
|
+
password,
|
|
9521
|
+
embedFonts
|
|
9522
|
+
};
|
|
9523
|
+
const serializeSlides = useSerialize(serializeInput);
|
|
9524
|
+
const serializeForRecovery = useSerialize({ ...serializeInput, purpose: "recovery-snapshot" });
|
|
9363
9525
|
const { autosaveStatus } = useAutosave({
|
|
9364
9526
|
isDirty: state.isDirty,
|
|
9365
9527
|
filePath,
|
|
9366
|
-
serializeSlides,
|
|
9367
|
-
enabled: autosaveEnabled
|
|
9528
|
+
serializeSlides: serializeForRecovery,
|
|
9529
|
+
enabled: autosaveEnabled,
|
|
9530
|
+
...autosaveIntervalSeconds === void 0 ? {} : { intervalSeconds: autosaveIntervalSeconds },
|
|
9531
|
+
// Everything `serializeForRecovery` reads that changes by REASSIGNMENT,
|
|
9532
|
+
// so a poll that finds all of them unchanged can skip re-serializing a
|
|
9533
|
+
// deck it has already snapshotted. The two refs are read by `.current`
|
|
9534
|
+
// because an inline edit in progress lives there and nowhere else yet.
|
|
9535
|
+
getChangeSources: () => [
|
|
9536
|
+
slides,
|
|
9537
|
+
state.templateElementsBySlideId,
|
|
9538
|
+
state.guides,
|
|
9539
|
+
state.headerFooter,
|
|
9540
|
+
state.presentationProperties,
|
|
9541
|
+
state.customShows,
|
|
9542
|
+
state.sections,
|
|
9543
|
+
state.coreProperties,
|
|
9544
|
+
state.appProperties,
|
|
9545
|
+
state.customProperties,
|
|
9546
|
+
state.tagCollections,
|
|
9547
|
+
state.notesMaster,
|
|
9548
|
+
state.handoutMaster,
|
|
9549
|
+
state.embeddedFonts,
|
|
9550
|
+
embedFonts,
|
|
9551
|
+
password,
|
|
9552
|
+
state.inlineEditingElementIdRef.current,
|
|
9553
|
+
state.inlineEditingTextRef.current
|
|
9554
|
+
]
|
|
9368
9555
|
});
|
|
9369
|
-
return { handlerRef, serializeSlides, autosaveStatus };
|
|
9556
|
+
return { handlerRef, serializeSlides, serializeForRecovery, autosaveStatus };
|
|
9370
9557
|
}
|
|
9371
9558
|
function useKeyboardShortcuts(input) {
|
|
9372
9559
|
const inputRef = react.useRef(input);
|
|
9373
9560
|
inputRef.current = input;
|
|
9374
9561
|
const handleKeyDown = react.useCallback((e) => {
|
|
9375
9562
|
const current = inputRef.current;
|
|
9376
|
-
const { action, dx, dy } =
|
|
9563
|
+
const { action, dx, dy } = chunkWVDM36ZM_js.mapEditorKey(e, {
|
|
9377
9564
|
canEdit: current.canEdit,
|
|
9378
|
-
|
|
9565
|
+
// The Slide Master view is an editing surface, not a viewing one.
|
|
9566
|
+
// Gating on `mode !== 'edit'` alone made `mapEditorKey` return
|
|
9567
|
+
// NO_ACTION there, so Delete, the arrow-key nudges and the clipboard
|
|
9568
|
+
// keys were all inert over a master shape even though the write path
|
|
9569
|
+
// behind them routes to the owning part correctly. Svelte and
|
|
9570
|
+
// vanilla, which render the master into their ordinary editable
|
|
9571
|
+
// stage, never had the gap.
|
|
9572
|
+
isPresenting: current.mode !== "edit" && current.mode !== "master",
|
|
9379
9573
|
hasSelection: current.hasSelection,
|
|
9380
9574
|
isEditingText: Boolean(current.inlineEditingElementId || current.tableEditorState?.isEditing),
|
|
9381
9575
|
isDrawing: current.activeTool !== "select",
|
|
9382
|
-
isTextInputTarget:
|
|
9576
|
+
isTextInputTarget: chunkWVDM36ZM_js.isEditorTextInputTarget(e.target)
|
|
9383
9577
|
});
|
|
9384
9578
|
if (action === null) {
|
|
9385
9579
|
return;
|
|
@@ -9422,6 +9616,9 @@ function useKeyboardShortcuts(input) {
|
|
|
9422
9616
|
case "toggleShortcuts":
|
|
9423
9617
|
current.onToggleShortcuts?.();
|
|
9424
9618
|
break;
|
|
9619
|
+
case "find":
|
|
9620
|
+
current.onFind?.();
|
|
9621
|
+
break;
|
|
9425
9622
|
case "nudge":
|
|
9426
9623
|
current.onNudge(dx ?? 0, dy ?? 0);
|
|
9427
9624
|
break;
|
|
@@ -9530,6 +9727,7 @@ function useViewerIntegration(input) {
|
|
|
9530
9727
|
content,
|
|
9531
9728
|
filePath,
|
|
9532
9729
|
autosaveEnabled,
|
|
9730
|
+
autosaveIntervalSeconds,
|
|
9533
9731
|
canEdit,
|
|
9534
9732
|
mode,
|
|
9535
9733
|
slides,
|
|
@@ -9580,19 +9778,24 @@ function useViewerIntegration(input) {
|
|
|
9580
9778
|
});
|
|
9581
9779
|
const [isEncryptedDialogOpen, setIsEncryptedDialogOpen] = react.useState(false);
|
|
9582
9780
|
const [loadVersion, setLoadVersion] = react.useState(0);
|
|
9583
|
-
const { handlerRef, serializeSlides, autosaveStatus } = useContentLifecycle(
|
|
9584
|
-
|
|
9585
|
-
|
|
9586
|
-
|
|
9587
|
-
|
|
9588
|
-
|
|
9589
|
-
|
|
9590
|
-
|
|
9591
|
-
|
|
9592
|
-
|
|
9593
|
-
|
|
9594
|
-
|
|
9595
|
-
|
|
9781
|
+
const { handlerRef, serializeSlides, serializeForRecovery, autosaveStatus } = useContentLifecycle(
|
|
9782
|
+
{
|
|
9783
|
+
content,
|
|
9784
|
+
filePath,
|
|
9785
|
+
autosaveEnabled,
|
|
9786
|
+
autosaveIntervalSeconds,
|
|
9787
|
+
// The File > Fonts toggle, finally reaching a save call.
|
|
9788
|
+
embedFonts: dialogs.embedFontsEnabled,
|
|
9789
|
+
slides,
|
|
9790
|
+
state,
|
|
9791
|
+
history,
|
|
9792
|
+
ops: editorOps.ops,
|
|
9793
|
+
actionSoundHandlerRef,
|
|
9794
|
+
setIsEncryptedDialogOpen,
|
|
9795
|
+
password: dialogs.presentationPassword ?? void 0,
|
|
9796
|
+
onContentApplied: () => setLoadVersion((v) => v + 1)
|
|
9797
|
+
}
|
|
9798
|
+
);
|
|
9596
9799
|
const { exportHandlers, printHandlers, themeHandlers, propertyHandlers } = useIOHandlers({
|
|
9597
9800
|
state,
|
|
9598
9801
|
slides,
|
|
@@ -9604,6 +9807,7 @@ function useViewerIntegration(input) {
|
|
|
9604
9807
|
zoom,
|
|
9605
9808
|
handlerRef,
|
|
9606
9809
|
serializeSlides,
|
|
9810
|
+
serializeForRecovery,
|
|
9607
9811
|
setContent,
|
|
9608
9812
|
onContentChange,
|
|
9609
9813
|
password: dialogs.presentationPassword ?? void 0
|
|
@@ -9673,7 +9877,7 @@ function useViewerIntegration(input) {
|
|
|
9673
9877
|
return zoom.scale;
|
|
9674
9878
|
},
|
|
9675
9879
|
setZoom(level) {
|
|
9676
|
-
zoom.setScale(
|
|
9880
|
+
zoom.setScale(chunkWVDM36ZM_js.clampZoomScale(level));
|
|
9677
9881
|
},
|
|
9678
9882
|
zoomIn() {
|
|
9679
9883
|
zoom.handleZoomIn();
|
|
@@ -9888,7 +10092,7 @@ function useReducedMotion() {
|
|
|
9888
10092
|
}
|
|
9889
10093
|
function useViewerOptions() {
|
|
9890
10094
|
const storeRef = react.useRef(null);
|
|
9891
|
-
storeRef.current ??=
|
|
10095
|
+
storeRef.current ??= chunkWVDM36ZM_js.createViewerOptionsStore();
|
|
9892
10096
|
const store = storeRef.current;
|
|
9893
10097
|
const options = react.useSyncExternalStore(
|
|
9894
10098
|
(onStoreChange) => store.subscribe(onStoreChange),
|
|
@@ -9897,9 +10101,9 @@ function useViewerOptions() {
|
|
|
9897
10101
|
);
|
|
9898
10102
|
return { optionsStore: store, options };
|
|
9899
10103
|
}
|
|
9900
|
-
var KNOWN_TAB_IDS = new Set(
|
|
10104
|
+
var KNOWN_TAB_IDS = new Set(chunkWVDM36ZM_js.TOOLBAR_TABS.map((tab) => tab.id));
|
|
9901
10105
|
function computeToolbarVisibility(hiddenActions) {
|
|
9902
|
-
const isHidden = (id) =>
|
|
10106
|
+
const isHidden = (id) => chunkWVDM36ZM_js.isActionHidden(id, hiddenActions);
|
|
9903
10107
|
const isTabVisible = (id) => !KNOWN_TAB_IDS.has(id) || !isHidden(id);
|
|
9904
10108
|
return { isHidden, isTabVisible };
|
|
9905
10109
|
}
|
|
@@ -9984,12 +10188,12 @@ function useYjsDocumentSync({
|
|
|
9984
10188
|
return;
|
|
9985
10189
|
}
|
|
9986
10190
|
try {
|
|
9987
|
-
const handler = new
|
|
10191
|
+
const handler = new chunkWVDM36ZM_js.PptxHandler();
|
|
9988
10192
|
await handler.load(sourceBytes.buffer);
|
|
9989
|
-
const currentSlides =
|
|
10193
|
+
const currentSlides = chunkWVDM36ZM_js.readSlidesFromYDoc(
|
|
9990
10194
|
doc
|
|
9991
10195
|
);
|
|
9992
|
-
const slidesToSave =
|
|
10196
|
+
const slidesToSave = chunkWVDM36ZM_js.buildSaveSlides(currentSlides, templateElementsBySlideId);
|
|
9993
10197
|
const bytes = await handler.save(slidesToSave);
|
|
9994
10198
|
config.onWriteBack(bytes);
|
|
9995
10199
|
} catch {
|
|
@@ -10004,7 +10208,7 @@ function useYjsDocumentSync({
|
|
|
10004
10208
|
if (!doc || !isConnected) {
|
|
10005
10209
|
return;
|
|
10006
10210
|
}
|
|
10007
|
-
const docSlides =
|
|
10211
|
+
const docSlides = chunkWVDM36ZM_js.readSlidesFromYDoc(
|
|
10008
10212
|
doc
|
|
10009
10213
|
);
|
|
10010
10214
|
if (docSlides.length === 0) {
|
|
@@ -10026,11 +10230,11 @@ function useYjsDocumentSync({
|
|
|
10026
10230
|
lastSyncedRef.current = serialized;
|
|
10027
10231
|
void (async () => {
|
|
10028
10232
|
const factories = await getFactories();
|
|
10029
|
-
|
|
10233
|
+
chunkWVDM36ZM_js.reconcileSlidesInYDoc(
|
|
10030
10234
|
slides,
|
|
10031
10235
|
doc,
|
|
10032
10236
|
factories,
|
|
10033
|
-
|
|
10237
|
+
chunkWVDM36ZM_js.LOCAL_SYNC_ORIGIN
|
|
10034
10238
|
);
|
|
10035
10239
|
scheduleWriteBack();
|
|
10036
10240
|
})();
|
|
@@ -10044,10 +10248,10 @@ function useYjsDocumentSync({
|
|
|
10044
10248
|
return;
|
|
10045
10249
|
}
|
|
10046
10250
|
const handleChange = (_events, transaction) => {
|
|
10047
|
-
if (transaction?.origin ===
|
|
10251
|
+
if (transaction?.origin === chunkWVDM36ZM_js.LOCAL_SYNC_ORIGIN) {
|
|
10048
10252
|
return;
|
|
10049
10253
|
}
|
|
10050
|
-
const remoteSlides =
|
|
10254
|
+
const remoteSlides = chunkWVDM36ZM_js.readSlidesFromYDoc(
|
|
10051
10255
|
doc
|
|
10052
10256
|
);
|
|
10053
10257
|
if (remoteSlides.length === 0) {
|
|
@@ -10063,7 +10267,7 @@ function useYjsDocumentSync({
|
|
|
10063
10267
|
isApplyingRemoteRef.current = false;
|
|
10064
10268
|
scheduleWriteBack();
|
|
10065
10269
|
};
|
|
10066
|
-
const unobserve =
|
|
10270
|
+
const unobserve = chunkWVDM36ZM_js.observeYDocSlides(
|
|
10067
10271
|
doc,
|
|
10068
10272
|
handleChange
|
|
10069
10273
|
);
|
|
@@ -10101,7 +10305,7 @@ function useBroadcastFollower({
|
|
|
10101
10305
|
if (!broadcaster) {
|
|
10102
10306
|
return;
|
|
10103
10307
|
}
|
|
10104
|
-
if (!
|
|
10308
|
+
if (!chunkWVDM36ZM_js.shouldAutoFollowBroadcaster({
|
|
10105
10309
|
localRole: collab.config.role,
|
|
10106
10310
|
broadcasterRole: broadcaster.role
|
|
10107
10311
|
})) {
|
|
@@ -10242,11 +10446,16 @@ function useLayoutSwitching(input) {
|
|
|
10242
10446
|
},
|
|
10243
10447
|
[handler, activeSlideIndex, ops, history, onTemplateElementsChanged]
|
|
10244
10448
|
);
|
|
10449
|
+
const loadLayoutPreviews = react.useCallback(
|
|
10450
|
+
async () => handler ? handler.getLayoutPreviews() : [],
|
|
10451
|
+
[handler]
|
|
10452
|
+
);
|
|
10245
10453
|
return {
|
|
10246
10454
|
availableLayouts,
|
|
10247
10455
|
isLoading,
|
|
10248
10456
|
loadAvailableLayouts,
|
|
10249
10457
|
applyLayout,
|
|
10458
|
+
loadLayoutPreviews,
|
|
10250
10459
|
currentLayoutPath
|
|
10251
10460
|
};
|
|
10252
10461
|
}
|
|
@@ -10267,10 +10476,10 @@ function useTouchGestures(input) {
|
|
|
10267
10476
|
if (!el || !enabled) {
|
|
10268
10477
|
return;
|
|
10269
10478
|
}
|
|
10270
|
-
const recognizer =
|
|
10479
|
+
const recognizer = chunkWVDM36ZM_js.createTouchGestureRecognizer({
|
|
10271
10480
|
getScale: () => scaleRef.current,
|
|
10272
|
-
minScale:
|
|
10273
|
-
maxScale:
|
|
10481
|
+
minScale: chunkWVDM36ZM_js.MIN_ZOOM_SCALE,
|
|
10482
|
+
maxScale: chunkWVDM36ZM_js.MAX_ZOOM_SCALE,
|
|
10274
10483
|
callbacks: {
|
|
10275
10484
|
onPinchZoom: (newScale) => callbacksRef.current.onPinchZoom?.(newScale),
|
|
10276
10485
|
onSwipe: (direction) => callbacksRef.current.onSwipe?.(direction),
|
|
@@ -10310,7 +10519,7 @@ function scrollFocusedIntoView(keyboardInset) {
|
|
|
10310
10519
|
return;
|
|
10311
10520
|
}
|
|
10312
10521
|
const rect = active.getBoundingClientRect();
|
|
10313
|
-
const delta =
|
|
10522
|
+
const delta = chunkWVDM36ZM_js.computeScrollDelta(
|
|
10314
10523
|
{ top: rect.top, bottom: rect.bottom },
|
|
10315
10524
|
window.innerHeight,
|
|
10316
10525
|
keyboardInset
|
|
@@ -10330,8 +10539,8 @@ function useKeyboardInsets(enabled = true) {
|
|
|
10330
10539
|
return;
|
|
10331
10540
|
}
|
|
10332
10541
|
const update = () => {
|
|
10333
|
-
const metrics =
|
|
10334
|
-
const inset = metrics ?
|
|
10542
|
+
const metrics = chunkWVDM36ZM_js.readViewportMetrics(window);
|
|
10543
|
+
const inset = metrics ? chunkWVDM36ZM_js.computeKeyboardInset(metrics) : 0;
|
|
10335
10544
|
setKeyboardInset(inset);
|
|
10336
10545
|
if (inset > 0) {
|
|
10337
10546
|
window.requestAnimationFrame(() => scrollFocusedIntoView(inset));
|
|
@@ -10342,8 +10551,8 @@ function useKeyboardInsets(enabled = true) {
|
|
|
10342
10551
|
vv.addEventListener("scroll", update);
|
|
10343
10552
|
const onFocusIn = () => {
|
|
10344
10553
|
window.requestAnimationFrame(() => {
|
|
10345
|
-
const metrics =
|
|
10346
|
-
const inset = metrics ?
|
|
10554
|
+
const metrics = chunkWVDM36ZM_js.readViewportMetrics(window);
|
|
10555
|
+
const inset = metrics ? chunkWVDM36ZM_js.computeKeyboardInset(metrics) : 0;
|
|
10347
10556
|
if (inset > 0) {
|
|
10348
10557
|
scrollFocusedIntoView(inset);
|
|
10349
10558
|
}
|
|
@@ -10356,7 +10565,7 @@ function useKeyboardInsets(enabled = true) {
|
|
|
10356
10565
|
document.removeEventListener("focusin", onFocusIn);
|
|
10357
10566
|
};
|
|
10358
10567
|
}, [enabled]);
|
|
10359
|
-
return { keyboardInset, isKeyboardOpen:
|
|
10568
|
+
return { keyboardInset, isKeyboardOpen: chunkWVDM36ZM_js.isKeyboardOpen(keyboardInset) };
|
|
10360
10569
|
}
|
|
10361
10570
|
|
|
10362
10571
|
// src/viewer/hooks/useViewerBuildingBlocks-canvas-props.ts
|
|
@@ -10383,7 +10592,7 @@ function buildCanvasProps(input) {
|
|
|
10383
10592
|
} = input;
|
|
10384
10593
|
const effectiveSlide = mode === "master" ? masterPseudoSlide : activeSlide;
|
|
10385
10594
|
const effectiveTemplateElements = mode === "master" ? s.activeLayout ? s.activeMaster?.elements ?? [] : [] : templateElements;
|
|
10386
|
-
const fieldContext =
|
|
10595
|
+
const fieldContext = chunkWVDM36ZM_js.buildFieldSubstitutionContext({
|
|
10387
10596
|
headerFooter: s.headerFooter,
|
|
10388
10597
|
customProperties: s.customProperties,
|
|
10389
10598
|
slide: activeSlide
|
|
@@ -10393,13 +10602,13 @@ function buildCanvasProps(input) {
|
|
|
10393
10602
|
if (mode === "present") {
|
|
10394
10603
|
presentation.handlePresentationAction(action);
|
|
10395
10604
|
} else if (action.url) {
|
|
10396
|
-
|
|
10605
|
+
chunkWVDM36ZM_js.safeOpenUrl(action.url);
|
|
10397
10606
|
}
|
|
10398
10607
|
};
|
|
10399
10608
|
const handleHyperlinkClick = (url) => {
|
|
10400
|
-
if (
|
|
10609
|
+
if (chunkWVDM36ZM_js.isPpactionUrl(url)) {
|
|
10401
10610
|
if (mode === "present") {
|
|
10402
|
-
const parsed =
|
|
10611
|
+
const parsed = chunkWVDM36ZM_js.parsePpactionUrl(url);
|
|
10403
10612
|
if (parsed) {
|
|
10404
10613
|
presentation.handlePresentationAction({
|
|
10405
10614
|
action: parsed.action,
|
|
@@ -10409,7 +10618,7 @@ function buildCanvasProps(input) {
|
|
|
10409
10618
|
}
|
|
10410
10619
|
return;
|
|
10411
10620
|
}
|
|
10412
|
-
|
|
10621
|
+
chunkWVDM36ZM_js.safeOpenUrl(url);
|
|
10413
10622
|
};
|
|
10414
10623
|
return {
|
|
10415
10624
|
activeSlide: effectiveSlide,
|
|
@@ -10505,41 +10714,7 @@ function buildCanvasProps(input) {
|
|
|
10505
10714
|
|
|
10506
10715
|
// src/viewer/hooks/useScopedLayoutOptions.ts
|
|
10507
10716
|
function scopeLayoutOptionsToActiveSlide(options, activeSlide) {
|
|
10508
|
-
|
|
10509
|
-
return options;
|
|
10510
|
-
}
|
|
10511
|
-
const hasAnyMasterInfo = options.some((o) => o.masterPath);
|
|
10512
|
-
if (!hasAnyMasterInfo) {
|
|
10513
|
-
return options;
|
|
10514
|
-
}
|
|
10515
|
-
const activeOption = options.find((o) => o.path === activeSlide.layoutPath);
|
|
10516
|
-
const activeMaster = activeOption?.masterPath;
|
|
10517
|
-
if (!activeMaster) {
|
|
10518
|
-
return options;
|
|
10519
|
-
}
|
|
10520
|
-
const scoped = options.filter((o) => o.masterPath === activeMaster);
|
|
10521
|
-
const seen = /* @__PURE__ */ new Map();
|
|
10522
|
-
for (const opt of scoped) {
|
|
10523
|
-
const isActive = opt.path === activeSlide.layoutPath;
|
|
10524
|
-
const existing = seen.get(opt.name);
|
|
10525
|
-
if (!existing || isActive) {
|
|
10526
|
-
seen.set(opt.name, opt);
|
|
10527
|
-
}
|
|
10528
|
-
}
|
|
10529
|
-
const chosen = new Set(Array.from(seen.values()).map((o) => o.path));
|
|
10530
|
-
const result = [];
|
|
10531
|
-
const usedNames = /* @__PURE__ */ new Set();
|
|
10532
|
-
for (const opt of scoped) {
|
|
10533
|
-
if (!chosen.has(opt.path)) {
|
|
10534
|
-
continue;
|
|
10535
|
-
}
|
|
10536
|
-
if (usedNames.has(opt.name)) {
|
|
10537
|
-
continue;
|
|
10538
|
-
}
|
|
10539
|
-
usedNames.add(opt.name);
|
|
10540
|
-
result.push(opt);
|
|
10541
|
-
}
|
|
10542
|
-
return result;
|
|
10717
|
+
return chunkWVDM36ZM_js.scopeLayoutOptionsToSlide(options, activeSlide?.layoutPath);
|
|
10543
10718
|
}
|
|
10544
10719
|
|
|
10545
10720
|
// src/viewer/hooks/useViewerBuildingBlocks-toolbar-handlers.ts
|
|
@@ -10552,7 +10727,7 @@ function buildToolbarAnimationHandlers(input) {
|
|
|
10552
10727
|
const current = activeSlide.animations ?? [];
|
|
10553
10728
|
if (group === "motionPath") {
|
|
10554
10729
|
propertyHandlers.handleUpdateSlide({
|
|
10555
|
-
animations:
|
|
10730
|
+
animations: chunkWVDM36ZM_js.applyMotionPathPreset(current, selectedElement.id, preset)
|
|
10556
10731
|
});
|
|
10557
10732
|
return;
|
|
10558
10733
|
}
|
|
@@ -10747,7 +10922,7 @@ function buildToolbarProps(input) {
|
|
|
10747
10922
|
onOpenFile,
|
|
10748
10923
|
onOpenRecentFile,
|
|
10749
10924
|
onCreatePresentation: (templateId) => {
|
|
10750
|
-
s.setSlides(
|
|
10925
|
+
s.setSlides(chunkWVDM36ZM_js.createBackstagePresentation(templateId));
|
|
10751
10926
|
s.setActiveSlideIndex(0);
|
|
10752
10927
|
s.setSelectedElementId(null);
|
|
10753
10928
|
s.setSelectedElementIds([]);
|
|
@@ -10772,9 +10947,11 @@ function buildToolbarProps(input) {
|
|
|
10772
10947
|
isOverflowMenuOpen: s.isOverflowMenuOpen,
|
|
10773
10948
|
onSetOverflowMenuOpen: s.setIsOverflowMenuOpen,
|
|
10774
10949
|
layoutOptions: scopedLayoutOptions,
|
|
10950
|
+
currentLayoutPath: activeSlide?.layoutPath,
|
|
10951
|
+
loadLayoutPreviews: input.loadLayoutPreviews,
|
|
10775
10952
|
onInsertSlideFromLayout: slideOps.handleInsertSlideFromLayout,
|
|
10776
10953
|
onInsertSlideFromTemplate: slideOps.handleInsertSlideFromTemplate,
|
|
10777
|
-
templateScheme:
|
|
10954
|
+
templateScheme: chunkWVDM36ZM_js.templateSchemeFromTheme(s.theme?.colorScheme),
|
|
10778
10955
|
customShows: s.customShows,
|
|
10779
10956
|
activeCustomShowId: s.activeCustomShowId,
|
|
10780
10957
|
onSetActiveCustomShowId: s.setActiveCustomShowId,
|
|
@@ -10788,6 +10965,15 @@ function buildToolbarProps(input) {
|
|
|
10788
10965
|
onToggleVersionHistory: () => propertyHandlers.setIsVersionHistoryOpen((p) => !p),
|
|
10789
10966
|
onOpenPasswordProtection: () => dialogs.setIsPasswordDialogOpen(true),
|
|
10790
10967
|
onOpenDocumentProperties: () => dialogs.setIsDocPropsDialogOpen(true),
|
|
10968
|
+
// Design > Slide Size: the size control is the inspector's SLIDE SIZE
|
|
10969
|
+
// card, which the deck (no-selection) panel renders. Drop the selection so
|
|
10970
|
+
// that panel is what the pane shows, then open it.
|
|
10971
|
+
onOpenSlideSize: () => {
|
|
10972
|
+
s.setSelectedElementId(null);
|
|
10973
|
+
s.setSelectedElementIds([]);
|
|
10974
|
+
s.setSidebarPanelMode("properties");
|
|
10975
|
+
s.setIsInspectorPaneOpen(true);
|
|
10976
|
+
},
|
|
10791
10977
|
onOpenFontEmbedding: () => dialogs.setIsFontEmbeddingOpen(true),
|
|
10792
10978
|
onOpenDigitalSignatures: () => dialogs.setIsDigitalSigDialogOpen(true),
|
|
10793
10979
|
onEnterPresenterView,
|
|
@@ -10806,7 +10992,7 @@ function buildToolbarProps(input) {
|
|
|
10806
10992
|
isCommentsPanelOpen: s.isInspectorPaneOpen,
|
|
10807
10993
|
slideCommentCount: activeSlide?.comments?.length ?? 0,
|
|
10808
10994
|
formatPainterActive: s.formatPainterActive,
|
|
10809
|
-
canActivateFormatPainter:
|
|
10995
|
+
canActivateFormatPainter: chunkWVDM36ZM_js.hasCopyableFormat(selectedElement),
|
|
10810
10996
|
onToggleFormatPainter: () => s.setFormatPainterActive((p) => !p),
|
|
10811
10997
|
isSelectionPaneOpen: s.isSelectionPaneOpen,
|
|
10812
10998
|
onToggleSelectionPane: () => s.setIsSelectionPaneOpen((p) => !p),
|
|
@@ -10823,6 +11009,20 @@ function buildToolbarProps(input) {
|
|
|
10823
11009
|
activeSlide,
|
|
10824
11010
|
onTransitionChange: handleTransitionChange,
|
|
10825
11011
|
onApplyTransitionToAll: handleApplyTransitionToAll,
|
|
11012
|
+
// No `onResetSlide` here: this building-blocks surface supplies no
|
|
11013
|
+
// `onApplyLayout` either, so there is no layout to reset to. The mounted
|
|
11014
|
+
// viewer (`ViewerToolbarSection`) wires both.
|
|
11015
|
+
onSelectAll: () => {
|
|
11016
|
+
const allIds = activeSlide?.elements.map((element) => element.id) ?? [];
|
|
11017
|
+
if (allIds.length > 0) {
|
|
11018
|
+
ops.applySelection(allIds[0], allIds);
|
|
11019
|
+
}
|
|
11020
|
+
},
|
|
11021
|
+
presentationProperties: s.presentationProperties,
|
|
11022
|
+
onPresentationPropertiesChange: (updates) => {
|
|
11023
|
+
s.setPresentationProperties((prev) => ({ ...prev, ...updates }));
|
|
11024
|
+
history.markDirty();
|
|
11025
|
+
},
|
|
10826
11026
|
hiddenActions
|
|
10827
11027
|
};
|
|
10828
11028
|
}
|
|
@@ -10900,7 +11100,12 @@ function useViewerBuildingBlocksCore(input) {
|
|
|
10900
11100
|
setMode: state.setMode,
|
|
10901
11101
|
setActiveSlideIndex: state.setActiveSlideIndex,
|
|
10902
11102
|
setSlides: state.setSlides,
|
|
10903
|
-
history
|
|
11103
|
+
history,
|
|
11104
|
+
// PowerPoint's bare `J` during a show toggles live captions.
|
|
11105
|
+
onToggleSubtitles: () => state.setPresentationProperties((prev) => ({
|
|
11106
|
+
...prev,
|
|
11107
|
+
showSubtitles: !prev.showSubtitles
|
|
11108
|
+
}))
|
|
10904
11109
|
});
|
|
10905
11110
|
return {
|
|
10906
11111
|
state,
|
|
@@ -11075,7 +11280,7 @@ function useViewerBuildingBlocks(input) {
|
|
|
11075
11280
|
}, [incomingContent]);
|
|
11076
11281
|
const onOpenFile = react.useCallback(() => {
|
|
11077
11282
|
void (async () => {
|
|
11078
|
-
const picked = await
|
|
11283
|
+
const picked = await chunkWVDM36ZM_js.openPptxFile();
|
|
11079
11284
|
if (picked) {
|
|
11080
11285
|
setContent(picked.buffer);
|
|
11081
11286
|
}
|
|
@@ -11083,7 +11288,7 @@ function useViewerBuildingBlocks(input) {
|
|
|
11083
11288
|
}, []);
|
|
11084
11289
|
const onOpenRecentFile = react.useCallback((key) => {
|
|
11085
11290
|
void (async () => {
|
|
11086
|
-
const bytes = await
|
|
11291
|
+
const bytes = await chunkWVDM36ZM_js.readBackstageRecentFile(key);
|
|
11087
11292
|
if (bytes) {
|
|
11088
11293
|
setContent(bytes);
|
|
11089
11294
|
}
|