pptx-react-viewer 1.1.5 → 1.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/{PowerPointViewer-CX0a7wz_.d.mts → PowerPointViewer-C5jGuKGB.d.mts} +3 -1
  2. package/dist/{PowerPointViewer-CX0a7wz_.d.ts → PowerPointViewer-C5jGuKGB.d.ts} +3 -1
  3. package/dist/index.d.mts +3 -2
  4. package/dist/index.d.ts +3 -2
  5. package/dist/index.js +1575 -515
  6. package/dist/index.mjs +1577 -517
  7. package/dist/pptx-viewer.css +1 -1
  8. package/dist/viewer/index.d.mts +6 -25
  9. package/dist/viewer/index.d.ts +6 -25
  10. package/dist/viewer/index.js +1575 -515
  11. package/dist/viewer/index.mjs +1577 -517
  12. package/node_modules/emf-converter/package.json +1 -1
  13. package/node_modules/mtx-decompressor/package.json +1 -1
  14. package/node_modules/pptx-viewer-core/dist/{SvgExporter-0TxiiorD.d.ts → SvgExporter-BtZczTlB.d.ts} +1 -1
  15. package/node_modules/pptx-viewer-core/dist/{SvgExporter-BQ4KbRO9.d.mts → SvgExporter-D4mBWJHE.d.mts} +1 -1
  16. package/node_modules/pptx-viewer-core/dist/cli/index.d.mts +2 -2
  17. package/node_modules/pptx-viewer-core/dist/cli/index.d.ts +2 -2
  18. package/node_modules/pptx-viewer-core/dist/cli/index.js +0 -0
  19. package/node_modules/pptx-viewer-core/dist/cli/index.mjs +0 -0
  20. package/node_modules/pptx-viewer-core/dist/converter/index.d.mts +3 -3
  21. package/node_modules/pptx-viewer-core/dist/converter/index.d.ts +3 -3
  22. package/node_modules/pptx-viewer-core/dist/converter/index.js +0 -0
  23. package/node_modules/pptx-viewer-core/dist/converter/index.mjs +0 -0
  24. package/node_modules/pptx-viewer-core/dist/index.d.mts +967 -60
  25. package/node_modules/pptx-viewer-core/dist/index.d.ts +967 -60
  26. package/node_modules/pptx-viewer-core/dist/index.js +29613 -16737
  27. package/node_modules/pptx-viewer-core/dist/index.mjs +29588 -16737
  28. package/node_modules/pptx-viewer-core/dist/{presentation-ArhfImJ5.d.mts → presentation-nZxgWvXq.d.mts} +875 -27
  29. package/node_modules/pptx-viewer-core/dist/{presentation-ArhfImJ5.d.ts → presentation-nZxgWvXq.d.ts} +875 -27
  30. package/node_modules/pptx-viewer-core/dist/{text-operations-CLj-sJyk.d.mts → text-operations-DCTGMltY.d.mts} +1 -1
  31. package/node_modules/pptx-viewer-core/dist/{text-operations-rhJV-A_W.d.ts → text-operations-DYmhoi7U.d.ts} +1 -1
  32. package/node_modules/pptx-viewer-core/package.json +1 -1
  33. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -198,7 +198,7 @@ function generateUUID() {
198
198
  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];
199
199
  return uuid.toLowerCase();
200
200
  }
