pptx-angular-viewer 4.24.1 → 4.24.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.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,17 @@ A release listed with no entries carried no Conventional Commit in this package'
7
7
  scope: scripts/release-plan.mjs re-releases a package whenever any of its files
8
8
  change, not only on conventional ones.
9
9
 
10
+ ## [4.24.1](https://github.com/ChristopherVR/pptx-viewer/releases/tag/pptx-angular-viewer@4.24.1) - 2026-10-05
11
+
12
+ ### Testing
13
+
14
+ - **shared:** Match control styles without relying on their formatting (by @ChristopherVR) ([e32497c](https://github.com/ChristopherVR/pptx-viewer/commit/e32497ca6e4367f5ddaf07cdda186bddec9e7271))
15
+ - **shared:** Expect the title bar's actions slot (by @ChristopherVR) ([3076cb8](https://github.com/ChristopherVR/pptx-viewer/commit/3076cb8f5f1d2ba6ce4dee4d75f171ffaaa6341a))
16
+
17
+ ### Build & CI
18
+
19
+ - **deps:** Adopt ooxml-core 0.20.0 and ooxml-ui 0.28.0 (by @ChristopherVR) ([3f52fa1](https://github.com/ChristopherVR/pptx-viewer/commit/3f52fa103a39a1c1cdfe04068a2cae8b624aa8d6))
20
+
10
21
  ## [4.24.0](https://github.com/ChristopherVR/pptx-viewer/releases/tag/pptx-angular-viewer@4.24.0) - 2026-10-04
11
22
 
12
23
  ### Features
@@ -245,7 +245,7 @@ function getStrokeOnlyPresetPaths(element) {
245
245
  const shapeType = element.shapeType;
246
246
  if (!shapeType || shapeType === "custom") return;
247
247
  if (element.pathData) return;
248
- const result = evaluatePresetShape(shapeType, Math.max(element.width, 1), Math.max(element.height, 1), element.shapeAdjustments);
248
+ const result = evaluatePresetShape(shapeType, Math.max(element.width, 0), Math.max(element.height, 0), element.shapeAdjustments);
249
249
  if (!result || !result.fillNone) return;
250
250
  const drawable = result.paths.filter((path) => path.d !== "");
251
251
  return drawable.length > 0 ? drawable : void 0;
@@ -818,7 +818,10 @@ function buildStrokeOutline(element) {
818
818
  };
819
819
  }
820
820
  function strokeOutlineViewBox(element) {
821
- return `0 0 ${Math.max(element.width, 0)} ${Math.max(element.height, 0)}`;
821
+ const width = Math.max(element.width, 0);
822
+ const height = Math.max(element.height, 0);
823
+ if (width < 1 || height < 1) return;
824
+ return `0 0 ${width} ${height}`;
822
825
  }
823
826
  function suppressesCssBorder(element) {
824
827
  return buildStrokeOutline(element) !== void 0;
@@ -61969,6 +61972,7 @@ function createElementClass() {
61969
61972
  return PptxThreeView;
61970
61973
  }
61971
61974
  function defineThreeViewElement(registry) {
61975
+ if (typeof HTMLElement === "undefined") return;
61972
61976
  const target = registry ?? (typeof customElements === "undefined" ? void 0 : customElements);
61973
61977
  if (!target || target.get("pptx-three-view")) return;
61974
61978
  target.define(THREE_VIEW_TAG, createElementClass());
@@ -71450,7 +71454,10 @@ function buildSelectControl(ctx, control) {
71450
71454
  sync(state) {
71451
71455
  const current = state.controls[key];
71452
71456
  const label = homeLabel(state, control.labelKey, control.fallback);
71453
- if (select.getAttribute("aria-label") !== label) select.setAttribute("aria-label", label);
71457
+ if (select.getAttribute("aria-label") !== label) {
71458
+ select.setAttribute("aria-label", label);
71459
+ select.requestUpdate?.();
71460
+ }
71454
71461
  select.title = label;
71455
71462
  select.hidden = Boolean(current?.hidden);
71456
71463
  const { nodes, signature: next } = selectOptions(doc, current?.items ?? control.items ?? [], state);
@@ -96615,6 +96622,8 @@ var ReflectionMirrorContentComponent = class ReflectionMirrorContentComponent {
96615
96622
  inset: 0;
96616
96623
  width: 100%;
96617
96624
  height: 100%;
96625
+ min-width: 1px;
96626
+ min-height: 1px;
96618
96627
  overflow: visible;
96619
96628
  pointer-events: none;
96620
96629
  "
@@ -96808,6 +96817,8 @@ i0.ɵɵngDeclareClassMetadata({
96808
96817
  inset: 0;
96809
96818
  width: 100%;
96810
96819
  height: 100%;
96820
+ min-width: 1px;
96821
+ min-height: 1px;
96811
96822
  overflow: visible;
96812
96823
  pointer-events: none;
96813
96824
  "
@@ -97183,7 +97194,7 @@ var ElementRendererShapeComponent = class ElementRendererShapeComponent {
97183
97194
  }
97184
97195
  },
97185
97196
  ngImport: i0,
97186
- template: "<div\n class=\"pptx-ng-element pptx-ng-shape\"\n [ngStyle]=\"shapeContainerStyle()\"\n [style.pointer-events]=\"rootPointerEvents()\"\n [attr.data-element-id]=\"elementIdAttr()\"\n [attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n>\n <!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n Change Font Style/Size) overrides the runs' own inline\n bold/italic/underline/size, which plain CSS inheritance cannot\n reach (the runs declare those unconditionally). -->\n <pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n <!-- Interaction-only hit target for a degenerate shape; see `hitTargetStyle`. -->\n @if (hitTargetStyle(); as hit) {\n <div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n }\n <!-- Per-sub-path fill overlay: a multi-sub-path preset (`smileyFace`'s\n open eyes, `actionButtonBlank`'s darkened bevel well) or custom\n geometry whose sub-paths cannot share one CSS background-color. -->\n @if (subpathFill(); as sf) {\n <svg\n class=\"pptx-ng-subpath-fill\"\n aria-hidden=\"true\"\n [attr.viewBox]=\"subpathFillViewBox()\"\n preserveAspectRatio=\"none\"\n style=\"position: absolute; inset: 0; width: 100%; height: 100%\"\n >\n @for (paint of sf.paints; track $index) {\n <path [attr.d]=\"paint.d\" [attr.fill]=\"paint.fill\" stroke=\"none\" />\n }\n </svg>\n }\n @if (fillOverlay(); as ov) {\n <div\n class=\"pptx-ng-fill-overlay\"\n aria-hidden=\"true\"\n style=\"position: absolute; inset: 0; pointer-events: none\"\n [style.background]=\"ov.color\"\n [style.mix-blend-mode]=\"ov.blendMode\"\n ></div>\n }\n <!-- Real 3D extrusion side panels (`a:sp3d/@extrusionH`), on top of the\n flat box-shadow approximation `shapeContainerStyle` already applied. -->\n <pptx-extrusion-3d-overlay [data]=\"extrusionData()\" />\n <!-- Mirrored reflection sibling (`a:reflection`): cross-browser, unlike\n the `-webkit-box-reflect` this replaced (Firefox never implemented\n that property, so reflections were invisible there entirely). A full\n inert clone of the element's own content (fill, outline, text body),\n not just its resolved fill - see `ReflectionMirrorContentComponent`. -->\n @if (reflection(); as refl) {\n <div class=\"pptx-ng-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl.wrapperStyle\">\n <pptx-reflection-mirror-content [element]=\"element()\" [mediaDataUrls]=\"mediaDataUrls()\" />\n </div>\n }\n <!-- Hollow frame hit target: an unfilled, textless shape is hit-tested\n on its outline only, so its interior lets clicks through. -->\n @if (hollowHit(); as hit) {\n <svg\n aria-hidden=\"true\"\n [attr.viewBox]=\"outlineViewBox()\"\n preserveAspectRatio=\"none\"\n style=\"\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n overflow: visible;\n pointer-events: none;\n \"\n >\n <path\n [attr.d]=\"hit.d\"\n fill=\"none\"\n stroke=\"transparent\"\n [attr.stroke-width]=\"hit.strokeWidth\"\n style=\"pointer-events: stroke\"\n />\n </svg>\n }\n <!-- Stroked outline: a CSS border takes one flat colour, and cannot\n outline an open preset (`line`, `arc`) at all. -->\n @if (gradientOutline(); as go) {\n <svg\n class=\"pptx-ng-gradient-outline\"\n aria-hidden=\"true\"\n [attr.viewBox]=\"outlineViewBox()\"\n preserveAspectRatio=\"none\"\n style=\"\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n overflow: visible;\n pointer-events: none;\n \"\n >\n @if (go.paint; as paint) {\n <defs>\n @if (paint.kind === 'pattern') {\n <pattern\n [attr.id]=\"paint.id\"\n [attr.width]=\"paint.width\"\n [attr.height]=\"paint.height\"\n patternUnits=\"userSpaceOnUse\"\n >\n <image\n [attr.href]=\"paint.href\"\n [attr.width]=\"paint.width\"\n [attr.height]=\"paint.height\"\n />\n </pattern>\n } @else if (paint.kind === 'rectPath') {\n <pattern [attr.id]=\"paint.id\" patternUnits=\"objectBoundingBox\" width=\"1\" height=\"1\">\n <image\n [attr.href]=\"paint.href\"\n x=\"0\"\n y=\"0\"\n width=\"1\"\n height=\"1\"\n preserveAspectRatio=\"none\"\n />\n </pattern>\n } @else if (paint.kind === 'radial') {\n <radialGradient\n [attr.id]=\"paint.id\"\n [attr.cx]=\"paint.cx\"\n [attr.cy]=\"paint.cy\"\n [attr.r]=\"paint.r\"\n >\n @for (stop of paint.stops; track $index) {\n <stop\n [attr.offset]=\"stop.offset\"\n [attr.stop-color]=\"stop.color\"\n [attr.stop-opacity]=\"stop.opacity\"\n />\n }\n </radialGradient>\n } @else {\n <linearGradient\n [attr.id]=\"paint.id\"\n [attr.x1]=\"paint.x1\"\n [attr.y1]=\"paint.y1\"\n [attr.x2]=\"paint.x2\"\n [attr.y2]=\"paint.y2\"\n >\n @for (stop of paint.stops; track $index) {\n <stop\n [attr.offset]=\"stop.offset\"\n [attr.stop-color]=\"stop.color\"\n [attr.stop-opacity]=\"stop.opacity\"\n />\n }\n </linearGradient>\n }\n </defs>\n }\n @for (strand of go.strands; track $index) {\n <path\n [attr.d]=\"go.d\"\n fill=\"none\"\n [attr.stroke]=\"go.stroke\"\n [attr.stroke-width]=\"strand.strokeWidth\"\n [attr.stroke-dasharray]=\"go.dashArray\"\n [attr.stroke-linecap]=\"go.lineCap\"\n [attr.stroke-linejoin]=\"go.lineJoin\"\n [style.transform]=\"strand.offset !== 0 ? 'translate(0, ' + strand.offset + 'px)' : null\"\n />\n }\n </svg>\n }\n <!-- While this element is open in the inline text editor, its live text\n is drawn by that overlay instead (see `isBeingInlineEdited`);\n rendering it here too produced a duplicate, offset \"text shadow\"\n (issue #182). -->\n @if (!isBeingInlineEdited()) {\n @if (glyphWarp(); as gwarp) {\n <svg\n [attr.width]=\"gwarp.width\"\n [attr.height]=\"gwarp.height\"\n [attr.viewBox]=\"'0 0 ' + gwarp.width + ' ' + gwarp.height\"\n style=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n aria-hidden=\"true\"\n >\n @for (g of gwarp.glyphs; track $index) {\n <!-- The glyph's real outline, already warped point-by-point (see\n `buildWarpedGlyphOutlinePathD` in pptx-viewer-shared): exact,\n so no affine fit or slicing is needed. -->\n @if (g.outlinePath) {\n <path [attr.d]=\"g.outlinePath\" [attr.fill]=\"g.fill\" />\n } @else if (!g.slices || g.slices.length <= 1) {\n <text\n [attr.x]=\"g.x\"\n [attr.y]=\"g.y\"\n [attr.transform]=\"g.transform\"\n [attr.fill]=\"g.fill\"\n [attr.font-size]=\"g.fontSize\"\n [attr.font-weight]=\"g.fontWeight\"\n [attr.font-style]=\"g.fontStyle\"\n [attr.font-family]=\"g.fontFamily\"\n >\n {{ g.char }}\n </text>\n } @else {\n <!-- A very wide glyph on a strongly-curved envelope: rendered\n as `slices.length` clipped copies, each with its own affine\n (see `chooseGlyphSliceCount` in pptx-viewer-shared), so the\n pieces tile across the glyph. Wrapped in a real <g> so it\n never matches an \"svg > text\" selector the single-slice\n case does. -->\n <g [attr.data-glyph-slices]=\"g.slices.length\">\n @for (slice of g.slices; track $index; let si = $index) {\n <clipPath [attr.id]=\"g.clipIdPrefix + '-s' + si\" clipPathUnits=\"userSpaceOnUse\">\n <rect\n [attr.x]=\"slice.clipX0\"\n y=\"-100000\"\n [attr.width]=\"slice.clipX1 - slice.clipX0\"\n height=\"200000\"\n />\n </clipPath>\n <text\n [attr.x]=\"g.x\"\n [attr.y]=\"g.y\"\n [attr.transform]=\"slice.transform\"\n [attr.clip-path]=\"'url(#' + g.clipIdPrefix + '-s' + si + ')'\"\n [attr.fill]=\"g.fill\"\n [attr.font-size]=\"g.fontSize\"\n [attr.font-weight]=\"g.fontWeight\"\n [attr.font-style]=\"g.fontStyle\"\n [attr.font-family]=\"g.fontFamily\"\n >\n {{ g.char }}\n </text>\n }\n </g>\n }\n }\n </svg>\n } @else if (pathWarp(); as warp) {\n <svg\n [attr.width]=\"warp.width\"\n [attr.height]=\"warp.height\"\n [attr.viewBox]=\"'0 0 ' + warp.width + ' ' + warp.height\"\n style=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n aria-hidden=\"true\"\n >\n <defs>\n @for (line of warp.pathLines; track line.pathId) {\n <path [attr.id]=\"line.pathId\" [attr.d]=\"line.d\" fill=\"none\" />\n }\n </defs>\n @for (line of warp.pathLines; track line.pathId) {\n <text\n [attr.font-size]=\"warp.baseFontSize\"\n [attr.font-family]=\"warp.baseFontFamily\"\n [attr.fill]=\"warp.baseColor\"\n >\n <textPath\n [attr.href]=\"'#' + line.pathId\"\n [attr.startOffset]=\"warp.startOffset\"\n [attr.text-anchor]=\"warp.textAnchor\"\n >\n @for (seg of line.segments; track $index) {\n <tspan\n [attr.fill]=\"seg.style?.color ?? warp.baseColor\"\n [attr.font-weight]=\"seg.style?.bold ? 700 : 400\"\n [attr.font-style]=\"seg.style?.italic ? 'italic' : 'normal'\"\n >\n {{ seg.text }}\n </tspan>\n }\n </textPath>\n </text>\n }\n </svg>\n } @else if (placeholderPrompt(); as prompt) {\n <div class=\"pptx-ng-text\" [ngStyle]=\"prompt.style\">{{ prompt.text }}</div>\n } @else if (hasText()) {\n <pptx-slide-text-block\n [paragraphs]=\"paragraphs()\"\n [textStyle]=\"warpedTextStyle()\"\n [elementId]=\"element().id\"\n [subElementAnimStates]=\"subElementAnimStates()\"\n [interactive]=\"true\"\n />\n }\n }\n</div>\n",
97197
+ template: "<div\n class=\"pptx-ng-element pptx-ng-shape\"\n [ngStyle]=\"shapeContainerStyle()\"\n [style.pointer-events]=\"rootPointerEvents()\"\n [attr.data-element-id]=\"elementIdAttr()\"\n [attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n>\n <!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n Change Font Style/Size) overrides the runs' own inline\n bold/italic/underline/size, which plain CSS inheritance cannot\n reach (the runs declare those unconditionally). -->\n <pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n <!-- Interaction-only hit target for a degenerate shape; see `hitTargetStyle`. -->\n @if (hitTargetStyle(); as hit) {\n <div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n }\n <!-- Per-sub-path fill overlay: a multi-sub-path preset (`smileyFace`'s\n open eyes, `actionButtonBlank`'s darkened bevel well) or custom\n geometry whose sub-paths cannot share one CSS background-color. -->\n @if (subpathFill(); as sf) {\n <svg\n class=\"pptx-ng-subpath-fill\"\n aria-hidden=\"true\"\n [attr.viewBox]=\"subpathFillViewBox()\"\n preserveAspectRatio=\"none\"\n style=\"position: absolute; inset: 0; width: 100%; height: 100%\"\n >\n @for (paint of sf.paints; track $index) {\n <path [attr.d]=\"paint.d\" [attr.fill]=\"paint.fill\" stroke=\"none\" />\n }\n </svg>\n }\n @if (fillOverlay(); as ov) {\n <div\n class=\"pptx-ng-fill-overlay\"\n aria-hidden=\"true\"\n style=\"position: absolute; inset: 0; pointer-events: none\"\n [style.background]=\"ov.color\"\n [style.mix-blend-mode]=\"ov.blendMode\"\n ></div>\n }\n <!-- Real 3D extrusion side panels (`a:sp3d/@extrusionH`), on top of the\n flat box-shadow approximation `shapeContainerStyle` already applied. -->\n <pptx-extrusion-3d-overlay [data]=\"extrusionData()\" />\n <!-- Mirrored reflection sibling (`a:reflection`): cross-browser, unlike\n the `-webkit-box-reflect` this replaced (Firefox never implemented\n that property, so reflections were invisible there entirely). A full\n inert clone of the element's own content (fill, outline, text body),\n not just its resolved fill - see `ReflectionMirrorContentComponent`. -->\n @if (reflection(); as refl) {\n <div class=\"pptx-ng-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl.wrapperStyle\">\n <pptx-reflection-mirror-content [element]=\"element()\" [mediaDataUrls]=\"mediaDataUrls()\" />\n </div>\n }\n <!-- Hollow frame hit target: an unfilled, textless shape is hit-tested\n on its outline only, so its interior lets clicks through. -->\n @if (hollowHit(); as hit) {\n <svg\n aria-hidden=\"true\"\n [attr.viewBox]=\"outlineViewBox()\"\n preserveAspectRatio=\"none\"\n style=\"\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n min-width: 1px;\n min-height: 1px;\n overflow: visible;\n pointer-events: none;\n \"\n >\n <path\n [attr.d]=\"hit.d\"\n fill=\"none\"\n stroke=\"transparent\"\n [attr.stroke-width]=\"hit.strokeWidth\"\n style=\"pointer-events: stroke\"\n />\n </svg>\n }\n <!-- Stroked outline: a CSS border takes one flat colour, and cannot\n outline an open preset (`line`, `arc`) at all. -->\n @if (gradientOutline(); as go) {\n <svg\n class=\"pptx-ng-gradient-outline\"\n aria-hidden=\"true\"\n [attr.viewBox]=\"outlineViewBox()\"\n preserveAspectRatio=\"none\"\n style=\"\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n min-width: 1px;\n min-height: 1px;\n overflow: visible;\n pointer-events: none;\n \"\n >\n @if (go.paint; as paint) {\n <defs>\n @if (paint.kind === 'pattern') {\n <pattern\n [attr.id]=\"paint.id\"\n [attr.width]=\"paint.width\"\n [attr.height]=\"paint.height\"\n patternUnits=\"userSpaceOnUse\"\n >\n <image\n [attr.href]=\"paint.href\"\n [attr.width]=\"paint.width\"\n [attr.height]=\"paint.height\"\n />\n </pattern>\n } @else if (paint.kind === 'rectPath') {\n <pattern [attr.id]=\"paint.id\" patternUnits=\"objectBoundingBox\" width=\"1\" height=\"1\">\n <image\n [attr.href]=\"paint.href\"\n x=\"0\"\n y=\"0\"\n width=\"1\"\n height=\"1\"\n preserveAspectRatio=\"none\"\n />\n </pattern>\n } @else if (paint.kind === 'radial') {\n <radialGradient\n [attr.id]=\"paint.id\"\n [attr.cx]=\"paint.cx\"\n [attr.cy]=\"paint.cy\"\n [attr.r]=\"paint.r\"\n >\n @for (stop of paint.stops; track $index) {\n <stop\n [attr.offset]=\"stop.offset\"\n [attr.stop-color]=\"stop.color\"\n [attr.stop-opacity]=\"stop.opacity\"\n />\n }\n </radialGradient>\n } @else {\n <linearGradient\n [attr.id]=\"paint.id\"\n [attr.x1]=\"paint.x1\"\n [attr.y1]=\"paint.y1\"\n [attr.x2]=\"paint.x2\"\n [attr.y2]=\"paint.y2\"\n >\n @for (stop of paint.stops; track $index) {\n <stop\n [attr.offset]=\"stop.offset\"\n [attr.stop-color]=\"stop.color\"\n [attr.stop-opacity]=\"stop.opacity\"\n />\n }\n </linearGradient>\n }\n </defs>\n }\n @for (strand of go.strands; track $index) {\n <path\n [attr.d]=\"go.d\"\n fill=\"none\"\n [attr.stroke]=\"go.stroke\"\n [attr.stroke-width]=\"strand.strokeWidth\"\n [attr.stroke-dasharray]=\"go.dashArray\"\n [attr.stroke-linecap]=\"go.lineCap\"\n [attr.stroke-linejoin]=\"go.lineJoin\"\n [style.transform]=\"strand.offset !== 0 ? 'translate(0, ' + strand.offset + 'px)' : null\"\n />\n }\n </svg>\n }\n <!-- While this element is open in the inline text editor, its live text\n is drawn by that overlay instead (see `isBeingInlineEdited`);\n rendering it here too produced a duplicate, offset \"text shadow\"\n (issue #182). -->\n @if (!isBeingInlineEdited()) {\n @if (glyphWarp(); as gwarp) {\n <svg\n [attr.width]=\"gwarp.width\"\n [attr.height]=\"gwarp.height\"\n [attr.viewBox]=\"'0 0 ' + gwarp.width + ' ' + gwarp.height\"\n style=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n aria-hidden=\"true\"\n >\n @for (g of gwarp.glyphs; track $index) {\n <!-- The glyph's real outline, already warped point-by-point (see\n `buildWarpedGlyphOutlinePathD` in pptx-viewer-shared): exact,\n so no affine fit or slicing is needed. -->\n @if (g.outlinePath) {\n <path [attr.d]=\"g.outlinePath\" [attr.fill]=\"g.fill\" />\n } @else if (!g.slices || g.slices.length <= 1) {\n <text\n [attr.x]=\"g.x\"\n [attr.y]=\"g.y\"\n [attr.transform]=\"g.transform\"\n [attr.fill]=\"g.fill\"\n [attr.font-size]=\"g.fontSize\"\n [attr.font-weight]=\"g.fontWeight\"\n [attr.font-style]=\"g.fontStyle\"\n [attr.font-family]=\"g.fontFamily\"\n >\n {{ g.char }}\n </text>\n } @else {\n <!-- A very wide glyph on a strongly-curved envelope: rendered\n as `slices.length` clipped copies, each with its own affine\n (see `chooseGlyphSliceCount` in pptx-viewer-shared), so the\n pieces tile across the glyph. Wrapped in a real <g> so it\n never matches an \"svg > text\" selector the single-slice\n case does. -->\n <g [attr.data-glyph-slices]=\"g.slices.length\">\n @for (slice of g.slices; track $index; let si = $index) {\n <clipPath [attr.id]=\"g.clipIdPrefix + '-s' + si\" clipPathUnits=\"userSpaceOnUse\">\n <rect\n [attr.x]=\"slice.clipX0\"\n y=\"-100000\"\n [attr.width]=\"slice.clipX1 - slice.clipX0\"\n height=\"200000\"\n />\n </clipPath>\n <text\n [attr.x]=\"g.x\"\n [attr.y]=\"g.y\"\n [attr.transform]=\"slice.transform\"\n [attr.clip-path]=\"'url(#' + g.clipIdPrefix + '-s' + si + ')'\"\n [attr.fill]=\"g.fill\"\n [attr.font-size]=\"g.fontSize\"\n [attr.font-weight]=\"g.fontWeight\"\n [attr.font-style]=\"g.fontStyle\"\n [attr.font-family]=\"g.fontFamily\"\n >\n {{ g.char }}\n </text>\n }\n </g>\n }\n }\n </svg>\n } @else if (pathWarp(); as warp) {\n <svg\n [attr.width]=\"warp.width\"\n [attr.height]=\"warp.height\"\n [attr.viewBox]=\"'0 0 ' + warp.width + ' ' + warp.height\"\n style=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n aria-hidden=\"true\"\n >\n <defs>\n @for (line of warp.pathLines; track line.pathId) {\n <path [attr.id]=\"line.pathId\" [attr.d]=\"line.d\" fill=\"none\" />\n }\n </defs>\n @for (line of warp.pathLines; track line.pathId) {\n <text\n [attr.font-size]=\"warp.baseFontSize\"\n [attr.font-family]=\"warp.baseFontFamily\"\n [attr.fill]=\"warp.baseColor\"\n >\n <textPath\n [attr.href]=\"'#' + line.pathId\"\n [attr.startOffset]=\"warp.startOffset\"\n [attr.text-anchor]=\"warp.textAnchor\"\n >\n @for (seg of line.segments; track $index) {\n <tspan\n [attr.fill]=\"seg.style?.color ?? warp.baseColor\"\n [attr.font-weight]=\"seg.style?.bold ? 700 : 400\"\n [attr.font-style]=\"seg.style?.italic ? 'italic' : 'normal'\"\n >\n {{ seg.text }}\n </tspan>\n }\n </textPath>\n </text>\n }\n </svg>\n } @else if (placeholderPrompt(); as prompt) {\n <div class=\"pptx-ng-text\" [ngStyle]=\"prompt.style\">{{ prompt.text }}</div>\n } @else if (hasText()) {\n <pptx-slide-text-block\n [paragraphs]=\"paragraphs()\"\n [textStyle]=\"warpedTextStyle()\"\n [elementId]=\"element().id\"\n [subElementAnimStates]=\"subElementAnimStates()\"\n [interactive]=\"true\"\n />\n }\n }\n</div>\n",
97187
97198
  dependencies: [
97188
97199
  {
97189
97200
  kind: "directive",
@@ -97249,7 +97260,7 @@ i0.ɵɵngDeclareClassMetadata({
97249
97260
  ReflectionMirrorContentComponent,
97250
97261
  SlideTextBlockComponent
97251
97262
  ],
97252
- template: "<div\n class=\"pptx-ng-element pptx-ng-shape\"\n [ngStyle]=\"shapeContainerStyle()\"\n [style.pointer-events]=\"rootPointerEvents()\"\n [attr.data-element-id]=\"elementIdAttr()\"\n [attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n>\n <!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n Change Font Style/Size) overrides the runs' own inline\n bold/italic/underline/size, which plain CSS inheritance cannot\n reach (the runs declare those unconditionally). -->\n <pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n <!-- Interaction-only hit target for a degenerate shape; see `hitTargetStyle`. -->\n @if (hitTargetStyle(); as hit) {\n <div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n }\n <!-- Per-sub-path fill overlay: a multi-sub-path preset (`smileyFace`'s\n open eyes, `actionButtonBlank`'s darkened bevel well) or custom\n geometry whose sub-paths cannot share one CSS background-color. -->\n @if (subpathFill(); as sf) {\n <svg\n class=\"pptx-ng-subpath-fill\"\n aria-hidden=\"true\"\n [attr.viewBox]=\"subpathFillViewBox()\"\n preserveAspectRatio=\"none\"\n style=\"position: absolute; inset: 0; width: 100%; height: 100%\"\n >\n @for (paint of sf.paints; track $index) {\n <path [attr.d]=\"paint.d\" [attr.fill]=\"paint.fill\" stroke=\"none\" />\n }\n </svg>\n }\n @if (fillOverlay(); as ov) {\n <div\n class=\"pptx-ng-fill-overlay\"\n aria-hidden=\"true\"\n style=\"position: absolute; inset: 0; pointer-events: none\"\n [style.background]=\"ov.color\"\n [style.mix-blend-mode]=\"ov.blendMode\"\n ></div>\n }\n <!-- Real 3D extrusion side panels (`a:sp3d/@extrusionH`), on top of the\n flat box-shadow approximation `shapeContainerStyle` already applied. -->\n <pptx-extrusion-3d-overlay [data]=\"extrusionData()\" />\n <!-- Mirrored reflection sibling (`a:reflection`): cross-browser, unlike\n the `-webkit-box-reflect` this replaced (Firefox never implemented\n that property, so reflections were invisible there entirely). A full\n inert clone of the element's own content (fill, outline, text body),\n not just its resolved fill - see `ReflectionMirrorContentComponent`. -->\n @if (reflection(); as refl) {\n <div class=\"pptx-ng-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl.wrapperStyle\">\n <pptx-reflection-mirror-content [element]=\"element()\" [mediaDataUrls]=\"mediaDataUrls()\" />\n </div>\n }\n <!-- Hollow frame hit target: an unfilled, textless shape is hit-tested\n on its outline only, so its interior lets clicks through. -->\n @if (hollowHit(); as hit) {\n <svg\n aria-hidden=\"true\"\n [attr.viewBox]=\"outlineViewBox()\"\n preserveAspectRatio=\"none\"\n style=\"\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n overflow: visible;\n pointer-events: none;\n \"\n >\n <path\n [attr.d]=\"hit.d\"\n fill=\"none\"\n stroke=\"transparent\"\n [attr.stroke-width]=\"hit.strokeWidth\"\n style=\"pointer-events: stroke\"\n />\n </svg>\n }\n <!-- Stroked outline: a CSS border takes one flat colour, and cannot\n outline an open preset (`line`, `arc`) at all. -->\n @if (gradientOutline(); as go) {\n <svg\n class=\"pptx-ng-gradient-outline\"\n aria-hidden=\"true\"\n [attr.viewBox]=\"outlineViewBox()\"\n preserveAspectRatio=\"none\"\n style=\"\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n overflow: visible;\n pointer-events: none;\n \"\n >\n @if (go.paint; as paint) {\n <defs>\n @if (paint.kind === 'pattern') {\n <pattern\n [attr.id]=\"paint.id\"\n [attr.width]=\"paint.width\"\n [attr.height]=\"paint.height\"\n patternUnits=\"userSpaceOnUse\"\n >\n <image\n [attr.href]=\"paint.href\"\n [attr.width]=\"paint.width\"\n [attr.height]=\"paint.height\"\n />\n </pattern>\n } @else if (paint.kind === 'rectPath') {\n <pattern [attr.id]=\"paint.id\" patternUnits=\"objectBoundingBox\" width=\"1\" height=\"1\">\n <image\n [attr.href]=\"paint.href\"\n x=\"0\"\n y=\"0\"\n width=\"1\"\n height=\"1\"\n preserveAspectRatio=\"none\"\n />\n </pattern>\n } @else if (paint.kind === 'radial') {\n <radialGradient\n [attr.id]=\"paint.id\"\n [attr.cx]=\"paint.cx\"\n [attr.cy]=\"paint.cy\"\n [attr.r]=\"paint.r\"\n >\n @for (stop of paint.stops; track $index) {\n <stop\n [attr.offset]=\"stop.offset\"\n [attr.stop-color]=\"stop.color\"\n [attr.stop-opacity]=\"stop.opacity\"\n />\n }\n </radialGradient>\n } @else {\n <linearGradient\n [attr.id]=\"paint.id\"\n [attr.x1]=\"paint.x1\"\n [attr.y1]=\"paint.y1\"\n [attr.x2]=\"paint.x2\"\n [attr.y2]=\"paint.y2\"\n >\n @for (stop of paint.stops; track $index) {\n <stop\n [attr.offset]=\"stop.offset\"\n [attr.stop-color]=\"stop.color\"\n [attr.stop-opacity]=\"stop.opacity\"\n />\n }\n </linearGradient>\n }\n </defs>\n }\n @for (strand of go.strands; track $index) {\n <path\n [attr.d]=\"go.d\"\n fill=\"none\"\n [attr.stroke]=\"go.stroke\"\n [attr.stroke-width]=\"strand.strokeWidth\"\n [attr.stroke-dasharray]=\"go.dashArray\"\n [attr.stroke-linecap]=\"go.lineCap\"\n [attr.stroke-linejoin]=\"go.lineJoin\"\n [style.transform]=\"strand.offset !== 0 ? 'translate(0, ' + strand.offset + 'px)' : null\"\n />\n }\n </svg>\n }\n <!-- While this element is open in the inline text editor, its live text\n is drawn by that overlay instead (see `isBeingInlineEdited`);\n rendering it here too produced a duplicate, offset \"text shadow\"\n (issue #182). -->\n @if (!isBeingInlineEdited()) {\n @if (glyphWarp(); as gwarp) {\n <svg\n [attr.width]=\"gwarp.width\"\n [attr.height]=\"gwarp.height\"\n [attr.viewBox]=\"'0 0 ' + gwarp.width + ' ' + gwarp.height\"\n style=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n aria-hidden=\"true\"\n >\n @for (g of gwarp.glyphs; track $index) {\n <!-- The glyph's real outline, already warped point-by-point (see\n `buildWarpedGlyphOutlinePathD` in pptx-viewer-shared): exact,\n so no affine fit or slicing is needed. -->\n @if (g.outlinePath) {\n <path [attr.d]=\"g.outlinePath\" [attr.fill]=\"g.fill\" />\n } @else if (!g.slices || g.slices.length <= 1) {\n <text\n [attr.x]=\"g.x\"\n [attr.y]=\"g.y\"\n [attr.transform]=\"g.transform\"\n [attr.fill]=\"g.fill\"\n [attr.font-size]=\"g.fontSize\"\n [attr.font-weight]=\"g.fontWeight\"\n [attr.font-style]=\"g.fontStyle\"\n [attr.font-family]=\"g.fontFamily\"\n >\n {{ g.char }}\n </text>\n } @else {\n <!-- A very wide glyph on a strongly-curved envelope: rendered\n as `slices.length` clipped copies, each with its own affine\n (see `chooseGlyphSliceCount` in pptx-viewer-shared), so the\n pieces tile across the glyph. Wrapped in a real <g> so it\n never matches an \"svg > text\" selector the single-slice\n case does. -->\n <g [attr.data-glyph-slices]=\"g.slices.length\">\n @for (slice of g.slices; track $index; let si = $index) {\n <clipPath [attr.id]=\"g.clipIdPrefix + '-s' + si\" clipPathUnits=\"userSpaceOnUse\">\n <rect\n [attr.x]=\"slice.clipX0\"\n y=\"-100000\"\n [attr.width]=\"slice.clipX1 - slice.clipX0\"\n height=\"200000\"\n />\n </clipPath>\n <text\n [attr.x]=\"g.x\"\n [attr.y]=\"g.y\"\n [attr.transform]=\"slice.transform\"\n [attr.clip-path]=\"'url(#' + g.clipIdPrefix + '-s' + si + ')'\"\n [attr.fill]=\"g.fill\"\n [attr.font-size]=\"g.fontSize\"\n [attr.font-weight]=\"g.fontWeight\"\n [attr.font-style]=\"g.fontStyle\"\n [attr.font-family]=\"g.fontFamily\"\n >\n {{ g.char }}\n </text>\n }\n </g>\n }\n }\n </svg>\n } @else if (pathWarp(); as warp) {\n <svg\n [attr.width]=\"warp.width\"\n [attr.height]=\"warp.height\"\n [attr.viewBox]=\"'0 0 ' + warp.width + ' ' + warp.height\"\n style=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n aria-hidden=\"true\"\n >\n <defs>\n @for (line of warp.pathLines; track line.pathId) {\n <path [attr.id]=\"line.pathId\" [attr.d]=\"line.d\" fill=\"none\" />\n }\n </defs>\n @for (line of warp.pathLines; track line.pathId) {\n <text\n [attr.font-size]=\"warp.baseFontSize\"\n [attr.font-family]=\"warp.baseFontFamily\"\n [attr.fill]=\"warp.baseColor\"\n >\n <textPath\n [attr.href]=\"'#' + line.pathId\"\n [attr.startOffset]=\"warp.startOffset\"\n [attr.text-anchor]=\"warp.textAnchor\"\n >\n @for (seg of line.segments; track $index) {\n <tspan\n [attr.fill]=\"seg.style?.color ?? warp.baseColor\"\n [attr.font-weight]=\"seg.style?.bold ? 700 : 400\"\n [attr.font-style]=\"seg.style?.italic ? 'italic' : 'normal'\"\n >\n {{ seg.text }}\n </tspan>\n }\n </textPath>\n </text>\n }\n </svg>\n } @else if (placeholderPrompt(); as prompt) {\n <div class=\"pptx-ng-text\" [ngStyle]=\"prompt.style\">{{ prompt.text }}</div>\n } @else if (hasText()) {\n <pptx-slide-text-block\n [paragraphs]=\"paragraphs()\"\n [textStyle]=\"warpedTextStyle()\"\n [elementId]=\"element().id\"\n [subElementAnimStates]=\"subElementAnimStates()\"\n [interactive]=\"true\"\n />\n }\n }\n</div>\n"
97263
+ template: "<div\n class=\"pptx-ng-element pptx-ng-shape\"\n [ngStyle]=\"shapeContainerStyle()\"\n [style.pointer-events]=\"rootPointerEvents()\"\n [attr.data-element-id]=\"elementIdAttr()\"\n [attr.data-pptx-element]=\"elementMarked() ? 'true' : null\"\n>\n <!-- A font-style emphasis effect (Bold Flash, Bold Reveal, Underline,\n Change Font Style/Size) overrides the runs' own inline\n bold/italic/underline/size, which plain CSS inheritance cannot\n reach (the runs declare those unconditionally). -->\n <pptx-dynamic-style [css]=\"textStyleOverrideCss()\" />\n <!-- Interaction-only hit target for a degenerate shape; see `hitTargetStyle`. -->\n @if (hitTargetStyle(); as hit) {\n <div aria-hidden=\"true\" data-pptx-hit-target=\"true\" [ngStyle]=\"hit\"></div>\n }\n <!-- Per-sub-path fill overlay: a multi-sub-path preset (`smileyFace`'s\n open eyes, `actionButtonBlank`'s darkened bevel well) or custom\n geometry whose sub-paths cannot share one CSS background-color. -->\n @if (subpathFill(); as sf) {\n <svg\n class=\"pptx-ng-subpath-fill\"\n aria-hidden=\"true\"\n [attr.viewBox]=\"subpathFillViewBox()\"\n preserveAspectRatio=\"none\"\n style=\"position: absolute; inset: 0; width: 100%; height: 100%\"\n >\n @for (paint of sf.paints; track $index) {\n <path [attr.d]=\"paint.d\" [attr.fill]=\"paint.fill\" stroke=\"none\" />\n }\n </svg>\n }\n @if (fillOverlay(); as ov) {\n <div\n class=\"pptx-ng-fill-overlay\"\n aria-hidden=\"true\"\n style=\"position: absolute; inset: 0; pointer-events: none\"\n [style.background]=\"ov.color\"\n [style.mix-blend-mode]=\"ov.blendMode\"\n ></div>\n }\n <!-- Real 3D extrusion side panels (`a:sp3d/@extrusionH`), on top of the\n flat box-shadow approximation `shapeContainerStyle` already applied. -->\n <pptx-extrusion-3d-overlay [data]=\"extrusionData()\" />\n <!-- Mirrored reflection sibling (`a:reflection`): cross-browser, unlike\n the `-webkit-box-reflect` this replaced (Firefox never implemented\n that property, so reflections were invisible there entirely). A full\n inert clone of the element's own content (fill, outline, text body),\n not just its resolved fill - see `ReflectionMirrorContentComponent`. -->\n @if (reflection(); as refl) {\n <div class=\"pptx-ng-reflection\" aria-hidden=\"true\" [ngStyle]=\"refl.wrapperStyle\">\n <pptx-reflection-mirror-content [element]=\"element()\" [mediaDataUrls]=\"mediaDataUrls()\" />\n </div>\n }\n <!-- Hollow frame hit target: an unfilled, textless shape is hit-tested\n on its outline only, so its interior lets clicks through. -->\n @if (hollowHit(); as hit) {\n <svg\n aria-hidden=\"true\"\n [attr.viewBox]=\"outlineViewBox()\"\n preserveAspectRatio=\"none\"\n style=\"\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n min-width: 1px;\n min-height: 1px;\n overflow: visible;\n pointer-events: none;\n \"\n >\n <path\n [attr.d]=\"hit.d\"\n fill=\"none\"\n stroke=\"transparent\"\n [attr.stroke-width]=\"hit.strokeWidth\"\n style=\"pointer-events: stroke\"\n />\n </svg>\n }\n <!-- Stroked outline: a CSS border takes one flat colour, and cannot\n outline an open preset (`line`, `arc`) at all. -->\n @if (gradientOutline(); as go) {\n <svg\n class=\"pptx-ng-gradient-outline\"\n aria-hidden=\"true\"\n [attr.viewBox]=\"outlineViewBox()\"\n preserveAspectRatio=\"none\"\n style=\"\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n min-width: 1px;\n min-height: 1px;\n overflow: visible;\n pointer-events: none;\n \"\n >\n @if (go.paint; as paint) {\n <defs>\n @if (paint.kind === 'pattern') {\n <pattern\n [attr.id]=\"paint.id\"\n [attr.width]=\"paint.width\"\n [attr.height]=\"paint.height\"\n patternUnits=\"userSpaceOnUse\"\n >\n <image\n [attr.href]=\"paint.href\"\n [attr.width]=\"paint.width\"\n [attr.height]=\"paint.height\"\n />\n </pattern>\n } @else if (paint.kind === 'rectPath') {\n <pattern [attr.id]=\"paint.id\" patternUnits=\"objectBoundingBox\" width=\"1\" height=\"1\">\n <image\n [attr.href]=\"paint.href\"\n x=\"0\"\n y=\"0\"\n width=\"1\"\n height=\"1\"\n preserveAspectRatio=\"none\"\n />\n </pattern>\n } @else if (paint.kind === 'radial') {\n <radialGradient\n [attr.id]=\"paint.id\"\n [attr.cx]=\"paint.cx\"\n [attr.cy]=\"paint.cy\"\n [attr.r]=\"paint.r\"\n >\n @for (stop of paint.stops; track $index) {\n <stop\n [attr.offset]=\"stop.offset\"\n [attr.stop-color]=\"stop.color\"\n [attr.stop-opacity]=\"stop.opacity\"\n />\n }\n </radialGradient>\n } @else {\n <linearGradient\n [attr.id]=\"paint.id\"\n [attr.x1]=\"paint.x1\"\n [attr.y1]=\"paint.y1\"\n [attr.x2]=\"paint.x2\"\n [attr.y2]=\"paint.y2\"\n >\n @for (stop of paint.stops; track $index) {\n <stop\n [attr.offset]=\"stop.offset\"\n [attr.stop-color]=\"stop.color\"\n [attr.stop-opacity]=\"stop.opacity\"\n />\n }\n </linearGradient>\n }\n </defs>\n }\n @for (strand of go.strands; track $index) {\n <path\n [attr.d]=\"go.d\"\n fill=\"none\"\n [attr.stroke]=\"go.stroke\"\n [attr.stroke-width]=\"strand.strokeWidth\"\n [attr.stroke-dasharray]=\"go.dashArray\"\n [attr.stroke-linecap]=\"go.lineCap\"\n [attr.stroke-linejoin]=\"go.lineJoin\"\n [style.transform]=\"strand.offset !== 0 ? 'translate(0, ' + strand.offset + 'px)' : null\"\n />\n }\n </svg>\n }\n <!-- While this element is open in the inline text editor, its live text\n is drawn by that overlay instead (see `isBeingInlineEdited`);\n rendering it here too produced a duplicate, offset \"text shadow\"\n (issue #182). -->\n @if (!isBeingInlineEdited()) {\n @if (glyphWarp(); as gwarp) {\n <svg\n [attr.width]=\"gwarp.width\"\n [attr.height]=\"gwarp.height\"\n [attr.viewBox]=\"'0 0 ' + gwarp.width + ' ' + gwarp.height\"\n style=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n aria-hidden=\"true\"\n >\n @for (g of gwarp.glyphs; track $index) {\n <!-- The glyph's real outline, already warped point-by-point (see\n `buildWarpedGlyphOutlinePathD` in pptx-viewer-shared): exact,\n so no affine fit or slicing is needed. -->\n @if (g.outlinePath) {\n <path [attr.d]=\"g.outlinePath\" [attr.fill]=\"g.fill\" />\n } @else if (!g.slices || g.slices.length <= 1) {\n <text\n [attr.x]=\"g.x\"\n [attr.y]=\"g.y\"\n [attr.transform]=\"g.transform\"\n [attr.fill]=\"g.fill\"\n [attr.font-size]=\"g.fontSize\"\n [attr.font-weight]=\"g.fontWeight\"\n [attr.font-style]=\"g.fontStyle\"\n [attr.font-family]=\"g.fontFamily\"\n >\n {{ g.char }}\n </text>\n } @else {\n <!-- A very wide glyph on a strongly-curved envelope: rendered\n as `slices.length` clipped copies, each with its own affine\n (see `chooseGlyphSliceCount` in pptx-viewer-shared), so the\n pieces tile across the glyph. Wrapped in a real <g> so it\n never matches an \"svg > text\" selector the single-slice\n case does. -->\n <g [attr.data-glyph-slices]=\"g.slices.length\">\n @for (slice of g.slices; track $index; let si = $index) {\n <clipPath [attr.id]=\"g.clipIdPrefix + '-s' + si\" clipPathUnits=\"userSpaceOnUse\">\n <rect\n [attr.x]=\"slice.clipX0\"\n y=\"-100000\"\n [attr.width]=\"slice.clipX1 - slice.clipX0\"\n height=\"200000\"\n />\n </clipPath>\n <text\n [attr.x]=\"g.x\"\n [attr.y]=\"g.y\"\n [attr.transform]=\"slice.transform\"\n [attr.clip-path]=\"'url(#' + g.clipIdPrefix + '-s' + si + ')'\"\n [attr.fill]=\"g.fill\"\n [attr.font-size]=\"g.fontSize\"\n [attr.font-weight]=\"g.fontWeight\"\n [attr.font-style]=\"g.fontStyle\"\n [attr.font-family]=\"g.fontFamily\"\n >\n {{ g.char }}\n </text>\n }\n </g>\n }\n }\n </svg>\n } @else if (pathWarp(); as warp) {\n <svg\n [attr.width]=\"warp.width\"\n [attr.height]=\"warp.height\"\n [attr.viewBox]=\"'0 0 ' + warp.width + ' ' + warp.height\"\n style=\"position: absolute; inset: 0; overflow: visible; pointer-events: none\"\n aria-hidden=\"true\"\n >\n <defs>\n @for (line of warp.pathLines; track line.pathId) {\n <path [attr.id]=\"line.pathId\" [attr.d]=\"line.d\" fill=\"none\" />\n }\n </defs>\n @for (line of warp.pathLines; track line.pathId) {\n <text\n [attr.font-size]=\"warp.baseFontSize\"\n [attr.font-family]=\"warp.baseFontFamily\"\n [attr.fill]=\"warp.baseColor\"\n >\n <textPath\n [attr.href]=\"'#' + line.pathId\"\n [attr.startOffset]=\"warp.startOffset\"\n [attr.text-anchor]=\"warp.textAnchor\"\n >\n @for (seg of line.segments; track $index) {\n <tspan\n [attr.fill]=\"seg.style?.color ?? warp.baseColor\"\n [attr.font-weight]=\"seg.style?.bold ? 700 : 400\"\n [attr.font-style]=\"seg.style?.italic ? 'italic' : 'normal'\"\n >\n {{ seg.text }}\n </tspan>\n }\n </textPath>\n </text>\n }\n </svg>\n } @else if (placeholderPrompt(); as prompt) {\n <div class=\"pptx-ng-text\" [ngStyle]=\"prompt.style\">{{ prompt.text }}</div>\n } @else if (hasText()) {\n <pptx-slide-text-block\n [paragraphs]=\"paragraphs()\"\n [textStyle]=\"warpedTextStyle()\"\n [elementId]=\"element().id\"\n [subElementAnimStates]=\"subElementAnimStates()\"\n [interactive]=\"true\"\n />\n }\n }\n</div>\n"
97253
97264
  }]
97254
97265
  }],
97255
97266
  propDecorators: {
@@ -121394,7 +121405,7 @@ i0.ɵɵngDeclareClassMetadata({
121394
121405
  }]
121395
121406
  }
121396
121407
  });
121397
- const PPTX_ANGULAR_VIEWER_VERSION = "4.24.0";
121408
+ const PPTX_ANGULAR_VIEWER_VERSION = "4.24.1";
121398
121409
  var AccountPageComponent = class AccountPageComponent {
121399
121410
  constructor() {
121400
121411
  this.accountAuth = input(void 0, ...ngDevMode ? [{ debugName: "accountAuth" }] : /* istanbul ignore next */ []);