pptx-react-viewer 1.1.4 → 1.1.6
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/dist/index.js +865 -159
- package/dist/index.mjs +866 -161
- package/dist/viewer/index.js +883 -165
- package/dist/viewer/index.mjs +884 -167
- package/node_modules/emf-converter/dist/index.d.mts +2 -2
- package/node_modules/emf-converter/dist/index.d.ts +2 -2
- package/node_modules/emf-converter/dist/index.js +91 -33
- package/node_modules/emf-converter/dist/index.mjs +91 -33
- package/node_modules/emf-converter/package.json +1 -1
- package/node_modules/mtx-decompressor/dist/index.js +39 -9
- package/node_modules/mtx-decompressor/dist/index.mjs +39 -9
- package/node_modules/mtx-decompressor/package.json +1 -1
- package/node_modules/pptx-viewer-core/dist/{SvgExporter-BQ4KbRO9.d.mts → SvgExporter-BTkk4oNQ.d.mts} +1 -1
- package/node_modules/pptx-viewer-core/dist/{SvgExporter-0TxiiorD.d.ts → SvgExporter-CTDG-t_z.d.ts} +1 -1
- package/node_modules/pptx-viewer-core/dist/cli/index.d.mts +2 -2
- package/node_modules/pptx-viewer-core/dist/cli/index.d.ts +2 -2
- package/node_modules/pptx-viewer-core/dist/cli/index.js +0 -0
- package/node_modules/pptx-viewer-core/dist/cli/index.mjs +0 -0
- package/node_modules/pptx-viewer-core/dist/converter/index.d.mts +3 -3
- package/node_modules/pptx-viewer-core/dist/converter/index.d.ts +3 -3
- package/node_modules/pptx-viewer-core/dist/converter/index.js +0 -0
- package/node_modules/pptx-viewer-core/dist/converter/index.mjs +0 -0
- package/node_modules/pptx-viewer-core/dist/index.d.mts +961 -59
- package/node_modules/pptx-viewer-core/dist/index.d.ts +961 -59
- package/node_modules/pptx-viewer-core/dist/index.js +29880 -16692
- package/node_modules/pptx-viewer-core/dist/index.mjs +29859 -16692
- package/node_modules/pptx-viewer-core/dist/{presentation-ArhfImJ5.d.mts → presentation-4fhI3din.d.mts} +835 -26
- package/node_modules/pptx-viewer-core/dist/{presentation-ArhfImJ5.d.ts → presentation-4fhI3din.d.ts} +835 -26
- package/node_modules/pptx-viewer-core/dist/{signature-inspection-status-BcJSdOvb.d.mts → signature-inspection-status-BCUpfCQh.d.mts} +13 -2
- package/node_modules/pptx-viewer-core/dist/{signature-inspection-status-BcJSdOvb.d.ts → signature-inspection-status-BCUpfCQh.d.ts} +13 -2
- package/node_modules/pptx-viewer-core/dist/signature-node/index.d.mts +2 -2
- package/node_modules/pptx-viewer-core/dist/signature-node/index.d.ts +2 -2
- package/node_modules/pptx-viewer-core/dist/signature-node/index.js +17 -3
- package/node_modules/pptx-viewer-core/dist/signature-node/index.mjs +16 -4
- package/node_modules/pptx-viewer-core/dist/{text-operations-rhJV-A_W.d.ts → text-operations-B9EwbptL.d.ts} +1 -1
- package/node_modules/pptx-viewer-core/dist/{text-operations-CLj-sJyk.d.mts → text-operations-C89Jn6S0.d.mts} +1 -1
- package/node_modules/pptx-viewer-core/package.json +1 -1
- package/package.json +6 -4
package/dist/viewer/index.mjs
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import * as React10 from 'react';
|
|
2
|
-
import React10__default, { createContext, useState, useEffect, useMemo, Suspense, useCallback, forwardRef, useRef, useSyncExternalStore, useImperativeHandle, useContext, useLayoutEffect } from 'react';
|
|
2
|
+
import React10__default, { createContext, useState, useEffect, useMemo, Suspense, useCallback, forwardRef, useRef, useSyncExternalStore, useImperativeHandle, useContext, useLayoutEffect, useDeferredValue } from 'react';
|
|
3
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
4
4
|
import * as ReactDOM from 'react-dom/client';
|
|
5
5
|
import { clsx } from 'clsx';
|
|
6
6
|
import { twMerge } from 'tailwind-merge';
|
|
7
7
|
import { LuMessageSquare, LuEyeOff, LuSettings, LuX, LuCast, LuShieldCheck, LuPlus, LuPanelLeftClose, LuStickyNote, LuMonitor, LuColumns2, LuPresentation, LuMinus, LuClock, LuDownload, LuTrash2, LuCheck, LuLock, LuEye, LuFileText, LuType, LuLoader, LuShieldAlert, LuSignature, LuInfo, LuTriangleAlert, LuPrinter, LuPenTool, LuWifi, LuWifiOff, LuUsers, LuCopy, LuMonitorOff, LuChevronLeft, LuChevronRight, LuPlay, LuPause, LuPanelLeft, LuUndo, LuRedo, LuSearch, LuShare2, LuPanelRight, LuFolderOpen, LuVideo, LuImage, LuClipboardPaste, LuScissors, LuPaintbrush, LuChevronDown, LuSquare, LuDatabase, LuLayers, LuAArrowUp, LuAArrowDown, LuRemoveFormatting, LuHighlighter, LuList, LuListOrdered, LuIndentDecrease, LuIndentIncrease, LuChevronUp, LuPalette, LuPencil, LuPaintBucket, LuSparkles, LuCaptions, LuSpellCheck, LuGitCompare, LuPipette, LuCaseSensitive, LuReplace, LuTimer, LuMousePointer2, LuEraser, LuGripVertical, LuUpload, LuBold, LuItalic, LuUnderline, LuStrikethrough, LuLink, LuGrid2X2, LuCopyPlus, LuEllipsis, LuCircle, LuMoveRight, LuTriangle, LuDiamond, LuAlignLeft, LuAlignCenter, LuAlignRight, LuAlignJustify, LuSpline, LuSettings2, LuMove, LuRadio, LuArrowDown, LuArrowUp, LuArrowRight, LuArrowLeft, LuReply, LuRotateCw, LuBookmark } from 'react-icons/lu';
|
|
8
|
-
import { hasShapeProperties, hasTextProperties, SWITCHABLE_LAYOUT_TYPES, isCalloutShape, getCalloutLeaderLineGeometry, buildCalloutLeaderLineSvgPath, getCalloutViewBoxBounds, isInkElement, getLinkedTextBoxSegments, isImageLikeElement, getSubstituteFontFamily, PptxHandler, EncryptedFileError, guidePxToEmu, guideEmuToPx, THEME_COLOR_SCHEME_KEYS, hslToRgb, PRESET_COLOR_MAP, elementActionToPptxAction, mergeShapes, SvgExporter, applyDrawingColorTransforms as applyDrawingColorTransforms$1, getPresetShapeClipPath, svgPathToPolygons, polygonsToSvgPath, EMU_PER_PX as EMU_PER_PX$1, chartDataChangeType, chartDataUpdatePoint, chartDataAddCategory, chartDataRemoveCategory, chartDataAddSeries, chartDataRemoveSeries, getOleObjectTypeLabel, pptxActionToElementAction, hasNonTrivialOverride, COLOR_MAP_ALIAS_KEYS, DEFAULT_COLOR_MAP, addSmartArtNodeAsChild, updateSmartArtNodeText, removeSmartArtNode, switchSmartArtLayout, applyThemeToData, THEME_PRESETS } from 'pptx-viewer-core';
|
|
8
|
+
import { hasShapeProperties, hasTextProperties, SWITCHABLE_LAYOUT_TYPES, isCalloutShape, getCalloutLeaderLineGeometry, buildCalloutLeaderLineSvgPath, getCalloutViewBoxBounds, isInkElement, getLinkedTextBoxSegments, isImageLikeElement, getSubstituteFontFamily, getAdjustmentAwareShapeClipPath, getShapeClipPathFromPreset, getCloudPathForRendering, PptxHandler, EncryptedFileError, guidePxToEmu, guideEmuToPx, THEME_COLOR_SCHEME_KEYS, hslToRgb, PRESET_COLOR_MAP, elementActionToPptxAction, mergeShapes, SvgExporter, applyDrawingColorTransforms as applyDrawingColorTransforms$1, getPresetShapeClipPath, svgPathToPolygons, polygonsToSvgPath, EMU_PER_PX as EMU_PER_PX$1, chartDataChangeType, chartDataUpdatePoint, chartDataAddCategory, chartDataRemoveCategory, chartDataAddSeries, chartDataRemoveSeries, getOleObjectTypeLabel, pptxActionToElementAction, hasNonTrivialOverride, COLOR_MAP_ALIAS_KEYS, DEFAULT_COLOR_MAP, addSmartArtNodeAsChild, updateSmartArtNodeText, removeSmartArtNode, switchSmartArtLayout, applyThemeToData, THEME_PRESETS } from 'pptx-viewer-core';
|
|
9
|
+
import DOMPurify from 'dompurify';
|
|
9
10
|
import { useTranslation } from 'react-i18next';
|
|
10
11
|
import html2canvasPro from 'html2canvas-pro';
|
|
11
12
|
import JSZip from 'jszip';
|
|
@@ -170,7 +171,7 @@ function generateUUID() {
|
|
|
170
171
|
const uuid = _lut[d0 & 255] + _lut[d0 >> 8 & 255] + _lut[d0 >> 16 & 255] + _lut[d0 >> 24 & 255] + "-" + _lut[d1 & 255] + _lut[d1 >> 8 & 255] + "-" + _lut[d1 >> 16 & 15 | 64] + _lut[d1 >> 24 & 255] + "-" + _lut[d2 & 63 | 128] + _lut[d2 >> 8 & 255] + "-" + _lut[d2 >> 16 & 255] + _lut[d2 >> 24 & 255] + _lut[d3 & 255] + _lut[d3 >> 8 & 255] + _lut[d3 >> 16 & 255] + _lut[d3 >> 24 & 255];
|
|
171
172
|
return uuid.toLowerCase();
|
|
172
173
|
}
|
|
173
|
-
function
|
|
174
|
+
function clamp2(value, min2, max2) {
|
|
174
175
|
return Math.max(min2, Math.min(max2, value));
|
|
175
176
|
}
|
|
176
177
|
function euclideanModulo(n, m2) {
|
|
@@ -545,7 +546,7 @@ function _generateTables() {
|
|
|
545
546
|
}
|
|
546
547
|
function toHalfFloat(val2) {
|
|
547
548
|
if (Math.abs(val2) > 65504) warn("DataUtils.toHalfFloat(): Value out of range.");
|
|
548
|
-
val2 =
|
|
549
|
+
val2 = clamp2(val2, -65504, 65504);
|
|
549
550
|
_tables.floatView[0] = val2;
|
|
550
551
|
const f = _tables.uint32View[0];
|
|
551
552
|
const e2 = f >> 23 & 511;
|
|
@@ -2034,7 +2035,7 @@ var init_three_core = __esm({
|
|
|
2034
2035
|
* @param {number} max - The max value.
|
|
2035
2036
|
* @return {number} The clamped value.
|
|
2036
2037
|
*/
|
|
2037
|
-
clamp,
|
|
2038
|
+
clamp: clamp2,
|
|
2038
2039
|
/**
|
|
2039
2040
|
* Computes the Euclidean modulo of the given parameters that
|
|
2040
2041
|
* is `( ( n % m ) + m ) % m`.
|
|
@@ -2561,8 +2562,8 @@ var init_three_core = __esm({
|
|
|
2561
2562
|
* @return {Vector2} A reference to this vector.
|
|
2562
2563
|
*/
|
|
2563
2564
|
clamp(min2, max2) {
|
|
2564
|
-
this.x =
|
|
2565
|
-
this.y =
|
|
2565
|
+
this.x = clamp2(this.x, min2.x, max2.x);
|
|
2566
|
+
this.y = clamp2(this.y, min2.y, max2.y);
|
|
2566
2567
|
return this;
|
|
2567
2568
|
}
|
|
2568
2569
|
/**
|
|
@@ -2576,8 +2577,8 @@ var init_three_core = __esm({
|
|
|
2576
2577
|
* @return {Vector2} A reference to this vector.
|
|
2577
2578
|
*/
|
|
2578
2579
|
clampScalar(minVal, maxVal) {
|
|
2579
|
-
this.x =
|
|
2580
|
-
this.y =
|
|
2580
|
+
this.x = clamp2(this.x, minVal, maxVal);
|
|
2581
|
+
this.y = clamp2(this.y, minVal, maxVal);
|
|
2581
2582
|
return this;
|
|
2582
2583
|
}
|
|
2583
2584
|
/**
|
|
@@ -2592,7 +2593,7 @@ var init_three_core = __esm({
|
|
|
2592
2593
|
*/
|
|
2593
2594
|
clampLength(min2, max2) {
|
|
2594
2595
|
const length2 = this.length();
|
|
2595
|
-
return this.divideScalar(length2 || 1).multiplyScalar(
|
|
2596
|
+
return this.divideScalar(length2 || 1).multiplyScalar(clamp2(length2, min2, max2));
|
|
2596
2597
|
}
|
|
2597
2598
|
/**
|
|
2598
2599
|
* The components of this vector are rounded down to the nearest integer value.
|
|
@@ -2717,7 +2718,7 @@ var init_three_core = __esm({
|
|
|
2717
2718
|
const denominator = Math.sqrt(this.lengthSq() * v.lengthSq());
|
|
2718
2719
|
if (denominator === 0) return Math.PI / 2;
|
|
2719
2720
|
const theta = this.dot(v) / denominator;
|
|
2720
|
-
return Math.acos(
|
|
2721
|
+
return Math.acos(clamp2(theta, -1, 1));
|
|
2721
2722
|
}
|
|
2722
2723
|
/**
|
|
2723
2724
|
* Computes the distance from the given vector to this instance.
|
|
@@ -3204,7 +3205,7 @@ var init_three_core = __esm({
|
|
|
3204
3205
|
* @return {number} The angle in radians.
|
|
3205
3206
|
*/
|
|
3206
3207
|
angleTo(q) {
|
|
3207
|
-
return 2 * Math.acos(Math.abs(
|
|
3208
|
+
return 2 * Math.acos(Math.abs(clamp2(this.dot(q), -1, 1)));
|
|
3208
3209
|
}
|
|
3209
3210
|
/**
|
|
3210
3211
|
* Rotates this quaternion by a given angular step to the given quaternion.
|
|
@@ -3910,9 +3911,9 @@ var init_three_core = __esm({
|
|
|
3910
3911
|
* @return {Vector3} A reference to this vector.
|
|
3911
3912
|
*/
|
|
3912
3913
|
clamp(min2, max2) {
|
|
3913
|
-
this.x =
|
|
3914
|
-
this.y =
|
|
3915
|
-
this.z =
|
|
3914
|
+
this.x = clamp2(this.x, min2.x, max2.x);
|
|
3915
|
+
this.y = clamp2(this.y, min2.y, max2.y);
|
|
3916
|
+
this.z = clamp2(this.z, min2.z, max2.z);
|
|
3916
3917
|
return this;
|
|
3917
3918
|
}
|
|
3918
3919
|
/**
|
|
@@ -3926,9 +3927,9 @@ var init_three_core = __esm({
|
|
|
3926
3927
|
* @return {Vector3} A reference to this vector.
|
|
3927
3928
|
*/
|
|
3928
3929
|
clampScalar(minVal, maxVal) {
|
|
3929
|
-
this.x =
|
|
3930
|
-
this.y =
|
|
3931
|
-
this.z =
|
|
3930
|
+
this.x = clamp2(this.x, minVal, maxVal);
|
|
3931
|
+
this.y = clamp2(this.y, minVal, maxVal);
|
|
3932
|
+
this.z = clamp2(this.z, minVal, maxVal);
|
|
3932
3933
|
return this;
|
|
3933
3934
|
}
|
|
3934
3935
|
/**
|
|
@@ -3943,7 +3944,7 @@ var init_three_core = __esm({
|
|
|
3943
3944
|
*/
|
|
3944
3945
|
clampLength(min2, max2) {
|
|
3945
3946
|
const length2 = this.length();
|
|
3946
|
-
return this.divideScalar(length2 || 1).multiplyScalar(
|
|
3947
|
+
return this.divideScalar(length2 || 1).multiplyScalar(clamp2(length2, min2, max2));
|
|
3947
3948
|
}
|
|
3948
3949
|
/**
|
|
3949
3950
|
* The components of this vector are rounded down to the nearest integer value.
|
|
@@ -4153,7 +4154,7 @@ var init_three_core = __esm({
|
|
|
4153
4154
|
const denominator = Math.sqrt(this.lengthSq() * v.lengthSq());
|
|
4154
4155
|
if (denominator === 0) return Math.PI / 2;
|
|
4155
4156
|
const theta = this.dot(v) / denominator;
|
|
4156
|
-
return Math.acos(
|
|
4157
|
+
return Math.acos(clamp2(theta, -1, 1));
|
|
4157
4158
|
}
|
|
4158
4159
|
/**
|
|
4159
4160
|
* Computes the distance from the given vector to this instance.
|
|
@@ -5842,10 +5843,10 @@ var init_three_core = __esm({
|
|
|
5842
5843
|
* @return {Vector4} A reference to this vector.
|
|
5843
5844
|
*/
|
|
5844
5845
|
clamp(min2, max2) {
|
|
5845
|
-
this.x =
|
|
5846
|
-
this.y =
|
|
5847
|
-
this.z =
|
|
5848
|
-
this.w =
|
|
5846
|
+
this.x = clamp2(this.x, min2.x, max2.x);
|
|
5847
|
+
this.y = clamp2(this.y, min2.y, max2.y);
|
|
5848
|
+
this.z = clamp2(this.z, min2.z, max2.z);
|
|
5849
|
+
this.w = clamp2(this.w, min2.w, max2.w);
|
|
5849
5850
|
return this;
|
|
5850
5851
|
}
|
|
5851
5852
|
/**
|
|
@@ -5859,10 +5860,10 @@ var init_three_core = __esm({
|
|
|
5859
5860
|
* @return {Vector4} A reference to this vector.
|
|
5860
5861
|
*/
|
|
5861
5862
|
clampScalar(minVal, maxVal) {
|
|
5862
|
-
this.x =
|
|
5863
|
-
this.y =
|
|
5864
|
-
this.z =
|
|
5865
|
-
this.w =
|
|
5863
|
+
this.x = clamp2(this.x, minVal, maxVal);
|
|
5864
|
+
this.y = clamp2(this.y, minVal, maxVal);
|
|
5865
|
+
this.z = clamp2(this.z, minVal, maxVal);
|
|
5866
|
+
this.w = clamp2(this.w, minVal, maxVal);
|
|
5866
5867
|
return this;
|
|
5867
5868
|
}
|
|
5868
5869
|
/**
|
|
@@ -5877,7 +5878,7 @@ var init_three_core = __esm({
|
|
|
5877
5878
|
*/
|
|
5878
5879
|
clampLength(min2, max2) {
|
|
5879
5880
|
const length2 = this.length();
|
|
5880
|
-
return this.divideScalar(length2 || 1).multiplyScalar(
|
|
5881
|
+
return this.divideScalar(length2 || 1).multiplyScalar(clamp2(length2, min2, max2));
|
|
5881
5882
|
}
|
|
5882
5883
|
/**
|
|
5883
5884
|
* The components of this vector are rounded down to the nearest integer value.
|
|
@@ -7660,7 +7661,7 @@ var init_three_core = __esm({
|
|
|
7660
7661
|
const m31 = te[2], m32 = te[6], m33 = te[10];
|
|
7661
7662
|
switch (order) {
|
|
7662
7663
|
case "XYZ":
|
|
7663
|
-
this._y = Math.asin(
|
|
7664
|
+
this._y = Math.asin(clamp2(m13, -1, 1));
|
|
7664
7665
|
if (Math.abs(m13) < 0.9999999) {
|
|
7665
7666
|
this._x = Math.atan2(-m23, m33);
|
|
7666
7667
|
this._z = Math.atan2(-m12, m11);
|
|
@@ -7670,7 +7671,7 @@ var init_three_core = __esm({
|
|
|
7670
7671
|
}
|
|
7671
7672
|
break;
|
|
7672
7673
|
case "YXZ":
|
|
7673
|
-
this._x = Math.asin(-
|
|
7674
|
+
this._x = Math.asin(-clamp2(m23, -1, 1));
|
|
7674
7675
|
if (Math.abs(m23) < 0.9999999) {
|
|
7675
7676
|
this._y = Math.atan2(m13, m33);
|
|
7676
7677
|
this._z = Math.atan2(m21, m22);
|
|
@@ -7680,7 +7681,7 @@ var init_three_core = __esm({
|
|
|
7680
7681
|
}
|
|
7681
7682
|
break;
|
|
7682
7683
|
case "ZXY":
|
|
7683
|
-
this._x = Math.asin(
|
|
7684
|
+
this._x = Math.asin(clamp2(m32, -1, 1));
|
|
7684
7685
|
if (Math.abs(m32) < 0.9999999) {
|
|
7685
7686
|
this._y = Math.atan2(-m31, m33);
|
|
7686
7687
|
this._z = Math.atan2(-m12, m22);
|
|
@@ -7690,7 +7691,7 @@ var init_three_core = __esm({
|
|
|
7690
7691
|
}
|
|
7691
7692
|
break;
|
|
7692
7693
|
case "ZYX":
|
|
7693
|
-
this._y = Math.asin(-
|
|
7694
|
+
this._y = Math.asin(-clamp2(m31, -1, 1));
|
|
7694
7695
|
if (Math.abs(m31) < 0.9999999) {
|
|
7695
7696
|
this._x = Math.atan2(m32, m33);
|
|
7696
7697
|
this._z = Math.atan2(m21, m11);
|
|
@@ -7700,7 +7701,7 @@ var init_three_core = __esm({
|
|
|
7700
7701
|
}
|
|
7701
7702
|
break;
|
|
7702
7703
|
case "YZX":
|
|
7703
|
-
this._z = Math.asin(
|
|
7704
|
+
this._z = Math.asin(clamp2(m21, -1, 1));
|
|
7704
7705
|
if (Math.abs(m21) < 0.9999999) {
|
|
7705
7706
|
this._x = Math.atan2(-m23, m22);
|
|
7706
7707
|
this._y = Math.atan2(-m31, m11);
|
|
@@ -7710,7 +7711,7 @@ var init_three_core = __esm({
|
|
|
7710
7711
|
}
|
|
7711
7712
|
break;
|
|
7712
7713
|
case "XZY":
|
|
7713
|
-
this._z = Math.asin(-
|
|
7714
|
+
this._z = Math.asin(-clamp2(m12, -1, 1));
|
|
7714
7715
|
if (Math.abs(m12) < 0.9999999) {
|
|
7715
7716
|
this._x = Math.atan2(m32, m22);
|
|
7716
7717
|
this._y = Math.atan2(m13, m11);
|
|
@@ -9334,8 +9335,8 @@ var init_three_core = __esm({
|
|
|
9334
9335
|
*/
|
|
9335
9336
|
setHSL(h2, s, l2, colorSpace = ColorManagement.workingColorSpace) {
|
|
9336
9337
|
h2 = euclideanModulo(h2, 1);
|
|
9337
|
-
s =
|
|
9338
|
-
l2 =
|
|
9338
|
+
s = clamp2(s, 0, 1);
|
|
9339
|
+
l2 = clamp2(l2, 0, 1);
|
|
9339
9340
|
if (s === 0) {
|
|
9340
9341
|
this.r = this.g = this.b = l2;
|
|
9341
9342
|
} else {
|
|
@@ -9521,7 +9522,7 @@ var init_three_core = __esm({
|
|
|
9521
9522
|
*/
|
|
9522
9523
|
getHex(colorSpace = SRGBColorSpace) {
|
|
9523
9524
|
ColorManagement.workingToColorSpace(_color.copy(this), colorSpace);
|
|
9524
|
-
return Math.round(
|
|
9525
|
+
return Math.round(clamp2(_color.r * 255, 0, 255)) * 65536 + Math.round(clamp2(_color.g * 255, 0, 255)) * 256 + Math.round(clamp2(_color.b * 255, 0, 255));
|
|
9525
9526
|
}
|
|
9526
9527
|
/**
|
|
9527
9528
|
* Returns the hexadecimal value of this color as a string (for example, 'FFFFFF').
|
|
@@ -18452,13 +18453,13 @@ var init_three_core = __esm({
|
|
|
18452
18453
|
vec.crossVectors(tangents[i3 - 1], tangents[i3]);
|
|
18453
18454
|
if (vec.length() > Number.EPSILON) {
|
|
18454
18455
|
vec.normalize();
|
|
18455
|
-
const theta = Math.acos(
|
|
18456
|
+
const theta = Math.acos(clamp2(tangents[i3 - 1].dot(tangents[i3]), -1, 1));
|
|
18456
18457
|
normals[i3].applyMatrix4(mat.makeRotationAxis(vec, theta));
|
|
18457
18458
|
}
|
|
18458
18459
|
binormals[i3].crossVectors(tangents[i3], normals[i3]);
|
|
18459
18460
|
}
|
|
18460
18461
|
if (closed === true) {
|
|
18461
|
-
let theta = Math.acos(
|
|
18462
|
+
let theta = Math.acos(clamp2(normals[0].dot(normals[segments]), -1, 1));
|
|
18462
18463
|
theta /= segments;
|
|
18463
18464
|
if (tangents[0].dot(vec.crossVectors(normals[0], normals[segments])) > 0) {
|
|
18464
18465
|
theta = -theta;
|
|
@@ -20247,7 +20248,7 @@ var init_three_core = __esm({
|
|
|
20247
20248
|
phiLength
|
|
20248
20249
|
};
|
|
20249
20250
|
segments = Math.floor(segments);
|
|
20250
|
-
phiLength =
|
|
20251
|
+
phiLength = clamp2(phiLength, 0, Math.PI * 2);
|
|
20251
20252
|
const indices = [];
|
|
20252
20253
|
const vertices = [];
|
|
20253
20254
|
const uvs = [];
|
|
@@ -21463,7 +21464,7 @@ var init_three_core = __esm({
|
|
|
21463
21464
|
this.ior = 1.5;
|
|
21464
21465
|
Object.defineProperty(this, "reflectivity", {
|
|
21465
21466
|
get: function() {
|
|
21466
|
-
return
|
|
21467
|
+
return clamp2(2.5 * (this.ior - 1) / (this.ior + 1), 0, 1);
|
|
21467
21468
|
},
|
|
21468
21469
|
set: function(reflectivity) {
|
|
21469
21470
|
this.ior = (1 + 0.4 * reflectivity) / (1 - 0.4 * reflectivity);
|
|
@@ -29731,7 +29732,7 @@ var init_three_core = __esm({
|
|
|
29731
29732
|
*/
|
|
29732
29733
|
makeSafe() {
|
|
29733
29734
|
const EPS = 1e-6;
|
|
29734
|
-
this.phi =
|
|
29735
|
+
this.phi = clamp2(this.phi, EPS, Math.PI - EPS);
|
|
29735
29736
|
return this;
|
|
29736
29737
|
}
|
|
29737
29738
|
/**
|
|
@@ -29759,7 +29760,7 @@ var init_three_core = __esm({
|
|
|
29759
29760
|
this.phi = 0;
|
|
29760
29761
|
} else {
|
|
29761
29762
|
this.theta = Math.atan2(x2, z);
|
|
29762
|
-
this.phi = Math.acos(
|
|
29763
|
+
this.phi = Math.acos(clamp2(y / this.radius, -1, 1));
|
|
29763
29764
|
}
|
|
29764
29765
|
return this;
|
|
29765
29766
|
}
|
|
@@ -30274,7 +30275,7 @@ var init_three_core = __esm({
|
|
|
30274
30275
|
const startEnd_startP = _startEnd.dot(_startP);
|
|
30275
30276
|
let t2 = startEnd_startP / startEnd2;
|
|
30276
30277
|
if (clampToLine) {
|
|
30277
|
-
t2 =
|
|
30278
|
+
t2 = clamp2(t2, 0, 1);
|
|
30278
30279
|
}
|
|
30279
30280
|
return t2;
|
|
30280
30281
|
}
|
|
@@ -30320,27 +30321,27 @@ var init_three_core = __esm({
|
|
|
30320
30321
|
if (a2 <= EPSILON) {
|
|
30321
30322
|
s = 0;
|
|
30322
30323
|
t2 = f / e2;
|
|
30323
|
-
t2 =
|
|
30324
|
+
t2 = clamp2(t2, 0, 1);
|
|
30324
30325
|
} else {
|
|
30325
30326
|
const c3 = _d1.dot(_r);
|
|
30326
30327
|
if (e2 <= EPSILON) {
|
|
30327
30328
|
t2 = 0;
|
|
30328
|
-
s =
|
|
30329
|
+
s = clamp2(-c3 / a2, 0, 1);
|
|
30329
30330
|
} else {
|
|
30330
30331
|
const b2 = _d1.dot(_d2);
|
|
30331
30332
|
const denom = a2 * e2 - b2 * b2;
|
|
30332
30333
|
if (denom !== 0) {
|
|
30333
|
-
s =
|
|
30334
|
+
s = clamp2((b2 * f - c3 * e2) / denom, 0, 1);
|
|
30334
30335
|
} else {
|
|
30335
30336
|
s = 0;
|
|
30336
30337
|
}
|
|
30337
30338
|
t2 = (b2 * s + f) / e2;
|
|
30338
30339
|
if (t2 < 0) {
|
|
30339
30340
|
t2 = 0;
|
|
30340
|
-
s =
|
|
30341
|
+
s = clamp2(-c3 / a2, 0, 1);
|
|
30341
30342
|
} else if (t2 > 1) {
|
|
30342
30343
|
t2 = 1;
|
|
30343
|
-
s =
|
|
30344
|
+
s = clamp2((b2 - c3) / a2, 0, 1);
|
|
30344
30345
|
}
|
|
30345
30346
|
}
|
|
30346
30347
|
}
|
|
@@ -43570,7 +43571,7 @@ var require_use_sync_external_store_shim_development = __commonJS({
|
|
|
43570
43571
|
return x2 === y && (0 !== x2 || 1 / x2 === 1 / y) || x2 !== x2 && y !== y;
|
|
43571
43572
|
}
|
|
43572
43573
|
function useSyncExternalStore$2(subscribe3, getSnapshot2) {
|
|
43573
|
-
didWarnOld18Alpha || void 0 ===
|
|
43574
|
+
didWarnOld18Alpha || void 0 === React100.startTransition || (didWarnOld18Alpha = true, console.error(
|
|
43574
43575
|
"You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release."
|
|
43575
43576
|
));
|
|
43576
43577
|
var value = getSnapshot2();
|
|
@@ -43580,7 +43581,7 @@ var require_use_sync_external_store_shim_development = __commonJS({
|
|
|
43580
43581
|
"The result of getSnapshot should be cached to avoid an infinite loop"
|
|
43581
43582
|
), didWarnUncachedGetSnapshot = true);
|
|
43582
43583
|
}
|
|
43583
|
-
cachedValue =
|
|
43584
|
+
cachedValue = useState86({
|
|
43584
43585
|
inst: { value, getSnapshot: getSnapshot2 }
|
|
43585
43586
|
});
|
|
43586
43587
|
var inst = cachedValue[0].inst, forceUpdate = cachedValue[1];
|
|
@@ -43618,8 +43619,8 @@ var require_use_sync_external_store_shim_development = __commonJS({
|
|
|
43618
43619
|
return getSnapshot2();
|
|
43619
43620
|
}
|
|
43620
43621
|
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
|
|
43621
|
-
var
|
|
43622
|
-
exports$1.useSyncExternalStore = void 0 !==
|
|
43622
|
+
var React100 = __require("react"), objectIs = "function" === typeof Object.is ? Object.is : is2, useState86 = React100.useState, useEffect72 = React100.useEffect, useLayoutEffect7 = React100.useLayoutEffect, useDebugValue = React100.useDebugValue, didWarnOld18Alpha = false, didWarnUncachedGetSnapshot = false, shim = "undefined" === typeof window || "undefined" === typeof window.document || "undefined" === typeof window.document.createElement ? useSyncExternalStore$1 : useSyncExternalStore$2;
|
|
43623
|
+
exports$1.useSyncExternalStore = void 0 !== React100.useSyncExternalStore ? React100.useSyncExternalStore : shim;
|
|
43623
43624
|
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
|
|
43624
43625
|
})();
|
|
43625
43626
|
}
|
|
@@ -43642,7 +43643,7 @@ var require_with_selector_development = __commonJS({
|
|
|
43642
43643
|
return x2 === y && (0 !== x2 || 1 / x2 === 1 / y) || x2 !== x2 && y !== y;
|
|
43643
43644
|
}
|
|
43644
43645
|
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
|
|
43645
|
-
var
|
|
43646
|
+
var React100 = __require("react"), shim = require_shim(), objectIs = "function" === typeof Object.is ? Object.is : is2, useSyncExternalStore3 = shim.useSyncExternalStore, useRef73 = React100.useRef, useEffect72 = React100.useEffect, useMemo42 = React100.useMemo, useDebugValue = React100.useDebugValue;
|
|
43646
43647
|
exports$1.useSyncExternalStoreWithSelector = function(subscribe3, getSnapshot2, getServerSnapshot2, selector, isEqual) {
|
|
43647
43648
|
var instRef = useRef73(null);
|
|
43648
43649
|
if (null === instRef.current) {
|
|
@@ -70279,6 +70280,55 @@ var ACTION_BUTTON_PRESETS = [
|
|
|
70279
70280
|
label: "Return",
|
|
70280
70281
|
defaultAction: "prevSlide",
|
|
70281
70282
|
iconPath: "M18 8 L18 14 L6 14 M6 14 L10 10 M6 14 L10 18"
|
|
70283
|
+
},
|
|
70284
|
+
{
|
|
70285
|
+
shapeType: "actionButtonHome",
|
|
70286
|
+
label: "Home",
|
|
70287
|
+
defaultAction: "firstSlide",
|
|
70288
|
+
// House: roof + body
|
|
70289
|
+
iconPath: "M12 4 L20 11 L20 20 L14 20 L14 14 L10 14 L10 20 L4 20 L4 11 Z"
|
|
70290
|
+
},
|
|
70291
|
+
{
|
|
70292
|
+
shapeType: "actionButtonHelp",
|
|
70293
|
+
label: "Help",
|
|
70294
|
+
defaultAction: "none",
|
|
70295
|
+
// Question mark
|
|
70296
|
+
iconPath: "M9 9 a3 3 0 1 1 4 2.8 c-1 0.4 -1 1.2 -1 2 M12 17 v0.5"
|
|
70297
|
+
},
|
|
70298
|
+
{
|
|
70299
|
+
shapeType: "actionButtonInformation",
|
|
70300
|
+
label: "Information",
|
|
70301
|
+
defaultAction: "none",
|
|
70302
|
+
// Lower-case "i": dot + body
|
|
70303
|
+
iconPath: "M12 6 v0.01 M12 10 v8"
|
|
70304
|
+
},
|
|
70305
|
+
{
|
|
70306
|
+
shapeType: "actionButtonDocument",
|
|
70307
|
+
label: "Document",
|
|
70308
|
+
defaultAction: "none",
|
|
70309
|
+
// Document with folded corner
|
|
70310
|
+
iconPath: "M6 4 L14 4 L18 8 L18 20 L6 20 Z M14 4 L14 8 L18 8"
|
|
70311
|
+
},
|
|
70312
|
+
{
|
|
70313
|
+
shapeType: "actionButtonSound",
|
|
70314
|
+
label: "Sound",
|
|
70315
|
+
defaultAction: "none",
|
|
70316
|
+
// Speaker cone + sound waves
|
|
70317
|
+
iconPath: "M4 10 L4 14 L8 14 L12 18 L12 6 L8 10 Z M16 9 a4 4 0 0 1 0 6 M18 7 a7 7 0 0 1 0 10"
|
|
70318
|
+
},
|
|
70319
|
+
{
|
|
70320
|
+
shapeType: "actionButtonMovie",
|
|
70321
|
+
label: "Movie",
|
|
70322
|
+
defaultAction: "none",
|
|
70323
|
+
// Film strip with play triangle
|
|
70324
|
+
iconPath: "M4 6 L20 6 L20 18 L4 18 Z M10 9 L15 12 L10 15 Z"
|
|
70325
|
+
},
|
|
70326
|
+
{
|
|
70327
|
+
shapeType: "actionButtonBlank",
|
|
70328
|
+
label: "Custom",
|
|
70329
|
+
defaultAction: "none",
|
|
70330
|
+
// No glyph — empty path. The button still renders as a rounded rect via clip-path.
|
|
70331
|
+
iconPath: ""
|
|
70282
70332
|
}
|
|
70283
70333
|
];
|
|
70284
70334
|
Object.fromEntries(ACTION_BUTTON_PRESETS.map((p3) => [p3.shapeType, p3.defaultAction]));
|
|
@@ -72558,8 +72608,8 @@ function hexToRgb2(hex) {
|
|
|
72558
72608
|
};
|
|
72559
72609
|
}
|
|
72560
72610
|
function rgbToHex(r2, g2, b2) {
|
|
72561
|
-
const
|
|
72562
|
-
return `#${
|
|
72611
|
+
const clamp3 = (v) => Math.max(0, Math.min(255, Math.round(v)));
|
|
72612
|
+
return `#${clamp3(r2).toString(16).padStart(2, "0")}${clamp3(g2).toString(16).padStart(2, "0")}${clamp3(b2).toString(16).padStart(2, "0")}`;
|
|
72563
72613
|
}
|
|
72564
72614
|
function rgbToHsl(r2, g2, b2) {
|
|
72565
72615
|
const rn = r2 / 255;
|
|
@@ -74063,6 +74113,13 @@ function hasDistinctScriptFonts(fonts) {
|
|
|
74063
74113
|
}
|
|
74064
74114
|
return Boolean(fonts.eastAsia) && fonts.eastAsia !== base || Boolean(fonts.complexScript) && fonts.complexScript !== base || Boolean(fonts.symbol) && fonts.symbol !== base;
|
|
74065
74115
|
}
|
|
74116
|
+
function sanitizeMathMl(markup) {
|
|
74117
|
+
const purify = DOMPurify;
|
|
74118
|
+
if (typeof purify.sanitize !== "function") {
|
|
74119
|
+
return markup;
|
|
74120
|
+
}
|
|
74121
|
+
return purify.sanitize(markup, { USE_PROFILES: { mathMl: true, svg: true } });
|
|
74122
|
+
}
|
|
74066
74123
|
function renderScriptAwareText(text2, needsScriptFonts, scriptFonts, baseFontFamily, keyPrefix) {
|
|
74067
74124
|
if (!needsScriptFonts || !text2) {
|
|
74068
74125
|
return text2;
|
|
@@ -74153,14 +74210,15 @@ function renderSegmentContent(elementId, segmentIndex, textValue, lines, needsSc
|
|
|
74153
74210
|
}
|
|
74154
74211
|
function renderEquationSegment(elementId, segmentIndex, equationXml, equationNumber) {
|
|
74155
74212
|
const mathml = convertOmmlToMathMl(equationXml);
|
|
74156
|
-
const
|
|
74213
|
+
const safeMathml = mathml ? sanitizeMathMl(mathml) : "";
|
|
74214
|
+
const equationContent = safeMathml ? /* @__PURE__ */ jsx(
|
|
74157
74215
|
"span",
|
|
74158
74216
|
{
|
|
74159
74217
|
className: "inline-block align-middle",
|
|
74160
74218
|
style: {
|
|
74161
74219
|
fontFamily: '"Cambria Math", "STIX Two Math", serif'
|
|
74162
74220
|
},
|
|
74163
|
-
dangerouslySetInnerHTML: { __html:
|
|
74221
|
+
dangerouslySetInnerHTML: { __html: safeMathml }
|
|
74164
74222
|
}
|
|
74165
74223
|
) : /* @__PURE__ */ jsx("span", { className: "inline-block px-1 py-0.5 rounded text-xs bg-gray-200/20 text-gray-400 italic", children: "Equation" });
|
|
74166
74224
|
if (equationNumber) {
|
|
@@ -74761,6 +74819,11 @@ function getShapeClipPath(shapeType, adjustments, width, height) {
|
|
|
74761
74819
|
}
|
|
74762
74820
|
const normalized = shapeType.toLowerCase();
|
|
74763
74821
|
if (normalized === "round1rect" || normalized === "round2samerect" || normalized === "round2diagrect" || normalized === "sniproundrect" || normalized === "snip1rect" || normalized === "snip2diagrect") {
|
|
74822
|
+
if (adjustments?.adj !== void 0 && width && height) {
|
|
74823
|
+
const ratio = Math.min(Math.max(adjustments.adj / 1e5, 0), 0.5);
|
|
74824
|
+
const radiusPx = Math.round(Math.min(width, height) * ratio);
|
|
74825
|
+
return `inset(0 round ${radiusPx}px)`;
|
|
74826
|
+
}
|
|
74764
74827
|
return "inset(0 round 18px)";
|
|
74765
74828
|
}
|
|
74766
74829
|
if (normalized === "can" || normalized === "cylinder") {
|
|
@@ -75407,6 +75470,128 @@ function mapDagBlendModeToCss(blend) {
|
|
|
75407
75470
|
return void 0;
|
|
75408
75471
|
}
|
|
75409
75472
|
}
|
|
75473
|
+
function getImageAlphaFilterId(elementId) {
|
|
75474
|
+
return `imgalpha-${elementId}`;
|
|
75475
|
+
}
|
|
75476
|
+
function hasAdvancedImageAlphaEffects(element2) {
|
|
75477
|
+
if (!isImageLikeElement(element2)) {
|
|
75478
|
+
return false;
|
|
75479
|
+
}
|
|
75480
|
+
const e2 = element2.imageEffects;
|
|
75481
|
+
if (!e2) {
|
|
75482
|
+
return false;
|
|
75483
|
+
}
|
|
75484
|
+
return Boolean(
|
|
75485
|
+
typeof e2.alphaModFix === "number" || e2.alphaInv || e2.alphaCeiling || e2.alphaFloor || typeof e2.alphaRepl === "number" || typeof e2.alphaBiLevel === "number" || typeof e2.biLevel === "number" || e2.lum && (typeof e2.lum.bright === "number" || typeof e2.lum.contrast === "number") || e2.hsl && (typeof e2.hsl.sat === "number" || typeof e2.hsl.lum === "number") || e2.tint && typeof e2.tint.amt === "number" || e2.clrRepl
|
|
75486
|
+
);
|
|
75487
|
+
}
|
|
75488
|
+
function renderImageAlphaSvgFilter(element2) {
|
|
75489
|
+
if (!isImageLikeElement(element2)) {
|
|
75490
|
+
return null;
|
|
75491
|
+
}
|
|
75492
|
+
const e2 = element2.imageEffects;
|
|
75493
|
+
if (!e2 || !hasAdvancedImageAlphaEffects(element2)) {
|
|
75494
|
+
return null;
|
|
75495
|
+
}
|
|
75496
|
+
const filterId = getImageAlphaFilterId(element2.id);
|
|
75497
|
+
const primitives = [];
|
|
75498
|
+
let resultIdx = 0;
|
|
75499
|
+
let inputRef = "SourceGraphic";
|
|
75500
|
+
const next = (jsx229) => {
|
|
75501
|
+
const result = `r${resultIdx++}`;
|
|
75502
|
+
primitives.push(jsx229(inputRef, result));
|
|
75503
|
+
inputRef = result;
|
|
75504
|
+
};
|
|
75505
|
+
if (typeof e2.alphaModFix === "number") {
|
|
75506
|
+
const mul = clamp(e2.alphaModFix / 100, 0, 1);
|
|
75507
|
+
next((inp, out) => /* @__PURE__ */ jsx(
|
|
75508
|
+
"feColorMatrix",
|
|
75509
|
+
{
|
|
75510
|
+
in: inp,
|
|
75511
|
+
result: out,
|
|
75512
|
+
type: "matrix",
|
|
75513
|
+
values: `1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 ${mul} 0`
|
|
75514
|
+
},
|
|
75515
|
+
out
|
|
75516
|
+
));
|
|
75517
|
+
}
|
|
75518
|
+
if (e2.alphaInv) {
|
|
75519
|
+
next((inp, out) => /* @__PURE__ */ jsx("feComponentTransfer", { in: inp, result: out, children: /* @__PURE__ */ jsx("feFuncA", { type: "linear", slope: -1, intercept: 1 }) }, out));
|
|
75520
|
+
}
|
|
75521
|
+
if (e2.alphaCeiling) {
|
|
75522
|
+
next((inp, out) => /* @__PURE__ */ jsx("feComponentTransfer", { in: inp, result: out, children: /* @__PURE__ */ jsx("feFuncA", { type: "discrete", tableValues: "0 1 1 1 1 1 1 1 1 1" }) }, out));
|
|
75523
|
+
}
|
|
75524
|
+
if (e2.alphaFloor) {
|
|
75525
|
+
next((inp, out) => /* @__PURE__ */ jsx("feComponentTransfer", { in: inp, result: out, children: /* @__PURE__ */ jsx("feFuncA", { type: "discrete", tableValues: "0 0 0 0 0 0 0 0 0 1" }) }, out));
|
|
75526
|
+
}
|
|
75527
|
+
if (typeof e2.alphaRepl === "number") {
|
|
75528
|
+
const a2 = clamp(e2.alphaRepl / 100, 0, 1);
|
|
75529
|
+
next((inp, out) => /* @__PURE__ */ jsx("feComponentTransfer", { in: inp, result: out, children: /* @__PURE__ */ jsx("feFuncA", { type: "linear", slope: 0, intercept: a2 }) }, out));
|
|
75530
|
+
}
|
|
75531
|
+
if (typeof e2.alphaBiLevel === "number") {
|
|
75532
|
+
const t2 = clamp(e2.alphaBiLevel / 100, 0, 1);
|
|
75533
|
+
const table = Array.from({ length: 10 }, (_, i3) => i3 / 10 >= t2 ? "1" : "0").join(" ");
|
|
75534
|
+
next((inp, out) => /* @__PURE__ */ jsx("feComponentTransfer", { in: inp, result: out, children: /* @__PURE__ */ jsx("feFuncA", { type: "discrete", tableValues: table }) }, out));
|
|
75535
|
+
}
|
|
75536
|
+
if (typeof e2.biLevel === "number") {
|
|
75537
|
+
next((inp, out) => /* @__PURE__ */ jsx("feColorMatrix", { in: inp, result: out, type: "saturate", values: "0" }, out));
|
|
75538
|
+
const t2 = clamp(e2.biLevel / 100, 0, 1);
|
|
75539
|
+
const tbl = t2 < 0.5 ? "0 1" : "0 1";
|
|
75540
|
+
next((inp, out) => /* @__PURE__ */ jsxs("feComponentTransfer", { in: inp, result: out, children: [
|
|
75541
|
+
/* @__PURE__ */ jsx("feFuncR", { type: "discrete", tableValues: tbl }),
|
|
75542
|
+
/* @__PURE__ */ jsx("feFuncG", { type: "discrete", tableValues: tbl }),
|
|
75543
|
+
/* @__PURE__ */ jsx("feFuncB", { type: "discrete", tableValues: tbl })
|
|
75544
|
+
] }, out));
|
|
75545
|
+
}
|
|
75546
|
+
if (e2.lum && (typeof e2.lum.bright === "number" || typeof e2.lum.contrast === "number")) {
|
|
75547
|
+
const b2 = (e2.lum.bright ?? 0) / 100;
|
|
75548
|
+
const c2 = 1 + (e2.lum.contrast ?? 0) / 100;
|
|
75549
|
+
const slope = c2;
|
|
75550
|
+
const intercept = b2 + (1 - c2) / 2;
|
|
75551
|
+
next((inp, out) => /* @__PURE__ */ jsxs("feComponentTransfer", { in: inp, result: out, children: [
|
|
75552
|
+
/* @__PURE__ */ jsx("feFuncR", { type: "linear", slope, intercept }),
|
|
75553
|
+
/* @__PURE__ */ jsx("feFuncG", { type: "linear", slope, intercept }),
|
|
75554
|
+
/* @__PURE__ */ jsx("feFuncB", { type: "linear", slope, intercept })
|
|
75555
|
+
] }, out));
|
|
75556
|
+
}
|
|
75557
|
+
if (e2.hsl && typeof e2.hsl.sat === "number") {
|
|
75558
|
+
const v = clamp(1 + e2.hsl.sat / 100, 0, 2);
|
|
75559
|
+
next((inp, out) => /* @__PURE__ */ jsx("feColorMatrix", { in: inp, result: out, type: "saturate", values: String(v) }, out));
|
|
75560
|
+
}
|
|
75561
|
+
if (e2.tint && typeof e2.tint.amt === "number" && e2.tint.amt < 0) {
|
|
75562
|
+
const v = clamp(1 + e2.tint.amt / 100, 0, 1);
|
|
75563
|
+
next((inp, out) => /* @__PURE__ */ jsx("feColorMatrix", { in: inp, result: out, type: "saturate", values: String(v) }, out));
|
|
75564
|
+
}
|
|
75565
|
+
if (e2.clrRepl) {
|
|
75566
|
+
const c2 = hexToRgbUnit(e2.clrRepl.color);
|
|
75567
|
+
next((inp, out) => /* @__PURE__ */ jsx(
|
|
75568
|
+
"feColorMatrix",
|
|
75569
|
+
{
|
|
75570
|
+
in: inp,
|
|
75571
|
+
result: out,
|
|
75572
|
+
type: "matrix",
|
|
75573
|
+
values: `0 0 0 0 ${c2.r} 0 0 0 0 ${c2.g} 0 0 0 0 ${c2.b} 0 0 0 1 0`
|
|
75574
|
+
},
|
|
75575
|
+
out
|
|
75576
|
+
));
|
|
75577
|
+
}
|
|
75578
|
+
if (primitives.length === 0) {
|
|
75579
|
+
return null;
|
|
75580
|
+
}
|
|
75581
|
+
return /* @__PURE__ */ jsx(
|
|
75582
|
+
"svg",
|
|
75583
|
+
{
|
|
75584
|
+
width: 0,
|
|
75585
|
+
height: 0,
|
|
75586
|
+
style: { position: "absolute", overflow: "hidden" },
|
|
75587
|
+
"aria-hidden": "true",
|
|
75588
|
+
children: /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsx("filter", { id: filterId, colorInterpolationFilters: "sRGB", children: primitives }) })
|
|
75589
|
+
}
|
|
75590
|
+
);
|
|
75591
|
+
}
|
|
75592
|
+
function clamp(v, lo, hi) {
|
|
75593
|
+
return v < lo ? lo : v > hi ? hi : v;
|
|
75594
|
+
}
|
|
75410
75595
|
function getDagDuotoneFilterId(elementId) {
|
|
75411
75596
|
return `dag-duotone-${elementId}`;
|
|
75412
75597
|
}
|
|
@@ -75490,6 +75675,9 @@ function getImageEffectsFilter(element2, options) {
|
|
|
75490
75675
|
const filterId = getDuotoneFilterId(element2.id);
|
|
75491
75676
|
filters.push(`url(#${filterId})`);
|
|
75492
75677
|
}
|
|
75678
|
+
if (hasAdvancedImageAlphaEffects(element2)) {
|
|
75679
|
+
filters.push(`url(#${getImageAlphaFilterId(element2.id)})`);
|
|
75680
|
+
}
|
|
75493
75681
|
if (effects.artisticEffect) {
|
|
75494
75682
|
const radius = effects.artisticRadius ?? 5;
|
|
75495
75683
|
if (needsSvgArtisticFilter(effects.artisticEffect)) {
|
|
@@ -75663,6 +75851,39 @@ function getEffectDagCssFilter(style, elementId) {
|
|
|
75663
75851
|
return filters.length > 0 ? filters.join(" ") : void 0;
|
|
75664
75852
|
}
|
|
75665
75853
|
var getEffectDagFilter = getEffectDagCssFilter;
|
|
75854
|
+
function getResolvedShapeClipPathFor(shapeType, width, height, adjustments) {
|
|
75855
|
+
if (!shapeType) {
|
|
75856
|
+
return void 0;
|
|
75857
|
+
}
|
|
75858
|
+
if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) {
|
|
75859
|
+
return getShapeClipPath(shapeType, adjustments, width, height);
|
|
75860
|
+
}
|
|
75861
|
+
if (adjustments && Object.keys(adjustments).length > 0) {
|
|
75862
|
+
const adjusted = getAdjustmentAwareShapeClipPath(shapeType, width, height, adjustments);
|
|
75863
|
+
if (adjusted !== void 0) {
|
|
75864
|
+
return adjusted;
|
|
75865
|
+
}
|
|
75866
|
+
}
|
|
75867
|
+
const fromPreset = getShapeClipPathFromPreset(shapeType, width, height, adjustments);
|
|
75868
|
+
if (fromPreset !== void 0) {
|
|
75869
|
+
return fromPreset;
|
|
75870
|
+
}
|
|
75871
|
+
const cloud = getCloudPathForRendering(shapeType, width, height);
|
|
75872
|
+
if (cloud !== void 0) {
|
|
75873
|
+
return cloud;
|
|
75874
|
+
}
|
|
75875
|
+
return getShapeClipPath(shapeType, adjustments, width, height);
|
|
75876
|
+
}
|
|
75877
|
+
function getResolvedShapeClipPath(element2, width, height) {
|
|
75878
|
+
const shapeType = element2.shapeType;
|
|
75879
|
+
if (!shapeType) {
|
|
75880
|
+
return void 0;
|
|
75881
|
+
}
|
|
75882
|
+
const w = element2.width;
|
|
75883
|
+
const h2 = element2.height;
|
|
75884
|
+
const adjustments = element2.shapeAdjustments;
|
|
75885
|
+
return getResolvedShapeClipPathFor(shapeType, w, h2, adjustments);
|
|
75886
|
+
}
|
|
75666
75887
|
|
|
75667
75888
|
// src/viewer/utils/shape-round-rect.ts
|
|
75668
75889
|
function localClampAdjustment(value) {
|
|
@@ -75734,6 +75955,27 @@ var MATERIAL_MAP = {
|
|
|
75734
75955
|
filter: "brightness(1.1) contrast(0.85)",
|
|
75735
75956
|
// Translucent powder: slight translucent glow
|
|
75736
75957
|
backgroundImage: "radial-gradient(ellipse at 30% 30%, rgba(255,255,255,0.1) 0%, transparent 60%)"
|
|
75958
|
+
},
|
|
75959
|
+
// Legacy materials (PowerPoint 2007 / earlier). Render as muted variants
|
|
75960
|
+
// of the modern equivalents so legacy decks still resemble the originals.
|
|
75961
|
+
legacyMatte: {
|
|
75962
|
+
filter: "brightness(0.92) saturate(0.85)",
|
|
75963
|
+
backgroundImage: "linear-gradient(180deg, rgba(255,255,255,0.03) 0%, transparent 50%, rgba(0,0,0,0.04) 100%)"
|
|
75964
|
+
},
|
|
75965
|
+
legacyPlastic: {
|
|
75966
|
+
filter: "brightness(1.02) contrast(1.03)",
|
|
75967
|
+
boxShadow: "inset -2px -2px 5px rgba(255,255,255,0.3)",
|
|
75968
|
+
backgroundImage: "radial-gradient(ellipse 35% 25% at 25% 20%, rgba(255,255,255,0.15) 0%, transparent 70%)"
|
|
75969
|
+
},
|
|
75970
|
+
legacyMetal: {
|
|
75971
|
+
filter: "brightness(1.05) contrast(1.1) saturate(1.1)",
|
|
75972
|
+
boxShadow: "inset -2px -2px 6px rgba(255,255,255,0.35), inset 1px 1px 3px rgba(255,255,255,0.15)",
|
|
75973
|
+
backgroundImage: "linear-gradient(135deg, rgba(255,255,255,0.18) 0%, rgba(255,255,255,0.06) 25%, transparent 50%, rgba(0,0,0,0.05) 80%)"
|
|
75974
|
+
},
|
|
75975
|
+
legacyWireframe: {
|
|
75976
|
+
filter: "brightness(1) contrast(1.4) saturate(0.6)",
|
|
75977
|
+
// Wireframe: high contrast outline-emphasising look
|
|
75978
|
+
boxShadow: "inset 0 0 0 1px rgba(0,0,0,0.4)"
|
|
75737
75979
|
}
|
|
75738
75980
|
};
|
|
75739
75981
|
function getMaterialCssOverrides(material) {
|
|
@@ -76688,8 +76930,7 @@ function getShapeVisualStyle(element2, hasFill, fillColor, strokeWidth, strokeCo
|
|
|
76688
76930
|
return {};
|
|
76689
76931
|
}
|
|
76690
76932
|
const normalizedShapeType = getShapeType(element2.shapeType);
|
|
76691
|
-
const
|
|
76692
|
-
const clipPath = getShapeClipPath(shapeType);
|
|
76933
|
+
const clipPath = getResolvedShapeClipPath(element2);
|
|
76693
76934
|
const fillOpacity = element2.shapeStyle?.fillOpacity;
|
|
76694
76935
|
const strokeOpacity = element2.shapeStyle?.strokeOpacity;
|
|
76695
76936
|
const strokeDash = normalizeStrokeDashType(element2.shapeStyle?.strokeDash);
|
|
@@ -77291,7 +77532,7 @@ function getImageMaskStyle(element2) {
|
|
|
77291
77532
|
if (normalized === "can" || normalized === "cylinder") {
|
|
77292
77533
|
return { borderRadius: "48% / 12%" };
|
|
77293
77534
|
}
|
|
77294
|
-
const clipPath =
|
|
77535
|
+
const clipPath = getResolvedShapeClipPath(element2);
|
|
77295
77536
|
if (!clipPath) {
|
|
77296
77537
|
return void 0;
|
|
77297
77538
|
}
|
|
@@ -77954,8 +78195,8 @@ function hexToRgb3(hex) {
|
|
|
77954
78195
|
};
|
|
77955
78196
|
}
|
|
77956
78197
|
function rgbToHex2(r2, g2, b2) {
|
|
77957
|
-
const
|
|
77958
|
-
return `#${
|
|
78198
|
+
const clamp3 = (v) => Math.max(0, Math.min(255, Math.round(v)));
|
|
78199
|
+
return `#${clamp3(r2).toString(16).padStart(2, "0").toUpperCase()}${clamp3(g2).toString(16).padStart(2, "0").toUpperCase()}${clamp3(b2).toString(16).padStart(2, "0").toUpperCase()}`;
|
|
77959
78200
|
}
|
|
77960
78201
|
function tintColor(hex, tintFactor) {
|
|
77961
78202
|
const { r: r2, g: g2, b: b2 } = hexToRgb3(hex);
|
|
@@ -78886,13 +79127,13 @@ function cellStyleToCss(style) {
|
|
|
78886
79127
|
}
|
|
78887
79128
|
if (style.textDirection) {
|
|
78888
79129
|
switch (style.textDirection) {
|
|
78889
|
-
case "
|
|
79130
|
+
case "vert":
|
|
78890
79131
|
case "eaVert":
|
|
78891
79132
|
case "wordArtVert":
|
|
78892
79133
|
case "wordArtVertRtl":
|
|
78893
79134
|
css.writingMode = "vertical-rl";
|
|
78894
79135
|
break;
|
|
78895
|
-
case "
|
|
79136
|
+
case "vert270":
|
|
78896
79137
|
case "mongolianVert":
|
|
78897
79138
|
css.writingMode = "vertical-lr";
|
|
78898
79139
|
break;
|
|
@@ -79419,8 +79660,8 @@ function hexToRgb4(hex) {
|
|
|
79419
79660
|
];
|
|
79420
79661
|
}
|
|
79421
79662
|
function rgbToHex3(r2, g2, b2) {
|
|
79422
|
-
const
|
|
79423
|
-
return `#${
|
|
79663
|
+
const clamp3 = (v) => Math.max(0, Math.min(255, Math.round(v)));
|
|
79664
|
+
return `#${clamp3(r2).toString(16).padStart(2, "0")}${clamp3(g2).toString(16).padStart(2, "0")}${clamp3(b2).toString(16).padStart(2, "0")}`;
|
|
79424
79665
|
}
|
|
79425
79666
|
function tint(hex, amount) {
|
|
79426
79667
|
const [r2, g2, b2] = hexToRgb4(hex);
|
|
@@ -81338,7 +81579,7 @@ function resolveRegionCode(label) {
|
|
|
81338
81579
|
return REGION_ALIAS_MAP[normalized];
|
|
81339
81580
|
}
|
|
81340
81581
|
function lerpColor(a2, b2, t2) {
|
|
81341
|
-
const
|
|
81582
|
+
const clamp3 = (v) => Math.max(0, Math.min(255, Math.round(v)));
|
|
81342
81583
|
const parse = (hex) => {
|
|
81343
81584
|
const h2 = hex.replace("#", "");
|
|
81344
81585
|
return [
|
|
@@ -81349,9 +81590,9 @@ function lerpColor(a2, b2, t2) {
|
|
|
81349
81590
|
};
|
|
81350
81591
|
const [r1, g1, b1] = parse(a2);
|
|
81351
81592
|
const [r2, g2, b22] = parse(b2);
|
|
81352
|
-
const r3 =
|
|
81353
|
-
const g3 =
|
|
81354
|
-
const bl =
|
|
81593
|
+
const r3 = clamp3(r1 + (r2 - r1) * t2);
|
|
81594
|
+
const g3 = clamp3(g1 + (g2 - g1) * t2);
|
|
81595
|
+
const bl = clamp3(b1 + (b22 - b1) * t2);
|
|
81355
81596
|
return `#${r3.toString(16).padStart(2, "0")}${g3.toString(16).padStart(2, "0")}${bl.toString(16).padStart(2, "0")}`;
|
|
81356
81597
|
}
|
|
81357
81598
|
function sequentialColorScale(t2) {
|
|
@@ -86517,7 +86758,7 @@ function ResizeHandle({
|
|
|
86517
86758
|
}
|
|
86518
86759
|
);
|
|
86519
86760
|
}
|
|
86520
|
-
function
|
|
86761
|
+
function SlideThumbnailImpl({
|
|
86521
86762
|
slide,
|
|
86522
86763
|
templateElements,
|
|
86523
86764
|
canvasSize
|
|
@@ -86755,6 +86996,37 @@ function ThumbnailTable({
|
|
|
86755
86996
|
}
|
|
86756
86997
|
return /* @__PURE__ */ jsx("div", { className: "w-full h-full flex items-center justify-center text-[10px] text-muted-foreground pointer-events-none", children: "Table" });
|
|
86757
86998
|
}
|
|
86999
|
+
function arePropsEqual(prev, next) {
|
|
87000
|
+
if (prev.slide.id !== next.slide.id) {
|
|
87001
|
+
return false;
|
|
87002
|
+
}
|
|
87003
|
+
if (prev.slide.isDirty !== next.slide.isDirty) {
|
|
87004
|
+
return false;
|
|
87005
|
+
}
|
|
87006
|
+
if (prev.slide.hidden !== next.slide.hidden) {
|
|
87007
|
+
return false;
|
|
87008
|
+
}
|
|
87009
|
+
if (prev.slide.elements !== next.slide.elements) {
|
|
87010
|
+
return false;
|
|
87011
|
+
}
|
|
87012
|
+
if (prev.slide.backgroundColor !== next.slide.backgroundColor) {
|
|
87013
|
+
return false;
|
|
87014
|
+
}
|
|
87015
|
+
if (prev.slide.backgroundImage !== next.slide.backgroundImage) {
|
|
87016
|
+
return false;
|
|
87017
|
+
}
|
|
87018
|
+
if (prev.slide.backgroundGradient !== next.slide.backgroundGradient) {
|
|
87019
|
+
return false;
|
|
87020
|
+
}
|
|
87021
|
+
if (prev.templateElements !== next.templateElements) {
|
|
87022
|
+
return false;
|
|
87023
|
+
}
|
|
87024
|
+
if (prev.canvasSize.width !== next.canvasSize.width || prev.canvasSize.height !== next.canvasSize.height) {
|
|
87025
|
+
return false;
|
|
87026
|
+
}
|
|
87027
|
+
return true;
|
|
87028
|
+
}
|
|
87029
|
+
var SlideThumbnail = React10__default.memo(SlideThumbnailImpl, arePropsEqual);
|
|
86758
87030
|
function ContextMenu({
|
|
86759
87031
|
contextMenuState,
|
|
86760
87032
|
mode,
|
|
@@ -88072,6 +88344,59 @@ function WarpedText({
|
|
|
88072
88344
|
}
|
|
88073
88345
|
);
|
|
88074
88346
|
}
|
|
88347
|
+
var GLYPH_BY_SHAPE = Object.fromEntries(
|
|
88348
|
+
ACTION_BUTTON_PRESETS.map((p3) => [p3.shapeType, p3.iconPath])
|
|
88349
|
+
);
|
|
88350
|
+
GLYPH_BY_SHAPE["actionButtonForwardOrNext"] = GLYPH_BY_SHAPE["actionButtonForwardNext"];
|
|
88351
|
+
GLYPH_BY_SHAPE["actionButtonBackOrPrevious"] = GLYPH_BY_SHAPE["actionButtonBackPrevious"];
|
|
88352
|
+
function isActionButtonShape(shapeType) {
|
|
88353
|
+
return Boolean(shapeType && shapeType in GLYPH_BY_SHAPE);
|
|
88354
|
+
}
|
|
88355
|
+
function getActionButtonGlyphPath(shapeType) {
|
|
88356
|
+
if (!shapeType) {
|
|
88357
|
+
return void 0;
|
|
88358
|
+
}
|
|
88359
|
+
const path = GLYPH_BY_SHAPE[shapeType];
|
|
88360
|
+
return path && path.length > 0 ? path : void 0;
|
|
88361
|
+
}
|
|
88362
|
+
function ActionButtonGlyphOverlay({
|
|
88363
|
+
element: element2,
|
|
88364
|
+
color
|
|
88365
|
+
}) {
|
|
88366
|
+
const shapeType = "shapeType" in element2 ? element2.shapeType : void 0;
|
|
88367
|
+
const path = getActionButtonGlyphPath(shapeType);
|
|
88368
|
+
if (!path) {
|
|
88369
|
+
return null;
|
|
88370
|
+
}
|
|
88371
|
+
const stroke = color ?? ("textStyle" in element2 && element2.textStyle?.color || "#ffffff");
|
|
88372
|
+
return /* @__PURE__ */ jsx(
|
|
88373
|
+
"svg",
|
|
88374
|
+
{
|
|
88375
|
+
viewBox: "0 0 24 24",
|
|
88376
|
+
width: "100%",
|
|
88377
|
+
height: "100%",
|
|
88378
|
+
preserveAspectRatio: "xMidYMid meet",
|
|
88379
|
+
style: {
|
|
88380
|
+
position: "absolute",
|
|
88381
|
+
inset: 0,
|
|
88382
|
+
pointerEvents: "none",
|
|
88383
|
+
padding: "20%"
|
|
88384
|
+
},
|
|
88385
|
+
"aria-hidden": "true",
|
|
88386
|
+
children: /* @__PURE__ */ jsx(
|
|
88387
|
+
"path",
|
|
88388
|
+
{
|
|
88389
|
+
d: path,
|
|
88390
|
+
fill: "none",
|
|
88391
|
+
stroke,
|
|
88392
|
+
strokeWidth: 2,
|
|
88393
|
+
strokeLinecap: "round",
|
|
88394
|
+
strokeLinejoin: "round"
|
|
88395
|
+
}
|
|
88396
|
+
)
|
|
88397
|
+
}
|
|
88398
|
+
);
|
|
88399
|
+
}
|
|
88075
88400
|
function ColorChangedImage({
|
|
88076
88401
|
src,
|
|
88077
88402
|
clrChange,
|
|
@@ -88342,6 +88667,7 @@ function renderImg(el, style, filter, alt, opacity) {
|
|
|
88342
88667
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
88343
88668
|
tileDuotoneColors && renderDuotoneSvgFilter(el.id, tileDuotoneColors.color1, tileDuotoneColors.color2),
|
|
88344
88669
|
renderArtisticEffectSvgFilter(el.id, artisticEffectName, artisticRadius),
|
|
88670
|
+
renderImageAlphaSvgFilter(el),
|
|
88345
88671
|
/* @__PURE__ */ jsx(
|
|
88346
88672
|
"div",
|
|
88347
88673
|
{
|
|
@@ -88363,6 +88689,7 @@ function renderImg(el, style, filter, alt, opacity) {
|
|
|
88363
88689
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
88364
88690
|
duotoneColors && !useDuotoneCanvas && renderDuotoneSvgFilter(el.id, duotoneColors.color1, duotoneColors.color2),
|
|
88365
88691
|
renderArtisticEffectSvgFilter(el.id, artisticEffectName, artisticRadius),
|
|
88692
|
+
renderImageAlphaSvgFilter(el),
|
|
88366
88693
|
useDuotoneCanvas && duotoneColors ? /* @__PURE__ */ jsx(
|
|
88367
88694
|
DuotoneImage,
|
|
88368
88695
|
{
|
|
@@ -90488,7 +90815,7 @@ function BendingProcessRenderer({
|
|
|
90488
90815
|
}
|
|
90489
90816
|
);
|
|
90490
90817
|
}
|
|
90491
|
-
function
|
|
90818
|
+
function SmartArtRendererImpl({
|
|
90492
90819
|
element: element2,
|
|
90493
90820
|
className = ""
|
|
90494
90821
|
}) {
|
|
@@ -90599,6 +90926,30 @@ function renderLayout(layoutType, element2, nodes, palette, style) {
|
|
|
90599
90926
|
}
|
|
90600
90927
|
return /* @__PURE__ */ jsx(ListRenderer, { element: element2, nodes, palette, style });
|
|
90601
90928
|
}
|
|
90929
|
+
function arePropsEqual2(prev, next) {
|
|
90930
|
+
if (prev.className !== next.className) {
|
|
90931
|
+
return false;
|
|
90932
|
+
}
|
|
90933
|
+
if (prev.element.id !== next.element.id) {
|
|
90934
|
+
return false;
|
|
90935
|
+
}
|
|
90936
|
+
if (prev.element.type !== next.element.type) {
|
|
90937
|
+
return false;
|
|
90938
|
+
}
|
|
90939
|
+
if (prev.element.width !== next.element.width || prev.element.height !== next.element.height) {
|
|
90940
|
+
return false;
|
|
90941
|
+
}
|
|
90942
|
+
if (prev.element.x !== next.element.x || prev.element.y !== next.element.y) {
|
|
90943
|
+
return false;
|
|
90944
|
+
}
|
|
90945
|
+
const prevData = prev.element.type === "smartArt" ? prev.element.smartArtData : void 0;
|
|
90946
|
+
const nextData = next.element.type === "smartArt" ? next.element.smartArtData : void 0;
|
|
90947
|
+
if (prevData !== nextData) {
|
|
90948
|
+
return false;
|
|
90949
|
+
}
|
|
90950
|
+
return true;
|
|
90951
|
+
}
|
|
90952
|
+
var SmartArtRenderer = React10__default.memo(SmartArtRendererImpl, arePropsEqual2);
|
|
90602
90953
|
function ZoomElementRenderer({
|
|
90603
90954
|
element: element2,
|
|
90604
90955
|
slides,
|
|
@@ -90847,8 +91198,11 @@ function renderBody(el, isImg, isEditing, editText, spellCheck, txtSE, txtS, vec
|
|
|
90847
91198
|
...scene3dStyle.perspective ? { perspective: scene3dStyle.perspective } : {},
|
|
90848
91199
|
...scene3dStyle.transformStyle ? { transformStyle: scene3dStyle.transformStyle } : {}
|
|
90849
91200
|
} : void 0;
|
|
91201
|
+
const shapeTypeForGlyph = "shapeType" in el ? el.shapeType : void 0;
|
|
91202
|
+
const showActionButtonGlyph = isActionButtonShape(shapeTypeForGlyph);
|
|
90850
91203
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
90851
91204
|
vecShape,
|
|
91205
|
+
showActionButtonGlyph && /* @__PURE__ */ jsx(ActionButtonGlyphOverlay, { element: el }),
|
|
90852
91206
|
isTxtEl ? useSvgWarp ? /* @__PURE__ */ jsx(
|
|
90853
91207
|
"div",
|
|
90854
91208
|
{
|
|
@@ -93637,7 +93991,7 @@ function SectionBlock({
|
|
|
93637
93991
|
)
|
|
93638
93992
|
] });
|
|
93639
93993
|
}
|
|
93640
|
-
function
|
|
93994
|
+
function SlideCardImpl({
|
|
93641
93995
|
slide,
|
|
93642
93996
|
index,
|
|
93643
93997
|
isActive,
|
|
@@ -93691,6 +94045,49 @@ function SlideCard({
|
|
|
93691
94045
|
}
|
|
93692
94046
|
);
|
|
93693
94047
|
}
|
|
94048
|
+
function arePropsEqual3(prev, next) {
|
|
94049
|
+
if (prev.slide.id !== next.slide.id) {
|
|
94050
|
+
return false;
|
|
94051
|
+
}
|
|
94052
|
+
if (prev.slide.isDirty !== next.slide.isDirty) {
|
|
94053
|
+
return false;
|
|
94054
|
+
}
|
|
94055
|
+
if (prev.slide.hidden !== next.slide.hidden) {
|
|
94056
|
+
return false;
|
|
94057
|
+
}
|
|
94058
|
+
if (prev.slide.elements !== next.slide.elements) {
|
|
94059
|
+
return false;
|
|
94060
|
+
}
|
|
94061
|
+
if (prev.index !== next.index) {
|
|
94062
|
+
return false;
|
|
94063
|
+
}
|
|
94064
|
+
if (prev.isActive !== next.isActive) {
|
|
94065
|
+
return false;
|
|
94066
|
+
}
|
|
94067
|
+
if (prev.isDragTarget !== next.isDragTarget) {
|
|
94068
|
+
return false;
|
|
94069
|
+
}
|
|
94070
|
+
if (prev.isSelected !== next.isSelected) {
|
|
94071
|
+
return false;
|
|
94072
|
+
}
|
|
94073
|
+
if (prev.selectedCount !== next.selectedCount) {
|
|
94074
|
+
return false;
|
|
94075
|
+
}
|
|
94076
|
+
if (prev.selectionOrder !== next.selectionOrder) {
|
|
94077
|
+
return false;
|
|
94078
|
+
}
|
|
94079
|
+
if (prev.canEdit !== next.canEdit) {
|
|
94080
|
+
return false;
|
|
94081
|
+
}
|
|
94082
|
+
if (prev.canvasSize.width !== next.canvasSize.width || prev.canvasSize.height !== next.canvasSize.height) {
|
|
94083
|
+
return false;
|
|
94084
|
+
}
|
|
94085
|
+
if (prev.onSlideClick !== next.onSlideClick || prev.onDoubleClick !== next.onDoubleClick || prev.onContextMenu !== next.onContextMenu || prev.onDragStart !== next.onDragStart || prev.onDragOver !== next.onDragOver || prev.onDragLeave !== next.onDragLeave || prev.onDrop !== next.onDrop) {
|
|
94086
|
+
return false;
|
|
94087
|
+
}
|
|
94088
|
+
return true;
|
|
94089
|
+
}
|
|
94090
|
+
var SlideCard = React10__default.memo(SlideCardImpl, arePropsEqual3);
|
|
93694
94091
|
function SorterContextMenu({
|
|
93695
94092
|
x: x2,
|
|
93696
94093
|
y,
|
|
@@ -94484,6 +94881,14 @@ function getCurrentParagraphIndex(editorEl, segments) {
|
|
|
94484
94881
|
}
|
|
94485
94882
|
return paraIdx;
|
|
94486
94883
|
}
|
|
94884
|
+
var CSS_VALUE_SAFE = /^[a-zA-Z0-9 _,.\-+#'%/]{1,100}$/;
|
|
94885
|
+
function isCssValueSafe(value) {
|
|
94886
|
+
if (value === void 0 || value === null) {
|
|
94887
|
+
return false;
|
|
94888
|
+
}
|
|
94889
|
+
const str = String(value);
|
|
94890
|
+
return str.length > 0 && CSS_VALUE_SAFE.test(str);
|
|
94891
|
+
}
|
|
94487
94892
|
function deriveStyleFromElement(element2, inheritedStyle) {
|
|
94488
94893
|
const style = { ...inheritedStyle };
|
|
94489
94894
|
const tagName = element2.tagName.toLowerCase();
|
|
@@ -94616,17 +95021,17 @@ function segmentsToEditorHtml(segments) {
|
|
|
94616
95021
|
if (segment.style.strikethrough) {
|
|
94617
95022
|
inlineStyles.push("text-decoration:line-through");
|
|
94618
95023
|
}
|
|
94619
|
-
if (segment.style.color) {
|
|
95024
|
+
if (segment.style.color && isCssValueSafe(segment.style.color)) {
|
|
94620
95025
|
inlineStyles.push(`color:${segment.style.color}`);
|
|
94621
95026
|
}
|
|
94622
|
-
if (segment.style.fontSize) {
|
|
94623
|
-
inlineStyles.push(`font-size:${segment.style.fontSize}pt`);
|
|
95027
|
+
if (segment.style.fontSize && Number.isFinite(Number(segment.style.fontSize))) {
|
|
95028
|
+
inlineStyles.push(`font-size:${Number(segment.style.fontSize)}pt`);
|
|
94624
95029
|
}
|
|
94625
|
-
if (segment.style.fontFamily) {
|
|
95030
|
+
if (segment.style.fontFamily && isCssValueSafe(segment.style.fontFamily)) {
|
|
94626
95031
|
inlineStyles.push(`font-family:${segment.style.fontFamily}`);
|
|
94627
95032
|
}
|
|
94628
95033
|
const text2 = escapeHtml(segment.text);
|
|
94629
|
-
if (segment.style.hyperlink) {
|
|
95034
|
+
if (segment.style.hyperlink && isUrlSafe(segment.style.hyperlink)) {
|
|
94630
95035
|
const href = escapeHtml(segment.style.hyperlink);
|
|
94631
95036
|
return `<a href="${href}" style="color:#4a9eff;text-decoration:underline;cursor:pointer" data-hyperlink="${href}">${text2}</a>`;
|
|
94632
95037
|
}
|
|
@@ -94709,7 +95114,8 @@ function renderRichNotesSegments(segments) {
|
|
|
94709
95114
|
if (segment.style.fontFamily) {
|
|
94710
95115
|
style.fontFamily = segment.style.fontFamily;
|
|
94711
95116
|
}
|
|
94712
|
-
if (segment.style.hyperlink) {
|
|
95117
|
+
if (segment.style.hyperlink && isUrlSafe(segment.style.hyperlink)) {
|
|
95118
|
+
const safeHref = segment.style.hyperlink;
|
|
94713
95119
|
style.color = "#4a9eff";
|
|
94714
95120
|
style.textDecoration = "underline";
|
|
94715
95121
|
style.cursor = "pointer";
|
|
@@ -94717,11 +95123,11 @@ function renderRichNotesSegments(segments) {
|
|
|
94717
95123
|
/* @__PURE__ */ jsx(
|
|
94718
95124
|
"a",
|
|
94719
95125
|
{
|
|
94720
|
-
href:
|
|
95126
|
+
href: safeHref,
|
|
94721
95127
|
style,
|
|
94722
95128
|
onClick: (e2) => {
|
|
94723
95129
|
e2.preventDefault();
|
|
94724
|
-
|
|
95130
|
+
safeOpenUrl(safeHref);
|
|
94725
95131
|
},
|
|
94726
95132
|
children: segment.text
|
|
94727
95133
|
},
|
|
@@ -95273,7 +95679,7 @@ function useSlideNotes({
|
|
|
95273
95679
|
const href = target.getAttribute("data-hyperlink") || target.getAttribute("href");
|
|
95274
95680
|
if (href && (e2.ctrlKey || e2.metaKey)) {
|
|
95275
95681
|
e2.preventDefault();
|
|
95276
|
-
|
|
95682
|
+
safeOpenUrl(href);
|
|
95277
95683
|
}
|
|
95278
95684
|
}, []);
|
|
95279
95685
|
return {
|
|
@@ -96946,7 +97352,7 @@ function renderNotesSegments(segments) {
|
|
|
96946
97352
|
return React10__default.createElement("span", { key: `seg-${index}`, style }, segment.text);
|
|
96947
97353
|
});
|
|
96948
97354
|
}
|
|
96949
|
-
function
|
|
97355
|
+
function ScaledSlidePreviewImpl({
|
|
96950
97356
|
slide,
|
|
96951
97357
|
templateElements,
|
|
96952
97358
|
canvasSize,
|
|
@@ -97093,6 +97499,40 @@ function ScaledSlidePreview({
|
|
|
97093
97499
|
}
|
|
97094
97500
|
);
|
|
97095
97501
|
}
|
|
97502
|
+
function arePropsEqual4(prev, next) {
|
|
97503
|
+
if (prev.slide.id !== next.slide.id) {
|
|
97504
|
+
return false;
|
|
97505
|
+
}
|
|
97506
|
+
if (prev.slide.isDirty !== next.slide.isDirty) {
|
|
97507
|
+
return false;
|
|
97508
|
+
}
|
|
97509
|
+
if (prev.slide.hidden !== next.slide.hidden) {
|
|
97510
|
+
return false;
|
|
97511
|
+
}
|
|
97512
|
+
if (prev.slide.elements !== next.slide.elements) {
|
|
97513
|
+
return false;
|
|
97514
|
+
}
|
|
97515
|
+
if (prev.slide.backgroundColor !== next.slide.backgroundColor) {
|
|
97516
|
+
return false;
|
|
97517
|
+
}
|
|
97518
|
+
if (prev.slide.backgroundImage !== next.slide.backgroundImage) {
|
|
97519
|
+
return false;
|
|
97520
|
+
}
|
|
97521
|
+
if (prev.slide.backgroundGradient !== next.slide.backgroundGradient) {
|
|
97522
|
+
return false;
|
|
97523
|
+
}
|
|
97524
|
+
if (prev.templateElements !== next.templateElements) {
|
|
97525
|
+
return false;
|
|
97526
|
+
}
|
|
97527
|
+
if (prev.canvasSize.width !== next.canvasSize.width || prev.canvasSize.height !== next.canvasSize.height) {
|
|
97528
|
+
return false;
|
|
97529
|
+
}
|
|
97530
|
+
if (prev.className !== next.className) {
|
|
97531
|
+
return false;
|
|
97532
|
+
}
|
|
97533
|
+
return true;
|
|
97534
|
+
}
|
|
97535
|
+
var ScaledSlidePreview = React10__default.memo(ScaledSlidePreviewImpl, arePropsEqual4);
|
|
97096
97536
|
function PresenterView({
|
|
97097
97537
|
slides,
|
|
97098
97538
|
currentSlideIndex,
|
|
@@ -111396,6 +111836,13 @@ function convertOmmlToLatex(omml) {
|
|
|
111396
111836
|
}
|
|
111397
111837
|
return ommlChildrenToLatex(oMath);
|
|
111398
111838
|
}
|
|
111839
|
+
function sanitizeMathMl2(markup) {
|
|
111840
|
+
const purify = DOMPurify;
|
|
111841
|
+
if (typeof purify.sanitize !== "function") {
|
|
111842
|
+
return markup;
|
|
111843
|
+
}
|
|
111844
|
+
return purify.sanitize(markup, { USE_PROFILES: { mathMl: true, svg: true } });
|
|
111845
|
+
}
|
|
111399
111846
|
var TEMPLATES = [
|
|
111400
111847
|
{
|
|
111401
111848
|
label: "Fraction",
|
|
@@ -111461,7 +111908,8 @@ var TEMPLATES = [
|
|
|
111461
111908
|
var TEMPLATE_MATHML = TEMPLATES.map((tmpl) => {
|
|
111462
111909
|
try {
|
|
111463
111910
|
const tmplOmml = convertLatexToOmml(tmpl.latex);
|
|
111464
|
-
|
|
111911
|
+
const raw = convertOmmlToMathMl(tmplOmml);
|
|
111912
|
+
return raw ? sanitizeMathMl2(raw) : "";
|
|
111465
111913
|
} catch {
|
|
111466
111914
|
return "";
|
|
111467
111915
|
}
|
|
@@ -111473,7 +111921,7 @@ function MathMlPreview({ mathml }) {
|
|
|
111473
111921
|
return;
|
|
111474
111922
|
}
|
|
111475
111923
|
if (mathml) {
|
|
111476
|
-
containerRef.current.innerHTML = mathml;
|
|
111924
|
+
containerRef.current.innerHTML = sanitizeMathMl2(mathml);
|
|
111477
111925
|
} else {
|
|
111478
111926
|
containerRef.current.innerHTML = "";
|
|
111479
111927
|
}
|
|
@@ -111501,6 +111949,7 @@ function EquationEditorDialog({
|
|
|
111501
111949
|
return convertOmmlToLatex(existingOmml);
|
|
111502
111950
|
}, [existingOmml]);
|
|
111503
111951
|
const [latex, setLatex] = useState(initialLatex);
|
|
111952
|
+
const deferredLatex = useDeferredValue(latex);
|
|
111504
111953
|
const textareaRef = useRef(null);
|
|
111505
111954
|
useEffect(() => {
|
|
111506
111955
|
if (isOpen) {
|
|
@@ -111509,17 +111958,17 @@ function EquationEditorDialog({
|
|
|
111509
111958
|
}
|
|
111510
111959
|
}, [isOpen, initialLatex]);
|
|
111511
111960
|
const { mathml, omml } = useMemo(() => {
|
|
111512
|
-
if (!
|
|
111961
|
+
if (!deferredLatex.trim()) {
|
|
111513
111962
|
return { mathml: "", omml: {} };
|
|
111514
111963
|
}
|
|
111515
111964
|
try {
|
|
111516
|
-
const ommlObj = convertLatexToOmml(
|
|
111965
|
+
const ommlObj = convertLatexToOmml(deferredLatex);
|
|
111517
111966
|
const mathmlStr = convertOmmlToMathMl(ommlObj);
|
|
111518
111967
|
return { mathml: mathmlStr, omml: ommlObj };
|
|
111519
111968
|
} catch {
|
|
111520
111969
|
return { mathml: "", omml: {} };
|
|
111521
111970
|
}
|
|
111522
|
-
}, [
|
|
111971
|
+
}, [deferredLatex]);
|
|
111523
111972
|
const handleInsert = useCallback(() => {
|
|
111524
111973
|
if (!latex.trim()) {
|
|
111525
111974
|
return;
|
|
@@ -114283,6 +114732,7 @@ function useEditorHistory(input) {
|
|
|
114283
114732
|
const historyFutureRef = useRef([]);
|
|
114284
114733
|
const lastHistorySnapshotRef = useRef(null);
|
|
114285
114734
|
const lastHistorySerializedRef = useRef("");
|
|
114735
|
+
const lastCheapHashRef = useRef("");
|
|
114286
114736
|
const isApplyingHistoryRef = useRef(false);
|
|
114287
114737
|
const unlockHistoryTimerRef = useRef(null);
|
|
114288
114738
|
const [canUndo, setCanUndo] = useState(false);
|
|
@@ -114424,15 +114874,21 @@ function useEditorHistory(input) {
|
|
|
114424
114874
|
if (hasActivePointerInteraction()) {
|
|
114425
114875
|
return;
|
|
114426
114876
|
}
|
|
114877
|
+
const cheapHash = `${slides.length}|${activeSlideIndex}|${canvasSize.width}x${canvasSize.height}|${slides.map((s) => `${s.id}:${s.elements.length}`).join("/")}`;
|
|
114878
|
+
if (cheapHash === lastCheapHashRef.current) {
|
|
114879
|
+
return;
|
|
114880
|
+
}
|
|
114427
114881
|
const snapshot2 = buildHistorySnapshot();
|
|
114428
114882
|
const serialized = JSON.stringify(snapshot2);
|
|
114429
114883
|
if (serialized === lastHistorySerializedRef.current) {
|
|
114884
|
+
lastCheapHashRef.current = cheapHash;
|
|
114430
114885
|
return;
|
|
114431
114886
|
}
|
|
114432
114887
|
const previousSnapshot = lastHistorySnapshotRef.current;
|
|
114433
114888
|
if (!previousSnapshot) {
|
|
114434
114889
|
lastHistorySnapshotRef.current = cloneHistorySnapshot(snapshot2);
|
|
114435
114890
|
lastHistorySerializedRef.current = serialized;
|
|
114891
|
+
lastCheapHashRef.current = cheapHash;
|
|
114436
114892
|
updateHistoryAvailability();
|
|
114437
114893
|
return;
|
|
114438
114894
|
}
|
|
@@ -114443,13 +114899,18 @@ function useEditorHistory(input) {
|
|
|
114443
114899
|
historyFutureRef.current = [];
|
|
114444
114900
|
lastHistorySnapshotRef.current = cloneHistorySnapshot(snapshot2);
|
|
114445
114901
|
lastHistorySerializedRef.current = serialized;
|
|
114902
|
+
lastCheapHashRef.current = cheapHash;
|
|
114446
114903
|
updateHistoryAvailability();
|
|
114447
114904
|
}, [
|
|
114905
|
+
activeSlideIndex,
|
|
114448
114906
|
buildHistorySnapshot,
|
|
114907
|
+
canvasSize.height,
|
|
114908
|
+
canvasSize.width,
|
|
114449
114909
|
error2,
|
|
114450
114910
|
hasActivePointerInteraction,
|
|
114451
114911
|
loading2,
|
|
114452
114912
|
pointerCommitNonce,
|
|
114913
|
+
slides,
|
|
114453
114914
|
updateHistoryAvailability
|
|
114454
114915
|
]);
|
|
114455
114916
|
return {
|
|
@@ -118142,6 +118603,7 @@ var DB_NAME2 = "pptx-viewer-audience";
|
|
|
118142
118603
|
var DB_VERSION2 = 1;
|
|
118143
118604
|
var STORE_NAME2 = "content";
|
|
118144
118605
|
var CONTENT_KEY = "pptx-bytes";
|
|
118606
|
+
var MAX_CONTENT_AGE_MS = 5 * 60 * 1e3;
|
|
118145
118607
|
function openDb() {
|
|
118146
118608
|
return new Promise((resolve2, reject) => {
|
|
118147
118609
|
const request = indexedDB.open(DB_NAME2, DB_VERSION2);
|
|
@@ -118161,7 +118623,8 @@ async function storeAudienceContent(content) {
|
|
|
118161
118623
|
const tx = db.transaction(STORE_NAME2, "readwrite");
|
|
118162
118624
|
const store = tx.objectStore(STORE_NAME2);
|
|
118163
118625
|
const bytes = content instanceof Uint8Array ? content : new Uint8Array(content);
|
|
118164
|
-
|
|
118626
|
+
const record = { bytes, createdAt: Date.now() };
|
|
118627
|
+
store.put(record, CONTENT_KEY);
|
|
118165
118628
|
tx.oncomplete = () => {
|
|
118166
118629
|
db.close();
|
|
118167
118630
|
resolve2();
|
|
@@ -118182,13 +118645,24 @@ async function loadAudienceContent() {
|
|
|
118182
118645
|
request.onsuccess = () => {
|
|
118183
118646
|
db.close();
|
|
118184
118647
|
const result = request.result;
|
|
118185
|
-
if (result
|
|
118186
|
-
|
|
118187
|
-
|
|
118188
|
-
|
|
118189
|
-
|
|
118190
|
-
|
|
118648
|
+
if (result && typeof result === "object" && "bytes" in result && "createdAt" in result) {
|
|
118649
|
+
const record = result;
|
|
118650
|
+
const age = Date.now() - record.createdAt;
|
|
118651
|
+
if (age > MAX_CONTENT_AGE_MS) {
|
|
118652
|
+
resolve2(null);
|
|
118653
|
+
return;
|
|
118654
|
+
}
|
|
118655
|
+
const raw = record.bytes;
|
|
118656
|
+
if (raw instanceof Uint8Array) {
|
|
118657
|
+
resolve2(raw);
|
|
118658
|
+
} else if (raw instanceof ArrayBuffer) {
|
|
118659
|
+
resolve2(new Uint8Array(raw));
|
|
118660
|
+
} else {
|
|
118661
|
+
resolve2(null);
|
|
118662
|
+
}
|
|
118663
|
+
return;
|
|
118191
118664
|
}
|
|
118665
|
+
resolve2(null);
|
|
118192
118666
|
};
|
|
118193
118667
|
request.onerror = () => {
|
|
118194
118668
|
db.close();
|
|
@@ -118221,14 +118695,34 @@ async function clearAudienceContent() {
|
|
|
118221
118695
|
var PRESENTER_CHANNEL_NAME = "pptx-viewer-presenter";
|
|
118222
118696
|
var AUDIENCE_HASH = "#pptx-audience";
|
|
118223
118697
|
var PRESENTER_MSG_ORIGIN = "pptx-viewer-presenter";
|
|
118698
|
+
var AUDIENCE_NONCE_KEY = "nonce";
|
|
118699
|
+
function generateSessionId() {
|
|
118700
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
118701
|
+
return crypto.randomUUID();
|
|
118702
|
+
}
|
|
118703
|
+
return `s${Date.now().toString(36)}${Math.random().toString(36).slice(2, 10)}`;
|
|
118704
|
+
}
|
|
118705
|
+
function parseAudienceNonce() {
|
|
118706
|
+
const hash = window.location.hash;
|
|
118707
|
+
if (!hash.startsWith(AUDIENCE_HASH)) {
|
|
118708
|
+
return null;
|
|
118709
|
+
}
|
|
118710
|
+
const trailing = hash.slice(AUDIENCE_HASH.length);
|
|
118711
|
+
if (!trailing) {
|
|
118712
|
+
return null;
|
|
118713
|
+
}
|
|
118714
|
+
const params2 = new URLSearchParams(trailing.replace(/^[&;?]/, ""));
|
|
118715
|
+
return params2.get(AUDIENCE_NONCE_KEY);
|
|
118716
|
+
}
|
|
118224
118717
|
function isAudienceTab() {
|
|
118225
|
-
return window.location.hash
|
|
118718
|
+
return window.location.hash.startsWith(AUDIENCE_HASH);
|
|
118226
118719
|
}
|
|
118227
118720
|
function usePresenterWindow(input) {
|
|
118228
118721
|
const { currentSlideIndex, isPresenterMode, content } = input;
|
|
118229
118722
|
const audienceWindowRef = useRef(null);
|
|
118230
118723
|
const channelRef = useRef(null);
|
|
118231
118724
|
const pollTimerRef = useRef(null);
|
|
118725
|
+
const sessionIdRef = useRef("");
|
|
118232
118726
|
const getChannel2 = useCallback(() => {
|
|
118233
118727
|
if (!channelRef.current) {
|
|
118234
118728
|
channelRef.current = new BroadcastChannel(PRESENTER_CHANNEL_NAME);
|
|
@@ -118240,10 +118734,14 @@ function usePresenterWindow(input) {
|
|
|
118240
118734
|
}, []);
|
|
118241
118735
|
const syncSlideToAudience = useCallback(
|
|
118242
118736
|
(slideIndex) => {
|
|
118737
|
+
if (!sessionIdRef.current) {
|
|
118738
|
+
return;
|
|
118739
|
+
}
|
|
118243
118740
|
const msg = {
|
|
118244
118741
|
origin: PRESENTER_MSG_ORIGIN,
|
|
118245
118742
|
type: "presenter-slide-change",
|
|
118246
|
-
slideIndex
|
|
118743
|
+
slideIndex,
|
|
118744
|
+
sessionId: sessionIdRef.current
|
|
118247
118745
|
};
|
|
118248
118746
|
try {
|
|
118249
118747
|
getChannel2().postMessage(msg);
|
|
@@ -118253,13 +118751,16 @@ function usePresenterWindow(input) {
|
|
|
118253
118751
|
[getChannel2]
|
|
118254
118752
|
);
|
|
118255
118753
|
const closeAudienceWindow = useCallback(() => {
|
|
118256
|
-
|
|
118257
|
-
|
|
118258
|
-
|
|
118259
|
-
|
|
118260
|
-
|
|
118261
|
-
|
|
118262
|
-
|
|
118754
|
+
if (sessionIdRef.current) {
|
|
118755
|
+
try {
|
|
118756
|
+
const exitMsg = {
|
|
118757
|
+
origin: PRESENTER_MSG_ORIGIN,
|
|
118758
|
+
type: "presenter-exit",
|
|
118759
|
+
sessionId: sessionIdRef.current
|
|
118760
|
+
};
|
|
118761
|
+
getChannel2().postMessage(exitMsg);
|
|
118762
|
+
} catch {
|
|
118763
|
+
}
|
|
118263
118764
|
}
|
|
118264
118765
|
const win = audienceWindowRef.current;
|
|
118265
118766
|
if (win && !win.closed) {
|
|
@@ -118269,6 +118770,7 @@ function usePresenterWindow(input) {
|
|
|
118269
118770
|
}
|
|
118270
118771
|
}
|
|
118271
118772
|
audienceWindowRef.current = null;
|
|
118773
|
+
sessionIdRef.current = "";
|
|
118272
118774
|
if (pollTimerRef.current !== null) {
|
|
118273
118775
|
clearInterval(pollTimerRef.current);
|
|
118274
118776
|
pollTimerRef.current = null;
|
|
@@ -118279,20 +118781,53 @@ function usePresenterWindow(input) {
|
|
|
118279
118781
|
if (isAudienceWindowOpen()) {
|
|
118280
118782
|
closeAudienceWindow();
|
|
118281
118783
|
}
|
|
118282
|
-
|
|
118283
|
-
|
|
118284
|
-
}
|
|
118285
|
-
const url = new URL(window.location.href);
|
|
118286
|
-
url.hash = AUDIENCE_HASH;
|
|
118287
|
-
const win = window.open(url.toString(), "_blank");
|
|
118288
|
-
if (!win) {
|
|
118784
|
+
const blankWin = window.open("about:blank", "_blank");
|
|
118785
|
+
if (!blankWin) {
|
|
118289
118786
|
return false;
|
|
118290
118787
|
}
|
|
118291
|
-
audienceWindowRef.current =
|
|
118788
|
+
audienceWindowRef.current = blankWin;
|
|
118789
|
+
const sessionId = generateSessionId();
|
|
118790
|
+
sessionIdRef.current = sessionId;
|
|
118791
|
+
const audienceUrl = new URL(window.location.href);
|
|
118792
|
+
const params2 = new URLSearchParams();
|
|
118793
|
+
params2.set(AUDIENCE_NONCE_KEY, sessionId);
|
|
118794
|
+
audienceUrl.hash = `${AUDIENCE_HASH}&${params2.toString()}`;
|
|
118795
|
+
const navigateOrClose = (ok) => {
|
|
118796
|
+
const win = audienceWindowRef.current;
|
|
118797
|
+
if (!win || win.closed) {
|
|
118798
|
+
return;
|
|
118799
|
+
}
|
|
118800
|
+
if (!ok) {
|
|
118801
|
+
try {
|
|
118802
|
+
win.close();
|
|
118803
|
+
} catch {
|
|
118804
|
+
}
|
|
118805
|
+
audienceWindowRef.current = null;
|
|
118806
|
+
sessionIdRef.current = "";
|
|
118807
|
+
return;
|
|
118808
|
+
}
|
|
118809
|
+
try {
|
|
118810
|
+
win.location.replace(audienceUrl.toString());
|
|
118811
|
+
} catch {
|
|
118812
|
+
try {
|
|
118813
|
+
win.close();
|
|
118814
|
+
} catch {
|
|
118815
|
+
}
|
|
118816
|
+
audienceWindowRef.current = null;
|
|
118817
|
+
sessionIdRef.current = "";
|
|
118818
|
+
}
|
|
118819
|
+
};
|
|
118820
|
+
if (content) {
|
|
118821
|
+
void storeAudienceContent(content).then(() => navigateOrClose(true)).catch(() => navigateOrClose(false));
|
|
118822
|
+
} else {
|
|
118823
|
+
navigateOrClose(true);
|
|
118824
|
+
}
|
|
118292
118825
|
window.setTimeout(() => syncSlideToAudience(currentSlideIndex), 1500);
|
|
118293
118826
|
pollTimerRef.current = setInterval(() => {
|
|
118294
|
-
|
|
118827
|
+
const win = audienceWindowRef.current;
|
|
118828
|
+
if (!win || win.closed) {
|
|
118295
118829
|
audienceWindowRef.current = null;
|
|
118830
|
+
sessionIdRef.current = "";
|
|
118296
118831
|
if (pollTimerRef.current !== null) {
|
|
118297
118832
|
clearInterval(pollTimerRef.current);
|
|
118298
118833
|
pollTimerRef.current = null;
|
|
@@ -118320,6 +118855,13 @@ function usePresenterWindow(input) {
|
|
|
118320
118855
|
closeAudienceWindow();
|
|
118321
118856
|
}
|
|
118322
118857
|
}, [isPresenterMode, closeAudienceWindow]);
|
|
118858
|
+
useEffect(() => {
|
|
118859
|
+
const handleBeforeUnload = () => {
|
|
118860
|
+
void clearAudienceContent();
|
|
118861
|
+
};
|
|
118862
|
+
window.addEventListener("beforeunload", handleBeforeUnload);
|
|
118863
|
+
return () => window.removeEventListener("beforeunload", handleBeforeUnload);
|
|
118864
|
+
}, []);
|
|
118323
118865
|
return {
|
|
118324
118866
|
openAudienceWindow,
|
|
118325
118867
|
closeAudienceWindow,
|
|
@@ -118357,6 +118899,7 @@ function useAudienceMode(input) {
|
|
|
118357
118899
|
if (!isAudienceTab()) {
|
|
118358
118900
|
return;
|
|
118359
118901
|
}
|
|
118902
|
+
const expectedSessionId = parseAudienceNonce();
|
|
118360
118903
|
let channel;
|
|
118361
118904
|
try {
|
|
118362
118905
|
channel = new BroadcastChannel(PRESENTER_CHANNEL_NAME);
|
|
@@ -118368,6 +118911,9 @@ function useAudienceMode(input) {
|
|
|
118368
118911
|
if (!data || data.origin !== PRESENTER_MSG_ORIGIN) {
|
|
118369
118912
|
return;
|
|
118370
118913
|
}
|
|
118914
|
+
if (expectedSessionId && data.sessionId !== expectedSessionId) {
|
|
118915
|
+
return;
|
|
118916
|
+
}
|
|
118371
118917
|
if (data.type === "presenter-slide-change") {
|
|
118372
118918
|
onSetActiveSlideIndex(data.slideIndex);
|
|
118373
118919
|
}
|
|
@@ -119301,6 +119847,12 @@ function useTouchGestures(input) {
|
|
|
119301
119847
|
callbacksRef.current = callbacks;
|
|
119302
119848
|
const scaleRef = useRef(currentScale);
|
|
119303
119849
|
scaleRef.current = currentScale;
|
|
119850
|
+
const [targetVersion, setTargetVersion] = useState(0);
|
|
119851
|
+
const lastTargetRef = useRef(null);
|
|
119852
|
+
if (targetRef.current !== lastTargetRef.current) {
|
|
119853
|
+
lastTargetRef.current = targetRef.current;
|
|
119854
|
+
queueMicrotask(() => setTargetVersion((v) => v + 1));
|
|
119855
|
+
}
|
|
119304
119856
|
useEffect(() => {
|
|
119305
119857
|
const el = targetRef.current;
|
|
119306
119858
|
if (!el || !enabled) {
|
|
@@ -119389,7 +119941,7 @@ function useTouchGestures(input) {
|
|
|
119389
119941
|
el.removeEventListener("touchcancel", handleTouchCancel);
|
|
119390
119942
|
cancelLongPress();
|
|
119391
119943
|
};
|
|
119392
|
-
}, [targetRef, enabled]);
|
|
119944
|
+
}, [targetRef, enabled, targetVersion]);
|
|
119393
119945
|
}
|
|
119394
119946
|
|
|
119395
119947
|
// src/viewer/utils/dom-helpers.ts
|
|
@@ -119410,11 +119962,31 @@ function safeConfirm(message) {
|
|
|
119410
119962
|
return false;
|
|
119411
119963
|
}
|
|
119412
119964
|
}
|
|
119965
|
+
function sanitizeDownloadFilename(input) {
|
|
119966
|
+
if (typeof input !== "string" || input.trim().length === 0) {
|
|
119967
|
+
return "presentation.pptx";
|
|
119968
|
+
}
|
|
119969
|
+
let cleaned = input.replace(/[\x00-\x1f\x7f"\\/:*?<>|]/g, "_").replace(/\.\./g, "__").replace(/^\.+/, "").trim();
|
|
119970
|
+
if (cleaned.length === 0) {
|
|
119971
|
+
return "presentation.pptx";
|
|
119972
|
+
}
|
|
119973
|
+
if (cleaned.length > 200) {
|
|
119974
|
+
const dot = cleaned.lastIndexOf(".");
|
|
119975
|
+
if (dot > 0 && cleaned.length - dot <= 16) {
|
|
119976
|
+
const ext = cleaned.slice(dot);
|
|
119977
|
+
cleaned = cleaned.slice(0, 200 - ext.length) + ext;
|
|
119978
|
+
} else {
|
|
119979
|
+
cleaned = cleaned.slice(0, 200);
|
|
119980
|
+
}
|
|
119981
|
+
}
|
|
119982
|
+
return cleaned;
|
|
119983
|
+
}
|
|
119413
119984
|
function downloadBlob(blob, filename) {
|
|
119985
|
+
const safeName = sanitizeDownloadFilename(filename);
|
|
119414
119986
|
const url = URL.createObjectURL(blob);
|
|
119415
119987
|
const a2 = document.createElement("a");
|
|
119416
119988
|
a2.href = url;
|
|
119417
|
-
a2.download =
|
|
119989
|
+
a2.download = safeName;
|
|
119418
119990
|
document.body.appendChild(a2);
|
|
119419
119991
|
a2.click();
|
|
119420
119992
|
setTimeout(() => {
|
|
@@ -119845,27 +120417,82 @@ function openAutosaveDb2() {
|
|
|
119845
120417
|
req.onerror = () => reject(req.error);
|
|
119846
120418
|
});
|
|
119847
120419
|
}
|
|
119848
|
-
async function
|
|
120420
|
+
async function deleteOldestAutosaveEntry() {
|
|
119849
120421
|
const db = await openAutosaveDb2();
|
|
119850
|
-
return new Promise((resolve2
|
|
119851
|
-
|
|
119852
|
-
|
|
119853
|
-
|
|
119854
|
-
|
|
119855
|
-
|
|
119856
|
-
|
|
119857
|
-
|
|
119858
|
-
|
|
119859
|
-
|
|
119860
|
-
|
|
119861
|
-
|
|
119862
|
-
|
|
119863
|
-
|
|
119864
|
-
|
|
119865
|
-
|
|
119866
|
-
|
|
120422
|
+
return new Promise((resolve2) => {
|
|
120423
|
+
try {
|
|
120424
|
+
const tx = db.transaction(STORE_NAME3, "readwrite");
|
|
120425
|
+
const store = tx.objectStore(STORE_NAME3);
|
|
120426
|
+
let oldestKey = null;
|
|
120427
|
+
let oldestTimestamp = Infinity;
|
|
120428
|
+
const cursorReq = store.openCursor();
|
|
120429
|
+
cursorReq.onsuccess = () => {
|
|
120430
|
+
const cursor = cursorReq.result;
|
|
120431
|
+
if (cursor) {
|
|
120432
|
+
const value = cursor.value;
|
|
120433
|
+
if (typeof value.timestamp === "number" && value.timestamp < oldestTimestamp) {
|
|
120434
|
+
oldestTimestamp = value.timestamp;
|
|
120435
|
+
oldestKey = cursor.primaryKey;
|
|
120436
|
+
}
|
|
120437
|
+
cursor.continue();
|
|
120438
|
+
} else if (oldestKey !== null) {
|
|
120439
|
+
store.delete(oldestKey);
|
|
120440
|
+
}
|
|
120441
|
+
};
|
|
120442
|
+
tx.oncomplete = () => {
|
|
120443
|
+
db.close();
|
|
120444
|
+
resolve2(oldestKey !== null);
|
|
120445
|
+
};
|
|
120446
|
+
tx.onerror = () => {
|
|
120447
|
+
db.close();
|
|
120448
|
+
resolve2(false);
|
|
120449
|
+
};
|
|
120450
|
+
} catch {
|
|
120451
|
+
try {
|
|
120452
|
+
db.close();
|
|
120453
|
+
} catch {
|
|
120454
|
+
}
|
|
120455
|
+
resolve2(false);
|
|
120456
|
+
}
|
|
119867
120457
|
});
|
|
119868
120458
|
}
|
|
120459
|
+
function putAutosaveRecord(filePath, data) {
|
|
120460
|
+
return openAutosaveDb2().then(
|
|
120461
|
+
(db) => new Promise((resolve2, reject) => {
|
|
120462
|
+
const tx = db.transaction(STORE_NAME3, "readwrite");
|
|
120463
|
+
const store = tx.objectStore(STORE_NAME3);
|
|
120464
|
+
store.put({
|
|
120465
|
+
key: filePath,
|
|
120466
|
+
data,
|
|
120467
|
+
timestamp: Date.now(),
|
|
120468
|
+
size: data.byteLength
|
|
120469
|
+
});
|
|
120470
|
+
tx.oncomplete = () => {
|
|
120471
|
+
db.close();
|
|
120472
|
+
resolve2(true);
|
|
120473
|
+
};
|
|
120474
|
+
tx.onerror = () => {
|
|
120475
|
+
db.close();
|
|
120476
|
+
reject(tx.error);
|
|
120477
|
+
};
|
|
120478
|
+
})
|
|
120479
|
+
);
|
|
120480
|
+
}
|
|
120481
|
+
async function saveToIndexedDb(filePath, data) {
|
|
120482
|
+
try {
|
|
120483
|
+
return await putAutosaveRecord(filePath, data);
|
|
120484
|
+
} catch (err) {
|
|
120485
|
+
const errName = err instanceof Error || err instanceof DOMException ? err.name : "";
|
|
120486
|
+
if (errName !== "QuotaExceededError") {
|
|
120487
|
+
throw err;
|
|
120488
|
+
}
|
|
120489
|
+
const deleted = await deleteOldestAutosaveEntry();
|
|
120490
|
+
if (!deleted) {
|
|
120491
|
+
throw err;
|
|
120492
|
+
}
|
|
120493
|
+
return putAutosaveRecord(filePath, data);
|
|
120494
|
+
}
|
|
120495
|
+
}
|
|
119869
120496
|
function useAutosave(input) {
|
|
119870
120497
|
const {
|
|
119871
120498
|
isDirty,
|
|
@@ -119982,6 +120609,25 @@ function collectReferencedFontFamilies(slides) {
|
|
|
119982
120609
|
}
|
|
119983
120610
|
return families;
|
|
119984
120611
|
}
|
|
120612
|
+
var FONT_NAME_UNSAFE_CHARS = /["\\\n\r;}<>]/;
|
|
120613
|
+
var FONT_FORMAT_ALLOWED = /* @__PURE__ */ new Set([
|
|
120614
|
+
"truetype",
|
|
120615
|
+
"opentype",
|
|
120616
|
+
"woff",
|
|
120617
|
+
"woff2",
|
|
120618
|
+
"svg",
|
|
120619
|
+
"embedded-opentype"
|
|
120620
|
+
]);
|
|
120621
|
+
var FONT_DATA_URL_PATTERN = /^data:font\/[a-z0-9+.-]+(?:;charset=[a-z0-9-]+)?;base64,[A-Za-z0-9+/=]+$/i;
|
|
120622
|
+
function isFontDataUrlSafe(url) {
|
|
120623
|
+
if (typeof url !== "string" || url.length === 0) {
|
|
120624
|
+
return false;
|
|
120625
|
+
}
|
|
120626
|
+
if (url.startsWith("blob:")) {
|
|
120627
|
+
return true;
|
|
120628
|
+
}
|
|
120629
|
+
return FONT_DATA_URL_PATTERN.test(url);
|
|
120630
|
+
}
|
|
119985
120631
|
function useFontInjection({ embeddedFonts, slides }) {
|
|
119986
120632
|
useEffect(() => {
|
|
119987
120633
|
if (!embeddedFonts.length) {
|
|
@@ -119989,17 +120635,28 @@ function useFontInjection({ embeddedFonts, slides }) {
|
|
|
119989
120635
|
}
|
|
119990
120636
|
const styleEl = document.createElement("style");
|
|
119991
120637
|
styleEl.id = EMBEDDED_FONTS_STYLE_ID;
|
|
119992
|
-
const cssRules = embeddedFonts.
|
|
120638
|
+
const cssRules = embeddedFonts.flatMap((font) => {
|
|
120639
|
+
if (typeof font.name !== "string" || font.name.length === 0 || FONT_NAME_UNSAFE_CHARS.test(font.name)) {
|
|
120640
|
+
return [];
|
|
120641
|
+
}
|
|
120642
|
+
if (!isFontDataUrlSafe(font.dataUrl)) {
|
|
120643
|
+
return [];
|
|
120644
|
+
}
|
|
120645
|
+
const fontFormat = font.format ?? "truetype";
|
|
120646
|
+
if (!FONT_FORMAT_ALLOWED.has(fontFormat)) {
|
|
120647
|
+
return [];
|
|
120648
|
+
}
|
|
119993
120649
|
const fontWeight = font.bold ? "700" : "400";
|
|
119994
120650
|
const fontStyleCss = font.italic ? "italic" : "normal";
|
|
119995
|
-
|
|
119996
|
-
|
|
120651
|
+
return [
|
|
120652
|
+
`@font-face {
|
|
119997
120653
|
font-family: "${font.name}";
|
|
119998
120654
|
src: url("${font.dataUrl}") format("${fontFormat}");
|
|
119999
120655
|
font-weight: ${fontWeight};
|
|
120000
120656
|
font-style: ${fontStyleCss};
|
|
120001
120657
|
font-display: swap;
|
|
120002
|
-
}
|
|
120658
|
+
}`
|
|
120659
|
+
];
|
|
120003
120660
|
}).join("\n");
|
|
120004
120661
|
styleEl.textContent = cssRules;
|
|
120005
120662
|
document.head.appendChild(styleEl);
|
|
@@ -120028,7 +120685,7 @@ function useFontInjection({ embeddedFonts, slides }) {
|
|
|
120028
120685
|
const linkEl = document.createElement("link");
|
|
120029
120686
|
linkEl.id = GOOGLE_FONTS_LINK_ID;
|
|
120030
120687
|
linkEl.rel = "stylesheet";
|
|
120031
|
-
linkEl.href = `https://fonts.googleapis.com/css2?${googleFamilies.map((f) => `family=${GOOGLE_FONTS_AVAILABLE[f]}`).join("&")}&display=swap`;
|
|
120688
|
+
linkEl.href = `https://fonts.googleapis.com/css2?${googleFamilies.map((f) => `family=${encodeURIComponent(GOOGLE_FONTS_AVAILABLE[f])}`).join("&")}&display=swap`;
|
|
120032
120689
|
document.head.appendChild(linkEl);
|
|
120033
120690
|
return () => {
|
|
120034
120691
|
const existing = document.getElementById(GOOGLE_FONTS_LINK_ID);
|
|
@@ -120044,13 +120701,18 @@ function useFontInjection({ embeddedFonts, slides }) {
|
|
|
120044
120701
|
}
|
|
120045
120702
|
const styleEl = document.createElement("style");
|
|
120046
120703
|
styleEl.id = SYMBOL_FONTS_STYLE_ID;
|
|
120047
|
-
const rules = neededSymbolFonts.
|
|
120048
|
-
(font
|
|
120704
|
+
const rules = neededSymbolFonts.flatMap((font) => {
|
|
120705
|
+
if (typeof font !== "string" || FONT_NAME_UNSAFE_CHARS.test(font)) {
|
|
120706
|
+
return [];
|
|
120707
|
+
}
|
|
120708
|
+
return [
|
|
120709
|
+
`@font-face {
|
|
120049
120710
|
font-family: "${font}";
|
|
120050
120711
|
src: local("${font}"), local("${font} Regular");
|
|
120051
120712
|
font-display: swap;
|
|
120052
120713
|
}`
|
|
120053
|
-
|
|
120714
|
+
];
|
|
120715
|
+
}).join("\n");
|
|
120054
120716
|
styleEl.textContent = rules;
|
|
120055
120717
|
document.head.appendChild(styleEl);
|
|
120056
120718
|
return () => {
|
|
@@ -120193,16 +120855,17 @@ function useLoadContent({
|
|
|
120193
120855
|
`[pptx] Large file detected (${fileSizeMB.toFixed(1)} MB). Loading may use significant memory.`
|
|
120194
120856
|
);
|
|
120195
120857
|
}
|
|
120196
|
-
|
|
120197
|
-
handlerRef.current.dispose();
|
|
120198
|
-
handlerRef.current = null;
|
|
120199
|
-
}
|
|
120858
|
+
const previousHandler = handlerRef.current;
|
|
120200
120859
|
const handler = new PptxHandler();
|
|
120201
120860
|
const parsed = await handler.load(buffer);
|
|
120202
120861
|
if (cancelled || token !== renderTokenRef.current) {
|
|
120203
120862
|
handler.dispose();
|
|
120204
120863
|
return;
|
|
120205
120864
|
}
|
|
120865
|
+
if (previousHandler) {
|
|
120866
|
+
previousHandler.dispose();
|
|
120867
|
+
}
|
|
120868
|
+
handlerRef.current = null;
|
|
120206
120869
|
const mediaElements = [];
|
|
120207
120870
|
for (const slide of parsed.slides) {
|
|
120208
120871
|
collectMediaElements(slide.elements, mediaElements);
|
|
@@ -120247,6 +120910,7 @@ function useLoadContent({
|
|
|
120247
120910
|
})
|
|
120248
120911
|
);
|
|
120249
120912
|
const { paths: imagePaths, refs: imageRefs } = collectImagePaths(parsed.slides);
|
|
120913
|
+
let nextSlides = parsed.slides;
|
|
120250
120914
|
if (imagePaths.size > 0) {
|
|
120251
120915
|
const resolvedMap = /* @__PURE__ */ new Map();
|
|
120252
120916
|
await Promise.all(
|
|
@@ -120260,15 +120924,47 @@ function useLoadContent({
|
|
|
120260
120924
|
}
|
|
120261
120925
|
})
|
|
120262
120926
|
);
|
|
120927
|
+
const elementPatches = /* @__PURE__ */ new Map();
|
|
120263
120928
|
for (const ref of imageRefs) {
|
|
120264
120929
|
const url = resolvedMap.get(ref.path);
|
|
120265
|
-
if (url) {
|
|
120266
|
-
|
|
120930
|
+
if (!url) {
|
|
120931
|
+
continue;
|
|
120267
120932
|
}
|
|
120933
|
+
const id2 = ref.element.id;
|
|
120934
|
+
const existing = elementPatches.get(id2) ?? {};
|
|
120935
|
+
existing[ref.field] = url;
|
|
120936
|
+
elementPatches.set(id2, existing);
|
|
120937
|
+
}
|
|
120938
|
+
if (elementPatches.size > 0) {
|
|
120939
|
+
const patchElements = (elements) => {
|
|
120940
|
+
let mutated = false;
|
|
120941
|
+
const next = elements.map((el) => {
|
|
120942
|
+
let updated = el;
|
|
120943
|
+
const patch = elementPatches.get(el.id);
|
|
120944
|
+
if (patch) {
|
|
120945
|
+
updated = { ...el, ...patch };
|
|
120946
|
+
}
|
|
120947
|
+
if (updated.type === "group" && updated.children?.length) {
|
|
120948
|
+
const newChildren = patchElements(updated.children);
|
|
120949
|
+
if (newChildren !== updated.children) {
|
|
120950
|
+
updated = { ...updated, children: newChildren };
|
|
120951
|
+
}
|
|
120952
|
+
}
|
|
120953
|
+
if (updated !== el) {
|
|
120954
|
+
mutated = true;
|
|
120955
|
+
}
|
|
120956
|
+
return updated;
|
|
120957
|
+
});
|
|
120958
|
+
return mutated ? next : elements;
|
|
120959
|
+
};
|
|
120960
|
+
nextSlides = parsed.slides.map((s) => {
|
|
120961
|
+
const newElements = patchElements(s.elements);
|
|
120962
|
+
return newElements === s.elements ? s : { ...s, elements: newElements };
|
|
120963
|
+
});
|
|
120268
120964
|
}
|
|
120269
120965
|
}
|
|
120270
120966
|
handlerRef.current = handler;
|
|
120271
|
-
setSlides(
|
|
120967
|
+
setSlides(nextSlides);
|
|
120272
120968
|
setTemplateElementsBySlideId({});
|
|
120273
120969
|
setCanvasSize({
|
|
120274
120970
|
width: parsed.width ?? DEFAULT_CANVAS_WIDTH,
|
|
@@ -121442,7 +122138,19 @@ function injectFontFaces(svg, fontFaces) {
|
|
|
121442
122138
|
if (!fontFaces.length) {
|
|
121443
122139
|
return svg;
|
|
121444
122140
|
}
|
|
121445
|
-
const
|
|
122141
|
+
const safeFontFaces = fontFaces.filter((f) => {
|
|
122142
|
+
if (f.css.toLowerCase().includes("</style")) {
|
|
122143
|
+
console.warn(
|
|
122144
|
+
`[export-svg] Dropping @font-face entry for "${f.family}" containing "</style" \u2014 would break out of the <style> block.`
|
|
122145
|
+
);
|
|
122146
|
+
return false;
|
|
122147
|
+
}
|
|
122148
|
+
return true;
|
|
122149
|
+
});
|
|
122150
|
+
if (!safeFontFaces.length) {
|
|
122151
|
+
return svg;
|
|
122152
|
+
}
|
|
122153
|
+
const styleBlock = `<style type="text/css">${safeFontFaces.map((f) => f.css).join("\n")}</style>`;
|
|
121446
122154
|
if (svg.includes("<defs>")) {
|
|
121447
122155
|
return svg.replace("<defs>", `<defs>${styleBlock}`);
|
|
121448
122156
|
}
|
|
@@ -121768,7 +122476,7 @@ function useExportHandlers(input) {
|
|
|
121768
122476
|
activeSlideIndexForGuides,
|
|
121769
122477
|
modalControls
|
|
121770
122478
|
});
|
|
121771
|
-
const handleExportPng = async () => {
|
|
122479
|
+
const handleExportPng = useCallback(async () => {
|
|
121772
122480
|
const stageEl = canvasStageRef.current;
|
|
121773
122481
|
if (!stageEl) {
|
|
121774
122482
|
return;
|
|
@@ -121780,8 +122488,8 @@ function useExportHandlers(input) {
|
|
|
121780
122488
|
} catch (err) {
|
|
121781
122489
|
console.error("[PowerPointViewer] PNG export failed:", err);
|
|
121782
122490
|
}
|
|
121783
|
-
};
|
|
121784
|
-
const handleExportPdf = async () => {
|
|
122491
|
+
}, [canvasStageRef, activeSlideIndex, activeSlide?.backgroundColor]);
|
|
122492
|
+
const handleExportPdf = useCallback(async () => {
|
|
121785
122493
|
if (!canvasStageRef.current) {
|
|
121786
122494
|
return;
|
|
121787
122495
|
}
|
|
@@ -121822,8 +122530,8 @@ function useExportHandlers(input) {
|
|
|
121822
122530
|
exportAbortRef.current = null;
|
|
121823
122531
|
setExportModalOpen(false);
|
|
121824
122532
|
}
|
|
121825
|
-
};
|
|
121826
|
-
const handleExportNotesPdf = async () => {
|
|
122533
|
+
}, [canvasStageRef, slides.length, setActiveSlideIndex, activeSlideIndex]);
|
|
122534
|
+
const handleExportNotesPdf = useCallback(async () => {
|
|
121827
122535
|
if (!canvasStageRef.current) {
|
|
121828
122536
|
return;
|
|
121829
122537
|
}
|
|
@@ -121866,8 +122574,8 @@ function useExportHandlers(input) {
|
|
|
121866
122574
|
exportAbortRef.current = null;
|
|
121867
122575
|
setExportModalOpen(false);
|
|
121868
122576
|
}
|
|
121869
|
-
};
|
|
121870
|
-
const handleCopySlideAsImage = async () => {
|
|
122577
|
+
}, [canvasStageRef, slides, setActiveSlideIndex, activeSlideIndex]);
|
|
122578
|
+
const handleCopySlideAsImage = useCallback(async () => {
|
|
121871
122579
|
const stageEl = canvasStageRef.current;
|
|
121872
122580
|
if (!stageEl) {
|
|
121873
122581
|
return;
|
|
@@ -121879,8 +122587,8 @@ function useExportHandlers(input) {
|
|
|
121879
122587
|
} catch (err) {
|
|
121880
122588
|
console.error("[PowerPointViewer] Copy slide as image failed:", err);
|
|
121881
122589
|
}
|
|
121882
|
-
};
|
|
121883
|
-
const handleExportVideo = async () => {
|
|
122590
|
+
}, [canvasStageRef, activeSlide?.backgroundColor]);
|
|
122591
|
+
const handleExportVideo = useCallback(async () => {
|
|
121884
122592
|
if (!canvasStageRef.current) {
|
|
121885
122593
|
return;
|
|
121886
122594
|
}
|
|
@@ -121922,8 +122630,8 @@ function useExportHandlers(input) {
|
|
|
121922
122630
|
exportAbortRef.current = null;
|
|
121923
122631
|
setExportModalOpen(false);
|
|
121924
122632
|
}
|
|
121925
|
-
};
|
|
121926
|
-
const handleExportGif = async () => {
|
|
122633
|
+
}, [canvasStageRef, slides.length, setActiveSlideIndex, activeSlideIndex]);
|
|
122634
|
+
const handleExportGif = useCallback(async () => {
|
|
121927
122635
|
if (!canvasStageRef.current) {
|
|
121928
122636
|
return;
|
|
121929
122637
|
}
|
|
@@ -121961,7 +122669,7 @@ function useExportHandlers(input) {
|
|
|
121961
122669
|
exportAbortRef.current = null;
|
|
121962
122670
|
setExportModalOpen(false);
|
|
121963
122671
|
}
|
|
121964
|
-
};
|
|
122672
|
+
}, [canvasStageRef, slides.length, setActiveSlideIndex, activeSlideIndex]);
|
|
121965
122673
|
const handleCancelExport = useCallback(() => {
|
|
121966
122674
|
exportAbortRef.current?.abort();
|
|
121967
122675
|
exportAbortRef.current = null;
|
|
@@ -121987,6 +122695,15 @@ function useExportHandlers(input) {
|
|
|
121987
122695
|
exportStatusMessage
|
|
121988
122696
|
};
|
|
121989
122697
|
}
|
|
122698
|
+
function escapeHtmlAttr(value) {
|
|
122699
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
122700
|
+
}
|
|
122701
|
+
function safeDataImageSrc(src) {
|
|
122702
|
+
if (typeof src !== "string" || !src.startsWith("data:image/")) {
|
|
122703
|
+
return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNgAAIAAAUAAen63NgAAAAASUVORK5CYII=";
|
|
122704
|
+
}
|
|
122705
|
+
return escapeHtmlAttr(src);
|
|
122706
|
+
}
|
|
121990
122707
|
function openPrintWindow(title, bodyHtml, orientation, colorFilter, frameSlides) {
|
|
121991
122708
|
const printWindow = window.open("", "_blank", "noopener,noreferrer");
|
|
121992
122709
|
if (!printWindow) {
|
|
@@ -122169,7 +122886,7 @@ function usePrintHandlers(input) {
|
|
|
122169
122886
|
const slideImages = slideIndices.map((idx) => allImages[idx]).filter(Boolean);
|
|
122170
122887
|
if (settings.printWhat === "slides") {
|
|
122171
122888
|
const bodyHtml = slideImages.map(
|
|
122172
|
-
(img, i3) => `<section class="page slide-page"><img class="slide-img" src="${img}" alt="Slide ${slideIndices[i3] + 1}" /></section>`
|
|
122889
|
+
(img, i3) => `<section class="page slide-page"><img class="slide-img" src="${safeDataImageSrc(img)}" alt="Slide ${slideIndices[i3] + 1}" /></section>`
|
|
122173
122890
|
).join("");
|
|
122174
122891
|
openPrintWindow(
|
|
122175
122892
|
"Slides",
|
|
@@ -122185,7 +122902,7 @@ function usePrintHandlers(input) {
|
|
|
122185
122902
|
const idx = slideIndices[i3];
|
|
122186
122903
|
const notes = slides[idx]?.notes?.trim() || "";
|
|
122187
122904
|
return `<section class="page notes-page">
|
|
122188
|
-
<img class="notes-slide" src="${img}" alt="Slide ${idx + 1}" />
|
|
122905
|
+
<img class="notes-slide" src="${safeDataImageSrc(img)}" alt="Slide ${idx + 1}" />
|
|
122189
122906
|
<div class="notes-text">${escapeHtml2(notes)}</div>
|
|
122190
122907
|
</section>`;
|
|
122191
122908
|
}).join("");
|
|
@@ -122217,14 +122934,14 @@ function usePrintHandlers(input) {
|
|
|
122217
122934
|
if (isThreePerPage) {
|
|
122218
122935
|
const rows = Array.from({ length: spp }, (_, cellIndex) => {
|
|
122219
122936
|
const img = pageImgs[cellIndex];
|
|
122220
|
-
const slideCell = img ? `<div class="handout-cell"><img src="${img}" alt="Slide ${slideIndices[i3 + cellIndex] + 1}" /></div>` : `<div class="handout-cell"></div>`;
|
|
122937
|
+
const slideCell = img ? `<div class="handout-cell"><img src="${safeDataImageSrc(img)}" alt="Slide ${slideIndices[i3 + cellIndex] + 1}" /></div>` : `<div class="handout-cell"></div>`;
|
|
122221
122938
|
return `<div class="handout-row-3">${slideCell}${buildNoteLines()}</div>`;
|
|
122222
122939
|
}).join("");
|
|
122223
122940
|
pages.push(`<section class="page"><div class="handout-grid-3">${rows}</div></section>`);
|
|
122224
122941
|
} else {
|
|
122225
122942
|
const cells = Array.from({ length: spp }, (_, cellIndex) => {
|
|
122226
122943
|
const img = pageImgs[cellIndex];
|
|
122227
|
-
return img ? `<div class="handout-cell"><img src="${img}" alt="Slide ${slideIndices[i3 + cellIndex] + 1}" /></div>` : `<div class="handout-cell"></div>`;
|
|
122944
|
+
return img ? `<div class="handout-cell"><img src="${safeDataImageSrc(img)}" alt="Slide ${slideIndices[i3 + cellIndex] + 1}" /></div>` : `<div class="handout-cell"></div>`;
|
|
122228
122945
|
}).join("");
|
|
122229
122946
|
pages.push(
|
|
122230
122947
|
`<section class="page"><div class="handout-grid" style="grid-template-columns: repeat(${grid.columns}, minmax(0, 1fr)); grid-template-rows: repeat(${grid.rows}, minmax(0, 1fr));">${cells}</div></section>`
|