201
- function clamp(value, min2, max2) {
201
+ function clamp2(value, min2, max2) {
202
202
  return Math.max(min2, Math.min(max2, value));
203
203
  }
204
204
  function euclideanModulo(n, m2) {
@@ -573,7 +573,7 @@ function _generateTables() {
573
573
  }
574
574
  function toHalfFloat(val2) {
575
575
  if (Math.abs(val2) > 65504) warn("DataUtils.toHalfFloat(): Value out of range.");
576
- val2 = clamp(val2, -65504, 65504);
576
+ val2 = clamp2(val2, -65504, 65504);
577
577
  _tables.floatView[0] = val2;
578
578
  const f = _tables.uint32View[0];
579
579
  const e2 = f >> 23 & 511;
@@ -2062,7 +2062,7 @@ var init_three_core = __esm({
2062
2062
  * @param {number} max - The max value.
2063
2063
  * @return {number} The clamped value.
2064
2064
  */
2065
- clamp,
2065
+ clamp: clamp2,
2066
2066
  /**
2067
2067
  * Computes the Euclidean modulo of the given parameters that
2068
2068
  * is `( ( n % m ) + m ) % m`.
@@ -2589,8 +2589,8 @@ var init_three_core = __esm({
2589
2589
  * @return {Vector2} A reference to this vector.
2590
2590
  */
2591
2591
  clamp(min2, max2) {
2592
- this.x = clamp(this.x, min2.x, max2.x);
2593
- this.y = clamp(this.y, min2.y, max2.y);
2592
+ this.x = clamp2(this.x, min2.x, max2.x);
2593
+ this.y = clamp2(this.y, min2.y, max2.y);
2594
2594
  return this;
2595
2595
  }
2596
2596
  /**
@@ -2604,8 +2604,8 @@ var init_three_core = __esm({
2604
2604
  * @return {Vector2} A reference to this vector.
2605
2605
  */
2606
2606
  clampScalar(minVal, maxVal) {
2607
- this.x = clamp(this.x, minVal, maxVal);
2608
- this.y = clamp(this.y, minVal, maxVal);
2607
+ this.x = clamp2(this.x, minVal, maxVal);
2608
+ this.y = clamp2(this.y, minVal, maxVal);
2609
2609
  return this;
2610
2610
  }
2611
2611
  /**
@@ -2620,7 +2620,7 @@ var init_three_core = __esm({
2620
2620
  */
2621
2621
  clampLength(min2, max2) {
2622
2622
  const length2 = this.length();
2623
- return this.divideScalar(length2 || 1).multiplyScalar(clamp(length2, min2, max2));
2623
+ return this.divideScalar(length2 || 1).multiplyScalar(clamp2(length2, min2, max2));
2624
2624
  }
2625
2625
  /**
2626
2626
  * The components of this vector are rounded down to the nearest integer value.
@@ -2745,7 +2745,7 @@ var init_three_core = __esm({
2745
2745
  const denominator = Math.sqrt(this.lengthSq() * v.lengthSq());
2746
2746
  if (denominator === 0) return Math.PI / 2;
2747
2747
  const theta = this.dot(v) / denominator;
2748
- return Math.acos(clamp(theta, -1, 1));
2748
+ return Math.acos(clamp2(theta, -1, 1));
2749
2749
  }
2750
2750
  /**
2751
2751
  * Computes the distance from the given vector to this instance.
@@ -3232,7 +3232,7 @@ var init_three_core = __esm({
3232
3232
  * @return {number} The angle in radians.
3233
3233
  */
3234
3234
  angleTo(q) {
3235
- return 2 * Math.acos(Math.abs(clamp(this.dot(q), -1, 1)));
3235
+ return 2 * Math.acos(Math.abs(clamp2(this.dot(q), -1, 1)));
3236
3236
  }
3237
3237
  /**
3238
3238
  * Rotates this quaternion by a given angular step to the given quaternion.
@@ -3938,9 +3938,9 @@ var init_three_core = __esm({
3938
3938
  * @return {Vector3} A reference to this vector.
3939
3939
  */
3940
3940
  clamp(min2, max2) {
3941
- this.x = clamp(this.x, min2.x, max2.x);
3942
- this.y = clamp(this.y, min2.y, max2.y);
3943
- this.z = clamp(this.z, min2.z, max2.z);
3941
+ this.x = clamp2(this.x, min2.x, max2.x);
3942
+ this.y = clamp2(this.y, min2.y, max2.y);
3943
+ this.z = clamp2(this.z, min2.z, max2.z);
3944
3944
  return this;
3945
3945
  }
3946
3946
  /**
@@ -3954,9 +3954,9 @@ var init_three_core = __esm({
3954
3954
  * @return {Vector3} A reference to this vector.
3955
3955
  */
3956
3956
  clampScalar(minVal, maxVal) {
3957
- this.x = clamp(this.x, minVal, maxVal);
3958
- this.y = clamp(this.y, minVal, maxVal);
3959
- this.z = clamp(this.z, minVal, maxVal);
3957
+ this.x = clamp2(this.x, minVal, maxVal);
3958
+ this.y = clamp2(this.y, minVal, maxVal);
3959
+ this.z = clamp2(this.z, minVal, maxVal);
3960
3960
  return this;
3961
3961
  }
3962
3962
  /**
@@ -3971,7 +3971,7 @@ var init_three_core = __esm({
3971
3971
  */
3972
3972
  clampLength(min2, max2) {
3973
3973
  const length2 = this.length();
3974
- return this.divideScalar(length2 || 1).multiplyScalar(clamp(length2, min2, max2));
3974
+ return this.divideScalar(length2 || 1).multiplyScalar(clamp2(length2, min2, max2));
3975
3975
  }
3976
3976
  /**
3977
3977
  * The components of this vector are rounded down to the nearest integer value.
@@ -4181,7 +4181,7 @@ var init_three_core = __esm({
4181
4181
  const denominator = Math.sqrt(this.lengthSq() * v.lengthSq());
4182
4182
  if (denominator === 0) return Math.PI / 2;
4183
4183
  const theta = this.dot(v) / denominator;
4184
- return Math.acos(clamp(theta, -1, 1));
4184
+ return Math.acos(clamp2(theta, -1, 1));
4185
4185
  }
4186
4186
  /**
4187
4187
  * Computes the distance from the given vector to this instance.
@@ -5870,10 +5870,10 @@ var init_three_core = __esm({
5870
5870
  * @return {Vector4} A reference to this vector.
5871
5871
  */
5872
5872
  clamp(min2, max2) {
5873
- this.x = clamp(this.x, min2.x, max2.x);
5874
- this.y = clamp(this.y, min2.y, max2.y);
5875
- this.z = clamp(this.z, min2.z, max2.z);
5876
- this.w = clamp(this.w, min2.w, max2.w);
5873
+ this.x = clamp2(this.x, min2.x, max2.x);
5874
+ this.y = clamp2(this.y, min2.y, max2.y);
5875
+ this.z = clamp2(this.z, min2.z, max2.z);
5876
+ this.w = clamp2(this.w, min2.w, max2.w);
5877
5877
  return this;
5878
5878
  }
5879
5879
  /**
@@ -5887,10 +5887,10 @@ var init_three_core = __esm({
5887
5887
  * @return {Vector4} A reference to this vector.
5888
5888
  */
5889
5889
  clampScalar(minVal, maxVal) {
5890
- this.x = clamp(this.x, minVal, maxVal);
5891
- this.y = clamp(this.y, minVal, maxVal);
5892
- this.z = clamp(this.z, minVal, maxVal);
5893
- this.w = clamp(this.w, minVal, maxVal);
5890
+ this.x = clamp2(this.x, minVal, maxVal);
5891
+ this.y = clamp2(this.y, minVal, maxVal);
5892
+ this.z = clamp2(this.z, minVal, maxVal);
5893
+ this.w = clamp2(this.w, minVal, maxVal);
5894
5894
  return this;
5895
5895
  }
5896
5896
  /**
@@ -5905,7 +5905,7 @@ var init_three_core = __esm({
5905
5905
  */
5906
5906
  clampLength(min2, max2) {
5907
5907
  const length2 = this.length();
5908
- return this.divideScalar(length2 || 1).multiplyScalar(clamp(length2, min2, max2));
5908
+ return this.divideScalar(length2 || 1).multiplyScalar(clamp2(length2, min2, max2));
5909
5909
  }
5910
5910
  /**
5911
5911
  * The components of this vector are rounded down to the nearest integer value.
@@ -7688,7 +7688,7 @@ var init_three_core = __esm({
7688
7688
  const m31 = te[2], m32 = te[6], m33 = te[10];
7689
7689
  switch (order) {
7690
7690
  case "XYZ":
7691
- this._y = Math.asin(clamp(m13, -1, 1));
7691
+ this._y = Math.asin(clamp2(m13, -1, 1));
7692
7692
  if (Math.abs(m13) < 0.9999999) {
7693
7693
  this._x = Math.atan2(-m23, m33);
7694
7694
  this._z = Math.atan2(-m12, m11);
@@ -7698,7 +7698,7 @@ var init_three_core = __esm({
7698
7698
  }
7699
7699
  break;
7700
7700
  case "YXZ":
7701
- this._x = Math.asin(-clamp(m23, -1, 1));
7701
+ this._x = Math.asin(-clamp2(m23, -1, 1));
7702
7702
  if (Math.abs(m23) < 0.9999999) {
7703
7703
  this._y = Math.atan2(m13, m33);
7704
7704
  this._z = Math.atan2(m21, m22);
@@ -7708,7 +7708,7 @@ var init_three_core = __esm({
7708
7708
  }
7709
7709
  break;
7710
7710
  case "ZXY":
7711
- this._x = Math.asin(clamp(m32, -1, 1));
7711
+ this._x = Math.asin(clamp2(m32, -1, 1));
7712
7712
  if (Math.abs(m32) < 0.9999999) {
7713
7713
  this._y = Math.atan2(-m31, m33);
7714
7714
  this._z = Math.atan2(-m12, m22);
@@ -7718,7 +7718,7 @@ var init_three_core = __esm({
7718
7718
  }
7719
7719
  break;
7720
7720
  case "ZYX":
7721
- this._y = Math.asin(-clamp(m31, -1, 1));
7721
+ this._y = Math.asin(-clamp2(m31, -1, 1));
7722
7722
  if (Math.abs(m31) < 0.9999999) {
7723
7723
  this._x = Math.atan2(m32, m33);
7724
7724
  this._z = Math.atan2(m21, m11);
@@ -7728,7 +7728,7 @@ var init_three_core = __esm({
7728
7728
  }
7729
7729
  break;
7730
7730
  case "YZX":
7731
- this._z = Math.asin(clamp(m21, -1, 1));
7731
+ this._z = Math.asin(clamp2(m21, -1, 1));
7732
7732
  if (Math.abs(m21) < 0.9999999) {
7733
7733
  this._x = Math.atan2(-m23, m22);
7734
7734
  this._y = Math.atan2(-m31, m11);
@@ -7738,7 +7738,7 @@ var init_three_core = __esm({
7738
7738
  }
7739
7739
  break;
7740
7740
  case "XZY":
7741
- this._z = Math.asin(-clamp(m12, -1, 1));
7741
+ this._z = Math.asin(-clamp2(m12, -1, 1));
7742
7742
  if (Math.abs(m12) < 0.9999999) {
7743
7743
  this._x = Math.atan2(m32, m22);
7744
7744
  this._y = Math.atan2(m13, m11);
@@ -9362,8 +9362,8 @@ var init_three_core = __esm({
9362
9362
  */
9363
9363
  setHSL(h2, s, l2, colorSpace = ColorManagement.workingColorSpace) {
9364
9364
  h2 = euclideanModulo(h2, 1);
9365
- s = clamp(s, 0, 1);
9366
- l2 = clamp(l2, 0, 1);
9365
+ s = clamp2(s, 0, 1);
9366
+ l2 = clamp2(l2, 0, 1);
9367
9367
  if (s === 0) {
9368
9368
  this.r = this.g = this.b = l2;
9369
9369
  } else {
@@ -9549,7 +9549,7 @@ var init_three_core = __esm({
9549
9549
  */
9550
9550
  getHex(colorSpace = SRGBColorSpace) {
9551
9551
  ColorManagement.workingToColorSpace(_color.copy(this), colorSpace);
9552
- return Math.round(clamp(_color.r * 255, 0, 255)) * 65536 + Math.round(clamp(_color.g * 255, 0, 255)) * 256 + Math.round(clamp(_color.b * 255, 0, 255));
9552
+ 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));
9553
9553
  }
9554
9554
  /**
9555
9555
  * Returns the hexadecimal value of this color as a string (for example, 'FFFFFF').
@@ -18480,13 +18480,13 @@ var init_three_core = __esm({
18480
18480
  vec.crossVectors(tangents[i3 - 1], tangents[i3]);
18481
18481
  if (vec.length() > Number.EPSILON) {
18482
18482
  vec.normalize();
18483
- const theta = Math.acos(clamp(tangents[i3 - 1].dot(tangents[i3]), -1, 1));
18483
+ const theta = Math.acos(clamp2(tangents[i3 - 1].dot(tangents[i3]), -1, 1));
18484
18484
  normals[i3].applyMatrix4(mat.makeRotationAxis(vec, theta));
18485
18485
  }
18486
18486
  binormals[i3].crossVectors(tangents[i3], normals[i3]);
18487
18487
  }
18488
18488
  if (closed === true) {
18489
- let theta = Math.acos(clamp(normals[0].dot(normals[segments]), -1, 1));
18489
+ let theta = Math.acos(clamp2(normals[0].dot(normals[segments]), -1, 1));
18490
18490
  theta /= segments;
18491
18491
  if (tangents[0].dot(vec.crossVectors(normals[0], normals[segments])) > 0) {
18492
18492
  theta = -theta;
@@ -20275,7 +20275,7 @@ var init_three_core = __esm({
20275
20275
  phiLength
20276
20276
  };
20277
20277
  segments = Math.floor(segments);
20278
- phiLength = clamp(phiLength, 0, Math.PI * 2);
20278
+ phiLength = clamp2(phiLength, 0, Math.PI * 2);
20279
20279
  const indices = [];
20280
20280
  const vertices = [];
20281
20281
  const uvs = [];
@@ -21491,7 +21491,7 @@ var init_three_core = __esm({
21491
21491
  this.ior = 1.5;
21492
21492
  Object.defineProperty(this, "reflectivity", {
21493
21493
  get: function() {
21494
- return clamp(2.5 * (this.ior - 1) / (this.ior + 1), 0, 1);
21494
+ return clamp2(2.5 * (this.ior - 1) / (this.ior + 1), 0, 1);
21495
21495
  },
21496
21496
  set: function(reflectivity) {
21497
21497
  this.ior = (1 + 0.4 * reflectivity) / (1 - 0.4 * reflectivity);
@@ -29759,7 +29759,7 @@ var init_three_core = __esm({
29759
29759
  */
29760
29760
  makeSafe() {
29761
29761
  const EPS = 1e-6;
29762
- this.phi = clamp(this.phi, EPS, Math.PI - EPS);
29762
+ this.phi = clamp2(this.phi, EPS, Math.PI - EPS);
29763
29763
  return this;
29764
29764
  }
29765
29765
  /**
@@ -29787,7 +29787,7 @@ var init_three_core = __esm({
29787
29787
  this.phi = 0;
29788
29788
  } else {
29789
29789
  this.theta = Math.atan2(x2, z);
29790
- this.phi = Math.acos(clamp(y / this.radius, -1, 1));
29790
+ this.phi = Math.acos(clamp2(y / this.radius, -1, 1));
29791
29791
  }
29792
29792
  return this;
29793
29793
  }
@@ -30302,7 +30302,7 @@ var init_three_core = __esm({
30302
30302
  const startEnd_startP = _startEnd.dot(_startP);
30303
30303
  let t2 = startEnd_startP / startEnd2;
30304
30304
  if (clampToLine) {
30305
- t2 = clamp(t2, 0, 1);
30305
+ t2 = clamp2(t2, 0, 1);
30306
30306
  }
30307
30307
  return t2;
30308
30308
  }
@@ -30348,27 +30348,27 @@ var init_three_core = __esm({
30348
30348
  if (a2 <= EPSILON) {
30349
30349
  s = 0;
30350
30350
  t2 = f / e2;
30351
- t2 = clamp(t2, 0, 1);
30351
+ t2 = clamp2(t2, 0, 1);
30352
30352
  } else {
30353
30353
  const c3 = _d1.dot(_r);
30354
30354
  if (e2 <= EPSILON) {
30355
30355
  t2 = 0;
30356
- s = clamp(-c3 / a2, 0, 1);
30356
+ s = clamp2(-c3 / a2, 0, 1);
30357
30357
  } else {
30358
30358
  const b2 = _d1.dot(_d2);
30359
30359
  const denom = a2 * e2 - b2 * b2;
30360
30360
  if (denom !== 0) {
30361
- s = clamp((b2 * f - c3 * e2) / denom, 0, 1);
30361
+ s = clamp2((b2 * f - c3 * e2) / denom, 0, 1);
30362
30362
  } else {
30363
30363
  s = 0;
30364
30364
  }
30365
30365
  t2 = (b2 * s + f) / e2;
30366
30366
  if (t2 < 0) {
30367
30367
  t2 = 0;
30368
- s = clamp(-c3 / a2, 0, 1);
30368
+ s = clamp2(-c3 / a2, 0, 1);
30369
30369
  } else if (t2 > 1) {
30370
30370
  t2 = 1;
30371
- s = clamp((b2 - c3) / a2, 0, 1);
30371
+ s = clamp2((b2 - c3) / a2, 0, 1);
30372
30372
  }
30373
30373
  }
30374
30374
  }
@@ -43598,7 +43598,7 @@ var require_use_sync_external_store_shim_development = __commonJS({
43598
43598
  return x2 === y && (0 !== x2 || 1 / x2 === 1 / y) || x2 !== x2 && y !== y;
43599
43599
  }
43600
43600
  function useSyncExternalStore$2(subscribe3, getSnapshot2) {
43601
- didWarnOld18Alpha || void 0 === React100.startTransition || (didWarnOld18Alpha = true, console.error(
43601
+ didWarnOld18Alpha || void 0 === React103.startTransition || (didWarnOld18Alpha = true, console.error(
43602
43602
  "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."
43603
43603
  ));
43604
43604
  var value = getSnapshot2();
@@ -43608,7 +43608,7 @@ var require_use_sync_external_store_shim_development = __commonJS({
43608
43608
  "The result of getSnapshot should be cached to avoid an infinite loop"
43609
43609
  ), didWarnUncachedGetSnapshot = true);
43610
43610
  }
43611
- cachedValue = useState86({
43611
+ cachedValue = useState89({
43612
43612
  inst: { value, getSnapshot: getSnapshot2 }
43613
43613
  });
43614
43614
  var inst = cachedValue[0].inst, forceUpdate = cachedValue[1];
@@ -43620,7 +43620,7 @@ var require_use_sync_external_store_shim_development = __commonJS({
43620
43620
  },
43621
43621
  [subscribe3, value, getSnapshot2]
43622
43622
  );
43623
- useEffect72(
43623
+ useEffect73(
43624
43624
  function() {
43625
43625
  checkIfSnapshotChanged(inst) && forceUpdate({ inst });
43626
43626
  return subscribe3(function() {
@@ -43646,8 +43646,8 @@ var require_use_sync_external_store_shim_development = __commonJS({
43646
43646
  return getSnapshot2();
43647
43647
  }
43648
43648
  "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
43649
- 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;
43650
- exports$1.useSyncExternalStore = void 0 !== React100.useSyncExternalStore ? React100.useSyncExternalStore : shim;
43649
+ var React103 = __require("react"), objectIs = "function" === typeof Object.is ? Object.is : is2, useState89 = React103.useState, useEffect73 = React103.useEffect, useLayoutEffect7 = React103.useLayoutEffect, useDebugValue = React103.useDebugValue, didWarnOld18Alpha = false, didWarnUncachedGetSnapshot = false, shim = "undefined" === typeof window || "undefined" === typeof window.document || "undefined" === typeof window.document.createElement ? useSyncExternalStore$1 : useSyncExternalStore$2;
43650
+ exports$1.useSyncExternalStore = void 0 !== React103.useSyncExternalStore ? React103.useSyncExternalStore : shim;
43651
43651
  "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());
43652
43652
  })();
43653
43653
  }
@@ -43670,9 +43670,9 @@ var require_with_selector_development = __commonJS({
43670
43670
  return x2 === y && (0 !== x2 || 1 / x2 === 1 / y) || x2 !== x2 && y !== y;
43671
43671
  }
43672
43672
  "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart && __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
43673
- var React100 = __require("react"), shim = require_shim(), objectIs = "function" === typeof Object.is ? Object.is : is2, useSyncExternalStore3 = shim.useSyncExternalStore, useRef73 = React100.useRef, useEffect72 = React100.useEffect, useMemo41 = React100.useMemo, useDebugValue = React100.useDebugValue;
43673
+ var React103 = __require("react"), shim = require_shim(), objectIs = "function" === typeof Object.is ? Object.is : is2, useSyncExternalStore3 = shim.useSyncExternalStore, useRef74 = React103.useRef, useEffect73 = React103.useEffect, useMemo41 = React103.useMemo, useDebugValue = React103.useDebugValue;
43674
43674
  exports$1.useSyncExternalStoreWithSelector = function(subscribe3, getSnapshot2, getServerSnapshot2, selector, isEqual) {
43675
- var instRef = useRef73(null);
43675
+ var instRef = useRef74(null);
43676
43676
  if (null === instRef.current) {
43677
43677
  var inst = { hasValue: false, value: null };
43678
43678
  instRef.current = inst;
@@ -43713,7 +43713,7 @@ var require_with_selector_development = __commonJS({
43713
43713
  [getSnapshot2, getServerSnapshot2, selector, isEqual]
43714
43714
  );
43715
43715
  var value = useSyncExternalStore3(subscribe3, instRef[0], instRef[1]);
43716
- useEffect72(
43716
+ useEffect73(
43717
43717
  function() {
43718
43718
  inst.hasValue = true;
43719
43719
  inst.value = value;
@@ -70318,6 +70318,55 @@ var ACTION_BUTTON_PRESETS = [
70318
70318
  label: "Return",
70319
70319
  defaultAction: "prevSlide",
70320
70320
  iconPath: "M18 8 L18 14 L6 14 M6 14 L10 10 M6 14 L10 18"
70321
+ },
70322
+ {
70323
+ shapeType: "actionButtonHome",
70324
+ label: "Home",
70325
+ defaultAction: "firstSlide",
70326
+ // House: roof + body
70327
+ iconPath: "M12 4 L20 11 L20 20 L14 20 L14 14 L10 14 L10 20 L4 20 L4 11 Z"
70328
+ },
70329
+ {
70330
+ shapeType: "actionButtonHelp",
70331
+ label: "Help",
70332
+ defaultAction: "none",
70333
+ // Question mark
70334
+ iconPath: "M9 9 a3 3 0 1 1 4 2.8 c-1 0.4 -1 1.2 -1 2 M12 17 v0.5"
70335
+ },
70336
+ {
70337
+ shapeType: "actionButtonInformation",
70338
+ label: "Information",
70339
+ defaultAction: "none",
70340
+ // Lower-case "i": dot + body
70341
+ iconPath: "M12 6 v0.01 M12 10 v8"
70342
+ },
70343
+ {
70344
+ shapeType: "actionButtonDocument",
70345
+ label: "Document",
70346
+ defaultAction: "none",
70347
+ // Document with folded corner
70348
+ iconPath: "M6 4 L14 4 L18 8 L18 20 L6 20 Z M14 4 L14 8 L18 8"
70349
+ },
70350
+ {
70351
+ shapeType: "actionButtonSound",
70352
+ label: "Sound",
70353
+ defaultAction: "none",
70354
+ // Speaker cone + sound waves
70355
+ 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"
70356
+ },
70357
+ {
70358
+ shapeType: "actionButtonMovie",
70359
+ label: "Movie",
70360
+ defaultAction: "none",
70361
+ // Film strip with play triangle
70362
+ iconPath: "M4 6 L20 6 L20 18 L4 18 Z M10 9 L15 12 L10 15 Z"
70363
+ },
70364
+ {
70365
+ shapeType: "actionButtonBlank",
70366
+ label: "Custom",
70367
+ defaultAction: "none",
70368
+ // No glyph — empty path. The button still renders as a rounded rect via clip-path.
70369
+ iconPath: ""
70321
70370
  }
70322
70371
  ];
70323
70372
  Object.fromEntries(ACTION_BUTTON_PRESETS.map((p3) => [p3.shapeType, p3.defaultAction]));
@@ -72597,8 +72646,8 @@ function hexToRgb2(hex) {
72597
72646
  };
72598
72647
  }
72599
72648
  function rgbToHex(r2, g2, b2) {
72600
- const clamp2 = (v) => Math.max(0, Math.min(255, Math.round(v)));
72601
- return `#${clamp2(r2).toString(16).padStart(2, "0")}${clamp2(g2).toString(16).padStart(2, "0")}${clamp2(b2).toString(16).padStart(2, "0")}`;
72649
+ const clamp3 = (v) => Math.max(0, Math.min(255, Math.round(v)));
72650
+ return `#${clamp3(r2).toString(16).padStart(2, "0")}${clamp3(g2).toString(16).padStart(2, "0")}${clamp3(b2).toString(16).padStart(2, "0")}`;
72602
72651
  }
72603
72652
  function rgbToHsl(r2, g2, b2) {
72604
72653
  const rn = r2 / 255;
@@ -74808,6 +74857,11 @@ function getShapeClipPath(shapeType, adjustments, width, height) {
74808
74857
  }
74809
74858
  const normalized = shapeType.toLowerCase();
74810
74859
  if (normalized === "round1rect" || normalized === "round2samerect" || normalized === "round2diagrect" || normalized === "sniproundrect" || normalized === "snip1rect" || normalized === "snip2diagrect") {
74860
+ if (adjustments?.adj !== void 0 && width && height) {
74861
+ const ratio = Math.min(Math.max(adjustments.adj / 1e5, 0), 0.5);
74862
+ const radiusPx = Math.round(Math.min(width, height) * ratio);
74863
+ return `inset(0 round ${radiusPx}px)`;
74864
+ }
74811
74865
  return "inset(0 round 18px)";
74812
74866
  }
74813
74867
  if (normalized === "can" || normalized === "cylinder") {
@@ -75454,6 +75508,128 @@ function mapDagBlendModeToCss(blend) {
75454
75508
  return void 0;
75455
75509
  }
75456
75510
  }
75511
+ function getImageAlphaFilterId(elementId) {
75512
+ return `imgalpha-${elementId}`;
75513
+ }
75514
+ function hasAdvancedImageAlphaEffects(element2) {
75515
+ if (!pptxViewerCore.isImageLikeElement(element2)) {
75516
+ return false;
75517
+ }
75518
+ const e2 = element2.imageEffects;
75519
+ if (!e2) {
75520
+ return false;
75521
+ }
75522
+ return Boolean(
75523
+ 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
75524
+ );
75525
+ }
75526
+ function renderImageAlphaSvgFilter(element2) {
75527
+ if (!pptxViewerCore.isImageLikeElement(element2)) {
75528
+ return null;
75529
+ }
75530
+ const e2 = element2.imageEffects;
75531
+ if (!e2 || !hasAdvancedImageAlphaEffects(element2)) {
75532
+ return null;
75533
+ }
75534
+ const filterId = getImageAlphaFilterId(element2.id);
75535
+ const primitives = [];
75536
+ let resultIdx = 0;
75537
+ let inputRef = "SourceGraphic";
75538
+ const next = (jsx235) => {
75539
+ const result = `r${resultIdx++}`;
75540
+ primitives.push(jsx235(inputRef, result));
75541
+ inputRef = result;
75542
+ };
75543
+ if (typeof e2.alphaModFix === "number") {
75544
+ const mul = clamp(e2.alphaModFix / 100, 0, 1);
75545
+ next((inp, out) => /* @__PURE__ */ jsxRuntime.jsx(
75546
+ "feColorMatrix",
75547
+ {
75548
+ in: inp,
75549
+ result: out,
75550
+ type: "matrix",
75551
+ values: `1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 ${mul} 0`
75552
+ },
75553
+ out
75554
+ ));
75555
+ }
75556
+ if (e2.alphaInv) {
75557
+ next((inp, out) => /* @__PURE__ */ jsxRuntime.jsx("feComponentTransfer", { in: inp, result: out, children: /* @__PURE__ */ jsxRuntime.jsx("feFuncA", { type: "linear", slope: -1, intercept: 1 }) }, out));
75558
+ }
75559
+ if (e2.alphaCeiling) {
75560
+ next((inp, out) => /* @__PURE__ */ jsxRuntime.jsx("feComponentTransfer", { in: inp, result: out, children: /* @__PURE__ */ jsxRuntime.jsx("feFuncA", { type: "discrete", tableValues: "0 1 1 1 1 1 1 1 1 1" }) }, out));
75561
+ }
75562
+ if (e2.alphaFloor) {
75563
+ next((inp, out) => /* @__PURE__ */ jsxRuntime.jsx("feComponentTransfer", { in: inp, result: out, children: /* @__PURE__ */ jsxRuntime.jsx("feFuncA", { type: "discrete", tableValues: "0 0 0 0 0 0 0 0 0 1" }) }, out));
75564
+ }
75565
+ if (typeof e2.alphaRepl === "number") {
75566
+ const a2 = clamp(e2.alphaRepl / 100, 0, 1);
75567
+ next((inp, out) => /* @__PURE__ */ jsxRuntime.jsx("feComponentTransfer", { in: inp, result: out, children: /* @__PURE__ */ jsxRuntime.jsx("feFuncA", { type: "linear", slope: 0, intercept: a2 }) }, out));
75568
+ }
75569
+ if (typeof e2.alphaBiLevel === "number") {
75570
+ const t2 = clamp(e2.alphaBiLevel / 100, 0, 1);
75571
+ const table = Array.from({ length: 10 }, (_, i3) => i3 / 10 >= t2 ? "1" : "0").join(" ");
75572
+ next((inp, out) => /* @__PURE__ */ jsxRuntime.jsx("feComponentTransfer", { in: inp, result: out, children: /* @__PURE__ */ jsxRuntime.jsx("feFuncA", { type: "discrete", tableValues: table }) }, out));
75573
+ }
75574
+ if (typeof e2.biLevel === "number") {
75575
+ next((inp, out) => /* @__PURE__ */ jsxRuntime.jsx("feColorMatrix", { in: inp, result: out, type: "saturate", values: "0" }, out));
75576
+ const t2 = clamp(e2.biLevel / 100, 0, 1);
75577
+ const tbl = t2 < 0.5 ? "0 1" : "0 1";
75578
+ next((inp, out) => /* @__PURE__ */ jsxRuntime.jsxs("feComponentTransfer", { in: inp, result: out, children: [
75579
+ /* @__PURE__ */ jsxRuntime.jsx("feFuncR", { type: "discrete", tableValues: tbl }),
75580
+ /* @__PURE__ */ jsxRuntime.jsx("feFuncG", { type: "discrete", tableValues: tbl }),
75581
+ /* @__PURE__ */ jsxRuntime.jsx("feFuncB", { type: "discrete", tableValues: tbl })
75582
+ ] }, out));
75583
+ }
75584
+ if (e2.lum && (typeof e2.lum.bright === "number" || typeof e2.lum.contrast === "number")) {
75585
+ const b2 = (e2.lum.bright ?? 0) / 100;
75586
+ const c2 = 1 + (e2.lum.contrast ?? 0) / 100;
75587
+ const slope = c2;
75588
+ const intercept = b2 + (1 - c2) / 2;
75589
+ next((inp, out) => /* @__PURE__ */ jsxRuntime.jsxs("feComponentTransfer", { in: inp, result: out, children: [
75590
+ /* @__PURE__ */ jsxRuntime.jsx("feFuncR", { type: "linear", slope, intercept }),
75591
+ /* @__PURE__ */ jsxRuntime.jsx("feFuncG", { type: "linear", slope, intercept }),
75592
+ /* @__PURE__ */ jsxRuntime.jsx("feFuncB", { type: "linear", slope, intercept })
75593
+ ] }, out));
75594
+ }
75595
+ if (e2.hsl && typeof e2.hsl.sat === "number") {
75596
+ const v = clamp(1 + e2.hsl.sat / 100, 0, 2);
75597
+ next((inp, out) => /* @__PURE__ */ jsxRuntime.jsx("feColorMatrix", { in: inp, result: out, type: "saturate", values: String(v) }, out));
75598
+ }
75599
+ if (e2.tint && typeof e2.tint.amt === "number" && e2.tint.amt < 0) {
75600
+ const v = clamp(1 + e2.tint.amt / 100, 0, 1);
75601
+ next((inp, out) => /* @__PURE__ */ jsxRuntime.jsx("feColorMatrix", { in: inp, result: out, type: "saturate", values: String(v) }, out));
75602
+ }
75603
+ if (e2.clrRepl) {
75604
+ const c2 = hexToRgbUnit(e2.clrRepl.color);
75605
+ next((inp, out) => /* @__PURE__ */ jsxRuntime.jsx(
75606
+ "feColorMatrix",
75607
+ {
75608
+ in: inp,
75609
+ result: out,
75610
+ type: "matrix",
75611
+ values: `0 0 0 0 ${c2.r} 0 0 0 0 ${c2.g} 0 0 0 0 ${c2.b} 0 0 0 1 0`
75612
+ },
75613
+ out
75614
+ ));
75615
+ }
75616
+ if (primitives.length === 0) {
75617
+ return null;
75618
+ }
75619
+ return /* @__PURE__ */ jsxRuntime.jsx(
75620
+ "svg",
75621
+ {
75622
+ width: 0,
75623
+ height: 0,
75624
+ style: { position: "absolute", overflow: "hidden" },
75625
+ "aria-hidden": "true",
75626
+ children: /* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsx("filter", { id: filterId, colorInterpolationFilters: "sRGB", children: primitives }) })
75627
+ }
75628
+ );
75629
+ }
75630
+ function clamp(v, lo, hi) {
75631
+ return v < lo ? lo : v > hi ? hi : v;
75632
+ }
75457
75633
  function getDagDuotoneFilterId(elementId) {
75458
75634
  return `dag-duotone-${elementId}`;
75459
75635
  }
@@ -75537,6 +75713,9 @@ function getImageEffectsFilter(element2, options) {
75537
75713
  const filterId = getDuotoneFilterId(element2.id);
75538
75714
  filters.push(`url(#${filterId})`);
75539
75715
  }
75716
+ if (hasAdvancedImageAlphaEffects(element2)) {
75717
+ filters.push(`url(#${getImageAlphaFilterId(element2.id)})`);
75718
+ }
75540
75719
  if (effects.artisticEffect) {
75541
75720
  const radius = effects.artisticRadius ?? 5;
75542
75721
  if (needsSvgArtisticFilter(effects.artisticEffect)) {
@@ -75710,6 +75889,39 @@ function getEffectDagCssFilter(style, elementId) {
75710
75889
  return filters.length > 0 ? filters.join(" ") : void 0;
75711
75890
  }
75712
75891
  var getEffectDagFilter = getEffectDagCssFilter;
75892
+ function getResolvedShapeClipPathFor(shapeType, width, height, adjustments) {
75893
+ if (!shapeType) {
75894
+ return void 0;
75895
+ }
75896
+ if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) {
75897
+ return getShapeClipPath(shapeType, adjustments, width, height);
75898
+ }
75899
+ if (adjustments && Object.keys(adjustments).length > 0) {
75900
+ const adjusted = pptxViewerCore.getAdjustmentAwareShapeClipPath(shapeType, width, height, adjustments);
75901
+ if (adjusted !== void 0) {
75902
+ return adjusted;
75903
+ }
75904
+ }
75905
+ const fromPreset = pptxViewerCore.getShapeClipPathFromPreset(shapeType, width, height, adjustments);
75906
+ if (fromPreset !== void 0) {
75907
+ return fromPreset;
75908
+ }
75909
+ const cloud = pptxViewerCore.getCloudPathForRendering(shapeType, width, height);
75910
+ if (cloud !== void 0) {
75911
+ return cloud;
75912
+ }
75913
+ return getShapeClipPath(shapeType, adjustments, width, height);
75914
+ }
75915
+ function getResolvedShapeClipPath(element2, width, height) {
75916
+ const shapeType = element2.shapeType;
75917
+ if (!shapeType) {
75918
+ return void 0;
75919
+ }
75920
+ const w = element2.width;
75921
+ const h2 = element2.height;
75922
+ const adjustments = element2.shapeAdjustments;
75923
+ return getResolvedShapeClipPathFor(shapeType, w, h2, adjustments);
75924
+ }
75713
75925
 
75714
75926
  // src/viewer/utils/shape-round-rect.ts
75715
75927
  function localClampAdjustment(value) {
@@ -75781,6 +75993,27 @@ var MATERIAL_MAP = {
75781
75993
  filter: "brightness(1.1) contrast(0.85)",
75782
75994
  // Translucent powder: slight translucent glow
75783
75995
  backgroundImage: "radial-gradient(ellipse at 30% 30%, rgba(255,255,255,0.1) 0%, transparent 60%)"
75996
+ },
75997
+ // Legacy materials (PowerPoint 2007 / earlier). Render as muted variants
75998
+ // of the modern equivalents so legacy decks still resemble the originals.
75999
+ legacyMatte: {
76000
+ filter: "brightness(0.92) saturate(0.85)",
76001
+ backgroundImage: "linear-gradient(180deg, rgba(255,255,255,0.03) 0%, transparent 50%, rgba(0,0,0,0.04) 100%)"
76002
+ },
76003
+ legacyPlastic: {
76004
+ filter: "brightness(1.02) contrast(1.03)",
76005
+ boxShadow: "inset -2px -2px 5px rgba(255,255,255,0.3)",
76006
+ backgroundImage: "radial-gradient(ellipse 35% 25% at 25% 20%, rgba(255,255,255,0.15) 0%, transparent 70%)"
76007
+ },
76008
+ legacyMetal: {
76009
+ filter: "brightness(1.05) contrast(1.1) saturate(1.1)",
76010
+ boxShadow: "inset -2px -2px 6px rgba(255,255,255,0.35), inset 1px 1px 3px rgba(255,255,255,0.15)",
76011
+ 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%)"
76012
+ },
76013
+ legacyWireframe: {
76014
+ filter: "brightness(1) contrast(1.4) saturate(0.6)",
76015
+ // Wireframe: high contrast outline-emphasising look
76016
+ boxShadow: "inset 0 0 0 1px rgba(0,0,0,0.4)"
75784
76017
  }
75785
76018
  };
75786
76019
  function getMaterialCssOverrides(material) {
@@ -76735,8 +76968,7 @@ function getShapeVisualStyle(element2, hasFill, fillColor, strokeWidth, strokeCo
76735
76968
  return {};
76736
76969
  }
76737
76970
  const normalizedShapeType = getShapeType(element2.shapeType);
76738
- const shapeType = element2.shapeType || normalizedShapeType;
76739
- const clipPath = getShapeClipPath(shapeType);
76971
+ const clipPath = getResolvedShapeClipPath(element2);
76740
76972
  const fillOpacity = element2.shapeStyle?.fillOpacity;
76741
76973
  const strokeOpacity = element2.shapeStyle?.strokeOpacity;
76742
76974
  const strokeDash = normalizeStrokeDashType(element2.shapeStyle?.strokeDash);
@@ -77338,7 +77570,7 @@ function getImageMaskStyle(element2) {
77338
77570
  if (normalized === "can" || normalized === "cylinder") {
77339
77571
  return { borderRadius: "48% / 12%" };
77340
77572
  }
77341
- const clipPath = getShapeClipPath(shapeType);
77573
+ const clipPath = getResolvedShapeClipPath(element2);
77342
77574
  if (!clipPath) {
77343
77575
  return void 0;
77344
77576
  }
@@ -78001,8 +78233,8 @@ function hexToRgb3(hex) {
78001
78233
  };
78002
78234
  }
78003
78235
  function rgbToHex2(r2, g2, b2) {
78004
- const clamp2 = (v) => Math.max(0, Math.min(255, Math.round(v)));
78005
- return `#${clamp2(r2).toString(16).padStart(2, "0").toUpperCase()}${clamp2(g2).toString(16).padStart(2, "0").toUpperCase()}${clamp2(b2).toString(16).padStart(2, "0").toUpperCase()}`;
78236
+ const clamp3 = (v) => Math.max(0, Math.min(255, Math.round(v)));
78237
+ 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()}`;
78006
78238
  }
78007
78239
  function tintColor(hex, tintFactor) {
78008
78240
  const { r: r2, g: g2, b: b2 } = hexToRgb3(hex);
@@ -78933,13 +79165,13 @@ function cellStyleToCss(style) {
78933
79165
  }
78934
79166
  if (style.textDirection) {
78935
79167
  switch (style.textDirection) {
78936
- case "vertical":
79168
+ case "vert":
78937
79169
  case "eaVert":
78938
79170
  case "wordArtVert":
78939
79171
  case "wordArtVertRtl":
78940
79172
  css.writingMode = "vertical-rl";
78941
79173
  break;
78942
- case "vertical270":
79174
+ case "vert270":
78943
79175
  case "mongolianVert":
78944
79176
  css.writingMode = "vertical-lr";
78945
79177
  break;
@@ -79346,8 +79578,8 @@ function renderTableElement(element2, textStyle, options) {
79346
79578
  {
79347
79579
  style: rowHeight ? { height: rowHeight } : void 0,
79348
79580
  children: cells.map((cell, cellIndex) => {
79349
- const isHMerged = cell["@_hMerge"] === "1" || cell["@_hMerge"] === true;
79350
- const isVMerged = cell["@_vMerge"] === "1" || cell["@_vMerge"] === true;
79581
+ const isHMerged = cell["@_hMerge"] === "1";
79582
+ const isVMerged = cell["@_vMerge"] === "1";
79351
79583
  if (isHMerged || isVMerged) {
79352
79584
  return null;
79353
79585
  }
@@ -79466,8 +79698,8 @@ function hexToRgb4(hex) {
79466
79698
  ];
79467
79699
  }
79468
79700
  function rgbToHex3(r2, g2, b2) {
79469
- const clamp2 = (v) => Math.max(0, Math.min(255, Math.round(v)));
79470
- return `#${clamp2(r2).toString(16).padStart(2, "0")}${clamp2(g2).toString(16).padStart(2, "0")}${clamp2(b2).toString(16).padStart(2, "0")}`;
79701
+ const clamp3 = (v) => Math.max(0, Math.min(255, Math.round(v)));
79702
+ return `#${clamp3(r2).toString(16).padStart(2, "0")}${clamp3(g2).toString(16).padStart(2, "0")}${clamp3(b2).toString(16).padStart(2, "0")}`;
79471
79703
  }
79472
79704
  function tint(hex, amount) {
79473
79705
  const [r2, g2, b2] = hexToRgb4(hex);
@@ -81385,7 +81617,7 @@ function resolveRegionCode(label) {
81385
81617
  return REGION_ALIAS_MAP[normalized];
81386
81618
  }
81387
81619
  function lerpColor(a2, b2, t2) {
81388
- const clamp2 = (v) => Math.max(0, Math.min(255, Math.round(v)));
81620
+ const clamp3 = (v) => Math.max(0, Math.min(255, Math.round(v)));
81389
81621
  const parse = (hex) => {
81390
81622
  const h2 = hex.replace("#", "");
81391
81623
  return [
@@ -81396,9 +81628,9 @@ function lerpColor(a2, b2, t2) {
81396
81628
  };
81397
81629
  const [r1, g1, b1] = parse(a2);
81398
81630
  const [r2, g2, b22] = parse(b2);
81399
- const r3 = clamp2(r1 + (r2 - r1) * t2);
81400
- const g3 = clamp2(g1 + (g2 - g1) * t2);
81401
- const bl = clamp2(b1 + (b22 - b1) * t2);
81631
+ const r3 = clamp3(r1 + (r2 - r1) * t2);
81632
+ const g3 = clamp3(g1 + (g2 - g1) * t2);
81633
+ const bl = clamp3(b1 + (b22 - b1) * t2);
81402
81634
  return `#${r3.toString(16).padStart(2, "0")}${g3.toString(16).padStart(2, "0")}${bl.toString(16).padStart(2, "0")}`;
81403
81635
  }
81404
81636
  function sequentialColorScale(t2) {
@@ -85356,6 +85588,15 @@ function copyFormatFromElement(element2) {
85356
85588
  }
85357
85589
  return result;
85358
85590
  }
85591
+ function definedEntries(obj) {
85592
+ const out = {};
85593
+ for (const key in obj) {
85594
+ if (obj[key] !== void 0) {
85595
+ out[key] = obj[key];
85596
+ }
85597
+ }
85598
+ return out;
85599
+ }
85359
85600
  function applyFormatToElement(element2, format) {
85360
85601
  let updated = { ...element2 };
85361
85602
  if (format.shapeStyle && pptxViewerCore.hasShapeProperties(updated)) {
@@ -85363,7 +85604,7 @@ function applyFormatToElement(element2, format) {
85363
85604
  ...updated,
85364
85605
  shapeStyle: {
85365
85606
  ...updated.shapeStyle,
85366
- ...format.shapeStyle
85607
+ ...definedEntries(format.shapeStyle)
85367
85608
  }
85368
85609
  };
85369
85610
  }
@@ -85372,12 +85613,18 @@ function applyFormatToElement(element2, format) {
85372
85613
  ...updated,
85373
85614
  textStyle: {
85374
85615
  ...updated.textStyle,
85375
- ...format.textStyle
85616
+ ...definedEntries(format.textStyle)
85376
85617
  }
85377
85618
  };
85378
85619
  }
85379
85620
  return updated;
85380
85621
  }
85622
+ function hasCopyableFormat(element2) {
85623
+ if (!element2) {
85624
+ return false;
85625
+ }
85626
+ return pptxViewerCore.hasShapeProperties(element2) || pptxViewerCore.hasTextProperties(element2);
85627
+ }
85381
85628
 
85382
85629
  // src/viewer/utils/animation-preview.ts
85383
85630
  var PRESET_TO_EFFECT = {
@@ -86726,8 +86973,8 @@ function ThumbnailTable({
86726
86973
  {
86727
86974
  style: rowHeight ? { height: rowHeight } : void 0,
86728
86975
  children: cells.map((cell, ci) => {
86729
- const isHMerged = cell["@_hMerge"] === "1" || cell["@_hMerge"] === true;
86730
- const isVMerged = cell["@_vMerge"] === "1" || cell["@_vMerge"] === true;
86976
+ const isHMerged = cell["@_hMerge"] === "1";
86977
+ const isVMerged = cell["@_vMerge"] === "1";
86731
86978
  if (isHMerged || isVMerged) {
86732
86979
  return null;
86733
86980
  }
@@ -88150,6 +88397,59 @@ function WarpedText({
88150
88397
  }
88151
88398
  );
88152
88399
  }
88400
+ var GLYPH_BY_SHAPE = Object.fromEntries(
88401
+ ACTION_BUTTON_PRESETS.map((p3) => [p3.shapeType, p3.iconPath])
88402
+ );
88403
+ GLYPH_BY_SHAPE["actionButtonForwardOrNext"] = GLYPH_BY_SHAPE["actionButtonForwardNext"];
88404
+ GLYPH_BY_SHAPE["actionButtonBackOrPrevious"] = GLYPH_BY_SHAPE["actionButtonBackPrevious"];
88405
+ function isActionButtonShape(shapeType) {
88406
+ return Boolean(shapeType && shapeType in GLYPH_BY_SHAPE);
88407
+ }
88408
+ function getActionButtonGlyphPath(shapeType) {
88409
+ if (!shapeType) {
88410
+ return void 0;
88411
+ }
88412
+ const path = GLYPH_BY_SHAPE[shapeType];
88413
+ return path && path.length > 0 ? path : void 0;
88414
+ }
88415
+ function ActionButtonGlyphOverlay({
88416
+ element: element2,
88417
+ color
88418
+ }) {
88419
+ const shapeType = "shapeType" in element2 ? element2.shapeType : void 0;
88420
+ const path = getActionButtonGlyphPath(shapeType);
88421
+ if (!path) {
88422
+ return null;
88423
+ }
88424
+ const stroke = color ?? ("textStyle" in element2 && element2.textStyle?.color || "#ffffff");
88425
+ return /* @__PURE__ */ jsxRuntime.jsx(
88426
+ "svg",
88427
+ {
88428
+ viewBox: "0 0 24 24",
88429
+ width: "100%",
88430
+ height: "100%",
88431
+ preserveAspectRatio: "xMidYMid meet",
88432
+ style: {
88433
+ position: "absolute",
88434
+ inset: 0,
88435
+ pointerEvents: "none",
88436
+ padding: "20%"
88437
+ },
88438
+ "aria-hidden": "true",
88439
+ children: /* @__PURE__ */ jsxRuntime.jsx(
88440
+ "path",
88441
+ {
88442
+ d: path,
88443
+ fill: "none",
88444
+ stroke,
88445
+ strokeWidth: 2,
88446
+ strokeLinecap: "round",
88447
+ strokeLinejoin: "round"
88448
+ }
88449
+ )
88450
+ }
88451
+ );
88452
+ }
88153
88453
  function ColorChangedImage({
88154
88454
  src,
88155
88455
  clrChange,
@@ -88420,6 +88720,7 @@ function renderImg(el, style, filter, alt, opacity) {
88420
88720
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
88421
88721
  tileDuotoneColors && renderDuotoneSvgFilter(el.id, tileDuotoneColors.color1, tileDuotoneColors.color2),
88422
88722
  renderArtisticEffectSvgFilter(el.id, artisticEffectName, artisticRadius),
88723
+ renderImageAlphaSvgFilter(el),
88423
88724
  /* @__PURE__ */ jsxRuntime.jsx(
88424
88725
  "div",
88425
88726
  {
@@ -88441,6 +88742,7 @@ function renderImg(el, style, filter, alt, opacity) {
88441
88742
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
88442
88743
  duotoneColors && !useDuotoneCanvas && renderDuotoneSvgFilter(el.id, duotoneColors.color1, duotoneColors.color2),
88443
88744
  renderArtisticEffectSvgFilter(el.id, artisticEffectName, artisticRadius),
88745
+ renderImageAlphaSvgFilter(el),
88444
88746
  useDuotoneCanvas && duotoneColors ? /* @__PURE__ */ jsxRuntime.jsx(
88445
88747
  DuotoneImage,
88446
88748
  {
@@ -90949,8 +91251,11 @@ function renderBody(el, isImg, isEditing, editText, spellCheck, txtSE, txtS, vec
90949
91251
  ...scene3dStyle.perspective ? { perspective: scene3dStyle.perspective } : {},
90950
91252
  ...scene3dStyle.transformStyle ? { transformStyle: scene3dStyle.transformStyle } : {}
90951
91253
  } : void 0;
91254
+ const shapeTypeForGlyph = "shapeType" in el ? el.shapeType : void 0;
91255
+ const showActionButtonGlyph = isActionButtonShape(shapeTypeForGlyph);
90952
91256
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
90953
91257
  vecShape,
91258
+ showActionButtonGlyph && /* @__PURE__ */ jsxRuntime.jsx(ActionButtonGlyphOverlay, { element: el }),
90954
91259
  isTxtEl ? useSvgWarp ? /* @__PURE__ */ jsxRuntime.jsx(
90955
91260
  "div",
90956
91261
  {
@@ -91760,11 +92065,16 @@ function usePresenceTracking({
91760
92065
  if (cid === localClientId) {
91761
92066
  return;
91762
92067
  }
91763
- const raw = state2?.presence;
92068
+ const stateRecord = state2;
92069
+ const raw = stateRecord?.presence;
91764
92070
  if (!raw || typeof raw !== "object") {
91765
92071
  return;
91766
92072
  }
91767
- const sanitized = sanitizePresence({ ...raw, clientId: cid }, canvasWidth, canvasHeight);
92073
+ const sanitized = sanitizePresence(
92074
+ { ...raw, clientId: cid },
92075
+ canvasWidth,
92076
+ canvasHeight
92077
+ );
91768
92078
  if (!sanitized) {
91769
92079
  return;
91770
92080
  }
@@ -91832,15 +92142,9 @@ function useYjsProvider({ config }) {
91832
92142
  try {
91833
92143
  const [Y, { WebsocketProvider: WebsocketProvider2 }] = await Promise.all([Promise.resolve().then(() => (init_yjs(), yjs_exports)), Promise.resolve().then(() => (init_y_websocket(), y_websocket_exports))]);
91834
92144
  const yDoc = new Y.Doc();
91835
- const provider = new WebsocketProvider2(
91836
- config.serverUrl,
91837
- roomId,
91838
- yDoc,
91839
- // eslint-disable-line @typescript-eslint/no-explicit-any
91840
- {
91841
- params: config.authToken ? { token: config.authToken } : void 0
91842
- }
91843
- );
92145
+ const provider = new WebsocketProvider2(config.serverUrl, roomId, yDoc, {
92146
+ params: config.authToken ? { token: config.authToken } : void 0
92147
+ });
91844
92148
  let connected = false;
91845
92149
  const handleStatus = (event) => {
91846
92150
  if (event.status === "connected") {
@@ -95406,90 +95710,101 @@ var SlideNotesPanel = ({
95406
95710
  });
95407
95711
  const hasNotes = draft.trim().length > 0;
95408
95712
  const slideLabel = activeSlide ? t2("pptx.notes.slideN", { n: activeSlide.slideNumber }) : t2("pptx.notes.noSlide");
95409
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col border-t border-border/60 bg-background select-none", children: [
95410
- /* @__PURE__ */ jsxRuntime.jsxs(
95411
- "button",
95412
- {
95413
- type: "button",
95414
- onClick: onToggle,
95415
- className: "flex items-center gap-1.5 px-3 py-1 text-[11px] text-muted-foreground hover:text-foreground hover:bg-accent/30 transition-colors w-full text-left shrink-0",
95416
- "aria-expanded": isExpanded,
95417
- "aria-controls": "slide-notes-content",
95418
- children: [
95419
- "Notes",
95420
- !isExpanded && hasNotes && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/50 text-[10px]", children: "(has notes)" })
95421
- ]
95422
- }
95423
- ),
95424
- isExpanded && /* @__PURE__ */ jsxRuntime.jsxs(
95425
- "div",
95426
- {
95427
- id: "slide-notes-content",
95428
- className: "px-3 pb-2 overflow-y-auto",
95429
- style: { maxHeight: panelHeight ?? EXPANDED_MAX_HEIGHT + 40 },
95430
- children: [
95431
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] text-muted-foreground mb-1", children: slideLabel }),
95432
- canEdit ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
95433
- /* @__PURE__ */ jsxRuntime.jsx(
95434
- NotesToolbar,
95435
- {
95436
- isRichEditEnabled,
95437
- showLinkPopover,
95438
- savedSelectionText: savedSelectionRef.current?.text ?? "",
95439
- hasAllSlides: allSlides !== void 0 && allSlides.length > 0,
95440
- onApplyRichCommand: applyRichCommand,
95441
- onToggleBulletList: toggleBulletList,
95442
- onToggleNumberedList: toggleNumberedList,
95443
- onIndent: handleIndent,
95444
- onOutdent: handleOutdent,
95445
- onLinkButtonClick: handleLinkButtonClick,
95446
- onInsertLink: handleInsertLink,
95447
- onCloseLinkPopover: () => setShowLinkPopover(false),
95448
- onPrintClick: () => setShowPrintDialog(true),
95449
- onToggleRichEdit: () => setIsRichEditEnabled((prev) => !prev)
95450
- }
95451
- ),
95452
- isRichEditEnabled ? /* @__PURE__ */ jsxRuntime.jsx(
95453
- "div",
95454
- {
95455
- ref: richEditorRef,
95456
- contentEditable: true,
95457
- suppressContentEditableWarning: true,
95458
- onInput: handleRichInput,
95459
- onBlur: handleBlur,
95460
- onKeyDown: handleKeyDownRich,
95461
- onClick: handleEditorClick,
95462
- className: "w-full overflow-y-auto rounded-md border border-border/50 bg-muted/60 px-2.5 py-1.5 text-xs text-foreground focus:border-primary/50 focus:outline-none focus:ring-1 focus:ring-primary/30 transition-colors whitespace-pre-wrap",
95463
- style: { maxHeight: EXPANDED_MAX_HEIGHT - 8, minHeight: 72 }
95464
- }
95465
- ) : /* @__PURE__ */ jsxRuntime.jsx(
95466
- "textarea",
95467
- {
95468
- ref: textareaRef,
95469
- name: "slide-notes",
95470
- value: draft,
95471
- onChange: handlePlainChange,
95472
- onBlur: handleBlur,
95473
- onKeyDown: handleKeyDownPlain,
95474
- placeholder: t2("pptx.notes.clickToAddNotes"),
95475
- rows: 4,
95476
- className: "w-full resize-none rounded-md border border-border/50 bg-muted/60 px-2.5 py-1.5 text-xs text-foreground placeholder:text-muted-foreground focus:border-primary/50 focus:outline-none focus:ring-1 focus:ring-primary/30 transition-colors",
95477
- style: { maxHeight: EXPANDED_MAX_HEIGHT - 8 }
95478
- }
95479
- )
95480
- ] }) : /* @__PURE__ */ jsxRuntime.jsx(
95481
- "div",
95482
- {
95483
- className: "w-full rounded-md border border-border/30 bg-muted/40 px-2.5 py-1.5 text-xs text-muted-foreground overflow-y-auto whitespace-pre-wrap",
95484
- style: { maxHeight: EXPANDED_MAX_HEIGHT - 32, minHeight: 60 },
95485
- children: hasNotes ? renderRichNotesSegments(draftSegments) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "italic text-muted-foreground", children: t2("pptx.notes.noNotes") })
95486
- }
95487
- )
95488
- ]
95489
- }
95490
- ),
95491
- showPrintDialog && allSlides && /* @__PURE__ */ jsxRuntime.jsx(NotesPrintDialog, { slides: allSlides, onClose: () => setShowPrintDialog(false) })
95492
- ] });
95713
+ return /* @__PURE__ */ jsxRuntime.jsxs(
95714
+ "div",
95715
+ {
95716
+ className: cn(
95717
+ "flex flex-col border-t border-border/60 bg-background select-none",
95718
+ // On mobile, hide the entire notes strip when collapsed — the
95719
+ // MobileBottomBar's Notes button is the entry point instead.
95720
+ !isExpanded && "max-md:hidden"
95721
+ ),
95722
+ children: [
95723
+ /* @__PURE__ */ jsxRuntime.jsxs(
95724
+ "button",
95725
+ {
95726
+ type: "button",
95727
+ onClick: onToggle,
95728
+ className: "flex items-center gap-1.5 px-3 py-1 text-[11px] text-muted-foreground hover:text-foreground hover:bg-accent/30 transition-colors w-full text-left shrink-0 max-md:hidden",
95729
+ "aria-expanded": isExpanded,
95730
+ "aria-controls": "slide-notes-content",
95731
+ children: [
95732
+ "Notes",
95733
+ !isExpanded && hasNotes && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground/50 text-[10px]", children: "(has notes)" })
95734
+ ]
95735
+ }
95736
+ ),
95737
+ isExpanded && /* @__PURE__ */ jsxRuntime.jsxs(
95738
+ "div",
95739
+ {
95740
+ id: "slide-notes-content",
95741
+ className: "px-3 pb-2 overflow-y-auto",
95742
+ style: { maxHeight: panelHeight ?? EXPANDED_MAX_HEIGHT + 40 },
95743
+ children: [
95744
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[10px] text-muted-foreground mb-1", children: slideLabel }),
95745
+ canEdit ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
95746
+ /* @__PURE__ */ jsxRuntime.jsx(
95747
+ NotesToolbar,
95748
+ {
95749
+ isRichEditEnabled,
95750
+ showLinkPopover,
95751
+ savedSelectionText: savedSelectionRef.current?.text ?? "",
95752
+ hasAllSlides: allSlides !== void 0 && allSlides.length > 0,
95753
+ onApplyRichCommand: applyRichCommand,
95754
+ onToggleBulletList: toggleBulletList,
95755
+ onToggleNumberedList: toggleNumberedList,
95756
+ onIndent: handleIndent,
95757
+ onOutdent: handleOutdent,
95758
+ onLinkButtonClick: handleLinkButtonClick,
95759
+ onInsertLink: handleInsertLink,
95760
+ onCloseLinkPopover: () => setShowLinkPopover(false),
95761
+ onPrintClick: () => setShowPrintDialog(true),
95762
+ onToggleRichEdit: () => setIsRichEditEnabled((prev) => !prev)
95763
+ }
95764
+ ),
95765
+ isRichEditEnabled ? /* @__PURE__ */ jsxRuntime.jsx(
95766
+ "div",
95767
+ {
95768
+ ref: richEditorRef,
95769
+ contentEditable: true,
95770
+ suppressContentEditableWarning: true,
95771
+ onInput: handleRichInput,
95772
+ onBlur: handleBlur,
95773
+ onKeyDown: handleKeyDownRich,
95774
+ onClick: handleEditorClick,
95775
+ className: "w-full overflow-y-auto rounded-md border border-border/50 bg-muted/60 px-2.5 py-1.5 text-xs text-foreground focus:border-primary/50 focus:outline-none focus:ring-1 focus:ring-primary/30 transition-colors whitespace-pre-wrap",
95776
+ style: { maxHeight: EXPANDED_MAX_HEIGHT - 8, minHeight: 72 }
95777
+ }
95778
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
95779
+ "textarea",
95780
+ {
95781
+ ref: textareaRef,
95782
+ name: "slide-notes",
95783
+ value: draft,
95784
+ onChange: handlePlainChange,
95785
+ onBlur: handleBlur,
95786
+ onKeyDown: handleKeyDownPlain,
95787
+ placeholder: t2("pptx.notes.clickToAddNotes"),
95788
+ rows: 4,
95789
+ className: "w-full resize-none rounded-md border border-border/50 bg-muted/60 px-2.5 py-1.5 text-xs text-foreground placeholder:text-muted-foreground focus:border-primary/50 focus:outline-none focus:ring-1 focus:ring-primary/30 transition-colors",
95790
+ style: { maxHeight: EXPANDED_MAX_HEIGHT - 8 }
95791
+ }
95792
+ )
95793
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(
95794
+ "div",
95795
+ {
95796
+ className: "w-full rounded-md border border-border/30 bg-muted/40 px-2.5 py-1.5 text-xs text-muted-foreground overflow-y-auto whitespace-pre-wrap",
95797
+ style: { maxHeight: EXPANDED_MAX_HEIGHT - 32, minHeight: 60 },
95798
+ children: hasNotes ? renderRichNotesSegments(draftSegments) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "italic text-muted-foreground", children: t2("pptx.notes.noNotes") })
95799
+ }
95800
+ )
95801
+ ]
95802
+ }
95803
+ ),
95804
+ showPrintDialog && allSlides && /* @__PURE__ */ jsxRuntime.jsx(NotesPrintDialog, { slides: allSlides, onClose: () => setShowPrintDialog(false) })
95805
+ ]
95806
+ }
95807
+ );
95493
95808
  };
95494
95809
  var DB_NAME = "pptx-viewer-autosave";
95495
95810
  var DB_VERSION = 1;
@@ -98026,7 +98341,8 @@ function ArrangeSection(p3) {
98026
98341
  {
98027
98342
  type: "button",
98028
98343
  onClick: p3.onToggleFormatPainter,
98029
- disabled: !p3.canEdit,
98344
+ disabled: !p3.canEdit || p3.canActivateFormatPainter === false && !p3.formatPainterActive,
98345
+ "data-testid": "format-painter-toggle",
98030
98346
  className: cn(
98031
98347
  pill,
98032
98348
  p3.formatPainterActive ? "bg-amber-600 hover:bg-amber-500 text-amber-50" : ""
@@ -98478,7 +98794,8 @@ function HomeSection(p3) {
98478
98794
  const { fontFamily, fontSize } = extractFontInfo(p3.selectedElement);
98479
98795
  const handleNewSlide = React10.useCallback(() => {
98480
98796
  if (p3.layoutOptions.length > 0) {
98481
- p3.onInsertSlideFromLayout(p3.layoutOptions[0].path);
98797
+ const first = p3.layoutOptions[0];
98798
+ p3.onInsertSlideFromLayout(first.path, first.name);
98482
98799
  }
98483
98800
  }, [p3]);
98484
98801
  React10.useEffect(() => {
@@ -98565,7 +98882,8 @@ function HomeSection(p3) {
98565
98882
  {
98566
98883
  type: "button",
98567
98884
  onClick: p3.onToggleFormatPainter,
98568
- disabled: !p3.canEdit,
98885
+ disabled: !p3.canEdit || p3.canActivateFormatPainter === false && !p3.formatPainterActive,
98886
+ "data-testid": "format-painter-toggle",
98569
98887
  className: cn(
98570
98888
  gL,
98571
98889
  p3.formatPainterActive ? "bg-amber-600 hover:bg-amber-500 text-amber-50" : ""
@@ -98615,7 +98933,7 @@ function HomeSection(p3) {
98615
98933
  type: "button",
98616
98934
  className: "flex items-center gap-2 w-full px-3 py-1.5 text-xs text-foreground hover:bg-muted transition-colors",
98617
98935
  onClick: () => {
98618
- p3.onInsertSlideFromLayout(lo.path);
98936
+ p3.onInsertSlideFromLayout(lo.path, lo.name);
98619
98937
  setLayoutMenuOpen(false);
98620
98938
  },
98621
98939
  children: lo.name
@@ -99515,6 +99833,561 @@ function TextSection(p3) {
99515
99833
  ] })
99516
99834
  ] });
99517
99835
  }
99836
+ function ViewSection(p3) {
99837
+ const { t: t2 } = reactI18next.useTranslation();
99838
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
99839
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-0.5", children: [
99840
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0.5", children: [
99841
+ /* @__PURE__ */ jsxRuntime.jsx("button", { className: pill, title: "Normal view", children: "Normal" }),
99842
+ p3.onToggleSlideSorter ? /* @__PURE__ */ jsxRuntime.jsx("button", { className: pill, onClick: p3.onToggleSlideSorter, title: "Slide Sorter view", children: "Slide Sorter" }) : /* @__PURE__ */ jsxRuntime.jsx("button", { className: pill, title: "Slide Sorter view", children: "Slide Sorter" }),
99843
+ /* @__PURE__ */ jsxRuntime.jsx("button", { className: pill, title: "Reading View", children: "Reading View" })
99844
+ ] }),
99845
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] text-muted-foreground leading-none", children: "Presentation Views" })
99846
+ ] }),
99847
+ sep,
99848
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-0.5", children: [
99849
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-0.5", children: /* @__PURE__ */ jsxRuntime.jsx(
99850
+ "button",
99851
+ {
99852
+ onClick: p3.onEnterMasterView,
99853
+ disabled: !p3.canEdit,
99854
+ className: pill,
99855
+ title: "Edit slide masters and layouts",
99856
+ children: "Slide Master"
99857
+ }
99858
+ ) }),
99859
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] text-muted-foreground leading-none", children: "Master Views" })
99860
+ ] }),
99861
+ sep,
99862
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-0.5", children: [
99863
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-0.5", children: p3.onZoomToFit && /* @__PURE__ */ jsxRuntime.jsx("button", { className: pill, onClick: p3.onZoomToFit, title: "Zoom to fit slide in window", children: "Zoom to Fit" }) }),
99864
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] text-muted-foreground leading-none", children: "Zoom" })
99865
+ ] }),
99866
+ sep,
99867
+ /* @__PURE__ */ jsxRuntime.jsx(
99868
+ "button",
99869
+ {
99870
+ onClick: () => p3.onSetEditTemplateMode(!p3.editTemplateMode),
99871
+ disabled: !p3.canEdit,
99872
+ className: cn(
99873
+ pill,
99874
+ p3.editTemplateMode ? "bg-amber-600 hover:bg-amber-500 text-amber-50" : ""
99875
+ ),
99876
+ title: "Toggle template/master element editing",
99877
+ children: p3.editTemplateMode ? "Templates On" : "Templates Off"
99878
+ }
99879
+ ),
99880
+ p3.onToggleSelectionPane && /* @__PURE__ */ jsxRuntime.jsxs(
99881
+ "button",
99882
+ {
99883
+ type: "button",
99884
+ onClick: p3.onToggleSelectionPane,
99885
+ className: cn(
99886
+ pill,
99887
+ p3.isSelectionPaneOpen ? "bg-primary hover:bg-primary/80 text-primary-foreground" : ""
99888
+ ),
99889
+ title: "Selection Pane",
99890
+ children: [
99891
+ /* @__PURE__ */ jsxRuntime.jsx(lu.LuList, { className: ic2 }),
99892
+ "Selection"
99893
+ ]
99894
+ }
99895
+ ),
99896
+ p3.onToggleEyedropper && /* @__PURE__ */ jsxRuntime.jsxs(
99897
+ "button",
99898
+ {
99899
+ type: "button",
99900
+ onClick: p3.onToggleEyedropper,
99901
+ disabled: !p3.canEdit,
99902
+ className: cn(
99903
+ pill,
99904
+ p3.eyedropperActive ? "bg-purple-600 hover:bg-purple-500 text-purple-50" : ""
99905
+ ),
99906
+ title: "Eyedropper \u2014 sample a colour from the slide",
99907
+ children: [
99908
+ /* @__PURE__ */ jsxRuntime.jsx(lu.LuPipette, { className: ic2 }),
99909
+ "Eyedropper"
99910
+ ]
99911
+ }
99912
+ ),
99913
+ /* @__PURE__ */ jsxRuntime.jsx(
99914
+ "button",
99915
+ {
99916
+ onClick: () => p3.onSetShowGrid(!p3.showGrid),
99917
+ className: cn(pill, p3.showGrid ? "bg-primary text-primary-foreground" : ""),
99918
+ title: t2("pptx.grid.toggleGrid"),
99919
+ children: t2("pptx.grid.grid")
99920
+ }
99921
+ ),
99922
+ /* @__PURE__ */ jsxRuntime.jsx(
99923
+ "button",
99924
+ {
99925
+ onClick: () => p3.onSetShowRulers(!p3.showRulers),
99926
+ className: cn(pill, p3.showRulers ? "bg-primary text-primary-foreground" : ""),
99927
+ title: t2("pptx.ruler.toggleRulers"),
99928
+ children: t2("pptx.ruler.rulers")
99929
+ }
99930
+ ),
99931
+ /* @__PURE__ */ jsxRuntime.jsx(
99932
+ "button",
99933
+ {
99934
+ onClick: () => p3.onSetSnapToGrid(!p3.snapToGrid),
99935
+ className: cn(pill, p3.snapToGrid ? "bg-primary text-primary-foreground" : ""),
99936
+ title: t2("pptx.grid.snapToGrid"),
99937
+ children: t2("pptx.grid.snapToGrid")
99938
+ }
99939
+ ),
99940
+ /* @__PURE__ */ jsxRuntime.jsx(
99941
+ "button",
99942
+ {
99943
+ onClick: () => p3.onSetSnapToShape(!p3.snapToShape),
99944
+ className: cn(pill, p3.snapToShape ? "bg-primary text-primary-foreground" : ""),
99945
+ title: t2("pptx.grid.snapToShape"),
99946
+ children: t2("pptx.grid.snapToShape")
99947
+ }
99948
+ ),
99949
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => p3.onAddGuide("h"), className: pill, title: "Add horizontal guide", children: "H Guide" }),
99950
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => p3.onAddGuide("v"), className: pill, title: "Add vertical guide", children: "V Guide" }),
99951
+ /* @__PURE__ */ jsxRuntime.jsx(
99952
+ "button",
99953
+ {
99954
+ onClick: () => p3.onSetSpellCheckEnabled(!p3.spellCheckEnabled),
99955
+ className: cn(pill, p3.spellCheckEnabled ? "bg-primary text-primary-foreground" : ""),
99956
+ title: "Toggle spell check",
99957
+ children: "Spell"
99958
+ }
99959
+ )
99960
+ ] });
99961
+ }
99962
+ function MobileSheet({
99963
+ open,
99964
+ onClose,
99965
+ title,
99966
+ children,
99967
+ heightFraction = 0.6,
99968
+ fullScreen = false,
99969
+ className,
99970
+ headerRight
99971
+ }) {
99972
+ const sheetRef = React10.useRef(null);
99973
+ const [dragY, setDragY] = React10.useState(0);
99974
+ const dragStartRef = React10.useRef(null);
99975
+ const onPointerDown = React10.useCallback((e2) => {
99976
+ dragStartRef.current = e2.clientY;
99977
+ e2.target.setPointerCapture?.(e2.pointerId);
99978
+ }, []);
99979
+ const onPointerMove = React10.useCallback((e2) => {
99980
+ if (dragStartRef.current === null) {
99981
+ return;
99982
+ }
99983
+ const delta = e2.clientY - dragStartRef.current;
99984
+ setDragY(Math.max(0, delta));
99985
+ }, []);
99986
+ const onPointerUp = React10.useCallback(
99987
+ (e2) => {
99988
+ if (dragStartRef.current === null) {
99989
+ return;
99990
+ }
99991
+ const delta = e2.clientY - dragStartRef.current;
99992
+ dragStartRef.current = null;
99993
+ e2.target.releasePointerCapture?.(e2.pointerId);
99994
+ if (delta > 120) {
99995
+ onClose();
99996
+ }
99997
+ setDragY(0);
99998
+ },
99999
+ [onClose]
100000
+ );
100001
+ React10.useEffect(() => {
100002
+ if (!open) {
100003
+ return;
100004
+ }
100005
+ const handleKey = (e2) => {
100006
+ if (e2.key === "Escape") {
100007
+ onClose();
100008
+ }
100009
+ };
100010
+ window.addEventListener("keydown", handleKey);
100011
+ return () => window.removeEventListener("keydown", handleKey);
100012
+ }, [open, onClose]);
100013
+ if (!open) {
100014
+ return null;
100015
+ }
100016
+ const heightStyle = fullScreen ? { height: "calc(100dvh - env(safe-area-inset-top))" } : { height: `${Math.round(heightFraction * 100)}dvh` };
100017
+ return /* @__PURE__ */ jsxRuntime.jsxs(
100018
+ "div",
100019
+ {
100020
+ className: "fixed inset-0 z-50 flex flex-col justify-end md:hidden",
100021
+ role: "dialog",
100022
+ "aria-modal": "true",
100023
+ children: [
100024
+ /* @__PURE__ */ jsxRuntime.jsx(
100025
+ "button",
100026
+ {
100027
+ type: "button",
100028
+ "aria-label": "Close",
100029
+ className: "absolute inset-0 bg-black/40 backdrop-blur-[2px] animate-in fade-in duration-150",
100030
+ onClick: onClose
100031
+ }
100032
+ ),
100033
+ /* @__PURE__ */ jsxRuntime.jsxs(
100034
+ "div",
100035
+ {
100036
+ ref: sheetRef,
100037
+ className: cn(
100038
+ "relative bg-background border-t border-border rounded-t-2xl shadow-2xl flex flex-col overflow-hidden",
100039
+ "animate-in slide-in-from-bottom duration-200",
100040
+ className
100041
+ ),
100042
+ style: {
100043
+ ...heightStyle,
100044
+ transform: dragY > 0 ? `translateY(${dragY}px)` : void 0,
100045
+ transition: dragStartRef.current === null ? "transform 150ms ease-out" : "none"
100046
+ },
100047
+ children: [
100048
+ /* @__PURE__ */ jsxRuntime.jsx(
100049
+ "div",
100050
+ {
100051
+ className: "flex items-center justify-center pt-2 pb-1 cursor-grab active:cursor-grabbing touch-none",
100052
+ onPointerDown,
100053
+ onPointerMove,
100054
+ onPointerUp,
100055
+ onPointerCancel: onPointerUp,
100056
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-1 w-10 rounded-full bg-muted-foreground/40" })
100057
+ }
100058
+ ),
100059
+ (title || headerRight) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2 px-4 pb-2 border-b border-border/60", children: [
100060
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-semibold text-foreground truncate", children: title }),
100061
+ headerRight
100062
+ ] }),
100063
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto overscroll-contain", children })
100064
+ ]
100065
+ }
100066
+ )
100067
+ ]
100068
+ }
100069
+ );
100070
+ }
100071
+ var MENU_ITEMS = [
100072
+ { key: "home", label: "Home", icon: lu.LuClipboardCopy },
100073
+ { key: "insert", label: "Insert", icon: lu.LuPlus },
100074
+ { key: "text", label: "Text", icon: lu.LuType },
100075
+ { key: "draw", label: "Draw", icon: lu.LuPaintbrush },
100076
+ { key: "arrange", label: "Arrange", icon: lu.LuShapes },
100077
+ { key: "design", label: "Design", icon: lu.LuLayoutGrid },
100078
+ { key: "transitions", label: "Transitions", icon: lu.LuSparkles },
100079
+ { key: "animations", label: "Animations", icon: lu.LuWand },
100080
+ { key: "slideShow", label: "Slide Show", icon: lu.LuPresentation },
100081
+ { key: "review", label: "Review", icon: lu.LuTextCursorInput },
100082
+ { key: "view", label: "View", icon: lu.LuSettings },
100083
+ { key: "file", label: "File", icon: lu.LuFile }
100084
+ ];
100085
+ function MobileMenuSheet(props) {
100086
+ const { open, onClose } = props;
100087
+ const [active, setActive] = React10.useState("home");
100088
+ return /* @__PURE__ */ jsxRuntime.jsx(MobileSheet, { open, onClose, fullScreen: true, title: "Menu", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
100089
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "sticky top-0 z-10 bg-background border-b border-border", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-1.5 overflow-x-auto px-3 py-2 scrollbar-none", children: MENU_ITEMS.map(({ key, label, icon: Icon }) => /* @__PURE__ */ jsxRuntime.jsxs(
100090
+ "button",
100091
+ {
100092
+ type: "button",
100093
+ onClick: () => setActive(active === key ? null : key),
100094
+ className: cn(
100095
+ "inline-flex items-center gap-1.5 shrink-0 px-3 py-2 rounded-full text-[12px] font-medium border transition-colors min-h-[36px]",
100096
+ active === key ? "bg-primary text-primary-foreground border-primary" : "border-border text-muted-foreground hover:text-foreground hover:bg-accent/40"
100097
+ ),
100098
+ children: [
100099
+ /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "w-4 h-4" }),
100100
+ label
100101
+ ]
100102
+ },
100103
+ key
100104
+ )) }) }),
100105
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-3", children: /* @__PURE__ */ jsxRuntime.jsx(MobileSectionBody, { active, ...props }) })
100106
+ ] }) });
100107
+ }
100108
+ function MobileSectionBody({
100109
+ active,
100110
+ ...p3
100111
+ }) {
100112
+ const wrap = "flex flex-wrap items-center gap-2";
100113
+ switch (active) {
100114
+ case "home":
100115
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrap, children: /* @__PURE__ */ jsxRuntime.jsx(
100116
+ HomeSection,
100117
+ {
100118
+ canEdit: p3.canEdit,
100119
+ clipboardPayload: p3.clipboardPayload,
100120
+ formatPainterActive: p3.formatPainterActive,
100121
+ canActivateFormatPainter: p3.canActivateFormatPainter,
100122
+ onCopy: p3.onCopy,
100123
+ onCut: p3.onCut,
100124
+ onPaste: p3.onPaste,
100125
+ onToggleFormatPainter: p3.onToggleFormatPainter,
100126
+ layoutOptions: p3.layoutOptions,
100127
+ onInsertSlideFromLayout: p3.onInsertSlideFromLayout,
100128
+ selectedElement: p3.selectedElement,
100129
+ onUpdateTextStyle: p3.onUpdateTextStyle
100130
+ }
100131
+ ) });
100132
+ case "insert":
100133
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrap, children: /* @__PURE__ */ jsxRuntime.jsx(
100134
+ InsertSection,
100135
+ {
100136
+ canEdit: p3.canEdit,
100137
+ newShapeType: p3.newShapeType,
100138
+ onSetNewShapeType: p3.onSetNewShapeType,
100139
+ onAddTextBox: p3.onAddTextBox,
100140
+ onAddShape: p3.onAddShape,
100141
+ onAddTable: p3.onAddTable,
100142
+ onAddSmartArt: p3.onAddSmartArt,
100143
+ onAddEquation: p3.onAddEquation,
100144
+ onAddActionButton: p3.onAddActionButton,
100145
+ onInsertField: p3.onInsertField,
100146
+ onOpenImagePicker: p3.onOpenImagePicker,
100147
+ onOpenMediaPicker: p3.onOpenMediaPicker
100148
+ }
100149
+ ) });
100150
+ case "text":
100151
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrap, children: /* @__PURE__ */ jsxRuntime.jsx(
100152
+ TextSection,
100153
+ {
100154
+ canEdit: p3.canEdit,
100155
+ selectedElement: p3.selectedElement,
100156
+ tableEditorState: p3.tableEditorState,
100157
+ onUpdateTextStyle: p3.onUpdateTextStyle
100158
+ }
100159
+ ) });
100160
+ case "draw":
100161
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrap, children: /* @__PURE__ */ jsxRuntime.jsx(
100162
+ DrawSection,
100163
+ {
100164
+ activeTool: p3.activeTool,
100165
+ drawingColor: p3.drawingColor,
100166
+ drawingWidth: p3.drawingWidth,
100167
+ onSetActiveTool: p3.onSetActiveTool,
100168
+ onSetDrawingColor: p3.onSetDrawingColor,
100169
+ onSetDrawingWidth: p3.onSetDrawingWidth
100170
+ }
100171
+ ) });
100172
+ case "arrange":
100173
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrap, children: /* @__PURE__ */ jsxRuntime.jsx(
100174
+ ArrangeSection,
100175
+ {
100176
+ canEdit: p3.canEdit,
100177
+ selectedElement: p3.selectedElement,
100178
+ clipboardPayload: p3.clipboardPayload,
100179
+ onAlignElements: p3.onAlignElements,
100180
+ onCopy: p3.onCopy,
100181
+ onCut: p3.onCut,
100182
+ onPaste: p3.onPaste,
100183
+ onFlip: p3.onFlip,
100184
+ onMoveLayer: p3.onMoveLayer,
100185
+ onMoveLayerToEdge: p3.onMoveLayerToEdge,
100186
+ onDuplicate: p3.onDuplicate,
100187
+ onDelete: p3.onDelete,
100188
+ formatPainterActive: p3.formatPainterActive,
100189
+ onToggleFormatPainter: p3.onToggleFormatPainter,
100190
+ canActivateFormatPainter: p3.canActivateFormatPainter
100191
+ }
100192
+ ) });
100193
+ case "design":
100194
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrap, children: /* @__PURE__ */ jsxRuntime.jsx(
100195
+ DesignSection,
100196
+ {
100197
+ canEdit: p3.canEdit,
100198
+ onToggleThemeGallery: p3.onToggleThemeGallery,
100199
+ isThemeGalleryOpen: p3.isThemeGalleryOpen,
100200
+ onToggleThemeEditor: p3.onToggleThemeEditor,
100201
+ isThemeEditorOpen: p3.isThemeEditorOpen,
100202
+ onOpenDocumentProperties: p3.onOpenDocumentProperties,
100203
+ onToggleInspector: p3.onToggleInspector,
100204
+ isInspectorPaneOpen: p3.isInspectorPaneOpen
100205
+ }
100206
+ ) });
100207
+ case "transitions":
100208
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrap, children: /* @__PURE__ */ jsxRuntime.jsx(
100209
+ TransitionsSection,
100210
+ {
100211
+ isInspectorPaneOpen: p3.isInspectorPaneOpen,
100212
+ onToggleInspector: p3.onToggleInspector
100213
+ }
100214
+ ) });
100215
+ case "animations":
100216
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrap, children: /* @__PURE__ */ jsxRuntime.jsx(
100217
+ AnimationsSection,
100218
+ {
100219
+ canEdit: p3.canEdit,
100220
+ selectedElement: p3.selectedElement,
100221
+ isInspectorPaneOpen: p3.isInspectorPaneOpen,
100222
+ onToggleInspector: p3.onToggleInspector,
100223
+ onOpenAnimationPanel: p3.onOpenAnimationPanel,
100224
+ onAddAnimation: p3.onAddAnimation,
100225
+ onRemoveAnimation: p3.onRemoveAnimation
100226
+ }
100227
+ ) });
100228
+ case "slideShow":
100229
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrap, children: /* @__PURE__ */ jsxRuntime.jsx(
100230
+ SlideShowSection,
100231
+ {
100232
+ onPresent: () => p3.onSetMode("present"),
100233
+ onEnterPresenterView: p3.onEnterPresenterView ?? (() => {
100234
+ }),
100235
+ onEnterRehearsalMode: p3.onEnterRehearsalMode ?? (() => {
100236
+ }),
100237
+ onOpenSetUpSlideShow: p3.onOpenSetUpSlideShow ?? (() => {
100238
+ }),
100239
+ onOpenBroadcastDialog: p3.onOpenBroadcastDialog ?? (() => {
100240
+ }),
100241
+ onToggleSubtitles: p3.onToggleSubtitles ?? (() => {
100242
+ }),
100243
+ showSubtitles: p3.showSubtitles ?? false,
100244
+ onSetMode: p3.onSetMode
100245
+ }
100246
+ ) });
100247
+ case "review":
100248
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrap, children: /* @__PURE__ */ jsxRuntime.jsx(
100249
+ ReviewSection,
100250
+ {
100251
+ canEdit: p3.canEdit,
100252
+ spellCheckEnabled: p3.spellCheckEnabled,
100253
+ onSetSpellCheckEnabled: p3.onSetSpellCheckEnabled,
100254
+ onToggleComments: p3.onToggleComments,
100255
+ isCommentsPanelOpen: p3.isCommentsPanelOpen,
100256
+ slideCommentCount: p3.slideCommentCount,
100257
+ onCompare: p3.onCompare
100258
+ }
100259
+ ) });
100260
+ case "view":
100261
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrap, children: /* @__PURE__ */ jsxRuntime.jsx(
100262
+ ViewSection,
100263
+ {
100264
+ canEdit: p3.canEdit,
100265
+ editTemplateMode: p3.editTemplateMode,
100266
+ onSetEditTemplateMode: p3.onSetEditTemplateMode,
100267
+ spellCheckEnabled: p3.spellCheckEnabled,
100268
+ onSetSpellCheckEnabled: p3.onSetSpellCheckEnabled,
100269
+ showGrid: p3.showGrid,
100270
+ showRulers: p3.showRulers,
100271
+ snapToGrid: p3.snapToGrid,
100272
+ snapToShape: p3.snapToShape,
100273
+ onSetShowGrid: p3.onSetShowGrid,
100274
+ onSetShowRulers: p3.onSetShowRulers,
100275
+ onSetSnapToGrid: p3.onSetSnapToGrid,
100276
+ onSetSnapToShape: p3.onSetSnapToShape,
100277
+ onAddGuide: p3.onAddGuide,
100278
+ onEnterMasterView: p3.onEnterMasterView,
100279
+ isSelectionPaneOpen: p3.isSelectionPaneOpen,
100280
+ onToggleSelectionPane: p3.onToggleSelectionPane,
100281
+ eyedropperActive: p3.eyedropperActive,
100282
+ onToggleEyedropper: p3.onToggleEyedropper
100283
+ }
100284
+ ) });
100285
+ case "file":
100286
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrap, children: /* @__PURE__ */ jsxRuntime.jsx(
100287
+ FileSection,
100288
+ {
100289
+ onExportPng: p3.onExportPng,
100290
+ onExportPdf: p3.onExportPdf,
100291
+ onExportVideo: p3.onExportVideo,
100292
+ onExportGif: p3.onExportGif,
100293
+ onPackageForSharing: p3.onPackageForSharing,
100294
+ onSaveAsPptx: p3.onSaveAsPptx,
100295
+ onSaveAsPpsx: p3.onSaveAsPpsx,
100296
+ onSaveAsPptm: p3.onSaveAsPptm,
100297
+ hasMacros: p3.hasMacros,
100298
+ onCopySlideAsImage: p3.onCopySlideAsImage,
100299
+ onPrint: p3.onPrint,
100300
+ onOpenDocumentProperties: p3.onOpenDocumentProperties,
100301
+ onOpenPasswordProtection: p3.onOpenPasswordProtection,
100302
+ onOpenFontEmbedding: p3.onOpenFontEmbedding,
100303
+ onOpenDigitalSignatures: p3.onOpenDigitalSignatures
100304
+ }
100305
+ ) });
100306
+ default:
100307
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center text-sm text-muted-foreground py-8", children: [
100308
+ /* @__PURE__ */ jsxRuntime.jsx(lu.LuChevronRight, { className: "w-5 h-5 inline-block opacity-50" }),
100309
+ " Select a section above"
100310
+ ] });
100311
+ }
100312
+ }
100313
+ function MobileToolbar(props) {
100314
+ const { t: t2 } = reactI18next.useTranslation();
100315
+ const { mode, canUndo, canRedo, onUndo, onRedo, onSetMode } = props;
100316
+ const [menuOpen, setMenuOpen] = React10.useState(false);
100317
+ const showEdit = mode === "edit" || mode === "master";
100318
+ const btn = "inline-flex items-center justify-center min-w-[44px] min-h-[44px] rounded-md text-foreground/80 hover:bg-accent/60 disabled:opacity-40 disabled:cursor-not-allowed active:scale-95 transition-transform";
100319
+ return /* @__PURE__ */ jsxRuntime.jsxs(
100320
+ "div",
100321
+ {
100322
+ role: "toolbar",
100323
+ "aria-label": "Toolbar",
100324
+ className: "relative z-20 flex items-center gap-1 px-2 py-1 border-b border-border bg-secondary/50 min-h-[52px] pt-[max(env(safe-area-inset-top),0px)]",
100325
+ children: [
100326
+ showEdit && /* @__PURE__ */ jsxRuntime.jsx(
100327
+ "button",
100328
+ {
100329
+ type: "button",
100330
+ onClick: () => setMenuOpen(true),
100331
+ className: btn,
100332
+ title: "Menu",
100333
+ "aria-label": "Menu",
100334
+ children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuMenu, { className: "w-5 h-5" })
100335
+ }
100336
+ ),
100337
+ showEdit && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
100338
+ /* @__PURE__ */ jsxRuntime.jsx(
100339
+ "button",
100340
+ {
100341
+ type: "button",
100342
+ onClick: onUndo,
100343
+ disabled: !canUndo,
100344
+ className: btn,
100345
+ title: t2("pptx.toolbar.undo"),
100346
+ "aria-label": t2("pptx.toolbar.undo"),
100347
+ children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuUndo, { className: "w-5 h-5" })
100348
+ }
100349
+ ),
100350
+ /* @__PURE__ */ jsxRuntime.jsx(
100351
+ "button",
100352
+ {
100353
+ type: "button",
100354
+ onClick: onRedo,
100355
+ disabled: !canRedo,
100356
+ className: btn,
100357
+ title: t2("pptx.toolbar.redo"),
100358
+ "aria-label": t2("pptx.toolbar.redo"),
100359
+ children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuRedo, { className: "w-5 h-5" })
100360
+ }
100361
+ )
100362
+ ] }),
100363
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1" }),
100364
+ /* @__PURE__ */ jsxRuntime.jsx(
100365
+ "button",
100366
+ {
100367
+ type: "button",
100368
+ onClick: () => onSetMode("present"),
100369
+ className: cn(btn, "text-primary"),
100370
+ title: t2("pptx.toolbar.present"),
100371
+ "aria-label": t2("pptx.toolbar.present"),
100372
+ children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuPresentation, { className: "w-5 h-5" })
100373
+ }
100374
+ ),
100375
+ showEdit && /* @__PURE__ */ jsxRuntime.jsx(
100376
+ "button",
100377
+ {
100378
+ type: "button",
100379
+ onClick: props.onOpenShareDialog ?? props.onPackageForSharing,
100380
+ className: cn(btn, "bg-primary text-primary-foreground hover:bg-primary/90 px-3"),
100381
+ title: t2("pptx.toolbar.share"),
100382
+ "aria-label": t2("pptx.toolbar.share"),
100383
+ children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuShare2, { className: "w-4 h-4" })
100384
+ }
100385
+ ),
100386
+ /* @__PURE__ */ jsxRuntime.jsx(MobileMenuSheet, { open: menuOpen, onClose: () => setMenuOpen(false), ...props })
100387
+ ]
100388
+ }
100389
+ );
100390
+ }
99518
100391
  function CustomShowsControls({
99519
100392
  customShows,
99520
100393
  activeCustomShowId,
@@ -99943,7 +100816,7 @@ function ToolbarPrimaryRow(p3) {
99943
100816
  onClick: p3.onToggleComments,
99944
100817
  className: cn(
99945
100818
  qab,
99946
- "max-md:hidden",
100819
+ "relative max-md:hidden",
99947
100820
  p3.isCommentsPanelOpen ? "text-foreground" : "text-muted-foreground"
99948
100821
  ),
99949
100822
  title: t2("pptx.toolbar.comments"),
@@ -100059,134 +100932,11 @@ function ToolbarPrimaryRow(p3) {
100059
100932
  /* @__PURE__ */ jsxRuntime.jsx(OverflowMenu, { ...p3 })
100060
100933
  ] });
100061
100934
  }
