pptx-angular-viewer 3.16.7 → 3.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@ import { NgStyle, NgTemplateOutlet, NgClass } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
3
  import { InjectionToken, input, output, inject, computed, ChangeDetectionStrategy, Component, signal, Injectable, DestroyRef, viewChild, effect, Injector, untracked, ElementRef, HostListener, afterNextRender, Renderer2, ViewEncapsulation, forwardRef, Directive, linkedSignal } from '@angular/core';
4
4
  import { TranslateService, TranslatePipe, translate } from '@ngx-translate/core';
5
- import { THEME_PRESETS, guideEmuToPx, evaluateCustomGeometryPathData, getShapeClipPath, getAdjustmentAwareClipPath, getShapeClipPathFromPreset, getCloudPathForRendering, MIN_ELEMENT_SIZE as MIN_ELEMENT_SIZE$1, evaluateCustomGeometryPaths, customGeometryPathsToSvgSubpaths, evaluatePresetShape, hasShapeProperties, ooxmlGradientAngleToCssDegrees, getShapeType, isImageLikeElement, getElementTextContent, getRoundRectRadiusPx as getRoundRectRadiusPx$1, applyDrawingColorTransforms as applyDrawingColorTransforms$1, hslToRgb as hslToRgb$1, PRESET_COLOR_MAP, getSubstituteFontFamily, parsePanoseString, hasTextProperties, evaluateGuides, deobfuscateFont, detectFontFormat, stripXmlOrderSuffix, orderedXmlKey, parseDataUrlToBytes, sampleFirstPixelColorFromBytes, flattenChartUserShapes, chartDataChangeType, isParetoChartData, resolveDisplayedChartTypeName, chartDataAddSeries, chartDataRemoveSeries, chartDataAddCategory, chartDataRemoveCategory, chartDataUpdatePoint, resolveThemeColorRef, rebuildTableStructureInRawXml, updateCellTextInRawXml, deepCloneData, cloneTemplateElementsBySlideId, cloneSlide, EMU_PER_PX as EMU_PER_PX$2, DEFAULT_POWERPOINT_TABLE_STYLE_ID, DEFAULT_SCHEME_COLOR_MAP as DEFAULT_SCHEME_COLOR_MAP$1, formatAutoNumberMarker, getLinkedTextBoxSegments, deriveSlideTitle, svgPathToPolygons, THEME_COLOR_SCHEME_KEYS, createBuiltinVariables, resolveCoordinate, getPresetConnectionSites, createAutoNumberSequence, breakAutoNumberRun, nextAutoNumber, resolveCustomGeometryToken, resolveCustomGeometryGuideContext, lookupPresetShape, normalizeStShapeType, PptxHandler, styleStroke, strokeFor, fitFontSize, nodeTextStyle, truncate, nodeOpacity, nodeStroke, nodeFill, styleShadow, buildTree, treeWidth, treeDepth, gearPoints, flattenNodes, interpretSmartArtLayout, addSmartArtNode, removeSmartArtNode, demoteSmartArtNode, promoteSmartArtNode, reorderSmartArtNode, createEditorId, makeStoreAwareId, reassignDescendantIds, checkMissingAltText, checkMissingSlideTitle, checkLowContrast, checkComplexTables, checkBlankSlide, checkDuplicateTitles, createChartElement, THEME_COLOR_PALETTE_COLUMNS, hexToRgbChannels as hexToRgbChannels$2, rgbToHsl as rgbToHsl$1, renameSlideMaster, deleteSlideMaster, duplicateSlideMaster, insertSlideMaster, renameLayout, deleteLayout, duplicateLayout, insertLayout, detectFileFormat, cloneElement, duplicateElement, resolveModifyVerifierAlgorithmName, verifyModifyPassword, TABLE_STYLE_PART_SEQUENCE, serializePptxToJson, PPTX_JSON_MIME_TYPE, PptxMarkdownConverter, ThemePresets, formatCommentTimestamp as formatCommentTimestamp$1, EncryptedFileError, decodeXmlEntities, parseSignatureXml, groupElements, ungroupElements, updateSmartArtNodeText, setSmartArtNodeStyle, isInkElement, isZoomElement, SvgExporter, applyThemeToData, reResolveElementColors, pptxActionToElementAction, elementActionToPptxAction, setChartTitle, setChartLegend, setChartDataLabels, setChartAxis, setChartSeriesTrendline, setChartSeriesErrorBars, setChartDataPointLabel, setChartAxisLogScale, setChartAxisTitleStyle, setChartAxisGridlineStyle, setChartSeriesMarker, setChartSeriesChartType, setChartDataPointFill, setChartDataPointMarker, setChartDataPointExplosion, getOleSheetGrid, getOleDocumentParagraphs, getOleNestedDeckDetail, applyOleSheetCellEdit, applyOleDocumentParagraphEdit, applyOleNestedDeckElementTextEdit, replaceOleFile, getOleObjectTypeLabel, addSmartArtNodeAsChild, switchSmartArtLayout, SWITCHABLE_LAYOUT_TYPES, normalizeTableStyleGuid, createTableStyleEntry, addTableStyleToMap, deleteTableStyleFromMap, COLOR_MAP_ALIAS_KEYS, DEFAULT_COLOR_MAP, applyThemeOverrideToSlide, TRANSITION_VALID_DIRECTIONS } from 'pptx-viewer-core';
5
+ import { THEME_PRESETS, guideEmuToPx, evaluateCustomGeometryPathData, getShapeClipPath, getAdjustmentAwareClipPath, getShapeClipPathFromPreset, getCloudPathForRendering, MIN_ELEMENT_SIZE as MIN_ELEMENT_SIZE$1, evaluateCustomGeometryPaths, customGeometryPathsToSvgSubpaths, evaluatePresetShape, hasShapeProperties, ooxmlGradientAngleToCssDegrees, getShapeType, isImageLikeElement, getElementTextContent, getRoundRectRadiusPx as getRoundRectRadiusPx$1, applyDrawingColorTransforms as applyDrawingColorTransforms$1, hslToRgb as hslToRgb$1, PRESET_COLOR_MAP, getSubstituteFontFamily, parsePanoseString, hasTextProperties, evaluateGuides, deobfuscateFont, detectFontFormat, stripXmlOrderSuffix, orderedXmlKey, parseDataUrlToBytes, sampleFirstPixelColorFromBytes, flattenChartUserShapes, chartDataChangeType, isParetoChartData, resolveDisplayedChartTypeName, chartDataAddSeries, chartDataRemoveSeries, chartDataAddCategory, chartDataRemoveCategory, chartDataUpdatePoint, resolveThemeColorRef, rebuildTableStructureInRawXml, updateCellTextInRawXml, deepCloneData, cloneTemplateElementsBySlideId, cloneSlide, EMU_PER_PX as EMU_PER_PX$2, DEFAULT_POWERPOINT_TABLE_STYLE_ID, DEFAULT_SCHEME_COLOR_MAP as DEFAULT_SCHEME_COLOR_MAP$1, formatAutoNumberMarker, createAutoNumberSequence, nextAutoNumber, breakAutoNumberRun, getLinkedTextBoxSegments, deriveSlideTitle, svgPathToPolygons, THEME_COLOR_SCHEME_KEYS, createBuiltinVariables, resolveCoordinate, getPresetConnectionSites, resolveCustomGeometryToken, resolveCustomGeometryGuideContext, lookupPresetShape, normalizeStShapeType, PptxHandler, styleStroke, strokeFor, fitFontSize, nodeTextStyle, truncate, nodeOpacity, nodeStroke, nodeFill, styleShadow, buildTree, treeWidth, treeDepth, gearPoints, flattenNodes, interpretSmartArtLayout, addSmartArtNode, removeSmartArtNode, demoteSmartArtNode, promoteSmartArtNode, reorderSmartArtNode, createEditorId, makeStoreAwareId, reassignDescendantIds, checkMissingAltText, checkMissingSlideTitle, checkLowContrast, checkComplexTables, checkBlankSlide, checkDuplicateTitles, createChartElement, THEME_COLOR_PALETTE_COLUMNS, hexToRgbChannels as hexToRgbChannels$2, rgbToHsl as rgbToHsl$1, renameSlideMaster, deleteSlideMaster, duplicateSlideMaster, insertSlideMaster, renameLayout, deleteLayout, duplicateLayout, insertLayout, detectFileFormat, cloneElement, duplicateElement, resolveModifyVerifierAlgorithmName, verifyModifyPassword, TABLE_STYLE_PART_SEQUENCE, serializePptxToJson, PPTX_JSON_MIME_TYPE, PptxMarkdownConverter, ThemePresets, formatCommentTimestamp as formatCommentTimestamp$1, EncryptedFileError, decodeXmlEntities, parseSignatureXml, groupElements, ungroupElements, updateSmartArtNodeText, setSmartArtNodeStyle, isInkElement, isZoomElement, SvgExporter, applyThemeToData, reResolveElementColors, pptxActionToElementAction, elementActionToPptxAction, setChartTitle, setChartLegend, setChartDataLabels, setChartAxis, setChartSeriesTrendline, setChartSeriesErrorBars, setChartDataPointLabel, setChartAxisLogScale, setChartAxisTitleStyle, setChartAxisGridlineStyle, setChartSeriesMarker, setChartSeriesChartType, setChartDataPointFill, setChartDataPointMarker, setChartDataPointExplosion, getOleSheetGrid, getOleDocumentParagraphs, getOleNestedDeckDetail, applyOleSheetCellEdit, applyOleDocumentParagraphEdit, applyOleNestedDeckElementTextEdit, replaceOleFile, getOleObjectTypeLabel, addSmartArtNodeAsChild, switchSmartArtLayout, SWITCHABLE_LAYOUT_TYPES, normalizeTableStyleGuid, createTableStyleEntry, addTableStyleToMap, deleteTableStyleFromMap, COLOR_MAP_ALIAS_KEYS, DEFAULT_COLOR_MAP, applyThemeOverrideToSlide, TRANSITION_VALID_DIRECTIONS } from 'pptx-viewer-core';
6
6
  import { parse } from 'opentype.js';
7
7
  import DOMPurify from 'dompurify';
8
8
  import { z } from 'zod';
@@ -52371,218 +52371,676 @@ function resolveParagraphIndent(paraIndent, paragraphLevel) {
52371
52371
  return { marginLeftPx: marginLeft, textIndentPx: textIndent };
52372
52372
  }
52373
52373
 
52374
- /**
52375
- * Bullet / numbered-list toggling for the ribbon's paragraph buttons.
52376
- *
52377
- * The renderer (`resolveParagraphBullet`) and the save writer
52378
- * (`applyBulletProperties`) both read a paragraph's list state from the
52379
- * `bulletInfo` of its FIRST segment; `TextStyle.listType` is consulted for
52380
- * nothing but the `'none'` suppression. Every binding's Bullets / Numbering
52381
- * button used to write `listType: 'bullet' | 'numbered'` onto the element's
52382
- * `textStyle`, a field nothing downstream reads, so the buttons were dead.
52383
- *
52384
- * These helpers author the real thing: a `BulletInfo` on each paragraph's
52385
- * first segment (`a:buChar` / `a:buAutoNum` / `a:buNone` on save), with the
52386
- * inert `listType` cleared so a stale `'none'` cannot suppress the new marker.
52387
- *
52388
- * On load core prefixes a display-only marker segment (text "• " / "1.") to a
52389
- * listed paragraph; the renderer drops it when its text matches the marker it
52390
- * would draw, and the save writer drops it because the paragraph properties
52391
- * already express it. Switching a bullet to a number (or off) would leave the
52392
- * old glyph behind as literal text, so the previous marker is removed and a
52393
- * fresh one authored in the same shape core uses.
52394
- */
52395
- /** The default character bullet PowerPoint inserts (`a:buChar char="•"`). */
52396
52374
  const DEFAULT_BULLET_CHAR = '•';
52397
- /** The default numbering scheme PowerPoint inserts (`a:buAutoNum type="arabicPeriod"`). */
52398
52375
  const DEFAULT_AUTONUM_TYPE = 'arabicPeriod';
52399
- /**
52400
- * The `BulletInfo` that authors `kind`.
52401
- *
52402
- * @param ordinal - Zero-based position of the paragraph within its numbered
52403
- * run, published as `paragraphIndex` so the renderer counts "1. 2. 3." (see
52404
- * `BulletInfo.paragraphIndex`). Ignored for the other kinds.
52405
- */
52406
52376
  function bulletInfoForKind(kind, ordinal = 0) {
52407
- switch (kind) {
52408
- case 'bullet':
52409
- return { char: DEFAULT_BULLET_CHAR };
52410
- case 'numbered':
52411
- return { autoNumType: DEFAULT_AUTONUM_TYPE, autoNumStartAt: 1, paragraphIndex: ordinal };
52412
- case 'none':
52413
- return { none: true };
52377
+ if (kind === 'none') {
52378
+ return { none: true };
52379
+ }
52380
+ if (kind === 'bullet') {
52381
+ return { char: DEFAULT_BULLET_CHAR };
52414
52382
  }
52383
+ return { autoNumType: DEFAULT_AUTONUM_TYPE, autoNumStartAt: 1, paragraphIndex: ordinal };
52415
52384
  }
52416
- /**
52417
- * Whether a segment is the display-only marker core inserts on load (mirrors
52418
- * the save writer's `isRenderedBulletMarker`): it carries `bulletInfo` and its
52419
- * text is exactly the glyph the renderer would draw for that info.
52420
- */
52385
+ /** Matches core's synthetic prefix, including picture and suppressed markers. */
52421
52386
  function isBulletMarkerSegment(segment) {
52422
- const bullet = segment.bulletInfo;
52423
- if (!bullet || bullet.none) {
52387
+ const info = segment.bulletInfo;
52388
+ if (!info || info.none || segment.fieldType || segment.isLineBreak) {
52424
52389
  return false;
52425
52390
  }
52426
- const resolved = resolveParagraphBullet(segment);
52427
- if (!resolved) {
52391
+ if (!info.char &&
52392
+ !info.autoNumType &&
52393
+ !info.imageRelId &&
52394
+ !info.imageDataUrl &&
52395
+ !info.imageBlipFillXml) {
52428
52396
  return false;
52429
52397
  }
52430
- return segment.text.trim() === resolved.marker.trim() && segment.text.trim().length > 0;
52398
+ if (info.autoNumType) {
52399
+ // Without this runtime field, a literal "1." is authored content (PR 204).
52400
+ if (info.paragraphIndex === undefined) {
52401
+ return false;
52402
+ }
52403
+ const marker = markerText(info);
52404
+ return segment.text === marker || segment.text === `${marker} `;
52405
+ }
52406
+ return segment.text === markerText(info);
52431
52407
  }
52432
- /**
52433
- * The current list state of one paragraph (its segments, separators excluded),
52434
- * derived from the resolved bullet of its first segment so an inherited
52435
- * (master / layout) bullet that core resolved on load counts as `'bullet'`.
52436
- */
52437
52408
  function paragraphBulletKind(paragraph) {
52438
52409
  const resolved = resolveParagraphBullet(paragraph[0]);
52439
- if (!resolved) {
52440
- return 'none';
52441
- }
52442
- return resolved.isNumbered ? 'numbered' : 'bullet';
52410
+ return resolved ? (resolved.isNumbered ? 'numbered' : 'bullet') : 'none';
52443
52411
  }
52444
- /** Copy of `style` without the inert `listType` flag. */
52445
52412
  function withoutListType(style) {
52446
- const next = { ...(style ?? {}) };
52413
+ const next = { ...style };
52447
52414
  delete next.listType;
52448
52415
  return next;
52449
52416
  }
52450
- function paragraphMeta(segment) {
52451
- const meta = {};
52452
- if (segment?.paragraphLevel !== undefined) {
52453
- meta.paragraphLevel = segment.paragraphLevel;
52454
- }
52455
- if (segment?.paragraphProperties !== undefined) {
52456
- meta.paragraphProperties = segment.paragraphProperties;
52417
+ function markerText(info) {
52418
+ if (info.imageRelId || info.imageDataUrl || info.imageBlipFillXml) {
52419
+ return '📎 ';
52457
52420
  }
52458
- if (segment?.endParaRunProperties !== undefined) {
52459
- meta.endParaRunProperties = segment.endParaRunProperties;
52421
+ if (info.autoNumType) {
52422
+ return formatAutoNumberMarker(info.autoNumType, Math.max(1, (info.autoNumStartAt ?? 1) + (info.paragraphIndex ?? 0)));
52460
52423
  }
52461
- return meta;
52424
+ return `${info.char ?? DEFAULT_BULLET_CHAR} `;
52462
52425
  }
52463
- /** The display text of the marker segment for a bullet / numbered `info`. */
52464
- function markerText(info) {
52465
- if (info.char) {
52466
- return `${info.char} `;
52426
+ function infoForParagraph(previous, kind, ordinal) {
52427
+ if (kind === 'none') {
52428
+ return { ...previous, none: true };
52429
+ }
52430
+ const sameKind = previous &&
52431
+ (kind === 'numbered'
52432
+ ? Boolean(previous.autoNumType)
52433
+ : Boolean(previous.char ||
52434
+ previous.imageRelId ||
52435
+ previous.imageDataUrl ||
52436
+ previous.imageBlipFillXml) && !previous.autoNumType);
52437
+ const info = sameKind ? { ...previous } : bulletInfoForKind(kind, ordinal);
52438
+ delete info.none;
52439
+ if (kind === 'numbered' && ordinal !== undefined) {
52440
+ info.paragraphIndex = ordinal;
52467
52441
  }
52468
- const ordinal = (info.autoNumStartAt ?? 1) + (info.paragraphIndex ?? 0);
52469
- return formatAutoNumberMarker(info.autoNumType ?? DEFAULT_AUTONUM_TYPE, ordinal);
52442
+ return info;
52470
52443
  }
52471
- /**
52472
- * Set one paragraph's list state to `kind`, returning the paragraph's new
52473
- * segments.
52474
- *
52475
- * The result uses the same shape core produces on load, so the renderer and
52476
- * the save writer treat an authored list exactly like a parsed one: for
52477
- * `'bullet'` / `'numbered'` a display-only marker segment carrying the new
52478
- * `bulletInfo` (and the paragraph-level fields) is placed first, followed by
52479
- * the content runs with any previous marker removed; for `'none'` the marker
52480
- * is dropped and the first content segment carries `{ none: true }`. The
52481
- * inert `style.listType` is cleared on the touched segments. An empty
52482
- * paragraph is returned unchanged since there is no run to carry the state.
52483
- *
52484
- * @param ordinal - Zero-based position within a numbered run; see
52485
- * {@link bulletInfoForKind}.
52486
- */
52487
- function toggleParagraphBullet(paragraph, kind, ordinal = 0) {
52488
- const content = paragraph.filter((segment) => !isBulletMarkerSegment(segment));
52489
- const first = content[0];
52490
- if (!first) {
52491
- return [...paragraph];
52492
- }
52493
- const meta = paragraphMeta(paragraph[0]);
52494
- const info = bulletInfoForKind(kind, ordinal);
52495
- const rest = content.slice(1);
52496
- if (kind === 'none') {
52497
- return [{ ...first, ...meta, style: withoutListType(first.style), bulletInfo: info }, ...rest];
52444
+ /** Explicit set, despite the historical name. Only the leading marker is removed. */
52445
+ function toggleParagraphBullet(paragraph, kind, ordinal) {
52446
+ const source = paragraph[0];
52447
+ if (!source) {
52448
+ return [];
52449
+ }
52450
+ if (paragraph.length === 1 &&
52451
+ source.paragraphInsertionStyle &&
52452
+ (source.text === '' || isBulletMarkerSegment(source))) {
52453
+ const info = infoForParagraph(source.bulletInfo, kind, ordinal);
52454
+ const picture = info.imageRelId || info.imageDataUrl || info.imageBlipFillXml;
52455
+ return [
52456
+ {
52457
+ ...source,
52458
+ text: kind === 'none' || picture ? '' : markerText(info),
52459
+ style: withoutListType(source.style),
52460
+ bulletInfo: info,
52461
+ },
52462
+ ];
52498
52463
  }
52499
- const marker = {
52500
- text: markerText(info),
52501
- style: withoutListType(first.style),
52502
- ...meta,
52503
- bulletInfo: info,
52464
+ const content = isBulletMarkerSegment(source) ? paragraph.slice(1) : [...paragraph];
52465
+ const first = content[0] ?? { text: '', style: source.style };
52466
+ const meta = {
52467
+ ...(source.paragraphLevel !== undefined ? { paragraphLevel: source.paragraphLevel } : {}),
52468
+ ...(source.paragraphProperties ? { paragraphProperties: source.paragraphProperties } : {}),
52469
+ ...(source.endParaRunProperties ? { endParaRunProperties: source.endParaRunProperties } : {}),
52470
+ ...(source.paragraphInsertionStyle
52471
+ ? { paragraphInsertionStyle: source.paragraphInsertionStyle }
52472
+ : {}),
52504
52473
  };
52505
- const body = { ...first, style: withoutListType(first.style) };
52474
+ const info = infoForParagraph(source.bulletInfo, kind, ordinal);
52475
+ const body = { ...first, ...meta, style: withoutListType(first.style) };
52476
+ const rest = content.slice(1).map((segment) => {
52477
+ if (!segment.bulletInfo) {
52478
+ return segment;
52479
+ }
52480
+ const run = { ...segment };
52481
+ delete run.bulletInfo;
52482
+ return run;
52483
+ });
52484
+ // Picture markers render separately; never insert their textual fallback as body.
52485
+ if (kind === 'none' || info.imageRelId || info.imageDataUrl || info.imageBlipFillXml) {
52486
+ return [{ ...body, bulletInfo: info }, ...rest];
52487
+ }
52506
52488
  delete body.bulletInfo;
52507
- return [marker, body, ...rest];
52489
+ delete body.paragraphInsertionStyle;
52490
+ const markerStyle = isBulletMarkerSegment(source) && paragraphBulletKind([source]) === kind
52491
+ ? source.style
52492
+ : first.style;
52493
+ return [
52494
+ { text: markerText(info), style: withoutListType(markerStyle), ...meta, bulletInfo: info },
52495
+ body,
52496
+ ...rest,
52497
+ ];
52508
52498
  }
52509
- function isParagraphSeparator$1(segment) {
52510
- return Boolean(segment.isParagraphBreak) || (segment.text === '\n' && !segment.isLineBreak);
52499
+ function elementSegments(element) {
52500
+ if (!hasTextProperties(element)) {
52501
+ return [];
52502
+ }
52503
+ if (element.textSegments?.length) {
52504
+ return element.textSegments;
52505
+ }
52506
+ return (element.text ?? '')
52507
+ .split('\n')
52508
+ .flatMap((text, index) => [
52509
+ ...(index ? [{ text: '\n', style: { ...element.textStyle }, isParagraphBreak: true }] : []),
52510
+ { text, style: { ...element.textStyle } },
52511
+ ]);
52511
52512
  }
52512
- /** Split a segment list into paragraphs, keeping each paragraph's terminator. */
52513
52513
  function splitParagraphs(segments) {
52514
52514
  const paragraphs = [
52515
52515
  { segments: [] },
52516
52516
  ];
52517
52517
  for (const segment of segments) {
52518
- if (isParagraphSeparator$1(segment)) {
52518
+ if (isParagraphSeparatorSegment(segment)) {
52519
52519
  paragraphs[paragraphs.length - 1].terminator = segment;
52520
52520
  paragraphs.push({ segments: [] });
52521
- continue;
52522
52521
  }
52523
- paragraphs[paragraphs.length - 1].segments.push(segment);
52522
+ else {
52523
+ paragraphs[paragraphs.length - 1].segments.push(segment);
52524
+ }
52524
52525
  }
52525
52526
  return paragraphs;
52526
52527
  }
52527
- /** The element's segments, synthesised from `text` when it carries none. */
52528
- function elementSegments(element) {
52528
+ /** Existing element-wide toggle convention: use its first nonempty paragraph. */
52529
+ function elementBulletKind(element) {
52530
+ for (const paragraph of splitParagraphs(elementSegments(element))) {
52531
+ if (paragraph.segments.length) {
52532
+ return paragraphBulletKind(paragraph.segments);
52533
+ }
52534
+ }
52535
+ return 'none';
52536
+ }
52537
+ /**
52538
+ * Explicitly set the touched paragraphs. Existing same-kind definitions survive;
52539
+ * defaults are only for new lists. Retained buNone metadata supports live off/on,
52540
+ * not restoration of a deleted definition after a save/reload.
52541
+ */
52542
+ function setElementBullets(element, kind, range) {
52529
52543
  if (!hasTextProperties(element)) {
52530
- return [];
52544
+ return {};
52531
52545
  }
52532
- if (element.textSegments && element.textSegments.length > 0) {
52533
- return element.textSegments;
52546
+ if (range &&
52547
+ (!Number.isInteger(range.startParagraph) ||
52548
+ !Number.isInteger(range.endParagraph) ||
52549
+ range.startParagraph < 0 ||
52550
+ range.endParagraph < range.startParagraph)) {
52551
+ return {};
52534
52552
  }
52535
- const style = { ...(element.textStyle ?? {}) };
52536
- const segments = [];
52537
- for (const [index, line] of (element.text ?? '').split('\n').entries()) {
52538
- if (index > 0) {
52539
- segments.push({ text: '\n', style: { ...style }, isParagraphBreak: true });
52553
+ const paragraphs = splitParagraphs(elementSegments(element));
52554
+ if (range && range.startParagraph >= paragraphs.length) {
52555
+ return {};
52556
+ }
52557
+ const next = [];
52558
+ const sequence = createAutoNumberSequence();
52559
+ for (const [index, paragraph] of paragraphs.entries()) {
52560
+ const selected = !range || (index >= range.startParagraph && index <= range.endParagraph);
52561
+ let segments = paragraph.segments;
52562
+ if (selected) {
52563
+ const empty = {
52564
+ ...paragraph.terminator,
52565
+ text: '',
52566
+ style: { ...paragraph.terminator?.style },
52567
+ };
52568
+ delete empty.isParagraphBreak;
52569
+ delete empty.isLineBreak;
52570
+ segments = toggleParagraphBullet(segments.length ? segments : [empty], kind);
52571
+ }
52572
+ const first = segments[0] ?? paragraph.terminator;
52573
+ const info = first?.bulletInfo;
52574
+ const level = first?.paragraphLevel ?? 0;
52575
+ if (info?.autoNumType && paragraphBulletKind(segments) === 'numbered') {
52576
+ const startAt = info.autoNumStartAt ?? 1;
52577
+ const ordinal = nextAutoNumber(sequence, level, info.autoNumType, startAt) - startAt;
52578
+ // List membership changes also renumber following items. Only this
52579
+ // derived ordinal changes outside the selected paragraphs.
52580
+ if (info.paragraphIndex !== ordinal) {
52581
+ segments = toggleParagraphBullet(segments, 'numbered', ordinal);
52582
+ }
52583
+ }
52584
+ else {
52585
+ breakAutoNumberRun(sequence, level);
52586
+ }
52587
+ next.push(...segments);
52588
+ if (paragraph.terminator) {
52589
+ next.push(paragraph.terminator);
52540
52590
  }
52541
- segments.push({ text: line, style: { ...style } });
52542
52591
  }
52543
- return segments;
52592
+ return {
52593
+ textSegments: next,
52594
+ textStyle: withoutListType(element.textStyle),
52595
+ };
52544
52596
  }
52597
+ /** Button intent, unlike the explicit style setter above. */
52598
+ function toggleElementBullets(element, kind) {
52599
+ return setElementBullets(element, elementBulletKind(element) === kind ? 'none' : kind);
52600
+ }
52601
+
52602
+ /** Keep a runless paragraph's future body formatting in the same style edit. */
52603
+ function updateTextSegmentStyle(segment, updates, options = {}) {
52604
+ return {
52605
+ ...segment,
52606
+ ...(options.updateBodyStyle === false ? {} : { style: { ...segment.style, ...updates } }),
52607
+ ...(segment.paragraphInsertionStyle
52608
+ ? { paragraphInsertionStyle: { ...segment.paragraphInsertionStyle, ...updates } }
52609
+ : {}),
52610
+ };
52611
+ }
52612
+
52545
52613
  /**
52546
- * The list state an element's ribbon buttons should show: the kind of its
52547
- * first non-empty paragraph, since that is what a toggle would act on.
52614
+ * Read the current browser selection and, if it falls within an
52615
+ * `[data-inline-editor]` element, return the segment-level range.
52616
+ *
52617
+ * Returns `null` when there is no editable text selected, the selection is
52618
+ * collapsed (just a cursor), or the selection is outside the inline editor.
52548
52619
  */
52549
- function elementBulletKind(element) {
52550
- for (const paragraph of splitParagraphs(elementSegments(element))) {
52551
- if (paragraph.segments.length > 0) {
52552
- return paragraphBulletKind(paragraph.segments);
52620
+ function getInlineEditorSelection(segments) {
52621
+ if (!segments?.length) {
52622
+ return null;
52623
+ }
52624
+ const selection = window.getSelection();
52625
+ if (!selection || selection.rangeCount === 0 || selection.isCollapsed) {
52626
+ return null;
52627
+ }
52628
+ // A Range is always in document order, including for a backwards selection.
52629
+ const range = selection.getRangeAt(0);
52630
+ const editor = findEditorContainer(range.startContainer);
52631
+ if (!editor || !editor.contains(range.endContainer) || range.toString().length === 0) {
52632
+ return null;
52633
+ }
52634
+ const start = getSegmentPosition(editor, range.startContainer, range.startOffset, segments);
52635
+ const end = getSegmentPosition(editor, range.endContainer, range.endOffset, segments);
52636
+ if (!start || !end) {
52637
+ return null;
52638
+ }
52639
+ const renderedSpans = Array.from(editor.querySelectorAll('[data-seg-idx]'));
52640
+ const startSpanIndex = renderedSpans.indexOf(start.span);
52641
+ const endSpanIndex = renderedSpans.indexOf(end.span);
52642
+ if (startSpanIndex < 0 || endSpanIndex < startSpanIndex) {
52643
+ return null;
52644
+ }
52645
+ const selectedSpans = renderedSpans.slice(startSpanIndex, endSpanIndex + 1);
52646
+ const first = selectedSpans.find((span) => isEditableSpan(span, segments) && (span !== start.span || start.offset < start.textLength));
52647
+ const last = [...selectedSpans]
52648
+ .reverse()
52649
+ .find((span) => isEditableSpan(span, segments) && (span !== end.span || end.offset > 0));
52650
+ if (!first || !last) {
52651
+ return null;
52652
+ }
52653
+ return {
52654
+ startSegIdx: getSegmentIndex(first),
52655
+ startOffset: first === start.span ? start.offset : 0,
52656
+ endSegIdx: getSegmentIndex(last),
52657
+ endOffset: last === end.span ? end.offset : (last.textContent?.length ?? 0),
52658
+ };
52659
+ }
52660
+ function isEditableSpan(span, segments) {
52661
+ const segment = segments[getSegmentIndex(span)];
52662
+ return Boolean(segment &&
52663
+ !segment.isParagraphBreak &&
52664
+ segment.text !== '\n' &&
52665
+ !isBulletMarkerSegment(segment) &&
52666
+ (span.textContent?.length ?? 0) > 0);
52667
+ }
52668
+ function getSegmentIndex(span) {
52669
+ return Number(span.getAttribute('data-seg-idx'));
52670
+ }
52671
+ function findEditorContainer(node) {
52672
+ const element = node.nodeType === Node.ELEMENT_NODE ? node : node.parentElement;
52673
+ return element?.closest('[data-inline-editor]') ?? null;
52674
+ }
52675
+ function getSegmentPosition(editor, node, offset, segments) {
52676
+ const element = node.nodeType === Node.ELEMENT_NODE ? node : node.parentElement;
52677
+ const span = element?.closest('[data-seg-idx]');
52678
+ if (!span || !editor.contains(span)) {
52679
+ return null;
52680
+ }
52681
+ const segIdx = getSegmentIndex(span);
52682
+ if (!Number.isInteger(segIdx) || segIdx < 0 || segIdx >= segments.length) {
52683
+ return null;
52684
+ }
52685
+ return {
52686
+ segIdx,
52687
+ offset: getTextOffsetWithin(span, node, offset),
52688
+ span,
52689
+ textLength: span.textContent?.length ?? 0,
52690
+ };
52691
+ }
52692
+ function getTextOffsetWithin(container, targetNode, targetOffset) {
52693
+ if (targetNode === container || targetNode.nodeType === Node.ELEMENT_NODE) {
52694
+ const parent = targetNode === container ? container : targetNode;
52695
+ let count = 0;
52696
+ for (let index = 0; index < targetOffset && index < parent.childNodes.length; index++) {
52697
+ count += parent.childNodes[index].textContent?.length ?? 0;
52553
52698
  }
52699
+ return count;
52554
52700
  }
52555
- return 'none';
52701
+ const walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT);
52702
+ let charCount = 0;
52703
+ let node;
52704
+ while ((node = walker.nextNode())) {
52705
+ if (node === targetNode) {
52706
+ return charCount + targetOffset;
52707
+ }
52708
+ charCount += node.length;
52709
+ }
52710
+ return charCount;
52711
+ }
52712
+
52713
+ let pendingRestore = null;
52714
+ function setPendingSelectionRestore(sel) {
52715
+ pendingRestore = sel;
52716
+ }
52717
+ /** Read-once: clears the stored value after returning it. */
52718
+ function getPendingSelectionRestore() {
52719
+ const sel = pendingRestore;
52720
+ pendingRestore = null;
52721
+ return sel;
52556
52722
  }
52557
52723
  /**
52558
- * Set every paragraph of an element to `kind`, returning the element patch
52559
- * (`textSegments` rewritten; `textStyle.listType` cleared so the element-level
52560
- * flag can no longer suppress or lie about the state). Numbered paragraphs are
52561
- * counted consecutively so the renderer shows "1. 2. 3.".
52724
+ * Apply `updates` only to the characters within the selection range. Segments
52725
+ * at the boundaries are split; segments outside the range are copied unchanged.
52726
+ * Paragraph-break segments (`\n`) are always passed through unchanged.
52727
+ *
52728
+ * Returns the new segments array AND the selection coordinates mapped to the
52729
+ * new segment indices (for cursor restoration).
52562
52730
  */
52563
- function setElementBullets(element, kind) {
52564
- const textStyle = withoutListType(hasTextProperties(element) ? element.textStyle : undefined);
52565
- const next = [];
52566
- let ordinal = 0;
52567
- for (const paragraph of splitParagraphs(elementSegments(element))) {
52568
- if (paragraph.segments.length > 0) {
52569
- next.push(...toggleParagraphBullet(paragraph.segments, kind, ordinal));
52570
- ordinal += 1;
52731
+ function applyStyleToSelectedSegments(segments, selection, updates) {
52732
+ const { startSegIdx, startOffset, endSegIdx, endOffset } = selection;
52733
+ const result = [];
52734
+ // Track new indices for the start/end of the selected text in the new array.
52735
+ let newStartSegIdx = -1;
52736
+ let newStartOffset = 0;
52737
+ let newEndSegIdx = -1;
52738
+ let newEndOffset = 0;
52739
+ for (let i = 0; i < segments.length; i++) {
52740
+ const seg = i >= startSegIdx && i <= endSegIdx
52741
+ ? updateTextSegmentStyle(segments[i], updates, { updateBodyStyle: false })
52742
+ : segments[i];
52743
+ // Paragraph-break segments always pass through.
52744
+ if (seg.isParagraphBreak || seg.text === '\n') {
52745
+ result.push({ ...seg, style: { ...seg.style } });
52746
+ continue;
52571
52747
  }
52572
- if (paragraph.terminator) {
52573
- next.push(paragraph.terminator);
52748
+ // Before selection range.
52749
+ if (i < startSegIdx) {
52750
+ result.push({ ...seg, style: { ...seg.style } });
52751
+ continue;
52752
+ }
52753
+ // After selection range.
52754
+ if (i > endSegIdx) {
52755
+ result.push({ ...seg, style: { ...seg.style } });
52756
+ continue;
52574
52757
  }
52758
+ // Single-segment selection (start and end in the same segment).
52759
+ if (seg.paragraphInsertionStyle && (seg.text === '' || isBulletMarkerSegment(seg))) {
52760
+ newStartSegIdx = newStartSegIdx < 0 ? result.length : newStartSegIdx;
52761
+ newEndSegIdx = result.length;
52762
+ result.push(seg);
52763
+ continue;
52764
+ }
52765
+ if (i === startSegIdx && i === endSegIdx) {
52766
+ splitSingle(seg, startOffset, endOffset, updates, result);
52767
+ // Track the new selection: the selected part is at `result.length - 1`
52768
+ // (or `result.length - 2` if there's an after part).
52769
+ const partsAdded = (startOffset > 0 ? 1 : 0) + 1 + (endOffset < seg.text.length ? 1 : 0);
52770
+ const selectedPartIdx = result.length - partsAdded + (startOffset > 0 ? 1 : 0);
52771
+ newStartSegIdx = selectedPartIdx;
52772
+ newStartOffset = 0;
52773
+ newEndSegIdx = selectedPartIdx;
52774
+ newEndOffset = endOffset - startOffset;
52775
+ continue;
52776
+ }
52777
+ // Start segment of multi-segment selection.
52778
+ if (i === startSegIdx) {
52779
+ if (startOffset === 0) {
52780
+ newStartSegIdx = result.length;
52781
+ newStartOffset = 0;
52782
+ result.push({ ...seg, style: { ...seg.style, ...updates } });
52783
+ }
52784
+ else {
52785
+ // Before-selection part.
52786
+ const beforeSeg = {
52787
+ text: seg.text.slice(0, startOffset),
52788
+ style: { ...seg.style },
52789
+ };
52790
+ if (seg.bulletInfo) {
52791
+ beforeSeg.bulletInfo = seg.bulletInfo;
52792
+ }
52793
+ result.push(beforeSeg);
52794
+ // Selected part.
52795
+ newStartSegIdx = result.length;
52796
+ newStartOffset = 0;
52797
+ result.push({
52798
+ text: seg.text.slice(startOffset),
52799
+ style: { ...seg.style, ...updates },
52800
+ });
52801
+ }
52802
+ continue;
52803
+ }
52804
+ // End segment of multi-segment selection.
52805
+ if (i === endSegIdx) {
52806
+ if (endOffset >= seg.text.length) {
52807
+ result.push({ ...seg, style: { ...seg.style, ...updates } });
52808
+ newEndSegIdx = result.length - 1;
52809
+ newEndOffset = seg.text.length;
52810
+ }
52811
+ else {
52812
+ // Selected part.
52813
+ result.push({
52814
+ text: seg.text.slice(0, endOffset),
52815
+ style: { ...seg.style, ...updates },
52816
+ });
52817
+ newEndSegIdx = result.length - 1;
52818
+ newEndOffset = endOffset;
52819
+ // After-selection part.
52820
+ result.push({
52821
+ text: seg.text.slice(endOffset),
52822
+ style: { ...seg.style },
52823
+ });
52824
+ }
52825
+ continue;
52826
+ }
52827
+ // Middle segment: entirely within selection.
52828
+ result.push({ ...seg, style: { ...seg.style, ...updates } });
52829
+ }
52830
+ return {
52831
+ newSegments: result,
52832
+ newSelection: {
52833
+ startSegIdx: newStartSegIdx,
52834
+ startOffset: newStartOffset,
52835
+ endSegIdx: newEndSegIdx,
52836
+ endOffset: newEndOffset,
52837
+ },
52838
+ };
52839
+ }
52840
+ function splitSingle(seg, startOffset, endOffset, updates, result) {
52841
+ // Entire segment selected.
52842
+ if (startOffset === 0 && endOffset >= seg.text.length) {
52843
+ result.push({ ...seg, style: { ...seg.style, ...updates } });
52844
+ return;
52845
+ }
52846
+ // Before-selection part.
52847
+ if (startOffset > 0) {
52848
+ const beforeSeg = {
52849
+ text: seg.text.slice(0, startOffset),
52850
+ style: { ...seg.style },
52851
+ };
52852
+ if (seg.bulletInfo) {
52853
+ beforeSeg.bulletInfo = seg.bulletInfo;
52854
+ }
52855
+ result.push(beforeSeg);
52856
+ }
52857
+ // Selected part.
52858
+ result.push({
52859
+ text: seg.text.slice(startOffset, endOffset),
52860
+ style: { ...seg.style, ...updates },
52861
+ });
52862
+ // After-selection part.
52863
+ if (endOffset < seg.text.length) {
52864
+ result.push({
52865
+ text: seg.text.slice(endOffset),
52866
+ style: { ...seg.style },
52867
+ });
52575
52868
  }
52576
- return { textSegments: next, textStyle };
52577
52869
  }
52578
52870
  /**
52579
- * The ribbon button behaviour: pressing Bullets (or Numbering) on an element
52580
- * already in that state turns its lists off, otherwise it applies that kind
52581
- * to every paragraph. Returns the element patch to apply through the
52582
- * binding's update-element operation.
52871
+ * Set the DOM selection inside the inline editor using segment-level
52872
+ * coordinates. Finds `[data-seg-idx]` spans and navigates to the correct
52873
+ * text-node offsets.
52583
52874
  */
52584
- function toggleElementBullets(element, kind) {
52585
- return setElementBullets(element, elementBulletKind(element) === kind ? 'none' : kind);
52875
+ function restoreSegmentSelection(editor, startSegIdx, startOffset, endSegIdx, endOffset) {
52876
+ const sel = window.getSelection();
52877
+ if (!sel) {
52878
+ return;
52879
+ }
52880
+ const startPos = findTextPositionInSegment(editor, startSegIdx, startOffset);
52881
+ const endPos = findTextPositionInSegment(editor, endSegIdx, endOffset);
52882
+ if (!startPos || !endPos) {
52883
+ return;
52884
+ }
52885
+ const range = document.createRange();
52886
+ range.setStart(startPos.node, startPos.offset);
52887
+ range.setEnd(endPos.node, endPos.offset);
52888
+ sel.removeAllRanges();
52889
+ sel.addRange(range);
52890
+ }
52891
+ function findTextPositionInSegment(editor, segIdx, charOffset) {
52892
+ const segSpan = editor.querySelector(`[data-seg-idx="${segIdx}"]`);
52893
+ if (!segSpan) {
52894
+ return null;
52895
+ }
52896
+ const walker = document.createTreeWalker(segSpan, NodeFilter.SHOW_TEXT);
52897
+ let charCount = 0;
52898
+ let node;
52899
+ while ((node = walker.nextNode())) {
52900
+ const textLen = node.length;
52901
+ if (charCount + textLen >= charOffset) {
52902
+ return { node, offset: charOffset - charCount };
52903
+ }
52904
+ charCount += textLen;
52905
+ }
52906
+ // If exact position not found, place at end of last text node.
52907
+ const lastTextNode = segSpan.querySelector('*') ? null : segSpan.firstChild;
52908
+ if (lastTextNode && lastTextNode.nodeType === Node.TEXT_NODE) {
52909
+ return { node: lastTextNode, offset: lastTextNode.length };
52910
+ }
52911
+ return null;
52912
+ }
52913
+
52914
+ /** Body offsets ignore only the leading display marker of each paragraph. */
52915
+ function positions(segments) {
52916
+ let offset = 0;
52917
+ let paragraph = 0;
52918
+ let first = true;
52919
+ return segments.map((segment) => {
52920
+ const marker = first && isBulletMarkerSegment(segment);
52921
+ const start = offset;
52922
+ if (!marker) {
52923
+ offset += segment.text.length;
52924
+ }
52925
+ const entry = {
52926
+ start,
52927
+ end: offset,
52928
+ paragraph,
52929
+ editable: !marker && !isParagraphSeparatorSegment(segment),
52930
+ };
52931
+ first = isParagraphSeparatorSegment(segment);
52932
+ if (first) {
52933
+ paragraph += 1;
52934
+ }
52935
+ return entry;
52936
+ });
52937
+ }
52938
+ function restorePoint(segments, offset, end) {
52939
+ const entries = positions(segments);
52940
+ let fallback = { index: 0, offset: 0 };
52941
+ for (const [index, entry] of entries.entries()) {
52942
+ if (!entry.editable) {
52943
+ continue;
52944
+ }
52945
+ fallback = { index, offset: segments[index].text.length };
52946
+ if (end ? offset <= entry.end : offset < entry.end) {
52947
+ return { index, offset: Math.max(0, offset - entry.start) };
52948
+ }
52949
+ }
52950
+ return fallback;
52951
+ }
52952
+ /** Keep paragraph metadata on the first run when character styling splits it. */
52953
+ function restoreParagraphMetadata$1(original, updated) {
52954
+ const firstRuns = original.filter((_, index) => index === 0 || isParagraphSeparatorSegment(original[index - 1]));
52955
+ let paragraph = 0;
52956
+ return updated.map((segment, index) => {
52957
+ const first = index === 0 || isParagraphSeparatorSegment(updated[index - 1]);
52958
+ if (!first) {
52959
+ return segment;
52960
+ }
52961
+ const source = firstRuns[paragraph++];
52962
+ if (!source) {
52963
+ return segment;
52964
+ }
52965
+ return {
52966
+ ...segment,
52967
+ bulletInfo: source.bulletInfo,
52968
+ paragraphLevel: source.paragraphLevel,
52969
+ paragraphProperties: source.paragraphProperties,
52970
+ endParaRunProperties: source.endParaRunProperties,
52971
+ };
52972
+ });
52973
+ }
52974
+ /** Current kind at the first selected paragraph; otherwise the element default. */
52975
+ function selectedParagraphBulletKind(element, selection) {
52976
+ if (!selection || !hasTextProperties(element) || !element.textSegments) {
52977
+ return elementBulletKind(element);
52978
+ }
52979
+ let first = selection.startSegIdx;
52980
+ while (first > 0 && !isParagraphSeparatorSegment(element.textSegments[first - 1])) {
52981
+ first -= 1;
52982
+ }
52983
+ return paragraphBulletKind(element.textSegments.slice(first));
52984
+ }
52985
+ /**
52986
+ * Apply a list request to touched paragraphs, while accompanying character
52987
+ * styles retain their existing selection scope. A null selection means the
52988
+ * whole element, matching the existing editor contract.
52989
+ */
52990
+ function applyListStyleUpdate(element, updates, selection) {
52991
+ if (!hasTextProperties(element) || !updates.listType) {
52992
+ return { patch: {}, selection };
52993
+ }
52994
+ const { listType, ...characterStyle } = updates;
52995
+ let segments = element.textSegments;
52996
+ let workingSelection = selection;
52997
+ if (segments && Object.keys(characterStyle).length > 0) {
52998
+ if (selection) {
52999
+ const styled = applyStyleToSelectedSegments(segments, selection, characterStyle);
53000
+ segments = restoreParagraphMetadata$1(segments, styled.newSegments);
53001
+ workingSelection = styled.newSelection;
53002
+ }
53003
+ else {
53004
+ segments = segments.map((segment) => updateTextSegmentStyle(segment, characterStyle));
53005
+ }
53006
+ }
53007
+ const working = {
53008
+ ...element,
53009
+ textSegments: segments,
53010
+ textStyle: selection ? element.textStyle : { ...element.textStyle, ...characterStyle },
53011
+ };
53012
+ if (!workingSelection || !segments) {
53013
+ return { patch: setElementBullets(working, listType), selection: null };
53014
+ }
53015
+ const entries = positions(segments);
53016
+ const startEntry = entries[workingSelection.startSegIdx];
53017
+ const endEntry = entries[workingSelection.endSegIdx];
53018
+ if (!startEntry || !endEntry) {
53019
+ return { patch: {}, selection: null };
53020
+ }
53021
+ const startOffset = startEntry.start + workingSelection.startOffset;
53022
+ const endOffset = endEntry.start + workingSelection.endOffset;
53023
+ const lastSelected = [...entries].reverse().find((entry) => entry.start < endOffset);
53024
+ const patch = setElementBullets(working, listType, {
53025
+ startParagraph: startEntry.paragraph,
53026
+ endParagraph: lastSelected?.paragraph ?? endEntry.paragraph,
53027
+ });
53028
+ const next = { ...working, ...patch };
53029
+ const nextSegments = hasTextProperties(next) ? next.textSegments : undefined;
53030
+ if (!nextSegments) {
53031
+ return { patch, selection: null };
53032
+ }
53033
+ const start = restorePoint(nextSegments, startOffset, false);
53034
+ const end = restorePoint(nextSegments, endOffset, true);
53035
+ return {
53036
+ patch,
53037
+ selection: {
53038
+ startSegIdx: start.index,
53039
+ startOffset: start.offset,
53040
+ endSegIdx: end.index,
53041
+ endOffset: end.offset,
53042
+ },
53043
+ };
52586
53044
  }
52587
53045
 
52588
53046
  /**
@@ -61984,299 +62442,6 @@ function buildLeaderString(leader, widthPx, fontSizePx = 16) {
61984
62442
  return char.repeat(count);
61985
62443
  }
61986
62444
 
61987
- /**
61988
- * Read the current browser selection and, if it falls within an
61989
- * `[data-inline-editor]` element, return the segment-level range.
61990
- *
61991
- * Returns `null` when there is no editable text selected, the selection is
61992
- * collapsed (just a cursor), or the selection is outside the inline editor.
61993
- */
61994
- function getInlineEditorSelection(segments) {
61995
- if (!segments?.length) {
61996
- return null;
61997
- }
61998
- const selection = window.getSelection();
61999
- if (!selection || selection.rangeCount === 0 || selection.isCollapsed) {
62000
- return null;
62001
- }
62002
- // A Range is always in document order, including for a backwards selection.
62003
- const range = selection.getRangeAt(0);
62004
- const editor = findEditorContainer(range.startContainer);
62005
- if (!editor || !editor.contains(range.endContainer) || range.toString().length === 0) {
62006
- return null;
62007
- }
62008
- const start = getSegmentPosition(editor, range.startContainer, range.startOffset, segments);
62009
- const end = getSegmentPosition(editor, range.endContainer, range.endOffset, segments);
62010
- if (!start || !end) {
62011
- return null;
62012
- }
62013
- const renderedSpans = Array.from(editor.querySelectorAll('[data-seg-idx]'));
62014
- const startSpanIndex = renderedSpans.indexOf(start.span);
62015
- const endSpanIndex = renderedSpans.indexOf(end.span);
62016
- if (startSpanIndex < 0 || endSpanIndex < startSpanIndex) {
62017
- return null;
62018
- }
62019
- const selectedSpans = renderedSpans.slice(startSpanIndex, endSpanIndex + 1);
62020
- const first = selectedSpans.find((span) => isEditableSpan(span, segments) && (span !== start.span || start.offset < start.textLength));
62021
- const last = [...selectedSpans]
62022
- .reverse()
62023
- .find((span) => isEditableSpan(span, segments) && (span !== end.span || end.offset > 0));
62024
- if (!first || !last) {
62025
- return null;
62026
- }
62027
- return {
62028
- startSegIdx: getSegmentIndex(first),
62029
- startOffset: first === start.span ? start.offset : 0,
62030
- endSegIdx: getSegmentIndex(last),
62031
- endOffset: last === end.span ? end.offset : (last.textContent?.length ?? 0),
62032
- };
62033
- }
62034
- function isEditableSpan(span, segments) {
62035
- const segment = segments[getSegmentIndex(span)];
62036
- return Boolean(segment &&
62037
- !segment.isParagraphBreak &&
62038
- segment.text !== '\n' &&
62039
- !isBulletMarkerSegment(segment) &&
62040
- (span.textContent?.length ?? 0) > 0);
62041
- }
62042
- function getSegmentIndex(span) {
62043
- return Number(span.getAttribute('data-seg-idx'));
62044
- }
62045
- function findEditorContainer(node) {
62046
- const element = node.nodeType === Node.ELEMENT_NODE ? node : node.parentElement;
62047
- return element?.closest('[data-inline-editor]') ?? null;
62048
- }
62049
- function getSegmentPosition(editor, node, offset, segments) {
62050
- const element = node.nodeType === Node.ELEMENT_NODE ? node : node.parentElement;
62051
- const span = element?.closest('[data-seg-idx]');
62052
- if (!span || !editor.contains(span)) {
62053
- return null;
62054
- }
62055
- const segIdx = getSegmentIndex(span);
62056
- if (!Number.isInteger(segIdx) || segIdx < 0 || segIdx >= segments.length) {
62057
- return null;
62058
- }
62059
- return {
62060
- segIdx,
62061
- offset: getTextOffsetWithin(span, node, offset),
62062
- span,
62063
- textLength: span.textContent?.length ?? 0,
62064
- };
62065
- }
62066
- function getTextOffsetWithin(container, targetNode, targetOffset) {
62067
- if (targetNode === container || targetNode.nodeType === Node.ELEMENT_NODE) {
62068
- const parent = targetNode === container ? container : targetNode;
62069
- let count = 0;
62070
- for (let index = 0; index < targetOffset && index < parent.childNodes.length; index++) {
62071
- count += parent.childNodes[index].textContent?.length ?? 0;
62072
- }
62073
- return count;
62074
- }
62075
- const walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT);
62076
- let charCount = 0;
62077
- let node;
62078
- while ((node = walker.nextNode())) {
62079
- if (node === targetNode) {
62080
- return charCount + targetOffset;
62081
- }
62082
- charCount += node.length;
62083
- }
62084
- return charCount;
62085
- }
62086
-
62087
- let pendingRestore = null;
62088
- function setPendingSelectionRestore(sel) {
62089
- pendingRestore = sel;
62090
- }
62091
- /** Read-once: clears the stored value after returning it. */
62092
- function getPendingSelectionRestore() {
62093
- const sel = pendingRestore;
62094
- pendingRestore = null;
62095
- return sel;
62096
- }
62097
- /**
62098
- * Apply `updates` only to the characters within the selection range. Segments
62099
- * at the boundaries are split; segments outside the range are copied unchanged.
62100
- * Paragraph-break segments (`\n`) are always passed through unchanged.
62101
- *
62102
- * Returns the new segments array AND the selection coordinates mapped to the
62103
- * new segment indices (for cursor restoration).
62104
- */
62105
- function applyStyleToSelectedSegments(segments, selection, updates) {
62106
- const { startSegIdx, startOffset, endSegIdx, endOffset } = selection;
62107
- const result = [];
62108
- // Track new indices for the start/end of the selected text in the new array.
62109
- let newStartSegIdx = -1;
62110
- let newStartOffset = 0;
62111
- let newEndSegIdx = -1;
62112
- let newEndOffset = 0;
62113
- for (let i = 0; i < segments.length; i++) {
62114
- const seg = segments[i];
62115
- // Paragraph-break segments always pass through.
62116
- if (seg.isParagraphBreak || seg.text === '\n') {
62117
- result.push({ ...seg, style: { ...seg.style } });
62118
- continue;
62119
- }
62120
- // Before selection range.
62121
- if (i < startSegIdx) {
62122
- result.push({ ...seg, style: { ...seg.style } });
62123
- continue;
62124
- }
62125
- // After selection range.
62126
- if (i > endSegIdx) {
62127
- result.push({ ...seg, style: { ...seg.style } });
62128
- continue;
62129
- }
62130
- // Single-segment selection (start and end in the same segment).
62131
- if (i === startSegIdx && i === endSegIdx) {
62132
- splitSingle(seg, startOffset, endOffset, updates, result);
62133
- // Track the new selection: the selected part is at `result.length - 1`
62134
- // (or `result.length - 2` if there's an after part).
62135
- const partsAdded = (startOffset > 0 ? 1 : 0) + 1 + (endOffset < seg.text.length ? 1 : 0);
62136
- const selectedPartIdx = result.length - partsAdded + (startOffset > 0 ? 1 : 0);
62137
- newStartSegIdx = selectedPartIdx;
62138
- newStartOffset = 0;
62139
- newEndSegIdx = selectedPartIdx;
62140
- newEndOffset = endOffset - startOffset;
62141
- continue;
62142
- }
62143
- // Start segment of multi-segment selection.
62144
- if (i === startSegIdx) {
62145
- if (startOffset === 0) {
62146
- newStartSegIdx = result.length;
62147
- newStartOffset = 0;
62148
- result.push({ ...seg, style: { ...seg.style, ...updates } });
62149
- }
62150
- else {
62151
- // Before-selection part.
62152
- const beforeSeg = {
62153
- text: seg.text.slice(0, startOffset),
62154
- style: { ...seg.style },
62155
- };
62156
- if (seg.bulletInfo) {
62157
- beforeSeg.bulletInfo = seg.bulletInfo;
62158
- }
62159
- result.push(beforeSeg);
62160
- // Selected part.
62161
- newStartSegIdx = result.length;
62162
- newStartOffset = 0;
62163
- result.push({
62164
- text: seg.text.slice(startOffset),
62165
- style: { ...seg.style, ...updates },
62166
- });
62167
- }
62168
- continue;
62169
- }
62170
- // End segment of multi-segment selection.
62171
- if (i === endSegIdx) {
62172
- if (endOffset >= seg.text.length) {
62173
- result.push({ ...seg, style: { ...seg.style, ...updates } });
62174
- newEndSegIdx = result.length - 1;
62175
- newEndOffset = seg.text.length;
62176
- }
62177
- else {
62178
- // Selected part.
62179
- result.push({
62180
- text: seg.text.slice(0, endOffset),
62181
- style: { ...seg.style, ...updates },
62182
- });
62183
- newEndSegIdx = result.length - 1;
62184
- newEndOffset = endOffset;
62185
- // After-selection part.
62186
- result.push({
62187
- text: seg.text.slice(endOffset),
62188
- style: { ...seg.style },
62189
- });
62190
- }
62191
- continue;
62192
- }
62193
- // Middle segment: entirely within selection.
62194
- result.push({ ...seg, style: { ...seg.style, ...updates } });
62195
- }
62196
- return {
62197
- newSegments: result,
62198
- newSelection: {
62199
- startSegIdx: newStartSegIdx,
62200
- startOffset: newStartOffset,
62201
- endSegIdx: newEndSegIdx,
62202
- endOffset: newEndOffset,
62203
- },
62204
- };
62205
- }
62206
- function splitSingle(seg, startOffset, endOffset, updates, result) {
62207
- // Entire segment selected.
62208
- if (startOffset === 0 && endOffset >= seg.text.length) {
62209
- result.push({ ...seg, style: { ...seg.style, ...updates } });
62210
- return;
62211
- }
62212
- // Before-selection part.
62213
- if (startOffset > 0) {
62214
- const beforeSeg = {
62215
- text: seg.text.slice(0, startOffset),
62216
- style: { ...seg.style },
62217
- };
62218
- if (seg.bulletInfo) {
62219
- beforeSeg.bulletInfo = seg.bulletInfo;
62220
- }
62221
- result.push(beforeSeg);
62222
- }
62223
- // Selected part.
62224
- result.push({
62225
- text: seg.text.slice(startOffset, endOffset),
62226
- style: { ...seg.style, ...updates },
62227
- });
62228
- // After-selection part.
62229
- if (endOffset < seg.text.length) {
62230
- result.push({
62231
- text: seg.text.slice(endOffset),
62232
- style: { ...seg.style },
62233
- });
62234
- }
62235
- }
62236
- /**
62237
- * Set the DOM selection inside the inline editor using segment-level
62238
- * coordinates. Finds `[data-seg-idx]` spans and navigates to the correct
62239
- * text-node offsets.
62240
- */
62241
- function restoreSegmentSelection(editor, startSegIdx, startOffset, endSegIdx, endOffset) {
62242
- const sel = window.getSelection();
62243
- if (!sel) {
62244
- return;
62245
- }
62246
- const startPos = findTextPositionInSegment(editor, startSegIdx, startOffset);
62247
- const endPos = findTextPositionInSegment(editor, endSegIdx, endOffset);
62248
- if (!startPos || !endPos) {
62249
- return;
62250
- }
62251
- const range = document.createRange();
62252
- range.setStart(startPos.node, startPos.offset);
62253
- range.setEnd(endPos.node, endPos.offset);
62254
- sel.removeAllRanges();
62255
- sel.addRange(range);
62256
- }
62257
- function findTextPositionInSegment(editor, segIdx, charOffset) {
62258
- const segSpan = editor.querySelector(`[data-seg-idx="${segIdx}"]`);
62259
- if (!segSpan) {
62260
- return null;
62261
- }
62262
- const walker = document.createTreeWalker(segSpan, NodeFilter.SHOW_TEXT);
62263
- let charCount = 0;
62264
- let node;
62265
- while ((node = walker.nextNode())) {
62266
- const textLen = node.length;
62267
- if (charCount + textLen >= charOffset) {
62268
- return { node, offset: charOffset - charCount };
62269
- }
62270
- charCount += textLen;
62271
- }
62272
- // If exact position not found, place at end of last text node.
62273
- const lastTextNode = segSpan.querySelector('*') ? null : segSpan.firstChild;
62274
- if (lastTextNode && lastTextNode.nodeType === Node.TEXT_NODE) {
62275
- return { node: lastTextNode, offset: lastTextNode.length };
62276
- }
62277
- return null;
62278
- }
62279
-
62280
62445
  /**
62281
62446
  * Caret placement for the inline text editors.
62282
62447
  *
@@ -63987,6 +64152,231 @@ function connectorArrowPatch(control, raw) {
63987
64152
  return { [control.styleKey]: raw };
63988
64153
  }
63989
64154
 
64155
+ /**
64156
+ * Regular-text font sizes are stored in slide/CSS pixels in the shared model,
64157
+ * while PowerPoint's font controls and the preset list below use points.
64158
+ */
64159
+ function textFontSizePxToPt(fontSizePx) {
64160
+ // DrawingML stores regular text sizes in hundredths of a point. Normalising
64161
+ // to that precision removes binary floating-point noise without discarding
64162
+ // valid authored values such as 10.5 pt or 48.1 pt.
64163
+ return Math.round(fontSizePx * (72 / 96) * 100) / 100;
64164
+ }
64165
+ /** Convert a PowerPoint font-control value in points to the model's pixels. */
64166
+ function textFontSizePtToPx(fontSizePt) {
64167
+ return fontSizePt * (96 / 72);
64168
+ }
64169
+ /**
64170
+ * Font families offered by the Home-tab font dropdown, alphabetically.
64171
+ *
64172
+ * Covers the families PowerPoint's own list leads with (the Office UI faces,
64173
+ * the Aptos family that replaced Calibri as the default theme font, and the
64174
+ * classic Windows/Mac core fonts) plus the handful of web faces decks
64175
+ * routinely arrive with. Entries the host cannot resolve simply fall back
64176
+ * through the CSS font stack, so listing a family costs nothing but gives the
64177
+ * user a name to pick when the deck already references it.
64178
+ */
64179
+ const COMMON_FONT_FAMILIES = [
64180
+ 'Abadi',
64181
+ 'Aptos',
64182
+ 'Aptos Display',
64183
+ 'Arial',
64184
+ 'Arial Black',
64185
+ 'Arial Narrow',
64186
+ 'Bahnschrift',
64187
+ 'Book Antiqua',
64188
+ 'Bookman Old Style',
64189
+ 'Calibri',
64190
+ 'Calibri Light',
64191
+ 'Cambria',
64192
+ 'Candara',
64193
+ 'Century Gothic',
64194
+ 'Comic Sans MS',
64195
+ 'Consolas',
64196
+ 'Corbel',
64197
+ 'Courier New',
64198
+ 'Franklin Gothic Book',
64199
+ 'Franklin Gothic Medium',
64200
+ 'Garamond',
64201
+ 'Georgia',
64202
+ 'Gill Sans MT',
64203
+ 'Helvetica',
64204
+ 'Impact',
64205
+ 'Inter',
64206
+ 'Lucida Console',
64207
+ 'Lucida Sans Unicode',
64208
+ 'Microsoft Sans Serif',
64209
+ 'Montserrat',
64210
+ 'Noto Sans',
64211
+ 'Open Sans',
64212
+ 'Palatino Linotype',
64213
+ 'Poppins',
64214
+ 'Roboto',
64215
+ 'Rockwell',
64216
+ 'Segoe UI',
64217
+ 'Source Sans Pro',
64218
+ 'Tahoma',
64219
+ 'Times New Roman',
64220
+ 'Trebuchet MS',
64221
+ 'Tw Cen MT',
64222
+ 'Verdana',
64223
+ ];
64224
+ /** Font sizes (pt) offered by the Home-tab size dropdown. */
64225
+ const COMMON_FONT_SIZES = [
64226
+ 8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 28, 32, 36, 40, 44, 48, 54, 60, 72, 96,
64227
+ ];
64228
+ /** Character-spacing presets for the toolbar dropdown. */
64229
+ const CHARACTER_SPACING_OPTIONS = [
64230
+ { label: 'Very Tight', i18nKey: 'pptx.text.characterSpacingVeryTight', value: -150 },
64231
+ { label: 'Tight', i18nKey: 'pptx.text.characterSpacingTight', value: -75 },
64232
+ { label: 'Normal', i18nKey: 'pptx.text.characterSpacingNormal', value: 0 },
64233
+ { label: 'Loose', i18nKey: 'pptx.text.characterSpacingLoose', value: 75 },
64234
+ { label: 'Very Loose', i18nKey: 'pptx.text.characterSpacingVeryLoose', value: 150 },
64235
+ ];
64236
+ /** Line-spacing presets for the paragraph dropdown. */
64237
+ const LINE_SPACING_OPTIONS$1 = [
64238
+ { label: '1.0', value: 1.0 },
64239
+ { label: '1.15', value: 1.15 },
64240
+ { label: '1.5', value: 1.5 },
64241
+ { label: '2.0', value: 2.0 },
64242
+ { label: '2.5', value: 2.5 },
64243
+ { label: '3.0', value: 3.0 },
64244
+ ];
64245
+ /** Change-case options in menu order (matches PowerPoint's ordering). */
64246
+ const CHANGE_CASE_OPTIONS$1 = [
64247
+ { value: 'sentence', i18nKey: 'pptx.text.changeCaseSentence' },
64248
+ { value: 'lower', i18nKey: 'pptx.text.changeCaseLower' },
64249
+ { value: 'upper', i18nKey: 'pptx.text.changeCaseUpper' },
64250
+ { value: 'capitalize', i18nKey: 'pptx.text.changeCaseCapitalize' },
64251
+ { value: 'toggle', i18nKey: 'pptx.text.changeCaseToggle' },
64252
+ ];
64253
+
64254
+ /**
64255
+ * inspector-helpers.ts: Pure (no framework) helpers for the inspector panel.
64256
+ *
64257
+ * Readers extract display values from a PptxElement (with sensible defaults),
64258
+ * and patch builders produce shallow-merge-ready Partial<PptxElement> objects
64259
+ * for the binding's element-update path. Shared across React, Vue, and Angular.
64260
+ */
64261
+ const DEFAULT_FILL = '#ffffff';
64262
+ const DEFAULT_STROKE = '#000000';
64263
+ const DEFAULT_TEXT_COLOR = '#000000';
64264
+ /**
64265
+ * PowerPoint's own presentation-level default text style (`p:defaultTextStyle
64266
+ * /a:lvl1pPr/a:defRPr@sz`) is 1800 (18pt), so a shape with no explicit font
64267
+ * size renders at 18pt in real PowerPoint, not 12pt. Kept as the last-resort
64268
+ * fallback below the deck's actual default when {@link fontSizeOf} is given one.
64269
+ */
64270
+ const DEFAULT_FONT_SIZE$2 = 18;
64271
+ /**
64272
+ * Returns the fill colour of the element's shapeStyle, or a white default.
64273
+ * Only meaningful for elements that pass `hasShapeProperties`.
64274
+ */
64275
+ function fillColorOf$1(el) {
64276
+ if (hasShapeProperties(el)) {
64277
+ return el.shapeStyle?.fillColor ?? DEFAULT_FILL;
64278
+ }
64279
+ return DEFAULT_FILL;
64280
+ }
64281
+ /**
64282
+ * Returns the stroke colour of the element's shapeStyle, or a black default.
64283
+ * Only meaningful for elements that pass `hasShapeProperties`.
64284
+ */
64285
+ function strokeColorOf(el) {
64286
+ if (hasShapeProperties(el)) {
64287
+ return el.shapeStyle?.strokeColor ?? DEFAULT_STROKE;
64288
+ }
64289
+ return DEFAULT_STROKE;
64290
+ }
64291
+ /**
64292
+ * Returns the text colour from the element's textStyle, or a black default.
64293
+ * Only meaningful for elements that pass `hasTextProperties`.
64294
+ */
64295
+ function textColorOf(el) {
64296
+ if (hasTextProperties(el)) {
64297
+ return el.textStyle?.color ?? DEFAULT_TEXT_COLOR;
64298
+ }
64299
+ return DEFAULT_TEXT_COLOR;
64300
+ }
64301
+ /**
64302
+ * Returns the font size (in points) from the element's textStyle.
64303
+ *
64304
+ * Falls back, in order, to: the deck's presentation-level default text style
64305
+ * (`p:defaultTextStyle`, passed as `presentationDefault` when the caller has
64306
+ * one), then `DEFAULT_FONT_SIZE` (18pt, matching PowerPoint's own
64307
+ * `a:lvl1pPr/a:defRPr@sz="1800"` when neither is available).
64308
+ */
64309
+ function fontSizeOf(el, presentationDefault) {
64310
+ if (hasTextProperties(el) && el.textStyle?.fontSize !== undefined) {
64311
+ return textFontSizePxToPt(el.textStyle.fontSize);
64312
+ }
64313
+ const deckDefault = presentationDefault?.levelStyles?.[0]?.fontSize;
64314
+ return deckDefault === undefined ? DEFAULT_FONT_SIZE$2 : textFontSizePxToPt(deckDefault);
64315
+ }
64316
+ /** Returns whether the element's text is bold (false when absent). */
64317
+ function isBold(el) {
64318
+ if (hasTextProperties(el)) {
64319
+ return el.textStyle?.bold ?? false;
64320
+ }
64321
+ return false;
64322
+ }
64323
+ /** Returns whether the element's text is italic (false when absent). */
64324
+ function isItalic(el) {
64325
+ if (hasTextProperties(el)) {
64326
+ return el.textStyle?.italic ?? false;
64327
+ }
64328
+ return false;
64329
+ }
64330
+ /** Returns whether the element's text has underline (false when absent). */
64331
+ function isUnderline(el) {
64332
+ if (hasTextProperties(el)) {
64333
+ return el.textStyle?.underline ?? false;
64334
+ }
64335
+ return false;
64336
+ }
64337
+ /**
64338
+ * Builds a Partial<PptxElement> patch that merges the given changes into the
64339
+ * element's existing shapeStyle without dropping any other shapeStyle fields.
64340
+ */
64341
+ function shapeStylePatch$1(el, changes) {
64342
+ const base = hasShapeProperties(el) ? (el.shapeStyle ?? {}) : {};
64343
+ return {
64344
+ shapeStyle: {
64345
+ ...base,
64346
+ ...changes,
64347
+ },
64348
+ };
64349
+ }
64350
+ /**
64351
+ * Builds a Partial<PptxElement> patch that merges the given changes into the
64352
+ * element's existing textStyle without dropping any other textStyle fields.
64353
+ */
64354
+ function textStylePatch(el, changes) {
64355
+ const base = hasTextProperties(el) ? (el.textStyle ?? {}) : {};
64356
+ return {
64357
+ ...(hasTextProperties(el) && el.textSegments?.some((segment) => segment.paragraphInsertionStyle)
64358
+ ? {
64359
+ textSegments: el.textSegments.map((segment) => updateTextSegmentStyle(segment, changes, { updateBodyStyle: false })),
64360
+ }
64361
+ : {}),
64362
+ textStyle: {
64363
+ ...base,
64364
+ ...changes,
64365
+ },
64366
+ };
64367
+ }
64368
+ /** Apply an ordinary-text model pixel size to the element and all of its runs. */
64369
+ function textFontSizePatch(el, fontSize) {
64370
+ const patch = textStylePatch(el, { fontSize });
64371
+ if (!hasTextProperties(el) || !el.textSegments) {
64372
+ return patch;
64373
+ }
64374
+ return {
64375
+ ...patch,
64376
+ textSegments: el.textSegments.map((segment) => updateTextSegmentStyle(segment, { fontSize })),
64377
+ };
64378
+ }
64379
+
63990
64380
  /** Copy the paintable shape + text style off an element. */
63991
64381
  function copyFormatFromElement(element) {
63992
64382
  const result = {};
@@ -64063,10 +64453,7 @@ function applyFormatToElement(element, format) {
64063
64453
  if (format.textStyle && hasTextProperties(updated)) {
64064
64454
  updated = {
64065
64455
  ...updated,
64066
- textStyle: {
64067
- ...updated.textStyle,
64068
- ...definedEntries(format.textStyle),
64069
- },
64456
+ ...textStylePatch(updated, definedEntries(format.textStyle)),
64070
64457
  };
64071
64458
  }
64072
64459
  return updated;
@@ -64079,6 +64466,29 @@ function hasCopyableFormat(element) {
64079
64466
  return hasShapeProperties(element) || hasTextProperties(element);
64080
64467
  }
64081
64468
 
64469
+ /** Materialize typed body text without borrowing a display marker's style. */
64470
+ function remapEmptyParagraph(text, segments, terminator) {
64471
+ const source = segments[0] ?? terminator;
64472
+ const insertionStyle = source?.paragraphInsertionStyle;
64473
+ if (!source ||
64474
+ !insertionStyle ||
64475
+ segments.length > 1 ||
64476
+ (segments.length > 0 && source.text !== '' && !isBulletMarkerSegment(source))) {
64477
+ return undefined;
64478
+ }
64479
+ if (text.length === 0) {
64480
+ return segments.map((segment) => ({ ...segment }));
64481
+ }
64482
+ const first = { ...source };
64483
+ delete first.paragraphInsertionStyle;
64484
+ const bullet = first.bulletInfo;
64485
+ if (bullet && !bullet.none && segments.length > 0) {
64486
+ return [first, { text, style: { ...insertionStyle } }];
64487
+ }
64488
+ delete first.isParagraphBreak;
64489
+ return [{ ...first, text, style: { ...insertionStyle } }];
64490
+ }
64491
+
64082
64492
  /** Refresh only derived ordinals after existing paragraphs have moved. */
64083
64493
  function renumberRemappedParagraphs(segments) {
64084
64494
  const sequence = createAutoNumberSequence();
@@ -64138,21 +64548,23 @@ function withoutRenderedBulletPrefix(text, originalSegments, dedicatedMarker) {
64138
64548
  return withoutMarker;
64139
64549
  }
64140
64550
  /**
64141
- * Advance an appended paragraph from the final authored auto-numbered item.
64551
+ * Continue an inserted paragraph from the immediately preceding list item.
64142
64552
  * Core stores the list-relative ordinal as `paragraphIndex`; copying the final
64143
64553
  * item unchanged would render every paragraph added with Enter as the same
64144
64554
  * number. The literal marker is refreshed only when core supplied a dedicated
64145
64555
  * display-marker segment. The donor's list level is retained because core
64146
64556
  * sequences each level independently when the deck is reloaded. Other bullet
64147
- * kinds and auto-numbers without a known runtime index remain unchanged.
64557
+ * kinds retain their definition and level; unknown auto-number indices stay unknown.
64148
64558
  */
64149
- function continueAutoNumberedParagraph(segments, donorSegments, offset) {
64559
+ function continueListParagraph(segments, donorSegments) {
64150
64560
  const donor = donorSegments[0];
64151
64561
  const paragraphIndex = donor?.bulletInfo?.paragraphIndex;
64152
- if (segments.length === 0 ||
64153
- !donor?.bulletInfo?.autoNumType ||
64154
- typeof paragraphIndex !== 'number' ||
64155
- !Number.isFinite(paragraphIndex)) {
64562
+ const bullet = resolveParagraphBullet(donor);
64563
+ if (segments.length === 0 || !bullet) {
64564
+ return segments;
64565
+ }
64566
+ if (bullet.isNumbered &&
64567
+ (typeof paragraphIndex !== 'number' || !Number.isFinite(paragraphIndex))) {
64156
64568
  return segments;
64157
64569
  }
64158
64570
  const [first, ...rest] = segments;
@@ -64160,13 +64572,18 @@ function continueAutoNumberedParagraph(segments, donorSegments, offset) {
64160
64572
  ...first,
64161
64573
  bulletInfo: {
64162
64574
  ...donor.bulletInfo,
64163
- paragraphIndex: paragraphIndex + offset,
64575
+ ...(bullet.isNumbered && typeof paragraphIndex === 'number' && Number.isFinite(paragraphIndex)
64576
+ ? { paragraphIndex: paragraphIndex + 1 }
64577
+ : {}),
64164
64578
  },
64165
64579
  };
64166
64580
  if (donor.paragraphLevel !== undefined) {
64167
64581
  continued.paragraphLevel = donor.paragraphLevel;
64168
64582
  }
64169
- if (isBulletMarkerSegment(donor)) {
64583
+ if (bullet.isNumbered &&
64584
+ typeof paragraphIndex === 'number' &&
64585
+ Number.isFinite(paragraphIndex) &&
64586
+ isBulletMarkerSegment(donor)) {
64170
64587
  const resolved = resolveParagraphBullet(continued);
64171
64588
  if (resolved) {
64172
64589
  const trailingWhitespace = donor.text.match(/\s+$/u)?.[0] ?? '';
@@ -64176,6 +64593,37 @@ function continueAutoNumberedParagraph(segments, donorSegments, offset) {
64176
64593
  return [continued, ...rest];
64177
64594
  }
64178
64595
 
64596
+ /**
64597
+ * Restore paragraph-scoped metadata on the first remapped run. Core and the
64598
+ * save writer deliberately carry these values on that run only; remapping the
64599
+ * characters must not turn an authored paragraph back into a default one.
64600
+ */
64601
+ function restoreParagraphMetadata(from, segments) {
64602
+ if (segments.length === 0) {
64603
+ return segments;
64604
+ }
64605
+ const [first, ...rest] = segments;
64606
+ const restored = { ...first };
64607
+ // `remapParagraph` may itself return a donor segment. Clear its paragraph
64608
+ // fields first so an extra paragraph cannot accidentally inherit metadata
64609
+ // merely because it reused the final paragraph for run styling.
64610
+ delete restored.paragraphLevel;
64611
+ delete restored.paragraphProperties;
64612
+ delete restored.endParaRunProperties;
64613
+ if (!from) {
64614
+ delete restored.paragraphInsertionStyle;
64615
+ }
64616
+ if (from?.paragraphLevel !== undefined) {
64617
+ restored.paragraphLevel = from.paragraphLevel;
64618
+ }
64619
+ if (from?.paragraphProperties !== undefined) {
64620
+ restored.paragraphProperties = from.paragraphProperties;
64621
+ }
64622
+ if (from?.endParaRunProperties !== undefined) {
64623
+ restored.endParaRunProperties = from.endParaRunProperties;
64624
+ }
64625
+ return [restored, ...rest];
64626
+ }
64179
64627
  function matches(text, paragraph) {
64180
64628
  const first = paragraph.segments[0];
64181
64629
  const marker = first &&
@@ -64283,6 +64731,9 @@ function isAtomicOriginalSegment(seg) {
64283
64731
  * style-level properties already survive via the copied `style` object.
64284
64732
  */
64285
64733
  function copySegmentMetadata(from, to) {
64734
+ if (!from) {
64735
+ return to;
64736
+ }
64286
64737
  if (from.equationXml !== undefined) {
64287
64738
  to.equationXml = from.equationXml;
64288
64739
  }
@@ -64303,39 +64754,11 @@ function copySegmentMetadata(from, to) {
64303
64754
  }
64304
64755
  return to;
64305
64756
  }
64306
- /**
64307
- * Restore paragraph-scoped metadata on the first remapped run. Core and the
64308
- * save writer deliberately carry these values on that run only; remapping the
64309
- * characters must not turn an authored paragraph back into a default one.
64310
- */
64311
- function restoreParagraphMetadata(from, segments) {
64312
- if (segments.length === 0) {
64313
- return segments;
64314
- }
64315
- const [first, ...rest] = segments;
64316
- const restored = { ...first };
64317
- // `remapParagraph` may itself return a donor segment. Clear its paragraph
64318
- // fields first so an extra paragraph cannot accidentally inherit metadata
64319
- // merely because it reused the final paragraph for run styling.
64320
- delete restored.paragraphLevel;
64321
- delete restored.paragraphProperties;
64322
- delete restored.endParaRunProperties;
64323
- if (from?.paragraphLevel !== undefined) {
64324
- restored.paragraphLevel = from.paragraphLevel;
64325
- }
64326
- if (from?.paragraphProperties !== undefined) {
64327
- restored.paragraphProperties = from.paragraphProperties;
64328
- }
64329
- if (from?.endParaRunProperties !== undefined) {
64330
- restored.endParaRunProperties = from.endParaRunProperties;
64331
- }
64332
- return [restored, ...rest];
64333
- }
64334
64757
  /**
64335
64758
  * Strategy:
64336
64759
  * 1. Split both original segments and new text into paragraphs by "\n".
64337
64760
  * 2. Distribute new characters proportionally across segments.
64338
- * 3. Extra chars go to last segment, extra paragraphs inherit last style.
64761
+ * 3. Extra chars go to the last segment; new paragraphs use their preceding context.
64339
64762
  * 4. Re-insert paragraph-break markers between paragraphs.
64340
64763
  */
64341
64764
  function remapTextToSegments(newText, originalSegments, elementTextStyle) {
@@ -64366,7 +64789,7 @@ function remapTextToSegments(newText, originalSegments, elementTextStyle) {
64366
64789
  const baseFallbackStyle = firstContentSeg?.style
64367
64790
  ? { ...firstContentSeg.style }
64368
64791
  : fallbackStyle;
64369
- function remapParagraph(paraNewText, paraOrigSegments) {
64792
+ function remapParagraph(paraNewText, paraOrigSegments, isOriginalParagraph = true) {
64370
64793
  if (paraOrigSegments.length === 0) {
64371
64794
  return paraNewText.length > 0
64372
64795
  ? [{ text: paraNewText, style: { ...baseFallbackStyle } }]
@@ -64380,9 +64803,12 @@ function remapTextToSegments(newText, originalSegments, elementTextStyle) {
64380
64803
  : undefined;
64381
64804
  if (dedicatedMarker) {
64382
64805
  const contentSegments = paraOrigSegments.slice(1);
64383
- const contentText = withoutRenderedBulletPrefix(paraNewText, paraOrigSegments, dedicatedMarker);
64806
+ // A new paragraph has no prior display marker to strip from authored text.
64807
+ const contentText = isOriginalParagraph
64808
+ ? withoutRenderedBulletPrefix(paraNewText, paraOrigSegments, dedicatedMarker)
64809
+ : paraNewText;
64384
64810
  const content = contentSegments.length > 0
64385
- ? remapParagraph(contentText, contentSegments)
64811
+ ? remapParagraph(contentText, contentSegments, isOriginalParagraph)
64386
64812
  : [{ text: contentText, style: { ...dedicatedMarker.style } }];
64387
64813
  return [dedicatedMarker, ...content];
64388
64814
  }
@@ -64398,7 +64824,7 @@ function remapTextToSegments(newText, originalSegments, elementTextStyle) {
64398
64824
  const totalOrigLen = paraOrigSegments.reduce((sum, s) => sum + s.text.length, 0);
64399
64825
  if (totalOrigLen === 0) {
64400
64826
  const result = [
64401
- copySegmentMetadata(paraOrigSegments[0], {
64827
+ copySegmentMetadata(isOriginalParagraph ? paraOrigSegments[0] : undefined, {
64402
64828
  text: paraNewText,
64403
64829
  style: { ...paraOrigSegments[0].style },
64404
64830
  }),
@@ -64415,7 +64841,8 @@ function remapTextToSegments(newText, originalSegments, elementTextStyle) {
64415
64841
  // An atomic (field/equation) segment never gets the "last segment
64416
64842
  // absorbs everything left over" treatment, even when it IS the last
64417
64843
  // segment - see `isAtomicOriginalSegment`.
64418
- const isLastSeg = i === paraOrigSegments.length - 1 && !isAtomicOriginalSegment(origSeg);
64844
+ const isLastSeg = i === paraOrigSegments.length - 1 &&
64845
+ (!isOriginalParagraph || !isAtomicOriginalSegment(origSeg));
64419
64846
  const origLen = origSeg.text.length;
64420
64847
  if (newPos >= paraNewText.length) {
64421
64848
  break;
@@ -64428,7 +64855,7 @@ function remapTextToSegments(newText, originalSegments, elementTextStyle) {
64428
64855
  segText = paraNewText.slice(newPos, newPos + origLen);
64429
64856
  }
64430
64857
  if (segText.length > 0) {
64431
- const outSeg = copySegmentMetadata(origSeg, {
64858
+ const outSeg = copySegmentMetadata(isOriginalParagraph ? origSeg : undefined, {
64432
64859
  text: segText,
64433
64860
  style: { ...origSeg.style },
64434
64861
  });
@@ -64452,7 +64879,7 @@ function remapTextToSegments(newText, originalSegments, elementTextStyle) {
64452
64879
  });
64453
64880
  }
64454
64881
  if (remapped.length === 0) {
64455
- const fallback = copySegmentMetadata(paraOrigSegments[0], {
64882
+ const fallback = copySegmentMetadata(isOriginalParagraph ? paraOrigSegments[0] : undefined, {
64456
64883
  text: paraNewText,
64457
64884
  style: { ...paraOrigSegments[0].style },
64458
64885
  });
@@ -64465,27 +64892,30 @@ function remapTextToSegments(newText, originalSegments, elementTextStyle) {
64465
64892
  }
64466
64893
  const output = [];
64467
64894
  const lastOrigPara = originalParagraphs[originalParagraphs.length - 1]?.segments;
64468
- const lastSourceOffset = [...paragraphSources]
64469
- .reverse()
64470
- .findIndex((source) => source !== undefined);
64471
- const appendStart = Math.max(originalParagraphs.length, lastSourceOffset < 0 ? 0 : paragraphSources.length - lastSourceOffset);
64895
+ let precedingParagraph;
64472
64896
  for (let pi = 0; pi < newParagraphTexts.length; pi++) {
64473
64897
  if (pi > 0) {
64474
64898
  const precedingOrigPara = originalParagraphs[paragraphSources[pi - 1] ?? -1]?.segments ?? [];
64475
64899
  const breakStyle = precedingOrigPara[0]?.style
64476
64900
  ? { ...precedingOrigPara[0].style }
64477
64901
  : { ...baseFallbackStyle };
64478
- output.push({ text: '\n', style: breakStyle, isParagraphBreak: true });
64902
+ const terminator = originalParagraphs[paragraphSources[pi - 1] ?? -1]?.terminator;
64903
+ output.push(terminator?.paragraphInsertionStyle && newParagraphTexts[pi - 1] === ''
64904
+ ? { ...terminator, text: '\n', isParagraphBreak: true }
64905
+ : { text: '\n', style: breakStyle, isParagraphBreak: true });
64479
64906
  }
64480
64907
  const originalParagraph = originalParagraphs[paragraphSources[pi] ?? -1];
64481
- const origPara = originalParagraph?.segments ?? lastOrigPara ?? [];
64482
- let paraSegments = restoreParagraphMetadata(originalParagraph?.segments[0] ?? originalParagraph?.terminator, remapParagraph(newParagraphTexts[pi], origPara));
64483
- // Only true tail appends use the historical numbering continuation rule.
64484
- // An unmatched middle paragraph has no donor paragraph metadata.
64485
- if (!originalParagraph && pi >= appendStart) {
64486
- paraSegments = continueAutoNumberedParagraph(paraSegments, lastOrigPara ?? [], pi - originalParagraphs.length + 1);
64908
+ const origPara = originalParagraph?.segments ?? precedingParagraph ?? lastOrigPara ?? [];
64909
+ let paraSegments = restoreParagraphMetadata(originalParagraph?.segments[0] ?? originalParagraph?.terminator, (originalParagraph &&
64910
+ remapEmptyParagraph(newParagraphTexts[pi], origPara, originalParagraph.terminator)) ??
64911
+ remapParagraph(newParagraphTexts[pi], origPara, originalParagraph !== undefined));
64912
+ // New items follow their local list, without inheriting paragraph spacing
64913
+ // or end-run properties reserved for an aligned original paragraph.
64914
+ if (!originalParagraph && precedingParagraph) {
64915
+ paraSegments = continueListParagraph(paraSegments, precedingParagraph);
64487
64916
  }
64488
64917
  output.push(...paraSegments);
64918
+ precedingParagraph = paraSegments;
64489
64919
  }
64490
64920
  if (paragraphSources.some((source, index) => source !== undefined && source !== index)) {
64491
64921
  return renumberRemappedParagraphs(output);
@@ -66143,6 +66573,9 @@ function buildSegmentAttrs(seg) {
66143
66573
  if (seg.endParaRunProperties) {
66144
66574
  a.pr = JSON.stringify(seg.endParaRunProperties);
66145
66575
  }
66576
+ if (seg.paragraphInsertionStyle) {
66577
+ a.pi = JSON.stringify(seg.paragraphInsertionStyle);
66578
+ }
66146
66579
  if (typeof seg.fieldType === 'string') {
66147
66580
  a.ft = seg.fieldType;
66148
66581
  }
@@ -66268,6 +66701,14 @@ function decodeDelta(delta) {
66268
66701
  /* skip */
66269
66702
  }
66270
66703
  }
66704
+ if (a.pi) {
66705
+ try {
66706
+ seg.paragraphInsertionStyle = JSON.parse(a.pi);
66707
+ }
66708
+ catch {
66709
+ /* skip */
66710
+ }
66711
+ }
66271
66712
  if (a.ft) {
66272
66713
  seg.fieldType = a.ft;
66273
66714
  }
@@ -66501,6 +66942,7 @@ const COMPLEX_ELEMENT_FIELDS = {
66501
66942
  children: '_ch',
66502
66943
  paragraphIndents: '_pi',
66503
66944
  rawXml: '_rx',
66945
+ inheritedTransform: '_it',
66504
66946
  extLstXml: '_elx',
66505
66947
  actionClick: '_ac',
66506
66948
  actionHover: '_av',
@@ -77556,229 +77998,6 @@ function smartArtNodeLabel(node) {
77556
77998
  };
77557
77999
  }
77558
78000
 
77559
- /**
77560
- * Regular-text font sizes are stored in slide/CSS pixels in the shared model,
77561
- * while PowerPoint's font controls and the preset list below use points.
77562
- */
77563
- function textFontSizePxToPt(fontSizePx) {
77564
- // DrawingML stores regular text sizes in hundredths of a point. Normalising
77565
- // to that precision removes binary floating-point noise without discarding
77566
- // valid authored values such as 10.5 pt or 48.1 pt.
77567
- return Math.round(fontSizePx * (72 / 96) * 100) / 100;
77568
- }
77569
- /** Convert a PowerPoint font-control value in points to the model's pixels. */
77570
- function textFontSizePtToPx(fontSizePt) {
77571
- return fontSizePt * (96 / 72);
77572
- }
77573
- /**
77574
- * Font families offered by the Home-tab font dropdown, alphabetically.
77575
- *
77576
- * Covers the families PowerPoint's own list leads with (the Office UI faces,
77577
- * the Aptos family that replaced Calibri as the default theme font, and the
77578
- * classic Windows/Mac core fonts) plus the handful of web faces decks
77579
- * routinely arrive with. Entries the host cannot resolve simply fall back
77580
- * through the CSS font stack, so listing a family costs nothing but gives the
77581
- * user a name to pick when the deck already references it.
77582
- */
77583
- const COMMON_FONT_FAMILIES = [
77584
- 'Abadi',
77585
- 'Aptos',
77586
- 'Aptos Display',
77587
- 'Arial',
77588
- 'Arial Black',
77589
- 'Arial Narrow',
77590
- 'Bahnschrift',
77591
- 'Book Antiqua',
77592
- 'Bookman Old Style',
77593
- 'Calibri',
77594
- 'Calibri Light',
77595
- 'Cambria',
77596
- 'Candara',
77597
- 'Century Gothic',
77598
- 'Comic Sans MS',
77599
- 'Consolas',
77600
- 'Corbel',
77601
- 'Courier New',
77602
- 'Franklin Gothic Book',
77603
- 'Franklin Gothic Medium',
77604
- 'Garamond',
77605
- 'Georgia',
77606
- 'Gill Sans MT',
77607
- 'Helvetica',
77608
- 'Impact',
77609
- 'Inter',
77610
- 'Lucida Console',
77611
- 'Lucida Sans Unicode',
77612
- 'Microsoft Sans Serif',
77613
- 'Montserrat',
77614
- 'Noto Sans',
77615
- 'Open Sans',
77616
- 'Palatino Linotype',
77617
- 'Poppins',
77618
- 'Roboto',
77619
- 'Rockwell',
77620
- 'Segoe UI',
77621
- 'Source Sans Pro',
77622
- 'Tahoma',
77623
- 'Times New Roman',
77624
- 'Trebuchet MS',
77625
- 'Tw Cen MT',
77626
- 'Verdana',
77627
- ];
77628
- /** Font sizes (pt) offered by the Home-tab size dropdown. */
77629
- const COMMON_FONT_SIZES = [
77630
- 8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 28, 32, 36, 40, 44, 48, 54, 60, 72, 96,
77631
- ];
77632
- /** Character-spacing presets for the toolbar dropdown. */
77633
- const CHARACTER_SPACING_OPTIONS = [
77634
- { label: 'Very Tight', i18nKey: 'pptx.text.characterSpacingVeryTight', value: -150 },
77635
- { label: 'Tight', i18nKey: 'pptx.text.characterSpacingTight', value: -75 },
77636
- { label: 'Normal', i18nKey: 'pptx.text.characterSpacingNormal', value: 0 },
77637
- { label: 'Loose', i18nKey: 'pptx.text.characterSpacingLoose', value: 75 },
77638
- { label: 'Very Loose', i18nKey: 'pptx.text.characterSpacingVeryLoose', value: 150 },
77639
- ];
77640
- /** Line-spacing presets for the paragraph dropdown. */
77641
- const LINE_SPACING_OPTIONS$1 = [
77642
- { label: '1.0', value: 1.0 },
77643
- { label: '1.15', value: 1.15 },
77644
- { label: '1.5', value: 1.5 },
77645
- { label: '2.0', value: 2.0 },
77646
- { label: '2.5', value: 2.5 },
77647
- { label: '3.0', value: 3.0 },
77648
- ];
77649
- /** Change-case options in menu order (matches PowerPoint's ordering). */
77650
- const CHANGE_CASE_OPTIONS$1 = [
77651
- { value: 'sentence', i18nKey: 'pptx.text.changeCaseSentence' },
77652
- { value: 'lower', i18nKey: 'pptx.text.changeCaseLower' },
77653
- { value: 'upper', i18nKey: 'pptx.text.changeCaseUpper' },
77654
- { value: 'capitalize', i18nKey: 'pptx.text.changeCaseCapitalize' },
77655
- { value: 'toggle', i18nKey: 'pptx.text.changeCaseToggle' },
77656
- ];
77657
-
77658
- /**
77659
- * inspector-helpers.ts: Pure (no framework) helpers for the inspector panel.
77660
- *
77661
- * Readers extract display values from a PptxElement (with sensible defaults),
77662
- * and patch builders produce shallow-merge-ready Partial<PptxElement> objects
77663
- * for the binding's element-update path. Shared across React, Vue, and Angular.
77664
- */
77665
- const DEFAULT_FILL = '#ffffff';
77666
- const DEFAULT_STROKE = '#000000';
77667
- const DEFAULT_TEXT_COLOR = '#000000';
77668
- /**
77669
- * PowerPoint's own presentation-level default text style (`p:defaultTextStyle
77670
- * /a:lvl1pPr/a:defRPr@sz`) is 1800 (18pt), so a shape with no explicit font
77671
- * size renders at 18pt in real PowerPoint, not 12pt. Kept as the last-resort
77672
- * fallback below the deck's actual default when {@link fontSizeOf} is given one.
77673
- */
77674
- const DEFAULT_FONT_SIZE$2 = 18;
77675
- /**
77676
- * Returns the fill colour of the element's shapeStyle, or a white default.
77677
- * Only meaningful for elements that pass `hasShapeProperties`.
77678
- */
77679
- function fillColorOf$1(el) {
77680
- if (hasShapeProperties(el)) {
77681
- return el.shapeStyle?.fillColor ?? DEFAULT_FILL;
77682
- }
77683
- return DEFAULT_FILL;
77684
- }
77685
- /**
77686
- * Returns the stroke colour of the element's shapeStyle, or a black default.
77687
- * Only meaningful for elements that pass `hasShapeProperties`.
77688
- */
77689
- function strokeColorOf(el) {
77690
- if (hasShapeProperties(el)) {
77691
- return el.shapeStyle?.strokeColor ?? DEFAULT_STROKE;
77692
- }
77693
- return DEFAULT_STROKE;
77694
- }
77695
- /**
77696
- * Returns the text colour from the element's textStyle, or a black default.
77697
- * Only meaningful for elements that pass `hasTextProperties`.
77698
- */
77699
- function textColorOf(el) {
77700
- if (hasTextProperties(el)) {
77701
- return el.textStyle?.color ?? DEFAULT_TEXT_COLOR;
77702
- }
77703
- return DEFAULT_TEXT_COLOR;
77704
- }
77705
- /**
77706
- * Returns the font size (in points) from the element's textStyle.
77707
- *
77708
- * Falls back, in order, to: the deck's presentation-level default text style
77709
- * (`p:defaultTextStyle`, passed as `presentationDefault` when the caller has
77710
- * one), then `DEFAULT_FONT_SIZE` (18pt, matching PowerPoint's own
77711
- * `a:lvl1pPr/a:defRPr@sz="1800"` when neither is available).
77712
- */
77713
- function fontSizeOf(el, presentationDefault) {
77714
- if (hasTextProperties(el) && el.textStyle?.fontSize !== undefined) {
77715
- return textFontSizePxToPt(el.textStyle.fontSize);
77716
- }
77717
- const deckDefault = presentationDefault?.levelStyles?.[0]?.fontSize;
77718
- return deckDefault === undefined ? DEFAULT_FONT_SIZE$2 : textFontSizePxToPt(deckDefault);
77719
- }
77720
- /** Returns whether the element's text is bold (false when absent). */
77721
- function isBold(el) {
77722
- if (hasTextProperties(el)) {
77723
- return el.textStyle?.bold ?? false;
77724
- }
77725
- return false;
77726
- }
77727
- /** Returns whether the element's text is italic (false when absent). */
77728
- function isItalic(el) {
77729
- if (hasTextProperties(el)) {
77730
- return el.textStyle?.italic ?? false;
77731
- }
77732
- return false;
77733
- }
77734
- /** Returns whether the element's text has underline (false when absent). */
77735
- function isUnderline(el) {
77736
- if (hasTextProperties(el)) {
77737
- return el.textStyle?.underline ?? false;
77738
- }
77739
- return false;
77740
- }
77741
- /**
77742
- * Builds a Partial<PptxElement> patch that merges the given changes into the
77743
- * element's existing shapeStyle without dropping any other shapeStyle fields.
77744
- */
77745
- function shapeStylePatch$1(el, changes) {
77746
- const base = hasShapeProperties(el) ? (el.shapeStyle ?? {}) : {};
77747
- return {
77748
- shapeStyle: {
77749
- ...base,
77750
- ...changes,
77751
- },
77752
- };
77753
- }
77754
- /**
77755
- * Builds a Partial<PptxElement> patch that merges the given changes into the
77756
- * element's existing textStyle without dropping any other textStyle fields.
77757
- */
77758
- function textStylePatch(el, changes) {
77759
- const base = hasTextProperties(el) ? (el.textStyle ?? {}) : {};
77760
- return {
77761
- textStyle: {
77762
- ...base,
77763
- ...changes,
77764
- },
77765
- };
77766
- }
77767
- /** Apply an ordinary-text model pixel size to the element and all of its runs. */
77768
- function textFontSizePatch(el, fontSize) {
77769
- const patch = textStylePatch(el, { fontSize });
77770
- if (!hasTextProperties(el) || !el.textSegments) {
77771
- return patch;
77772
- }
77773
- return {
77774
- ...patch,
77775
- textSegments: el.textSegments.map((segment) => ({
77776
- ...segment,
77777
- style: { ...segment.style, fontSize },
77778
- })),
77779
- };
77780
- }
77781
-
77782
78001
  /**
77783
78002
  * effects-shadow-helpers.ts: Pure (no framework) outer/inner shadow helpers
77784
78003
  * for the effects panel.
@@ -80918,7 +81137,7 @@ function zoomOutPercent(percent) {
80918
81137
  *
80919
81138
  * The model here is one thing:
80920
81139
  * - `zoom` is the USER's factor, where 1 means "whatever fits".
80921
- * - `fitScale` is the viewport measurement the binding feeds in (<= 1).
81140
+ * - `fitScale` is the positive viewport measurement the binding feeds in.
80922
81141
  * - `manual` records whether the user has taken control, which is what
80923
81142
  * separates "reset to 100%" from "fit to viewport" without needing a
80924
81143
  * sentinel value smuggled into the number.
@@ -82942,10 +83161,40 @@ function buildElementClipboardPayload(element, isTemplate) {
82942
83161
  function cloneElementForPaste(element, options = {}) {
82943
83162
  const clone = structuredClone(element);
82944
83163
  const intoTemplate = options.intoTemplate ?? false;
82945
- clone.id = makeCloneId(intoTemplate, element.id);
83164
+ const modelIds = new Map();
83165
+ const nativeIds = new Map();
83166
+ const mintId = (node) => {
83167
+ const id = makeCloneId(intoTemplate, element.id);
83168
+ modelIds.set(node.id, id);
83169
+ if (node.shapeId !== undefined) {
83170
+ nativeIds.set(node.shapeId, id);
83171
+ }
83172
+ // A clone is a new native shape too; save allocates IDs for its targets.
83173
+ delete node.shapeId;
83174
+ return id;
83175
+ };
83176
+ clone.id = mintId(clone);
82946
83177
  // The root's ORIGINAL id decides the template store for the whole subtree,
82947
83178
  // so a descendant that carries no prefix of its own cannot vote it elsewhere.
82948
- reassignDescendantIds(clone, () => makeCloneId(intoTemplate, element.id));
83179
+ reassignDescendantIds(clone, mintId);
83180
+ const remapConnections = (node) => {
83181
+ if (node.type === 'group') {
83182
+ node.children.forEach(remapConnections);
83183
+ }
83184
+ if (node.type !== 'connector') {
83185
+ return;
83186
+ }
83187
+ for (const ref of [
83188
+ node.shapeStyle?.connectorStartConnection,
83189
+ node.shapeStyle?.connectorEndConnection,
83190
+ ]) {
83191
+ if (!ref?.shapeId) {
83192
+ continue;
83193
+ }
83194
+ ref.shapeId = modelIds.get(ref.shapeId) ?? nativeIds.get(ref.shapeId) ?? ref.shapeId;
83195
+ }
83196
+ };
83197
+ remapConnections(clone);
82949
83198
  clone.x += options.offsetX ?? PASTE_OFFSET_PX;
82950
83199
  clone.y += options.offsetY ?? PASTE_OFFSET_PX;
82951
83200
  return clone;
@@ -83398,6 +83647,7 @@ const GUARD_DEFAULTS$1 = {
83398
83647
  canEdit: true,
83399
83648
  isPresenting: false,
83400
83649
  hasSelection: false,
83650
+ canPaste: true,
83401
83651
  isEditingText: false,
83402
83652
  isDrawing: false,
83403
83653
  isTextInputTarget: false,
@@ -83499,6 +83749,9 @@ function mapEditorKey(input, guard = {}) {
83499
83749
  if (mod && !alt) {
83500
83750
  const chord = resolveChord(key, Boolean(input.shiftKey), state.hasSelection);
83501
83751
  if (chord) {
83752
+ if (chord.action === 'paste' && state.canPaste === false) {
83753
+ return NO_ACTION$1;
83754
+ }
83502
83755
  return chord;
83503
83756
  }
83504
83757
  }
@@ -89985,6 +90238,17 @@ const COMMON_FONTS = [
89985
90238
  'Verdana',
89986
90239
  ];
89987
90240
 
90241
+ /** Prepare a caller-owned model for insertion into an ordinary editable slide. */
90242
+ function prepareElementForInsertion(element, target) {
90243
+ if (!target.canEdit ||
90244
+ target.mode !== 'edit' ||
90245
+ !target.hasActiveSlide ||
90246
+ target.editTemplateMode) {
90247
+ return undefined;
90248
+ }
90249
+ return cloneElementForPaste(element, { offsetX: 0, offsetY: 0 });
90250
+ }
90251
+
89988
90252
  /**
89989
90253
  * Clone a `PptxHeaderFooter` into a fresh draft object for the Header & Footer
89990
90254
  * dialog to mutate locally, without touching the committed value until the
@@ -96088,10 +96352,19 @@ function resolveSlideSizeRescaleTransform(oldSize, newSize, mode) {
96088
96352
  }
96089
96353
  /** Scale every font size an element's own text style carries, in place on a shallow copy. */
96090
96354
  function scaleTextSegment(segment, scale) {
96091
- if (typeof segment.style.fontSize !== 'number') {
96355
+ const insertion = segment.paragraphInsertionStyle;
96356
+ if (typeof segment.style.fontSize !== 'number' && typeof insertion?.fontSize !== 'number') {
96092
96357
  return segment;
96093
96358
  }
96094
- return { ...segment, style: { ...segment.style, fontSize: segment.style.fontSize * scale } };
96359
+ return {
96360
+ ...segment,
96361
+ ...(typeof segment.style.fontSize === 'number'
96362
+ ? { style: { ...segment.style, fontSize: segment.style.fontSize * scale } }
96363
+ : {}),
96364
+ ...(typeof insertion?.fontSize === 'number'
96365
+ ? { paragraphInsertionStyle: { ...insertion, fontSize: insertion.fontSize * scale } }
96366
+ : {}),
96367
+ };
96095
96368
  }
96096
96369
  /**
96097
96370
  * Scale an element's font sizes (its own `textStyle.fontSize` and every
@@ -97464,6 +97737,62 @@ function wrapForeignObjectSvg(bodyMarkup, tile) {
97464
97737
  `viewBox="${viewBoxX} ${viewBoxY} ${viewBoxWidth} ${viewBoxHeight}">${bodyMarkup}</svg>`);
97465
97738
  }
97466
97739
 
97740
+ const DEFAULTS$1 = {
97741
+ fitPadding: { horizontal: 0, vertical: 0 },
97742
+ maxFitScale: null,
97743
+ };
97744
+ function validPadding(value, fallback) {
97745
+ return Number.isFinite(value) && value >= 0 ? value : fallback;
97746
+ }
97747
+ /** Normalize once for both fit measurement and a binding's physical viewport CSS. */
97748
+ function resolveViewportFitOptions(options = {}, defaults = DEFAULTS$1) {
97749
+ const base = typeof defaults.fitPadding === 'number'
97750
+ ? { horizontal: defaults.fitPadding, vertical: defaults.fitPadding }
97751
+ : defaults.fitPadding;
97752
+ const padding = options.fitPadding ?? base;
97753
+ const horizontal = typeof padding === 'number' ? padding : padding.horizontal;
97754
+ const vertical = typeof padding === 'number' ? padding : padding.vertical;
97755
+ const cap = options.maxFitScale;
97756
+ return {
97757
+ fitPadding: {
97758
+ horizontal: validPadding(horizontal, base.horizontal),
97759
+ vertical: validPadding(vertical, base.vertical),
97760
+ },
97761
+ maxFitScale: cap === null
97762
+ ? null
97763
+ : typeof cap === 'number' && Number.isFinite(cap) && cap > 0
97764
+ ? cap
97765
+ : defaults.maxFitScale,
97766
+ };
97767
+ }
97768
+ /** Calculate fit only: the user's zoom factor is applied separately by the viewer. */
97769
+ function calculateViewportFit(input, defaults = DEFAULTS$1) {
97770
+ const { fitPadding, maxFitScale } = resolveViewportFitOptions(input, defaults);
97771
+ const availableWidth = Math.max(0, validPadding(input.viewportWidth, 0) -
97772
+ 2 * fitPadding.horizontal -
97773
+ validPadding(input.horizontalGutter ?? 0, 0));
97774
+ const availableHeight = Math.max(0, validPadding(input.viewportHeight, 0) -
97775
+ 2 * fitPadding.vertical -
97776
+ validPadding(input.verticalGutter ?? 0, 0));
97777
+ const fallback = typeof input.fallbackScale === 'number' &&
97778
+ Number.isFinite(input.fallbackScale) &&
97779
+ input.fallbackScale > 0
97780
+ ? input.fallbackScale
97781
+ : 1;
97782
+ const validCanvas = Number.isFinite(input.canvasWidth) &&
97783
+ input.canvasWidth > 0 &&
97784
+ Number.isFinite(input.canvasHeight) &&
97785
+ input.canvasHeight > 0;
97786
+ const scale = availableWidth > 0 && availableHeight > 0 && validCanvas
97787
+ ? Math.min(availableWidth / input.canvasWidth, availableHeight / input.canvasHeight, maxFitScale ?? Number.POSITIVE_INFINITY)
97788
+ : fallback;
97789
+ return {
97790
+ scale: Number.isFinite(scale) && scale > 0 ? scale : fallback,
97791
+ availableWidth,
97792
+ availableHeight,
97793
+ };
97794
+ }
97795
+
97467
97796
  /**
97468
97797
  * Framework-agnostic rendering & editing helpers shared by the React, Vue, and
97469
97798
  * Angular `pptx-viewer` bindings. Pure TypeScript (no framework imports) — each
@@ -103684,7 +104013,7 @@ function createLocalStorageBackend(namespace) {
103684
104013
  /** Try IndexedDB first; fall back to localStorage on any failure. */
103685
104014
  async function resolveBackend(dbName, namespace) {
103686
104015
  try {
103687
- const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-B-Z8kwp1.mjs');
104016
+ const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-DjOCNjw-.mjs');
103688
104017
  const db = await openChatDb(dbName);
103689
104018
  return createIdbBackend(db);
103690
104019
  }
@@ -104421,10 +104750,7 @@ function applyTextUpdate(el, u) {
104421
104750
  // visibly restyles instead of only the (unused) element-level fallback.
104422
104751
  textEl.textStyle = { ...textEl.textStyle, ...textStyle };
104423
104752
  if (textEl.textSegments) {
104424
- textEl.textSegments = textEl.textSegments.map((seg) => ({
104425
- ...seg,
104426
- style: { ...seg.style, ...textStyle },
104427
- }));
104753
+ textEl.textSegments = textEl.textSegments.map((seg) => updateTextSegmentStyle(seg, textStyle));
104428
104754
  }
104429
104755
  }
104430
104756
  /** Apply fill/stroke updates when the element carries a shape style. */
@@ -114084,8 +114410,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
114084
114410
 
114085
114411
  /**
114086
114412
  * canvas-fit.service.ts: Auto-fit scale measurement for `SlideCanvasComponent`.
114087
- * Computes the largest scale (<= 1) at which the whole slide fits its scroll
114088
- * viewport, reserving the 1rem gutter + drop shadow, so the parent's `zoom`
114413
+ * Computes the largest scale (capped at 1 by default) fitting its scroll
114414
+ * viewport, reserving host-configurable decorative padding, so the parent's `zoom`
114089
114415
  * input means "100% of fit" rather than "100% of the authored slide size".
114090
114416
  * Thumbnail consumers (slides panel, slide sorter) set `autoFit` false and
114091
114417
  * manage their own scale via `zoom` instead.
@@ -114101,7 +114427,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
114101
114427
  class CanvasFitService {
114102
114428
  constructor() {
114103
114429
  /**
114104
- * Auto-fit scale (<= 1): how much the fixed-size slide must shrink to fit
114430
+ * Auto-fit scale (capped at 1 by default): how the fixed-size slide fits
114105
114431
  * the scroll viewport. The authored slide is e.g. 1280x720, which overflows
114106
114432
  * a phone; without this it renders off-screen at `zoom=1`.
114107
114433
  */
@@ -114134,14 +114460,14 @@ class CanvasFitService {
114134
114460
  this.fitScale.set(1);
114135
114461
  return;
114136
114462
  }
114137
- const availW = Math.max(el.clientWidth - 16, 0);
114138
- const availH = Math.max(el.clientHeight - 32, 0);
114139
- if (!availW || !availH) {
114140
- this.fitScale.set(1);
114141
- return;
114142
- }
114143
- const fit = Math.min(availW / size.width, availH / size.height, 1);
114144
- this.fitScale.set(fit > 0 ? fit : 1);
114463
+ const fit = calculateViewportFit({
114464
+ viewportWidth: el.clientWidth,
114465
+ viewportHeight: el.clientHeight,
114466
+ canvasWidth: size.width,
114467
+ canvasHeight: size.height,
114468
+ ...this.host.fitOptions?.(),
114469
+ }, { fitPadding: { horizontal: 8, vertical: 16 }, maxFitScale: 1 });
114470
+ this.fitScale.set(fit.scale);
114145
114471
  }
114146
114472
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: CanvasFitService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
114147
114473
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: CanvasFitService }); }
@@ -123758,6 +124084,12 @@ class SlideCanvasComponent {
123758
124084
  ...(ngDevMode ? [{ debugName: "mediaDataUrls" }] : /* istanbul ignore next */ []));
123759
124085
  this.zoom = input(1, /* @ts-ignore */
123760
124086
  ...(ngDevMode ? [{ debugName: "zoom" }] : /* istanbul ignore next */ []));
124087
+ /** Unscaled padding on each side; omission keeps the existing fit allowance. */
124088
+ this.fitPadding = input(undefined, /* @ts-ignore */
124089
+ ...(ngDevMode ? [{ debugName: "fitPadding" }] : /* istanbul ignore next */ []));
124090
+ /** Fit-factor ceiling, independent of user zoom; null permits enlargement. */
124091
+ this.maxFitScale = input(undefined, /* @ts-ignore */
124092
+ ...(ngDevMode ? [{ debugName: "maxFitScale" }] : /* istanbul ignore next */ []));
123761
124093
  /** When true, elements are selectable and drag/resize handles are shown. */
123762
124094
  this.editable = input(false, /* @ts-ignore */
123763
124095
  ...(ngDevMode ? [{ debugName: "editable" }] : /* istanbul ignore next */ []));
@@ -124307,10 +124639,13 @@ class SlideCanvasComponent {
124307
124639
  autoFit: () => this.autoFit(),
124308
124640
  viewportElement: () => this.viewportRef()?.nativeElement,
124309
124641
  canvasSize: () => this.canvasSize(),
124642
+ fitOptions: () => ({ fitPadding: this.fitPadding(), maxFitScale: this.maxFitScale() }),
124310
124643
  });
124311
124644
  // Re-fit whenever the authored slide size changes (e.g. switching decks).
124312
124645
  effect(() => {
124313
124646
  this.canvasSize();
124647
+ this.fitPadding();
124648
+ this.maxFitScale();
124314
124649
  this.canvasFit.recompute();
124315
124650
  });
124316
124651
  // Keep every delegated element renderer aligned with the shared role/name
@@ -124990,7 +125325,7 @@ class SlideCanvasComponent {
124990
125325
  }
124991
125326
  }
124992
125327
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SlideCanvasComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
124993
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: SlideCanvasComponent, isStandalone: true, selector: "pptx-slide-canvas", inputs: { slide: { classPropertyName: "slide", publicName: "slide", isSignal: true, isRequired: false, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, zoom: { classPropertyName: "zoom", publicName: "zoom", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, showGrid: { classPropertyName: "showGrid", publicName: "showGrid", isSignal: true, isRequired: false, transformFunction: null }, showRulers: { classPropertyName: "showRulers", publicName: "showRulers", isSignal: true, isRequired: false, transformFunction: null }, rulerUnit: { classPropertyName: "rulerUnit", publicName: "rulerUnit", isSignal: true, isRequired: false, transformFunction: null }, showGuides: { classPropertyName: "showGuides", publicName: "showGuides", isSignal: true, isRequired: false, transformFunction: null }, snapToGrid: { classPropertyName: "snapToGrid", publicName: "snapToGrid", isSignal: true, isRequired: false, transformFunction: null }, gridSpacing: { classPropertyName: "gridSpacing", publicName: "gridSpacing", isSignal: true, isRequired: false, transformFunction: null }, snapToShape: { classPropertyName: "snapToShape", publicName: "snapToShape", isSignal: true, isRequired: false, transformFunction: null }, guideCommand: { classPropertyName: "guideCommand", publicName: "guideCommand", isSignal: true, isRequired: false, transformFunction: null }, spellCheck: { classPropertyName: "spellCheck", publicName: "spellCheck", isSignal: true, isRequired: false, transformFunction: null }, snapToGuides: { classPropertyName: "snapToGuides", publicName: "snapToGuides", isSignal: true, isRequired: false, transformFunction: null }, autoFit: { classPropertyName: "autoFit", publicName: "autoFit", isSignal: true, isRequired: false, transformFunction: null }, transparentBackground: { classPropertyName: "transparentBackground", publicName: "transparentBackground", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, exposeElementIds: { classPropertyName: "exposeElementIds", publicName: "exposeElementIds", isSignal: true, isRequired: false, transformFunction: null }, presenting: { classPropertyName: "presenting", publicName: "presenting", isSignal: true, isRequired: false, transformFunction: null }, selectedIds: { classPropertyName: "selectedIds", publicName: "selectedIds", isSignal: true, isRequired: false, transformFunction: null }, editingId: { classPropertyName: "editingId", publicName: "editingId", isSignal: true, isRequired: false, transformFunction: null }, editTemplateMode: { classPropertyName: "editTemplateMode", publicName: "editTemplateMode", isSignal: true, isRequired: false, transformFunction: null }, templateElements: { classPropertyName: "templateElements", publicName: "templateElements", isSignal: true, isRequired: false, transformFunction: null }, aiHighlights: { classPropertyName: "aiHighlights", publicName: "aiHighlights", isSignal: true, isRequired: false, transformFunction: null }, aiActive: { classPropertyName: "aiActive", publicName: "aiActive", isSignal: true, isRequired: false, transformFunction: null }, aiActiveSlideIndex: { classPropertyName: "aiActiveSlideIndex", publicName: "aiActiveSlideIndex", isSignal: true, isRequired: false, transformFunction: null }, aiChangeBatch: { classPropertyName: "aiChangeBatch", publicName: "aiChangeBatch", isSignal: true, isRequired: false, transformFunction: null }, aiPickMode: { classPropertyName: "aiPickMode", publicName: "aiPickMode", isSignal: true, isRequired: false, transformFunction: null }, drawTool: { classPropertyName: "drawTool", publicName: "drawTool", isSignal: true, isRequired: false, transformFunction: null }, drawColor: { classPropertyName: "drawColor", publicName: "drawColor", isSignal: true, isRequired: false, transformFunction: null }, drawWidth: { classPropertyName: "drawWidth", publicName: "drawWidth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { elementSelect: "elementSelect", backgroundClick: "backgroundClick", transformStart: "transformStart", transformUpdate: "transformUpdate", transformEnd: "transformEnd", adjustUpdate: "adjustUpdate", connectorEndpointUpdate: "connectorEndpointUpdate", contextMenu: "contextMenu", textEditStart: "textEditStart", textCommit: "textCommit", textInput: "textInput", textCancel: "textCancel", textFormat: "textFormat", rotateUpdate: "rotateUpdate", marqueeSelect: "marqueeSelect", inkStrokeComplete: "inkStrokeComplete", eraserHit: "eraserHit", cellCommit: "cellCommit", tableChange: "tableChange" }, host: { listeners: { "document:pointermove": "onPointerMove($event)", "document:pointerup": "onPointerUp()" } }, providers: [
125328
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: SlideCanvasComponent, isStandalone: true, selector: "pptx-slide-canvas", inputs: { slide: { classPropertyName: "slide", publicName: "slide", isSignal: true, isRequired: false, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, zoom: { classPropertyName: "zoom", publicName: "zoom", isSignal: true, isRequired: false, transformFunction: null }, fitPadding: { classPropertyName: "fitPadding", publicName: "fitPadding", isSignal: true, isRequired: false, transformFunction: null }, maxFitScale: { classPropertyName: "maxFitScale", publicName: "maxFitScale", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, showGrid: { classPropertyName: "showGrid", publicName: "showGrid", isSignal: true, isRequired: false, transformFunction: null }, showRulers: { classPropertyName: "showRulers", publicName: "showRulers", isSignal: true, isRequired: false, transformFunction: null }, rulerUnit: { classPropertyName: "rulerUnit", publicName: "rulerUnit", isSignal: true, isRequired: false, transformFunction: null }, showGuides: { classPropertyName: "showGuides", publicName: "showGuides", isSignal: true, isRequired: false, transformFunction: null }, snapToGrid: { classPropertyName: "snapToGrid", publicName: "snapToGrid", isSignal: true, isRequired: false, transformFunction: null }, gridSpacing: { classPropertyName: "gridSpacing", publicName: "gridSpacing", isSignal: true, isRequired: false, transformFunction: null }, snapToShape: { classPropertyName: "snapToShape", publicName: "snapToShape", isSignal: true, isRequired: false, transformFunction: null }, guideCommand: { classPropertyName: "guideCommand", publicName: "guideCommand", isSignal: true, isRequired: false, transformFunction: null }, spellCheck: { classPropertyName: "spellCheck", publicName: "spellCheck", isSignal: true, isRequired: false, transformFunction: null }, snapToGuides: { classPropertyName: "snapToGuides", publicName: "snapToGuides", isSignal: true, isRequired: false, transformFunction: null }, autoFit: { classPropertyName: "autoFit", publicName: "autoFit", isSignal: true, isRequired: false, transformFunction: null }, transparentBackground: { classPropertyName: "transparentBackground", publicName: "transparentBackground", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, exposeElementIds: { classPropertyName: "exposeElementIds", publicName: "exposeElementIds", isSignal: true, isRequired: false, transformFunction: null }, presenting: { classPropertyName: "presenting", publicName: "presenting", isSignal: true, isRequired: false, transformFunction: null }, selectedIds: { classPropertyName: "selectedIds", publicName: "selectedIds", isSignal: true, isRequired: false, transformFunction: null }, editingId: { classPropertyName: "editingId", publicName: "editingId", isSignal: true, isRequired: false, transformFunction: null }, editTemplateMode: { classPropertyName: "editTemplateMode", publicName: "editTemplateMode", isSignal: true, isRequired: false, transformFunction: null }, templateElements: { classPropertyName: "templateElements", publicName: "templateElements", isSignal: true, isRequired: false, transformFunction: null }, aiHighlights: { classPropertyName: "aiHighlights", publicName: "aiHighlights", isSignal: true, isRequired: false, transformFunction: null }, aiActive: { classPropertyName: "aiActive", publicName: "aiActive", isSignal: true, isRequired: false, transformFunction: null }, aiActiveSlideIndex: { classPropertyName: "aiActiveSlideIndex", publicName: "aiActiveSlideIndex", isSignal: true, isRequired: false, transformFunction: null }, aiChangeBatch: { classPropertyName: "aiChangeBatch", publicName: "aiChangeBatch", isSignal: true, isRequired: false, transformFunction: null }, aiPickMode: { classPropertyName: "aiPickMode", publicName: "aiPickMode", isSignal: true, isRequired: false, transformFunction: null }, drawTool: { classPropertyName: "drawTool", publicName: "drawTool", isSignal: true, isRequired: false, transformFunction: null }, drawColor: { classPropertyName: "drawColor", publicName: "drawColor", isSignal: true, isRequired: false, transformFunction: null }, drawWidth: { classPropertyName: "drawWidth", publicName: "drawWidth", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { elementSelect: "elementSelect", backgroundClick: "backgroundClick", transformStart: "transformStart", transformUpdate: "transformUpdate", transformEnd: "transformEnd", adjustUpdate: "adjustUpdate", connectorEndpointUpdate: "connectorEndpointUpdate", contextMenu: "contextMenu", textEditStart: "textEditStart", textCommit: "textCommit", textInput: "textInput", textCancel: "textCancel", textFormat: "textFormat", rotateUpdate: "rotateUpdate", marqueeSelect: "marqueeSelect", inkStrokeComplete: "inkStrokeComplete", eraserHit: "eraserHit", cellCommit: "cellCommit", tableChange: "tableChange" }, host: { listeners: { "document:pointermove": "onPointerMove($event)", "document:pointerup": "onPointerUp()" } }, providers: [
124994
125329
  CanvasFitService,
124995
125330
  InkDrawingService,
124996
125331
  RulerGuidesService,
@@ -125018,7 +125353,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
125018
125353
  AiChangeOverlayComponent,
125019
125354
  ActiveXControlsOverlayComponent,
125020
125355
  ], template: "<div\n\t#viewport\n\tclass=\"pptx-ng-canvas-viewport\"\n\t[attr.data-pptx-viewport]=\"interactive() ? '' : null\"\n\t(pointerdown)=\"onViewportPointerDown($event)\"\n>\n\t<div class=\"pptx-ng-canvas-wrapper\" [ngStyle]=\"wrapperStyle()\">\n\t\t<div\n\t\t\t#stage\n\t\t\tclass=\"pptx-ng-canvas-stage\"\n\t\t\t[class.is-editable]=\"editable()\"\n\t\t\trole=\"region\"\n\t\t\t[attr.aria-roledescription]=\"interactive() || presenting() ? 'slide' : null\"\n\t\t\t[attr.data-pptx-ai-active]=\"aiActive() ? 'true' : null\"\n\t\t\t[ngStyle]=\"stageStyle()\"\n\t\t\t(pointerdown)=\"onStagePointerDown($event)\"\n\t\t\t(contextmenu)=\"onContextMenu($event)\"\n\t\t\t(dblclick)=\"onDblClick($event)\"\n\t\t>\n\t\t\t<!--\n\t\t\t\tTemplate layer: inherited master/layout elements, rendered BEHIND\n\t\t\t\tthe slide's own elements (lower z-index). Interactive + given the\n\t\t\t\tamber editable affordance only while editTemplateMode is on; when\n\t\t\t\toff they render inertly with no affordance, exactly as core\n\t\t\t\tdelivered them. `marked` keeps the data-pptx-element contract on\n\t\t\t\tthem even while locked: the marker means \"rendered slide element\",\n\t\t\t\tnot \"editable right now\".\n\t\t\t-->\n\t\t\t@for (element of visibleTemplateElements(); track element.id; let i = $index) {\n\t\t\t\t<pptx-element-renderer\n\t\t\t\t\t[element]=\"element\"\n\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t[zIndex]=\"i\"\n\t\t\t\t\t[obstacles]=\"connectorObstacles()\"\n\t\t\t\t\t[canvasWidth]=\"canvasSize().width\"\n\t\t\t\t\t[canvasHeight]=\"canvasSize().height\"\n\t\t\t\t\t[interactive]=\"interactive() && editTemplateMode()\"\n\t\t\t\t\t[marked]=\"interactive()\"\n\t\t\t\t\t[exposeElementId]=\"exposeElementIds()\"\n\t\t\t\t\t[editable]=\"editable() && editTemplateMode()\"\n\t\t\t\t\t[fieldContext]=\"fieldContext()\"\n\t\t\t\t\t[slideElements]=\"allElements()\"\n\t\t\t\t\t[editTemplateMode]=\"editTemplateMode()\"\n\t\t\t\t\t[editingElementId]=\"editingId()\"\n\t\t\t\t\t(cellCommit)=\"cellCommit.emit($event)\"\n\t\t\t\t\t(tableChange)=\"tableChange.emit($event)\"\n\t\t\t\t/>\n\t\t\t}\n\t\t\t@for (element of elements(); track element.id; let i = $index) {\n\t\t\t\t<pptx-element-renderer\n\t\t\t\t\t[element]=\"element\"\n\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t[zIndex]=\"visibleTemplateElements().length + i\"\n\t\t\t\t\t[obstacles]=\"connectorObstacles()\"\n\t\t\t\t\t[canvasWidth]=\"canvasSize().width\"\n\t\t\t\t\t[canvasHeight]=\"canvasSize().height\"\n\t\t\t\t\t[interactive]=\"interactive()\"\n\t\t\t\t\t[exposeElementId]=\"exposeElementIds()\"\n\t\t\t\t\t[presenting]=\"presenting()\"\n\t\t\t\t\t[editable]=\"editable()\"\n\t\t\t\t\t[fieldContext]=\"fieldContext()\"\n\t\t\t\t\t[slideElements]=\"allElements()\"\n\t\t\t\t\t[editTemplateMode]=\"false\"\n\t\t\t\t\t[editingElementId]=\"editingId()\"\n\t\t\t\t\t(cellCommit)=\"cellCommit.emit($event)\"\n\t\t\t\t\t(tableChange)=\"tableChange.emit($event)\"\n\t\t\t\t/>\n\t\t\t}\n\t\t\t<pptx-activex-controls-overlay\n\t\t\t\t[controls]=\"slide()?.activeXControls ?? []\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t/>\n\t\t\t@if (aiHighlights().length > 0 || aiActive()) {\n\t\t\t\t<pptx-ai-focus-highlight-overlay\n\t\t\t\t\t[highlights]=\"aiHighlights()\"\n\t\t\t\t\t[elements]=\"elements()\"\n\t\t\t\t\t[activeSlideIndex]=\"aiActiveSlideIndex()\"\n\t\t\t\t/>\n\t\t\t}\n\t\t\t@if (aiChangeBatch(); as batch) {\n\t\t\t\t<pptx-ai-change-overlay [batch]=\"batch\" [activeSlideIndex]=\"aiActiveSlideIndex()\" />\n\t\t\t}\n\t\t\t@for (box of selectionBoxes(); track box.id) {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"pptx-ng-selection\"\n\t\t\t\t\t[style.left.px]=\"box.x\"\n\t\t\t\t\t[style.top.px]=\"box.y\"\n\t\t\t\t\t[style.width.px]=\"box.width\"\n\t\t\t\t\t[style.height.px]=\"box.height\"\n\t\t\t\t></div>\n\t\t\t}\n\t\t\t@for (h of handleBoxes(); track h.handle) {\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"pptx-ng-handle\"\n\t\t\t\t\t[attr.aria-label]=\"'pptx.selectionOverlay.resize' | translate: { handle: h.handle }\"\n\t\t\t\t\t[style.left.px]=\"h.left\"\n\t\t\t\t\t[style.top.px]=\"h.top\"\n\t\t\t\t\t[style.width.px]=\"h.size\"\n\t\t\t\t\t[style.height.px]=\"h.size\"\n\t\t\t\t\t[style.cursor]=\"h.cursor\"\n\t\t\t\t\t(pointerdown)=\"onHandlePointerDown($event, h.handle)\"\n\t\t\t\t\t(keydown)=\"onResizeHandleKeydown($event, h.handle)\"\n\t\t\t\t></button>\n\t\t\t}\n\t\t\t@if (marqueeRect(); as mr) {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"pptx-ng-marquee\"\n\t\t\t\t\t[style.left.px]=\"mr.x\"\n\t\t\t\t\t[style.top.px]=\"mr.y\"\n\t\t\t\t\t[style.width.px]=\"mr.width\"\n\t\t\t\t\t[style.height.px]=\"mr.height\"\n\t\t\t\t></div>\n\t\t\t}\n\t\t\t@for (g of snapGuides(); track $index) {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"pptx-ng-snap-guide\"\n\t\t\t\t\t[style.left.px]=\"g.axis === 'x' ? g.pos : g.start\"\n\t\t\t\t\t[style.top.px]=\"g.axis === 'x' ? g.start : g.pos\"\n\t\t\t\t\t[style.width.px]=\"g.axis === 'x' ? 0 : g.end - g.start\"\n\t\t\t\t\t[style.height.px]=\"g.axis === 'x' ? g.end - g.start : 0\"\n\t\t\t\t></div>\n\t\t\t}\n\t\t\t@if (rotateHandle(); as rh) {\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"pptx-ng-rotate-handle\"\n\t\t\t\t\t[attr.aria-label]=\"'pptx.selectionOverlay.rotate' | translate\"\n\t\t\t\t\t[style.left.px]=\"rh.left\"\n\t\t\t\t\t[style.top.px]=\"rh.top\"\n\t\t\t\t\t[style.width.px]=\"rh.size\"\n\t\t\t\t\t[style.height.px]=\"rh.size\"\n\t\t\t\t\t(pointerdown)=\"onRotatePointerDown($event)\"\n\t\t\t\t\t(keydown)=\"onRotateHandleKeydown($event)\"\n\t\t\t\t></button>\n\t\t\t}\n\t\t\t<!--\n\t\t\t\tShape-adjustment affordances (amber diamonds), ONE per `a:avLst`\n\t\t\t\tguide. Existence, position and cursor all come from the SHARED\n\t\t\t\t`getShapeAdjustmentHandleDescriptors`, so they appear only for a\n\t\t\t\tgeometry with an adjustable parameter, sit where the other four\n\t\t\t\tbindings put them, and are absent for a shape locked with\n\t\t\t\t`noAdjustHandles`. Dragging one writes `shapeAdjustments`; it does\n\t\t\t\tNOT resize the element.\n\t\t\t-->\n\t\t\t@for (ah of adjustHandles(); track ah.key) {\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"pptx-ng-adjust-handle\"\n\t\t\t\t\t[attr.data-pptx-adjust-key]=\"ah.key\"\n\t\t\t\t\t[attr.aria-label]=\"'pptx.selectionOverlay.adjust' | translate\"\n\t\t\t\t\t[style.left.px]=\"ah.left\"\n\t\t\t\t\t[style.top.px]=\"ah.top\"\n\t\t\t\t\t[style.width.px]=\"ah.size\"\n\t\t\t\t\t[style.height.px]=\"ah.size\"\n\t\t\t\t\t[style.cursor]=\"ah.cursor\"\n\t\t\t\t\t(pointerdown)=\"onAdjustPointerDown($event, ah)\"\n\t\t\t\t></button>\n\t\t\t}\n\t\t\t<!--\n\t\t\t\tConnector endpoint authoring: drag an end onto a shape's connection\n\t\t\t\tpoint to bind it (`a:stCxn` / `a:endCxn`), or off one to detach.\n\t\t\t\tCandidate sites are revealed only while an end is in flight so they\n\t\t\t\tnever obscure the deck at rest.\n\t\t\t-->\n\t\t\t@for (site of connectorSiteCandidates(); track site.key) {\n\t\t\t\t<div\n\t\t\t\t\tclass=\"pptx-ng-connection-site\"\n\t\t\t\t\t[class.is-snapped]=\"site.snapped\"\n\t\t\t\t\tdata-pptx-connection-site\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[style.left.px]=\"site.left\"\n\t\t\t\t\t[style.top.px]=\"site.top\"\n\t\t\t\t\t[style.width.px]=\"site.size\"\n\t\t\t\t\t[style.height.px]=\"site.size\"\n\t\t\t\t></div>\n\t\t\t}\n\t\t\t@for (ep of connectorEndpoints(); track ep.kind) {\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"pptx-ng-connector-endpoint\"\n\t\t\t\t\t[class.is-attached]=\"ep.attached\"\n\t\t\t\t\t[attr.data-pptx-connector-endpoint]=\"ep.kind\"\n\t\t\t\t\t[attr.data-pptx-connector-attached]=\"ep.attached\"\n\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t(ep.kind === 'start'\n\t\t\t\t\t\t\t? 'pptx.canvas.connectorEndpointStart'\n\t\t\t\t\t\t\t: 'pptx.canvas.connectorEndpointEnd'\n\t\t\t\t\t\t) | translate\n\t\t\t\t\t\"\n\t\t\t\t\t[style.left.px]=\"ep.left\"\n\t\t\t\t\t[style.top.px]=\"ep.top\"\n\t\t\t\t\t[style.width.px]=\"ep.size\"\n\t\t\t\t\t[style.height.px]=\"ep.size\"\n\t\t\t\t\t(pointerdown)=\"onConnectorEndpointPointerDown($event, ep.kind)\"\n\t\t\t\t></button>\n\t\t\t}\n\t\t\t@if (editingBox(); as eb) {\n\t\t\t\t<textarea\n\t\t\t\t\t#textEditor\n\t\t\t\t\tdata-inline-editor\n\t\t\t\t\tclass=\"pptx-ng-text-editor\"\n\t\t\t\t\taria-label=\"Edit slide text\"\n\t\t\t\t\t[spellcheck]=\"spellCheck()\"\n\t\t\t\t\t[style.left.px]=\"eb.x\"\n\t\t\t\t\t[style.top.px]=\"eb.y\"\n\t\t\t\t\t[style.width.px]=\"eb.width\"\n\t\t\t\t\t[style.height.px]=\"eb.height\"\n\t\t\t\t\t(pointerdown)=\"$event.stopPropagation()\"\n\t\t\t\t\t(input)=\"onTextInput($event, eb.id)\"\n\t\t\t\t\t(blur)=\"commitText($event, eb.id)\"\n\t\t\t\t\t(keydown)=\"onEditorKeydown($event)\"\n\t\t\t\t></textarea>\n\t\t\t}\n\n\t\t\t<!--\n\t\t\t\tView overlays: editor aids only, never on thumbnails/preview/presentation.\n\t\t\t\tAll are pointer-events:none so they never break selection/drag.\n\t\t\t\tNone carry data-pptx-element / aria-roledescription / data-pptx-viewport.\n\t\t\t-->\n\t\t\t@if (interactive() && showGrid()) {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-overlay-grid\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.width]=\"canvasSize().width\"\n\t\t\t\t\t[attr.height]=\"canvasSize().height\"\n\t\t\t\t>\n\t\t\t\t\t<defs>\n\t\t\t\t\t\t<pattern\n\t\t\t\t\t\t\t[attr.id]=\"gridPatternId\"\n\t\t\t\t\t\t\t[attr.width]=\"gridSpacingPx()\"\n\t\t\t\t\t\t\t[attr.height]=\"gridSpacingPx()\"\n\t\t\t\t\t\t\tpatternUnits=\"userSpaceOnUse\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<circle\n\t\t\t\t\t\t\t\t[attr.cx]=\"gridSpacingPx() / 2\"\n\t\t\t\t\t\t\t\t[attr.cy]=\"gridSpacingPx() / 2\"\n\t\t\t\t\t\t\t\tr=\"0.6\"\n\t\t\t\t\t\t\t\tfill=\"rgba(156,163,175,0.55)\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</pattern>\n\t\t\t\t\t</defs>\n\t\t\t\t\t<rect\n\t\t\t\t\t\t[attr.width]=\"canvasSize().width\"\n\t\t\t\t\t\t[attr.height]=\"canvasSize().height\"\n\t\t\t\t\t\t[attr.fill]=\"'url(#' + gridPatternId + ')'\"\n\t\t\t\t\t/>\n\t\t\t\t</svg>\n\t\t\t}\n\n\t\t\t@if (interactive() && showGuides()) {\n\t\t\t\t<!--\n\t\t\t\t\tCenter crosshair: one horizontal line and one vertical line\n\t\t\t\t\tthrough the midpoint of the slide. Static; draggable guides\n\t\t\t\t\tare a follow-up.\n\t\t\t\t-->\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-overlay-guides\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.width]=\"canvasSize().width\"\n\t\t\t\t\t[attr.height]=\"canvasSize().height\"\n\t\t\t\t>\n\t\t\t\t\t<!-- Horizontal center guide -->\n\t\t\t\t\t<line\n\t\t\t\t\t\tx1=\"0\"\n\t\t\t\t\t\t[attr.y1]=\"canvasSize().height / 2\"\n\t\t\t\t\t\t[attr.x2]=\"canvasSize().width\"\n\t\t\t\t\t\t[attr.y2]=\"canvasSize().height / 2\"\n\t\t\t\t\t\tstroke=\"rgba(99,102,241,0.7)\"\n\t\t\t\t\t\tstroke-width=\"1\"\n\t\t\t\t\t\tstroke-dasharray=\"6 3\"\n\t\t\t\t\t/>\n\t\t\t\t\t<!-- Vertical center guide -->\n\t\t\t\t\t<line\n\t\t\t\t\t\t[attr.x1]=\"canvasSize().width / 2\"\n\t\t\t\t\t\ty1=\"0\"\n\t\t\t\t\t\t[attr.x2]=\"canvasSize().width / 2\"\n\t\t\t\t\t\t[attr.y2]=\"canvasSize().height\"\n\t\t\t\t\t\tstroke=\"rgba(99,102,241,0.7)\"\n\t\t\t\t\t\tstroke-width=\"1\"\n\t\t\t\t\t\tstroke-dasharray=\"6 3\"\n\t\t\t\t\t/>\n\t\t\t\t</svg>\n\t\t\t}\n\n\t\t\t<!--\n\t\t\t\tUser-created ruler guides.\n\t\t\t\tEach guide has a non-interactive line body and an interactive\n\t\t\t\tdrag handle. Double-click the handle to delete the guide.\n\n\t\t\t\tDeliberately OUTSIDE the showGuides() gate above (which owns the\n\t\t\t\tstatic centre crosshair): a guide the user just dragged off a ruler\n\t\t\t\tstrip must be visible immediately, as it is in Vue and Vanilla.\n\t\t\t\tWhile it lived under that gate, the drag-out gesture silently\n\t\t\t\tproduced an invisible guide unless View > Guides happened to be on.\n\t\t\t-->\n\t\t\t@if (interactive()) {\n\t\t\t\t@for (g of rulerGuidesSvc.rulerGuides(); track g.id) {\n\t\t\t\t\t<!-- Guide line body: pointer-events:none -->\n\t\t\t\t\t<div\n\t\t\t\t\t\tclass=\"pptx-ng-ruler-guide-line\"\n\t\t\t\t\t\t[style.left.px]=\"g.axis === 'x' ? g.pos : 0\"\n\t\t\t\t\t\t[style.top.px]=\"g.axis === 'y' ? g.pos : 0\"\n\t\t\t\t\t\t[style.width]=\"g.axis === 'x' ? '1px' : '100%'\"\n\t\t\t\t\t\t[style.height]=\"g.axis === 'y' ? '1px' : '100%'\"\n\t\t\t\t\t></div>\n\t\t\t\t\t<!-- Drag handle: pointer-events:auto -->\n\t\t\t\t\t<div\n\t\t\t\t\t\tclass=\"pptx-ng-ruler-guide-handle\"\n\t\t\t\t\t\t[style.left.px]=\"g.axis === 'x' ? g.pos - 4 : 0\"\n\t\t\t\t\t\t[style.top.px]=\"g.axis === 'y' ? g.pos - 4 : 0\"\n\t\t\t\t\t\t[style.width]=\"g.axis === 'x' ? '9px' : '100%'\"\n\t\t\t\t\t\t[style.height]=\"g.axis === 'y' ? '9px' : '100%'\"\n\t\t\t\t\t\t[style.cursor]=\"g.axis === 'x' ? 'col-resize' : 'row-resize'\"\n\t\t\t\t\t\t(pointerdown)=\"rulerGuidesSvc.onGuidePointerDown($event, g.id, g.axis)\"\n\t\t\t\t\t\t(dblclick)=\"rulerGuidesSvc.onGuideDoubleClick($event, g.id)\"\n\t\t\t\t\t\t[title]=\"'pptx.canvas.guideTooltip' | translate\"\n\t\t\t\t\t></div>\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t<!--\n\t\t\t\tLive ink stroke preview: shown while the user is drawing.\n\t\t\t\tpointer-events:none so it never intercepts element gestures.\n\t\t\t\tNo data-pptx-element / aria-roledescription / data-pptx-viewport.\n\n\t\t\t\tRenders `inkDrawing.liveStrokeView()`: the same plain-path /\n\t\t\t\tpressure-circle / tilt-nib decision `InkRendererComponent` makes for\n\t\t\t\ta committed stroke, so a calligraphic lean or pressure-variable\n\t\t\t\twidth shows up while the pointer is still down, not only after\n\t\t\t\trelease.\n\t\t\t-->\n\t\t\t@if (inkDrawing.active() && inkDrawing.liveStrokeView() && drawTool() !== 'select') {\n\t\t\t\t<svg\n\t\t\t\t\tclass=\"pptx-ng-ink-preview\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t[attr.width]=\"canvasSize().width\"\n\t\t\t\t\t[attr.height]=\"canvasSize().height\"\n\t\t\t\t\tstyle=\"position: absolute; inset: 0; pointer-events: none; z-index: 70\"\n\t\t\t\t>\n\t\t\t\t\t@if (inkDrawing.liveStrokeView()?.nibMarks; as nibMarks) {\n\t\t\t\t\t\t<g [attr.opacity]=\"inkDrawing.liveStrokeView()?.opacity\">\n\t\t\t\t\t\t\t@for (m of nibMarks; track $index) {\n\t\t\t\t\t\t\t\t<ellipse\n\t\t\t\t\t\t\t\t\t[attr.cx]=\"m.cx\"\n\t\t\t\t\t\t\t\t\t[attr.cy]=\"m.cy\"\n\t\t\t\t\t\t\t\t\t[attr.rx]=\"m.rPerp\"\n\t\t\t\t\t\t\t\t\t[attr.ry]=\"m.rTilt\"\n\t\t\t\t\t\t\t\t\t[attr.transform]=\"'rotate(' + m.rotationDeg + ' ' + m.cx + ' ' + m.cy + ')'\"\n\t\t\t\t\t\t\t\t\t[attr.fill]=\"inkDrawing.liveStrokeView()?.color\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</g>\n\t\t\t\t\t} @else if (inkDrawing.liveStrokeView()?.circles; as circles) {\n\t\t\t\t\t\t<g [attr.opacity]=\"inkDrawing.liveStrokeView()?.opacity\">\n\t\t\t\t\t\t\t@for (c of circles; track $index) {\n\t\t\t\t\t\t\t\t<circle\n\t\t\t\t\t\t\t\t\t[attr.cx]=\"c.cx\"\n\t\t\t\t\t\t\t\t\t[attr.cy]=\"c.cy\"\n\t\t\t\t\t\t\t\t\t[attr.r]=\"c.r\"\n\t\t\t\t\t\t\t\t\t[attr.fill]=\"inkDrawing.liveStrokeView()?.color\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</g>\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t[attr.d]=\"inkDrawing.liveStrokeView()?.d\"\n\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t[attr.stroke]=\"inkDrawing.liveStrokeView()?.color\"\n\t\t\t\t\t\t\t[attr.stroke-width]=\"inkDrawing.liveStrokeView()?.width\"\n\t\t\t\t\t\t\t[attr.stroke-opacity]=\"inkDrawing.liveStrokeView()?.opacity\"\n\t\t\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t}\n\t\t\t\t</svg>\n\t\t\t}\n\n\t\t\t<!--\n\t\t\t\tProjected overlays (collaboration cursors + remote selections).\n\t\t\t\tThey live INSIDE the scaled stage so the stage's CSS\n\t\t\t\ttransform:scale() applies the on-screen scale exactly once and\n\t\t\t\tthey can be authored in raw, unscaled slide coordinates, exactly\n\t\t\t\tlike the React/Vue overlays.\n\t\t\t-->\n\t\t\t<ng-content />\n\t\t</div>\n\n\t\t<!--\n\t\t\tRuler strips: siblings to the scaled stage inside the wrapper div,\n\t\t\tabsolutely positioned at top:0/left:0 within the wrapper's padding area.\n\t\t\tThe wrapper's padding (RULER_THICKNESS px top+left) reserves space for\n\t\t\tthese strips so the stage content starts below/right of them.\n\t\t\tpointer-events:none so they never intercept element gestures.\n\t\t-->\n\t\t@if (interactive() && showRulers()) {\n\t\t\t<!-- Corner square at the intersection of the two ruler strips -->\n\t\t\t<div class=\"pptx-ng-ruler-corner\" aria-hidden=\"true\"></div>\n\n\t\t\t<!--\n\t\t\t\tHorizontal ruler: spans the top padding row of the wrapper.\n\t\t\t\tA guide is dropped on pointer-UP (not down), resolved by the shared\n\t\t\t\trulerDragToGuidePosition, so a stray click on the strip cannot\n\t\t\t\tdrop a guide the user never dragged out - the rule React, Vue,\n\t\t\t\tSvelte and Vanilla all follow.\n\t\t\t-->\n\t\t\t<svg\n\t\t\t\tclass=\"pptx-ng-ruler-h\"\n\t\t\t\tdata-pptx-ruler=\"h\"\n\t\t\t\trole=\"presentation\"\n\t\t\t\t[attr.width]=\"canvasSize().width * effectiveScalePublic()\"\n\t\t\t\t[attr.height]=\"rulerThickness\"\n\t\t\t\t[style.cursor]=\"editable() ? 'row-resize' : null\"\n\t\t\t\t(pointerdown)=\"rulerGuidesSvc.onRulerPointerDown('h', $event)\"\n\t\t\t\t(pointerup)=\"rulerGuidesSvc.onRulerPointerUp('h', $event)\"\n\t\t\t>\n\t\t\t\t<rect\n\t\t\t\t\t[attr.width]=\"canvasSize().width * effectiveScalePublic()\"\n\t\t\t\t\t[attr.height]=\"rulerThickness\"\n\t\t\t\t\tfill=\"#1e293b\"\n\t\t\t\t/>\n\t\t\t\t@if (hRulerHighlight(); as highlight) {\n\t\t\t\t\t<rect\n\t\t\t\t\t\t[attr.x]=\"highlight.start\"\n\t\t\t\t\t\ty=\"0\"\n\t\t\t\t\t\t[attr.width]=\"highlight.span\"\n\t\t\t\t\t\t[attr.height]=\"rulerThickness\"\n\t\t\t\t\t\tfill=\"rgba(96,165,250,0.25)\"\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t\t<line\n\t\t\t\t\tx1=\"0\"\n\t\t\t\t\t[attr.y1]=\"rulerThickness - 0.5\"\n\t\t\t\t\t[attr.x2]=\"canvasSize().width * effectiveScalePublic()\"\n\t\t\t\t\t[attr.y2]=\"rulerThickness - 0.5\"\n\t\t\t\t\tstroke=\"rgba(255,255,255,0.15)\"\n\t\t\t\t\tstroke-width=\"1\"\n\t\t\t\t/>\n\t\t\t\t@for (tick of hRulerTicks(); track $index) {\n\t\t\t\t\t<line\n\t\t\t\t\t\t[attr.x1]=\"tick.position\"\n\t\t\t\t\t\t[attr.y1]=\"rulerThickness\"\n\t\t\t\t\t\t[attr.x2]=\"tick.position\"\n\t\t\t\t\t\t[attr.y2]=\"rulerThickness - rulerThickness * (tick.isMajor ? 0.6 : 0.3)\"\n\t\t\t\t\t\tstroke=\"rgba(156,163,175,0.7)\"\n\t\t\t\t\t\t[attr.stroke-width]=\"tick.isMajor ? 1 : 0.5\"\n\t\t\t\t\t/>\n\t\t\t\t\t@if (tick.label) {\n\t\t\t\t\t\t<text\n\t\t\t\t\t\t\t[attr.x]=\"tick.position + 2\"\n\t\t\t\t\t\t\t[attr.y]=\"rulerFontSize + 1\"\n\t\t\t\t\t\t\t[attr.font-size]=\"rulerFontSize\"\n\t\t\t\t\t\t\tfill=\"rgba(156,163,175,0.9)\"\n\t\t\t\t\t\t\tstyle=\"font-family: system-ui, sans-serif\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{{ tick.label }}\n\t\t\t\t\t\t</text>\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</svg>\n\n\t\t\t<!-- Vertical ruler: spans the left padding column of the wrapper -->\n\t\t\t<svg\n\t\t\t\tclass=\"pptx-ng-ruler-v\"\n\t\t\t\tdata-pptx-ruler=\"v\"\n\t\t\t\trole=\"presentation\"\n\t\t\t\t[attr.width]=\"rulerThickness\"\n\t\t\t\t[attr.height]=\"canvasSize().height * effectiveScalePublic()\"\n\t\t\t\t[style.cursor]=\"editable() ? 'col-resize' : null\"\n\t\t\t\t(pointerdown)=\"rulerGuidesSvc.onRulerPointerDown('v', $event)\"\n\t\t\t\t(pointerup)=\"rulerGuidesSvc.onRulerPointerUp('v', $event)\"\n\t\t\t>\n\t\t\t\t<rect\n\t\t\t\t\t[attr.width]=\"rulerThickness\"\n\t\t\t\t\t[attr.height]=\"canvasSize().height * effectiveScalePublic()\"\n\t\t\t\t\tfill=\"#1e293b\"\n\t\t\t\t/>\n\t\t\t\t@if (vRulerHighlight(); as highlight) {\n\t\t\t\t\t<rect\n\t\t\t\t\t\tx=\"0\"\n\t\t\t\t\t\t[attr.y]=\"highlight.start\"\n\t\t\t\t\t\t[attr.width]=\"rulerThickness\"\n\t\t\t\t\t\t[attr.height]=\"highlight.span\"\n\t\t\t\t\t\tfill=\"rgba(96,165,250,0.25)\"\n\t\t\t\t\t/>\n\t\t\t\t}\n\t\t\t\t<line\n\t\t\t\t\t[attr.x1]=\"rulerThickness - 0.5\"\n\t\t\t\t\ty1=\"0\"\n\t\t\t\t\t[attr.x2]=\"rulerThickness - 0.5\"\n\t\t\t\t\t[attr.y2]=\"canvasSize().height * effectiveScalePublic()\"\n\t\t\t\t\tstroke=\"rgba(255,255,255,0.15)\"\n\t\t\t\t\tstroke-width=\"1\"\n\t\t\t\t/>\n\t\t\t\t@for (tick of vRulerTicks(); track $index) {\n\t\t\t\t\t<line\n\t\t\t\t\t\t[attr.x1]=\"rulerThickness\"\n\t\t\t\t\t\t[attr.y1]=\"tick.position\"\n\t\t\t\t\t\t[attr.x2]=\"rulerThickness - rulerThickness * (tick.isMajor ? 0.6 : 0.3)\"\n\t\t\t\t\t\t[attr.y2]=\"tick.position\"\n\t\t\t\t\t\tstroke=\"rgba(156,163,175,0.7)\"\n\t\t\t\t\t\t[attr.stroke-width]=\"tick.isMajor ? 1 : 0.5\"\n\t\t\t\t\t/>\n\t\t\t\t\t@if (tick.label) {\n\t\t\t\t\t\t<text\n\t\t\t\t\t\t\tx=\"2\"\n\t\t\t\t\t\t\t[attr.y]=\"tick.position + rulerFontSize + 2\"\n\t\t\t\t\t\t\t[attr.font-size]=\"rulerFontSize\"\n\t\t\t\t\t\t\tfill=\"rgba(156,163,175,0.9)\"\n\t\t\t\t\t\t\tstyle=\"font-family: system-ui, sans-serif\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{{ tick.label }}\n\t\t\t\t\t\t</text>\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</svg>\n\t\t}\n\t</div>\n</div>\n", styles: [".pptx-ng-canvas-stage.is-editable{touch-action:none}\n"] }]
125021
- }], ctorParameters: () => [], propDecorators: { slide: [{ type: i0.Input, args: [{ isSignal: true, alias: "slide", required: false }] }], canvasSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasSize", required: true }] }], mediaDataUrls: [{ type: i0.Input, args: [{ isSignal: true, alias: "mediaDataUrls", required: false }] }], zoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoom", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], showGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGrid", required: false }] }], showRulers: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRulers", required: false }] }], rulerUnit: [{ type: i0.Input, args: [{ isSignal: true, alias: "rulerUnit", required: false }] }], showGuides: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGuides", required: false }] }], snapToGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToGrid", required: false }] }], gridSpacing: [{ type: i0.Input, args: [{ isSignal: true, alias: "gridSpacing", required: false }] }], snapToShape: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToShape", required: false }] }], guideCommand: [{ type: i0.Input, args: [{ isSignal: true, alias: "guideCommand", required: false }] }], spellCheck: [{ type: i0.Input, args: [{ isSignal: true, alias: "spellCheck", required: false }] }], snapToGuides: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToGuides", required: false }] }], autoFit: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoFit", required: false }] }], transparentBackground: [{ type: i0.Input, args: [{ isSignal: true, alias: "transparentBackground", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], exposeElementIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "exposeElementIds", required: false }] }], presenting: [{ type: i0.Input, args: [{ isSignal: true, alias: "presenting", required: false }] }], selectedIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedIds", required: false }] }], editingId: [{ type: i0.Input, args: [{ isSignal: true, alias: "editingId", required: false }] }], editTemplateMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "editTemplateMode", required: false }] }], templateElements: [{ type: i0.Input, args: [{ isSignal: true, alias: "templateElements", required: false }] }], aiHighlights: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiHighlights", required: false }] }], aiActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiActive", required: false }] }], aiActiveSlideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiActiveSlideIndex", required: false }] }], aiChangeBatch: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiChangeBatch", required: false }] }], aiPickMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiPickMode", required: false }] }], drawTool: [{ type: i0.Input, args: [{ isSignal: true, alias: "drawTool", required: false }] }], drawColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "drawColor", required: false }] }], drawWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "drawWidth", required: false }] }], elementSelect: [{ type: i0.Output, args: ["elementSelect"] }], backgroundClick: [{ type: i0.Output, args: ["backgroundClick"] }], transformStart: [{ type: i0.Output, args: ["transformStart"] }], transformUpdate: [{ type: i0.Output, args: ["transformUpdate"] }], transformEnd: [{ type: i0.Output, args: ["transformEnd"] }], adjustUpdate: [{ type: i0.Output, args: ["adjustUpdate"] }], connectorEndpointUpdate: [{ type: i0.Output, args: ["connectorEndpointUpdate"] }], contextMenu: [{ type: i0.Output, args: ["contextMenu"] }], textEditStart: [{ type: i0.Output, args: ["textEditStart"] }], textCommit: [{ type: i0.Output, args: ["textCommit"] }], textInput: [{ type: i0.Output, args: ["textInput"] }], textCancel: [{ type: i0.Output, args: ["textCancel"] }], textFormat: [{ type: i0.Output, args: ["textFormat"] }], rotateUpdate: [{ type: i0.Output, args: ["rotateUpdate"] }], marqueeSelect: [{ type: i0.Output, args: ["marqueeSelect"] }], inkStrokeComplete: [{ type: i0.Output, args: ["inkStrokeComplete"] }], eraserHit: [{ type: i0.Output, args: ["eraserHit"] }], cellCommit: [{ type: i0.Output, args: ["cellCommit"] }], tableChange: [{ type: i0.Output, args: ["tableChange"] }], textEditor: [{ type: i0.ViewChild, args: ['textEditor', { isSignal: true }] }], stageRef: [{ type: i0.ViewChild, args: ['stage', { isSignal: true }] }], viewportRef: [{ type: i0.ViewChild, args: ['viewport', { isSignal: true }] }], onPointerMove: [{
125356
+ }], ctorParameters: () => [], propDecorators: { slide: [{ type: i0.Input, args: [{ isSignal: true, alias: "slide", required: false }] }], canvasSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasSize", required: true }] }], mediaDataUrls: [{ type: i0.Input, args: [{ isSignal: true, alias: "mediaDataUrls", required: false }] }], zoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "zoom", required: false }] }], fitPadding: [{ type: i0.Input, args: [{ isSignal: true, alias: "fitPadding", required: false }] }], maxFitScale: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFitScale", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], showGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGrid", required: false }] }], showRulers: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRulers", required: false }] }], rulerUnit: [{ type: i0.Input, args: [{ isSignal: true, alias: "rulerUnit", required: false }] }], showGuides: [{ type: i0.Input, args: [{ isSignal: true, alias: "showGuides", required: false }] }], snapToGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToGrid", required: false }] }], gridSpacing: [{ type: i0.Input, args: [{ isSignal: true, alias: "gridSpacing", required: false }] }], snapToShape: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToShape", required: false }] }], guideCommand: [{ type: i0.Input, args: [{ isSignal: true, alias: "guideCommand", required: false }] }], spellCheck: [{ type: i0.Input, args: [{ isSignal: true, alias: "spellCheck", required: false }] }], snapToGuides: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToGuides", required: false }] }], autoFit: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoFit", required: false }] }], transparentBackground: [{ type: i0.Input, args: [{ isSignal: true, alias: "transparentBackground", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], exposeElementIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "exposeElementIds", required: false }] }], presenting: [{ type: i0.Input, args: [{ isSignal: true, alias: "presenting", required: false }] }], selectedIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedIds", required: false }] }], editingId: [{ type: i0.Input, args: [{ isSignal: true, alias: "editingId", required: false }] }], editTemplateMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "editTemplateMode", required: false }] }], templateElements: [{ type: i0.Input, args: [{ isSignal: true, alias: "templateElements", required: false }] }], aiHighlights: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiHighlights", required: false }] }], aiActive: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiActive", required: false }] }], aiActiveSlideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiActiveSlideIndex", required: false }] }], aiChangeBatch: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiChangeBatch", required: false }] }], aiPickMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiPickMode", required: false }] }], drawTool: [{ type: i0.Input, args: [{ isSignal: true, alias: "drawTool", required: false }] }], drawColor: [{ type: i0.Input, args: [{ isSignal: true, alias: "drawColor", required: false }] }], drawWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "drawWidth", required: false }] }], elementSelect: [{ type: i0.Output, args: ["elementSelect"] }], backgroundClick: [{ type: i0.Output, args: ["backgroundClick"] }], transformStart: [{ type: i0.Output, args: ["transformStart"] }], transformUpdate: [{ type: i0.Output, args: ["transformUpdate"] }], transformEnd: [{ type: i0.Output, args: ["transformEnd"] }], adjustUpdate: [{ type: i0.Output, args: ["adjustUpdate"] }], connectorEndpointUpdate: [{ type: i0.Output, args: ["connectorEndpointUpdate"] }], contextMenu: [{ type: i0.Output, args: ["contextMenu"] }], textEditStart: [{ type: i0.Output, args: ["textEditStart"] }], textCommit: [{ type: i0.Output, args: ["textCommit"] }], textInput: [{ type: i0.Output, args: ["textInput"] }], textCancel: [{ type: i0.Output, args: ["textCancel"] }], textFormat: [{ type: i0.Output, args: ["textFormat"] }], rotateUpdate: [{ type: i0.Output, args: ["rotateUpdate"] }], marqueeSelect: [{ type: i0.Output, args: ["marqueeSelect"] }], inkStrokeComplete: [{ type: i0.Output, args: ["inkStrokeComplete"] }], eraserHit: [{ type: i0.Output, args: ["eraserHit"] }], cellCommit: [{ type: i0.Output, args: ["cellCommit"] }], tableChange: [{ type: i0.Output, args: ["tableChange"] }], textEditor: [{ type: i0.ViewChild, args: ['textEditor', { isSignal: true }] }], stageRef: [{ type: i0.ViewChild, args: ['stage', { isSignal: true }] }], viewportRef: [{ type: i0.ViewChild, args: ['viewport', { isSignal: true }] }], onPointerMove: [{
125022
125357
  type: HostListener,
125023
125358
  args: ['document:pointermove', ['$event']]
125024
125359
  }], onPointerUp: [{
@@ -125184,7 +125519,7 @@ class MasterViewCanvasComponent {
125184
125519
  <p class="empty">No master is available.</p>
125185
125520
  }
125186
125521
  </main>
125187
- `, isInline: true, styles: [":host{display:flex;min-width:0;min-height:0;flex:1}.master-canvas{display:flex;min-width:0;min-height:0;flex:1;overflow:hidden;background:var(--pptx-background, #11111b)}pptx-slide-canvas{display:flex;min-width:0;min-height:0;flex:1}.empty{margin:auto;color:var(--pptx-muted-foreground, #a5a5b5)}\n"], dependencies: [{ kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
125522
+ `, isInline: true, styles: [":host{display:flex;min-width:0;min-height:0;flex:1}.master-canvas{display:flex;min-width:0;min-height:0;flex:1;overflow:hidden;background:var(--pptx-background, #11111b)}pptx-slide-canvas{display:flex;min-width:0;min-height:0;flex:1}.empty{margin:auto;color:var(--pptx-muted-foreground, #a5a5b5)}\n"], dependencies: [{ kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
125188
125523
  }
125189
125524
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: MasterViewCanvasComponent, decorators: [{
125190
125525
  type: Component,
@@ -126441,7 +126776,7 @@ class MobilePresenterViewComponent {
126441
126776
  return { ...slide, elements: [...template, ...slide.elements] };
126442
126777
  }
126443
126778
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: MobilePresenterViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
126444
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: MobilePresenterViewComponent, isStandalone: true, selector: "pptx-mobile-presenter-view", inputs: { slides: { classPropertyName: "slides", publicName: "slides", isSignal: true, isRequired: true, transformFunction: null }, currentSlideIndex: { classPropertyName: "currentSlideIndex", publicName: "currentSlideIndex", isSignal: true, isRequired: true, transformFunction: null }, activeCustomShow: { classPropertyName: "activeCustomShow", publicName: "activeCustomShow", isSignal: true, isRequired: false, transformFunction: null }, authoredRange: { classPropertyName: "authoredRange", publicName: "authoredRange", isSignal: true, isRequired: false, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, templateElements: { classPropertyName: "templateElements", publicName: "templateElements", isSignal: true, isRequired: false, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, presentationStartTime: { classPropertyName: "presentationStartTime", publicName: "presentationStartTime", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { movePresentationSlide: "movePresentationSlide", exit: "exit" }, ngImport: i0, template: "@if (currentSlide(); as current) {\n\t<!-- Header: elapsed + counter + exit -->\n\t<div class=\"pptx-ng-mpresenter-header\">\n\t\t<div>\n\t\t\t<div class=\"pptx-ng-mpresenter-label\">{{ 'pptx.presenter.elapsed' | translate }}</div>\n\t\t\t<div class=\"pptx-ng-mpresenter-elapsed\">{{ elapsedLabel() }}</div>\n\t\t</div>\n\t\t<span class=\"pptx-ng-mpresenter-counter\">{{ counterLabel() }}</span>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-mpresenter-exit\"\n\t\t\t(click)=\"exit.emit()\"\n\t\t\t[attr.aria-label]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t\t[title]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t>\n\t\t\t&#x2715;\n\t\t</button>\n\t</div>\n\n\t<!-- Current slide (large) -->\n\t<div class=\"pptx-ng-mpresenter-main\">\n\t\t<div class=\"pptx-ng-mpresenter-main-stage\">\n\t\t\t<pptx-slide-canvas\n\t\t\t\t[slide]=\"currentPreviewSlide()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t[zoom]=\"1\"\n\t\t\t\t[interactive]=\"false\"\n\t\t\t/>\n\t\t</div>\n\t</div>\n\n\t<!-- Next thumbnail -->\n\t<div class=\"pptx-ng-mpresenter-next\">\n\t\t<span class=\"pptx-ng-mpresenter-label\">{{\n\t\t\t'pptx.presenter.nextSlidePreview' | translate\n\t\t}}</span>\n\t\t@if (nextPreviewSlide(); as next) {\n\t\t\t<div class=\"pptx-ng-mpresenter-thumb\" [ngStyle]=\"thumbStyle()\">\n\t\t\t\t<pptx-slide-canvas\n\t\t\t\t\t[slide]=\"next\"\n\t\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t[zoom]=\"1\"\n\t\t\t\t\t[interactive]=\"false\"\n\t\t\t\t/>\n\t\t\t</div>\n\t\t} @else {\n\t\t\t<div class=\"pptx-ng-mpresenter-next-empty\">\n\t\t\t\t{{ 'pptx.presenter.endOfPresentation' | translate }}\n\t\t\t</div>\n\t\t}\n\t</div>\n\n\t<!-- Speaker notes (scrollable) -->\n\t<div class=\"pptx-ng-mpresenter-notes\">\n\t\t<div class=\"pptx-ng-mpresenter-label\">{{ 'pptx.presenter.speakerNotes' | translate }}</div>\n\t\t<div class=\"pptx-ng-mpresenter-notes-body\">\n\t\t\t@if (notes().hasRichNotes) {\n\t\t\t\t@for (seg of notes().segments; track seg.key) {\n\t\t\t\t\t@if (seg.isBreak) {\n\t\t\t\t\t\t<br />\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<span [ngStyle]=\"seg.style\">{{ seg.text }}</span>\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} @else if (notes().hasAnyNotes) {\n\t\t\t\t{{ notes().plainText }}\n\t\t\t} @else {\n\t\t\t\t<span class=\"pptx-ng-mpresenter-notes-empty\">{{\n\t\t\t\t\t'pptx.presenter.noNotes' | translate\n\t\t\t\t}}</span>\n\t\t\t}\n\t\t</div>\n\t</div>\n\n\t<!-- Prev / Next controls -->\n\t<div class=\"pptx-ng-mpresenter-ctl\">\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-mpresenter-navbtn\"\n\t\t\tdata-pptx-presenter-control=\"prev\"\n\t\t\t(click)=\"movePresentationSlide.emit(-1)\"\n\t\t\t[disabled]=\"prevDisabled()\"\n\t\t\t[attr.aria-label]=\"'pptx.presenter.previousSlide' | translate\"\n\t\t\t[title]=\"'pptx.presenter.previousSlide' | translate\"\n\t\t>\n\t\t\t&#x2039; {{ 'pptx.presenter.prev' | translate }}\n\t\t</button>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-mpresenter-navbtn\"\n\t\t\tdata-pptx-presenter-control=\"next\"\n\t\t\t(click)=\"movePresentationSlide.emit(1)\"\n\t\t\t[disabled]=\"nextDisabled()\"\n\t\t\t[attr.aria-label]=\"'pptx.presenter.nextSlide' | translate\"\n\t\t\t[title]=\"'pptx.presenter.nextSlide' | translate\"\n\t\t>\n\t\t\t{{ 'pptx.presenter.next' | translate }} &#x203A;\n\t\t</button>\n\t</div>\n} @else {\n\t<div class=\"pptx-ng-mpresenter-empty\">{{ 'pptx.presenter.noSlides' | translate }}</div>\n}\n", styles: [":host{position:absolute;inset:0;z-index:50;display:flex;flex-direction:column;background:#0b0b0c;color:#f5f5f5;font-family:system-ui,sans-serif;padding-top:env(safe-area-inset-top,0px);padding-bottom:env(safe-area-inset-bottom,0px);padding-left:env(safe-area-inset-left,0px);padding-right:env(safe-area-inset-right,0px)}.pptx-ng-mpresenter-header,.pptx-ng-mpresenter-next,.pptx-ng-mpresenter-ctl{display:flex;align-items:center;gap:.75rem;padding:.5rem 1rem}.pptx-ng-mpresenter-header{justify-content:space-between;border-bottom:1px solid rgba(255,255,255,.08)}.pptx-ng-mpresenter-label{font-size:.625rem;text-transform:uppercase;letter-spacing:.06em;color:#ffffff8c}.pptx-ng-mpresenter-elapsed{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:1.125rem;color:#6ea8fe}.pptx-ng-mpresenter-counter{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.875rem}.pptx-ng-mpresenter-exit{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;min-width:44px;min-height:44px;border:none;border-radius:6px;background:transparent;color:#ffffffbf;cursor:pointer;font-size:1.25rem;line-height:1}.pptx-ng-mpresenter-exit:hover{background:#ffffff1f;color:#fff}.pptx-ng-mpresenter-main{display:flex;align-items:center;justify-content:center;background:#000;padding:.75rem}.pptx-ng-mpresenter-main-stage{width:100%;max-width:640px}.pptx-ng-mpresenter-next{border-bottom:1px solid rgba(255,255,255,.08)}.pptx-ng-mpresenter-thumb{flex:0 0 auto;overflow:hidden;border:1px solid rgba(255,255,255,.15);border-radius:4px}.pptx-ng-mpresenter-next-empty{display:flex;flex:1 1 auto;align-items:center;justify-content:center;height:3rem;border:1px solid rgba(255,255,255,.15);border-radius:4px;background:#ffffff0a;font-size:.625rem;font-style:italic;color:#ffffff80}.pptx-ng-mpresenter-notes{flex:1 1 auto;display:flex;flex-direction:column;min-height:0;padding:.5rem 1rem}.pptx-ng-mpresenter-notes-body{flex:1 1 auto;overflow-y:auto;margin-top:.25rem;border:1px solid rgba(255,255,255,.15);border-radius:6px;background:#ffffff0a;padding:.5rem .75rem;white-space:pre-wrap;line-height:1.5;font-size:15px}.pptx-ng-mpresenter-notes-empty{font-style:italic;color:#ffffff80}.pptx-ng-mpresenter-ctl{justify-content:space-between;border-top:1px solid rgba(255,255,255,.08)}.pptx-ng-mpresenter-navbtn{flex:1 1 0;display:inline-flex;align-items:center;justify-content:center;gap:.375rem;height:44px;border:none;border-radius:6px;background:#ffffff14;color:#f5f5f5;cursor:pointer;font-size:.9rem}.pptx-ng-mpresenter-navbtn:hover:not(:disabled){background:#ffffff29}.pptx-ng-mpresenter-navbtn:disabled{opacity:.4;cursor:not-allowed}.pptx-ng-mpresenter-empty{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#fff9}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
126779
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: MobilePresenterViewComponent, isStandalone: true, selector: "pptx-mobile-presenter-view", inputs: { slides: { classPropertyName: "slides", publicName: "slides", isSignal: true, isRequired: true, transformFunction: null }, currentSlideIndex: { classPropertyName: "currentSlideIndex", publicName: "currentSlideIndex", isSignal: true, isRequired: true, transformFunction: null }, activeCustomShow: { classPropertyName: "activeCustomShow", publicName: "activeCustomShow", isSignal: true, isRequired: false, transformFunction: null }, authoredRange: { classPropertyName: "authoredRange", publicName: "authoredRange", isSignal: true, isRequired: false, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, templateElements: { classPropertyName: "templateElements", publicName: "templateElements", isSignal: true, isRequired: false, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, presentationStartTime: { classPropertyName: "presentationStartTime", publicName: "presentationStartTime", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { movePresentationSlide: "movePresentationSlide", exit: "exit" }, ngImport: i0, template: "@if (currentSlide(); as current) {\n\t<!-- Header: elapsed + counter + exit -->\n\t<div class=\"pptx-ng-mpresenter-header\">\n\t\t<div>\n\t\t\t<div class=\"pptx-ng-mpresenter-label\">{{ 'pptx.presenter.elapsed' | translate }}</div>\n\t\t\t<div class=\"pptx-ng-mpresenter-elapsed\">{{ elapsedLabel() }}</div>\n\t\t</div>\n\t\t<span class=\"pptx-ng-mpresenter-counter\">{{ counterLabel() }}</span>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-mpresenter-exit\"\n\t\t\t(click)=\"exit.emit()\"\n\t\t\t[attr.aria-label]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t\t[title]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t>\n\t\t\t&#x2715;\n\t\t</button>\n\t</div>\n\n\t<!-- Current slide (large) -->\n\t<div class=\"pptx-ng-mpresenter-main\">\n\t\t<div class=\"pptx-ng-mpresenter-main-stage\">\n\t\t\t<pptx-slide-canvas\n\t\t\t\t[slide]=\"currentPreviewSlide()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t[zoom]=\"1\"\n\t\t\t\t[interactive]=\"false\"\n\t\t\t/>\n\t\t</div>\n\t</div>\n\n\t<!-- Next thumbnail -->\n\t<div class=\"pptx-ng-mpresenter-next\">\n\t\t<span class=\"pptx-ng-mpresenter-label\">{{\n\t\t\t'pptx.presenter.nextSlidePreview' | translate\n\t\t}}</span>\n\t\t@if (nextPreviewSlide(); as next) {\n\t\t\t<div class=\"pptx-ng-mpresenter-thumb\" [ngStyle]=\"thumbStyle()\">\n\t\t\t\t<pptx-slide-canvas\n\t\t\t\t\t[slide]=\"next\"\n\t\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t[zoom]=\"1\"\n\t\t\t\t\t[interactive]=\"false\"\n\t\t\t\t/>\n\t\t\t</div>\n\t\t} @else {\n\t\t\t<div class=\"pptx-ng-mpresenter-next-empty\">\n\t\t\t\t{{ 'pptx.presenter.endOfPresentation' | translate }}\n\t\t\t</div>\n\t\t}\n\t</div>\n\n\t<!-- Speaker notes (scrollable) -->\n\t<div class=\"pptx-ng-mpresenter-notes\">\n\t\t<div class=\"pptx-ng-mpresenter-label\">{{ 'pptx.presenter.speakerNotes' | translate }}</div>\n\t\t<div class=\"pptx-ng-mpresenter-notes-body\">\n\t\t\t@if (notes().hasRichNotes) {\n\t\t\t\t@for (seg of notes().segments; track seg.key) {\n\t\t\t\t\t@if (seg.isBreak) {\n\t\t\t\t\t\t<br />\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<span [ngStyle]=\"seg.style\">{{ seg.text }}</span>\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} @else if (notes().hasAnyNotes) {\n\t\t\t\t{{ notes().plainText }}\n\t\t\t} @else {\n\t\t\t\t<span class=\"pptx-ng-mpresenter-notes-empty\">{{\n\t\t\t\t\t'pptx.presenter.noNotes' | translate\n\t\t\t\t}}</span>\n\t\t\t}\n\t\t</div>\n\t</div>\n\n\t<!-- Prev / Next controls -->\n\t<div class=\"pptx-ng-mpresenter-ctl\">\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-mpresenter-navbtn\"\n\t\t\tdata-pptx-presenter-control=\"prev\"\n\t\t\t(click)=\"movePresentationSlide.emit(-1)\"\n\t\t\t[disabled]=\"prevDisabled()\"\n\t\t\t[attr.aria-label]=\"'pptx.presenter.previousSlide' | translate\"\n\t\t\t[title]=\"'pptx.presenter.previousSlide' | translate\"\n\t\t>\n\t\t\t&#x2039; {{ 'pptx.presenter.prev' | translate }}\n\t\t</button>\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-mpresenter-navbtn\"\n\t\t\tdata-pptx-presenter-control=\"next\"\n\t\t\t(click)=\"movePresentationSlide.emit(1)\"\n\t\t\t[disabled]=\"nextDisabled()\"\n\t\t\t[attr.aria-label]=\"'pptx.presenter.nextSlide' | translate\"\n\t\t\t[title]=\"'pptx.presenter.nextSlide' | translate\"\n\t\t>\n\t\t\t{{ 'pptx.presenter.next' | translate }} &#x203A;\n\t\t</button>\n\t</div>\n} @else {\n\t<div class=\"pptx-ng-mpresenter-empty\">{{ 'pptx.presenter.noSlides' | translate }}</div>\n}\n", styles: [":host{position:absolute;inset:0;z-index:50;display:flex;flex-direction:column;background:#0b0b0c;color:#f5f5f5;font-family:system-ui,sans-serif;padding-top:env(safe-area-inset-top,0px);padding-bottom:env(safe-area-inset-bottom,0px);padding-left:env(safe-area-inset-left,0px);padding-right:env(safe-area-inset-right,0px)}.pptx-ng-mpresenter-header,.pptx-ng-mpresenter-next,.pptx-ng-mpresenter-ctl{display:flex;align-items:center;gap:.75rem;padding:.5rem 1rem}.pptx-ng-mpresenter-header{justify-content:space-between;border-bottom:1px solid rgba(255,255,255,.08)}.pptx-ng-mpresenter-label{font-size:.625rem;text-transform:uppercase;letter-spacing:.06em;color:#ffffff8c}.pptx-ng-mpresenter-elapsed{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:1.125rem;color:#6ea8fe}.pptx-ng-mpresenter-counter{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.875rem}.pptx-ng-mpresenter-exit{display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;min-width:44px;min-height:44px;border:none;border-radius:6px;background:transparent;color:#ffffffbf;cursor:pointer;font-size:1.25rem;line-height:1}.pptx-ng-mpresenter-exit:hover{background:#ffffff1f;color:#fff}.pptx-ng-mpresenter-main{display:flex;align-items:center;justify-content:center;background:#000;padding:.75rem}.pptx-ng-mpresenter-main-stage{width:100%;max-width:640px}.pptx-ng-mpresenter-next{border-bottom:1px solid rgba(255,255,255,.08)}.pptx-ng-mpresenter-thumb{flex:0 0 auto;overflow:hidden;border:1px solid rgba(255,255,255,.15);border-radius:4px}.pptx-ng-mpresenter-next-empty{display:flex;flex:1 1 auto;align-items:center;justify-content:center;height:3rem;border:1px solid rgba(255,255,255,.15);border-radius:4px;background:#ffffff0a;font-size:.625rem;font-style:italic;color:#ffffff80}.pptx-ng-mpresenter-notes{flex:1 1 auto;display:flex;flex-direction:column;min-height:0;padding:.5rem 1rem}.pptx-ng-mpresenter-notes-body{flex:1 1 auto;overflow-y:auto;margin-top:.25rem;border:1px solid rgba(255,255,255,.15);border-radius:6px;background:#ffffff0a;padding:.5rem .75rem;white-space:pre-wrap;line-height:1.5;font-size:15px}.pptx-ng-mpresenter-notes-empty{font-style:italic;color:#ffffff80}.pptx-ng-mpresenter-ctl{justify-content:space-between;border-top:1px solid rgba(255,255,255,.08)}.pptx-ng-mpresenter-navbtn{flex:1 1 0;display:inline-flex;align-items:center;justify-content:center;gap:.375rem;height:44px;border:none;border-radius:6px;background:#ffffff14;color:#f5f5f5;cursor:pointer;font-size:.9rem}.pptx-ng-mpresenter-navbtn:hover:not(:disabled){background:#ffffff29}.pptx-ng-mpresenter-navbtn:disabled{opacity:.4;cursor:not-allowed}.pptx-ng-mpresenter-empty{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#fff9}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
126445
126780
  }
126446
126781
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: MobilePresenterViewComponent, decorators: [{
126447
126782
  type: Component,
@@ -126617,7 +126952,7 @@ class MobileSlidesSheetComponent {
126617
126952
  }
126618
126953
  </div>
126619
126954
  </pptx-mobile-sheet>
126620
- `, isInline: true, styles: [":host{display:contents}.pptx-ng-mslides-count{margin:0;padding:.5rem 1rem .25rem;font-size:.75rem;color:#ffffff73}.pptx-ng-mslides-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:.75rem;padding:.75rem .875rem 1.5rem}.pptx-ng-mslides-cell{display:flex;flex-direction:column;align-items:center;gap:.375rem;padding:.375rem;border:2px solid transparent;border-radius:.5rem;background:transparent;color:inherit;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;transition:border-color .12s,background .12s}.pptx-ng-mslides-cell:hover{background:#ffffff0d;border-color:#ffffff26}.pptx-ng-mslides-cell:active{background:#ffffff1a}.pptx-ng-mslides-cell.is-active{border-color:#3b82f6;background:#3b82f61a}.pptx-ng-mslides-clip{overflow:hidden;border-radius:.25rem;width:100%}.pptx-ng-mslides-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}.pptx-ng-mslides-num{display:block;font-size:.625rem;color:#fff6;line-height:1.4;-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: MobileSheetComponent, selector: "pptx-mobile-sheet", inputs: ["open", "title", "heightFraction", "fullScreen"], outputs: ["closed"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
126955
+ `, isInline: true, styles: [":host{display:contents}.pptx-ng-mslides-count{margin:0;padding:.5rem 1rem .25rem;font-size:.75rem;color:#ffffff73}.pptx-ng-mslides-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:.75rem;padding:.75rem .875rem 1.5rem}.pptx-ng-mslides-cell{display:flex;flex-direction:column;align-items:center;gap:.375rem;padding:.375rem;border:2px solid transparent;border-radius:.5rem;background:transparent;color:inherit;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;transition:border-color .12s,background .12s}.pptx-ng-mslides-cell:hover{background:#ffffff0d;border-color:#ffffff26}.pptx-ng-mslides-cell:active{background:#ffffff1a}.pptx-ng-mslides-cell.is-active{border-color:#3b82f6;background:#3b82f61a}.pptx-ng-mslides-clip{overflow:hidden;border-radius:.25rem;width:100%}.pptx-ng-mslides-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}.pptx-ng-mslides-num{display:block;font-size:.625rem;color:#fff6;line-height:1.4;-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: MobileSheetComponent, selector: "pptx-mobile-sheet", inputs: ["open", "title", "heightFraction", "fullScreen"], outputs: ["closed"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
126621
126956
  }
126622
126957
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: MobileSlidesSheetComponent, decorators: [{
126623
126958
  type: Component,
@@ -131668,6 +132003,7 @@ class ViewerKeyboardService {
131668
132003
  }
131669
132004
  const { action, dx, dy } = mapEditorKey(event, {
131670
132005
  canEdit: host.canEdit(),
132006
+ canPaste: this.editor.hasClipboard(),
131671
132007
  isPresenting: host.presenting(),
131672
132008
  hasSelection: this.editor.hasSelection(),
131673
132009
  isDrawing: host.isDrawing?.() ?? false,
@@ -134592,7 +134928,7 @@ class FragmentedTransitionLayerComponent {
134592
134928
  </div>
134593
134929
  }
134594
134930
  </div>
134595
- `, isInline: true, styles: [":host{display:block}.pptx-ng-transition-layer{position:absolute;inset:0}.pptx-ng-transition-fragment{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;pointer-events:none}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
134931
+ `, isInline: true, styles: [":host{display:block}.pptx-ng-transition-layer{position:absolute;inset:0}.pptx-ng-transition-fragment{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;pointer-events:none}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
134596
134932
  }
134597
134933
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: FragmentedTransitionLayerComponent, decorators: [{
134598
134934
  type: Component,
@@ -134724,7 +135060,7 @@ class MorphExtraLayersComponent {
134724
135060
  </div>
134725
135061
  </div>
134726
135062
  }
134727
- `, isInline: true, styles: [".pptx-ng-transition-layer{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
135063
+ `, isInline: true, styles: [".pptx-ng-transition-layer{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
134728
135064
  }
134729
135065
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: MorphExtraLayersComponent, decorators: [{
134730
135066
  type: Component,
@@ -135285,7 +135621,7 @@ class PresentationTransitionOverlayComponent {
135285
135621
  });
135286
135622
  }
135287
135623
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: PresentationTransitionOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
135288
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: PresentationTransitionOverlayComponent, isStandalone: true, selector: "pptx-presentation-transition-overlay", inputs: { outgoingSlide: { classPropertyName: "outgoingSlide", publicName: "outgoingSlide", isSignal: true, isRequired: true, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, transition: { classPropertyName: "transition", publicName: "transition", isSignal: true, isRequired: true, transformFunction: null }, templateElements: { classPropertyName: "templateElements", publicName: "templateElements", isSignal: true, isRequired: false, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, durationMs: { classPropertyName: "durationMs", publicName: "durationMs", isSignal: true, isRequired: false, transformFunction: null }, zoom: { classPropertyName: "zoom", publicName: "zoom", isSignal: true, isRequired: false, transformFunction: null }, incomingSlide: { classPropertyName: "incomingSlide", publicName: "incomingSlide", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { complete: "complete" }, host: { attributes: { "data-pptx-transition-overlay": "" } }, ngImport: i0, template: "<!-- The seven multi-fragment cinematic transitions (vortex, honeycomb,\n glitter, shred, fracture, curtains, airplane) replace whichever\n layer(s) 'getFragmentedTransitionDescriptor' names with N clipped\n copies of the slide instead of one animated block. Morph never sets\n 'fragmented' (it is its own transition type), so the two never race. -->\n@if (fragmentedIncoming(); as fragIncoming) {\n\t<pptx-fragmented-transition-layer\n\t\t[layer]=\"fragIncoming\"\n\t\t[slide]=\"incomingFragmentSlide()!\"\n\t\t[canvasSize]=\"canvasSize()\"\n\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t[zoom]=\"zoom()\"\n\t\tlayerName=\"incoming\"\n\t\t[zIndex]=\"fragmentedIncomingZIndex()\"\n\t/>\n} @else if (incomingLayerSlide(); as incoming) {\n\t<div\n\t\tclass=\"pptx-ng-transition-layer\"\n\t\tdata-pptx-transition-layer=\"incoming\"\n\t\t[ngStyle]=\"incomingLayerStyle()\"\n\t>\n\t\t<div [ngStyle]=\"slideBoxStyle()\">\n\t\t\t<pptx-slide-canvas\n\t\t\t\t[slide]=\"incoming\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t\t[autoFit]=\"false\"\n\t\t\t\t[interactive]=\"false\"\n\t\t\t/>\n\t\t</div>\n\t</div>\n}\n\n@if (fragmentedOutgoing(); as fragOutgoing) {\n\t<pptx-fragmented-transition-layer\n\t\t[layer]=\"fragOutgoing\"\n\t\t[slide]=\"layerSlide()\"\n\t\t[canvasSize]=\"canvasSize()\"\n\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t[zoom]=\"zoom()\"\n\t\tlayerName=\"outgoing\"\n\t\t[zIndex]=\"fragmentedOutgoingZIndex()\"\n\t/>\n} @else {\n\t<div\n\t\tclass=\"pptx-ng-transition-layer\"\n\t\tdata-pptx-transition-layer=\"outgoing\"\n\t\t[attr.data-pptx-morph-outgoing]=\"morphPlan() ? 'true' : null\"\n\t\t[ngStyle]=\"layerStyle()\"\n\t>\n\t\t<div [ngStyle]=\"slideBoxStyle()\">\n\t\t\t<pptx-slide-canvas\n\t\t\t\t[slide]=\"layerSlide()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t\t[autoFit]=\"false\"\n\t\t\t\t[interactive]=\"false\"\n\t\t\t\t[transparentBackground]=\"isMorph()\"\n\t\t\t/>\n\t\t</div>\n\t</div>\n}\n\n<!-- The two morph-only extra layers (arriving-above-departing \"lifted\"\n shapes, and same-pair crossfade groups) - see\n `MorphExtraLayersComponent`. -->\n<pptx-morph-extra-layers\n\t[liftedSlide]=\"liftedSlide()\"\n\t[crossfadeGroups]=\"crossfadeGroups()\"\n\t[canvasSize]=\"canvasSize()\"\n\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t[zoom]=\"zoom()\"\n\t[slideBoxStyle]=\"slideBoxStyle()\"\n/>\n", styles: [":host{display:block;position:absolute;inset:0;overflow:hidden;pointer-events:none}.pptx-ng-transition-layer{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: FragmentedTransitionLayerComponent, selector: "pptx-fragmented-transition-layer", inputs: ["layer", "slide", "canvasSize", "mediaDataUrls", "zoom", "layerName", "zIndex"] }, { kind: "component", type: MorphExtraLayersComponent, selector: "pptx-morph-extra-layers", inputs: ["liftedSlide", "crossfadeGroups", "canvasSize", "mediaDataUrls", "zoom", "slideBoxStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
135624
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: PresentationTransitionOverlayComponent, isStandalone: true, selector: "pptx-presentation-transition-overlay", inputs: { outgoingSlide: { classPropertyName: "outgoingSlide", publicName: "outgoingSlide", isSignal: true, isRequired: true, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, transition: { classPropertyName: "transition", publicName: "transition", isSignal: true, isRequired: true, transformFunction: null }, templateElements: { classPropertyName: "templateElements", publicName: "templateElements", isSignal: true, isRequired: false, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, durationMs: { classPropertyName: "durationMs", publicName: "durationMs", isSignal: true, isRequired: false, transformFunction: null }, zoom: { classPropertyName: "zoom", publicName: "zoom", isSignal: true, isRequired: false, transformFunction: null }, incomingSlide: { classPropertyName: "incomingSlide", publicName: "incomingSlide", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { complete: "complete" }, host: { attributes: { "data-pptx-transition-overlay": "" } }, ngImport: i0, template: "<!-- The seven multi-fragment cinematic transitions (vortex, honeycomb,\n glitter, shred, fracture, curtains, airplane) replace whichever\n layer(s) 'getFragmentedTransitionDescriptor' names with N clipped\n copies of the slide instead of one animated block. Morph never sets\n 'fragmented' (it is its own transition type), so the two never race. -->\n@if (fragmentedIncoming(); as fragIncoming) {\n\t<pptx-fragmented-transition-layer\n\t\t[layer]=\"fragIncoming\"\n\t\t[slide]=\"incomingFragmentSlide()!\"\n\t\t[canvasSize]=\"canvasSize()\"\n\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t[zoom]=\"zoom()\"\n\t\tlayerName=\"incoming\"\n\t\t[zIndex]=\"fragmentedIncomingZIndex()\"\n\t/>\n} @else if (incomingLayerSlide(); as incoming) {\n\t<div\n\t\tclass=\"pptx-ng-transition-layer\"\n\t\tdata-pptx-transition-layer=\"incoming\"\n\t\t[ngStyle]=\"incomingLayerStyle()\"\n\t>\n\t\t<div [ngStyle]=\"slideBoxStyle()\">\n\t\t\t<pptx-slide-canvas\n\t\t\t\t[slide]=\"incoming\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t\t[autoFit]=\"false\"\n\t\t\t\t[interactive]=\"false\"\n\t\t\t/>\n\t\t</div>\n\t</div>\n}\n\n@if (fragmentedOutgoing(); as fragOutgoing) {\n\t<pptx-fragmented-transition-layer\n\t\t[layer]=\"fragOutgoing\"\n\t\t[slide]=\"layerSlide()\"\n\t\t[canvasSize]=\"canvasSize()\"\n\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t[zoom]=\"zoom()\"\n\t\tlayerName=\"outgoing\"\n\t\t[zIndex]=\"fragmentedOutgoingZIndex()\"\n\t/>\n} @else {\n\t<div\n\t\tclass=\"pptx-ng-transition-layer\"\n\t\tdata-pptx-transition-layer=\"outgoing\"\n\t\t[attr.data-pptx-morph-outgoing]=\"morphPlan() ? 'true' : null\"\n\t\t[ngStyle]=\"layerStyle()\"\n\t>\n\t\t<div [ngStyle]=\"slideBoxStyle()\">\n\t\t\t<pptx-slide-canvas\n\t\t\t\t[slide]=\"layerSlide()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t\t[autoFit]=\"false\"\n\t\t\t\t[interactive]=\"false\"\n\t\t\t\t[transparentBackground]=\"isMorph()\"\n\t\t\t/>\n\t\t</div>\n\t</div>\n}\n\n<!-- The two morph-only extra layers (arriving-above-departing \"lifted\"\n shapes, and same-pair crossfade groups) - see\n `MorphExtraLayersComponent`. -->\n<pptx-morph-extra-layers\n\t[liftedSlide]=\"liftedSlide()\"\n\t[crossfadeGroups]=\"crossfadeGroups()\"\n\t[canvasSize]=\"canvasSize()\"\n\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t[zoom]=\"zoom()\"\n\t[slideBoxStyle]=\"slideBoxStyle()\"\n/>\n", styles: [":host{display:block;position:absolute;inset:0;overflow:hidden;pointer-events:none}.pptx-ng-transition-layer{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: FragmentedTransitionLayerComponent, selector: "pptx-fragmented-transition-layer", inputs: ["layer", "slide", "canvasSize", "mediaDataUrls", "zoom", "layerName", "zIndex"] }, { kind: "component", type: MorphExtraLayersComponent, selector: "pptx-morph-extra-layers", inputs: ["liftedSlide", "crossfadeGroups", "canvasSize", "mediaDataUrls", "zoom", "slideBoxStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
135289
135625
  }
135290
135626
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: PresentationTransitionOverlayComponent, decorators: [{
135291
135627
  type: Component,
@@ -135405,7 +135741,7 @@ class PresenterSlideNavigatorComponent {
135405
135741
  }
135406
135742
  </div>
135407
135743
  </div>
135408
- `, isInline: true, dependencies: [{ kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
135744
+ `, isInline: true, dependencies: [{ kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
135409
135745
  }
135410
135746
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: PresenterSlideNavigatorComponent, decorators: [{
135411
135747
  type: Component,
@@ -136303,7 +136639,7 @@ class PresentationOverlayComponent {
136303
136639
  this.closed.emit();
136304
136640
  }
136305
136641
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: PresentationOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
136306
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: PresentationOverlayComponent, isStandalone: true, selector: "pptx-presentation-overlay", inputs: { slides: { classPropertyName: "slides", publicName: "slides", isSignal: true, isRequired: true, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, startIndex: { classPropertyName: "startIndex", publicName: "startIndex", isSignal: true, isRequired: false, transformFunction: null }, activeCustomShow: { classPropertyName: "activeCustomShow", publicName: "activeCustomShow", isSignal: true, isRequired: false, transformFunction: null }, authoredRange: { classPropertyName: "authoredRange", publicName: "authoredRange", isSignal: true, isRequired: false, transformFunction: null }, loopContinuously: { classPropertyName: "loopContinuously", publicName: "loopContinuously", isSignal: true, isRequired: false, transformFunction: null }, showWithAnimation: { classPropertyName: "showWithAnimation", publicName: "showWithAnimation", isSignal: true, isRequired: false, transformFunction: null }, useTimings: { classPropertyName: "useTimings", publicName: "useTimings", isSignal: true, isRequired: false, transformFunction: null }, subtitlesVisible: { classPropertyName: "subtitlesVisible", publicName: "subtitlesVisible", isSignal: true, isRequired: false, transformFunction: null }, sessionEnded: { classPropertyName: "sessionEnded", publicName: "sessionEnded", isSignal: true, isRequired: false, transformFunction: null }, endWithBlackSlide: { classPropertyName: "endWithBlackSlide", publicName: "endWithBlackSlide", isSignal: true, isRequired: false, transformFunction: null }, pixelateMosaicAnimation: { classPropertyName: "pixelateMosaicAnimation", publicName: "pixelateMosaicAnimation", isSignal: true, isRequired: false, transformFunction: null }, presenterMode: { classPropertyName: "presenterMode", publicName: "presenterMode", isSignal: true, isRequired: false, transformFunction: null }, showMenuOnRightClick: { classPropertyName: "showMenuOnRightClick", publicName: "showMenuOnRightClick", isSignal: true, isRequired: false, transformFunction: null }, showPopupToolbar: { classPropertyName: "showPopupToolbar", publicName: "showPopupToolbar", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { indexChange: "indexChange", closed: "closed", subtitlesChange: "subtitlesChange", presenterViewToggle: "presenterViewToggle", annotationsExit: "annotationsExit", customShowRequest: "customShowRequest", endOfShowChange: "endOfShowChange" }, host: { listeners: { "document:wheel": "onWheel($event)", "document:fullscreenchange": "onFullscreenChange()", "window:resize": "onWindowResize()", "document:keydown": "onKeyDown($event)" } }, providers: [AnimationPlaybackService, PresentationAnnotationsService, ZoomNavigationService], viewQueries: [{ propertyName: "stageRef", first: true, predicate: ["stage"], descendants: true, isSignal: true }, { propertyName: "rootRef", first: true, predicate: ["root"], descendants: true, isSignal: true }, { propertyName: "toolbarRef", first: true, predicate: PresentationToolbarComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<div #root class=\"pptx-ng-presentation-root\">\n\t<!--\n\t\tSlide counter, rendered first in DOM (before slide content) so a\n\t\tgeneric \"N / M\" text query resolves to it rather than to any slide-text\n\t\trun that happens to read like \"24 / 7\". Position is fixed, so DOM order\n\t\tdoes not affect its on-screen placement.\n\t-->\n\t<span class=\"pptx-ng-presentation-counter\" [ngStyle]=\"counterStyle\">\n\t\t{{ counterLabel() }}\n\t</span>\n\n\t<!-- Black \"End of slide show\" screen: the show has run past its last\n\t slide. It MUST be visible - while it is up the next input either\n\t goes nowhere (backward) or ends the show (forward), so a deck that\n\t kept painting the last slide looked stuck and swallowed advances. -->\n\t@if (endOfShow()) {\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-presentation-end\"\n\t\t\tdata-pptx-end-of-show\n\t\t\t(click)=\"onEndScreenClick($event)\"\n\t\t>\n\t\t\t<span>{{ 'pptx.presentation.endOfSlideShow' | translate }}</span>\n\t\t</button>\n\t}\n\n\t<div\n\t\t#stage\n\t\tclass=\"pptx-ng-presentation-stage\"\n\t\t[ngStyle]=\"stageContainerStyle()\"\n\t\t(click)=\"onBodyClick($event)\"\n\t\t(mouseover)=\"onStageHover($event)\"\n\t\t(mouseout)=\"onStageHoverEnd($event)\"\n\t\t(contextmenu)=\"onStageContextMenu($event)\"\n\t>\n\t\t<pptx-slide-canvas\n\t\t\t[slide]=\"currentSlide()\"\n\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zoom]=\"zoom()\"\n\t\t\t[autoFit]=\"false\"\n\t\t\t[interactive]=\"false\"\n\t\t\t[presenting]=\"true\"\n\t\t/>\n\n\t\t@if (activeTransition(); as t) {\n\t\t\t<pptx-presentation-transition-overlay\n\t\t\t\t[outgoingSlide]=\"t.outgoing\"\n\t\t\t\t[incomingSlide]=\"currentSlide()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[transition]=\"t.transition\"\n\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t\t(complete)=\"activeTransition.set(null)\"\n\t\t\t/>\n\t\t}\n\n\t\t<!-- Ink annotation overlay (pen/highlighter/eraser/laser). Ctrl+M\n\t\t hides the markup without discarding the strokes. The host carries\n\t\t the shared blackboard z-index so strokes stay visible ABOVE the\n\t\t blackout sheet while the screen is blanked (the stage no longer\n\t\t creates a stacking context, see stageContainerStyle). -->\n\t\t@if (inkMarkupVisible()) {\n\t\t\t<pptx-presentation-annotation-overlay\n\t\t\t\tdata-pptx-annotation-overlay\n\t\t\t\t[style.z-index]=\"annotationOverlayZ()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t/>\n\t\t}\n\t</div>\n\t@if (presenterWindow.snapshot().blackout !== 'none') {\n\t\t<div\n\t\t\tclass=\"presenter-blank\"\n\t\t\tdata-pptx-blackout\n\t\t\t[style.background]=\"presenterWindow.snapshot().blackout\"\n\t\t></div>\n\t}\n\t@if (presenterWindow.snapshot().pointer?.tool === 'laser') {\n\t\t<div\n\t\t\tclass=\"presenter-laser\"\n\t\t\t[style.left.%]=\"(presenterWindow.snapshot().pointer?.x ?? 0.5) * 100\"\n\t\t\t[style.top.%]=\"(presenterWindow.snapshot().pointer?.y ?? 0.5) * 100\"\n\t\t></div>\n\t}\n\t@if (presenterWindow.snapshot().subtitlesVisible && presenterWindow.snapshot().caption) {\n\t\t<div class=\"presenter-caption\">{{ presenterWindow.snapshot().caption }}</div>\n\t}\n\n\t<!-- Live-caption (subtitle) bar. -->\n\t<pptx-presentation-subtitle-bar [visible]=\"subtitlesVisible()\" />\n\n\t<!--\n\t\tTouch-only chrome (close button, edge arrows, counter pill). The\n\t\tcomponent stylesheet hides all three unless the device has a coarse\n\t\tpointer, matching React's `PresentationTouchControls`: on a desktop they\n\t\tduplicate the toolbar above and put a SECOND slide counter on screen.\n\n\t\tRendered BEFORE the show toolbar, as React renders its touch controls,\n\t\tbecause both carry the same accessible names (\"Next Slide\", \"Previous\n\t\tSlide\", \"End Presentation\"). On a coarse pointer the toolbar's copies are\n\t\tstill in the DOM but inert (`pointer-events: none`), so whichever comes\n\t\tfirst is what a by-name lookup - a screen reader's, or a spec's `.first()`\n\t\t- resolves to. With the toolbar first, every such lookup landed on a\n\t\tbutton no user could press: it reported itself visible and enabled, and\n\t\tthe tap was swallowed by the overlay. Position is fixed on all of these,\n\t\tso moving them in the DOM does not move them on screen.\n\t-->\n\t<!-- Always-visible close button (top-right, safe-area aware). -->\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-close\"\n\t\t[ngStyle]=\"closeButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'close')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'close')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.endPresentation' | translate\"\n\t>\n\t\t<svg lucideX class=\"h-5 w-5\"></svg>\n\t</button>\n\n\t<!-- Edge navigation buttons (vertically centred, touch-friendly). -->\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-nav pptx-ng-presentation-prev\"\n\t\t[ngStyle]=\"prevButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'prev')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'prev')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.previousSlide' | translate\"\n\t>\n\t\t<svg lucideChevronLeft class=\"h-6 w-6\"></svg>\n\t</button>\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-nav pptx-ng-presentation-next\"\n\t\t[ngStyle]=\"nextButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'next')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'next')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.nextSlide' | translate\"\n\t>\n\t\t<svg lucideChevronRight class=\"h-6 w-6\"></svg>\n\t</button>\n\n\t<!--\n\t\tThe show toolbar (bottom-centre, auto-hiding): navigation, counter,\n\t\telapsed time, annotation tools, presenter view and end-show, per\n\t\t`PRESENT_TOOLBAR_CONTROLS` in pptx-viewer-shared.\n\t-->\n\t<pptx-presentation-toolbar\n\t\t#toolbar\n\t\t[currentSlideIndex]=\"currentIndex()\"\n\t\t[totalSlides]=\"slides().length\"\n\t\t[presentationStartTime]=\"showStartedAt\"\n\t\t[presenterMode]=\"presenterMode()\"\n\t\t[popupToolbarEnabled]=\"showPopupToolbar()\"\n\t\t(move)=\"navigator.navigate($event === 1 ? 'next' : 'prev')\"\n\t\t(presenterViewToggle)=\"presenterViewToggle.emit()\"\n\t\t(endPresentation)=\"onToolbarEnd()\"\n\t/>\n\n\t<!--\n\t\tPowerPoint's \"See All Slides\" (Ctrl+S during a show). The same navigator\n\t\tthe presenter console uses, laid over the show itself: the shortcut exists\n\t\tso a presenter can reach a backup slide WITHOUT leaving the show, so it\n\t\tmust not be a door into presenter view.\n\t-->\n\t@if (allSlidesOpen()) {\n\t\t<pptx-presenter-slide-navigator\n\t\t\t[slides]=\"slides()\"\n\t\t\t[current]=\"currentIndex()\"\n\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t(select)=\"onNavigatorSelect($event)\"\n\t\t\t(close)=\"allSlidesOpen.set(false)\"\n\t\t/>\n\t}\n\n\t<!-- Slide-show right-click menu. -->\n\t@if (contextMenuState(); as pos) {\n\t\t<pptx-presentation-context-menu\n\t\t\t[x]=\"pos.x\"\n\t\t\t[y]=\"pos.y\"\n\t\t\t(action)=\"onContextMenuAction($event)\"\n\t\t\t(closed)=\"contextMenuState.set(null)\"\n\t\t/>\n\t}\n\n\t<!-- `ppaction://program` (\"Run program\") notices: see run-program-notices.component.ts. -->\n\t<pptx-run-program-notices\n\t\t[notices]=\"runProgramNotices.notices()\"\n\t\t(dismiss)=\"runProgramNotices.dismiss($event)\"\n\t/>\n</div>\n", styles: [":host{display:block;position:fixed;inset:0;z-index:10000;background:#000;cursor:pointer;-webkit-user-select:none;user-select:none;overflow:hidden}.pptx-ng-presentation-root{position:absolute;inset:0;touch-action:pan-y;overflow:hidden}.pptx-ng-presentation-close:hover,.pptx-ng-presentation-nav:hover{background:#000000bf}@media not all and (any-pointer:coarse){.pptx-ng-presentation-close,.pptx-ng-presentation-nav,.pptx-ng-presentation-counter{display:none!important}}.presenter-blank{position:absolute;inset:0;z-index:75;pointer-events:none}.pptx-ng-presentation-end{position:absolute;inset:0;z-index:90;display:flex;align-items:flex-start;border:0;padding:0;background:#000;text-align:left;cursor:default}.pptx-ng-presentation-end span{padding:.75rem 1rem;color:#ffffffb3;font-size:12px}.presenter-laser{position:absolute;z-index:76;width:20px;height:20px;transform:translate(-50%,-50%);border-radius:50%;background:#ef4444;box-shadow:0 0 20px 8px #ef444488;pointer-events:none}.presenter-caption{position:absolute;z-index:77;left:10%;right:10%;bottom:2rem;padding:.75rem 1.5rem;border-radius:.5rem;background:#000c;color:#fff;text-align:center;font-size:1.25rem;pointer-events:none}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresentationTransitionOverlayComponent, selector: "pptx-presentation-transition-overlay", inputs: ["outgoingSlide", "canvasSize", "transition", "templateElements", "mediaDataUrls", "durationMs", "zoom", "incomingSlide"], outputs: ["complete"] }, { kind: "component", type: PresentationAnnotationOverlayComponent, selector: "pptx-presentation-annotation-overlay", inputs: ["canvasSize", "zoom"] }, { kind: "component", type: PresentationSubtitleBarComponent, selector: "pptx-presentation-subtitle-bar", inputs: ["visible"] }, { kind: "component", type: PresentationToolbarComponent, selector: "pptx-presentation-toolbar", inputs: ["currentSlideIndex", "totalSlides", "presentationStartTime", "presenterMode", "popupToolbarEnabled"], outputs: ["move", "endPresentation", "presenterViewToggle"] }, { kind: "component", type: PresentationContextMenuComponent, selector: "pptx-presentation-context-menu", inputs: ["x", "y"], outputs: ["closed", "action"] }, { kind: "component", type: PresenterSlideNavigatorComponent, selector: "pptx-presenter-slide-navigator", inputs: ["slides", "current", "canvasSize", "mediaDataUrls", "templateElements"], outputs: ["select", "close"] }, { kind: "component", type: RunProgramNoticesComponent, selector: "pptx-run-program-notices", inputs: ["notices"], outputs: ["dismiss"] }, { kind: "component", type: LucideX, selector: "svg[lucideX]" }, { kind: "component", type: LucideChevronLeft, selector: "svg[lucideChevronLeft]" }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
136642
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: PresentationOverlayComponent, isStandalone: true, selector: "pptx-presentation-overlay", inputs: { slides: { classPropertyName: "slides", publicName: "slides", isSignal: true, isRequired: true, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, startIndex: { classPropertyName: "startIndex", publicName: "startIndex", isSignal: true, isRequired: false, transformFunction: null }, activeCustomShow: { classPropertyName: "activeCustomShow", publicName: "activeCustomShow", isSignal: true, isRequired: false, transformFunction: null }, authoredRange: { classPropertyName: "authoredRange", publicName: "authoredRange", isSignal: true, isRequired: false, transformFunction: null }, loopContinuously: { classPropertyName: "loopContinuously", publicName: "loopContinuously", isSignal: true, isRequired: false, transformFunction: null }, showWithAnimation: { classPropertyName: "showWithAnimation", publicName: "showWithAnimation", isSignal: true, isRequired: false, transformFunction: null }, useTimings: { classPropertyName: "useTimings", publicName: "useTimings", isSignal: true, isRequired: false, transformFunction: null }, subtitlesVisible: { classPropertyName: "subtitlesVisible", publicName: "subtitlesVisible", isSignal: true, isRequired: false, transformFunction: null }, sessionEnded: { classPropertyName: "sessionEnded", publicName: "sessionEnded", isSignal: true, isRequired: false, transformFunction: null }, endWithBlackSlide: { classPropertyName: "endWithBlackSlide", publicName: "endWithBlackSlide", isSignal: true, isRequired: false, transformFunction: null }, pixelateMosaicAnimation: { classPropertyName: "pixelateMosaicAnimation", publicName: "pixelateMosaicAnimation", isSignal: true, isRequired: false, transformFunction: null }, presenterMode: { classPropertyName: "presenterMode", publicName: "presenterMode", isSignal: true, isRequired: false, transformFunction: null }, showMenuOnRightClick: { classPropertyName: "showMenuOnRightClick", publicName: "showMenuOnRightClick", isSignal: true, isRequired: false, transformFunction: null }, showPopupToolbar: { classPropertyName: "showPopupToolbar", publicName: "showPopupToolbar", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { indexChange: "indexChange", closed: "closed", subtitlesChange: "subtitlesChange", presenterViewToggle: "presenterViewToggle", annotationsExit: "annotationsExit", customShowRequest: "customShowRequest", endOfShowChange: "endOfShowChange" }, host: { listeners: { "document:wheel": "onWheel($event)", "document:fullscreenchange": "onFullscreenChange()", "window:resize": "onWindowResize()", "document:keydown": "onKeyDown($event)" } }, providers: [AnimationPlaybackService, PresentationAnnotationsService, ZoomNavigationService], viewQueries: [{ propertyName: "stageRef", first: true, predicate: ["stage"], descendants: true, isSignal: true }, { propertyName: "rootRef", first: true, predicate: ["root"], descendants: true, isSignal: true }, { propertyName: "toolbarRef", first: true, predicate: PresentationToolbarComponent, descendants: true, isSignal: true }], ngImport: i0, template: "<div #root class=\"pptx-ng-presentation-root\">\n\t<!--\n\t\tSlide counter, rendered first in DOM (before slide content) so a\n\t\tgeneric \"N / M\" text query resolves to it rather than to any slide-text\n\t\trun that happens to read like \"24 / 7\". Position is fixed, so DOM order\n\t\tdoes not affect its on-screen placement.\n\t-->\n\t<span class=\"pptx-ng-presentation-counter\" [ngStyle]=\"counterStyle\">\n\t\t{{ counterLabel() }}\n\t</span>\n\n\t<!-- Black \"End of slide show\" screen: the show has run past its last\n\t slide. It MUST be visible - while it is up the next input either\n\t goes nowhere (backward) or ends the show (forward), so a deck that\n\t kept painting the last slide looked stuck and swallowed advances. -->\n\t@if (endOfShow()) {\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-presentation-end\"\n\t\t\tdata-pptx-end-of-show\n\t\t\t(click)=\"onEndScreenClick($event)\"\n\t\t>\n\t\t\t<span>{{ 'pptx.presentation.endOfSlideShow' | translate }}</span>\n\t\t</button>\n\t}\n\n\t<div\n\t\t#stage\n\t\tclass=\"pptx-ng-presentation-stage\"\n\t\t[ngStyle]=\"stageContainerStyle()\"\n\t\t(click)=\"onBodyClick($event)\"\n\t\t(mouseover)=\"onStageHover($event)\"\n\t\t(mouseout)=\"onStageHoverEnd($event)\"\n\t\t(contextmenu)=\"onStageContextMenu($event)\"\n\t>\n\t\t<pptx-slide-canvas\n\t\t\t[slide]=\"currentSlide()\"\n\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t[zoom]=\"zoom()\"\n\t\t\t[autoFit]=\"false\"\n\t\t\t[interactive]=\"false\"\n\t\t\t[presenting]=\"true\"\n\t\t/>\n\n\t\t@if (activeTransition(); as t) {\n\t\t\t<pptx-presentation-transition-overlay\n\t\t\t\t[outgoingSlide]=\"t.outgoing\"\n\t\t\t\t[incomingSlide]=\"currentSlide()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[transition]=\"t.transition\"\n\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t\t(complete)=\"activeTransition.set(null)\"\n\t\t\t/>\n\t\t}\n\n\t\t<!-- Ink annotation overlay (pen/highlighter/eraser/laser). Ctrl+M\n\t\t hides the markup without discarding the strokes. The host carries\n\t\t the shared blackboard z-index so strokes stay visible ABOVE the\n\t\t blackout sheet while the screen is blanked (the stage no longer\n\t\t creates a stacking context, see stageContainerStyle). -->\n\t\t@if (inkMarkupVisible()) {\n\t\t\t<pptx-presentation-annotation-overlay\n\t\t\t\tdata-pptx-annotation-overlay\n\t\t\t\t[style.z-index]=\"annotationOverlayZ()\"\n\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t[zoom]=\"zoom()\"\n\t\t\t/>\n\t\t}\n\t</div>\n\t@if (presenterWindow.snapshot().blackout !== 'none') {\n\t\t<div\n\t\t\tclass=\"presenter-blank\"\n\t\t\tdata-pptx-blackout\n\t\t\t[style.background]=\"presenterWindow.snapshot().blackout\"\n\t\t></div>\n\t}\n\t@if (presenterWindow.snapshot().pointer?.tool === 'laser') {\n\t\t<div\n\t\t\tclass=\"presenter-laser\"\n\t\t\t[style.left.%]=\"(presenterWindow.snapshot().pointer?.x ?? 0.5) * 100\"\n\t\t\t[style.top.%]=\"(presenterWindow.snapshot().pointer?.y ?? 0.5) * 100\"\n\t\t></div>\n\t}\n\t@if (presenterWindow.snapshot().subtitlesVisible && presenterWindow.snapshot().caption) {\n\t\t<div class=\"presenter-caption\">{{ presenterWindow.snapshot().caption }}</div>\n\t}\n\n\t<!-- Live-caption (subtitle) bar. -->\n\t<pptx-presentation-subtitle-bar [visible]=\"subtitlesVisible()\" />\n\n\t<!--\n\t\tTouch-only chrome (close button, edge arrows, counter pill). The\n\t\tcomponent stylesheet hides all three unless the device has a coarse\n\t\tpointer, matching React's `PresentationTouchControls`: on a desktop they\n\t\tduplicate the toolbar above and put a SECOND slide counter on screen.\n\n\t\tRendered BEFORE the show toolbar, as React renders its touch controls,\n\t\tbecause both carry the same accessible names (\"Next Slide\", \"Previous\n\t\tSlide\", \"End Presentation\"). On a coarse pointer the toolbar's copies are\n\t\tstill in the DOM but inert (`pointer-events: none`), so whichever comes\n\t\tfirst is what a by-name lookup - a screen reader's, or a spec's `.first()`\n\t\t- resolves to. With the toolbar first, every such lookup landed on a\n\t\tbutton no user could press: it reported itself visible and enabled, and\n\t\tthe tap was swallowed by the overlay. Position is fixed on all of these,\n\t\tso moving them in the DOM does not move them on screen.\n\t-->\n\t<!-- Always-visible close button (top-right, safe-area aware). -->\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-close\"\n\t\t[ngStyle]=\"closeButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'close')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'close')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.endPresentation' | translate\"\n\t>\n\t\t<svg lucideX class=\"h-5 w-5\"></svg>\n\t</button>\n\n\t<!-- Edge navigation buttons (vertically centred, touch-friendly). -->\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-nav pptx-ng-presentation-prev\"\n\t\t[ngStyle]=\"prevButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'prev')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'prev')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.previousSlide' | translate\"\n\t>\n\t\t<svg lucideChevronLeft class=\"h-6 w-6\"></svg>\n\t</button>\n\t<button\n\t\ttype=\"button\"\n\t\tclass=\"pptx-ng-presentation-nav pptx-ng-presentation-next\"\n\t\t[ngStyle]=\"nextButtonStyle\"\n\t\t(click)=\"onChromeButton($event, 'next')\"\n\t\t(touchend)=\"onChromeButtonTouch($event, 'next')\"\n\t\t[attr.aria-label]=\"'pptx.presenter.nextSlide' | translate\"\n\t>\n\t\t<svg lucideChevronRight class=\"h-6 w-6\"></svg>\n\t</button>\n\n\t<!--\n\t\tThe show toolbar (bottom-centre, auto-hiding): navigation, counter,\n\t\telapsed time, annotation tools, presenter view and end-show, per\n\t\t`PRESENT_TOOLBAR_CONTROLS` in pptx-viewer-shared.\n\t-->\n\t<pptx-presentation-toolbar\n\t\t#toolbar\n\t\t[currentSlideIndex]=\"currentIndex()\"\n\t\t[totalSlides]=\"slides().length\"\n\t\t[presentationStartTime]=\"showStartedAt\"\n\t\t[presenterMode]=\"presenterMode()\"\n\t\t[popupToolbarEnabled]=\"showPopupToolbar()\"\n\t\t(move)=\"navigator.navigate($event === 1 ? 'next' : 'prev')\"\n\t\t(presenterViewToggle)=\"presenterViewToggle.emit()\"\n\t\t(endPresentation)=\"onToolbarEnd()\"\n\t/>\n\n\t<!--\n\t\tPowerPoint's \"See All Slides\" (Ctrl+S during a show). The same navigator\n\t\tthe presenter console uses, laid over the show itself: the shortcut exists\n\t\tso a presenter can reach a backup slide WITHOUT leaving the show, so it\n\t\tmust not be a door into presenter view.\n\t-->\n\t@if (allSlidesOpen()) {\n\t\t<pptx-presenter-slide-navigator\n\t\t\t[slides]=\"slides()\"\n\t\t\t[current]=\"currentIndex()\"\n\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t(select)=\"onNavigatorSelect($event)\"\n\t\t\t(close)=\"allSlidesOpen.set(false)\"\n\t\t/>\n\t}\n\n\t<!-- Slide-show right-click menu. -->\n\t@if (contextMenuState(); as pos) {\n\t\t<pptx-presentation-context-menu\n\t\t\t[x]=\"pos.x\"\n\t\t\t[y]=\"pos.y\"\n\t\t\t(action)=\"onContextMenuAction($event)\"\n\t\t\t(closed)=\"contextMenuState.set(null)\"\n\t\t/>\n\t}\n\n\t<!-- `ppaction://program` (\"Run program\") notices: see run-program-notices.component.ts. -->\n\t<pptx-run-program-notices\n\t\t[notices]=\"runProgramNotices.notices()\"\n\t\t(dismiss)=\"runProgramNotices.dismiss($event)\"\n\t/>\n</div>\n", styles: [":host{display:block;position:fixed;inset:0;z-index:10000;background:#000;cursor:pointer;-webkit-user-select:none;user-select:none;overflow:hidden}.pptx-ng-presentation-root{position:absolute;inset:0;touch-action:pan-y;overflow:hidden}.pptx-ng-presentation-close:hover,.pptx-ng-presentation-nav:hover{background:#000000bf}@media not all and (any-pointer:coarse){.pptx-ng-presentation-close,.pptx-ng-presentation-nav,.pptx-ng-presentation-counter{display:none!important}}.presenter-blank{position:absolute;inset:0;z-index:75;pointer-events:none}.pptx-ng-presentation-end{position:absolute;inset:0;z-index:90;display:flex;align-items:flex-start;border:0;padding:0;background:#000;text-align:left;cursor:default}.pptx-ng-presentation-end span{padding:.75rem 1rem;color:#ffffffb3;font-size:12px}.presenter-laser{position:absolute;z-index:76;width:20px;height:20px;transform:translate(-50%,-50%);border-radius:50%;background:#ef4444;box-shadow:0 0 20px 8px #ef444488;pointer-events:none}.presenter-caption{position:absolute;z-index:77;left:10%;right:10%;bottom:2rem;padding:.75rem 1.5rem;border-radius:.5rem;background:#000c;color:#fff;text-align:center;font-size:1.25rem;pointer-events:none}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresentationTransitionOverlayComponent, selector: "pptx-presentation-transition-overlay", inputs: ["outgoingSlide", "canvasSize", "transition", "templateElements", "mediaDataUrls", "durationMs", "zoom", "incomingSlide"], outputs: ["complete"] }, { kind: "component", type: PresentationAnnotationOverlayComponent, selector: "pptx-presentation-annotation-overlay", inputs: ["canvasSize", "zoom"] }, { kind: "component", type: PresentationSubtitleBarComponent, selector: "pptx-presentation-subtitle-bar", inputs: ["visible"] }, { kind: "component", type: PresentationToolbarComponent, selector: "pptx-presentation-toolbar", inputs: ["currentSlideIndex", "totalSlides", "presentationStartTime", "presenterMode", "popupToolbarEnabled"], outputs: ["move", "endPresentation", "presenterViewToggle"] }, { kind: "component", type: PresentationContextMenuComponent, selector: "pptx-presentation-context-menu", inputs: ["x", "y"], outputs: ["closed", "action"] }, { kind: "component", type: PresenterSlideNavigatorComponent, selector: "pptx-presenter-slide-navigator", inputs: ["slides", "current", "canvasSize", "mediaDataUrls", "templateElements"], outputs: ["select", "close"] }, { kind: "component", type: RunProgramNoticesComponent, selector: "pptx-run-program-notices", inputs: ["notices"], outputs: ["dismiss"] }, { kind: "component", type: LucideX, selector: "svg[lucideX]" }, { kind: "component", type: LucideChevronLeft, selector: "svg[lucideChevronLeft]" }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
136307
136643
  }
136308
136644
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: PresentationOverlayComponent, decorators: [{
136309
136645
  type: Component,
@@ -137008,7 +137344,7 @@ class PresenterViewComponent {
137008
137344
  return { ...slide, elements: [...template, ...slide.elements] };
137009
137345
  }
137010
137346
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: PresenterViewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
137011
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: PresenterViewComponent, isStandalone: true, selector: "pptx-presenter-view", inputs: { slides: { classPropertyName: "slides", publicName: "slides", isSignal: true, isRequired: true, transformFunction: null }, currentSlideIndex: { classPropertyName: "currentSlideIndex", publicName: "currentSlideIndex", isSignal: true, isRequired: true, transformFunction: null }, activeCustomShow: { classPropertyName: "activeCustomShow", publicName: "activeCustomShow", isSignal: true, isRequired: false, transformFunction: null }, authoredRange: { classPropertyName: "authoredRange", publicName: "authoredRange", isSignal: true, isRequired: false, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, templateElements: { classPropertyName: "templateElements", publicName: "templateElements", isSignal: true, isRequired: false, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, presentationStartTime: { classPropertyName: "presentationStartTime", publicName: "presentationStartTime", isSignal: true, isRequired: false, transformFunction: null }, isAudienceWindowOpen: { classPropertyName: "isAudienceWindowOpen", publicName: "isAudienceWindowOpen", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { movePresentationSlide: "movePresentationSlide", exit: "exit", openAudienceWindow: "openAudienceWindow", closeAudienceWindow: "closeAudienceWindow", navigateToSlide: "navigateToSlide" }, ngImport: i0, template: "@if (currentSlide(); as current) {\n\t<pptx-presenter-controls\n\t\t[snapshot]=\"presenterWindow.snapshot()\"\n\t\t[audienceOpen]=\"isAudienceWindowOpen()\"\n\t\t[slides]=\"slides()\"\n\t\t[current]=\"currentSlideIndex()\"\n\t\t[canvasSize]=\"canvasSize()\"\n\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t[templateElements]=\"templateElements()\"\n\t\t(patch)=\"presenterWindow.updateSnapshot($event)\"\n\t\t(navigate)=\"navigateToSlide.emit($event)\"\n\t\t(audience)=\"onToggleAudienceWindow()\"\n\t\t(swapDisplays)=\"onSwapDisplays()\"\n\t\t(end)=\"exit.emit()\"\n\t/>\n\t<div class=\"pptx-ng-presenter-body\">\n\t\t<!-- Current slide (\u224870%) -->\n\t\t<div\n\t\t\tclass=\"pptx-ng-presenter-current\"\n\t\t\t[class.pptx-ng-presenter-current--advances]=\"paneAdvancesOnClick()\"\n\t\t\trole=\"presentation\"\n\t\t\tdata-pptx-presenter-slide\n\t\t\t(click)=\"onSlidePaneClick()\"\n\t\t>\n\t\t\t<div class=\"pptx-ng-presenter-preview-stage\" [ngStyle]=\"previewStageStyle()\">\n\t\t\t\t<pptx-slide-canvas\n\t\t\t\t\t[slide]=\"currentPreviewSlide()\"\n\t\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t[zoom]=\"1\"\n\t\t\t\t\t[interactive]=\"false\"\n\t\t\t\t/>\n\t\t\t</div>\n\t\t\t<div class=\"pptx-ng-presenter-slide-badge\">{{ slideBadge() }}</div>\n\t\t</div>\n\n\t\t<!-- Controls (\u224830%) -->\n\t\t<div class=\"pptx-ng-presenter-side\">\n\t\t\t<!-- Header: clock + elapsed + window/exit -->\n\t\t\t<div class=\"pptx-ng-presenter-header\">\n\t\t\t\t<div>\n\t\t\t\t\t<div class=\"pptx-ng-presenter-label\">\n\t\t\t\t\t\t{{ 'pptx.presenter.currentTime' | translate }}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"pptx-ng-presenter-clock\">{{ clockLabel() }}</div>\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t<div class=\"pptx-ng-presenter-label\">{{ 'pptx.presenter.elapsed' | translate }}</div>\n\t\t\t\t\t<div class=\"pptx-ng-presenter-clock pptx-ng-presenter-elapsed\">\n\t\t\t\t\t\t{{ elapsedLabel() }}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div style=\"display: flex; align-items: center; gap: 0.25rem\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"pptx-ng-presenter-iconbtn\"\n\t\t\t\t\t\t(click)=\"onToggleAudienceWindow()\"\n\t\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t\t(isAudienceWindowOpen()\n\t\t\t\t\t\t\t\t? 'pptx.presenter.closeAudienceWindow'\n\t\t\t\t\t\t\t\t: 'pptx.presenter.openAudienceWindow'\n\t\t\t\t\t\t\t) | translate\n\t\t\t\t\t\t\"\n\t\t\t\t\t\t[title]=\"\n\t\t\t\t\t\t\t(isAudienceWindowOpen()\n\t\t\t\t\t\t\t\t? 'pptx.presenter.closeAudienceWindow'\n\t\t\t\t\t\t\t\t: 'pptx.presenter.openAudienceWindow'\n\t\t\t\t\t\t\t) | translate\n\t\t\t\t\t\t\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{ isAudienceWindowOpen() ? '\u25A3' : '\u25A1' }}\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"pptx-ng-presenter-iconbtn\"\n\t\t\t\t\t\t(click)=\"exit.emit()\"\n\t\t\t\t\t\t[attr.aria-label]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t\t\t\t\t[title]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t\t\t\t>\n\t\t\t\t\t\t&#x2715;\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Navigation -->\n\t\t\t<div class=\"pptx-ng-presenter-nav\">\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"pptx-ng-presenter-navbtn\"\n\t\t\t\t\t(click)=\"movePresentationSlide.emit(-1)\"\n\t\t\t\t\t[disabled]=\"prevDisabled()\"\n\t\t\t\t\tdata-pptx-presenter-control=\"prev\"\n\t\t\t\t\t[attr.aria-label]=\"'pptx.presenter.prev' | translate\"\n\t\t\t\t\t[title]=\"'pptx.presenter.prev' | translate\"\n\t\t\t\t>\n\t\t\t\t\t&#x2039; {{ 'pptx.presenter.prev' | translate }}\n\t\t\t\t</button>\n\t\t\t\t<span class=\"pptx-ng-presenter-counter\">{{ counterLabel() }}</span>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"pptx-ng-presenter-navbtn\"\n\t\t\t\t\t(click)=\"movePresentationSlide.emit(1)\"\n\t\t\t\t\t[disabled]=\"nextDisabled()\"\n\t\t\t\t\tdata-pptx-presenter-control=\"next\"\n\t\t\t\t\t[attr.aria-label]=\"'pptx.presenter.next' | translate\"\n\t\t\t\t\t[title]=\"'pptx.presenter.next' | translate\"\n\t\t\t\t>\n\t\t\t\t\t{{ 'pptx.presenter.next' | translate }} &#x203A;\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t<!-- Next slide preview -->\n\t\t\t<div class=\"pptx-ng-presenter-next\" data-pptx-presenter-next-preview>\n\t\t\t\t<div class=\"pptx-ng-presenter-label\" style=\"margin-bottom: 0.5rem\">\n\t\t\t\t\t{{ 'pptx.presenter.nextSlidePreview' | translate }}\n\t\t\t\t</div>\n\t\t\t\t@if (nextPreviewSlide(); as next) {\n\t\t\t\t\t<pptx-slide-canvas\n\t\t\t\t\t\t[slide]=\"next\"\n\t\t\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t\t[zoom]=\"1\"\n\t\t\t\t\t\t[interactive]=\"false\"\n\t\t\t\t\t/>\n\t\t\t\t} @else {\n\t\t\t\t\t<div class=\"pptx-ng-presenter-next-empty\">\n\t\t\t\t\t\t{{ 'pptx.presenter.endOfPresentation' | translate }}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t</div>\n\n\t\t\t<!-- Speaker notes -->\n\t\t\t<div class=\"pptx-ng-presenter-notes\" data-pptx-presenter-notes>\n\t\t\t\t<div class=\"pptx-ng-presenter-notes-head\">\n\t\t\t\t\t<div class=\"pptx-ng-presenter-label\">\n\t\t\t\t\t\t{{ 'pptx.presenter.speakerNotes' | translate }}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"pptx-ng-presenter-notes-size\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"pptx-ng-presenter-iconbtn\"\n\t\t\t\t\t\t\t(click)=\"decreaseNotesFontSize()\"\n\t\t\t\t\t\t\t[disabled]=\"notesFontSize() <= NOTES_FONT_SIZE_MIN\"\n\t\t\t\t\t\t\tdata-pptx-presenter-control=\"notes-font-decrease\"\n\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.presenter.decreaseFontSize' | translate\"\n\t\t\t\t\t\t\t[title]=\"'pptx.presenter.decreaseFontSize' | translate\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t&#x2212;\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<span class=\"pptx-ng-presenter-notes-size-value\">{{ notesFontSize() }}px</span>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"pptx-ng-presenter-iconbtn\"\n\t\t\t\t\t\t\t(click)=\"increaseNotesFontSize()\"\n\t\t\t\t\t\t\t[disabled]=\"notesFontSize() >= NOTES_FONT_SIZE_MAX\"\n\t\t\t\t\t\t\tdata-pptx-presenter-control=\"notes-font-increase\"\n\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.presenter.increaseFontSize' | translate\"\n\t\t\t\t\t\t\t[title]=\"'pptx.presenter.increaseFontSize' | translate\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t&#x2b;\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"pptx-ng-presenter-notes-body\" [ngStyle]=\"notesBodyStyle()\">\n\t\t\t\t\t@if (notes().hasRichNotes) {\n\t\t\t\t\t\t@for (seg of notes().segments; track seg.key) {\n\t\t\t\t\t\t\t@if (seg.isBreak) {\n\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<span [ngStyle]=\"seg.style\">{{ seg.text }}</span>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} @else if (notes().hasAnyNotes) {\n\t\t\t\t\t\t{{ notes().plainText }}\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<span class=\"pptx-ng-presenter-notes-empty\">\n\t\t\t\t\t\t\t{{ 'pptx.presenter.noNotes' | translate }}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n\n\t<!-- Timer progress bar -->\n\t<div\n\t\tclass=\"pptx-ng-presenter-progress\"\n\t\trole=\"progressbar\"\n\t\t[attr.aria-valuenow]=\"progressValue()\"\n\t\taria-valuemin=\"0\"\n\t\taria-valuemax=\"100\"\n\t\t[attr.aria-label]=\"'pptx.presenter.timerProgress' | translate\"\n\t>\n\t\t<div class=\"pptx-ng-presenter-progress-fill\" [style.width.%]=\"timerPercent()\"></div>\n\t</div>\n} @else {\n\t<div class=\"pptx-ng-presenter-empty\">{{ 'pptx.presenter.noSlides' | translate }}</div>\n}\n", styles: [":host{position:absolute;inset:0;z-index:50;display:flex;flex-direction:column;background:var(--pptx-card, #0b0b0c);color:var(--pptx-foreground, #f5f5f5);font-family:system-ui,sans-serif}.pptx-ng-presenter-body{display:flex;flex:1 1 auto;min-height:0}.pptx-ng-presenter-current--advances{cursor:pointer}.pptx-ng-presenter-current{flex:7 1 0;display:flex;flex-direction:column;align-items:center;justify-content:center;background:#000;padding:1rem;min-width:0;overflow:hidden}.pptx-ng-presenter-preview-stage{width:100%;max-width:100%;min-height:0;transition:transform .2s ease}.pptx-ng-presenter-slide-badge{margin-top:.5rem;font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.75rem;color:#ffffff80;-webkit-user-select:none;user-select:none}.pptx-ng-presenter-side{flex:3 1 0;display:flex;flex-direction:column;background:var(--pptx-background, #18181b);border-left:1px solid var(--pptx-border, rgba(255, 255, 255, .12));min-width:260px;max-width:440px}.pptx-ng-presenter-header,.pptx-ng-presenter-nav,.pptx-ng-presenter-next{padding:.5rem 1rem;border-bottom:1px solid var(--pptx-border, rgba(255, 255, 255, .12))}.pptx-ng-presenter-header{display:flex;align-items:center;justify-content:space-between;gap:.5rem}.pptx-ng-presenter-label{font-size:.625rem;text-transform:uppercase;letter-spacing:.06em;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .55))}.pptx-ng-presenter-clock{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:1.125rem}.pptx-ng-presenter-elapsed{color:var(--pptx-primary, #6ea8fe)}.pptx-ng-presenter-iconbtn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;border-radius:6px;background:transparent;color:var(--pptx-foreground, rgba(255, 255, 255, .7));cursor:pointer;font-size:1rem;line-height:1}.pptx-ng-presenter-iconbtn:hover{background:var(--pptx-secondary, rgba(255, 255, 255, .1));color:#fff}.pptx-ng-presenter-iconbtn:disabled{opacity:.3;cursor:not-allowed}.pptx-ng-presenter-nav{display:flex;align-items:center;justify-content:space-between}.pptx-ng-presenter-navbtn{display:inline-flex;align-items:center;gap:.375rem;padding:.375rem .75rem;border:none;border-radius:6px;background:var(--pptx-secondary, rgba(255, 255, 255, .08));color:var(--pptx-foreground, #f5f5f5);cursor:pointer;font-size:.75rem}.pptx-ng-presenter-navbtn:hover:not(:disabled){background:#ffffff29}.pptx-ng-presenter-navbtn:disabled{opacity:.4;cursor:not-allowed}.pptx-ng-presenter-counter{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.875rem}.pptx-ng-presenter-next-empty{display:flex;align-items:center;justify-content:center;height:4rem;border:1px solid var(--pptx-border, rgba(255, 255, 255, .12));border-radius:6px;background:var(--pptx-muted, rgba(255, 255, 255, .04));font-size:.75rem;font-style:italic;color:#ffffff80}.pptx-ng-presenter-notes{flex:1 1 auto;display:flex;flex-direction:column;min-height:0;padding:.75rem 1rem}.pptx-ng-presenter-notes-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:.5rem}.pptx-ng-presenter-notes-size{display:flex;align-items:center;gap:.25rem}.pptx-ng-presenter-notes-size-value{min-width:28px;text-align:center;font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.625rem;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .55));-webkit-user-select:none;user-select:none}.pptx-ng-presenter-notes-body{flex:1 1 auto;overflow-y:auto;border:1px solid var(--pptx-border, rgba(255, 255, 255, .12));border-radius:6px;background:var(--pptx-muted, rgba(255, 255, 255, .04));padding:.5rem .75rem;white-space:pre-wrap;line-height:1.5}.pptx-ng-presenter-notes-empty{font-style:italic;color:#ffffff80}.pptx-ng-presenter-progress{height:6px;width:100%;background:#ffffff1f;flex:0 0 auto}.pptx-ng-presenter-progress-fill{height:100%;background:#6ea8fe;transition:width 1s linear}.pptx-ng-presenter-empty{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#fff9}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresenterControlsComponent, selector: "pptx-presenter-controls", inputs: ["snapshot", "audienceOpen", "slides", "current", "canvasSize", "mediaDataUrls", "templateElements"], outputs: ["patch", "navigate", "audience", "swapDisplays", "end"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
137347
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: PresenterViewComponent, isStandalone: true, selector: "pptx-presenter-view", inputs: { slides: { classPropertyName: "slides", publicName: "slides", isSignal: true, isRequired: true, transformFunction: null }, currentSlideIndex: { classPropertyName: "currentSlideIndex", publicName: "currentSlideIndex", isSignal: true, isRequired: true, transformFunction: null }, activeCustomShow: { classPropertyName: "activeCustomShow", publicName: "activeCustomShow", isSignal: true, isRequired: false, transformFunction: null }, authoredRange: { classPropertyName: "authoredRange", publicName: "authoredRange", isSignal: true, isRequired: false, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, templateElements: { classPropertyName: "templateElements", publicName: "templateElements", isSignal: true, isRequired: false, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, presentationStartTime: { classPropertyName: "presentationStartTime", publicName: "presentationStartTime", isSignal: true, isRequired: false, transformFunction: null }, isAudienceWindowOpen: { classPropertyName: "isAudienceWindowOpen", publicName: "isAudienceWindowOpen", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { movePresentationSlide: "movePresentationSlide", exit: "exit", openAudienceWindow: "openAudienceWindow", closeAudienceWindow: "closeAudienceWindow", navigateToSlide: "navigateToSlide" }, ngImport: i0, template: "@if (currentSlide(); as current) {\n\t<pptx-presenter-controls\n\t\t[snapshot]=\"presenterWindow.snapshot()\"\n\t\t[audienceOpen]=\"isAudienceWindowOpen()\"\n\t\t[slides]=\"slides()\"\n\t\t[current]=\"currentSlideIndex()\"\n\t\t[canvasSize]=\"canvasSize()\"\n\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t[templateElements]=\"templateElements()\"\n\t\t(patch)=\"presenterWindow.updateSnapshot($event)\"\n\t\t(navigate)=\"navigateToSlide.emit($event)\"\n\t\t(audience)=\"onToggleAudienceWindow()\"\n\t\t(swapDisplays)=\"onSwapDisplays()\"\n\t\t(end)=\"exit.emit()\"\n\t/>\n\t<div class=\"pptx-ng-presenter-body\">\n\t\t<!-- Current slide (\u224870%) -->\n\t\t<div\n\t\t\tclass=\"pptx-ng-presenter-current\"\n\t\t\t[class.pptx-ng-presenter-current--advances]=\"paneAdvancesOnClick()\"\n\t\t\trole=\"presentation\"\n\t\t\tdata-pptx-presenter-slide\n\t\t\t(click)=\"onSlidePaneClick()\"\n\t\t>\n\t\t\t<div class=\"pptx-ng-presenter-preview-stage\" [ngStyle]=\"previewStageStyle()\">\n\t\t\t\t<pptx-slide-canvas\n\t\t\t\t\t[slide]=\"currentPreviewSlide()\"\n\t\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t[zoom]=\"1\"\n\t\t\t\t\t[interactive]=\"false\"\n\t\t\t\t/>\n\t\t\t</div>\n\t\t\t<div class=\"pptx-ng-presenter-slide-badge\">{{ slideBadge() }}</div>\n\t\t</div>\n\n\t\t<!-- Controls (\u224830%) -->\n\t\t<div class=\"pptx-ng-presenter-side\">\n\t\t\t<!-- Header: clock + elapsed + window/exit -->\n\t\t\t<div class=\"pptx-ng-presenter-header\">\n\t\t\t\t<div>\n\t\t\t\t\t<div class=\"pptx-ng-presenter-label\">\n\t\t\t\t\t\t{{ 'pptx.presenter.currentTime' | translate }}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"pptx-ng-presenter-clock\">{{ clockLabel() }}</div>\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t<div class=\"pptx-ng-presenter-label\">{{ 'pptx.presenter.elapsed' | translate }}</div>\n\t\t\t\t\t<div class=\"pptx-ng-presenter-clock pptx-ng-presenter-elapsed\">\n\t\t\t\t\t\t{{ elapsedLabel() }}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div style=\"display: flex; align-items: center; gap: 0.25rem\">\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"pptx-ng-presenter-iconbtn\"\n\t\t\t\t\t\t(click)=\"onToggleAudienceWindow()\"\n\t\t\t\t\t\t[attr.aria-label]=\"\n\t\t\t\t\t\t\t(isAudienceWindowOpen()\n\t\t\t\t\t\t\t\t? 'pptx.presenter.closeAudienceWindow'\n\t\t\t\t\t\t\t\t: 'pptx.presenter.openAudienceWindow'\n\t\t\t\t\t\t\t) | translate\n\t\t\t\t\t\t\"\n\t\t\t\t\t\t[title]=\"\n\t\t\t\t\t\t\t(isAudienceWindowOpen()\n\t\t\t\t\t\t\t\t? 'pptx.presenter.closeAudienceWindow'\n\t\t\t\t\t\t\t\t: 'pptx.presenter.openAudienceWindow'\n\t\t\t\t\t\t\t) | translate\n\t\t\t\t\t\t\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{{ isAudienceWindowOpen() ? '\u25A3' : '\u25A1' }}\n\t\t\t\t\t</button>\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"pptx-ng-presenter-iconbtn\"\n\t\t\t\t\t\t(click)=\"exit.emit()\"\n\t\t\t\t\t\t[attr.aria-label]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t\t\t\t\t[title]=\"'pptx.presenter.endPresentation' | translate\"\n\t\t\t\t\t>\n\t\t\t\t\t\t&#x2715;\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<!-- Navigation -->\n\t\t\t<div class=\"pptx-ng-presenter-nav\">\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"pptx-ng-presenter-navbtn\"\n\t\t\t\t\t(click)=\"movePresentationSlide.emit(-1)\"\n\t\t\t\t\t[disabled]=\"prevDisabled()\"\n\t\t\t\t\tdata-pptx-presenter-control=\"prev\"\n\t\t\t\t\t[attr.aria-label]=\"'pptx.presenter.prev' | translate\"\n\t\t\t\t\t[title]=\"'pptx.presenter.prev' | translate\"\n\t\t\t\t>\n\t\t\t\t\t&#x2039; {{ 'pptx.presenter.prev' | translate }}\n\t\t\t\t</button>\n\t\t\t\t<span class=\"pptx-ng-presenter-counter\">{{ counterLabel() }}</span>\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"pptx-ng-presenter-navbtn\"\n\t\t\t\t\t(click)=\"movePresentationSlide.emit(1)\"\n\t\t\t\t\t[disabled]=\"nextDisabled()\"\n\t\t\t\t\tdata-pptx-presenter-control=\"next\"\n\t\t\t\t\t[attr.aria-label]=\"'pptx.presenter.next' | translate\"\n\t\t\t\t\t[title]=\"'pptx.presenter.next' | translate\"\n\t\t\t\t>\n\t\t\t\t\t{{ 'pptx.presenter.next' | translate }} &#x203A;\n\t\t\t\t</button>\n\t\t\t</div>\n\n\t\t\t<!-- Next slide preview -->\n\t\t\t<div class=\"pptx-ng-presenter-next\" data-pptx-presenter-next-preview>\n\t\t\t\t<div class=\"pptx-ng-presenter-label\" style=\"margin-bottom: 0.5rem\">\n\t\t\t\t\t{{ 'pptx.presenter.nextSlidePreview' | translate }}\n\t\t\t\t</div>\n\t\t\t\t@if (nextPreviewSlide(); as next) {\n\t\t\t\t\t<pptx-slide-canvas\n\t\t\t\t\t\t[slide]=\"next\"\n\t\t\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t\t[zoom]=\"1\"\n\t\t\t\t\t\t[interactive]=\"false\"\n\t\t\t\t\t/>\n\t\t\t\t} @else {\n\t\t\t\t\t<div class=\"pptx-ng-presenter-next-empty\">\n\t\t\t\t\t\t{{ 'pptx.presenter.endOfPresentation' | translate }}\n\t\t\t\t\t</div>\n\t\t\t\t}\n\t\t\t</div>\n\n\t\t\t<!-- Speaker notes -->\n\t\t\t<div class=\"pptx-ng-presenter-notes\" data-pptx-presenter-notes>\n\t\t\t\t<div class=\"pptx-ng-presenter-notes-head\">\n\t\t\t\t\t<div class=\"pptx-ng-presenter-label\">\n\t\t\t\t\t\t{{ 'pptx.presenter.speakerNotes' | translate }}\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"pptx-ng-presenter-notes-size\">\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"pptx-ng-presenter-iconbtn\"\n\t\t\t\t\t\t\t(click)=\"decreaseNotesFontSize()\"\n\t\t\t\t\t\t\t[disabled]=\"notesFontSize() <= NOTES_FONT_SIZE_MIN\"\n\t\t\t\t\t\t\tdata-pptx-presenter-control=\"notes-font-decrease\"\n\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.presenter.decreaseFontSize' | translate\"\n\t\t\t\t\t\t\t[title]=\"'pptx.presenter.decreaseFontSize' | translate\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t&#x2212;\n\t\t\t\t\t\t</button>\n\t\t\t\t\t\t<span class=\"pptx-ng-presenter-notes-size-value\">{{ notesFontSize() }}px</span>\n\t\t\t\t\t\t<button\n\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\tclass=\"pptx-ng-presenter-iconbtn\"\n\t\t\t\t\t\t\t(click)=\"increaseNotesFontSize()\"\n\t\t\t\t\t\t\t[disabled]=\"notesFontSize() >= NOTES_FONT_SIZE_MAX\"\n\t\t\t\t\t\t\tdata-pptx-presenter-control=\"notes-font-increase\"\n\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.presenter.increaseFontSize' | translate\"\n\t\t\t\t\t\t\t[title]=\"'pptx.presenter.increaseFontSize' | translate\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t&#x2b;\n\t\t\t\t\t\t</button>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"pptx-ng-presenter-notes-body\" [ngStyle]=\"notesBodyStyle()\">\n\t\t\t\t\t@if (notes().hasRichNotes) {\n\t\t\t\t\t\t@for (seg of notes().segments; track seg.key) {\n\t\t\t\t\t\t\t@if (seg.isBreak) {\n\t\t\t\t\t\t\t\t<br />\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<span [ngStyle]=\"seg.style\">{{ seg.text }}</span>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} @else if (notes().hasAnyNotes) {\n\t\t\t\t\t\t{{ notes().plainText }}\n\t\t\t\t\t} @else {\n\t\t\t\t\t\t<span class=\"pptx-ng-presenter-notes-empty\">\n\t\t\t\t\t\t\t{{ 'pptx.presenter.noNotes' | translate }}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n\n\t<!-- Timer progress bar -->\n\t<div\n\t\tclass=\"pptx-ng-presenter-progress\"\n\t\trole=\"progressbar\"\n\t\t[attr.aria-valuenow]=\"progressValue()\"\n\t\taria-valuemin=\"0\"\n\t\taria-valuemax=\"100\"\n\t\t[attr.aria-label]=\"'pptx.presenter.timerProgress' | translate\"\n\t>\n\t\t<div class=\"pptx-ng-presenter-progress-fill\" [style.width.%]=\"timerPercent()\"></div>\n\t</div>\n} @else {\n\t<div class=\"pptx-ng-presenter-empty\">{{ 'pptx.presenter.noSlides' | translate }}</div>\n}\n", styles: [":host{position:absolute;inset:0;z-index:50;display:flex;flex-direction:column;background:var(--pptx-card, #0b0b0c);color:var(--pptx-foreground, #f5f5f5);font-family:system-ui,sans-serif}.pptx-ng-presenter-body{display:flex;flex:1 1 auto;min-height:0}.pptx-ng-presenter-current--advances{cursor:pointer}.pptx-ng-presenter-current{flex:7 1 0;display:flex;flex-direction:column;align-items:center;justify-content:center;background:#000;padding:1rem;min-width:0;overflow:hidden}.pptx-ng-presenter-preview-stage{width:100%;max-width:100%;min-height:0;transition:transform .2s ease}.pptx-ng-presenter-slide-badge{margin-top:.5rem;font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.75rem;color:#ffffff80;-webkit-user-select:none;user-select:none}.pptx-ng-presenter-side{flex:3 1 0;display:flex;flex-direction:column;background:var(--pptx-background, #18181b);border-left:1px solid var(--pptx-border, rgba(255, 255, 255, .12));min-width:260px;max-width:440px}.pptx-ng-presenter-header,.pptx-ng-presenter-nav,.pptx-ng-presenter-next{padding:.5rem 1rem;border-bottom:1px solid var(--pptx-border, rgba(255, 255, 255, .12))}.pptx-ng-presenter-header{display:flex;align-items:center;justify-content:space-between;gap:.5rem}.pptx-ng-presenter-label{font-size:.625rem;text-transform:uppercase;letter-spacing:.06em;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .55))}.pptx-ng-presenter-clock{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:1.125rem}.pptx-ng-presenter-elapsed{color:var(--pptx-primary, #6ea8fe)}.pptx-ng-presenter-iconbtn{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;border-radius:6px;background:transparent;color:var(--pptx-foreground, rgba(255, 255, 255, .7));cursor:pointer;font-size:1rem;line-height:1}.pptx-ng-presenter-iconbtn:hover{background:var(--pptx-secondary, rgba(255, 255, 255, .1));color:#fff}.pptx-ng-presenter-iconbtn:disabled{opacity:.3;cursor:not-allowed}.pptx-ng-presenter-nav{display:flex;align-items:center;justify-content:space-between}.pptx-ng-presenter-navbtn{display:inline-flex;align-items:center;gap:.375rem;padding:.375rem .75rem;border:none;border-radius:6px;background:var(--pptx-secondary, rgba(255, 255, 255, .08));color:var(--pptx-foreground, #f5f5f5);cursor:pointer;font-size:.75rem}.pptx-ng-presenter-navbtn:hover:not(:disabled){background:#ffffff29}.pptx-ng-presenter-navbtn:disabled{opacity:.4;cursor:not-allowed}.pptx-ng-presenter-counter{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.875rem}.pptx-ng-presenter-next-empty{display:flex;align-items:center;justify-content:center;height:4rem;border:1px solid var(--pptx-border, rgba(255, 255, 255, .12));border-radius:6px;background:var(--pptx-muted, rgba(255, 255, 255, .04));font-size:.75rem;font-style:italic;color:#ffffff80}.pptx-ng-presenter-notes{flex:1 1 auto;display:flex;flex-direction:column;min-height:0;padding:.75rem 1rem}.pptx-ng-presenter-notes-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:.5rem}.pptx-ng-presenter-notes-size{display:flex;align-items:center;gap:.25rem}.pptx-ng-presenter-notes-size-value{min-width:28px;text-align:center;font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums;font-size:.625rem;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .55));-webkit-user-select:none;user-select:none}.pptx-ng-presenter-notes-body{flex:1 1 auto;overflow-y:auto;border:1px solid var(--pptx-border, rgba(255, 255, 255, .12));border-radius:6px;background:var(--pptx-muted, rgba(255, 255, 255, .04));padding:.5rem .75rem;white-space:pre-wrap;line-height:1.5}.pptx-ng-presenter-notes-empty{font-style:italic;color:#ffffff80}.pptx-ng-presenter-progress{height:6px;width:100%;background:#ffffff1f;flex:0 0 auto}.pptx-ng-presenter-progress-fill{height:100%;background:#6ea8fe;transition:width 1s linear}.pptx-ng-presenter-empty{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#fff9}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresenterControlsComponent, selector: "pptx-presenter-controls", inputs: ["snapshot", "audienceOpen", "slides", "current", "canvasSize", "mediaDataUrls", "templateElements"], outputs: ["patch", "navigate", "audience", "swapDisplays", "end"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
137012
137348
  }
137013
137349
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: PresenterViewComponent, decorators: [{
137014
137350
  type: Component,
@@ -138417,7 +138753,7 @@ class ReadingViewOverlayComponent {
138417
138753
  </div>
138418
138754
  </div>
138419
138755
  }
138420
- `, isInline: true, styles: [".pptx-ng-reading-root{position:fixed;inset:0;z-index:1300;display:flex;flex-direction:column;background:#171717}.pptx-ng-reading-viewport{display:flex;flex:1 1 0%;min-height:0;align-items:center;justify-content:center}.pptx-ng-reading-stage{position:relative;overflow:hidden}.pptx-ng-reading-stage ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}.pptx-ng-reading-nav{display:flex;flex-shrink:0;align-items:center;justify-content:center;gap:.75rem;padding:.5rem 1rem;border-top:1px solid rgba(255,255,255,.1)}.pptx-ng-reading-btn{display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;border:none;border-radius:.25rem;background:transparent;color:#fffc;cursor:pointer;transition:background .15s,color .15s}.pptx-ng-reading-btn:hover:not(:disabled){background:#ffffff26;color:#fff}.pptx-ng-reading-btn:disabled{cursor:default;opacity:.3}.pptx-ng-reading-counter{min-width:4rem;text-align:center;font-size:.75rem;font-variant-numeric:tabular-nums;color:#ffffffb3}\n"], dependencies: [{ kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: LucideChevronLeft, selector: "svg[lucideChevronLeft]" }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }, { kind: "component", type: LucideX, selector: "svg[lucideX]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
138756
+ `, isInline: true, styles: [".pptx-ng-reading-root{position:fixed;inset:0;z-index:1300;display:flex;flex-direction:column;background:#171717}.pptx-ng-reading-viewport{display:flex;flex:1 1 0%;min-height:0;align-items:center;justify-content:center}.pptx-ng-reading-stage{position:relative;overflow:hidden}.pptx-ng-reading-stage ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}.pptx-ng-reading-nav{display:flex;flex-shrink:0;align-items:center;justify-content:center;gap:.75rem;padding:.5rem 1rem;border-top:1px solid rgba(255,255,255,.1)}.pptx-ng-reading-btn{display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;border:none;border-radius:.25rem;background:transparent;color:#fffc;cursor:pointer;transition:background .15s,color .15s}.pptx-ng-reading-btn:hover:not(:disabled){background:#ffffff26;color:#fff}.pptx-ng-reading-btn:disabled{cursor:default;opacity:.3}.pptx-ng-reading-counter{min-width:4rem;text-align:center;font-size:.75rem;font-variant-numeric:tabular-nums;color:#ffffffb3}\n"], dependencies: [{ kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: LucideChevronLeft, selector: "svg[lucideChevronLeft]" }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }, { kind: "component", type: LucideX, selector: "svg[lucideX]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
138421
138757
  }
138422
138758
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: ReadingViewOverlayComponent, decorators: [{
138423
138759
  type: Component,
@@ -139071,9 +139407,30 @@ function patchTextStyle(editor, slideIndex, el, patch) {
139071
139407
  if (!el || !hasTextProperties(el)) {
139072
139408
  return;
139073
139409
  }
139074
- editor.updateElement(slideIndex, el.id, {
139075
- textStyle: { ...el.textStyle, ...patch },
139076
- });
139410
+ const { listType, ...stylePatch } = patch;
139411
+ if (listType !== undefined) {
139412
+ const liveText = currentInlineEditorText();
139413
+ const base = liveText === undefined
139414
+ ? el
139415
+ : {
139416
+ ...el,
139417
+ text: liveText,
139418
+ textSegments: el.textSegments
139419
+ ? remapTextToSegments(liveText, el.textSegments, el.textStyle)
139420
+ : undefined,
139421
+ };
139422
+ const listed = { ...base, ...setElementBullets(base, listType) };
139423
+ if (!hasTextProperties(listed)) {
139424
+ return;
139425
+ }
139426
+ editor.updateElement(slideIndex, el.id, {
139427
+ ...(liveText !== undefined ? { text: liveText } : {}),
139428
+ textSegments: listed.textSegments,
139429
+ ...textStylePatch(listed, stylePatch),
139430
+ });
139431
+ return;
139432
+ }
139433
+ editor.updateElement(slideIndex, el.id, textStylePatch(el, patch));
139077
139434
  }
139078
139435
  /**
139079
139436
  * Rewrite the selection's text characters (ribbon Aa "Change Case" dropdown).
@@ -143678,7 +144035,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
143678
144035
  }], propDecorators: { canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }], selectedElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedElement", required: false }] }] } });
143679
144036
 
143680
144037
  // Generated by scripts/inline-shared.mjs from package.json. Do not edit.
143681
- const PPTX_ANGULAR_VIEWER_VERSION = "3.16.6";
144038
+ const PPTX_ANGULAR_VIEWER_VERSION = "3.16.7";
143682
144039
 
143683
144040
  /**
143684
144041
  * account-page.component.ts: File > Account content.
@@ -144983,12 +145340,19 @@ class RibbonParagraphControlsComponent {
144983
145340
  ...(ngDevMode ? [{ debugName: "slideIndex" }] : /* istanbul ignore next */ []));
144984
145341
  this.selectedElement = input(null, /* @ts-ignore */
144985
145342
  ...(ngDevMode ? [{ debugName: "selectedElement" }] : /* istanbul ignore next */ []));
145343
+ this.canEdit = input(false, /* @ts-ignore */
145344
+ ...(ngDevMode ? [{ debugName: "canEdit" }] : /* istanbul ignore next */ []));
144986
145345
  this.lineSpacingOptions = LINE_SPACING_OPTIONS;
144987
145346
  this.textDirectionOptions = TEXT_DIRECTION_OPTIONS;
144988
145347
  this.columnOptions = COLUMN_OPTIONS;
144989
145348
  /** Current text style of the selection (for active-state highlighting). */
144990
145349
  this.curStyle = computed(() => textStyleOf(this.selectedElement()), /* @ts-ignore */
144991
145350
  ...(ngDevMode ? [{ debugName: "curStyle" }] : /* istanbul ignore next */ []));
145351
+ this.listKind = computed(() => {
145352
+ const element = this.selectedElement();
145353
+ return element ? elementBulletKind(element) : 'none';
145354
+ }, /* @ts-ignore */
145355
+ ...(ngDevMode ? [{ debugName: "listKind" }] : /* istanbul ignore next */ []));
144992
145356
  }
144993
145357
  isText() {
144994
145358
  return isTextElement(this.selectedElement());
@@ -145007,7 +145371,10 @@ class RibbonParagraphControlsComponent {
145007
145371
  }
145008
145372
  /** Toggle the paragraph list style (bullet / numbered) off when already set. */
145009
145373
  toggleList(kind) {
145010
- this.patch({ listType: this.curStyle()?.listType === kind ? 'none' : kind });
145374
+ if (!this.canEdit()) {
145375
+ return;
145376
+ }
145377
+ this.patch({ listType: this.listKind() === kind ? 'none' : kind });
145011
145378
  }
145012
145379
  /** Step the paragraph left-indent by `deltaPx` (clamped at 0). */
145013
145380
  changeIndent(deltaPx) {
@@ -145030,14 +145397,15 @@ class RibbonParagraphControlsComponent {
145030
145397
  patchTextStyle(this.editor, this.slideIndex(), this.selectedElement(), patch);
145031
145398
  }
145032
145399
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RibbonParagraphControlsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
145033
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RibbonParagraphControlsComponent, isStandalone: true, selector: "pptx-ribbon-paragraph-controls", inputs: { slideIndex: { classPropertyName: "slideIndex", publicName: "slideIndex", isSignal: true, isRequired: false, transformFunction: null }, selectedElement: { classPropertyName: "selectedElement", publicName: "selectedElement", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "contents" }, ngImport: i0, template: `
145400
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RibbonParagraphControlsComponent, isStandalone: true, selector: "pptx-ribbon-paragraph-controls", inputs: { slideIndex: { classPropertyName: "slideIndex", publicName: "slideIndex", isSignal: true, isRequired: false, transformFunction: null }, selectedElement: { classPropertyName: "selectedElement", publicName: "selectedElement", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "contents" }, ngImport: i0, template: `
145034
145401
  <!-- List style: bullets + numbering -->
145035
145402
  <div class="pptx-rb-grp">
145036
145403
  <button
145037
145404
  type="button"
145038
145405
  class="pptx-rb-gb"
145039
- [disabled]="!isText()"
145040
- [ngClass]="curStyle()?.listType === 'bullet' ? 'bg-accent' : ''"
145406
+ [disabled]="!canEdit() || !isText()"
145407
+ [ngClass]="listKind() === 'bullet' ? 'bg-accent' : ''"
145408
+ [attr.aria-pressed]="listKind() === 'bullet'"
145041
145409
  [title]="'pptx.ribbon.bulletList' | translate"
145042
145410
  (click)="toggleList('bullet')"
145043
145411
  >
@@ -145046,8 +145414,9 @@ class RibbonParagraphControlsComponent {
145046
145414
  <button
145047
145415
  type="button"
145048
145416
  class="pptx-rb-gl"
145049
- [disabled]="!isText()"
145050
- [ngClass]="curStyle()?.listType === 'numbered' ? 'bg-accent' : ''"
145417
+ [disabled]="!canEdit() || !isText()"
145418
+ [ngClass]="listKind() === 'numbered' ? 'bg-accent' : ''"
145419
+ [attr.aria-pressed]="listKind() === 'numbered'"
145051
145420
  [title]="'pptx.notes.numberedList' | translate"
145052
145421
  (click)="toggleList('numbered')"
145053
145422
  >
@@ -145180,8 +145549,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
145180
145549
  <button
145181
145550
  type="button"
145182
145551
  class="pptx-rb-gb"
145183
- [disabled]="!isText()"
145184
- [ngClass]="curStyle()?.listType === 'bullet' ? 'bg-accent' : ''"
145552
+ [disabled]="!canEdit() || !isText()"
145553
+ [ngClass]="listKind() === 'bullet' ? 'bg-accent' : ''"
145554
+ [attr.aria-pressed]="listKind() === 'bullet'"
145185
145555
  [title]="'pptx.ribbon.bulletList' | translate"
145186
145556
  (click)="toggleList('bullet')"
145187
145557
  >
@@ -145190,8 +145560,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
145190
145560
  <button
145191
145561
  type="button"
145192
145562
  class="pptx-rb-gl"
145193
- [disabled]="!isText()"
145194
- [ngClass]="curStyle()?.listType === 'numbered' ? 'bg-accent' : ''"
145563
+ [disabled]="!canEdit() || !isText()"
145564
+ [ngClass]="listKind() === 'numbered' ? 'bg-accent' : ''"
145565
+ [attr.aria-pressed]="listKind() === 'numbered'"
145195
145566
  [title]="'pptx.notes.numberedList' | translate"
145196
145567
  (click)="toggleList('numbered')"
145197
145568
  >
@@ -145299,7 +145670,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
145299
145670
  </select>
145300
145671
  `,
145301
145672
  }]
145302
- }], propDecorators: { slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }], selectedElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedElement", required: false }] }] } });
145673
+ }], propDecorators: { slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }], selectedElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedElement", required: false }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }] } });
145303
145674
 
145304
145675
  /**
145305
145676
  * ribbon-home-section.component.ts: the Home ribbon tab (Clipboard, Slides, Font
@@ -145596,6 +145967,7 @@ class RibbonHomeSectionComponent {
145596
145967
  <div class="flex flex-col items-center gap-0.5">
145597
145968
  <div class="flex items-center gap-1">
145598
145969
  <pptx-ribbon-paragraph-controls
145970
+ [canEdit]="canEdit()"
145599
145971
  [slideIndex]="slideIndex()"
145600
145972
  [selectedElement]="selectedElement()"
145601
145973
  />
@@ -145615,7 +145987,7 @@ class RibbonHomeSectionComponent {
145615
145987
  {{ 'pptx.shortcuts.group.editing' | translate }}
145616
145988
  </span>
145617
145989
  </div>
145618
- `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: RibbonLayoutGalleryComponent, selector: "pptx-ribbon-layout-gallery", inputs: ["layoutOptions", "previews", "currentLayoutPath", "disabled"], outputs: ["select"] }, { kind: "component", type: LucidePlus, selector: "svg[lucidePlus]" }, { kind: "component", type: LucideChevronDown, selector: "svg[lucideChevronDown]" }, { kind: "component", type: LucideClipboardPaste, selector: "svg[lucideClipboardPaste]" }, { kind: "component", type: LucideCopy, selector: "svg[lucideCopy]" }, { kind: "component", type: LucideFolderPlus, selector: "svg[lucideFolderPlus]" }, { kind: "component", type: LucideLayoutGrid, selector: "svg[lucideLayoutGrid]" }, { kind: "component", type: LucideLayoutTemplate, selector: "svg[lucideLayoutTemplate]" }, { kind: "component", type: LucidePaintbrush, selector: "svg[lucidePaintbrush]" }, { kind: "component", type: LucideRotateCcw, selector: "svg[lucideRotateCcw]" }, { kind: "component", type: LucideScissors, selector: "svg[lucideScissors]" }, { kind: "component", type: RibbonFontControlsComponent, selector: "pptx-ribbon-font-controls", inputs: ["slideIndex", "selectedElement"] }, { kind: "component", type: RibbonParagraphControlsComponent, selector: "pptx-ribbon-paragraph-controls", inputs: ["slideIndex", "selectedElement"] }, { kind: "component", type: RibbonEditingSectionComponent, selector: "pptx-ribbon-editing-section", outputs: ["toggleFindReplace", "selectAll"] }, { kind: "directive", type: AnchoredPopupDirective, selector: "[pptxAnchoredPopup]", inputs: ["pptxAnchoredPopup", "pptxAnchoredPopupAlignRight"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
145990
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: RibbonLayoutGalleryComponent, selector: "pptx-ribbon-layout-gallery", inputs: ["layoutOptions", "previews", "currentLayoutPath", "disabled"], outputs: ["select"] }, { kind: "component", type: LucidePlus, selector: "svg[lucidePlus]" }, { kind: "component", type: LucideChevronDown, selector: "svg[lucideChevronDown]" }, { kind: "component", type: LucideClipboardPaste, selector: "svg[lucideClipboardPaste]" }, { kind: "component", type: LucideCopy, selector: "svg[lucideCopy]" }, { kind: "component", type: LucideFolderPlus, selector: "svg[lucideFolderPlus]" }, { kind: "component", type: LucideLayoutGrid, selector: "svg[lucideLayoutGrid]" }, { kind: "component", type: LucideLayoutTemplate, selector: "svg[lucideLayoutTemplate]" }, { kind: "component", type: LucidePaintbrush, selector: "svg[lucidePaintbrush]" }, { kind: "component", type: LucideRotateCcw, selector: "svg[lucideRotateCcw]" }, { kind: "component", type: LucideScissors, selector: "svg[lucideScissors]" }, { kind: "component", type: RibbonFontControlsComponent, selector: "pptx-ribbon-font-controls", inputs: ["slideIndex", "selectedElement"] }, { kind: "component", type: RibbonParagraphControlsComponent, selector: "pptx-ribbon-paragraph-controls", inputs: ["slideIndex", "selectedElement", "canEdit"] }, { kind: "component", type: RibbonEditingSectionComponent, selector: "pptx-ribbon-editing-section", outputs: ["toggleFindReplace", "selectAll"] }, { kind: "directive", type: AnchoredPopupDirective, selector: "[pptxAnchoredPopup]", inputs: ["pptxAnchoredPopup", "pptxAnchoredPopupAlignRight"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
145619
145991
  }
145620
145992
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RibbonHomeSectionComponent, decorators: [{
145621
145993
  type: Component,
@@ -145831,6 +146203,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
145831
146203
  <div class="flex flex-col items-center gap-0.5">
145832
146204
  <div class="flex items-center gap-1">
145833
146205
  <pptx-ribbon-paragraph-controls
146206
+ [canEdit]="canEdit()"
145834
146207
  [slideIndex]="slideIndex()"
145835
146208
  [selectedElement]="selectedElement()"
145836
146209
  />
@@ -147064,6 +147437,7 @@ class RibbonContentComponent {
147064
147437
  />
147065
147438
  <span class="pptx-rb-sep"></span>
147066
147439
  <pptx-ribbon-paragraph-controls
147440
+ [canEdit]="canEdit()"
147067
147441
  [slideIndex]="slideIndex()"
147068
147442
  [selectedElement]="selectedElement()"
147069
147443
  />
@@ -147079,7 +147453,7 @@ class RibbonContentComponent {
147079
147453
  />
147080
147454
  }
147081
147455
  }
147082
- `, isInline: true, dependencies: [{ kind: "component", type: RibbonFileSectionComponent, selector: "pptx-ribbon-file-section", inputs: ["fileName", "slideCount", "exporting", "hasMacros", "hiddenActions", "recentPresentationsCount", "accountAuth"], outputs: ["close", "createPresentation", "openFile", "openRecentFile", "save", "savePpsx", "savePptm", "savePpt", "exportPng", "exportPdf", "exportGif", "exportVideo", "exportJson", "copySlideAsImage", "print", "info", "signatures", "replace", "openPassword", "openFontEmbedding", "openVersionHistory", "share", "options"] }, { kind: "component", type: RibbonHomeSectionComponent, selector: "pptx-ribbon-home-section", inputs: ["slideIndex", "selectedElement", "canEdit", "formatPainterActive", "canActivateFormatPainter"], outputs: ["toggleFormatPainter", "findReplace", "openTemplateGallery", "applyLayout", "resetSlide"] }, { kind: "component", type: RibbonInsertSectionComponent, selector: "pptx-ribbon-insert-section", inputs: ["slideIndex", "newChartType", "newShapeType"], outputs: ["openSmartArtDialog", "openEquationDialog", "openHyperlink", "chartTypeChange", "shapeTypeChange"] }, { kind: "component", type: RibbonFontControlsComponent, selector: "pptx-ribbon-font-controls", inputs: ["slideIndex", "selectedElement"] }, { kind: "component", type: RibbonParagraphControlsComponent, selector: "pptx-ribbon-paragraph-controls", inputs: ["slideIndex", "selectedElement"] }, { kind: "component", type: RibbonArrangeSectionComponent, selector: "pptx-ribbon-arrange-section", inputs: ["slideIndex", "selectedElement", "canEdit", "formatPainterActive", "canActivateFormatPainter"], outputs: ["toggleFormatPainter"] }, { kind: "component", type: RibbonDrawingGroupComponent, selector: "pptx-ribbon-drawing-group", inputs: ["canEdit", "slideIndex", "selectedElement"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
147456
+ `, isInline: true, dependencies: [{ kind: "component", type: RibbonFileSectionComponent, selector: "pptx-ribbon-file-section", inputs: ["fileName", "slideCount", "exporting", "hasMacros", "hiddenActions", "recentPresentationsCount", "accountAuth"], outputs: ["close", "createPresentation", "openFile", "openRecentFile", "save", "savePpsx", "savePptm", "savePpt", "exportPng", "exportPdf", "exportGif", "exportVideo", "exportJson", "copySlideAsImage", "print", "info", "signatures", "replace", "openPassword", "openFontEmbedding", "openVersionHistory", "share", "options"] }, { kind: "component", type: RibbonHomeSectionComponent, selector: "pptx-ribbon-home-section", inputs: ["slideIndex", "selectedElement", "canEdit", "formatPainterActive", "canActivateFormatPainter"], outputs: ["toggleFormatPainter", "findReplace", "openTemplateGallery", "applyLayout", "resetSlide"] }, { kind: "component", type: RibbonInsertSectionComponent, selector: "pptx-ribbon-insert-section", inputs: ["slideIndex", "newChartType", "newShapeType"], outputs: ["openSmartArtDialog", "openEquationDialog", "openHyperlink", "chartTypeChange", "shapeTypeChange"] }, { kind: "component", type: RibbonFontControlsComponent, selector: "pptx-ribbon-font-controls", inputs: ["slideIndex", "selectedElement"] }, { kind: "component", type: RibbonParagraphControlsComponent, selector: "pptx-ribbon-paragraph-controls", inputs: ["slideIndex", "selectedElement", "canEdit"] }, { kind: "component", type: RibbonArrangeSectionComponent, selector: "pptx-ribbon-arrange-section", inputs: ["slideIndex", "selectedElement", "canEdit", "formatPainterActive", "canActivateFormatPainter"], outputs: ["toggleFormatPainter"] }, { kind: "component", type: RibbonDrawingGroupComponent, selector: "pptx-ribbon-drawing-group", inputs: ["canEdit", "slideIndex", "selectedElement"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
147083
147457
  }
147084
147458
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RibbonContentComponent, decorators: [{
147085
147459
  type: Component,
@@ -147182,6 +147556,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
147182
147556
  />
147183
147557
  <span class="pptx-rb-sep"></span>
147184
147558
  <pptx-ribbon-paragraph-controls
147559
+ [canEdit]="canEdit()"
147185
147560
  [slideIndex]="slideIndex()"
147186
147561
  [selectedElement]="selectedElement()"
147187
147562
  />
@@ -168580,7 +168955,7 @@ class SlideSorterOverlayComponent {
168580
168955
  return hiddenSlideCue(this.isHiddenSlide(slide), 'sorter', index);
168581
168956
  }
168582
168957
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SlideSorterOverlayComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
168583
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: SlideSorterOverlayComponent, isStandalone: true, selector: "pptx-slide-sorter-overlay", inputs: { slides: { classPropertyName: "slides", publicName: "slides", isSignal: true, isRequired: true, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { select: "select", closed: "closed", deleteSlide: "deleteSlide", duplicateSlide: "duplicateSlide", toggleHiddenSlide: "toggleHiddenSlide" }, host: { listeners: { "document:keydown": "onKeydown($event)" } }, ngImport: i0, template: "<!-- Backdrop -->\n<div class=\"pptx-ng-sorter-backdrop\" (click)=\"onBackdropClick($event)\">\n\t<!-- Modal panel -->\n\t<div class=\"pptx-ng-sorter-panel\" (click)=\"$event.stopPropagation()\">\n\t\t<!-- Header -->\n\t\t<header class=\"pptx-ng-sorter-header\">\n\t\t\t<h2 class=\"pptx-ng-sorter-title\">{{ 'pptx.slideSorter.title' | translate }}</h2>\n\t\t\t<span class=\"pptx-ng-sorter-count\">{{\n\t\t\t\t'pptx.slideSorter.slideCount' | translate: { count: slides().length }\n\t\t\t}}</span>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"pptx-ng-sorter-close\"\n\t\t\t\t[attr.aria-label]=\"'pptx.slideSorter.close' | translate\"\n\t\t\t\t(click)=\"closed.emit()\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\t\twidth=\"16\"\n\t\t\t\t\theight=\"16\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t>\n\t\t\t\t\t<line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n\t\t\t\t\t<line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n\t\t\t\t</svg>\n\t\t\t</button>\n\t\t</header>\n\n\t\t<!-- Scrollable grid -->\n\t\t<div class=\"pptx-ng-sorter-grid-scroll\">\n\t\t\t<div class=\"pptx-ng-sorter-grid\" [ngStyle]=\"gridStyle()\">\n\t\t\t\t@for (slide of slides(); track slide.id; let i = $index) {\n\t\t\t\t\t@let hidden = hiddenCue(slide, i);\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"pptx-ng-sorter-cell\"\n\t\t\t\t\t\t[class.is-active]=\"i === activeIndex()\"\n\t\t\t\t\t\t[class.is-hidden]=\"hidden.hidden\"\n\t\t\t\t\t\t[attr.data-pptx-slide-hidden]=\"hidden.marker ?? null\"\n\t\t\t\t\t\t[attr.aria-label]=\"'pptx.notes.slideN' | translate: { n: i + 1 }\"\n\t\t\t\t\t\t[attr.aria-describedby]=\"hidden.labelId ?? null\"\n\t\t\t\t\t\t[attr.aria-current]=\"i === activeIndex() ? 'true' : null\"\n\t\t\t\t\t\t(click)=\"onThumbClick(i)\"\n\t\t\t\t\t\t(contextmenu)=\"onThumbContextMenu($event, i)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<!-- Thumbnail clipping wrapper -->\n\t\t\t\t\t\t<div class=\"pptx-ng-sorter-thumb-clip\" [ngStyle]=\"clipStyle()\">\n\t\t\t\t\t\t\t<pptx-slide-canvas\n\t\t\t\t\t\t\t\t[slide]=\"slide\"\n\t\t\t\t\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t\t\t\t[zoom]=\"thumbZoom()\"\n\t\t\t\t\t\t\t\t[autoFit]=\"false\"\n\t\t\t\t\t\t\t\t[interactive]=\"false\"\n\t\t\t\t\t\t\t\t[exposeElementIds]=\"false\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<!-- Slide number badge, struck through with the shared diagonal\n\t\t\t\t\t\t slash when hidden (PowerPoint's own cue). -->\n\t\t\t\t\t\t<span\n\t\t\t\t\t\t\tclass=\"pptx-ng-sorter-index\"\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t[style.background-image]=\"hidden.hidden ? slashGradient : null\"\n\t\t\t\t\t\t\t>{{ i + 1 }}</span\n\t\t\t\t\t\t>\n\t\t\t\t\t\t@if (hidden.hidden) {\n\t\t\t\t\t\t\t<span class=\"pptx-ng-sorter-hidden\" [id]=\"hidden.labelId\">{{\n\t\t\t\t\t\t\t\thiddenLabelKey | translate\n\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t</div>\n\t</div>\n\n\t@if (contextMenu(); as menu) {\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-sorter-menu-backdrop\"\n\t\t\t[attr.aria-label]=\"'pptx.overflow.closeMenu' | translate\"\n\t\t\t(click)=\"closeContextMenu()\"\n\t\t\t(contextmenu)=\"$event.preventDefault(); closeContextMenu()\"\n\t\t></button>\n\t\t<div\n\t\t\tclass=\"pptx-ng-sorter-context-menu\"\n\t\t\t[style.left.px]=\"menu.x\"\n\t\t\t[style.top.px]=\"menu.y\"\n\t\t\trole=\"menu\"\n\t\t>\n\t\t\t<button type=\"button\" role=\"menuitem\" (click)=\"menuDuplicate()\">\n\t\t\t\t{{ 'pptx.slideMenu.duplicate' | translate }}\n\t\t\t</button>\n\t\t\t<button type=\"button\" role=\"menuitem\" (click)=\"menuToggleHidden()\">\n\t\t\t\t{{\n\t\t\t\t\t(contextMenuTargetHidden() ? 'pptx.slideMenu.show' : 'pptx.slideMenu.hide') | translate\n\t\t\t\t}}\n\t\t\t</button>\n\t\t\t<div class=\"pptx-ng-sorter-context-menu-sep\"></div>\n\t\t\t<button type=\"button\" role=\"menuitem\" class=\"is-danger\" (click)=\"menuDelete()\">\n\t\t\t\t{{ 'pptx.slideMenu.delete' | translate }}\n\t\t\t</button>\n\t\t</div>\n\t}\n</div>\n", styles: [":host{display:contents}.pptx-ng-sorter-backdrop{position:fixed;inset:0;z-index:50;display:flex;align-items:center;justify-content:center;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.pptx-ng-sorter-panel{display:flex;flex-direction:column;width:min(96vw,1200px);max-height:90vh;border-radius:.5rem;background:#1a1a1a;color:#e5e5e5;box-shadow:0 24px 64px #0009;overflow:hidden}.pptx-ng-sorter-header{display:flex;align-items:center;gap:.75rem;padding:.75rem 1.25rem;border-bottom:1px solid rgba(255,255,255,.1);flex-shrink:0}.pptx-ng-sorter-title{margin:0;font-size:.875rem;font-weight:500}.pptx-ng-sorter-count{font-size:.75rem;color:#ffffff80;flex:1}.pptx-ng-sorter-close{display:flex;align-items:center;justify-content:center;width:44px;height:44px;min-width:44px;min-height:44px;padding:0;border:none;border-radius:50%;background:#ffffff1a;color:#e5e5e5;cursor:pointer;transition:background .15s;flex-shrink:0;touch-action:manipulation}.pptx-ng-sorter-close:hover{background:#fff3}.pptx-ng-sorter-grid-scroll{flex:1;overflow-y:auto;padding:1.25rem}.pptx-ng-sorter-grid{display:grid;gap:1rem}.pptx-ng-sorter-cell{display:flex;flex-direction:column;align-items:center;gap:.5rem;padding:.5rem;border:2px solid transparent;border-radius:.375rem;background:transparent;cursor:pointer;transition:border-color .15s,background .15s;color:inherit}.pptx-ng-sorter-cell:hover{background:#ffffff0f;border-color:#fff3}.pptx-ng-sorter-cell.is-active{border-color:#3b82f6;background:#3b82f61a}.pptx-ng-sorter-cell.is-hidden{opacity:.4}.pptx-ng-sorter-thumb-clip{overflow:hidden;border-radius:2px}.pptx-ng-sorter-thumb-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}.pptx-ng-sorter-index{display:inline-block;padding:0 .2rem;font-size:.6875rem;color:#ffffff8c;-webkit-user-select:none;user-select:none}.pptx-ng-sorter-hidden{font-size:.5625rem;text-transform:uppercase;letter-spacing:.05em;color:#ffffff8c;-webkit-user-select:none;user-select:none}.pptx-ng-sorter-menu-backdrop{position:fixed;inset:0;z-index:59;border:none;padding:0;background:transparent;cursor:default}.pptx-ng-sorter-context-menu{position:fixed;z-index:60;min-width:160px;padding:.25rem;border:1px solid rgba(255,255,255,.12);border-radius:.375rem;background:#1a1a1a;color:#e5e5e5;box-shadow:0 8px 24px #00000080}.pptx-ng-sorter-context-menu button{display:block;width:100%;padding:.375rem .625rem;border:none;border-radius:.25rem;background:transparent;color:inherit;text-align:left;font-size:.75rem;cursor:pointer}.pptx-ng-sorter-context-menu button:hover{background:#ffffff14}.pptx-ng-sorter-context-menu button.is-danger{color:#f87171}.pptx-ng-sorter-context-menu-sep{margin:.25rem .125rem;border-top:1px solid rgba(255,255,255,.12)}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
168958
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: SlideSorterOverlayComponent, isStandalone: true, selector: "pptx-slide-sorter-overlay", inputs: { slides: { classPropertyName: "slides", publicName: "slides", isSignal: true, isRequired: true, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { select: "select", closed: "closed", deleteSlide: "deleteSlide", duplicateSlide: "duplicateSlide", toggleHiddenSlide: "toggleHiddenSlide" }, host: { listeners: { "document:keydown": "onKeydown($event)" } }, ngImport: i0, template: "<!-- Backdrop -->\n<div class=\"pptx-ng-sorter-backdrop\" (click)=\"onBackdropClick($event)\">\n\t<!-- Modal panel -->\n\t<div class=\"pptx-ng-sorter-panel\" (click)=\"$event.stopPropagation()\">\n\t\t<!-- Header -->\n\t\t<header class=\"pptx-ng-sorter-header\">\n\t\t\t<h2 class=\"pptx-ng-sorter-title\">{{ 'pptx.slideSorter.title' | translate }}</h2>\n\t\t\t<span class=\"pptx-ng-sorter-count\">{{\n\t\t\t\t'pptx.slideSorter.slideCount' | translate: { count: slides().length }\n\t\t\t}}</span>\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"pptx-ng-sorter-close\"\n\t\t\t\t[attr.aria-label]=\"'pptx.slideSorter.close' | translate\"\n\t\t\t\t(click)=\"closed.emit()\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\t\t\twidth=\"16\"\n\t\t\t\t\theight=\"16\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t>\n\t\t\t\t\t<line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n\t\t\t\t\t<line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n\t\t\t\t</svg>\n\t\t\t</button>\n\t\t</header>\n\n\t\t<!-- Scrollable grid -->\n\t\t<div class=\"pptx-ng-sorter-grid-scroll\">\n\t\t\t<div class=\"pptx-ng-sorter-grid\" [ngStyle]=\"gridStyle()\">\n\t\t\t\t@for (slide of slides(); track slide.id; let i = $index) {\n\t\t\t\t\t@let hidden = hiddenCue(slide, i);\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclass=\"pptx-ng-sorter-cell\"\n\t\t\t\t\t\t[class.is-active]=\"i === activeIndex()\"\n\t\t\t\t\t\t[class.is-hidden]=\"hidden.hidden\"\n\t\t\t\t\t\t[attr.data-pptx-slide-hidden]=\"hidden.marker ?? null\"\n\t\t\t\t\t\t[attr.aria-label]=\"'pptx.notes.slideN' | translate: { n: i + 1 }\"\n\t\t\t\t\t\t[attr.aria-describedby]=\"hidden.labelId ?? null\"\n\t\t\t\t\t\t[attr.aria-current]=\"i === activeIndex() ? 'true' : null\"\n\t\t\t\t\t\t(click)=\"onThumbClick(i)\"\n\t\t\t\t\t\t(contextmenu)=\"onThumbContextMenu($event, i)\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<!-- Thumbnail clipping wrapper -->\n\t\t\t\t\t\t<div class=\"pptx-ng-sorter-thumb-clip\" [ngStyle]=\"clipStyle()\">\n\t\t\t\t\t\t\t<pptx-slide-canvas\n\t\t\t\t\t\t\t\t[slide]=\"slide\"\n\t\t\t\t\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t\t\t\t[zoom]=\"thumbZoom()\"\n\t\t\t\t\t\t\t\t[autoFit]=\"false\"\n\t\t\t\t\t\t\t\t[interactive]=\"false\"\n\t\t\t\t\t\t\t\t[exposeElementIds]=\"false\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<!-- Slide number badge, struck through with the shared diagonal\n\t\t\t\t\t\t slash when hidden (PowerPoint's own cue). -->\n\t\t\t\t\t\t<span\n\t\t\t\t\t\t\tclass=\"pptx-ng-sorter-index\"\n\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t[style.background-image]=\"hidden.hidden ? slashGradient : null\"\n\t\t\t\t\t\t\t>{{ i + 1 }}</span\n\t\t\t\t\t\t>\n\t\t\t\t\t\t@if (hidden.hidden) {\n\t\t\t\t\t\t\t<span class=\"pptx-ng-sorter-hidden\" [id]=\"hidden.labelId\">{{\n\t\t\t\t\t\t\t\thiddenLabelKey | translate\n\t\t\t\t\t\t\t}}</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t</button>\n\t\t\t\t}\n\t\t\t</div>\n\t\t</div>\n\t</div>\n\n\t@if (contextMenu(); as menu) {\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-sorter-menu-backdrop\"\n\t\t\t[attr.aria-label]=\"'pptx.overflow.closeMenu' | translate\"\n\t\t\t(click)=\"closeContextMenu()\"\n\t\t\t(contextmenu)=\"$event.preventDefault(); closeContextMenu()\"\n\t\t></button>\n\t\t<div\n\t\t\tclass=\"pptx-ng-sorter-context-menu\"\n\t\t\t[style.left.px]=\"menu.x\"\n\t\t\t[style.top.px]=\"menu.y\"\n\t\t\trole=\"menu\"\n\t\t>\n\t\t\t<button type=\"button\" role=\"menuitem\" (click)=\"menuDuplicate()\">\n\t\t\t\t{{ 'pptx.slideMenu.duplicate' | translate }}\n\t\t\t</button>\n\t\t\t<button type=\"button\" role=\"menuitem\" (click)=\"menuToggleHidden()\">\n\t\t\t\t{{\n\t\t\t\t\t(contextMenuTargetHidden() ? 'pptx.slideMenu.show' : 'pptx.slideMenu.hide') | translate\n\t\t\t\t}}\n\t\t\t</button>\n\t\t\t<div class=\"pptx-ng-sorter-context-menu-sep\"></div>\n\t\t\t<button type=\"button\" role=\"menuitem\" class=\"is-danger\" (click)=\"menuDelete()\">\n\t\t\t\t{{ 'pptx.slideMenu.delete' | translate }}\n\t\t\t</button>\n\t\t</div>\n\t}\n</div>\n", styles: [":host{display:contents}.pptx-ng-sorter-backdrop{position:fixed;inset:0;z-index:50;display:flex;align-items:center;justify-content:center;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.pptx-ng-sorter-panel{display:flex;flex-direction:column;width:min(96vw,1200px);max-height:90vh;border-radius:.5rem;background:#1a1a1a;color:#e5e5e5;box-shadow:0 24px 64px #0009;overflow:hidden}.pptx-ng-sorter-header{display:flex;align-items:center;gap:.75rem;padding:.75rem 1.25rem;border-bottom:1px solid rgba(255,255,255,.1);flex-shrink:0}.pptx-ng-sorter-title{margin:0;font-size:.875rem;font-weight:500}.pptx-ng-sorter-count{font-size:.75rem;color:#ffffff80;flex:1}.pptx-ng-sorter-close{display:flex;align-items:center;justify-content:center;width:44px;height:44px;min-width:44px;min-height:44px;padding:0;border:none;border-radius:50%;background:#ffffff1a;color:#e5e5e5;cursor:pointer;transition:background .15s;flex-shrink:0;touch-action:manipulation}.pptx-ng-sorter-close:hover{background:#fff3}.pptx-ng-sorter-grid-scroll{flex:1;overflow-y:auto;padding:1.25rem}.pptx-ng-sorter-grid{display:grid;gap:1rem}.pptx-ng-sorter-cell{display:flex;flex-direction:column;align-items:center;gap:.5rem;padding:.5rem;border:2px solid transparent;border-radius:.375rem;background:transparent;cursor:pointer;transition:border-color .15s,background .15s;color:inherit}.pptx-ng-sorter-cell:hover{background:#ffffff0f;border-color:#fff3}.pptx-ng-sorter-cell.is-active{border-color:#3b82f6;background:#3b82f61a}.pptx-ng-sorter-cell.is-hidden{opacity:.4}.pptx-ng-sorter-thumb-clip{overflow:hidden;border-radius:2px}.pptx-ng-sorter-thumb-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}.pptx-ng-sorter-index{display:inline-block;padding:0 .2rem;font-size:.6875rem;color:#ffffff8c;-webkit-user-select:none;user-select:none}.pptx-ng-sorter-hidden{font-size:.5625rem;text-transform:uppercase;letter-spacing:.05em;color:#ffffff8c;-webkit-user-select:none;user-select:none}.pptx-ng-sorter-menu-backdrop{position:fixed;inset:0;z-index:59;border:none;padding:0;background:transparent;cursor:default}.pptx-ng-sorter-context-menu{position:fixed;z-index:60;min-width:160px;padding:.25rem;border:1px solid rgba(255,255,255,.12);border-radius:.375rem;background:#1a1a1a;color:#e5e5e5;box-shadow:0 8px 24px #00000080}.pptx-ng-sorter-context-menu button{display:block;width:100%;padding:.375rem .625rem;border:none;border-radius:.25rem;background:transparent;color:inherit;text-align:left;font-size:.75rem;cursor:pointer}.pptx-ng-sorter-context-menu button:hover{background:#ffffff14}.pptx-ng-sorter-context-menu button.is-danger{color:#f87171}.pptx-ng-sorter-context-menu-sep{margin:.25rem .125rem;border-top:1px solid rgba(255,255,255,.12)}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
168584
168959
  }
168585
168960
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SlideSorterOverlayComponent, decorators: [{
168586
168961
  type: Component,
@@ -169001,7 +169376,7 @@ class SlidesPanelComponent {
169001
169376
  return hiddenSlideCue(slide.hidden, 'rail', index);
169002
169377
  }
169003
169378
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SlidesPanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
169004
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: SlidesPanelComponent, isStandalone: true, selector: "pptx-slides-panel", inputs: { canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { select: "select" }, viewQueries: [{ propertyName: "scrollViewport", first: true, predicate: ["scrollViewport"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"pptx-ng-spanel\">\n\t<!-- Scrollable slide list -->\n\t<div\n\t\t#scrollViewport\n\t\tclass=\"pptx-ng-spanel-scroll\"\n\t\trole=\"listbox\"\n\t\t[attr.aria-label]=\"'pptx.sections.slides' | translate\"\n\t\t(scroll)=\"onScroll()\"\n\t>\n\t\t<div\n\t\t\tclass=\"pptx-ng-spanel-space\"\n\t\t\t[attr.data-virtualized]=\"shouldVirtualize() ? 'true' : null\"\n\t\t\t[style.height.px]=\"shouldVirtualize() ? virtualRange().totalHeight : null\"\n\t\t>\n\t\t\t<div\n\t\t\t\tclass=\"pptx-ng-spanel-window\"\n\t\t\t\t[class.is-virtualized]=\"shouldVirtualize()\"\n\t\t\t\t[style.top.px]=\"shouldVirtualize() ? virtualRange().offsetY : null\"\n\t\t\t>\n\t\t\t\t@for (item of renderedSlides(); track item.slide.id) {\n\t\t\t\t\t@let slide = item.slide;\n\t\t\t\t\t@let i = item.index;\n\t\t\t\t\t@let hidden = hiddenCue(slide, i);\n\t\t\t\t\t@if (item.sectionStart) {\n\t\t\t\t\t\t<header class=\"pptx-ng-section-header\" [attr.data-section-id]=\"item.section?.id\">\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-section-toggle\"\n\t\t\t\t\t\t\t\t[attr.aria-expanded]=\"!item.section?.collapsed\"\n\t\t\t\t\t\t\t\t(click)=\"item.section && editor.sectionOps.toggle(item.section.id)\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span>{{ item.section?.collapsed ? '\u25B8' : '\u25BE' }}</span>\n\t\t\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t\t\tSection highlight colour (p15:sectionPr/@clr). Core parses and\n\t\t\t\t\t\t\t\t\tround-trips it; only React was drawing it.\n\t\t\t\t\t\t\t\t-->\n\t\t\t\t\t\t\t\t@if (item.section?.color; as sectionColor) {\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-section-swatch\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-section-color\n\t\t\t\t\t\t\t\t\t\t[style.background-color]=\"sectionColor\"\n\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t<strong>{{\n\t\t\t\t\t\t\t\t\titem.section?.name ?? ('pptx.slides.ungroupedSlides' | translate)\n\t\t\t\t\t\t\t\t}}</strong>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t@if (item.section) {\n\t\t\t\t\t\t\t\t<div class=\"pptx-ng-section-actions\">\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t\t(click)=\"onRenameSection(item.section.id, item.section.name)\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\u270E\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t\t[disabled]=\"sectionIndex(item.section.id) === 0\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"editor.sectionOps.move(item.section.id, 'up')\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\u2191\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t\t[disabled]=\"sectionIndex(item.section.id) === editor.sections().length - 1\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"editor.sectionOps.move(item.section.id, 'down')\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\u2193\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t\t(click)=\"editor.sectionOps.delete(item.section.id)\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\u00D7\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</header>\n\t\t\t\t\t}\n\t\t\t\t\t@if (!item.section?.collapsed) {\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-card\"\n\t\t\t\t\t\t\t[class.is-active]=\"i === activeIndex()\"\n\t\t\t\t\t\t\t[attr.data-pptx-slide-hidden]=\"hidden.marker ?? null\"\n\t\t\t\t\t\t\trole=\"option\"\n\t\t\t\t\t\t\t[attr.aria-selected]=\"i === activeIndex()\"\n\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.notes.slideN' | translate: { n: i + 1 }\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<!-- Thumbnail (clickable to select). Slide number sits to the LEFT\n\t\t\t\t\t\t\t of the preview (React SlideItem parity), not below it. -->\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-thumb-btn\"\n\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.slidesPanel.goToSlide' | translate: { n: i + 1 }\"\n\t\t\t\t\t\t\t\t[attr.aria-describedby]=\"hidden.labelId ?? null\"\n\t\t\t\t\t\t\t\t(click)=\"select.emit(i)\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<!-- Slide number badge (left column). Struck through with the shared\n\t\t\t\t\t\t\t\t diagonal slash when the slide is hidden, which is PowerPoint's own\n\t\t\t\t\t\t\t\t cue and, unlike the dimming, is not a colour-only signal. -->\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-num\"\n\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t[style.background-image]=\"hidden.hidden ? slashGradient : null\"\n\t\t\t\t\t\t\t\t\t>{{ i + 1 }}</span\n\t\t\t\t\t\t\t\t>\n\n\t\t\t\t\t\t\t\t<!-- Clipping wrapper: neutralises the 1rem auto margin from SlideCanvas -->\n\t\t\t\t\t\t\t\t<div class=\"pptx-ng-spanel-clip\" [ngStyle]=\"clipStyle()\">\n\t\t\t\t\t\t\t\t\t<pptx-slide-canvas\n\t\t\t\t\t\t\t\t\t\t[slide]=\"slide\"\n\t\t\t\t\t\t\t\t\t\t[templateElements]=\"editor.templateElementsBySlideId()[slide.id] ?? []\"\n\t\t\t\t\t\t\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t\t\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t\t\t\t\t\t[zoom]=\"thumbZoom()\"\n\t\t\t\t\t\t\t\t\t\t[editable]=\"false\"\n\t\t\t\t\t\t\t\t\t\t[autoFit]=\"false\"\n\t\t\t\t\t\t\t\t\t\t[interactive]=\"false\"\n\t\t\t\t\t\t\t\t\t\t[exposeElementIds]=\"false\"\n\t\t\t\t\t\t\t\t\t\t[style.opacity]=\"hidden.hidden ? dimOpacity : null\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t@if (hidden.hidden) {\n\t\t\t\t\t\t\t\t\t\t<!-- Announced through aria-describedby, so the accessible name\n\t\t\t\t\t\t\t\t\t\t stays exactly \"Go to slide {{ i + 1 }}\". -->\n\t\t\t\t\t\t\t\t\t\t<span class=\"pptx-ng-spanel-hidden\" [id]=\"hidden.labelId\">\n\t\t\t\t\t\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\t\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\t\t\t\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\t\t\t\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\t\t\t\t\t\td=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94\"\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\t\t\t\t\t\td=\"M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19\"\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t<path d=\"M14.12 14.12a3 3 0 1 1-4.24-4.24\" />\n\t\t\t\t\t\t\t\t\t\t\t\t<path d=\"M1 1l22 22\" />\n\t\t\t\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"pptx-ng-sr-only\">{{ hiddenLabelKey | translate }}</span>\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</button>\n\n\t\t\t\t\t\t\t<!-- Per-card action toolbar (visible on hover / focus-within) -->\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-actions\"\n\t\t\t\t\t\t\t\trole=\"toolbar\"\n\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.slideMenu.slideActions' | translate: { n: i + 1 }\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-action\"\n\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t[title]=\"'pptx.ribbon.duplicateSlide' | translate\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.arrange.duplicate' | translate\"\n\t\t\t\t\t\t\t\t\t(click)=\"onDuplicate(i)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<svg lucideCopy class=\"h-3.5 w-3.5\"></svg>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-action\"\n\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t[title]=\"'pptx.slidesPanel.deleteSlide' | translate\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.arrange.delete' | translate\"\n\t\t\t\t\t\t\t\t\t[disabled]=\"editor.slides().length <= 1\"\n\t\t\t\t\t\t\t\t\t(click)=\"onDelete(i)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<svg lucideTrash2 class=\"h-3.5 w-3.5\"></svg>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-action\"\n\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t[title]=\"'pptx.sections.moveUp' | translate\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.sections.moveUp' | translate\"\n\t\t\t\t\t\t\t\t\t[disabled]=\"i === 0\"\n\t\t\t\t\t\t\t\t\t(click)=\"onMoveUp(i)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<svg lucideArrowUp class=\"h-3.5 w-3.5\"></svg>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-action\"\n\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t[title]=\"'pptx.sections.moveDown' | translate\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.sections.moveDown' | translate\"\n\t\t\t\t\t\t\t\t\t[disabled]=\"i === editor.slides().length - 1\"\n\t\t\t\t\t\t\t\t\t(click)=\"onMoveDown(i)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<svg lucideArrowDown class=\"h-3.5 w-3.5\"></svg>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</div>\n\t\t</div>\n\t</div>\n\n\t<!-- Footer: add new slide -->\n\t<footer class=\"pptx-ng-spanel-footer\">\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-spanel-add\"\n\t\t\t[attr.aria-label]=\"'pptx.sections.addSlide' | translate\"\n\t\t\t(click)=\"onAddSlide()\"\n\t\t>\n\t\t\t<svg lucidePlus class=\"h-3.5 w-3.5\"></svg> {{ 'pptx.sections.addSlide' | translate }}\n\t\t</button>\n\t</footer>\n</div>\n", styles: [":host{display:flex;flex-direction:column;height:100%;overflow:hidden}.pptx-ng-spanel{display:flex;flex-direction:column;height:100%;background:var(--pptx-secondary, #1e1e1e);color:var(--pptx-foreground, #e5e5e5);border-right:1px solid var(--pptx-border, rgba(255, 255, 255, .08));overflow:hidden}.pptx-ng-spanel-scroll{flex:1;overflow-y:auto;padding:.5rem .375rem}.pptx-ng-spanel-space{position:relative}.pptx-ng-spanel-window{display:flex;flex-direction:column;gap:.375rem}.pptx-ng-spanel-window.is-virtualized{position:absolute;inset-inline:0}.pptx-ng-section-header{display:flex;align-items:center;gap:.2rem;min-height:1.75rem;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .58))}.pptx-ng-section-toggle{display:flex;align-items:center;gap:.35rem;min-width:0;flex:1;border:0;background:transparent;color:inherit;cursor:pointer;text-align:left}.pptx-ng-section-swatch{display:inline-block;flex:0 0 auto;width:.5rem;height:.5rem;border-radius:9999px}.pptx-ng-section-toggle strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.7rem}.pptx-ng-section-actions{display:flex}.pptx-ng-section-actions button{width:1.25rem;height:1.25rem;padding:0;border:0;border-radius:.2rem;background:transparent;color:inherit;cursor:pointer}.pptx-ng-section-actions button:hover:not(:disabled){background:color-mix(in srgb,var(--pptx-primary, #3b82f6) 35%,transparent);color:var(--pptx-foreground, #fff)}.pptx-ng-section-actions button:disabled{opacity:.3}.pptx-ng-spanel-card{position:relative;border-radius:.375rem;border:2px solid transparent;background:transparent;transition:border-color .15s,background .15s}.pptx-ng-spanel-card:hover,.pptx-ng-spanel-card:focus-within{background:color-mix(in srgb,var(--pptx-foreground, #fff) 5%,transparent);border-color:color-mix(in srgb,var(--pptx-foreground, #fff) 15%,transparent)}.pptx-ng-spanel-card.is-active{border-color:var(--pptx-primary, #3b82f6);background:color-mix(in srgb,var(--pptx-primary, #3b82f6) 10%,transparent)}.pptx-ng-spanel-thumb-btn{display:flex;align-items:center;gap:.25rem;width:100%;padding:.375rem;border:none;background:transparent;cursor:pointer;color:inherit;line-height:0}.pptx-ng-spanel-thumb-btn:focus-visible{outline:2px solid var(--pptx-ring, #3b82f6);outline-offset:2px;border-radius:.25rem}.pptx-ng-spanel-clip{position:relative;overflow:hidden;border-radius:2px}.pptx-ng-spanel-hidden{position:absolute;right:2px;bottom:2px;z-index:10;display:inline-flex;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .45))}.pptx-ng-spanel-hidden svg{width:.75rem;height:.75rem}.pptx-ng-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.pptx-ng-spanel-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}.pptx-ng-spanel-num{flex:0 0 auto;width:1.1rem;text-align:right;font-size:.625rem;line-height:1;font-variant-numeric:tabular-nums;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .45));-webkit-user-select:none;user-select:none}.pptx-ng-spanel-card.is-active .pptx-ng-spanel-num{color:var(--pptx-primary, #3b82f6);font-weight:500}.pptx-ng-spanel-actions{position:absolute;top:.25rem;right:.25rem;display:flex;flex-direction:column;gap:.125rem;opacity:0;pointer-events:none;transition:opacity .12s}.pptx-ng-spanel-card:hover .pptx-ng-spanel-actions,.pptx-ng-spanel-card:focus-within .pptx-ng-spanel-actions{opacity:1;pointer-events:auto}.pptx-ng-spanel-action{display:flex;align-items:center;justify-content:center;width:1.375rem;height:1.375rem;padding:0;border:none;border-radius:.25rem;background:color-mix(in srgb,var(--pptx-popover, #1e1e1e) 85%,transparent);color:var(--pptx-popover-foreground, #e5e5e5);font-size:.6875rem;cursor:pointer;transition:background .12s;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.pptx-ng-spanel-action:hover:not([disabled]){background:color-mix(in srgb,var(--pptx-primary, #3b82f6) 75%,transparent);color:var(--pptx-primary-foreground, #fff)}.pptx-ng-spanel-action[disabled]{opacity:.3;cursor:not-allowed}.pptx-ng-spanel-footer{flex-shrink:0;padding:.5rem .375rem;border-top:1px solid var(--pptx-border, rgba(255, 255, 255, .08))}.pptx-ng-spanel-add{display:flex;align-items:center;justify-content:center;gap:.25rem;width:100%;padding:.25rem .5rem;border:none;border-radius:.25rem;background:transparent;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .6));font-size:.6875rem;cursor:pointer;transition:background .15s,color .15s}.pptx-ng-spanel-add:hover{background:color-mix(in srgb,var(--pptx-foreground, #fff) 8%,transparent);color:var(--pptx-foreground, #e5e5e5)}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: LucideCopy, selector: "svg[lucideCopy]" }, { kind: "component", type: LucideTrash2, selector: "svg[lucideTrash], svg[lucideTrash2]" }, { kind: "component", type: LucideArrowUp, selector: "svg[lucideArrowUp]" }, { kind: "component", type: LucideArrowDown, selector: "svg[lucideArrowDown]" }, { kind: "component", type: LucidePlus, selector: "svg[lucidePlus]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
169379
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: SlidesPanelComponent, isStandalone: true, selector: "pptx-slides-panel", inputs: { canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: true, transformFunction: null }, mediaDataUrls: { classPropertyName: "mediaDataUrls", publicName: "mediaDataUrls", isSignal: true, isRequired: false, transformFunction: null }, activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { select: "select" }, viewQueries: [{ propertyName: "scrollViewport", first: true, predicate: ["scrollViewport"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"pptx-ng-spanel\">\n\t<!-- Scrollable slide list -->\n\t<div\n\t\t#scrollViewport\n\t\tclass=\"pptx-ng-spanel-scroll\"\n\t\trole=\"listbox\"\n\t\t[attr.aria-label]=\"'pptx.sections.slides' | translate\"\n\t\t(scroll)=\"onScroll()\"\n\t>\n\t\t<div\n\t\t\tclass=\"pptx-ng-spanel-space\"\n\t\t\t[attr.data-virtualized]=\"shouldVirtualize() ? 'true' : null\"\n\t\t\t[style.height.px]=\"shouldVirtualize() ? virtualRange().totalHeight : null\"\n\t\t>\n\t\t\t<div\n\t\t\t\tclass=\"pptx-ng-spanel-window\"\n\t\t\t\t[class.is-virtualized]=\"shouldVirtualize()\"\n\t\t\t\t[style.top.px]=\"shouldVirtualize() ? virtualRange().offsetY : null\"\n\t\t\t>\n\t\t\t\t@for (item of renderedSlides(); track item.slide.id) {\n\t\t\t\t\t@let slide = item.slide;\n\t\t\t\t\t@let i = item.index;\n\t\t\t\t\t@let hidden = hiddenCue(slide, i);\n\t\t\t\t\t@if (item.sectionStart) {\n\t\t\t\t\t\t<header class=\"pptx-ng-section-header\" [attr.data-section-id]=\"item.section?.id\">\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-section-toggle\"\n\t\t\t\t\t\t\t\t[attr.aria-expanded]=\"!item.section?.collapsed\"\n\t\t\t\t\t\t\t\t(click)=\"item.section && editor.sectionOps.toggle(item.section.id)\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span>{{ item.section?.collapsed ? '\u25B8' : '\u25BE' }}</span>\n\t\t\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t\t\tSection highlight colour (p15:sectionPr/@clr). Core parses and\n\t\t\t\t\t\t\t\t\tround-trips it; only React was drawing it.\n\t\t\t\t\t\t\t\t-->\n\t\t\t\t\t\t\t\t@if (item.section?.color; as sectionColor) {\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-section-swatch\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-section-color\n\t\t\t\t\t\t\t\t\t\t[style.background-color]=\"sectionColor\"\n\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t<strong>{{\n\t\t\t\t\t\t\t\t\titem.section?.name ?? ('pptx.slides.ungroupedSlides' | translate)\n\t\t\t\t\t\t\t\t}}</strong>\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t@if (item.section) {\n\t\t\t\t\t\t\t\t<div class=\"pptx-ng-section-actions\">\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t\t(click)=\"onRenameSection(item.section.id, item.section.name)\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\u270E\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t\t[disabled]=\"sectionIndex(item.section.id) === 0\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"editor.sectionOps.move(item.section.id, 'up')\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\u2191\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t\t[disabled]=\"sectionIndex(item.section.id) === editor.sections().length - 1\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"editor.sectionOps.move(item.section.id, 'down')\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\u2193\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t\t(click)=\"editor.sectionOps.delete(item.section.id)\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\u00D7\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t</header>\n\t\t\t\t\t}\n\t\t\t\t\t@if (!item.section?.collapsed) {\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-card\"\n\t\t\t\t\t\t\t[class.is-active]=\"i === activeIndex()\"\n\t\t\t\t\t\t\t[attr.data-pptx-slide-hidden]=\"hidden.marker ?? null\"\n\t\t\t\t\t\t\trole=\"option\"\n\t\t\t\t\t\t\t[attr.aria-selected]=\"i === activeIndex()\"\n\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.notes.slideN' | translate: { n: i + 1 }\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<!-- Thumbnail (clickable to select). Slide number sits to the LEFT\n\t\t\t\t\t\t\t of the preview (React SlideItem parity), not below it. -->\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-thumb-btn\"\n\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.slidesPanel.goToSlide' | translate: { n: i + 1 }\"\n\t\t\t\t\t\t\t\t[attr.aria-describedby]=\"hidden.labelId ?? null\"\n\t\t\t\t\t\t\t\t(click)=\"select.emit(i)\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<!-- Slide number badge (left column). Struck through with the shared\n\t\t\t\t\t\t\t\t diagonal slash when the slide is hidden, which is PowerPoint's own\n\t\t\t\t\t\t\t\t cue and, unlike the dimming, is not a colour-only signal. -->\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-num\"\n\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t[style.background-image]=\"hidden.hidden ? slashGradient : null\"\n\t\t\t\t\t\t\t\t\t>{{ i + 1 }}</span\n\t\t\t\t\t\t\t\t>\n\n\t\t\t\t\t\t\t\t<!-- Clipping wrapper: neutralises the 1rem auto margin from SlideCanvas -->\n\t\t\t\t\t\t\t\t<div class=\"pptx-ng-spanel-clip\" [ngStyle]=\"clipStyle()\">\n\t\t\t\t\t\t\t\t\t<pptx-slide-canvas\n\t\t\t\t\t\t\t\t\t\t[slide]=\"slide\"\n\t\t\t\t\t\t\t\t\t\t[templateElements]=\"editor.templateElementsBySlideId()[slide.id] ?? []\"\n\t\t\t\t\t\t\t\t\t\t[canvasSize]=\"canvasSize()\"\n\t\t\t\t\t\t\t\t\t\t[mediaDataUrls]=\"mediaDataUrls()\"\n\t\t\t\t\t\t\t\t\t\t[zoom]=\"thumbZoom()\"\n\t\t\t\t\t\t\t\t\t\t[editable]=\"false\"\n\t\t\t\t\t\t\t\t\t\t[autoFit]=\"false\"\n\t\t\t\t\t\t\t\t\t\t[interactive]=\"false\"\n\t\t\t\t\t\t\t\t\t\t[exposeElementIds]=\"false\"\n\t\t\t\t\t\t\t\t\t\t[style.opacity]=\"hidden.hidden ? dimOpacity : null\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t@if (hidden.hidden) {\n\t\t\t\t\t\t\t\t\t\t<!-- Announced through aria-describedby, so the accessible name\n\t\t\t\t\t\t\t\t\t\t stays exactly \"Go to slide {{ i + 1 }}\". -->\n\t\t\t\t\t\t\t\t\t\t<span class=\"pptx-ng-spanel-hidden\" [id]=\"hidden.labelId\">\n\t\t\t\t\t\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\t\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\t\t\t\t\t\t\t\tfill=\"none\"\n\t\t\t\t\t\t\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\t\t\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\t\t\t\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\t\t\t\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\t\t\t\t\t\td=\"M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94\"\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t<path\n\t\t\t\t\t\t\t\t\t\t\t\t\td=\"M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19\"\n\t\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t\t\t<path d=\"M14.12 14.12a3 3 0 1 1-4.24-4.24\" />\n\t\t\t\t\t\t\t\t\t\t\t\t<path d=\"M1 1l22 22\" />\n\t\t\t\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t\t\t\t\t<span class=\"pptx-ng-sr-only\">{{ hiddenLabelKey | translate }}</span>\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</button>\n\n\t\t\t\t\t\t\t<!-- Per-card action toolbar (visible on hover / focus-within) -->\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-actions\"\n\t\t\t\t\t\t\t\trole=\"toolbar\"\n\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.slideMenu.slideActions' | translate: { n: i + 1 }\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-action\"\n\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t[title]=\"'pptx.ribbon.duplicateSlide' | translate\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.arrange.duplicate' | translate\"\n\t\t\t\t\t\t\t\t\t(click)=\"onDuplicate(i)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<svg lucideCopy class=\"h-3.5 w-3.5\"></svg>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-action\"\n\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t[title]=\"'pptx.slidesPanel.deleteSlide' | translate\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.arrange.delete' | translate\"\n\t\t\t\t\t\t\t\t\t[disabled]=\"editor.slides().length <= 1\"\n\t\t\t\t\t\t\t\t\t(click)=\"onDelete(i)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<svg lucideTrash2 class=\"h-3.5 w-3.5\"></svg>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-action\"\n\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t[title]=\"'pptx.sections.moveUp' | translate\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.sections.moveUp' | translate\"\n\t\t\t\t\t\t\t\t\t[disabled]=\"i === 0\"\n\t\t\t\t\t\t\t\t\t(click)=\"onMoveUp(i)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<svg lucideArrowUp class=\"h-3.5 w-3.5\"></svg>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"pptx-ng-spanel-action\"\n\t\t\t\t\t\t\t\t\tdata-pptx-compact\n\t\t\t\t\t\t\t\t\t[title]=\"'pptx.sections.moveDown' | translate\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"'pptx.sections.moveDown' | translate\"\n\t\t\t\t\t\t\t\t\t[disabled]=\"i === editor.slides().length - 1\"\n\t\t\t\t\t\t\t\t\t(click)=\"onMoveDown(i)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<svg lucideArrowDown class=\"h-3.5 w-3.5\"></svg>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t</div>\n\t\t</div>\n\t</div>\n\n\t<!-- Footer: add new slide -->\n\t<footer class=\"pptx-ng-spanel-footer\">\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"pptx-ng-spanel-add\"\n\t\t\t[attr.aria-label]=\"'pptx.sections.addSlide' | translate\"\n\t\t\t(click)=\"onAddSlide()\"\n\t\t>\n\t\t\t<svg lucidePlus class=\"h-3.5 w-3.5\"></svg> {{ 'pptx.sections.addSlide' | translate }}\n\t\t</button>\n\t</footer>\n</div>\n", styles: [":host{display:flex;flex-direction:column;height:100%;overflow:hidden}.pptx-ng-spanel{display:flex;flex-direction:column;height:100%;background:var(--pptx-secondary, #1e1e1e);color:var(--pptx-foreground, #e5e5e5);border-right:1px solid var(--pptx-border, rgba(255, 255, 255, .08));overflow:hidden}.pptx-ng-spanel-scroll{flex:1;overflow-y:auto;padding:.5rem .375rem}.pptx-ng-spanel-space{position:relative}.pptx-ng-spanel-window{display:flex;flex-direction:column;gap:.375rem}.pptx-ng-spanel-window.is-virtualized{position:absolute;inset-inline:0}.pptx-ng-section-header{display:flex;align-items:center;gap:.2rem;min-height:1.75rem;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .58))}.pptx-ng-section-toggle{display:flex;align-items:center;gap:.35rem;min-width:0;flex:1;border:0;background:transparent;color:inherit;cursor:pointer;text-align:left}.pptx-ng-section-swatch{display:inline-block;flex:0 0 auto;width:.5rem;height:.5rem;border-radius:9999px}.pptx-ng-section-toggle strong{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.7rem}.pptx-ng-section-actions{display:flex}.pptx-ng-section-actions button{width:1.25rem;height:1.25rem;padding:0;border:0;border-radius:.2rem;background:transparent;color:inherit;cursor:pointer}.pptx-ng-section-actions button:hover:not(:disabled){background:color-mix(in srgb,var(--pptx-primary, #3b82f6) 35%,transparent);color:var(--pptx-foreground, #fff)}.pptx-ng-section-actions button:disabled{opacity:.3}.pptx-ng-spanel-card{position:relative;border-radius:.375rem;border:2px solid transparent;background:transparent;transition:border-color .15s,background .15s}.pptx-ng-spanel-card:hover,.pptx-ng-spanel-card:focus-within{background:color-mix(in srgb,var(--pptx-foreground, #fff) 5%,transparent);border-color:color-mix(in srgb,var(--pptx-foreground, #fff) 15%,transparent)}.pptx-ng-spanel-card.is-active{border-color:var(--pptx-primary, #3b82f6);background:color-mix(in srgb,var(--pptx-primary, #3b82f6) 10%,transparent)}.pptx-ng-spanel-thumb-btn{display:flex;align-items:center;gap:.25rem;width:100%;padding:.375rem;border:none;background:transparent;cursor:pointer;color:inherit;line-height:0}.pptx-ng-spanel-thumb-btn:focus-visible{outline:2px solid var(--pptx-ring, #3b82f6);outline-offset:2px;border-radius:.25rem}.pptx-ng-spanel-clip{position:relative;overflow:hidden;border-radius:2px}.pptx-ng-spanel-hidden{position:absolute;right:2px;bottom:2px;z-index:10;display:inline-flex;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .45))}.pptx-ng-spanel-hidden svg{width:.75rem;height:.75rem}.pptx-ng-sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.pptx-ng-spanel-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}.pptx-ng-spanel-num{flex:0 0 auto;width:1.1rem;text-align:right;font-size:.625rem;line-height:1;font-variant-numeric:tabular-nums;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .45));-webkit-user-select:none;user-select:none}.pptx-ng-spanel-card.is-active .pptx-ng-spanel-num{color:var(--pptx-primary, #3b82f6);font-weight:500}.pptx-ng-spanel-actions{position:absolute;top:.25rem;right:.25rem;display:flex;flex-direction:column;gap:.125rem;opacity:0;pointer-events:none;transition:opacity .12s}.pptx-ng-spanel-card:hover .pptx-ng-spanel-actions,.pptx-ng-spanel-card:focus-within .pptx-ng-spanel-actions{opacity:1;pointer-events:auto}.pptx-ng-spanel-action{display:flex;align-items:center;justify-content:center;width:1.375rem;height:1.375rem;padding:0;border:none;border-radius:.25rem;background:color-mix(in srgb,var(--pptx-popover, #1e1e1e) 85%,transparent);color:var(--pptx-popover-foreground, #e5e5e5);font-size:.6875rem;cursor:pointer;transition:background .12s;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.pptx-ng-spanel-action:hover:not([disabled]){background:color-mix(in srgb,var(--pptx-primary, #3b82f6) 75%,transparent);color:var(--pptx-primary-foreground, #fff)}.pptx-ng-spanel-action[disabled]{opacity:.3;cursor:not-allowed}.pptx-ng-spanel-footer{flex-shrink:0;padding:.5rem .375rem;border-top:1px solid var(--pptx-border, rgba(255, 255, 255, .08))}.pptx-ng-spanel-add{display:flex;align-items:center;justify-content:center;gap:.25rem;width:100%;padding:.25rem .5rem;border:none;border-radius:.25rem;background:transparent;color:var(--pptx-muted-foreground, rgba(255, 255, 255, .6));font-size:.6875rem;cursor:pointer;transition:background .15s,color .15s}.pptx-ng-spanel-add:hover{background:color-mix(in srgb,var(--pptx-foreground, #fff) 8%,transparent);color:var(--pptx-foreground, #e5e5e5)}\n"], dependencies: [{ kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: LucideCopy, selector: "svg[lucideCopy]" }, { kind: "component", type: LucideTrash2, selector: "svg[lucideTrash], svg[lucideTrash2]" }, { kind: "component", type: LucideArrowUp, selector: "svg[lucideArrowUp]" }, { kind: "component", type: LucideArrowDown, selector: "svg[lucideArrowDown]" }, { kind: "component", type: LucidePlus, selector: "svg[lucidePlus]" }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
169005
169380
  }
169006
169381
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SlidesPanelComponent, decorators: [{
169007
169382
  type: Component,
@@ -170629,7 +171004,7 @@ class SlideDiffThumbnailsComponent {
170629
171004
  </div>
170630
171005
  }
170631
171006
  </div>
170632
- `, isInline: true, styles: [".pptx-ng-diff-thumbs{display:flex;gap:.5rem}.pptx-ng-diff-thumb-col{flex:1}.pptx-ng-diff-thumb-label{margin-bottom:.25rem;font-size:.625rem;color:var(--pptx-muted-foreground, #9ca3af)}.pptx-ng-diff-thumb-clip{overflow:hidden;border:1px solid var(--pptx-border, #374151);border-radius:.25rem}.pptx-ng-diff-thumb-clip[data-status=added]{border-color:#15803d99}.pptx-ng-diff-thumb-clip[data-status=changed]{border-color:#b4530999}.pptx-ng-diff-thumb-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}\n"], dependencies: [{ kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
171007
+ `, isInline: true, styles: [".pptx-ng-diff-thumbs{display:flex;gap:.5rem}.pptx-ng-diff-thumb-col{flex:1}.pptx-ng-diff-thumb-label{margin-bottom:.25rem;font-size:.625rem;color:var(--pptx-muted-foreground, #9ca3af)}.pptx-ng-diff-thumb-clip{overflow:hidden;border:1px solid var(--pptx-border, #374151);border-radius:.25rem}.pptx-ng-diff-thumb-clip[data-status=added]{border-color:#15803d99}.pptx-ng-diff-thumb-clip[data-status=changed]{border-color:#b4530999}.pptx-ng-diff-thumb-clip ::ng-deep .pptx-ng-canvas-wrapper{margin:0!important}\n"], dependencies: [{ kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
170633
171008
  }
170634
171009
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: SlideDiffThumbnailsComponent, decorators: [{
170635
171010
  type: Component,
@@ -175772,6 +176147,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
175772
176147
  }]
175773
176148
  }], ctorParameters: () => [], propDecorators: { activeSlideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeSlideIndex", required: false }] }], selectedElementId: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedElementId", required: false }] }], filePath: [{ type: i0.Input, args: [{ isSignal: true, alias: "filePath", required: false }] }], customShows: [{ type: i0.Input, args: [{ isSignal: true, alias: "customShows", required: false }] }], themeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "themeKey", required: false }] }], availableThemes: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableThemes", required: false }] }], localeCode: [{ type: i0.Input, args: [{ isSignal: true, alias: "localeCode", required: false }] }], availableLocales: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableLocales", required: false }] }], aiExportVisible: [{ type: i0.Input, args: [{ isSignal: true, alias: "aiExportVisible", required: false }] }], restoreContent: [{ type: i0.Output, args: ["restoreContent"] }], themeKeySelect: [{ type: i0.Output, args: ["themeKeySelect"] }], localeSelect: [{ type: i0.Output, args: ["localeSelect"] }] } });
175774
176149
 
176150
+ /** Public insertion uses the same synchronous commit and editor transaction as the canvas. */
176151
+ function insertPublicElement(element, target, editor, slideIndex, commitPendingText) {
176152
+ const prepared = prepareElementForInsertion(element, target);
176153
+ if (!prepared) {
176154
+ return undefined;
176155
+ }
176156
+ commitPendingText();
176157
+ editor.addElement(slideIndex, prepared);
176158
+ return prepared.id;
176159
+ }
176160
+
175775
176161
  /* oxlint-disable eslint/one-var -- pre-existing throughout this file; independent concerns, not one statement */
175776
176162
  /**
175777
176163
  * PowerPointViewerComponent: Angular port of the React `PowerPointViewer.tsx`
@@ -175867,6 +176253,12 @@ class PowerPointViewerComponent {
175867
176253
  */
175868
176254
  this.fileName = input(undefined, /* @ts-ignore */
175869
176255
  ...(ngDevMode ? [{ debugName: "fileName" }] : /* istanbul ignore next */ []));
176256
+ /** Unscaled decorative viewport padding per side; omission preserves defaults. */
176257
+ this.fitPadding = input(undefined, /* @ts-ignore */
176258
+ ...(ngDevMode ? [{ debugName: "fitPadding" }] : /* istanbul ignore next */ []));
176259
+ /** Fit-factor ceiling, independent of user zoom; null permits enlargement. */
176260
+ this.maxFitScale = input(undefined, /* @ts-ignore */
176261
+ ...(ngDevMode ? [{ debugName: "maxFitScale" }] : /* istanbul ignore next */ []));
175870
176262
  /**
175871
176263
  * Recovery autosave: after an edit the deck is re-serialised (always as a
175872
176264
  * plain, unencrypted package, because recovery has no password) and stashed
@@ -176106,9 +176498,13 @@ class PowerPointViewerComponent {
176106
176498
  * read-only recommendation (`p:modifyVerifier` / "Mark as Final"; lifted by
176107
176499
  * the read-only banner's "Edit anyway", see {@link LoadNoticesService}).
176108
176500
  */
176109
- this.canEdit = computed(() => this.canEditInput() &&
176501
+ this.hasEditPermission = computed(() => this.canEditInput() &&
176110
176502
  (!this.viewerOpts.options().trust.openInProtectedView || this.protectedViewDismissed()) &&
176111
176503
  !this.loadNotices.lockActive(), /* @ts-ignore */
176504
+ ...(ngDevMode ? [{ debugName: "hasEditPermission" }] : /* istanbul ignore next */ []));
176505
+ this.editingRequested = signal(true, /* @ts-ignore */
176506
+ ...(ngDevMode ? [{ debugName: "editingRequested" }] : /* istanbul ignore next */ []));
176507
+ this.canEdit = computed(() => this.hasEditPermission() && this.editingRequested(), /* @ts-ignore */
176112
176508
  ...(ngDevMode ? [{ debugName: "canEdit" }] : /* istanbul ignore next */ []));
176113
176509
  /** Whether the Protected View banner should show: host allows editing, the option still blocks it, and the user hasn't dismissed it yet. */
176114
176510
  this.protectedViewActive = computed(() => this.canEditInput() &&
@@ -176145,8 +176541,8 @@ class PowerPointViewerComponent {
176145
176541
  */
176146
176542
  this.audienceSessionEnded = signal(false, /* @ts-ignore */
176147
176543
  ...(ngDevMode ? [{ debugName: "audienceSessionEnded" }] : /* istanbul ignore next */ []));
176148
- /** Slides to display: the editable deck when `canEdit`, else the loaded deck. */
176149
- this.displaySlides = computed(() => this.canEdit() ? this.editor.slides() : this.loader.slides(), /* @ts-ignore */
176544
+ /** Preview changes interaction, not which permitted live deck is displayed. */
176545
+ this.displaySlides = computed(() => this.hasEditPermission() ? this.editor.slides() : this.loader.slides(), /* @ts-ignore */
176150
176546
  ...(ngDevMode ? [{ debugName: "displaySlides" }] : /* istanbul ignore next */ []));
176151
176547
  this.slideCount = computed(() => this.displaySlides().length, /* @ts-ignore */
176152
176548
  ...(ngDevMode ? [{ debugName: "slideCount" }] : /* istanbul ignore next */ []));
@@ -176156,7 +176552,7 @@ class PowerPointViewerComponent {
176156
176552
  * consumer that needs the COMPLETE slide (export, print, slide thumbnails,
176157
176553
  * accessibility) renders this instead so template elements are not lost.
176158
176554
  */
176159
- this.mergedSlides = computed(() => this.canEdit()
176555
+ this.mergedSlides = computed(() => this.hasEditPermission()
176160
176556
  ? buildSaveSlides(this.editor.slides(), this.editor.templateElementsBySlideId())
176161
176557
  : this.loader.slides(), /* @ts-ignore */
176162
176558
  ...(ngDevMode ? [{ debugName: "mergedSlides" }] : /* istanbul ignore next */ []));
@@ -176168,7 +176564,7 @@ class PowerPointViewerComponent {
176168
176564
  /** Inherited template (master/layout) elements for the active slide, when editing. */
176169
176565
  this.activeTemplateElements = computed(() => {
176170
176566
  const slide = this.activeSlide();
176171
- if (!this.canEdit() || !slide) {
176567
+ if (!this.hasEditPermission() || !slide) {
176172
176568
  return [];
176173
176569
  }
176174
176570
  return this.editor.templateElementsBySlideId()[slide.id] ?? [];
@@ -176966,7 +177362,7 @@ class PowerPointViewerComponent {
176966
177362
  // component (canEdit, the host `content` input, the File ▸ Open override,
176967
177363
  // the editor's slides + template elements, and the contentChange emitter).
176968
177364
  this.fileIO.bind({
176969
- canEdit: () => this.canEdit(),
177365
+ canEdit: () => this.hasEditPermission(),
176970
177366
  content: () => this.content(),
176971
177367
  onOpenFile: () => this.onOpenFile(),
176972
177368
  slides: () => this.editor.slides(),
@@ -177382,6 +177778,12 @@ class PowerPointViewerComponent {
177382
177778
  }
177383
177779
  /** Switch the viewer mode (e.g. 'edit', 'preview', 'present'). */
177384
177780
  setMode(mode) {
177781
+ if (mode === 'preview' && this.canEdit()) {
177782
+ this.mainEl()?.nativeElement.querySelector('[data-inline-editor]')?.blur();
177783
+ }
177784
+ if (mode !== 'present') {
177785
+ this.editingRequested.set(mode !== 'preview');
177786
+ }
177385
177787
  if (mode === 'present') {
177386
177788
  this.presentationMode.present();
177387
177789
  }
@@ -177531,6 +177933,18 @@ class PowerPointViewerComponent {
177531
177933
  const s = this.displaySlides()[idx];
177532
177934
  return s?.elements.find((e) => e.id === elementId);
177533
177935
  }
177936
+ /** Insert a defensive copy into the active ordinary editable slide. */
177937
+ addElement(element) {
177938
+ return insertPublicElement(element, {
177939
+ canEdit: this.canEdit(),
177940
+ mode: this.getMode(),
177941
+ hasActiveSlide: !this.loader.loading() && !this.loader.error() && Boolean(this.activeSlide()),
177942
+ editTemplateMode: this.editor.editTemplateMode(),
177943
+ }, this.editor, this.activeSlideIndex(), () => {
177944
+ // Blur synchronously emits the existing canvas textCommit before insertion.
177945
+ this.mainEl()?.nativeElement.querySelector('[data-inline-editor]')?.blur();
177946
+ });
177947
+ }
177534
177948
  /** Update one or more properties of an element by ID. */
177535
177949
  updateElement(elementId, updates) {
177536
177950
  this.editor.updateElement(this.activeSlideIndex(), elementId, updates);
@@ -177886,7 +178300,7 @@ class PowerPointViewerComponent {
177886
178300
  return (this.mainEl()?.nativeElement.querySelector('.pptx-ng-canvas-stage') ?? undefined);
177887
178301
  }
177888
178302
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: PowerPointViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
177889
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: PowerPointViewerComponent, isStandalone: true, selector: "pptx-viewer", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, fontsInput: { classPropertyName: "fontsInput", publicName: "fonts", isSignal: true, isRequired: false, transformFunction: null }, canEditInput: { classPropertyName: "canEditInput", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null }, defaultThemeKey: { classPropertyName: "defaultThemeKey", publicName: "defaultThemeKey", isSignal: true, isRequired: false, transformFunction: null }, availableThemes: { classPropertyName: "availableThemes", publicName: "availableThemes", isSignal: true, isRequired: false, transformFunction: null }, onThemeChange: { classPropertyName: "onThemeChange", publicName: "onThemeChange", isSignal: true, isRequired: false, transformFunction: null }, defaultLocale: { classPropertyName: "defaultLocale", publicName: "defaultLocale", isSignal: true, isRequired: false, transformFunction: null }, availableLocales: { classPropertyName: "availableLocales", publicName: "availableLocales", isSignal: true, isRequired: false, transformFunction: null }, onLocaleChange: { classPropertyName: "onLocaleChange", publicName: "onLocaleChange", isSignal: true, isRequired: false, transformFunction: null }, accountAuth: { classPropertyName: "accountAuth", publicName: "accountAuth", isSignal: true, isRequired: false, transformFunction: null }, filePath: { classPropertyName: "filePath", publicName: "filePath", isSignal: true, isRequired: false, transformFunction: null }, fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null }, autosaveInput: { classPropertyName: "autosaveInput", publicName: "autosave", isSignal: true, isRequired: false, transformFunction: null }, autosaveIntervalMs: { classPropertyName: "autosaveIntervalMs", publicName: "autosaveIntervalMs", isSignal: true, isRequired: false, transformFunction: null }, collaboration: { classPropertyName: "collaboration", publicName: "collaboration", isSignal: true, isRequired: false, transformFunction: null }, authorName: { classPropertyName: "authorName", publicName: "authorName", isSignal: true, isRequired: false, transformFunction: null }, shareDefaults: { classPropertyName: "shareDefaults", publicName: "shareDefaults", isSignal: true, isRequired: false, transformFunction: null }, onOpenFile: { classPropertyName: "onOpenFile", publicName: "onOpenFile", isSignal: true, isRequired: false, transformFunction: null }, smartArt3D: { classPropertyName: "smartArt3D", publicName: "smartArt3D", isSignal: true, isRequired: false, transformFunction: null }, surfaceChart3D: { classPropertyName: "surfaceChart3D", publicName: "surfaceChart3D", isSignal: true, isRequired: false, transformFunction: null }, barChart3D: { classPropertyName: "barChart3D", publicName: "barChart3D", isSignal: true, isRequired: false, transformFunction: null }, lineChart3D: { classPropertyName: "lineChart3D", publicName: "lineChart3D", isSignal: true, isRequired: false, transformFunction: null }, areaChart3D: { classPropertyName: "areaChart3D", publicName: "areaChart3D", isSignal: true, isRequired: false, transformFunction: null }, pieChart3D: { classPropertyName: "pieChart3D", publicName: "pieChart3D", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null }, ai: { classPropertyName: "ai", publicName: "ai", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeSlideChange: "activeSlideChange", dirtyChange: "dirtyChange", contentChange: "contentChange", propertiesChange: "propertiesChange", modeChange: "modeChange", zoomChange: "zoomChange", selectionChange: "selectionChange", slideCountChange: "slideCountChange", startCollaboration: "startCollaboration", stopCollaboration: "stopCollaboration" }, host: { listeners: { "document:keydown": "onKeyDown($event)", "window:beforeunload": "clearCacheOnUnload()" } }, providers: [...POWER_POINT_VIEWER_PROVIDERS], viewQueries: [{ propertyName: "extraDialogs", first: true, predicate: ViewerExtraDialogsComponent, descendants: true, isSignal: true }, { propertyName: "mainEl", first: true, predicate: ["mainEl"], descendants: true, isSignal: true }], ngImport: i0, template: `
178303
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: PowerPointViewerComponent, isStandalone: true, selector: "pptx-viewer", inputs: { content: { classPropertyName: "content", publicName: "content", isSignal: true, isRequired: false, transformFunction: null }, fontsInput: { classPropertyName: "fontsInput", publicName: "fonts", isSignal: true, isRequired: false, transformFunction: null }, canEditInput: { classPropertyName: "canEditInput", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null }, class: { classPropertyName: "class", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null }, defaultThemeKey: { classPropertyName: "defaultThemeKey", publicName: "defaultThemeKey", isSignal: true, isRequired: false, transformFunction: null }, availableThemes: { classPropertyName: "availableThemes", publicName: "availableThemes", isSignal: true, isRequired: false, transformFunction: null }, onThemeChange: { classPropertyName: "onThemeChange", publicName: "onThemeChange", isSignal: true, isRequired: false, transformFunction: null }, defaultLocale: { classPropertyName: "defaultLocale", publicName: "defaultLocale", isSignal: true, isRequired: false, transformFunction: null }, availableLocales: { classPropertyName: "availableLocales", publicName: "availableLocales", isSignal: true, isRequired: false, transformFunction: null }, onLocaleChange: { classPropertyName: "onLocaleChange", publicName: "onLocaleChange", isSignal: true, isRequired: false, transformFunction: null }, accountAuth: { classPropertyName: "accountAuth", publicName: "accountAuth", isSignal: true, isRequired: false, transformFunction: null }, filePath: { classPropertyName: "filePath", publicName: "filePath", isSignal: true, isRequired: false, transformFunction: null }, fileName: { classPropertyName: "fileName", publicName: "fileName", isSignal: true, isRequired: false, transformFunction: null }, fitPadding: { classPropertyName: "fitPadding", publicName: "fitPadding", isSignal: true, isRequired: false, transformFunction: null }, maxFitScale: { classPropertyName: "maxFitScale", publicName: "maxFitScale", isSignal: true, isRequired: false, transformFunction: null }, autosaveInput: { classPropertyName: "autosaveInput", publicName: "autosave", isSignal: true, isRequired: false, transformFunction: null }, autosaveIntervalMs: { classPropertyName: "autosaveIntervalMs", publicName: "autosaveIntervalMs", isSignal: true, isRequired: false, transformFunction: null }, collaboration: { classPropertyName: "collaboration", publicName: "collaboration", isSignal: true, isRequired: false, transformFunction: null }, authorName: { classPropertyName: "authorName", publicName: "authorName", isSignal: true, isRequired: false, transformFunction: null }, shareDefaults: { classPropertyName: "shareDefaults", publicName: "shareDefaults", isSignal: true, isRequired: false, transformFunction: null }, onOpenFile: { classPropertyName: "onOpenFile", publicName: "onOpenFile", isSignal: true, isRequired: false, transformFunction: null }, smartArt3D: { classPropertyName: "smartArt3D", publicName: "smartArt3D", isSignal: true, isRequired: false, transformFunction: null }, surfaceChart3D: { classPropertyName: "surfaceChart3D", publicName: "surfaceChart3D", isSignal: true, isRequired: false, transformFunction: null }, barChart3D: { classPropertyName: "barChart3D", publicName: "barChart3D", isSignal: true, isRequired: false, transformFunction: null }, lineChart3D: { classPropertyName: "lineChart3D", publicName: "lineChart3D", isSignal: true, isRequired: false, transformFunction: null }, areaChart3D: { classPropertyName: "areaChart3D", publicName: "areaChart3D", isSignal: true, isRequired: false, transformFunction: null }, pieChart3D: { classPropertyName: "pieChart3D", publicName: "pieChart3D", isSignal: true, isRequired: false, transformFunction: null }, hiddenActions: { classPropertyName: "hiddenActions", publicName: "hiddenActions", isSignal: true, isRequired: false, transformFunction: null }, ai: { classPropertyName: "ai", publicName: "ai", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeSlideChange: "activeSlideChange", dirtyChange: "dirtyChange", contentChange: "contentChange", propertiesChange: "propertiesChange", modeChange: "modeChange", zoomChange: "zoomChange", selectionChange: "selectionChange", slideCountChange: "slideCountChange", startCollaboration: "startCollaboration", stopCollaboration: "stopCollaboration" }, host: { listeners: { "document:keydown": "onKeyDown($event)", "window:beforeunload": "clearCacheOnUnload()" } }, providers: [...POWER_POINT_VIEWER_PROVIDERS], viewQueries: [{ propertyName: "extraDialogs", first: true, predicate: ViewerExtraDialogsComponent, descendants: true, isSignal: true }, { propertyName: "mainEl", first: true, predicate: ["mainEl"], descendants: true, isSignal: true }], ngImport: i0, template: `
177890
178304
  <div
177891
178305
  class="pptx-ng-viewer"
177892
178306
  [ngClass]="rootClasses()"
@@ -178141,6 +178555,8 @@ class PowerPointViewerComponent {
178141
178555
  [canvasSize]="loader.canvasSize()"
178142
178556
  [mediaDataUrls]="loader.mediaDataUrls()"
178143
178557
  [zoom]="zoomSvc.zoom()"
178558
+ [fitPadding]="fitPadding()"
178559
+ [maxFitScale]="maxFitScale()"
178144
178560
  [editable]="canEdit()"
178145
178561
  [selectedIds]="editor.selectedIds()"
178146
178562
  [showGrid]="showGrid()"
@@ -178840,7 +179256,7 @@ class PowerPointViewerComponent {
178840
179256
  (dismissAll)="loadNotices.dismissAllToasts()"
178841
179257
  />
178842
179258
  </div>
178843
- `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresentationOverlayComponent, selector: "pptx-presentation-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "startIndex", "activeCustomShow", "authoredRange", "loopContinuously", "showWithAnimation", "useTimings", "subtitlesVisible", "sessionEnded", "endWithBlackSlide", "pixelateMosaicAnimation", "presenterMode", "showMenuOnRightClick", "showPopupToolbar"], outputs: ["indexChange", "closed", "subtitlesChange", "presenterViewToggle", "annotationsExit", "customShowRequest", "endOfShowChange"] }, { kind: "component", type: PresenterViewComponent, selector: "pptx-presenter-view", inputs: ["slides", "currentSlideIndex", "activeCustomShow", "authoredRange", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime", "isAudienceWindowOpen"], outputs: ["movePresentationSlide", "exit", "openAudienceWindow", "closeAudienceWindow", "navigateToSlide"] }, { kind: "component", type: MobilePresenterViewComponent, selector: "pptx-mobile-presenter-view", inputs: ["slides", "currentSlideIndex", "activeCustomShow", "authoredRange", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime"], outputs: ["movePresentationSlide", "exit"] }, { kind: "component", type: SlideSorterOverlayComponent, selector: "pptx-slide-sorter-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "activeIndex", "canEdit"], outputs: ["select", "closed", "deleteSlide", "duplicateSlide", "toggleHiddenSlide"] }, { kind: "component", type: OutlineViewOverlayComponent, selector: "pptx-outline-view-overlay", inputs: ["slides", "canvasSize", "canEdit"], outputs: ["commit", "closed"] }, { kind: "component", type: ReadingViewOverlayComponent, selector: "pptx-reading-view-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "activeSlideIndex"], outputs: ["exit"] }, { kind: "component", type: SlideDefaultInspectorComponent, selector: "pptx-slide-default-inspector", inputs: ["slideIndex", "canEdit", "selectedElement", "comments", "modernCommentAuthors"], outputs: ["commentAdd", "commentRemove", "commentResolve", "commentReply"] }, { kind: "component", type: FindBarComponent, selector: "pptx-find-bar", inputs: ["slides"], outputs: ["navigate", "closed"] }, { kind: "component", type: FindReplaceBarComponent, selector: "pptx-find-replace-bar", inputs: ["matchCount", "matchIndex"], outputs: ["find", "navigate", "replaceOne", "replaceAll", "close"] }, { kind: "component", type: SlidesPanelComponent, selector: "pptx-slides-panel", inputs: ["canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["select"] }, { kind: "component", type: StatusBarComponent, selector: "pptx-status-bar", inputs: ["slideIndex", "slideCount", "canEdit", "dirty", "autosaveStatus", "notesOpen", "zoomPercent", "sorterActive", "presenting", "hiddenActions"], outputs: ["toggleNotes", "normalView", "openSorter", "slideShow", "zoomIn", "zoomOut", "zoomReset"] }, { kind: "component", type: EditorContextMenuComponent, selector: "pptx-editor-context-menu", inputs: ["x", "y", "slideIndex", "showAiActions"], outputs: ["closed", "askAi", "fixAi", "editHyperlink", "addComment"] }, { kind: "component", type: ExportProgressModalComponent, selector: "pptx-export-progress-modal", inputs: ["open", "title", "progress", "statusMessage"], outputs: ["cancel"] }, { kind: "component", type: CommentMarkersOverlayComponent, selector: "pptx-comment-markers-overlay", inputs: ["comments", "canvasSize"], outputs: ["markerClick"] }, { kind: "component", type: CommentsPanelComponent, selector: "pptx-comments-panel", inputs: ["comments", "authorName", "modernCommentAuthors"], outputs: ["add", "remove", "resolve", "reply"] }, { kind: "component", type: CompatToastsComponent, selector: "pptx-compat-toasts", inputs: ["toasts"], outputs: ["dismissOne", "dismissAll"] }, { kind: "component", type: ReadOnlyBannerComponent, selector: "pptx-readonly-banner", inputs: ["kind", "messageKey", "passwordPromptOpen", "passwordError", "checkingPassword"], outputs: ["editAnyway", "dismiss", "submitPassword", "cancelPassword"] }, { kind: "component", type: SignaturesPanelComponent, selector: "pptx-signatures-panel", inputs: ["signatures"] }, { kind: "component", type: AccessibilityPanelComponent, selector: "pptx-accessibility-panel", inputs: ["issues"], outputs: ["selectSlide"] }, { kind: "component", type: CollaborationCursorsComponent, selector: "pptx-collaboration-cursors", inputs: ["cursors", "zoom"] }, { kind: "component", type: RemoteSelectionOverlayComponent, selector: "pptx-remote-selection-overlay", inputs: ["presences", "elements", "activeSlideIndex", "zoom"] }, { kind: "component", type: MotionPathOverlayComponent, selector: "pptx-motion-path-overlay", inputs: ["element", "animations", "canvasSize", "canEdit"], outputs: ["pathChange"] }, { kind: "component", type: FollowModeBarComponent, selector: "pptx-follow-mode-bar", inputs: ["presences", "followedClientId"], outputs: ["follow"] }, { kind: "component", type: PropertiesDialogComponent, selector: "pptx-properties-dialog", inputs: ["open", "properties"], outputs: ["save", "close"] }, { kind: "component", type: HyperlinkDialogComponent, selector: "pptx-hyperlink-dialog", inputs: ["open", "element"], outputs: ["save", "close"] }, { kind: "component", type: PrintDialogComponent, selector: "pptx-print-dialog", inputs: ["slides", "activeSlideIndex", "defaultSlidesPerPage", "defaultFrameSlides", "defaultSettings"], outputs: ["print", "cancel"] }, { kind: "component", type: ShareDialogComponent, selector: "pptx-share-dialog", inputs: ["open", "defaults", "active", "connected", "userCount", "shareUrl", "p2p", "activeRoomId", "activeServerUrl", "users"], outputs: ["start", "stop", "close"] }, { kind: "component", type: BroadcastDialogComponent, selector: "pptx-broadcast-dialog", inputs: ["open", "defaults", "active", "connected", "viewerCount", "viewerUrl", "p2p"], outputs: ["start", "stop", "close"] }, { kind: "component", type: MobileBottomBarComponent, selector: "pptx-mobile-bottom-bar", inputs: ["slideCount", "commentCount", "activeSheet"], outputs: ["openSlides", "insert", "openFormat", "openComments", "notes"] }, { kind: "component", type: MobileMenuSheetComponent, selector: "pptx-mobile-menu-sheet", inputs: ["open", "slideCount", "exporting", "showNotes", "canEdit", "hiddenActions"], outputs: ["closed", "openFind", "openSorter", "toggleNotes", "insertText", "present", "openFile", "savePptx", "exportPng", "exportPdf", "exportGif", "exportVideo", "print"] }, { kind: "component", type: MobileSlidesSheetComponent, selector: "pptx-mobile-slides-sheet", inputs: ["open", "slides", "canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["closed", "jumpToSlide"] }, { kind: "component", type: MobileToolbarComponent, selector: "pptx-mobile-toolbar", inputs: ["canUndo", "canRedo", "canPresent", "canEdit", "menuOpen", "aiEnabled", "aiPanelOpen", "hiddenActions"], outputs: ["toggleMenu", "toggleAiPanel", "undo", "redo", "share", "save", "present"] }, { kind: "component", type: MasterViewCanvasComponent, selector: "pptx-master-view-canvas", inputs: ["tab", "slideMasters", "activeMasterIndex", "activeLayoutIndex", "notesMaster", "handoutMaster", "canvasSize", "notesCanvasSize", "mediaDataUrls", "editable"], outputs: ["notesMasterChange", "handoutMasterChange", "slideMastersChange"] }, { kind: "component", type: MasterViewSidebarComponent, selector: "pptx-master-view-sidebar", inputs: ["tab", "slideMasters", "notesMaster", "handoutMaster", "activeMasterIndex", "activeLayoutIndex", "handoutSlidesPerPage", "editable", "crudActions"], outputs: ["tabChange", "selectMaster", "selectLayout", "slidesPerPageChange", "backgroundChange", "close", "crudAction"] }, { kind: "component", type: NotesPanelComponent, selector: "pptx-notes-panel", inputs: ["slide", "expanded", "notesStyle"], outputs: ["update", "notesToggle"] }, { kind: "component", type: QuickAccessStripComponent, selector: "pptx-quick-access-strip", inputs: ["quickAccess", "canUndo", "canRedo"], outputs: ["command"] }, { kind: "component", type: RibbonComponent, selector: "pptx-ribbon", inputs: ["slideIndex", "slideCount", "canEdit", "selectedElement", "zoomPercent", "formatPainterActive", "canActivateFormatPainter", "exporting", "hasMacros", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "eyedropperActive", "themeGalleryOpen", "sidebarCollapsed", "inspectorOpen", "commentsOpen", "commentCount", "findOpen", "collabConnected", "connectedCount", "spellCheckEnabled", "showSubtitles", "hiddenActions", "aiEnabled", "aiPanelOpen", "accountAuth", "activeSlideHidden"], outputs: ["prev", "next", "zoomIn", "zoomOut", "zoomReset", "find", "present", "presenter", "record", "presentFromBeginning", "rehearseTimings", "toggleSubtitles", "openSubtitleSettings", "recordFromBeginning", "recordFromCurrent", "spellCheckChange", "share", "broadcast", "openFile", "openRecentFile", "createPresentation", "save", "savePpsx", "savePptm", "savePpt", "toggleSidebar", "toggleAiPanel", "signatures", "info", "print", "comments", "a11y", "shortcuts", "versionHistory", "passwordProtection", "fontEmbedding", "link", "openSorter", "openReadingView", "openOutlineView", "openMasterView", "toggleNotes", "toggleFormatPainter", "exportPng", "exportPdf", "exportGif", "exportVideo", "exportJson", "copySlideAsImage", "replace", "toggleInspector", "openAnimationPanel", "drawToolChange", "toggleThemeGallery", "editTheme", "openSlideSize", "toggleGrid", "toggleRulers", "toggleGuides", "toggleSelectionPane", "openCustomShows", "toggleSnapToGrid", "toggleSnapToShape", "addGuide", "zoomToFit", "toggleEyedropper", "openSmartArtDialog", "openTemplateGallery", "openEquationDialog", "openSetUpSlideShow", "toggleHideSlide", "openCompare", "openPassword", "openFontEmbedding", "openVersionHistory", "openShortcuts", "openSettings"] }, { kind: "component", type: TitleBarComponent, selector: "pptx-title-bar", inputs: ["canEdit", "fileName", "isDirty", "autosaveStatus", "autosaveEnabled", "canUndo", "canRedo", "undoLabel", "redoLabel", "findReplaceOpen", "hiddenActions", "quickAccess"], outputs: ["toggleAutosave", "save", "undo", "redo", "quickCommand", "toggleFindReplace", "commandSearch"] }, { kind: "component", type: ThemeGalleryComponent, selector: "pptx-theme-gallery", inputs: ["open", "activeName", "theme", "startCustomizing"], outputs: ["applyTheme", "applyCustomTheme", "close"] }, { kind: "component", type: SelectionPaneComponent, selector: "pptx-selection-pane", inputs: ["elements", "selectedIds"], outputs: ["selectElement", "bringForward", "sendBackward", "toggleHidden", "renameElement"] }, { kind: "component", type: CustomShowsComponent, selector: "pptx-custom-shows", inputs: ["open", "slides", "customShows", "activeCustomShowId"], outputs: ["create", "remove", "update", "setActive", "close"] }, { kind: "component", type: InsertSmartArtDialogComponent, selector: "pptx-insert-smart-art-dialog", inputs: ["open"], outputs: ["close", "insert"] }, { kind: "component", type: SlideTemplateGalleryDialogComponent, selector: "pptx-slide-template-gallery-dialog", inputs: ["open", "scheme"], outputs: ["close", "insert"] }, { kind: "component", type: ViewerExtraDialogsComponent, selector: "pptx-viewer-extra-dialogs", inputs: ["activeSlideIndex", "selectedElementId", "filePath", "customShows", "themeKey", "availableThemes", "localeCode", "availableLocales", "aiExportVisible"], outputs: ["restoreContent", "themeKeySelect", "localeSelect"] }, { kind: "component", type: AutosaveRecoveryDialogComponent, selector: "pptx-autosave-recovery-dialog", inputs: ["prompt"], outputs: ["restore", "discard"] }, { kind: "component", type: RehearseTimingsComponent, selector: "pptx-rehearse-timings", inputs: ["summary", "paused", "slideStartedAt", "presentationStartedAt", "timings"], outputs: ["togglePause", "save", "discard"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [/* @ts-ignore */
179259
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: SlideCanvasComponent, selector: "pptx-slide-canvas", inputs: ["slide", "canvasSize", "mediaDataUrls", "zoom", "fitPadding", "maxFitScale", "editable", "showGrid", "showRulers", "rulerUnit", "showGuides", "snapToGrid", "gridSpacing", "snapToShape", "guideCommand", "spellCheck", "snapToGuides", "autoFit", "transparentBackground", "interactive", "exposeElementIds", "presenting", "selectedIds", "editingId", "editTemplateMode", "templateElements", "aiHighlights", "aiActive", "aiActiveSlideIndex", "aiChangeBatch", "aiPickMode", "drawTool", "drawColor", "drawWidth"], outputs: ["elementSelect", "backgroundClick", "transformStart", "transformUpdate", "transformEnd", "adjustUpdate", "connectorEndpointUpdate", "contextMenu", "textEditStart", "textCommit", "textInput", "textCancel", "textFormat", "rotateUpdate", "marqueeSelect", "inkStrokeComplete", "eraserHit", "cellCommit", "tableChange"] }, { kind: "component", type: PresentationOverlayComponent, selector: "pptx-presentation-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "startIndex", "activeCustomShow", "authoredRange", "loopContinuously", "showWithAnimation", "useTimings", "subtitlesVisible", "sessionEnded", "endWithBlackSlide", "pixelateMosaicAnimation", "presenterMode", "showMenuOnRightClick", "showPopupToolbar"], outputs: ["indexChange", "closed", "subtitlesChange", "presenterViewToggle", "annotationsExit", "customShowRequest", "endOfShowChange"] }, { kind: "component", type: PresenterViewComponent, selector: "pptx-presenter-view", inputs: ["slides", "currentSlideIndex", "activeCustomShow", "authoredRange", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime", "isAudienceWindowOpen"], outputs: ["movePresentationSlide", "exit", "openAudienceWindow", "closeAudienceWindow", "navigateToSlide"] }, { kind: "component", type: MobilePresenterViewComponent, selector: "pptx-mobile-presenter-view", inputs: ["slides", "currentSlideIndex", "activeCustomShow", "authoredRange", "canvasSize", "templateElements", "mediaDataUrls", "presentationStartTime"], outputs: ["movePresentationSlide", "exit"] }, { kind: "component", type: SlideSorterOverlayComponent, selector: "pptx-slide-sorter-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "activeIndex", "canEdit"], outputs: ["select", "closed", "deleteSlide", "duplicateSlide", "toggleHiddenSlide"] }, { kind: "component", type: OutlineViewOverlayComponent, selector: "pptx-outline-view-overlay", inputs: ["slides", "canvasSize", "canEdit"], outputs: ["commit", "closed"] }, { kind: "component", type: ReadingViewOverlayComponent, selector: "pptx-reading-view-overlay", inputs: ["slides", "canvasSize", "mediaDataUrls", "activeSlideIndex"], outputs: ["exit"] }, { kind: "component", type: SlideDefaultInspectorComponent, selector: "pptx-slide-default-inspector", inputs: ["slideIndex", "canEdit", "selectedElement", "comments", "modernCommentAuthors"], outputs: ["commentAdd", "commentRemove", "commentResolve", "commentReply"] }, { kind: "component", type: FindBarComponent, selector: "pptx-find-bar", inputs: ["slides"], outputs: ["navigate", "closed"] }, { kind: "component", type: FindReplaceBarComponent, selector: "pptx-find-replace-bar", inputs: ["matchCount", "matchIndex"], outputs: ["find", "navigate", "replaceOne", "replaceAll", "close"] }, { kind: "component", type: SlidesPanelComponent, selector: "pptx-slides-panel", inputs: ["canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["select"] }, { kind: "component", type: StatusBarComponent, selector: "pptx-status-bar", inputs: ["slideIndex", "slideCount", "canEdit", "dirty", "autosaveStatus", "notesOpen", "zoomPercent", "sorterActive", "presenting", "hiddenActions"], outputs: ["toggleNotes", "normalView", "openSorter", "slideShow", "zoomIn", "zoomOut", "zoomReset"] }, { kind: "component", type: EditorContextMenuComponent, selector: "pptx-editor-context-menu", inputs: ["x", "y", "slideIndex", "showAiActions"], outputs: ["closed", "askAi", "fixAi", "editHyperlink", "addComment"] }, { kind: "component", type: ExportProgressModalComponent, selector: "pptx-export-progress-modal", inputs: ["open", "title", "progress", "statusMessage"], outputs: ["cancel"] }, { kind: "component", type: CommentMarkersOverlayComponent, selector: "pptx-comment-markers-overlay", inputs: ["comments", "canvasSize"], outputs: ["markerClick"] }, { kind: "component", type: CommentsPanelComponent, selector: "pptx-comments-panel", inputs: ["comments", "authorName", "modernCommentAuthors"], outputs: ["add", "remove", "resolve", "reply"] }, { kind: "component", type: CompatToastsComponent, selector: "pptx-compat-toasts", inputs: ["toasts"], outputs: ["dismissOne", "dismissAll"] }, { kind: "component", type: ReadOnlyBannerComponent, selector: "pptx-readonly-banner", inputs: ["kind", "messageKey", "passwordPromptOpen", "passwordError", "checkingPassword"], outputs: ["editAnyway", "dismiss", "submitPassword", "cancelPassword"] }, { kind: "component", type: SignaturesPanelComponent, selector: "pptx-signatures-panel", inputs: ["signatures"] }, { kind: "component", type: AccessibilityPanelComponent, selector: "pptx-accessibility-panel", inputs: ["issues"], outputs: ["selectSlide"] }, { kind: "component", type: CollaborationCursorsComponent, selector: "pptx-collaboration-cursors", inputs: ["cursors", "zoom"] }, { kind: "component", type: RemoteSelectionOverlayComponent, selector: "pptx-remote-selection-overlay", inputs: ["presences", "elements", "activeSlideIndex", "zoom"] }, { kind: "component", type: MotionPathOverlayComponent, selector: "pptx-motion-path-overlay", inputs: ["element", "animations", "canvasSize", "canEdit"], outputs: ["pathChange"] }, { kind: "component", type: FollowModeBarComponent, selector: "pptx-follow-mode-bar", inputs: ["presences", "followedClientId"], outputs: ["follow"] }, { kind: "component", type: PropertiesDialogComponent, selector: "pptx-properties-dialog", inputs: ["open", "properties"], outputs: ["save", "close"] }, { kind: "component", type: HyperlinkDialogComponent, selector: "pptx-hyperlink-dialog", inputs: ["open", "element"], outputs: ["save", "close"] }, { kind: "component", type: PrintDialogComponent, selector: "pptx-print-dialog", inputs: ["slides", "activeSlideIndex", "defaultSlidesPerPage", "defaultFrameSlides", "defaultSettings"], outputs: ["print", "cancel"] }, { kind: "component", type: ShareDialogComponent, selector: "pptx-share-dialog", inputs: ["open", "defaults", "active", "connected", "userCount", "shareUrl", "p2p", "activeRoomId", "activeServerUrl", "users"], outputs: ["start", "stop", "close"] }, { kind: "component", type: BroadcastDialogComponent, selector: "pptx-broadcast-dialog", inputs: ["open", "defaults", "active", "connected", "viewerCount", "viewerUrl", "p2p"], outputs: ["start", "stop", "close"] }, { kind: "component", type: MobileBottomBarComponent, selector: "pptx-mobile-bottom-bar", inputs: ["slideCount", "commentCount", "activeSheet"], outputs: ["openSlides", "insert", "openFormat", "openComments", "notes"] }, { kind: "component", type: MobileMenuSheetComponent, selector: "pptx-mobile-menu-sheet", inputs: ["open", "slideCount", "exporting", "showNotes", "canEdit", "hiddenActions"], outputs: ["closed", "openFind", "openSorter", "toggleNotes", "insertText", "present", "openFile", "savePptx", "exportPng", "exportPdf", "exportGif", "exportVideo", "print"] }, { kind: "component", type: MobileSlidesSheetComponent, selector: "pptx-mobile-slides-sheet", inputs: ["open", "slides", "canvasSize", "mediaDataUrls", "activeIndex"], outputs: ["closed", "jumpToSlide"] }, { kind: "component", type: MobileToolbarComponent, selector: "pptx-mobile-toolbar", inputs: ["canUndo", "canRedo", "canPresent", "canEdit", "menuOpen", "aiEnabled", "aiPanelOpen", "hiddenActions"], outputs: ["toggleMenu", "toggleAiPanel", "undo", "redo", "share", "save", "present"] }, { kind: "component", type: MasterViewCanvasComponent, selector: "pptx-master-view-canvas", inputs: ["tab", "slideMasters", "activeMasterIndex", "activeLayoutIndex", "notesMaster", "handoutMaster", "canvasSize", "notesCanvasSize", "mediaDataUrls", "editable"], outputs: ["notesMasterChange", "handoutMasterChange", "slideMastersChange"] }, { kind: "component", type: MasterViewSidebarComponent, selector: "pptx-master-view-sidebar", inputs: ["tab", "slideMasters", "notesMaster", "handoutMaster", "activeMasterIndex", "activeLayoutIndex", "handoutSlidesPerPage", "editable", "crudActions"], outputs: ["tabChange", "selectMaster", "selectLayout", "slidesPerPageChange", "backgroundChange", "close", "crudAction"] }, { kind: "component", type: NotesPanelComponent, selector: "pptx-notes-panel", inputs: ["slide", "expanded", "notesStyle"], outputs: ["update", "notesToggle"] }, { kind: "component", type: QuickAccessStripComponent, selector: "pptx-quick-access-strip", inputs: ["quickAccess", "canUndo", "canRedo"], outputs: ["command"] }, { kind: "component", type: RibbonComponent, selector: "pptx-ribbon", inputs: ["slideIndex", "slideCount", "canEdit", "selectedElement", "zoomPercent", "formatPainterActive", "canActivateFormatPainter", "exporting", "hasMacros", "showGrid", "showRulers", "showGuides", "snapToGrid", "snapToShape", "eyedropperActive", "themeGalleryOpen", "sidebarCollapsed", "inspectorOpen", "commentsOpen", "commentCount", "findOpen", "collabConnected", "connectedCount", "spellCheckEnabled", "showSubtitles", "hiddenActions", "aiEnabled", "aiPanelOpen", "accountAuth", "activeSlideHidden"], outputs: ["prev", "next", "zoomIn", "zoomOut", "zoomReset", "find", "present", "presenter", "record", "presentFromBeginning", "rehearseTimings", "toggleSubtitles", "openSubtitleSettings", "recordFromBeginning", "recordFromCurrent", "spellCheckChange", "share", "broadcast", "openFile", "openRecentFile", "createPresentation", "save", "savePpsx", "savePptm", "savePpt", "toggleSidebar", "toggleAiPanel", "signatures", "info", "print", "comments", "a11y", "shortcuts", "versionHistory", "passwordProtection", "fontEmbedding", "link", "openSorter", "openReadingView", "openOutlineView", "openMasterView", "toggleNotes", "toggleFormatPainter", "exportPng", "exportPdf", "exportGif", "exportVideo", "exportJson", "copySlideAsImage", "replace", "toggleInspector", "openAnimationPanel", "drawToolChange", "toggleThemeGallery", "editTheme", "openSlideSize", "toggleGrid", "toggleRulers", "toggleGuides", "toggleSelectionPane", "openCustomShows", "toggleSnapToGrid", "toggleSnapToShape", "addGuide", "zoomToFit", "toggleEyedropper", "openSmartArtDialog", "openTemplateGallery", "openEquationDialog", "openSetUpSlideShow", "toggleHideSlide", "openCompare", "openPassword", "openFontEmbedding", "openVersionHistory", "openShortcuts", "openSettings"] }, { kind: "component", type: TitleBarComponent, selector: "pptx-title-bar", inputs: ["canEdit", "fileName", "isDirty", "autosaveStatus", "autosaveEnabled", "canUndo", "canRedo", "undoLabel", "redoLabel", "findReplaceOpen", "hiddenActions", "quickAccess"], outputs: ["toggleAutosave", "save", "undo", "redo", "quickCommand", "toggleFindReplace", "commandSearch"] }, { kind: "component", type: ThemeGalleryComponent, selector: "pptx-theme-gallery", inputs: ["open", "activeName", "theme", "startCustomizing"], outputs: ["applyTheme", "applyCustomTheme", "close"] }, { kind: "component", type: SelectionPaneComponent, selector: "pptx-selection-pane", inputs: ["elements", "selectedIds"], outputs: ["selectElement", "bringForward", "sendBackward", "toggleHidden", "renameElement"] }, { kind: "component", type: CustomShowsComponent, selector: "pptx-custom-shows", inputs: ["open", "slides", "customShows", "activeCustomShowId"], outputs: ["create", "remove", "update", "setActive", "close"] }, { kind: "component", type: InsertSmartArtDialogComponent, selector: "pptx-insert-smart-art-dialog", inputs: ["open"], outputs: ["close", "insert"] }, { kind: "component", type: SlideTemplateGalleryDialogComponent, selector: "pptx-slide-template-gallery-dialog", inputs: ["open", "scheme"], outputs: ["close", "insert"] }, { kind: "component", type: ViewerExtraDialogsComponent, selector: "pptx-viewer-extra-dialogs", inputs: ["activeSlideIndex", "selectedElementId", "filePath", "customShows", "themeKey", "availableThemes", "localeCode", "availableLocales", "aiExportVisible"], outputs: ["restoreContent", "themeKeySelect", "localeSelect"] }, { kind: "component", type: AutosaveRecoveryDialogComponent, selector: "pptx-autosave-recovery-dialog", inputs: ["prompt"], outputs: ["restore", "discard"] }, { kind: "component", type: RehearseTimingsComponent, selector: "pptx-rehearse-timings", inputs: ["summary", "paused", "slideStartedAt", "presentationStartedAt", "timings"], outputs: ["togglePause", "save", "discard"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, deferBlockDependencies: [() => [/* @ts-ignore */
178844
179260
  Promise.resolve().then(function () { return aiChatPanel_component; }).then(m => m.AiChatPanelComponent)]] }); }
178845
179261
  }
178846
179262
  i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.6", ngImport: i0, type: PowerPointViewerComponent, resolveDeferredDeps: () => [/* @ts-ignore */
@@ -179160,6 +179576,8 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.6", ng
179160
179576
  [canvasSize]="loader.canvasSize()"
179161
179577
  [mediaDataUrls]="loader.mediaDataUrls()"
179162
179578
  [zoom]="zoomSvc.zoom()"
179579
+ [fitPadding]="fitPadding()"
179580
+ [maxFitScale]="maxFitScale()"
179163
179581
  [editable]="canEdit()"
179164
179582
  [selectedIds]="editor.selectedIds()"
179165
179583
  [showGrid]="showGrid()"
@@ -179861,7 +180279,7 @@ i0.ɵɵngDeclareClassMetadataAsync({ minVersion: "18.0.0", version: "22.1.6", ng
179861
180279
  </div>
179862
180280
  `,
179863
180281
  }]
179864
- }], ctorParameters: () => [], propDecorators: { content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: false }] }], fontsInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "fonts", required: false }] }], canEditInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], defaultThemeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultThemeKey", required: false }] }], availableThemes: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableThemes", required: false }] }], onThemeChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "onThemeChange", required: false }] }], defaultLocale: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultLocale", required: false }] }], availableLocales: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableLocales", required: false }] }], onLocaleChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "onLocaleChange", required: false }] }], accountAuth: [{ type: i0.Input, args: [{ isSignal: true, alias: "accountAuth", required: false }] }], filePath: [{ type: i0.Input, args: [{ isSignal: true, alias: "filePath", required: false }] }], fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: false }] }], autosaveInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "autosave", required: false }] }], autosaveIntervalMs: [{ type: i0.Input, args: [{ isSignal: true, alias: "autosaveIntervalMs", required: false }] }], collaboration: [{ type: i0.Input, args: [{ isSignal: true, alias: "collaboration", required: false }] }], authorName: [{ type: i0.Input, args: [{ isSignal: true, alias: "authorName", required: false }] }], shareDefaults: [{ type: i0.Input, args: [{ isSignal: true, alias: "shareDefaults", required: false }] }], onOpenFile: [{ type: i0.Input, args: [{ isSignal: true, alias: "onOpenFile", required: false }] }], smartArt3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "smartArt3D", required: false }] }], surfaceChart3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceChart3D", required: false }] }], barChart3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "barChart3D", required: false }] }], lineChart3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "lineChart3D", required: false }] }], areaChart3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "areaChart3D", required: false }] }], pieChart3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "pieChart3D", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], ai: [{ type: i0.Input, args: [{ isSignal: true, alias: "ai", required: false }] }], activeSlideChange: [{ type: i0.Output, args: ["activeSlideChange"] }], dirtyChange: [{ type: i0.Output, args: ["dirtyChange"] }], contentChange: [{ type: i0.Output, args: ["contentChange"] }], propertiesChange: [{ type: i0.Output, args: ["propertiesChange"] }], modeChange: [{ type: i0.Output, args: ["modeChange"] }], zoomChange: [{ type: i0.Output, args: ["zoomChange"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], slideCountChange: [{ type: i0.Output, args: ["slideCountChange"] }], startCollaboration: [{ type: i0.Output, args: ["startCollaboration"] }], stopCollaboration: [{ type: i0.Output, args: ["stopCollaboration"] }], extraDialogs: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ViewerExtraDialogsComponent), { isSignal: true }] }], mainEl: [{ type: i0.ViewChild, args: ['mainEl', { isSignal: true }] }], onKeyDown: [{
180282
+ }], ctorParameters: () => [], propDecorators: { content: [{ type: i0.Input, args: [{ isSignal: true, alias: "content", required: false }] }], fontsInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "fonts", required: false }] }], canEditInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], class: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], defaultThemeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultThemeKey", required: false }] }], availableThemes: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableThemes", required: false }] }], onThemeChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "onThemeChange", required: false }] }], defaultLocale: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultLocale", required: false }] }], availableLocales: [{ type: i0.Input, args: [{ isSignal: true, alias: "availableLocales", required: false }] }], onLocaleChange: [{ type: i0.Input, args: [{ isSignal: true, alias: "onLocaleChange", required: false }] }], accountAuth: [{ type: i0.Input, args: [{ isSignal: true, alias: "accountAuth", required: false }] }], filePath: [{ type: i0.Input, args: [{ isSignal: true, alias: "filePath", required: false }] }], fileName: [{ type: i0.Input, args: [{ isSignal: true, alias: "fileName", required: false }] }], fitPadding: [{ type: i0.Input, args: [{ isSignal: true, alias: "fitPadding", required: false }] }], maxFitScale: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFitScale", required: false }] }], autosaveInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "autosave", required: false }] }], autosaveIntervalMs: [{ type: i0.Input, args: [{ isSignal: true, alias: "autosaveIntervalMs", required: false }] }], collaboration: [{ type: i0.Input, args: [{ isSignal: true, alias: "collaboration", required: false }] }], authorName: [{ type: i0.Input, args: [{ isSignal: true, alias: "authorName", required: false }] }], shareDefaults: [{ type: i0.Input, args: [{ isSignal: true, alias: "shareDefaults", required: false }] }], onOpenFile: [{ type: i0.Input, args: [{ isSignal: true, alias: "onOpenFile", required: false }] }], smartArt3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "smartArt3D", required: false }] }], surfaceChart3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceChart3D", required: false }] }], barChart3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "barChart3D", required: false }] }], lineChart3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "lineChart3D", required: false }] }], areaChart3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "areaChart3D", required: false }] }], pieChart3D: [{ type: i0.Input, args: [{ isSignal: true, alias: "pieChart3D", required: false }] }], hiddenActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hiddenActions", required: false }] }], ai: [{ type: i0.Input, args: [{ isSignal: true, alias: "ai", required: false }] }], activeSlideChange: [{ type: i0.Output, args: ["activeSlideChange"] }], dirtyChange: [{ type: i0.Output, args: ["dirtyChange"] }], contentChange: [{ type: i0.Output, args: ["contentChange"] }], propertiesChange: [{ type: i0.Output, args: ["propertiesChange"] }], modeChange: [{ type: i0.Output, args: ["modeChange"] }], zoomChange: [{ type: i0.Output, args: ["zoomChange"] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], slideCountChange: [{ type: i0.Output, args: ["slideCountChange"] }], startCollaboration: [{ type: i0.Output, args: ["startCollaboration"] }], stopCollaboration: [{ type: i0.Output, args: ["stopCollaboration"] }], extraDialogs: [{ type: i0.ViewChild, args: [i0.forwardRef(() => ViewerExtraDialogsComponent), { isSignal: true }] }], mainEl: [{ type: i0.ViewChild, args: ['mainEl', { isSignal: true }] }], onKeyDown: [{
179865
180283
  type: HostListener,
179866
180284
  args: ['document:keydown', ['$event']]
179867
180285
  }], clearCacheOnUnload: [{
@@ -182140,4 +182558,4 @@ function cn(...values) {
182140
182558
  */
182141
182559
 
182142
182560
  export { CollaborationService as $, AFTER_ANIMATION_VALUES as A, AnimationAuthorPanelComponent as B, AnimationPanelComponent as C, AnimationPlaybackService as D, AutosaveRecoveryDialogComponent as E, AutosaveService as F, BroadcastDialogComponent as G, CHART_EDITOR_STYLES as H, CURSOR_PALETTE as I, CanvasFitService as J, ChartAxisOptionsComponent as K, ChartAxisStyleOptionsComponent as L, ChartComboTypeOptionsComponent as M, ChartDataEditorComponent as N, ChartDataLabelOptionsComponent as O, ChartDatapointMarkerOptionsComponent as P, ChartDatapointOptionsComponent as Q, ChartDisplayOptionsComponent as R, ChartElementViewComponent as S, ChartErrorBarOptionsComponent as T, ChartMarkerOptionsComponent as U, ChartPartSelectionService as V, ChartPrimitivesComponent as W, ChartRendererComponent as X, ChartTrendlineOptionsComponent as Y, ChartTypeSelectorComponent as Z, CollaborationCursorsComponent as _, ALIGN_OPTIONS as a, InsertSmartArtDialogComponent as a$, ColorChangedImageComponent as a0, CommentMarkersOverlayComponent as a1, CommentsPanelComponent as a2, CommentsService as a3, ComparePanelComponent as a4, ConnectorRendererComponent as a5, ConnectorTextOverlayComponent as a6, CustomShowsComponent as a7, DEFAULT_BOUNDS as a8, DEFAULT_BROADCAST_SERVER_URL as a9, EditorToolbarComponent as aA, EffectsPanelComponent as aB, ElementRendererComponent as aC, EmbeddedFontsService as aD, EncryptedFileDialogComponent as aE, EquationEditorDialogComponent as aF, EquationRendererComponent as aG, EquationTemplateGalleryComponent as aH, ExportProgressModalComponent as aI, ExportService as aJ, FieldContextService as aK, FindBarComponent as aL, FindReplaceBarComponent as aM, FollowModeBarComponent as aN, FontEmbeddingListComponent as aO, FontEmbeddingPanelComponent as aP, GALLERY_THEME_PRESETS as aQ, GOOGLE_WEBFONTS_LINK_ID as aR, GRIDLINE_COLOR$1 as aS, GoogleWebfontsService as aT, GradientPickerComponent as aU, HANDOUT_OPTIONS as aV, HeaderFooterDialogComponent as aW, HyperlinkDialogComponent as aX, ImagePropertiesPanelComponent as aY, InkDrawingService as aZ, InkRendererComponent as a_, DEFAULT_CANVAS_HEIGHT as aa, DEFAULT_CANVAS_WIDTH as ab, DEFAULT_COLOR_SCHEME as ac, DEFAULT_FILL_COLOR$1 as ad, DEFAULT_LAYOUT as ae, DEFAULT_PALETTE$1 as af, DEFAULT_PATTERN_FILL_PRESET as ag, DEFAULT_PRINT_SETTINGS as ah, DEFAULT_SLIDE_BACKGROUND as ai, DEFAULT_STROKE_COLOR as aj, DEFAULT_STYLE as ak, DEFAULT_TABLE_ROW_HEIGHT as al, DEFAULT_TEXT_COLOR$2 as am, DEFAULT_VIEWER_PROFILE as an, DIRECTIONAL_PRESETS as ao, DIRECTION_OPTIONS as ap, DocumentPropertiesCardComponent as aq, EFFECT_SOUND_CATALOGUE as ar, EMBEDDED_FONTS_STYLE_ID as as, EMPHASIS_PRESETS as at, ENTRANCE_PRESETS as au, TEMPLATES as av, EXIT_PRESETS as aw, EditorContextMenuComponent as ax, EditorHistory as ay, EditorStateService as az, ANIMATION_PRESET_CATEGORIES as b, RibbonArrangeSectionComponent as b$, InspectorPaneHeaderComponent as b0, InspectorPanelComponent as b1, IsMobileService as b2, KeepAnnotationsDialogComponent as b3, LOCALE_CATALOG as b4, LONG_PRESS_DURATION_MS as b5, LONG_PRESS_MOVE_TOLERANCE_PX as b6, LoadContentService as b7, LocalPresencePublisher as b8, MAX_ZOOM_SCALE as b9, PX_PER_INCH as bA, PasswordProtectionDialogComponent as bB, PasswordStrengthMeterComponent as bC, PowerPointViewerComponent as bD, PresentToolbarAutoHide as bE, PresentationAnnotationOverlayComponent as bF, PresentationAnnotationsService as bG, PresentationOverlayComponent as bH, PresentationPropertiesPanelComponent as bI, PresentationSettingsCardComponent as bJ, PresentationSubtitleBarComponent as bK, PresentationToolbarComponent as bL, PresentationTransitionOverlayComponent as bM, PresenterViewComponent as bN, PresenterWindowService as bO, PrintDialogComponent as bP, PrintService as bQ, PrintSettingsPanelComponent as bR, PropertiesDialogComponent as bS, REPEAT_MODE_OPTIONS as bT, RESIZE_HANDLES as bU, RULER_FONT_SIZE as bV, RULER_THICKNESS as bW, ReadingViewOverlayComponent as bX, RemoteSelectionOverlayComponent as bY, RibbonAnimationGalleryComponent as bZ, RibbonAnimationsSectionComponent as b_, MIN_ZOOM_SCALE as ba, MOTION_PATH_COLUMNS as bb, MediaPreviewComponent as bc, MediaPropertiesPanelComponent as bd, MediaRendererComponent as be, MediaTrimTimelineComponent as bf, MobileBottomBarComponent as bg, MobileMenuSheetComponent as bh, MobilePresenterViewComponent as bi, MobileSheetComponent as bj, MobileSlidesSheetComponent as bk, MobileToolbarComponent as bl, ModalDialogComponent as bm, Model3DRendererComponent as bn, NotesHandoutCardComponent as bo, NotesPanelComponent as bp, NotesToolbarComponent as bq, OleRendererComponent as br, OutlineViewOverlayComponent as bs, POWER_POINT_VIEWER_PROVIDERS as bt, PPTX_OPEN_ACCEPT as bu, PRESENTATION_OPEN_EXTENSIONS as bv, PRESENTER_CHANNEL_NAME as bw, PRESENTER_MSG_ORIGIN as bx, PRESENTER_TIMER_SEGMENT_MS as by, PX_PER_CM as bz, AUDIENCE_HASH as c, TABLE_STRUCTURE_TOGGLES as c$, RibbonColorPopoverComponent as c0, RibbonComponent as c1, RibbonDesignSectionComponent as c2, RibbonDrawSectionComponent as c3, RibbonDrawingGroupComponent as c4, RibbonEditingSectionComponent as c5, RibbonFileSectionComponent as c6, RibbonFontControlsComponent as c7, RibbonHomeSectionComponent as c8, RibbonHyperlinkButtonComponent as c9, SettingsAppearanceTabComponent as cA, SettingsDialogComponent as cB, SettingsLanguageTabComponent as cC, ShareDialogComponent as cD, ShortcutPanelComponent as cE, ShowOptionsFieldsetComponent as cF, ShowSlidesFieldsetComponent as cG, SignatureStrippedDialogComponent as cH, SignaturesPanelComponent as cI, SignaturesService as cJ, SlideBackgroundCardComponent as cK, SlideCanvasComponent as cL, SlideDefaultInspectorComponent as cM, SlideDiffChangesComponent as cN, SlideDiffRowComponent as cO, SlideDiffThumbnailsComponent as cP, SlideSizeCardComponent as cQ, SlideSorterOverlayComponent as cR, SlideThemeOverridePanelComponent as cS, SlideTransitionCardComponent as cT, SlidesPanelComponent as cU, SmartArt3DRendererComponent as cV, SmartArt3DService as cW, SmartArtPreviewComponent as cX, SmartArtPropertiesComponent as cY, SmartArtRendererComponent as cZ, StatusBarComponent as c_, RibbonInsertFieldsComponent as ca, RibbonInsertSectionComponent as cb, RibbonMotionPathGalleryComponent as cc, RibbonParagraphControlsComponent as cd, RibbonPrimaryRowComponent as ce, RibbonReviewSectionComponent as cf, RibbonShapeExtrasComponent as cg, RibbonSlideshowSectionComponent as ch, RibbonTransitionsSectionComponent as ci, RibbonViewSectionComponent as cj, RulerGuidesService as ck, SEQUENCE_OPTIONS as cl, SEVERITY_GROUPS as cm, SEVERITY_LABELS as cn, SHORTCUT_REFERENCE_ITEMS as co, SLIDE_TRANSITION_KEYFRAMES as cp, DEFAULT_PALETTE as cq, PALETTES$1 as cr, SMART_ART_COLOR_SCHEMES as cs, SMART_ART_STYLE_OPTIONS as ct, SUB_ITEM_LABEL as cu, SVG_WARP_PRESETS as cv, SWIPE_MAX_VERTICAL_PX as cw, SWIPE_THRESHOLD_PX as cx, SelectionPaneComponent as cy, SetUpSlideShowDialogComponent as cz, AUDIENCE_NONCE_KEY as d, alignPatch as d$, TEXT_3D_BOTTOM_BEVEL_KEYS as d0, TEXT_3D_TOP_BEVEL_KEYS as d1, TEXT_DIRECTION_OPTIONS$1 as d2, THEME_CATALOG as d3, TIMING_CURVE_OPTIONS as d4, TRIGGER_OPTIONS as d5, TYPE_LABELS as d6, TableCellAdvancedFillComponent as d7, TableCellFormattingComponent as d8, TableDataEditorComponent as d9, ViewerExportService as dA, ViewerExtraDialogsComponent as dB, ViewerFileIOService as dC, ViewerFindReplaceService as dD, ViewerFormatPainterService as dE, ViewerInspectorPanelService as dF, ViewerKeyboardService as dG, ViewerMobileSheetService as dH, ViewerPresentationModeService as dI, ViewerThemeGalleryService as dJ, ViewerTouchGesturesService as dK, ViewerZoomService as dL, WEBM_MIME_CANDIDATES as dM, WriteBackScheduler as dN, ZERO_LINE_COLOR as dO, ZoomNavigationService as dP, ZoomRendererComponent as dQ, ZoomTargetService as dR, addCategory as dS, addCommentToList as dT, addGradientStopPatch as dU, addItem as dV, addSeries as dW, addSubItem as dX, advanceStep as dY, affordanceElements as dZ, aiToggleVisible as d_, TablePropertiesComponent as da, TableRendererComponent as db, TableResizeOverlayComponent as dc, TableSelectionService as dd, TagsCardComponent as de, Text3DBevelSectionComponent as df, Text3DPanelComponent as dg, TextAdvancedPanelComponent as dh, ThemeEditorFieldsComponent as di, ThemeGalleryComponent as dj, ThemeSelectorCardComponent as dk, TitleBarComponent as dl, TitleBarSearchComponent as dm, TransitionDirectionPickerComponent as dn, TransitionPreviewComponent as dp, VALIGN_OPTIONS as dq, VIEWER_THEME as dr, VersionHistoryPanelComponent as ds, ViewerCanvasEditingService as dt, ViewerCollabCursorService as du, ViewerCollaborationSessionService as dv, ViewerCompareService as dw, ViewerCustomShowsService as dx, ViewerDialogsService as dy, ViewerDocumentPropertiesService as dz, AVATAR_COLOR_SWATCHES as e, buildSmartArtNodes as e$, animationFor as e0, animationPresetLabelKey as e1, annotationMapToInkInserts as e2, applyAcceptedDiff as e3, applyAnimationPreset as e4, applyFindReplacements as e5, applyFormatToElement as e6, applyMove as e7, applyResize as e8, asMediaElement as e9, buildDuotoneFilterId as eA, buildEmbeddedFontStyles as eB, buildEquationElement as eC, buildEquationSegment as eD, buildFallbackViewModel as eE, buildFontFaceRule as eF, buildGradientFillCss as eG, buildGridlinesAndLabels as eH, buildHyperlinkPatch as eI, buildInkContainerStyle as eJ, buildInkStrokes as eK, buildLegend as eL, buildLiveInkStrokeView as eM, buildMarkTooltip as eN, buildModel3DContainerStyle as eO, buildModel3DViewModel as eP, buildOleActionModel as eQ, buildOleInfoRows as eR, buildPatternFillCss as eS, buildPieViewModel as eT, buildPrintHtmlDocument as eU, buildPropertiesPatch as eV, buildRadarViewModel as eW, buildRegionMapViewModel as eX, buildSaveSlides as eY, buildShareUrl as eZ, buildSmartArtInsertElement as e_, assignUserColor as ea, attachShowVisibilityPause as eb, attachTouchGestures as ec, axisTickValues as ed, beginDrawingNodeEdit as ee, beginNodeEdit as ef, bevelSizePatch as eg, boolFromEvent as eh, bringForward as ei, bringToFront as ej, buildBarActions as ek, buildBroadcastConfig as el, buildBroadcastViewerUrl as em, buildCategoryLabels as en, buildCellParagraphs as eo, buildChartViewModel as ep, buildChatLogExport as eq, buildChatLogMarkdown as er, buildChromeStyle as es, buildClearHyperlinkPatch as et, buildClickGroups as eu, buildColStyles as ev, buildCollaborationConfig as ew, buildComboViewModel as ex, buildCssGradientFromShapeStyle as ey, buildDuotoneFilter as ez, AXIS_LABEL_COLOR as f, computePieSlices as f$, buildStockViewModel as f0, buildSurfaceViewModel as f1, buildTableViewModel as f2, buildTreemapViewModel as f3, buildTrimFragment as f4, buildWaterfallViewModel as f5, buildZeroLine as f6, buildZoomContainerStyle as f7, buildZoomViewModel as f8, bulletIndentPx as f9, cn as fA, collectAccessibilityIssues as fB, collectElementText as fC, collectSlideText as fD, collectStoredChats as fE, collectUsedFontFamilies as fF, columnWidthStyle as fG, commitNodeText as fH, computeAlign as fI, computeAxisTitlePrimitives as fJ, computeBarRects as fK, computeBubbleRadius as fL, computeCornerHandle as fM, computeDistribute as fN, computeDrawingViewBox as fO, computeErrorBarPrimitives as fP, computeFocusTargets as fQ, computeGridSpacingPx as fR, computeHandleBoxes as fS, computeHandoutLayout as fT, computeIsMobile as fU, computeIsTablet as fV, computeLinePoints as fW, computeLinearRegression as fX, computePageCount as fY, computePieLayout as fZ, computePieSlicePath as f_, canAddTopLevelNode as fa, canEditSmartArtNodes as fb, canGroupSelection as fc, canRemoveTopLevelNode as fd, canSetStrokeWidth as fe, canStartBroadcast as ff, canStartShare as fg, canUngroupSelection as fh, canUseClipboard as fi, captionDisplayText as fj, cellRunStyle as fk, cellStyleToStyleMap as fl, cellTdStyle as fm, changeCountLabel as fn, changeIcon as fo, characterSpacingPatch as fp, chartPreserveAspectRatio as fq, checkFontAvailable as fr, clampCursorPosition as fs, clampGifDimensions as ft, clampIndex as fu, clampNotesFontSize as fv, clampScale as fw, clampStep as fx, clearAllLocalViewerData as fy, clearAudienceContent as fz, AccessibilityPanelComponent as g, fitZoom as g$, computePlotLayout as g0, computeRSquared as g1, computeRadarPoints as g2, computeResizeHandleBoxes as g3, computeRotateHandleBox as g4, computeScatterDots as g5, computeScatterXDomain as g6, computeSelectionBoxes as g7, computeSingleSelected as g8, computeSlideIndices as g9, describeSmartArtBounds as gA, disableGlowPatch as gB, disableInnerShadowPatch as gC, disableOuterShadowPatch as gD, disableReflectionPatch as gE, disableSoftEdgePatch as gF, duplicateElementById as gG, durationOf as gH, effectsStateOf as gI, enableGlowPatch as gJ, enableInnerShadowPatch as gK, enableOuterShadowPatch as gL, enableReflectionPatch as gM, enableSoftEdgePatch as gN, encodeGif as gO, endShowMediaCleanup as gP, estimatePageCount as gQ, exitPresentationFullscreen as gR, exportAiChatLogs as gS, extractPathPoints as gT, eyedropperAvailable as gU, fillColorOf$1 as gV, findInSlides as gW, findOwningSlideIndex as gX, findSlideIndexByElementId as gY, firstVisibleIndex as gZ, fitPolynomial as g_, computeSnap as ga, computeStackedBarRects as gb, computeStackedValueRange as gc, computeTrendlinePrimitives as gd, computeValueRange as ge, convertOmmlToMathMl as gf, copyFormatFromElement as gg, countAccessibilityIssues as gh, countAnnotationStrokes as gi, createAngularAiBridge as gj, createCustomShow as gk, createSwipeDismissDrag as gl, createWebrtcBundle as gm, createWebsocketBundle as gn, cssObjectToStyleMap as go, currentColorScheme as gp, currentLayout as gq, currentStyle as gr, defaultCssVars as gs, defaultRadius as gt, defaultThemeColors as gu, deleteElementsByIds as gv, deleteVersion as gw, demoteNode as gx, deriveModel3DBlobUrl as gy, derivePresenceList as gz, AccessibilityService as h, insertTableElementColumn as h$, focusTargetChips as h0, fontMimeForFormat as h1, fontSizeOf as h2, forgetSessionDeck as h3, formatAxisValue as h4, formatBytes as h5, formatCursorLabel as h6, formatElapsed as h7, formatFileSize as h8, formatPropertyDate as h9, getSessionTabId as hA, getShapeFillStrokeStyle as hB, getSlideBackgroundStyle as hC, getSlideTransitionAnimations as hD, getSmartArtNodeBounds as hE, getSpeechRecognitionCtor as hF, getTextBlockStyle as hG, getTextWarp as hH, getTouchDistance as hI, getWarpCategory as hJ, getWarpPath as hK, gradientStateFromStyle as hL, gradientStateOf as hM, gradientStatePatch as hN, gradientStopColorCommitPatch as hO, gridColumns as hP, groupIssuesBySeverity as hQ, hasAnimation as hR, hasCopyableFormat as hS, hasExistingLink as hT, hasExitedFullscreen as hU, hasGradientFill as hV, hasPressureVariation as hW, hasVisibleSlideAfter as hX, headerLabel as hY, imageDimensions as hZ, inkViewBox as h_, formatTime as ha, fpsToFrameIntervalMs as hb, generateBroadcastRoomId as hc, generateCommentId as hd, generateCustomShowId as he, generatePressureCircles as hf, generateTicks as hg, getClrChangeParams as hh, getContainerStyle as hi, getDuotoneFilterDef as hj, getEffectSoundAsset as hk, getEffectSoundState as hl, getImageSrc as hm, getLocalStorageUsageSummary as hn, getOleAriaLabel as ho, getOleBadgeLabel as hp, getOleDisplayName as hq, getOleDownloadFileName as hr, getOleTypeColor as hs, getOleTypeLabel as ht, getPasswordStrength as hu, getPatternSvg as hv, getPlaceholderStyle as hw, getVersions as hx, getResolvedShapeClipPath as hy, getResolvedShapeClipPathFor as hz, AccessibilityTextPanelComponent as i, normalizeFontFormat as i$, insertTableElementRow as i0, interpolateWidth as i1, isAudienceTab as i2, isBold as i3, isBrowserOpenableMime as i4, isChildNode as i5, isElementInteractive as i6, isInjectableUrl as i7, isItalic as i8, isLegacyBinaryPresentation as i9, mergeCaptionResults as iA, mergeDown as iB, mergeRight as iC, mergeSelection as iD, mergeTablesDirective as iE, moveElementBy as iF, moveNodeDown as iG, moveNodeUp as iH, msToFrameDelayCs as iI, narrowToCircle as iJ, narrowToPolygon as iK, narrowToRect as iL, newChartElement as iM, newEquationElement as iN, newPresetShapeElement as iO, newShapeElement as iP, newSmartArtElement as iQ, newTableElement as iR, newTextElement as iS, nextVisibleIndex as iT, nodeBold as iU, nodeEditBox as iV, nodeFillColor as iW, nodeFontColor as iX, nodeIdFromKey as iY, nodeItalic as iZ, nodeStyle as i_, isPpactionUrl as ia, isPresenterMessage as ib, isSigned as ic, isSupportedPresentationFile as id, isTextElement as ie, isTwoTableFocus as ig, isUnderline as ih, isUrlSafe as ii, isValidRoomId as ij, isViewportBackgroundPressTarget as ik, isZoomActivationKey as il, issueTrackKey as im, issueTypeLabel as io, keyToLabel as ip, lastVisibleIndex as iq, latexToMathml as ir, layoutConnectorPaints as is, layoutNodeLabels as it, linePointsToSvgString as iu, lineSpacingPatch as iv, loadAudienceContent as iw, loadSessionDeck as ix, mediaFallbackFor as iy, mediaSurfaceFor as iz, AccountPageComponent as j, resolveOleType as j$, normalizeSlidesPerPage as j0, normalizeValue as j1, numFromEvent as j2, ommlToMathml as j3, ooxmlDashToCssBorderStyle as j4, openNativeEyeDropper as j5, overallStatus as j6, paletteColor as j7, parseAudienceNonce as j8, parseNodeTextarea as j9, radarRingPoints as jA, readAsDataUrl as jB, recordWebm as jC, registerCrossSlideAudio as jD, rememberSessionDeck as jE, removeAnimation as jF, removeCategory as jG, removeTableElementColumn as jH, removeCommentFromList as jI, removeElementAnimation as jJ, removeGradientStopPatch as jK, removeNode as jL, removeTableElementRow as jM, removeSeries as jN, renderToCanvas as jO, reorderAnimationDown as jP, reorderAnimationUp as jQ, replaceInSlides as jR, replaceMatch as jS, requestPresentationFullscreen as jT, resizeElement as jU, resolveCaptionTracks as jV, resolveChartKind as jW, resolveFontVariant as jX, resolveHyperlinkHref as jY, resolveInteractiveElementId as jZ, resolveMediaSrc as j_, partitionSlides as ja, patchChartData as jb, patchChartStyle as jc, patchTableData as jd, patchTextStyle as je, patternPresetOptions as jf, pendingElementStyles as jg, pickColorByClickFallback as jh, pickFile as ji, pickSupportedMimeType as jj, planGifFrames as jk, planVideoSegments as jl, pointFromPointerEvent as jm, pointsToSvgPathD as jn, presenceToCursors as jo, presentationBaseName as jp, presentationStageStyle as jq, presenterTimerProgress as jr, presetByLayout as js, presetsForCategory as jt, pressuresToWidths as ju, prevVisibleIndex as jv, projectDrawingShapes as jw, promoteNode as jx, provideViewerTheme as jy, radarAngle as jz, ActionSettingsPanelComponent as k, setRepeatMode as k$, resolveParagraphBullet as k0, resolvePresenterNotes as k1, resolveProfileInitial as k2, resolveRegionCode as k3, resolveRibbonCanGroup as k4, resolveSlideAutoAdvanceMs as k5, resolvePalette as k6, resolveThemeCatalogEntry as k7, resolveTransitionDuration as k8, restoreSessionDeck as k9, setAfterAnimationColor as kA, setAnimationEmphasis as kB, setAnimationEntrance as kC, setAnimationExit as kD, setAxis as kE, setAxisLogScale as kF, setAxisTitleStyle as kG, setCategoryLabel as kH, setCellText as kI, setColorScheme as kJ, setDataLabels as kK, setDataPointExplosion as kL, setDataPointFill as kM, setDataPointLabel as kN, setDataPointMarker as kO, setDelay as kP, setDirection as kQ, setDuration as kR, setEffectSound as kS, setEffectStockSound as kT, setElementPosition as kU, setGridlineStyle as kV, setLayout as kW, setLegend as kX, setNodeStyle as kY, setNodeText as kZ, setRepeatCount as k_, revealedElementStyles as ka, routeOrthogonalConnector as kb, rowStyle as kc, rulerDragToGuidePosition as kd, rulerHighlight as ke, rulerStripTicks as kf, sampleColorFromSlide as kg, sanitizeColor as kh, sanitizeSlideIndex as ki, sanitizeUserName as kj, saveViewerProfile as kk, savedPresentationFileName as kl, scanAvailableFonts as km, searchSlides as kn, seedBroadcastFields as ko, seedHyperlinkDraft as kp, seedPropertiesDraft as kq, seedShareFields as kr, segmentFrameCount as ks, selectValue$3 as kt, sendBackward as ku, sendToBack as kv, sequentialColorScale as kw, serializeWriteBack as kx, seriesColor as ky, setAfterAnimation as kz, AdvancedChartEditorComponent as l, updateOuterShadowPatch as l$, setSequence as l0, setSeriesChartType as l1, setSeriesColor as l2, setSeriesErrorBars as l3, setSeriesMarker as l4, setSeriesName as l5, setSeriesTrendline as l6, setSeriesValue as l7, setStyle as l8, setTimingCurve as l9, strokeToInkElement as lA, strokeWidthOf as lB, styleShadowFilter as lC, surfaceColor as lD, textAdvancedPatch as lE, textAdvancedStateFromStyle as lF, textAdvancedStateOf as lG, textColorOf as lH, textDirectionPatch as lI, textFontSizePatch as lJ, textStyleOf as lK, textStylePatch as lL, themeStyle as lM, themeToCssVars as lN, thumbnailHeight as lO, thumbnailZoom as lP, toggleCommentResolvedInList as lQ, toggleNodeBold as lR, toggleNodeItalic as lS, toggleSheet as lT, topLevelNodeCount as lU, transformSelectedTextCase as lV, translationsEn as lW, updateElementById as lX, updateGlowPatch as lY, updateGradientStopPatch as lZ, updateInnerShadowPatch as l_, setTitle as la, setTrigger as lb, setTriggerShapeId as lc, shapeStylePatch$1 as ld, sheetAfterNavigate as le, shouldBlockClickAdvance as lf, shouldUseSvgWarp as lg, showDirectionPicker as lh, showsTemplateAffordance as li, signatureCountLabel as lj, signatureKey as lk, signatureTimestamp as ll, signerName as lm, statusLabel as ln, slideNumberOf as lo, slidesWithReappliedLayout as lp, smartArtNodes as lq, paletteColour as lr, snapToGridStep as ls, splitCursorCell as lt, splitMergedCell as lu, statusKind as lv, statusLabel$1 as lw, storeAudienceContent as lx, stringFromEvent$5 as ly, strokeColorOf as lz, AiChangeOverlayComponent as m, updateReflectionPatch as m0, vAlignPatch as m1, validatePassword as m2, validatePrintSettings as m3, validateRoomId as m4, valueToY as m5, vermilionDarkColors as m6, vermilionDarkTheme as m7, vermilionLightColors as m8, vermilionLightTheme as m9, vermilionRadius as ma, waypointsToPathD as mb, withManualLayouts as mc, worstStatus as md, zoomTargetSlideIndex as me, AiChatPanelComponent as n, AiChatService as o, AiComposerComponent as p, AiFocusBarComponent as q, AiFocusHighlightOverlayComponent as r, AiHistoryMenuComponent as s, toChatSummary as t, AiHistoryService as u, AiMessageListComponent as v, AiPanelStore as w, AiProposalCardComponent as x, AiSettingsSectionComponent as y, AiToolCallCardComponent as z };
182143
- //# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-DMCiVwQO.mjs.map
182561
+ //# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-CY2-kaW3.mjs.map