ooxml-ui 1.26.0 → 1.26.2

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 (40) hide show
  1. package/dist/{chunk-WH3EGA3S.js → chunk-2EFIFIPB.js} +2 -2
  2. package/dist/{chunk-P4FRKIPE.js → chunk-W2JD75LX.js} +1 -0
  3. package/dist/docx/print-picture.d.ts +1 -0
  4. package/dist/docx.js +3 -2
  5. package/dist/index.js +3 -3
  6. package/dist/pptx/{chunk-LUDEAPHZ.cjs → chunk-4PYBBOIK.cjs} +43 -43
  7. package/dist/pptx/{chunk-CWHK7HF4.mjs → chunk-HF2YJASV.mjs} +1 -1
  8. package/dist/pptx/{chunk-HAO5PKWK.cjs → chunk-NFP4PCTP.cjs} +606 -314
  9. package/dist/pptx/{chunk-IWUIGVWT.mjs → chunk-R5GKUSHI.mjs} +607 -317
  10. package/dist/pptx/dom/index.cjs +385 -385
  11. package/dist/pptx/dom/index.mjs +5 -5
  12. package/dist/pptx/index.cjs +2996 -2988
  13. package/dist/pptx/index.mjs +1 -1
  14. package/dist/pptx/render/morph-animation.d.ts +11 -2
  15. package/dist/pptx/render/morph-animation.d.ts.map +1 -1
  16. package/dist/pptx/render/morph-geometry-keyframes.d.ts.map +1 -1
  17. package/dist/pptx/render/morph-matching.d.ts +1 -0
  18. package/dist/pptx/render/morph-matching.d.ts.map +1 -1
  19. package/dist/pptx/render/morph-stacked-copies.d.ts +20 -0
  20. package/dist/pptx/render/morph-stacked-copies.d.ts.map +1 -0
  21. package/dist/pptx/render/morph-text-flow.d.ts +48 -0
  22. package/dist/pptx/render/morph-text-flow.d.ts.map +1 -0
  23. package/dist/pptx/render/ribbon-galleries/themes-gallery.d.ts.map +1 -1
  24. package/dist/pptx/render/shape-geometry-cascade.d.ts.map +1 -1
  25. package/dist/pptx/render/stroke-clip-edge.d.ts +27 -0
  26. package/dist/pptx/render/stroke-clip-edge.d.ts.map +1 -0
  27. package/dist/pptx/render/stroke-clip-outset.d.ts +11 -1
  28. package/dist/pptx/render/stroke-clip-outset.d.ts.map +1 -1
  29. package/dist/pptx/render/stroke-outline.d.ts +13 -0
  30. package/dist/pptx/render/stroke-outline.d.ts.map +1 -1
  31. package/dist/pptx/render/stroke-style.d.ts +10 -1
  32. package/dist/pptx/render/stroke-style.d.ts.map +1 -1
  33. package/dist/pptx/{smartart-insert-preview-5ZTZYAZR.cjs → smartart-insert-preview-CTBWMXNX.cjs} +3 -3
  34. package/dist/pptx/{smartart-insert-preview-HMSNUWDO.mjs → smartart-insert-preview-QJBRDU4C.mjs} +2 -2
  35. package/dist/smartart.js +1 -1
  36. package/dist/teams.js +1 -1
  37. package/dist/xlsx/grid/styles.d.ts +1 -1
  38. package/dist/xlsx.js +5 -5
  39. package/package.json +2 -2
  40. /package/dist/{chunk-HGLCXNCT.js → chunk-WBE2Q5DC.js} +0 -0
@@ -1253,6 +1253,315 @@ function buildCustomPathMarkers(element, stroke) {
1253
1253
  const end = add2("End");
1254
1254
  return { markup: markup.join(""), start, end };
1255
1255
  }