100062
- function ViewSection(p3) {
100063
- const { t: t2 } = reactI18next.useTranslation();
100064
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
100065
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-0.5", children: [
100066
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-0.5", children: [
100067
- /* @__PURE__ */ jsxRuntime.jsx("button", { className: pill, title: "Normal view", children: "Normal" }),
100068
- p3.onToggleSlideSorter ? /* @__PURE__ */ jsxRuntime.jsx("button", { className: pill, onClick: p3.onToggleSlideSorter, title: "Slide Sorter view", children: "Slide Sorter" }) : /* @__PURE__ */ jsxRuntime.jsx("button", { className: pill, title: "Slide Sorter view", children: "Slide Sorter" }),
100069
- /* @__PURE__ */ jsxRuntime.jsx("button", { className: pill, title: "Reading View", children: "Reading View" })
100070
- ] }),
100071
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] text-muted-foreground leading-none", children: "Presentation Views" })
100072
- ] }),
100073
- sep,
100074
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-0.5", children: [
100075
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-0.5", children: /* @__PURE__ */ jsxRuntime.jsx(
100076
- "button",
100077
- {
100078
- onClick: p3.onEnterMasterView,
100079
- disabled: !p3.canEdit,
100080
- className: pill,
100081
- title: "Edit slide masters and layouts",
100082
- children: "Slide Master"
100083
- }
100084
- ) }),
100085
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] text-muted-foreground leading-none", children: "Master Views" })
100086
- ] }),
100087
- sep,
100088
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-0.5", children: [
100089
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-0.5", children: p3.onZoomToFit && /* @__PURE__ */ jsxRuntime.jsx("button", { className: pill, onClick: p3.onZoomToFit, title: "Zoom to fit slide in window", children: "Zoom to Fit" }) }),
100090
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[9px] text-muted-foreground leading-none", children: "Zoom" })
100091
- ] }),
100092
- sep,
100093
- /* @__PURE__ */ jsxRuntime.jsx(
100094
- "button",
100095
- {
100096
- onClick: () => p3.onSetEditTemplateMode(!p3.editTemplateMode),
100097
- disabled: !p3.canEdit,
100098
- className: cn(
100099
- pill,
100100
- p3.editTemplateMode ? "bg-amber-600 hover:bg-amber-500 text-amber-50" : ""
100101
- ),
100102
- title: "Toggle template/master element editing",
100103
- children: p3.editTemplateMode ? "Templates On" : "Templates Off"
100104
- }
100105
- ),
100106
- p3.onToggleSelectionPane && /* @__PURE__ */ jsxRuntime.jsxs(
100107
- "button",
100108
- {
100109
- type: "button",
100110
- onClick: p3.onToggleSelectionPane,
100111
- className: cn(
100112
- pill,
100113
- p3.isSelectionPaneOpen ? "bg-primary hover:bg-primary/80 text-primary-foreground" : ""
100114
- ),
100115
- title: "Selection Pane",
100116
- children: [
100117
- /* @__PURE__ */ jsxRuntime.jsx(lu.LuList, { className: ic2 }),
100118
- "Selection"
100119
- ]
100120
- }
100121
- ),
100122
- p3.onToggleEyedropper && /* @__PURE__ */ jsxRuntime.jsxs(
100123
- "button",
100124
- {
100125
- type: "button",
100126
- onClick: p3.onToggleEyedropper,
100127
- disabled: !p3.canEdit,
100128
- className: cn(
100129
- pill,
100130
- p3.eyedropperActive ? "bg-purple-600 hover:bg-purple-500 text-purple-50" : ""
100131
- ),
100132
- title: "Eyedropper \u2014 sample a colour from the slide",
100133
- children: [
100134
- /* @__PURE__ */ jsxRuntime.jsx(lu.LuPipette, { className: ic2 }),
100135
- "Eyedropper"
100136
- ]
100137
- }
100138
- ),
100139
- /* @__PURE__ */ jsxRuntime.jsx(
100140
- "button",
100141
- {
100142
- onClick: () => p3.onSetShowGrid(!p3.showGrid),
100143
- className: cn(pill, p3.showGrid ? "bg-primary text-primary-foreground" : ""),
100144
- title: t2("pptx.grid.toggleGrid"),
100145
- children: t2("pptx.grid.grid")
100146
- }
100147
- ),
100148
- /* @__PURE__ */ jsxRuntime.jsx(
100149
- "button",
100150
- {
100151
- onClick: () => p3.onSetShowRulers(!p3.showRulers),
100152
- className: cn(pill, p3.showRulers ? "bg-primary text-primary-foreground" : ""),
100153
- title: t2("pptx.ruler.toggleRulers"),
100154
- children: t2("pptx.ruler.rulers")
100155
- }
100156
- ),
100157
- /* @__PURE__ */ jsxRuntime.jsx(
100158
- "button",
100159
- {
100160
- onClick: () => p3.onSetSnapToGrid(!p3.snapToGrid),
100161
- className: cn(pill, p3.snapToGrid ? "bg-primary text-primary-foreground" : ""),
100162
- title: t2("pptx.grid.snapToGrid"),
100163
- children: t2("pptx.grid.snapToGrid")
100164
- }
100165
- ),
100166
- /* @__PURE__ */ jsxRuntime.jsx(
100167
- "button",
100168
- {
100169
- onClick: () => p3.onSetSnapToShape(!p3.snapToShape),
100170
- className: cn(pill, p3.snapToShape ? "bg-primary text-primary-foreground" : ""),
100171
- title: t2("pptx.grid.snapToShape"),
100172
- children: t2("pptx.grid.snapToShape")
100173
- }
100174
- ),
100175
- /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => p3.onAddGuide("h"), className: pill, title: "Add horizontal guide", children: "H Guide" }),
100176
- /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => p3.onAddGuide("v"), className: pill, title: "Add vertical guide", children: "V Guide" }),
100177
- /* @__PURE__ */ jsxRuntime.jsx(
100178
- "button",
100179
- {
100180
- onClick: () => p3.onSetSpellCheckEnabled(!p3.spellCheckEnabled),
100181
- className: cn(pill, p3.spellCheckEnabled ? "bg-primary text-primary-foreground" : ""),
100182
- title: "Toggle spell check",
100183
- children: "Spell"
100184
- }
100185
- )
100186
- ] });
100187
- }
100188
100935
  function Toolbar(p3) {
100189
100936
  const { mode, isNarrowViewport, isCompactToolbarOpen, toolbarSection, onSetToolbarSection } = p3;
100937
+ if (isNarrowViewport && mode !== "present") {
100938
+ return /* @__PURE__ */ jsxRuntime.jsx(MobileToolbar, { ...p3 });
100939
+ }
100190
100940
  const sFil = toolbarSection === "file";
100191
100941
  const sHome = toolbarSection === "home";
100192
100942
  const sIns = toolbarSection === "insert";
@@ -100272,6 +101022,7 @@ function Toolbar(p3) {
100272
101022
  canEdit: p3.canEdit,
100273
101023
  clipboardPayload: p3.clipboardPayload,
100274
101024
  formatPainterActive: p3.formatPainterActive,
101025
+ canActivateFormatPainter: p3.canActivateFormatPainter,
100275
101026
  onCopy: p3.onCopy,
100276
101027
  onCut: p3.onCut,
100277
101028
  onPaste: p3.onPaste,
@@ -100335,7 +101086,8 @@ function Toolbar(p3) {
100335
101086
  onDuplicate: p3.onDuplicate,
100336
101087
  onDelete: p3.onDelete,
100337
101088
  formatPainterActive: p3.formatPainterActive,
100338
- onToggleFormatPainter: p3.onToggleFormatPainter
101089
+ onToggleFormatPainter: p3.onToggleFormatPainter,
101090
+ canActivateFormatPainter: p3.canActivateFormatPainter
100339
101091
  }
100340
101092
  ),
100341
101093
  sDes && /* @__PURE__ */ jsxRuntime.jsx(
@@ -106048,181 +106800,194 @@ function InspectorPane(props) {
106048
106800
  const fallback = themeOptions[0]?.path ?? "";
106049
106801
  setSelectedThemePath((previous) => previous || fallback);
106050
106802
  }, [slideMasters, themeOptions]);
106051
- return /* @__PURE__ */ jsxRuntime.jsxs(
106052
- "div",
106053
- {
106054
- className: cn(
106055
- // Shared styles
106056
- "bg-background flex flex-col text-xs text-foreground shadow-xl",
106057
- // Mobile: absolute bottom sheet overlay
106058
- "max-md:fixed max-md:inset-x-0 max-md:bottom-0 max-md:top-auto max-md:w-full max-md:max-h-[60vh] max-md:rounded-t-xl max-md:border-t max-md:border-border max-md:z-30",
106059
- "max-md:transition-transform max-md:duration-200 max-md:ease-in-out",
106060
- isOpen ? "max-md:translate-y-0" : "max-md:translate-y-full",
106061
- // Desktop: flow-based flex child (takes space from canvas)
106062
- "md:h-full md:border-l md:border-border",
106063
- !panelWidth && "md:w-72"
106064
- ),
106065
- style: panelWidth ? { width: panelWidth } : void 0,
106066
- children: [
106067
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2 px-3 py-2 border-b border-border", children: [
106068
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1 rounded bg-muted p-0.5", children: INSPECTOR_TABS.map(({ key, label, icon: Icon }) => /* @__PURE__ */ jsxRuntime.jsxs(
106069
- "button",
106070
- {
106071
- type: "button",
106072
- title: label,
106073
- className: cn(
106074
- "flex items-center gap-1 px-2 py-1 rounded text-[11px] transition-colors",
106075
- activeTab === key ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:text-foreground hover:bg-accent"
106076
- ),
106077
- onClick: () => onSetActiveTab(key),
106078
- children: [
106079
- /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "w-3.5 h-3.5" }),
106080
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline", children: label })
106081
- ]
106082
- },
106083
- key
106084
- )) }),
106085
- /* @__PURE__ */ jsxRuntime.jsx(
106086
- "button",
106087
- {
106088
- type: "button",
106089
- onClick: onClose,
106090
- title: t2("common.close"),
106091
- className: "p-1 rounded text-muted-foreground hover:text-foreground hover:bg-muted transition-colors",
106092
- children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuX, { className: "w-4 h-4" })
106093
- }
106094
- )
106095
- ] }),
106096
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto p-3 space-y-3", children: [
106097
- activeTab === "elements" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
106098
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(HEADING, "mb-2"), children: t2("pptx.inspector.layerOrder") }),
106099
- activeSlide ? [...activeSlide.elements || []].reverse().map((el, ri) => {
106100
- const idx = (activeSlide.elements || []).length - 1 - ri;
106101
- const sel = selectedElement?.id === el.id || selectedElementIds.includes(el.id);
106102
- const label = (pptxViewerCore.hasTextProperties(el) ? (el.text || "").slice(0, 24) : void 0) || el.type;
106103
- return /* @__PURE__ */ jsxRuntime.jsxs(
106104
- "div",
106105
- {
106106
- title: `${el.type} \u2014 ${el.id}`,
106107
- className: cn(
106108
- "flex items-center gap-2 px-2 py-1 rounded cursor-pointer transition-colors",
106109
- sel ? "bg-primary/30 text-primary" : "hover:bg-muted text-foreground"
106110
- ),
106111
- onClick: () => onSelectElement(el.id),
106112
- children: [
106113
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground w-4 text-right", children: idx + 1 }),
106114
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate", children: label })
106115
- ]
106116
- },
106117
- el.id
106118
- );
106119
- }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-muted-foreground italic", children: t2("pptx.inspector.noSlideSelected") })
106120
- ] }),
106121
- activeTab === "properties" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: hasSelection && selectedElement ? /* @__PURE__ */ jsxRuntime.jsx(
106122
- ElementInspectorBody,
106123
- {
106124
- selectedElement,
106125
- canEdit,
106126
- slides,
106127
- tableEditorState,
106128
- mediaDataUrls,
106129
- onUpdateElement,
106130
- onUpdateElementStyle,
106131
- onUpdateTextStyle,
106132
- onMoveLayer
106133
- }
106134
- ) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
106803
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
106804
+ isOpen && /* @__PURE__ */ jsxRuntime.jsx(
106805
+ "button",
106806
+ {
106807
+ type: "button",
106808
+ "aria-label": t2("common.close"),
106809
+ onClick: onClose,
106810
+ className: "md:hidden fixed inset-0 z-20 bg-black/40 backdrop-blur-[2px] animate-in fade-in duration-150"
106811
+ }
106812
+ ),
106813
+ /* @__PURE__ */ jsxRuntime.jsxs(
106814
+ "div",
106815
+ {
106816
+ className: cn(
106817
+ // Shared styles
106818
+ "bg-background flex flex-col text-xs text-foreground shadow-xl",
106819
+ // Mobile: absolute bottom sheet overlay sized via dvh so it
106820
+ // adapts to the on-screen keyboard / dynamic browser chrome.
106821
+ "max-md:fixed max-md:inset-x-0 max-md:bottom-0 max-md:top-auto max-md:w-full max-md:max-h-[75dvh] max-md:rounded-t-2xl max-md:border-t max-md:border-border max-md:z-30 max-md:pb-[max(env(safe-area-inset-bottom),0px)]",
106822
+ "max-md:transition-transform max-md:duration-200 max-md:ease-in-out",
106823
+ isOpen ? "max-md:translate-y-0" : "max-md:translate-y-full",
106824
+ // Desktop: flow-based flex child (takes space from canvas)
106825
+ "md:h-full md:border-l md:border-border",
106826
+ !panelWidth && "md:w-72"
106827
+ ),
106828
+ style: panelWidth ? { width: panelWidth } : void 0,
106829
+ children: [
106830
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "md:hidden flex items-center justify-center pt-2 pb-1", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-1 w-10 rounded-full bg-muted-foreground/40" }) }),
106831
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2 px-3 py-2 border-b border-border", children: [
106832
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1 rounded bg-muted p-0.5", children: INSPECTOR_TABS.map(({ key, label, icon: Icon }) => /* @__PURE__ */ jsxRuntime.jsxs(
106833
+ "button",
106834
+ {
106835
+ type: "button",
106836
+ title: label,
106837
+ className: cn(
106838
+ "flex items-center gap-1 px-2 py-1 rounded text-[11px] transition-colors",
106839
+ activeTab === key ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:text-foreground hover:bg-accent"
106840
+ ),
106841
+ onClick: () => onSetActiveTab(key),
106842
+ children: [
106843
+ /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "w-3.5 h-3.5" }),
106844
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "hidden sm:inline", children: label })
106845
+ ]
106846
+ },
106847
+ key
106848
+ )) }),
106135
106849
  /* @__PURE__ */ jsxRuntime.jsx(
106136
- PresentationPropertiesPanel,
106850
+ "button",
106137
106851
  {
106138
- canEdit,
106139
- canvasSize,
106140
- presentationProperties,
106141
- onUpdatePresentationProperties,
106142
- notesMaster,
106143
- handoutMaster,
106144
- notesCanvasSize,
106145
- coreProperties,
106146
- appProperties,
106147
- customProperties,
106148
- themeOptions,
106149
- selectedThemePath,
106150
- setSelectedThemePath,
106151
- onApplyTheme,
106152
- onUpdateCoreProperties,
106153
- onUpdateAppProperties,
106154
- onUpdateCustomProperties,
106155
- tagCollections,
106156
- onUpdateTagCollections,
106157
- onUpdateCanvasSize,
106158
- activeSlide,
106159
- theme,
106160
- onUpdateSlide
106852
+ type: "button",
106853
+ onClick: onClose,
106854
+ title: t2("common.close"),
106855
+ className: "p-1 rounded text-muted-foreground hover:text-foreground hover:bg-muted transition-colors",
106856
+ children: /* @__PURE__ */ jsxRuntime.jsx(lu.LuX, { className: "w-4 h-4" })
106161
106857
  }
106162
- ),
106163
- activeSlide && /* @__PURE__ */ jsxRuntime.jsx(
106164
- SlideBackgroundPanel,
106858
+ )
106859
+ ] }),
106860
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto p-3 space-y-3", children: [
106861
+ activeTab === "elements" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1", children: [
106862
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn(HEADING, "mb-2"), children: t2("pptx.inspector.layerOrder") }),
106863
+ activeSlide ? [...activeSlide.elements || []].reverse().map((el, ri) => {
106864
+ const idx = (activeSlide.elements || []).length - 1 - ri;
106865
+ const sel = selectedElement?.id === el.id || selectedElementIds.includes(el.id);
106866
+ const label = (pptxViewerCore.hasTextProperties(el) ? (el.text || "").slice(0, 24) : void 0) || el.type;
106867
+ return /* @__PURE__ */ jsxRuntime.jsxs(
106868
+ "div",
106869
+ {
106870
+ title: `${el.type} \u2014 ${el.id}`,
106871
+ className: cn(
106872
+ "flex items-center gap-2 px-2 py-1 rounded cursor-pointer transition-colors",
106873
+ sel ? "bg-primary/30 text-primary" : "hover:bg-muted text-foreground"
106874
+ ),
106875
+ onClick: () => onSelectElement(el.id),
106876
+ children: [
106877
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground w-4 text-right", children: idx + 1 }),
106878
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 truncate", children: label })
106879
+ ]
106880
+ },
106881
+ el.id
106882
+ );
106883
+ }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-muted-foreground italic", children: t2("pptx.inspector.noSlideSelected") })
106884
+ ] }),
106885
+ activeTab === "properties" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: hasSelection && selectedElement ? /* @__PURE__ */ jsxRuntime.jsx(
106886
+ ElementInspectorBody,
106165
106887
  {
106166
- activeSlide,
106888
+ selectedElement,
106167
106889
  canEdit,
106168
- onUpdateSlide,
106169
- editTemplateMode,
106170
- slideMasters,
106171
- onSetTemplateBackground,
106172
- onGetTemplateBackgroundColor
106890
+ slides,
106891
+ tableEditorState,
106892
+ mediaDataUrls,
106893
+ onUpdateElement,
106894
+ onUpdateElementStyle,
106895
+ onUpdateTextStyle,
106896
+ onMoveLayer
106173
106897
  }
106174
- )
106175
- ] }) }),
106176
- activeTab === "comments" && /* @__PURE__ */ jsxRuntime.jsx(
106177
- InspectorCommentsSection,
106178
- {
106179
- comments,
106180
- canEdit,
106181
- activeSlide,
106182
- selectedElement,
106183
- editingCommentId,
106184
- commentEditDraft,
106185
- commentDraft,
106186
- replyingToCommentId: replyingToCommentId ?? null,
106187
- replyDraftByCommentId: replyDraftByCommentId ?? {},
106188
- onSetCommentDraft,
106189
- onAddComment,
106190
- onDeleteComment,
106191
- onStartEditComment,
106192
- onSaveEditComment,
106193
- onCancelEditComment,
106194
- onSetCommentEditDraft,
106195
- onToggleCommentResolved,
106196
- onStartReply,
106197
- onCancelReply,
106198
- onReplyDraftChange,
106199
- onSubmitReply,
106200
- onSelectElement
106201
- }
106202
- )
106203
- ] }),
106204
- hasSelection && selectedElement && activeSlide && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
106205
- /* @__PURE__ */ jsxRuntime.jsx(ResizeHandle, { direction: "vertical", onResize: onResizeAnim }),
106206
- /* @__PURE__ */ jsxRuntime.jsx(
106207
- "div",
106208
- {
106209
- className: "border-t border-border p-3 overflow-y-auto flex-shrink-0",
106210
- style: { height: animPanelHeight },
106211
- children: /* @__PURE__ */ jsxRuntime.jsx(
106212
- AnimationPanel,
106898
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
106899
+ /* @__PURE__ */ jsxRuntime.jsx(
106900
+ PresentationPropertiesPanel,
106213
106901
  {
106214
- selectedElement,
106215
- activeSlide,
106216
106902
  canEdit,
106903
+ canvasSize,
106904
+ presentationProperties,
106905
+ onUpdatePresentationProperties,
106906
+ notesMaster,
106907
+ handoutMaster,
106908
+ notesCanvasSize,
106909
+ coreProperties,
106910
+ appProperties,
106911
+ customProperties,
106912
+ themeOptions,
106913
+ selectedThemePath,
106914
+ setSelectedThemePath,
106915
+ onApplyTheme,
106916
+ onUpdateCoreProperties,
106917
+ onUpdateAppProperties,
106918
+ onUpdateCustomProperties,
106919
+ tagCollections,
106920
+ onUpdateTagCollections,
106921
+ onUpdateCanvasSize,
106922
+ activeSlide,
106923
+ theme,
106217
106924
  onUpdateSlide
106218
106925
  }
106926
+ ),
106927
+ activeSlide && /* @__PURE__ */ jsxRuntime.jsx(
106928
+ SlideBackgroundPanel,
106929
+ {
106930
+ activeSlide,
106931
+ canEdit,
106932
+ onUpdateSlide,
106933
+ editTemplateMode,
106934
+ slideMasters,
106935
+ onSetTemplateBackground,
106936
+ onGetTemplateBackgroundColor
106937
+ }
106219
106938
  )
106220
- }
106221
- )
106222
- ] })
106223
- ]
106224
- }
106225
- );
106939
+ ] }) }),
106940
+ activeTab === "comments" && /* @__PURE__ */ jsxRuntime.jsx(
106941
+ InspectorCommentsSection,
106942
+ {
106943
+ comments,
106944
+ canEdit,
106945
+ activeSlide,
106946
+ selectedElement,
106947
+ editingCommentId,
106948
+ commentEditDraft,
106949
+ commentDraft,
106950
+ replyingToCommentId: replyingToCommentId ?? null,
106951
+ replyDraftByCommentId: replyDraftByCommentId ?? {},
106952
+ onSetCommentDraft,
106953
+ onAddComment,
106954
+ onDeleteComment,
106955
+ onStartEditComment,
106956
+ onSaveEditComment,
106957
+ onCancelEditComment,
106958
+ onSetCommentEditDraft,
106959
+ onToggleCommentResolved,
106960
+ onStartReply,
106961
+ onCancelReply,
106962
+ onReplyDraftChange,
106963
+ onSubmitReply,
106964
+ onSelectElement
106965
+ }
106966
+ )
106967
+ ] }),
106968
+ hasSelection && selectedElement && activeSlide && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
106969
+ /* @__PURE__ */ jsxRuntime.jsx(ResizeHandle, { direction: "vertical", onResize: onResizeAnim }),
106970
+ /* @__PURE__ */ jsxRuntime.jsx(
106971
+ "div",
106972
+ {
106973
+ className: "border-t border-border p-3 overflow-y-auto flex-shrink-0",
106974
+ style: { height: animPanelHeight },
106975
+ children: /* @__PURE__ */ jsxRuntime.jsx(
106976
+ AnimationPanel,
106977
+ {
106978
+ selectedElement,
106979
+ activeSlide,
106980
+ canEdit,
106981
+ onUpdateSlide
106982
+ }
106983
+ )
106984
+ }
106985
+ )
106986
+ ] })
106987
+ ]
106988
+ }
106989
+ )
106990
+ ] });
106226
106991
  }
106227
106992
  function buildPathD(points) {
106228
106993
  if (points.length === 0) {
@@ -110356,7 +111121,8 @@ function ViewerBottomPanels({
110356
111121
  onZoomToFit,
110357
111122
  mode,
110358
111123
  onSetMode,
110359
- onToggleSlideSorter
111124
+ onToggleSlideSorter,
111125
+ hideStatusBar = false
110360
111126
  }) {
110361
111127
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
110362
111128
  onResizeBottom && !isSlideNotesCollapsed && /* @__PURE__ */ jsxRuntime.jsx(ResizeHandle, { direction: "vertical", onResize: onResizeBottom }),
@@ -110372,7 +111138,7 @@ function ViewerBottomPanels({
110372
111138
  panelHeight: notesPanelHeight
110373
111139
  }
110374
111140
  ),
110375
- /* @__PURE__ */ jsxRuntime.jsx(
111141
+ !hideStatusBar && /* @__PURE__ */ jsxRuntime.jsx(
110376
111142
  StatusBar,
110377
111143
  {
110378
111144
  slideCount,
@@ -110529,6 +111295,45 @@ function ViewerInspector({
110529
111295
  }
110530
111296
  );
110531
111297
  }
111298
+
111299
+ // src/viewer/hooks/useScopedLayoutOptions.ts
111300
+ function scopeLayoutOptionsToActiveSlide(options, activeSlide) {
111301
+ if (!activeSlide?.layoutPath) {
111302
+ return options;
111303
+ }
111304
+ const hasAnyMasterInfo = options.some((o3) => o3.masterPath);
111305
+ if (!hasAnyMasterInfo) {
111306
+ return options;
111307
+ }
111308
+ const activeOption = options.find((o3) => o3.path === activeSlide.layoutPath);
111309
+ const activeMaster = activeOption?.masterPath;
111310
+ if (!activeMaster) {
111311
+ return options;
111312
+ }
111313
+ const scoped = options.filter((o3) => o3.masterPath === activeMaster);
111314
+ const seen = /* @__PURE__ */ new Map();
111315
+ for (const opt of scoped) {
111316
+ const isActive = opt.path === activeSlide.layoutPath;
111317
+ const existing = seen.get(opt.name);
111318
+ if (!existing || isActive) {
111319
+ seen.set(opt.name, opt);
111320
+ }
111321
+ }
111322
+ const chosen = new Set(Array.from(seen.values()).map((o3) => o3.path));
111323
+ const result = [];
111324
+ const usedNames = /* @__PURE__ */ new Set();
111325
+ for (const opt of scoped) {
111326
+ if (!chosen.has(opt.path)) {
111327
+ continue;
111328
+ }
111329
+ if (usedNames.has(opt.name)) {
111330
+ continue;
111331
+ }
111332
+ usedNames.add(opt.name);
111333
+ result.push(opt);
111334
+ }
111335
+ return result;
111336
+ }
110532
111337
  function ViewerToolbarSection(props) {
110533
111338
  const {
110534
111339
  mode,
@@ -110598,6 +111403,10 @@ function ViewerToolbarSection(props) {
110598
111403
  },
110599
111404
  [activeSlide, propertyHandlers]
110600
111405
  );
111406
+ const scopedLayoutOptions = React10__namespace.default.useMemo(
111407
+ () => scopeLayoutOptionsToActiveSlide(s.layoutOptions, activeSlide),
111408
+ [s.layoutOptions, activeSlide]
111409
+ );
110601
111410
  const handleApplyTransitionToAll = React10.useCallback(() => {
110602
111411
  const transition = activeSlide?.transition;
110603
111412
  if (!transition) {
@@ -110704,7 +111513,7 @@ function ViewerToolbarSection(props) {
110704
111513
  onUpdateTextStyle: ops.updateSelectedTextStyle,
110705
111514
  isOverflowMenuOpen: s.isOverflowMenuOpen,
110706
111515
  onSetOverflowMenuOpen: s.setIsOverflowMenuOpen,
110707
- layoutOptions: s.layoutOptions,
111516
+ layoutOptions: scopedLayoutOptions,
110708
111517
  onInsertSlideFromLayout: slideOps.handleInsertSlideFromLayout,
110709
111518
  customShows: s.customShows,
110710
111519
  activeCustomShowId: s.activeCustomShowId,
@@ -110737,6 +111546,7 @@ function ViewerToolbarSection(props) {
110737
111546
  isCommentsPanelOpen: s.isInspectorPaneOpen,
110738
111547
  slideCommentCount: activeSlide?.comments?.length ?? 0,
110739
111548
  formatPainterActive: s.formatPainterActive,
111549
+ canActivateFormatPainter: hasCopyableFormat(selectedElement),
110740
111550
  onToggleFormatPainter: onToggleFormatPainterProp ?? (() => s.setFormatPainterActive((p3) => !p3)),
110741
111551
  isSelectionPaneOpen: s.isSelectionPaneOpen,
110742
111552
  onToggleSelectionPane: () => s.setIsSelectionPaneOpen((p3) => !p3),
@@ -113885,6 +114695,166 @@ function ViewerMainContent(props) {
113885
114695
  )
113886
114696
  ] });
113887
114697
  }
114698
+ function MobileBottomBar({
114699
+ onOpenSlides,
114700
+ onOpenInsert,
114701
+ onOpenInspector,
114702
+ onOpenComments,
114703
+ onToggleNotes,
114704
+ activeSheet,
114705
+ commentCount
114706
+ }) {
114707
+ const actions = [
114708
+ {
114709
+ key: "slides",
114710
+ label: "Slides",
114711
+ icon: lu.LuLayers,
114712
+ onClick: onOpenSlides
114713
+ },
114714
+ {
114715
+ key: "insert",
114716
+ label: "Insert",
114717
+ icon: lu.LuPlus,
114718
+ onClick: onOpenInsert
114719
+ },
114720
+ {
114721
+ key: "inspector",
114722
+ label: "Format",
114723
+ icon: lu.LuSettings2,
114724
+ onClick: onOpenInspector
114725
+ },
114726
+ {
114727
+ key: "comments",
114728
+ label: "Comments",
114729
+ icon: lu.LuMessageSquare,
114730
+ onClick: onOpenComments,
114731
+ badge: commentCount
114732
+ },
114733
+ {
114734
+ key: "notes",
114735
+ label: "Notes",
114736
+ icon: lu.LuStickyNote,
114737
+ onClick: onToggleNotes
114738
+ }
114739
+ ];
114740
+ return /* @__PURE__ */ jsxRuntime.jsx(
114741
+ "nav",
114742
+ {
114743
+ "aria-label": "Editor actions",
114744
+ className: "md:hidden flex items-stretch justify-around border-t border-border bg-secondary/80 backdrop-blur supports-[backdrop-filter]:bg-secondary/60 pb-[max(env(safe-area-inset-bottom),0px)]",
114745
+ children: actions.map(({ key, label, icon: Icon, onClick, badge }) => {
114746
+ const active = activeSheet === key;
114747
+ return /* @__PURE__ */ jsxRuntime.jsxs(
114748
+ "button",
114749
+ {
114750
+ type: "button",
114751
+ onClick,
114752
+ className: cn(
114753
+ "relative flex flex-col items-center justify-center gap-0.5 flex-1 min-h-[56px] py-1.5 text-[10px] font-medium transition-colors active:scale-95",
114754
+ active ? "text-primary" : "text-muted-foreground hover:text-foreground"
114755
+ ),
114756
+ "aria-pressed": active,
114757
+ children: [
114758
+ /* @__PURE__ */ jsxRuntime.jsx(Icon, { className: "w-5 h-5" }),
114759
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: label }),
114760
+ badge !== void 0 && badge > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute top-1 right-1/4 flex items-center justify-center min-w-[16px] h-4 px-1 rounded-full bg-primary text-[9px] font-semibold text-primary-foreground", children: badge > 99 ? "99+" : badge }),
114761
+ active && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute top-0 left-1/2 -translate-x-1/2 w-8 h-0.5 rounded-full bg-primary" })
114762
+ ]
114763
+ },
114764
+ key
114765
+ );
114766
+ })
114767
+ }
114768
+ );
114769
+ }
114770
+ function MobileSlidesSheet({
114771
+ open,
114772
+ onClose,
114773
+ ...sidebar
114774
+ }) {
114775
+ return /* @__PURE__ */ jsxRuntime.jsx(MobileSheet, { open, onClose, heightFraction: 0.7, title: "Slides", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full", children: /* @__PURE__ */ jsxRuntime.jsx(SlidesPaneSidebar, { ...sidebar }) }) });
114776
+ }
114777
+ function MobileChromeOverlay(props) {
114778
+ const {
114779
+ state: s,
114780
+ editorOps,
114781
+ presentation,
114782
+ slides,
114783
+ activeSlideIndex,
114784
+ canvasSize,
114785
+ slideSectionGroups,
114786
+ canEdit,
114787
+ commentCount
114788
+ } = props;
114789
+ const activeSheet = s.isSlidesPaneOpen ? "slides" : s.isInspectorPaneOpen ? s.sidebarPanelMode === "comments" ? "comments" : "inspector" : !s.isSlideNotesCollapsed ? "notes" : null;
114790
+ const closeAllSheets = () => {
114791
+ s.setIsSlidesPaneOpen(false);
114792
+ s.setIsInspectorPaneOpen(false);
114793
+ s.setIsSlideNotesCollapsed(true);
114794
+ };
114795
+ const openSheet = (which) => {
114796
+ closeAllSheets();
114797
+ switch (which) {
114798
+ case "slides":
114799
+ s.setIsSlidesPaneOpen(true);
114800
+ break;
114801
+ case "inspector":
114802
+ s.setSidebarPanelMode("properties");
114803
+ s.setIsInspectorPaneOpen(true);
114804
+ break;
114805
+ case "comments":
114806
+ s.setSidebarPanelMode("comments");
114807
+ s.setIsInspectorPaneOpen(true);
114808
+ break;
114809
+ case "notes":
114810
+ s.setIsSlideNotesCollapsed(false);
114811
+ break;
114812
+ }
114813
+ };
114814
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
114815
+ /* @__PURE__ */ jsxRuntime.jsx(
114816
+ MobileSlidesSheet,
114817
+ {
114818
+ open: s.isSlidesPaneOpen,
114819
+ onClose: () => s.setIsSlidesPaneOpen(false),
114820
+ slides,
114821
+ activeSlideIndex,
114822
+ canvasSize,
114823
+ sectionGroups: slideSectionGroups,
114824
+ isOpen: true,
114825
+ canEdit,
114826
+ onSelectSlide: (index) => {
114827
+ s.setActiveSlideIndex(index);
114828
+ s.setIsSlidesPaneOpen(false);
114829
+ },
114830
+ onSlideContextMenu: editorOps.slideOps.handleSlideContextMenu,
114831
+ onMoveSlide: editorOps.slideOps.handleMoveSlide,
114832
+ onAddSlide: editorOps.slideOps.handleAddSlide,
114833
+ onCollapse: () => s.setIsSlidesPaneOpen(false),
114834
+ onAddSection: editorOps.sectionOps.addSection,
114835
+ onRenameSection: editorOps.sectionOps.renameSection,
114836
+ onDeleteSection: editorOps.sectionOps.deleteSection,
114837
+ onMoveSectionUp: editorOps.sectionOps.moveSectionUp,
114838
+ onMoveSectionDown: editorOps.sectionOps.moveSectionDown,
114839
+ rehearsalTimings: Object.keys(presentation.recordedTimings).length > 0 ? presentation.recordedTimings : void 0
114840
+ }
114841
+ ),
114842
+ /* @__PURE__ */ jsxRuntime.jsx(
114843
+ MobileBottomBar,
114844
+ {
114845
+ activeSheet,
114846
+ commentCount,
114847
+ onOpenSlides: () => s.isSlidesPaneOpen ? s.setIsSlidesPaneOpen(false) : openSheet("slides"),
114848
+ onOpenInsert: () => {
114849
+ editorOps.insertHandlers.handleAddTextBox();
114850
+ },
114851
+ onOpenInspector: () => s.isInspectorPaneOpen && s.sidebarPanelMode !== "comments" ? s.setIsInspectorPaneOpen(false) : openSheet("inspector"),
114852
+ onOpenComments: () => s.isInspectorPaneOpen && s.sidebarPanelMode === "comments" ? s.setIsInspectorPaneOpen(false) : openSheet("comments"),
114853
+ onToggleNotes: () => !s.isSlideNotesCollapsed ? s.setIsSlideNotesCollapsed(true) : openSheet("notes")
114854
+ }
114855
+ )
114856
+ ] });
114857
+ }
113888
114858
  function ToggleSwitch({
113889
114859
  label,
113890
114860
  enabled,
@@ -114077,14 +115047,10 @@ function useYjsDocumentSync({
114077
115047
  const lastSyncedRef = React10.useRef("");
114078
115048
  const hasInitializedRef = React10.useRef(false);
114079
115049
  const getDocMap = React10.useCallback(() => {
114080
- if (!doc2 || typeof doc2 !== "object") {
115050
+ if (!doc2) {
114081
115051
  return null;
114082
115052
  }
114083
- const d = doc2;
114084
- if (typeof d.getMap !== "function") {
114085
- return null;
114086
- }
114087
- return d.getMap("slides-data");
115053
+ return doc2.getMap("slides-data");
114088
115054
  }, [doc2]);
114089
115055
  React10.useEffect(() => {
114090
115056
  if (!isConnected || !doc2) {
@@ -114105,10 +115071,9 @@ function useYjsDocumentSync({
114105
115071
  return;
114106
115072
  }
114107
115073
  lastSyncedRef.current = serialized;
114108
- const d = doc2;
114109
- d.transact(() => {
115074
+ doc2.transact(() => {
114110
115075
  const currentCount = map3.get("count");
114111
- if (currentCount && currentCount > slides.length) {
115076
+ if (typeof currentCount === "number" && currentCount > slides.length) {
114112
115077
  for (let i3 = slides.length; i3 < currentCount; i3++) {
114113
115078
  map3.delete(`slide-${i3}`);
114114
115079
  }
@@ -114133,13 +115098,13 @@ function useYjsDocumentSync({
114133
115098
  }
114134
115099
  const handleUpdate = () => {
114135
115100
  const count = map3.get("count");
114136
- if (!count || count === 0) {
115101
+ if (typeof count !== "number" || count === 0) {
114137
115102
  return;
114138
115103
  }
114139
115104
  const remoteSlides = [];
114140
115105
  for (let i3 = 0; i3 < count; i3++) {
114141
115106
  const slideJson = map3.get(`slide-${i3}`);
114142
- if (slideJson) {
115107
+ if (typeof slideJson === "string") {
114143
115108
  try {
114144
115109
  remoteSlides.push(JSON.parse(slideJson));
114145
115110
  } catch {
@@ -114164,7 +115129,7 @@ function useYjsDocumentSync({
114164
115129
  if (!hasInitializedRef.current) {
114165
115130
  hasInitializedRef.current = true;
114166
115131
  const count = map3.get("count");
114167
- if (count && count > 0) {
115132
+ if (typeof count === "number" && count > 0) {
114168
115133
  handleUpdate();
114169
115134
  }
114170
115135
  }
@@ -114725,13 +115690,14 @@ function useCanvasInteractions(input) {
114725
115690
  if (e2.button !== 0) {
114726
115691
  return;
114727
115692
  }
114728
- if (!selectedElementIdSet.has(elementId)) {
115693
+ const wasSelected = selectedElementIdSet.has(elementId);
115694
+ if (!wasSelected) {
114729
115695
  ops.applySelection(elementId);
114730
115696
  justSelectedRef.current = true;
114731
115697
  } else {
114732
115698
  justSelectedRef.current = false;
114733
115699
  }
114734
- const ids = effectiveSelectedIds.length ? effectiveSelectedIds : [elementId];
115700
+ const ids = !wasSelected ? [elementId] : effectiveSelectedIds.length ? effectiveSelectedIds : [elementId];
114735
115701
  const startPositions = {};
114736
115702
  const domEls = /* @__PURE__ */ new Map();
114737
115703
  for (const id2 of ids) {
@@ -116768,8 +117734,14 @@ function useSectionOperations(input) {
116768
117734
  }
116769
117735
 
116770
117736
  // src/viewer/hooks/useSlideManagement.ts
117737
+ function insertSlideFromLayoutUpdater(slides, activeIndex, draft) {
117738
+ const next = [...slides];
117739
+ const insertAt = Math.max(0, Math.min(activeIndex + 1, next.length));
117740
+ next.splice(insertAt, 0, draft);
117741
+ return next;
117742
+ }
116771
117743
  function useSlideManagement(input) {
116772
- const { slides, activeSlideIndex, setActiveSlideIndex, ops, history } = input;
117744
+ const { slides, activeSlideIndex, setActiveSlideIndex, ops, history, handlerRef } = input;
116773
117745
  const handleAddSlide = () => {
116774
117746
  const newSlide = {
116775
117747
  id: `slide-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
@@ -116868,8 +117840,42 @@ function useSlideManagement(input) {
116868
117840
  });
116869
117841
  history.markDirty();
116870
117842
  };
116871
- const handleInsertSlideFromLayout = (_layoutPath) => {
116872
- handleAddSlide();
117843
+ const handleInsertSlideFromLayout = (layoutPath, layoutName) => {
117844
+ const insertAt = activeSlideIndex + 1;
117845
+ const draft = {
117846
+ id: `slide-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
117847
+ rId: "",
117848
+ slideNumber: slides.length + 1,
117849
+ elements: [],
117850
+ layoutPath,
117851
+ ...layoutName ? { layoutName } : {}
117852
+ };
117853
+ let inserted = [];
117854
+ ops.updateSlides((prev) => {
117855
+ inserted = insertSlideFromLayoutUpdater(prev, activeSlideIndex, draft);
117856
+ return inserted;
117857
+ });
117858
+ setActiveSlideIndex(insertAt);
117859
+ history.markDirty();
117860
+ const handler = handlerRef?.current;
117861
+ if (handler) {
117862
+ void handler.applyLayoutToSlide(insertAt, layoutPath, inserted).then(
117863
+ (updated) => {
117864
+ ops.updateSlides((prev) => {
117865
+ if (prev[insertAt]?.id !== draft.id) {
117866
+ return prev;
117867
+ }
117868
+ const next = [...prev];
117869
+ next[insertAt] = updated;
117870
+ return next;
117871
+ });
117872
+ return void 0;
117873
+ },
117874
+ () => {
117875
+ return void 0;
117876
+ }
117877
+ );
117878
+ }
116873
117879
  };
116874
117880
  return {
116875
117881
  handleAddSlide,
@@ -117405,7 +118411,8 @@ function useEditorOperations(input) {
117405
118411
  canvasSize,
117406
118412
  dialogs,
117407
118413
  presentation,
117408
- userName
118414
+ userName,
118415
+ handlerRef
117409
118416
  } = input;
117410
118417
  const ops = useElementOperations({
117411
118418
  activeSlide,
@@ -117507,7 +118514,8 @@ function useEditorOperations(input) {
117507
118514
  activeSlideIndex,
117508
118515
  setActiveSlideIndex: state2.setActiveSlideIndex,
117509
118516
  ops,
117510
- history
118517
+ history,
118518
+ handlerRef
117511
118519
  });
117512
118520
  const tableOps = useTableOperations({
117513
118521
  selectedElement,
@@ -117536,21 +118544,34 @@ function useEditorOperations(input) {
117536
118544
  );
117537
118545
  const copiedFormatRef = React10.useRef(null);
117538
118546
  const prevFormatPainterRef = React10.useRef(false);
118547
+ const { formatPainterActive, setFormatPainterActive, elementLookup } = state2;
117539
118548
  React10.useEffect(() => {
117540
- if (state2.formatPainterActive && !prevFormatPainterRef.current && selectedElement) {
118549
+ if (formatPainterActive && !prevFormatPainterRef.current && selectedElement) {
117541
118550
  copiedFormatRef.current = copyFormatFromElement(selectedElement);
117542
- } else if (!state2.formatPainterActive) {
118551
+ } else if (!formatPainterActive) {
117543
118552
  copiedFormatRef.current = null;
117544
118553
  }
117545
- prevFormatPainterRef.current = state2.formatPainterActive;
117546
- }, [state2.formatPainterActive, selectedElement]);
118554
+ prevFormatPainterRef.current = formatPainterActive;
118555
+ }, [formatPainterActive, selectedElement]);
118556
+ React10.useEffect(() => {
118557
+ if (!formatPainterActive) {
118558
+ return;
118559
+ }
118560
+ const onKey = (e2) => {
118561
+ if (e2.key === "Escape") {
118562
+ setFormatPainterActive(false);
118563
+ }
118564
+ };
118565
+ window.addEventListener("keydown", onKey);
118566
+ return () => window.removeEventListener("keydown", onKey);
118567
+ }, [formatPainterActive, setFormatPainterActive]);
117547
118568
  const formatPainterCanvasHandlers = React10.useMemo(
117548
118569
  () => ({
117549
118570
  ...canvasHandlers,
117550
118571
  handleElementClick: (elementId, e2) => {
117551
- if (state2.formatPainterActive && copiedFormatRef.current) {
118572
+ if (formatPainterActive && copiedFormatRef.current) {
117552
118573
  e2.stopPropagation();
117553
- const element2 = state2.elementLookup.get(elementId);
118574
+ const element2 = elementLookup.get(elementId);
117554
118575
  if (element2) {
117555
118576
  const updated = applyFormatToElement(element2, copiedFormatRef.current);
117556
118577
  const updates = {};
@@ -117563,14 +118584,21 @@ function useEditorOperations(input) {
117563
118584
  ops.updateElementById(elementId, updates);
117564
118585
  }
117565
118586
  copiedFormatRef.current = null;
117566
- state2.setFormatPainterActive(false);
118587
+ setFormatPainterActive(false);
117567
118588
  ops.applySelection(elementId);
117568
118589
  return;
117569
118590
  }
117570
118591
  canvasHandlers.handleElementClick(elementId, e2);
118592
+ },
118593
+ handleCanvasMouseDown: (e2) => {
118594
+ if (formatPainterActive) {
118595
+ setFormatPainterActive(false);
118596
+ return;
118597
+ }
118598
+ canvasHandlers.handleCanvasMouseDown(e2);
117571
118599
  }
117572
118600
  }),
117573
- [canvasHandlers, ops, state2]
118601
+ [canvasHandlers, ops, formatPainterActive, setFormatPainterActive, elementLookup]
117574
118602
  );
117575
118603
  return {
117576
118604
  ops: combinedOps,
@@ -119709,21 +120737,35 @@ function useViewerDialogs(input) {
119709
120737
  null
119710
120738
  );
119711
120739
  const [embedFontsEnabled, setEmbedFontsEnabled] = React10.useState(false);
119712
- const [isNarrowViewport, setIsNarrowViewport] = React10.useState(false);
120740
+ const [isNarrowViewport, setIsNarrowViewport] = React10.useState(
120741
+ () => typeof window !== "undefined" ? window.innerWidth < 768 : false
120742
+ );
119713
120743
  React10.useEffect(() => {
119714
- const el = containerRef.current;
119715
- if (!el) {
119716
- return;
119717
- }
119718
- const observer = new ResizeObserver((entries) => {
119719
- const entry = entries[0];
119720
- if (entry) {
119721
- setIsNarrowViewport(entry.contentRect.width < 768);
120744
+ const handleWindow = () => setIsNarrowViewport(window.innerWidth < 768);
120745
+ let observer = null;
120746
+ let raf = 0;
120747
+ const attach2 = () => {
120748
+ const el = containerRef.current;
120749
+ if (!el) {
120750
+ raf = requestAnimationFrame(attach2);
120751
+ return;
119722
120752
  }
119723
- });
119724
- observer.observe(el);
119725
- setIsNarrowViewport(el.clientWidth < 768);
119726
- return () => observer.disconnect();
120753
+ observer = new ResizeObserver((entries) => {
120754
+ const entry = entries[0];
120755
+ if (entry) {
120756
+ setIsNarrowViewport(entry.contentRect.width < 768);
120757
+ }
120758
+ });
120759
+ observer.observe(el);
120760
+ setIsNarrowViewport(el.clientWidth < 768);
120761
+ };
120762
+ attach2();
120763
+ window.addEventListener("resize", handleWindow);
120764
+ return () => {
120765
+ cancelAnimationFrame(raf);
120766
+ observer?.disconnect();
120767
+ window.removeEventListener("resize", handleWindow);
120768
+ };
119727
120769
  }, []);
119728
120770
  React10.useEffect(() => {
119729
120771
  if (isDirty && hasDigitalSignatures && !signatureStripAcknowledgedRef.current) {
@@ -124195,7 +125237,9 @@ function useViewerCoreState(_input) {
124195
125237
  function useViewerUIState() {
124196
125238
  const [isCompactToolbarOpen, setIsCompactToolbarOpen] = React10.useState(false);
124197
125239
  const [toolbarSection, setToolbarSection] = React10.useState("home");
124198
- const [isSlidesPaneOpen, setIsSlidesPaneOpen] = React10.useState(true);
125240
+ const [isSlidesPaneOpen, setIsSlidesPaneOpen] = React10.useState(
125241
+ () => typeof window === "undefined" ? true : window.innerWidth >= 768
125242
+ );
124199
125243
  const [isInspectorPaneOpen, setIsInspectorPaneOpen] = React10.useState(false);
124200
125244
  const [isSlideNotesCollapsed, setIsSlideNotesCollapsed] = React10.useState(true);
124201
125245
  const [isOverflowMenuOpen, setIsOverflowMenuOpen] = React10.useState(false);
@@ -124638,7 +125682,8 @@ var PowerPointViewer = React10.forwardRef(
124638
125682
  canvasSize,
124639
125683
  dialogs,
124640
125684
  presentation,
124641
- userName: authorName ?? collaboration?.userName
125685
+ userName: authorName ?? collaboration?.userName,
125686
+ handlerRef: actionSoundHandlerRef
124642
125687
  });
124643
125688
  const {
124644
125689
  exportHandlers,
@@ -124761,7 +125806,7 @@ var PowerPointViewer = React10.forwardRef(
124761
125806
  {
124762
125807
  activeSlide,
124763
125808
  allSlides: slides,
124764
- isSlideNotesCollapsed: isMobile || state2.isSlideNotesCollapsed,
125809
+ isSlideNotesCollapsed: state2.isSlideNotesCollapsed,
124765
125810
  canEdit,
124766
125811
  slideCount: slides.length,
124767
125812
  activeSlideIndex,
@@ -124778,7 +125823,22 @@ var PowerPointViewer = React10.forwardRef(
124778
125823
  onZoomToFit: zoom.handleZoomToFit,
124779
125824
  mode,
124780
125825
  onSetMode: handleSetMode,
124781
- onToggleSlideSorter: () => state2.setShowSlideSorter((p3) => !p3)
125826
+ onToggleSlideSorter: () => state2.setShowSlideSorter((p3) => !p3),
125827
+ hideStatusBar: isMobile
125828
+ }
125829
+ ),
125830
+ mode !== "present" && isMobile && /* @__PURE__ */ jsxRuntime.jsx(
125831
+ MobileChromeOverlay,
125832
+ {
125833
+ state: state2,
125834
+ editorOps,
125835
+ presentation,
125836
+ slides,
125837
+ activeSlideIndex,
125838
+ canvasSize,
125839
+ slideSectionGroups,
125840
+ canEdit,
125841
+ commentCount: activeSlide?.comments?.length ?? 0
124782
125842
  }
124783
125843
  ),
124784
125844
  /* @__PURE__ */ jsxRuntime.jsx(