1256
+
1257
+ // src/pptx/render/stroke-clip-outset.ts
1258
+ var SVG_DEFAULT_JOIN = { join: "miter", miterLimit: 4 };
1259
+ var ROUND_JOIN_STEPS = 16;
1260
+ var CURVE_STEPS = 16;
1261
+ function flattenArc(from, rx, ry, rotationDeg, largeArc, sweep, to) {
1262
+ if (rx === 0 || ry === 0 || from[0] === to[0] && from[1] === to[1]) {
1263
+ return [to];
1264
+ }
1265
+ const phi = rotationDeg * Math.PI / 180;
1266
+ const cosPhi = Math.cos(phi);
1267
+ const sinPhi = Math.sin(phi);
1268
+ const dx = (from[0] - to[0]) / 2;
1269
+ const dy = (from[1] - to[1]) / 2;
1270
+ const x1 = cosPhi * dx + sinPhi * dy;
1271
+ const y1 = -sinPhi * dx + cosPhi * dy;
1272
+ let radiusX = Math.abs(rx);
1273
+ let radiusY = Math.abs(ry);
1274
+ const lambda = x1 * x1 / (radiusX * radiusX) + y1 * y1 / (radiusY * radiusY);
1275
+ if (lambda > 1) {
1276
+ const scale2 = Math.sqrt(lambda);
1277
+ radiusX *= scale2;
1278
+ radiusY *= scale2;
1279
+ }
1280
+ const numerator = radiusX * radiusX * radiusY * radiusY - radiusX * radiusX * y1 * y1 - radiusY * radiusY * x1 * x1;
1281
+ const denominator = radiusX * radiusX * y1 * y1 + radiusY * radiusY * x1 * x1;
1282
+ const coefficient = (largeArc === sweep ? -1 : 1) * Math.sqrt(Math.max(0, numerator / denominator));
1283
+ const cxp = coefficient * radiusX * y1 / radiusY;
1284
+ const cyp = -coefficient * radiusY * x1 / radiusX;
1285
+ const cx = cosPhi * cxp - sinPhi * cyp + (from[0] + to[0]) / 2;
1286
+ const cy = sinPhi * cxp + cosPhi * cyp + (from[1] + to[1]) / 2;
1287
+ const angle = (ux, uy, vx, vy) => {
1288
+ const sign = ux * vy - uy * vx < 0 ? -1 : 1;
1289
+ const dot = (ux * vx + uy * vy) / (Math.hypot(ux, uy) * Math.hypot(vx, vy));
1290
+ return sign * Math.acos(Math.max(-1, Math.min(1, dot)));
1291
+ };
1292
+ const theta1 = angle(1, 0, (x1 - cxp) / radiusX, (y1 - cyp) / radiusY);
1293
+ let delta = angle(
1294
+ (x1 - cxp) / radiusX,
1295
+ (y1 - cyp) / radiusY,
1296
+ (-x1 - cxp) / radiusX,
1297
+ (-y1 - cyp) / radiusY
1298
+ );
1299
+ if (!sweep && delta > 0) {
1300
+ delta -= 2 * Math.PI;
1301
+ } else if (sweep && delta < 0) {
1302
+ delta += 2 * Math.PI;
1303
+ }
1304
+ const out = [];
1305
+ for (let step2 = 1; step2 <= CURVE_STEPS; step2++) {
1306
+ const t2 = theta1 + delta * step2 / CURVE_STEPS;
1307
+ const px3 = radiusX * Math.cos(t2);
1308
+ const py = radiusY * Math.sin(t2);
1309
+ out.push([cosPhi * px3 - sinPhi * py + cx, sinPhi * px3 + cosPhi * py + cy]);
1310
+ }
1311
+ return out;
1312
+ }
1313
+ function flattenPath(d) {
1314
+ const tokens = d.match(/[A-Za-z]|-?\d*\.?\d+(?:e[-+]?\d+)?/giu);
1315
+ if (!tokens) {
1316
+ return void 0;
1317
+ }
1318
+ const subpaths = [];
1319
+ let current = [];
1320
+ let pos = [0, 0];
1321
+ let start = [0, 0];
1322
+ let i = 0;
1323
+ let command2 = "";
1324
+ const num14 = () => Number.parseFloat(tokens[i++] ?? "NaN");
1325
+ while (i < tokens.length) {
1326
+ const token = tokens[i];
1327
+ if (/^[A-Za-z]$/u.test(token)) {
1328
+ command2 = token;
1329
+ i++;
1330
+ if (command2 === "Z" || command2 === "z") {
1331
+ if (current.length > 1) {
1332
+ subpaths.push(current);
1333
+ }
1334
+ current = [];
1335
+ pos = start;
1336
+ continue;
1337
+ }
1338
+ } else if (command2 === "M") {
1339
+ command2 = "L";
1340
+ }
1341
+ switch (command2) {
1342
+ case "M":
1343
+ if (current.length > 1) {
1344
+ subpaths.push(current);
1345
+ }
1346
+ pos = [num14(), num14()];
1347
+ start = pos;
1348
+ current = [pos];
1349
+ break;
1350
+ case "L":
1351
+ pos = [num14(), num14()];
1352
+ current.push(pos);
1353
+ break;
1354
+ case "H":
1355
+ pos = [num14(), pos[1]];
1356
+ current.push(pos);
1357
+ break;
1358
+ case "V":
1359
+ pos = [pos[0], num14()];
1360
+ current.push(pos);
1361
+ break;
1362
+ case "C": {
1363
+ const p1 = [num14(), num14()];
1364
+ const p2 = [num14(), num14()];
1365
+ const p3 = [num14(), num14()];
1366
+ for (let step2 = 1; step2 <= CURVE_STEPS; step2++) {
1367
+ const t2 = step2 / CURVE_STEPS;
1368
+ const u = 1 - t2;
1369
+ current.push([
1370
+ u * u * u * pos[0] + 3 * u * u * t2 * p1[0] + 3 * u * t2 * t2 * p2[0] + t2 * t2 * t2 * p3[0],
1371
+ u * u * u * pos[1] + 3 * u * u * t2 * p1[1] + 3 * u * t2 * t2 * p2[1] + t2 * t2 * t2 * p3[1]
1372
+ ]);
1373
+ }
1374
+ pos = p3;
1375
+ break;
1376
+ }
1377
+ case "Q": {
1378
+ const p1 = [num14(), num14()];
1379
+ const p2 = [num14(), num14()];
1380
+ for (let step2 = 1; step2 <= CURVE_STEPS; step2++) {
1381
+ const t2 = step2 / CURVE_STEPS;
1382
+ const u = 1 - t2;
1383
+ current.push([
1384
+ u * u * pos[0] + 2 * u * t2 * p1[0] + t2 * t2 * p2[0],
1385
+ u * u * pos[1] + 2 * u * t2 * p1[1] + t2 * t2 * p2[1]
1386
+ ]);
1387
+ }
1388
+ pos = p2;
1389
+ break;
1390
+ }
1391
+ case "A": {
1392
+ const rx = num14();
1393
+ const ry = num14();
1394
+ const rotation = num14();
1395
+ const largeArc = num14() !== 0;
1396
+ const sweep = num14() !== 0;
1397
+ const to = [num14(), num14()];
1398
+ current.push(...flattenArc(pos, rx, ry, rotation, largeArc, sweep, to));
1399
+ pos = to;
1400
+ break;
1401
+ }
1402
+ default:
1403
+ return void 0;
1404
+ }
1405
+ }
1406
+ if (current.length > 1) {
1407
+ subpaths.push(current);
1408
+ }
1409
+ return subpaths.every((sub) => sub.every(([x, y]) => Number.isFinite(x) && Number.isFinite(y))) ? subpaths : void 0;
1410
+ }
1411
+ var fmt = (n) => String(Math.round(n * 1e3) / 1e3);
1412
+ function outsetClipPathForStroke(clipPath, strokeWidth, width, height, join = SVG_DEFAULT_JOIN) {
1413
+ if (!(strokeWidth > 0)) {
1414
+ return clipPath;
1415
+ }
1416
+ const d = outlinePathData(clipPath, width, height);
1417
+ const subpaths = d ? flattenPath(d) : void 0;
1418
+ if (!d || !subpaths || subpaths.length === 0) {
1419
+ return clipPath;
1420
+ }
1421
+ const half = strokeWidth / 2;
1422
+ const signedArea4 = (pts) => {
1423
+ let area = 0;
1424
+ for (let k = 0; k < pts.length; k++) {
1425
+ const a = pts[k];
1426
+ const b = pts[(k + 1) % pts.length];
1427
+ area += a[0] * b[1] - b[0] * a[1];
1428
+ }
1429
+ return area;
1430
+ };
1431
+ const reference = Math.sign(signedArea4(subpaths[0])) || 1;
1432
+ const quads = [];
1433
+ const push = (poly3) => {
1434
+ const wound = Math.sign(signedArea4(poly3)) === reference ? poly3 : [...poly3].reverse();
1435
+ quads.push(`M ${wound.map(([x, y]) => `${fmt(x)} ${fmt(y)}`).join(" L ")} Z`);
1436
+ };
1437
+ for (const sub of subpaths) {
1438
+ const pts = sub;
1439
+ let last = [0, 0];
1440
+ const normals = pts.map((a, k) => {
1441
+ const b = pts[(k + 1) % pts.length];
1442
+ const len = Math.hypot(b[0] - a[0], b[1] - a[1]);
1443
+ if (len >= 1e-6) {
1444
+ last = [-(b[1] - a[1]) / len, (b[0] - a[0]) / len];
1445
+ }
1446
+ return last;
1447
+ });
1448
+ for (let k = 0; k < pts.length; k++) {
1449
+ const a = pts[k];
1450
+ const b = pts[(k + 1) % pts.length];
1451
+ const [nx, ny] = normals[k];
1452
+ push([
1453
+ [a[0] + nx * half, a[1] + ny * half],
1454
+ [b[0] + nx * half, b[1] + ny * half],
1455
+ [b[0] - nx * half, b[1] - ny * half],
1456
+ [a[0] - nx * half, a[1] - ny * half]
1457
+ ]);
1458
+ push(joinPiece(b, normals[k], normals[(k + 1) % pts.length]));
1459
+ }
1460
+ }
1461
+ function joinPiece(v, n1, n2) {
1462
+ if (join.join === "round") {
1463
+ const r = half / Math.cos(Math.PI / ROUND_JOIN_STEPS);
1464
+ return Array.from({ length: ROUND_JOIN_STEPS }, (_, i) => {
1465
+ const t2 = 2 * Math.PI * i / ROUND_JOIN_STEPS;
1466
+ return [v[0] + r * Math.cos(t2), v[1] + r * Math.sin(t2)];
1467
+ });
1468
+ }
1469
+ const turn = n1[0] * n2[1] - n1[1] * n2[0];
1470
+ if (Math.abs(turn) < 1e-9) {
1471
+ return [v, v, v, v];
1472
+ }
1473
+ const side = turn > 0 ? -1 : 1;
1474
+ const p1 = [v[0] + side * n1[0] * half, v[1] + side * n1[1] * half];
1475
+ const p2 = [v[0] + side * n2[0] * half, v[1] + side * n2[1] * half];
1476
+ const cosHalf = Math.sqrt(Math.max(0, (1 + n1[0] * n2[0] + n1[1] * n2[1]) / 2));
1477
+ if (join.join === "miter" && cosHalf > 0 && 1 / cosHalf <= join.miterLimit) {
1478
+ const bx = n1[0] + n2[0];
1479
+ const by = n1[1] + n2[1];
1480
+ const blen = Math.hypot(bx, by);
1481
+ const reach = half / cosHalf / blen;
1482
+ return [v, p1, [v[0] + side * bx * reach, v[1] + side * by * reach], p2];
1483
+ }
1484
+ return [v, p1, p2, p2];
1485
+ }
1486
+ return `path('${d} ${quads.join(" ")}')`;
1487
+ }
1488
+
1489
+ // src/pptx/render/stroke-clip-edge.ts
1490
+ var ROUND_JOIN_STEPS2 = 8;
1491
+ var fmt2 = (n) => String(Math.round(n * 1e3) / 1e3);
1492
+ function signedArea(pts) {
1493
+ let area = 0;
1494
+ for (let k = 0; k < pts.length; k++) {
1495
+ const a = pts[k];
1496
+ const b = pts[(k + 1) % pts.length];
1497
+ area += a[0] * b[1] - b[0] * a[1];
1498
+ }
1499
+ return area;
1500
+ }
1501
+ function offsetRing(pts, half, join, away) {
1502
+ let last = [0, 0];
1503
+ const normals = pts.map((a, k) => {
1504
+ const b = pts[(k + 1) % pts.length];
1505
+ const len = Math.hypot(b[0] - a[0], b[1] - a[1]);
1506
+ if (len >= 1e-6) {
1507
+ last = [away * -(b[1] - a[1]) / len, away * (b[0] - a[0]) / len];
1508
+ }
1509
+ return last;
1510
+ });
1511
+ const ring = [];
1512
+ for (let k = 0; k < pts.length; k++) {
1513
+ const v = pts[k];
1514
+ const n1 = normals[(k - 1 + pts.length) % pts.length];
1515
+ const n2 = normals[k];
1516
+ const p1 = [v[0] + n1[0] * half, v[1] + n1[1] * half];
1517
+ const p2 = [v[0] + n2[0] * half, v[1] + n2[1] * half];
1518
+ const cosHalf = Math.sqrt(Math.max(0, (1 + n1[0] * n2[0] + n1[1] * n2[1]) / 2));
1519
+ const bx = n1[0] + n2[0];
1520
+ const by = n1[1] + n2[1];
1521
+ const blen = Math.hypot(bx, by);
1522
+ const miter = cosHalf > 1e-6 && blen > 1e-9 ? [v[0] + bx / blen * (half / cosHalf), v[1] + by / blen * (half / cosHalf)] : void 0;
1523
+ const turn = n1[0] * n2[1] - n1[1] * n2[0];
1524
+ const opensOutward = away * turn < 0;
1525
+ if (!opensOutward || Math.abs(turn) < 1e-9) {
1526
+ ring.push(miter ?? p2);
1527
+ } else if (join.join === "miter" && miter && 1 / cosHalf <= join.miterLimit) {
1528
+ ring.push(miter);
1529
+ } else if (join.join === "round") {
1530
+ const a1 = Math.atan2(n1[1], n1[0]);
1531
+ let sweep = Math.atan2(n2[1], n2[0]) - a1;
1532
+ while (sweep > Math.PI) sweep -= 2 * Math.PI;
1533
+ while (sweep < -Math.PI) sweep += 2 * Math.PI;
1534
+ for (let i = 0; i <= ROUND_JOIN_STEPS2; i++) {
1535
+ const t2 = a1 + sweep * i / ROUND_JOIN_STEPS2;
1536
+ ring.push([v[0] + Math.cos(t2) * half, v[1] + Math.sin(t2) * half]);
1537
+ }
1538
+ } else {
1539
+ ring.push(p1, p2);
1540
+ }
1541
+ }
1542
+ return ring;
1543
+ }
1544
+ function outerStrokeEdgePath(d, strokeWidth, join) {
1545
+ if (!(strokeWidth > 0)) {
1546
+ return void 0;
1547
+ }
1548
+ const subpaths = flattenPath(d);
1549
+ if (!subpaths || subpaths.length === 0) {
1550
+ return void 0;
1551
+ }
1552
+ const reference = Math.sign(signedArea(subpaths[0])) || 1;
1553
+ return subpaths.filter((sub) => sub.length > 2).map((sub) => {
1554
+ const sign = Math.sign(signedArea(sub)) || reference;
1555
+ const away = sign > 0 ? -1 : 1;
1556
+ const ring = offsetRing(
1557
+ sub,
1558
+ strokeWidth / 2,
1559
+ join,
1560
+ sign === reference ? away : away === 1 ? -1 : 1
1561
+ );
1562
+ return `M ${ring.map(([x, y]) => `${fmt2(x)} ${fmt2(y)}`).join(" L ")} Z`;
1563
+ }).join(" ");
1564
+ }
1256
1565
  function getStrokeOnlyPresetPaths(element) {
1257
1566
  if (element.type !== "shape" || !pptx.hasShapeProperties(element)) {
1258
1567
  return void 0;
@@ -1287,6 +1596,79 @@ function strokeOnlyPresetPathData(element) {
1287
1596
  const stroked = paths.filter((path) => path.stroke !== false).map((path) => path.d);
1288
1597
  return stroked.length > 0 ? stroked.join(" ") : void 0;
1289
1598
  }
1599
+ var NO_STROKE = {
1600
+ borderWidth: 0,
1601
+ cssBorderWidth: "0px",
1602
+ borderStyle: void 0,
1603
+ borderColor: void 0,
1604
+ border: void 0,
1605
+ strokeLinejoin: void 0,
1606
+ strokeLinecap: void 0,
1607
+ strokeMiterlimit: void 0
1608
+ };
1609
+ function svgLineJoin(join) {
1610
+ switch (join) {
1611
+ case "round":
1612
+ return "round";
1613
+ case "bevel":
1614
+ return "bevel";
1615
+ case "miter":
1616
+ return "miter";
1617
+ default:
1618
+ return void 0;
1619
+ }
1620
+ }
1621
+ function svgStrokeLineCap(cap) {
1622
+ switch (cap) {
1623
+ case "rnd":
1624
+ return "round";
1625
+ case "sq":
1626
+ return "square";
1627
+ case "flat":
1628
+ return "butt";
1629
+ default:
1630
+ return void 0;
1631
+ }
1632
+ }
1633
+ function strokeMiterLimit(style) {
1634
+ if (style?.lineJoin !== "miter" || typeof style.miterLimit !== "number") {
1635
+ return void 0;
1636
+ }
1637
+ if (!Number.isFinite(style.miterLimit)) {
1638
+ return void 0;
1639
+ }
1640
+ return Math.max(style.miterLimit / 1e5, 1);
1641
+ }
1642
+ function getComputedStrokeStyle(element) {
1643
+ if (!pptx.hasShapeProperties(element)) {
1644
+ return NO_STROKE;
1645
+ }
1646
+ const style = element.shapeStyle;
1647
+ const width = suppressesCssBorder(element) ? 0 : paintedStrokeWidth(style);
1648
+ const joins = {
1649
+ strokeLinejoin: svgLineJoin(style?.lineJoin),
1650
+ strokeLinecap: svgStrokeLineCap(style?.lineCap),
1651
+ strokeMiterlimit: strokeMiterLimit(style)
1652
+ };
1653
+ if (width <= 0 || !style) {
1654
+ return { ...NO_STROKE, ...joins };
1655
+ }
1656
+ const borderWidth = width;
1657
+ const borderStyle = chunk6KLPQQYP_cjs.getCssBorderDashStyle(
1658
+ chunk6KLPQQYP_cjs.normalizeStrokeDashType(style.strokeDash),
1659
+ style.compoundLine
1660
+ );
1661
+ const rawColor = style.strokeColor ?? chunk6KLPQQYP_cjs.DEFAULT_STROKE_COLOR;
1662
+ const borderColor = style.strokeOpacity === void 0 ? rawColor : chunk6KLPQQYP_cjs.colorWithOpacity(chunk6KLPQQYP_cjs.normalizeHexColor(rawColor, chunk6KLPQQYP_cjs.DEFAULT_STROKE_COLOR), style.strokeOpacity);
1663
+ return {
1664
+ borderWidth,
1665
+ cssBorderWidth: chunkFM4C4MBJ_cjs.screenStrokeWidth(borderWidth),
1666
+ borderStyle,
1667
+ borderColor,
1668
+ border: chunkFM4C4MBJ_cjs.screenBorder(borderWidth, borderStyle ?? "solid", borderColor),
1669
+ ...joins
1670
+ };
1671
+ }
1290
1672
 
1291
1673
  // src/pptx/render/svg-gradient-rect-path.ts
1292
1674
  function buildRectPathGradientDef(stops, id, focalPoint, fillToRect) {
@@ -1521,6 +1903,33 @@ function needsCenteredStrokeOverlay(element, style, declaredWidth) {
1521
1903
  }
1522
1904
  return style.lineAlignment !== "in";
1523
1905
  }
1906
+ function clipEdgeBleed(element, d, style) {
1907
+ if ((style?.strokeOpacity ?? 1) < 1 || element.type === "picture" || element.type === "image" || isArrowedCustomPath(element)) {
1908
+ return void 0;
1909
+ }
1910
+ const width = straddlingStrokeWidth(element);
1911
+ const shapeType = pptx.getShapeType(element.shapeType);
1912
+ if (width <= 0 || shapeType === "roundRect" || shapeType === "ellipse" || isIdentityRectClip(element) || getResolvedShapeClipPath(element) === void 0) {
1913
+ return void 0;
1914
+ }
1915
+ const edge = outerStrokeEdgePath(d, width, outlineStrokeJoin(element));
1916
+ return edge ? {
1917
+ d: edge,
1918
+ strokeWidth: 1,
1919
+ cssStrokeWidth: `max(1px, calc(2 * var(${chunkFM4C4MBJ_cjs.DEVICE_PX_VAR}, 0px)))`,
1920
+ offset: 0
1921
+ } : void 0;
1922
+ }
1923
+ function insetLineOnClippedShape(element, style, declaredWidth) {
1924
+ if (!style || style.lineAlignment !== "in" || declaredWidth <= 0 || element.type === "connector" || element.type === "picture" || element.type === "image" || !hasStrokePaint(style)) {
1925
+ return false;
1926
+ }
1927
+ const shapeType = pptx.getShapeType(element.shapeType);
1928
+ if (shapeType === "line" || shapeType === "roundRect" || shapeType === "ellipse") {
1929
+ return false;
1930
+ }
1931
+ return !isIdentityRectClip(element) && getResolvedShapeClipPath(element) !== void 0;
1932
+ }
1524
1933
  function straddlingStrokeWidth(element) {
1525
1934
  if (!pptx.hasShapeProperties(element)) {
1526
1935
  return 0;
@@ -1533,6 +1942,11 @@ function straddlingStrokeWidth(element) {
1533
1942
  const dash = chunk6KLPQQYP_cjs.normalizeStrokeDashType(style?.strokeDash);
1534
1943
  return !dash || dash === "solid" ? width : 0;
1535
1944
  }
1945
+ function outlineStrokeJoin(element) {
1946
+ const style = pptx.hasShapeProperties(element) ? element.shapeStyle : void 0;
1947
+ const join = style?.lineJoin === "bevel" ? "bevel" : style?.lineJoin === "miter" ? "miter" : "round";
1948
+ return { join, miterLimit: strokeMiterLimit(style) ?? 4 };
1949
+ }
1536
1950
  function buildStrokeOutline(element) {
1537
1951
  if (!pptx.hasShapeProperties(element)) {
1538
1952
  return void 0;
@@ -1544,30 +1958,34 @@ function buildStrokeOutline(element) {
1544
1958
  return void 0;
1545
1959
  }
1546
1960
  const paint = style && declaredWidth > 0 ? buildSvgStrokeGradientDef(style, element.id) ?? buildSvgStrokePatternDef(style, element.id) : void 0;
1961
+ const insetOnClip = !openPresetD && insetLineOnClippedShape(element, style, declaredWidth);
1547
1962
  const centeredFlatStroke = !paint && !openPresetD && (isArrowedCustomPath(element) || needsCenteredStrokeOverlay(element, style, declaredWidth));
1548
- if (!paint && !openPresetD && !centeredFlatStroke) {
1963
+ if (!paint && !openPresetD && !centeredFlatStroke && !insetOnClip) {
1549
1964
  return void 0;
1550
1965
  }
1551
1966
  const d = openPresetD ?? outlinePathData(getResolvedShapeClipPath(element), element.width, element.height);
1552
1967
  if (!d) {
1553
1968
  return void 0;
1554
1969
  }
1555
- const strokeWidth = declaredWidth > 0 ? declaredWidth : DEFAULT_OPEN_PRESET_STROKE_WIDTH;
1970
+ const lineWidth = declaredWidth > 0 ? declaredWidth : DEFAULT_OPEN_PRESET_STROKE_WIDTH;
1971
+ const strokeWidth = insetOnClip ? lineWidth * 2 : lineWidth;
1556
1972
  const stroke = paint ? svgGradientFillRef(paint) : chunk6KLPQQYP_cjs.colorWithOpacity(style?.strokeColor ?? chunk6KLPQQYP_cjs.DEFAULT_STROKE_COLOR, style?.strokeOpacity);
1973
+ const strands = outlineStrands(style?.compoundLine, strokeWidth);
1974
+ const bleed = !openPresetD ? clipEdgeBleed(element, d, style) : void 0;
1557
1975
  return {
1558
1976
  markers: buildCustomPathMarkers(element, stroke),
1559
1977
  d,
1560
1978
  paint,
1561
1979
  stroke,
1562
1980
  strokeWidth,
1563
- strands: outlineStrands(style?.compoundLine, strokeWidth),
1981
+ strands: bleed ? [...strands, bleed] : strands,
1564
1982
  dashArray: chunk6KLPQQYP_cjs.getSvgStrokeDasharray(
1565
1983
  chunk6KLPQQYP_cjs.normalizeStrokeDashType(style?.strokeDash),
1566
- Math.max(strokeWidth, 1),
1984
+ Math.max(lineWidth, 1),
1567
1985
  style?.customDashSegments
1568
1986
  ),
1569
1987
  lineCap: svgLineCap(style?.lineCap),
1570
- lineJoin: style?.lineJoin === "bevel" ? "bevel" : style?.lineJoin === "miter" ? "miter" : "round"
1988
+ lineJoin: outlineStrokeJoin(element).join
1571
1989
  };
1572
1990
  }
1573
1991
  function strokeOutlineViewBox(element) {
@@ -1654,208 +2072,6 @@ function mapEditingWheel(input, buffer, canScrollFurther) {
1654
2072
  function mapPresentationWheel(input, buffer) {
1655
2073
  return accumulate(buffer, normalizeWheelDelta(input));
1656
2074
  }
1657
-
1658
- // src/pptx/render/stroke-clip-outset.ts
1659
- var CURVE_STEPS = 16;
1660
- function flattenArc(from, rx, ry, rotationDeg, largeArc, sweep, to) {
1661
- if (rx === 0 || ry === 0 || from[0] === to[0] && from[1] === to[1]) {
1662
- return [to];
1663
- }
1664
- const phi = rotationDeg * Math.PI / 180;
1665
- const cosPhi = Math.cos(phi);
1666
- const sinPhi = Math.sin(phi);
1667
- const dx = (from[0] - to[0]) / 2;
1668
- const dy = (from[1] - to[1]) / 2;
1669
- const x1 = cosPhi * dx + sinPhi * dy;
1670
- const y1 = -sinPhi * dx + cosPhi * dy;
1671
- let radiusX = Math.abs(rx);
1672
- let radiusY = Math.abs(ry);
1673
- const lambda = x1 * x1 / (radiusX * radiusX) + y1 * y1 / (radiusY * radiusY);
1674
- if (lambda > 1) {
1675
- const scale2 = Math.sqrt(lambda);
1676
- radiusX *= scale2;
1677
- radiusY *= scale2;
1678
- }
1679
- const numerator = radiusX * radiusX * radiusY * radiusY - radiusX * radiusX * y1 * y1 - radiusY * radiusY * x1 * x1;
1680
- const denominator = radiusX * radiusX * y1 * y1 + radiusY * radiusY * x1 * x1;
1681
- const coefficient = (largeArc === sweep ? -1 : 1) * Math.sqrt(Math.max(0, numerator / denominator));
1682
- const cxp = coefficient * radiusX * y1 / radiusY;
1683
- const cyp = -coefficient * radiusY * x1 / radiusX;
1684
- const cx = cosPhi * cxp - sinPhi * cyp + (from[0] + to[0]) / 2;
1685
- const cy = sinPhi * cxp + cosPhi * cyp + (from[1] + to[1]) / 2;
1686
- const angle = (ux, uy, vx, vy) => {
1687
- const sign = ux * vy - uy * vx < 0 ? -1 : 1;
1688
- const dot = (ux * vx + uy * vy) / (Math.hypot(ux, uy) * Math.hypot(vx, vy));
1689
- return sign * Math.acos(Math.max(-1, Math.min(1, dot)));
1690
- };
1691
- const theta1 = angle(1, 0, (x1 - cxp) / radiusX, (y1 - cyp) / radiusY);
1692
- let delta = angle(
1693
- (x1 - cxp) / radiusX,
1694
- (y1 - cyp) / radiusY,
1695
- (-x1 - cxp) / radiusX,
1696
- (-y1 - cyp) / radiusY
1697
- );
1698
- if (!sweep && delta > 0) {
1699
- delta -= 2 * Math.PI;
1700
- } else if (sweep && delta < 0) {
1701
- delta += 2 * Math.PI;
1702
- }
1703
- const out = [];
1704
- for (let step2 = 1; step2 <= CURVE_STEPS; step2++) {
1705
- const t2 = theta1 + delta * step2 / CURVE_STEPS;
1706
- const px3 = radiusX * Math.cos(t2);
1707
- const py = radiusY * Math.sin(t2);
1708
- out.push([cosPhi * px3 - sinPhi * py + cx, sinPhi * px3 + cosPhi * py + cy]);
1709
- }
1710
- return out;
1711
- }
1712
- function flattenPath(d) {
1713
- const tokens = d.match(/[A-Za-z]|-?\d*\.?\d+(?:e[-+]?\d+)?/giu);
1714
- if (!tokens) {
1715
- return void 0;
1716
- }
1717
- const subpaths = [];
1718
- let current = [];
1719
- let pos = [0, 0];
1720
- let start = [0, 0];
1721
- let i = 0;
1722
- let command2 = "";
1723
- const num14 = () => Number.parseFloat(tokens[i++] ?? "NaN");
1724
- while (i < tokens.length) {
1725
- const token = tokens[i];
1726
- if (/^[A-Za-z]$/u.test(token)) {
1727
- command2 = token;
1728
- i++;
1729
- if (command2 === "Z" || command2 === "z") {
1730
- if (current.length > 1) {
1731
- subpaths.push(current);
1732
- }
1733
- current = [];
1734
- pos = start;
1735
- continue;
1736
- }
1737
- } else if (command2 === "M") {
1738
- command2 = "L";
1739
- }
1740
- switch (command2) {
1741
- case "M":
1742
- if (current.length > 1) {
1743
- subpaths.push(current);
1744
- }
1745
- pos = [num14(), num14()];
1746
- start = pos;
1747
- current = [pos];
1748
- break;
1749
- case "L":
1750
- pos = [num14(), num14()];
1751
- current.push(pos);
1752
- break;
1753
- case "H":
1754
- pos = [num14(), pos[1]];
1755
- current.push(pos);
1756
- break;
1757
- case "V":
1758
- pos = [pos[0], num14()];
1759
- current.push(pos);
1760
- break;
1761
- case "C": {
1762
- const p1 = [num14(), num14()];
1763
- const p2 = [num14(), num14()];
1764
- const p3 = [num14(), num14()];
1765
- for (let step2 = 1; step2 <= CURVE_STEPS; step2++) {
1766
- const t2 = step2 / CURVE_STEPS;
1767
- const u = 1 - t2;
1768
- current.push([
1769
- u * u * u * pos[0] + 3 * u * u * t2 * p1[0] + 3 * u * t2 * t2 * p2[0] + t2 * t2 * t2 * p3[0],
1770
- u * u * u * pos[1] + 3 * u * u * t2 * p1[1] + 3 * u * t2 * t2 * p2[1] + t2 * t2 * t2 * p3[1]
1771
- ]);
1772
- }
1773
- pos = p3;
1774
- break;
1775
- }
1776
- case "Q": {
1777
- const p1 = [num14(), num14()];
1778
- const p2 = [num14(), num14()];
1779
- for (let step2 = 1; step2 <= CURVE_STEPS; step2++) {
1780
- const t2 = step2 / CURVE_STEPS;
1781
- const u = 1 - t2;
1782
- current.push([
1783
- u * u * pos[0] + 2 * u * t2 * p1[0] + t2 * t2 * p2[0],
1784
- u * u * pos[1] + 2 * u * t2 * p1[1] + t2 * t2 * p2[1]
1785
- ]);
1786
- }
1787
- pos = p2;
1788
- break;
1789
- }
1790
- case "A": {
1791
- const rx = num14();
1792
- const ry = num14();
1793
- const rotation = num14();
1794
- const largeArc = num14() !== 0;
1795
- const sweep = num14() !== 0;
1796
- const to = [num14(), num14()];
1797
- current.push(...flattenArc(pos, rx, ry, rotation, largeArc, sweep, to));
1798
- pos = to;
1799
- break;
1800
- }
1801
- default:
1802
- return void 0;
1803
- }
1804
- }
1805
- if (current.length > 1) {
1806
- subpaths.push(current);
1807
- }
1808
- return subpaths.every((sub) => sub.every(([x, y]) => Number.isFinite(x) && Number.isFinite(y))) ? subpaths : void 0;
1809
- }
1810
- var fmt = (n) => String(Math.round(n * 1e3) / 1e3);
1811
- function outsetClipPathForStroke(clipPath, strokeWidth, width, height) {
1812
- if (!(strokeWidth > 0)) {
1813
- return clipPath;
1814
- }
1815
- const d = outlinePathData(clipPath, width, height);
1816
- const subpaths = d ? flattenPath(d) : void 0;
1817
- if (!d || !subpaths || subpaths.length === 0) {
1818
- return clipPath;
1819
- }
1820
- const half = strokeWidth / 2;
1821
- const signedArea3 = (pts) => {
1822
- let area = 0;
1823
- for (let k = 0; k < pts.length; k++) {
1824
- const a = pts[k];
1825
- const b = pts[(k + 1) % pts.length];
1826
- area += a[0] * b[1] - b[0] * a[1];
1827
- }
1828
- return area;
1829
- };
1830
- const reference = Math.sign(signedArea3(subpaths[0])) || 1;
1831
- const quads = [];
1832
- for (const sub of subpaths) {
1833
- const closed = [...sub, sub[0]];
1834
- for (let k = 0; k < closed.length - 1; k++) {
1835
- const a = closed[k];
1836
- const b = closed[k + 1];
1837
- const len = Math.hypot(b[0] - a[0], b[1] - a[1]);
1838
- if (len < 1e-6) {
1839
- continue;
1840
- }
1841
- const nx = -(b[1] - a[1]) / len * half;
1842
- const ny = (b[0] - a[0]) / len * half;
1843
- let quad2 = [
1844
- [a[0] + nx, a[1] + ny],
1845
- [b[0] + nx, b[1] + ny],
1846
- [b[0] - nx, b[1] - ny],
1847
- [a[0] - nx, a[1] - ny]
1848
- ];
1849
- if (Math.sign(signedArea3(quad2)) !== reference) {
1850
- quad2 = quad2.reverse();
1851
- }
1852
- quads.push(`M ${quad2.map(([x, y]) => `${fmt(x)} ${fmt(y)}`).join(" L ")} Z`);
1853
- }
1854
- }
1855
- return `path('${d} ${quads.join(" ")}')`;
1856
- }
1857
-
1858
- // src/pptx/render/shape-geometry-cascade.ts
1859
2075
  var CYLINDER_RADIUS = "48% / 12%";
1860
2076
  var MIN_ROUND_RECT_RADIUS_PX = 0.01;
1861
2077
  function resolveShapeGeometry(element) {
@@ -1878,7 +2094,13 @@ function resolveShapeGeometry(element) {
1878
2094
  const stroke = straddlingStrokeWidth(element);
1879
2095
  return {
1880
2096
  kind: "clipPath",
1881
- clipPath: stroke > 0 ? outsetClipPathForStroke(clipPath, stroke, element.width, element.height) : clipPath
2097
+ clipPath: stroke > 0 ? outsetClipPathForStroke(
2098
+ clipPath,
2099
+ stroke,
2100
+ element.width,
2101
+ element.height,
2102
+ outlineStrokeJoin(element)
2103
+ ) : clipPath
1882
2104
  };
1883
2105
  }
1884
2106
  if (shapeType === "line") {
@@ -2141,79 +2363,6 @@ function buildColorAnimationKeyframes(colorAnim, keyframeName2, steps = 10, them
2141
2363
  ${lines.join("\n")}
2142
2364
  }` : void 0;
2143
2365
  }
2144
- var NO_STROKE = {
2145
- borderWidth: 0,
2146
- cssBorderWidth: "0px",
2147
- borderStyle: void 0,
2148
- borderColor: void 0,
2149
- border: void 0,
2150
- strokeLinejoin: void 0,
2151
- strokeLinecap: void 0,
2152
- strokeMiterlimit: void 0
2153
- };
2154
- function svgLineJoin(join) {
2155
- switch (join) {
2156
- case "round":
2157
- return "round";
2158
- case "bevel":
2159
- return "bevel";
2160
- case "miter":
2161
- return "miter";
2162
- default:
2163
- return void 0;
2164
- }
2165
- }
2166
- function svgStrokeLineCap(cap) {
2167
- switch (cap) {
2168
- case "rnd":
2169
- return "round";
2170
- case "sq":
2171
- return "square";
2172
- case "flat":
2173
- return "butt";
2174
- default:
2175
- return void 0;
2176
- }
2177
- }
2178
- function strokeMiterLimit(style) {
2179
- if (style?.lineJoin !== "miter" || typeof style.miterLimit !== "number") {
2180
- return void 0;
2181
- }
2182
- if (!Number.isFinite(style.miterLimit)) {
2183
- return void 0;
2184
- }
2185
- return Math.max(style.miterLimit / 1e5, 1);
2186
- }
2187
- function getComputedStrokeStyle(element) {
2188
- if (!pptx.hasShapeProperties(element)) {
2189
- return NO_STROKE;
2190
- }
2191
- const style = element.shapeStyle;
2192
- const width = suppressesCssBorder(element) ? 0 : paintedStrokeWidth(style);
2193
- const joins = {
2194
- strokeLinejoin: svgLineJoin(style?.lineJoin),
2195
- strokeLinecap: svgStrokeLineCap(style?.lineCap),
2196
- strokeMiterlimit: strokeMiterLimit(style)
2197
- };
2198
- if (width <= 0 || !style) {
2199
- return { ...NO_STROKE, ...joins };
2200
- }
2201
- const borderWidth = width;
2202
- const borderStyle = chunk6KLPQQYP_cjs.getCssBorderDashStyle(
2203
- chunk6KLPQQYP_cjs.normalizeStrokeDashType(style.strokeDash),
2204
- style.compoundLine
2205
- );
2206
- const rawColor = style.strokeColor ?? chunk6KLPQQYP_cjs.DEFAULT_STROKE_COLOR;
2207
- const borderColor = style.strokeOpacity === void 0 ? rawColor : chunk6KLPQQYP_cjs.colorWithOpacity(chunk6KLPQQYP_cjs.normalizeHexColor(rawColor, chunk6KLPQQYP_cjs.DEFAULT_STROKE_COLOR), style.strokeOpacity);
2208
- return {
2209
- borderWidth,
2210
- cssBorderWidth: chunkFM4C4MBJ_cjs.screenStrokeWidth(borderWidth),
2211
- borderStyle,
2212
- borderColor,
2213
- border: chunkFM4C4MBJ_cjs.screenBorder(borderWidth, borderStyle ?? "solid", borderColor),
2214
- ...joins
2215
- };
2216
- }
2217
2366
 
2218
2367
  // src/pptx/render/animation-color-base-style.ts
2219
2368
  function getAnimationColorBaseStyle(element, options = {}) {
@@ -6979,7 +7128,7 @@ function buildGlyphEnvelope(preset2, segments, width, height, align2, adj, adj2,
6979
7128
  }
6980
7129
 
6981
7130
  // src/pptx/render/text-warp-glyph-trace-contour.ts
6982
- function signedArea(ring) {
7131
+ function signedArea2(ring) {
6983
7132
  let area = 0;
6984
7133
  for (let i = 0; i < ring.length; i++) {
6985
7134
  const a = ring[i];
@@ -7120,7 +7269,7 @@ function contourRaster(values, w, h, level) {
7120
7269
  0
7121
7270
  );
7122
7271
  const wantPositive = depth % 2 === 0;
7123
- return signedArea(ring) > 0 === wantPositive ? ring : ring.slice().reverse();
7272
+ return signedArea2(ring) > 0 === wantPositive ? ring : ring.slice().reverse();
7124
7273
  });
7125
7274
  }
7126
7275
 
@@ -11109,7 +11258,7 @@ function powerPointAccelDecelProgress(t2, accel, decel) {
11109
11258
  function rampStopCount(fraction) {
11110
11259
  return Math.max(3, Math.ceil(12 * Math.sqrt(fraction)));
11111
11260
  }
11112
- function fmt2(value, digits) {
11261
+ function fmt3(value, digits) {
11113
11262
  return String(Number(value.toFixed(digits)));
11114
11263
  }
11115
11264
  function linearEasing(a, d) {
@@ -11127,11 +11276,11 @@ function linearEasing(a, d) {
11127
11276
  addRamp(1 - d, d);
11128
11277
  }
11129
11278
  const stops = [...times].sort((x, y) => x - y).map((t2) => {
11130
- const value = fmt2(powerPointAccelDecelProgress(t2, a, d), 4);
11279
+ const value = fmt3(powerPointAccelDecelProgress(t2, a, d), 4);
11131
11280
  if (t2 === 0 || t2 === 1) {
11132
11281
  return value;
11133
11282
  }
11134
- return `${value} ${fmt2(t2 * 100, 2)}%`;
11283
+ return `${value} ${fmt3(t2 * 100, 2)}%`;
11135
11284
  });
11136
11285
  return `linear(${stops.join(", ")})`;
11137
11286
  }
@@ -18037,25 +18186,25 @@ function createBehaviorPlayer(anim, box) {
18037
18186
  // src/pptx/render/animation-behavior-keyframes.ts
18038
18187
  var DENSE_SAMPLES = 60;
18039
18188
  var HOLD_EPSILON = 1e-5;
18040
- function fmt3(value, digits = 4) {
18189
+ function fmt4(value, digits = 4) {
18041
18190
  const rounded = Number(value.toFixed(digits));
18042
18191
  return String(Object.is(rounded, -0) ? 0 : rounded);
18043
18192
  }
18044
18193
  function declarations(frame, usage) {
18045
18194
  const parts = [
18046
- usage.slidePx ? `translate(${fmt3(frame.dx * usage.slidePx.width, 2)}px, ${fmt3(frame.dy * usage.slidePx.height, 2)}px)` : `translate(calc(var(--pptx-slide-w, 1280px) * ${fmt3(frame.dx)}), calc(var(--pptx-slide-h, 720px) * ${fmt3(frame.dy)}))`
18195
+ usage.slidePx ? `translate(${fmt4(frame.dx * usage.slidePx.width, 2)}px, ${fmt4(frame.dy * usage.slidePx.height, 2)}px)` : `translate(calc(var(--pptx-slide-w, 1280px) * ${fmt4(frame.dx)}), calc(var(--pptx-slide-h, 720px) * ${fmt4(frame.dy)}))`
18047
18196
  ];
18048
18197
  if (usage.rotate) {
18049
- parts.push(`rotate(${fmt3(frame.rotation, 2)}deg)`);
18198
+ parts.push(`rotate(${fmt4(frame.rotation, 2)}deg)`);
18050
18199
  }
18051
18200
  if (usage.shear) {
18052
- parts.push(`skewX(${fmt3(Math.atan(frame.shearX) * 180 / Math.PI, 2)}deg)`);
18201
+ parts.push(`skewX(${fmt4(Math.atan(frame.shearX) * 180 / Math.PI, 2)}deg)`);
18053
18202
  }
18054
18203
  if (usage.scale) {
18055
- parts.push(`scale(${fmt3(frame.scaleX)}, ${fmt3(frame.scaleY)})`);
18204
+ parts.push(`scale(${fmt4(frame.scaleX)}, ${fmt4(frame.scaleY)})`);
18056
18205
  }
18057
18206
  const mask = usage.wipeEdge ? ` ${maskEdgePartialDecl(usage.wipeEdge, frame.wipe?.revealed ?? 1)}` : "";
18058
- return `opacity: ${fmt3(frame.opacity, 3)}; transform: ${parts.join(" ")};${mask}`;
18207
+ return `opacity: ${fmt4(frame.opacity, 3)}; transform: ${parts.join(" ")};${mask}`;
18059
18208
  }
18060
18209
  function buildBehaviorKeyframes(anim, uid2, box, options = {}) {
18061
18210
  const player = createBehaviorPlayer(anim, box);
@@ -18089,7 +18238,7 @@ function buildBehaviorKeyframes(anim, uid2, box, options = {}) {
18089
18238
  };
18090
18239
  const name = `${options.prefix ?? "pptx-tl-bhvr"}-${uid2}`;
18091
18240
  const lines = frames.map(
18092
- ({ offset, frame }) => ` ${fmt3(offset * 100, 3)}% { ${declarations(frame, usage)} }`
18241
+ ({ offset, frame }) => ` ${fmt4(offset * 100, 3)}% { ${declarations(frame, usage)} }`
18093
18242
  );
18094
18243
  if (anim.presetClass === "entr") {
18095
18244
  lines[0] = lines[0].replace(/^\t0% \{ opacity: [\d.]+;/u, " 0% { opacity: 0;");
@@ -32626,7 +32775,7 @@ function resamplePolygon(poly3, count) {
32626
32775
  }
32627
32776
  return result;
32628
32777
  }
32629
- function signedArea2(poly3) {
32778
+ function signedArea3(poly3) {
32630
32779
  let area = 0;
32631
32780
  for (let i = 0; i < poly3.length; i++) {
32632
32781
  const a = poly3[i];
@@ -32664,7 +32813,7 @@ function bestRotation(from, to) {
32664
32813
  function normalizeOutlinePair(fromPoly, toPoly, count = OUTLINE_SAMPLE_COUNT) {
32665
32814
  const from = resamplePolygon(fromPoly, count);
32666
32815
  let to = resamplePolygon(toPoly, count);
32667
- if (Math.sign(signedArea2(from)) !== Math.sign(signedArea2(to))) {
32816
+ if (Math.sign(signedArea3(from)) !== Math.sign(signedArea3(to))) {
32668
32817
  to = [...to].reverse();
32669
32818
  }
32670
32819
  const offset = bestRotation(from, to);
@@ -32726,6 +32875,8 @@ function buildClipKeyframeBody(from, to, steps) {
32726
32875
  if (fromRing.length === 0 || toRing.length === 0) {
32727
32876
  return null;
32728
32877
  }
32878
+ const stroke = straddlingStrokeWidth(to);
32879
+ const join = outlineStrokeJoin(to);
32729
32880
  const lines = [];
32730
32881
  for (let s = 0; s <= steps; s++) {
32731
32882
  const t2 = s / steps;
@@ -32733,9 +32884,11 @@ function buildClipKeyframeBody(from, to, steps) {
32733
32884
  if (!d) {
32734
32885
  return null;
32735
32886
  }
32887
+ const clip = `path('${d}')`;
32888
+ const widened = stroke > 0 ? outsetClipPathForStroke(clip, stroke, to.width, to.height, join) : clip;
32736
32889
  const pct4 = Number((s / steps * 100).toFixed(2));
32737
32890
  lines.push(` ${pct4}% {
32738
- clip-path: path('${d}');
32891
+ clip-path: ${widened};
32739
32892
  }`);
32740
32893
  }
32741
32894
  return lines.join("\n");
@@ -33350,6 +33503,74 @@ function matchIdenticalTwins(fromElements, toElements, usedFrom, usedTo) {
33350
33503
  return pairs;
33351
33504
  }
33352
33505
 
33506
+ // src/pptx/render/morph-text-flow.ts
33507
+ function paragraphsOf(element) {
33508
+ const text4 = element.text ?? "";
33509
+ return text4.split(/[\n\r\v]/u).map((paragraph2) => paragraph2.replace(/\s+/gu, " ").trim()).filter((paragraph2) => paragraph2 !== "");
33510
+ }
33511
+ function distinctiveParagraphs(elements) {
33512
+ const owner = /* @__PURE__ */ new Map();
33513
+ for (const element of elements) {
33514
+ for (const paragraph2 of new Set(paragraphsOf(element))) {
33515
+ owner.set(paragraph2, owner.has(paragraph2) ? null : element);
33516
+ }
33517
+ }
33518
+ const distinctive = /* @__PURE__ */ new Map();
33519
+ for (const [paragraph2, element] of owner) {
33520
+ if (element) {
33521
+ distinctive.set(paragraph2, element);
33522
+ }
33523
+ }
33524
+ return distinctive;
33525
+ }
33526
+ function morphTextFlow(fromElements, toElements) {
33527
+ return { from: distinctiveParagraphs(fromElements), to: distinctiveParagraphs(toElements) };
33528
+ }
33529
+ function splitsTextFlow(flow, fromEl, toEl) {
33530
+ const elsewhere = (element, own, other, partner) => paragraphsOf(element).some((paragraph2) => {
33531
+ if (own.get(paragraph2) !== element) {
33532
+ return false;
33533
+ }
33534
+ const holder = other.get(paragraph2);
33535
+ return holder !== void 0 && holder !== partner;
33536
+ });
33537
+ return elsewhere(fromEl, flow.from, flow.to, toEl) || elsewhere(toEl, flow.to, flow.from, fromEl);
33538
+ }
33539
+ var MIN_TWIN_TEXT = 4;
33540
+ function matchTextTwins(fromElements, toElements, usedFrom, usedTo) {
33541
+ const byText = (elements) => {
33542
+ const map = /* @__PURE__ */ new Map();
33543
+ for (const element of elements) {
33544
+ if (element.type !== "text") {
33545
+ continue;
33546
+ }
33547
+ const text4 = paragraphsOf(element).join("\n");
33548
+ if (text4.replace(/\s/gu, "").length < MIN_TWIN_TEXT) {
33549
+ continue;
33550
+ }
33551
+ map.set(text4, [...map.get(text4) ?? [], element]);
33552
+ }
33553
+ return map;
33554
+ };
33555
+ const toByText = byText(toElements);
33556
+ const pairs = [];
33557
+ for (const [text4, froms] of byText(fromElements)) {
33558
+ const tos = toByText.get(text4);
33559
+ const fromEl = froms[0];
33560
+ const toEl = tos?.[0];
33561
+ if (froms.length !== 1 || tos?.length !== 1 || !fromEl || !toEl) {
33562
+ continue;
33563
+ }
33564
+ if (usedFrom.has(fromEl.id) || usedTo.has(toEl.id)) {
33565
+ continue;
33566
+ }
33567
+ pairs.push({ fromElement: fromEl, toElement: toEl });
33568
+ usedFrom.add(fromEl.id);
33569
+ usedTo.add(toEl.id);
33570
+ }
33571
+ return pairs;
33572
+ }
33573
+
33353
33574
  // src/pptx/render/morph-matching.ts
33354
33575
  var NV_PR_KEYS = [
33355
33576
  "p:nvSpPr",
@@ -33392,6 +33613,7 @@ function matchMorphElementsFull(fromSlide, toSlide) {
33392
33613
  const usedTo = /* @__PURE__ */ new Set();
33393
33614
  const fromElements = flattenMorphElements(fromSlide.elements, toSlide.elements);
33394
33615
  const toElements = flattenMorphElements(toSlide.elements, fromSlide.elements);
33616
+ const textFlow = morphTextFlow(fromElements, toElements);
33395
33617
  for (const fromEl of fromElements) {
33396
33618
  const fromName = getElementMorphName(fromEl);
33397
33619
  if (!fromName) {
@@ -33430,6 +33652,9 @@ function matchMorphElementsFull(fromSlide, toSlide) {
33430
33652
  continue;
33431
33653
  }
33432
33654
  if (creationIdOf(toEl) === fromGuid) {
33655
+ if (splitsTextFlow(textFlow, fromEl, toEl)) {
33656
+ break;
33657
+ }
33433
33658
  pairs.push({ fromElement: fromEl, toElement: toEl });
33434
33659
  usedFrom.add(fromEl.id);
33435
33660
  usedTo.add(toEl.id);
@@ -33457,6 +33682,7 @@ function matchMorphElementsFull(fromSlide, toSlide) {
33457
33682
  pairs.push(...matchSameMedia(fromElements, toElements, usedFrom, usedTo));
33458
33683
  pairs.push(...matchIdenticalTwins(fromElements, toElements, usedFrom, usedTo));
33459
33684
  pairs.push(...matchNamedTextTwins(fromElements, toElements, usedFrom, usedTo));
33685
+ pairs.push(...matchTextTwins(fromElements, toElements, usedFrom, usedTo));
33460
33686
  pairs.push(...matchGroupTwins(fromElements, toElements, usedFrom, usedTo));
33461
33687
  for (const fromEl of fromElements) {
33462
33688
  if (usedFrom.has(fromEl.id) || !fromEl.shapeId) {
@@ -33470,7 +33696,7 @@ function matchMorphElementsFull(fromSlide, toSlide) {
33470
33696
  if (creationIdOf(fromEl) && creationIdOf(toEl)) {
33471
33697
  continue;
33472
33698
  }
33473
- if (conflictingMorphNames(fromEl, toEl)) {
33699
+ if (conflictingMorphNames(fromEl, toEl) || splitsTextFlow(textFlow, fromEl, toEl)) {
33474
33700
  continue;
33475
33701
  }
33476
33702
  pairs.push({ fromElement: fromEl, toElement: toEl });
@@ -33770,17 +33996,53 @@ function matchTextTokens(fromTokens, toTokens) {
33770
33996
  return pairs;
33771
33997
  }
33772
33998
 
33999
+ // src/pptx/render/morph-stacked-copies.ts
34000
+ var MAX_COPY_OFFSET = 4;
34001
+ function ownText(element) {
34002
+ return (element.text ?? "").replace(/\s+/gu, " ").trim();
34003
+ }
34004
+ function isStackedCopy(a, b) {
34005
+ if (a.type !== b.type || (a.rotation ?? 0) !== (b.rotation ?? 0)) {
34006
+ return false;
34007
+ }
34008
+ if (Math.abs(a.width - b.width) > 1 || Math.abs(a.height - b.height) > 1) {
34009
+ return false;
34010
+ }
34011
+ if (Math.hypot(a.x - b.x, a.y - b.y) > MAX_COPY_OFFSET) {
34012
+ return false;
34013
+ }
34014
+ const text4 = ownText(a);
34015
+ if (text4 !== "") {
34016
+ return text4 === ownText(b);
34017
+ }
34018
+ const media = mediaIdentity(a);
34019
+ return media !== void 0 && media === mediaIdentity(b);
34020
+ }
34021
+ function coveredStackedCopyIds(elements) {
34022
+ const covered = /* @__PURE__ */ new Set();
34023
+ for (let i = 0; i < elements.length; i++) {
34024
+ const lower = elements[i];
34025
+ for (let j = i + 1; j < elements.length; j++) {
34026
+ if (isStackedCopy(lower, elements[j])) {
34027
+ covered.add(lower.id);
34028
+ break;
34029
+ }
34030
+ }
34031
+ }
34032
+ return covered;
34033
+ }
34034
+
33773
34035
  // src/pptx/render/morph-text-slot.ts
33774
34036
  var SAME_SLOT_OVERLAP = 0.4;
33775
- function ownText(element) {
34037
+ function ownText2(element) {
33776
34038
  return (element.text ?? "").replace(/\s+/gu, " ").trim();
33777
34039
  }
33778
34040
  function morphTextReplacedInSlot(fromElement, toElement) {
33779
34041
  if (fromElement.type !== "text" || toElement.type !== "text") {
33780
34042
  return false;
33781
34043
  }
33782
- const from = ownText(fromElement);
33783
- const to = ownText(toElement);
34044
+ const from = ownText2(fromElement);
34045
+ const to = ownText2(toElement);
33784
34046
  if (from === "" || to === "" || from === to) {
33785
34047
  return false;
33786
34048
  }
@@ -34013,6 +34275,12 @@ function appearanceSignature2(element, depth = 0) {
34013
34275
  parts.push(image.imagePath ?? "", image.svgPath ?? "");
34014
34276
  if (pptx.hasTextProperties(element)) {
34015
34277
  parts.push(element.text ?? "", element.textStyle?.color ?? "");
34278
+ for (const segment of element.textSegments ?? []) {
34279
+ const style = segment.style;
34280
+ parts.push(
34281
+ `${style?.fontSize ?? ""}|${style?.bold ? 1 : 0}|${style?.italic ? 1 : 0}|${style?.underline ? 1 : 0}|${style?.fontFamily ?? ""}|${style?.color ?? ""}`
34282
+ );
34283
+ }
34016
34284
  }
34017
34285
  const children = element.children;
34018
34286
  if (children && depth < SIGNATURE_MAX_DEPTH) {
@@ -34239,10 +34507,21 @@ function flipFactors(el) {
34239
34507
  return ` scaleX(${el.flipHorizontal ? -1 : 1}) scaleY(${el.flipVertical ? -1 : 1})`;
34240
34508
  }
34241
34509
  function generateUnmatchedFadeOutAnimations(elements, durationMs, startIndex) {
34510
+ const covered = coveredStackedCopyIds(elements);
34242
34511
  return elements.map((el, i) => {
34243
34512
  const safeName = `pptx-morph-fadeout-${startIndex + i}-${el.id.replace(/[^a-zA-Z0-9]/gu, "")}`;
34244
34513
  const transform = ` transform: scale(1)${staticTransformSuffix(el)};`;
34245
- const keyframes = `
34514
+ const keyframes = covered.has(el.id) ? `
34515
+ @keyframes ${safeName} {
34516
+ 0%, ${MORPH_FADE_OUT_HOLD_PERCENT}% {
34517
+ opacity: ${el.opacity ?? 1};
34518
+ ${transform}
34519
+ }
34520
+ ${MORPH_FADE_OUT_HOLD_PERCENT + 0.1}%, 100% {
34521
+ opacity: 0;
34522
+ ${transform}
34523
+ }
34524
+ }` : `
34246
34525
  @keyframes ${safeName} {
34247
34526
  0% {
34248
34527
  opacity: ${el.opacity ?? 1};
@@ -34269,10 +34548,21 @@ ${transform}
34269
34548
  });
34270
34549
  }
34271
34550
  function generateUnmatchedFadeInAnimations(elements, durationMs, startIndex) {
34551
+ const covered = coveredStackedCopyIds(elements);
34272
34552
  return elements.map((el, i) => {
34273
34553
  const safeName = `pptx-morph-fadein-${startIndex + i}-${el.id.replace(/[^a-zA-Z0-9]/gu, "")}`;
34274
34554
  const transform = ` transform: scale(1)${staticTransformSuffix(el)};`;
34275
- const keyframes = `
34555
+ const keyframes = covered.has(el.id) ? `
34556
+ @keyframes ${safeName} {
34557
+ 0%, 99.9% {
34558
+ opacity: 0;
34559
+ ${transform}
34560
+ }
34561
+ 100% {
34562
+ opacity: ${el.opacity ?? 1};
34563
+ ${transform}
34564
+ }
34565
+ }` : `
34276
34566
  @keyframes ${safeName} {
34277
34567
  0% {
34278
34568
  opacity: 0;
@@ -53250,7 +53540,7 @@ function editGeometryBounds(geometry) {
53250
53540
  }
53251
53541
  return { minX, minY, maxX, maxY };
53252
53542
  }
53253
- function fmt4(value) {
53543
+ function fmt5(value) {
53254
53544
  return String(Math.round(value * 1e3) / 1e3);
53255
53545
  }
53256
53546
  function editGeometryToPaths(geometry, ox, oy, width, height, scale2 = EDIT_POINTS_PATH_SCALE) {
@@ -53265,7 +53555,7 @@ function editGeometryToPaths(geometry, ox, oy, width, height, scale2 = EDIT_POIN
53265
53555
  const segments = [];
53266
53556
  const start = pt(sub.nodes[0]);
53267
53557
  segments.push({ type: "moveTo", pt: start });
53268
- svg2.push(`M ${fmt4(start.x)} ${fmt4(start.y)}`);
53558
+ svg2.push(`M ${fmt5(start.x)} ${fmt5(start.y)}`);
53269
53559
  sub.segments.forEach((seg, i) => {
53270
53560
  if (sub.closed && seg.kind === "line" && i === sub.segments.length - 1) {
53271
53561
  return;
@@ -53273,13 +53563,13 @@ function editGeometryToPaths(geometry, ox, oy, width, height, scale2 = EDIT_POIN
53273
53563
  const end = pt(sub.nodes[(i + 1) % sub.nodes.length]);
53274
53564
  if (seg.kind === "line") {
53275
53565
  segments.push({ type: "lineTo", pt: end });
53276
- svg2.push(`L ${fmt4(end.x)} ${fmt4(end.y)}`);
53566
+ svg2.push(`L ${fmt5(end.x)} ${fmt5(end.y)}`);
53277
53567
  } else {
53278
53568
  const c1 = pt(seg.c1);
53279
53569
  const c2 = pt(seg.c2);
53280
53570
  segments.push({ type: "cubicBezTo", pts: [c1, c2, end] });
53281
53571
  svg2.push(
53282
- `C ${fmt4(c1.x)} ${fmt4(c1.y)} ${fmt4(c2.x)} ${fmt4(c2.y)} ${fmt4(end.x)} ${fmt4(end.y)}`
53572
+ `C ${fmt5(c1.x)} ${fmt5(c1.y)} ${fmt5(c2.x)} ${fmt5(c2.y)} ${fmt5(end.x)} ${fmt5(end.y)}`
53283
53573
  );
53284
53574
  }
53285
53575
  });
@@ -63662,14 +63952,14 @@ var THEMES_GALLERY = {
63662
63952
  build(ctx) {
63663
63953
  const active2 = chunk3ESFHUZI_cjs.activeGalleryThemePreset(ctx.theme);
63664
63954
  const items = chunk3ESFHUZI_cjs.GALLERY_THEME_PRESETS.map((preset2) => tile6(preset2, preset2.id === active2?.id));
63665
- if (ctx.theme && !active2) {
63955
+ if (ctx.theme) {
63666
63956
  const scheme = galleryColorScheme(ctx);
63667
63957
  items.unshift({
63668
63958
  id: CURRENT_ID2,
63669
63959
  labelKey: "pptx.gallery.themes.current",
63670
63960
  label: "Current theme",
63671
63961
  previewSvg: themeTileSvg(scheme, currentFonts(ctx)?.majorFont?.latin),
63672
- applied: true
63962
+ applied: !active2
63673
63963
  });
63674
63964
  }
63675
63965
  return {
@@ -68983,7 +69273,7 @@ var HANDLE_ANCHORS = [
68983
69273
  ["sw", 0, 1],
68984
69274
  ["w", 0, 0.5]
68985
69275
  ];
68986
- function fmt5(n) {
69276
+ function fmt6(n) {
68987
69277
  return String(Math.round(n * 1e3) / 1e3);
68988
69278
  }
68989
69279
  function handleFor(id, fx2, fy, frameW, frameH, len, thick) {
@@ -68992,7 +69282,7 @@ function handleFor(id, fx2, fy, frameW, frameH, len, thick) {
68992
69282
  const height = fy === 0.5 ? len : isCorner ? len : thick;
68993
69283
  const left = fx2 === 0 ? 0 : fx2 === 1 ? frameW - width : frameW / 2 - width / 2;
68994
69284
  const top = fy === 0 ? 0 : fy === 1 ? frameH - height : frameH / 2 - height / 2;
68995
- let path = `M0 0 H${fmt5(width)} V${fmt5(height)} H0 Z`;
69285
+ let path = `M0 0 H${fmt6(width)} V${fmt6(height)} H0 Z`;
68996
69286
  if (isCorner) {
68997
69287
  const x0 = fx2 === 0 ? 0 : len;
68998
69288
  const y0 = fy === 0 ? 0 : len;
@@ -69006,7 +69296,7 @@ function handleFor(id, fx2, fy, frameW, frameH, len, thick) {
69006
69296
  [x0 + sx * thick, y0 + sy * len],
69007
69297
  [x0, y0 + sy * len]
69008
69298
  ];
69009
- path = `M${pts.map(([x, y]) => `${fmt5(x)} ${fmt5(y)}`).join(" L")} Z`;
69299
+ path = `M${pts.map(([x, y]) => `${fmt6(x)} ${fmt6(y)}`).join(" L")} Z`;
69010
69300
  }
69011
69301
  return { id, left, top, width, height, path, cursor: CURSORS[id] };
69012
69302
  }
@@ -69024,8 +69314,8 @@ function buildCropOverlay(el, zoom = 1) {
69024
69314
  };
69025
69315
  const hx = frame.x - image.x;
69026
69316
  const hy = frame.y - image.y;
69027
- const outer3 = `M0 0 H${fmt5(image.width)} V${fmt5(image.height)} H0 Z`;
69028
- const hole = `M${fmt5(hx)} ${fmt5(hy)} H${fmt5(hx + frame.width)} V${fmt5(hy + frame.height)} H${fmt5(hx)} Z`;
69317
+ const outer3 = `M0 0 H${fmt6(image.width)} V${fmt6(image.height)} H0 Z`;
69318
+ const hole = `M${fmt6(hx)} ${fmt6(hy)} H${fmt6(hx + frame.width)} V${fmt6(hy + frame.height)} H${fmt6(hx)} Z`;
69029
69319
  const flips = [
69030
69320
  start.flipHorizontal ? "scaleX(-1)" : "",
69031
69321
  start.flipVertical ? "scaleY(-1)" : ""
@@ -81227,7 +81517,7 @@ function definePptxInsertSmartArtDialog(registry2) {
81227
81517
  if (this.#live || this.#draw) {
81228
81518
  return;
81229
81519
  }
81230
- this.#live = import('./smartart-insert-preview-5ZTZYAZR.cjs').then((module) => {
81520
+ this.#live = import('./smartart-insert-preview-CTBWMXNX.cjs').then((module) => {
81231
81521
  if (this.#draw || !this.#picker) {
81232
81522
  return;
81233
81523
  }
@@ -91886,6 +92176,7 @@ exports.outgoingSegmentIndex = outgoingSegmentIndex;
91886
92176
  exports.outlineBounds = outlineBounds;
91887
92177
  exports.outlinePathData = outlinePathData;
91888
92178
  exports.outlineRowKey = outlineRowKey;
92179
+ exports.outlineStrokeJoin = outlineStrokeJoin;
91889
92180
  exports.overlayInlineTextSnapshot = overlayInlineTextSnapshot;
91890
92181
  exports.overlayMasterViewInlineSnapshot = overlayMasterViewInlineSnapshot;
91891
92182
  exports.overlayPointerInput = overlayPointerInput;
@@ -92457,6 +92748,7 @@ exports.storePresentationDeck = storePresentationDeck;
92457
92748
  exports.straddlingStrokeWidth = straddlingStrokeWidth;
92458
92749
  exports.stripEditLayerMarkers = stripEditLayerMarkers;
92459
92750
  exports.stripUnderlineDecoration = stripUnderlineDecoration;
92751
+ exports.strokeMiterLimit = strokeMiterLimit;
92460
92752
  exports.strokeOnlyPresetPathData = strokeOnlyPresetPathData;
92461
92753
  exports.strokeOutlineViewBox = strokeOutlineViewBox;
92462
92754
  exports.strokeToInkElement = strokeToInkElement;