pptx-angular-viewer 4.16.0 → 4.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (21) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/fesm2022/{pptx-angular-viewer-chart-3d-view-scene-D-8RhIEx.mjs → pptx-angular-viewer-chart-3d-view-scene-B2GMxwCZ.mjs} +2 -2
  3. package/fesm2022/{pptx-angular-viewer-chart-3d-view-scene-D-8RhIEx.mjs.map → pptx-angular-viewer-chart-3d-view-scene-B2GMxwCZ.mjs.map} +1 -1
  4. package/fesm2022/{pptx-angular-viewer-chat-history-idb-CV-VR2z1.mjs → pptx-angular-viewer-chat-history-idb-Bb82Jssm.mjs} +2 -2
  5. package/fesm2022/{pptx-angular-viewer-chat-history-idb-CV-VR2z1.mjs.map → pptx-angular-viewer-chat-history-idb-Bb82Jssm.mjs.map} +1 -1
  6. package/fesm2022/{pptx-angular-viewer-pptx-angular-viewer-Bc1e9poJ.mjs → pptx-angular-viewer-pptx-angular-viewer-ByBs8vwz.mjs} +1810 -1625
  7. package/fesm2022/{pptx-angular-viewer-pptx-angular-viewer-Bc1e9poJ.mjs.map → pptx-angular-viewer-pptx-angular-viewer-ByBs8vwz.mjs.map} +1 -1
  8. package/fesm2022/{pptx-angular-viewer-view-scene-DK5uoxBI.mjs → pptx-angular-viewer-view-scene-yiGd2Mi4.mjs} +2 -2
  9. package/fesm2022/{pptx-angular-viewer-view-scene-DK5uoxBI.mjs.map → pptx-angular-viewer-view-scene-yiGd2Mi4.mjs.map} +1 -1
  10. package/fesm2022/pptx-angular-viewer.mjs +1 -1
  11. package/i18n/de.cjs +3 -0
  12. package/i18n/de.mjs +3 -0
  13. package/i18n/es.cjs +3 -0
  14. package/i18n/es.mjs +3 -0
  15. package/i18n/fr.cjs +3 -0
  16. package/i18n/fr.mjs +3 -0
  17. package/i18n/zh-CN.cjs +3 -0
  18. package/i18n/zh-CN.mjs +3 -0
  19. package/package.json +2 -2
  20. package/types/pptx-angular-viewer.d.ts +144 -10
  21. package/types/pptx-angular-viewer.d.ts.map +1 -1
@@ -1,6 +1,6 @@
1
1
  import { NgStyle, NgTemplateOutlet, NgClass } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
- import { InjectionToken, input, output, inject, computed, ChangeDetectionStrategy, Component, signal, Injectable, DestroyRef, viewChild, effect, Injector, ElementRef, Directive, afterNextRender, untracked, HostListener, Renderer2, ViewEncapsulation, CUSTOM_ELEMENTS_SCHEMA, forwardRef, afterRenderEffect, Input, Pipe, EventEmitter, Output, linkedSignal } from '@angular/core';
3
+ import { InjectionToken, input, output, inject, computed, ChangeDetectionStrategy, Component, signal, Injectable, DestroyRef, viewChild, effect, Injector, ElementRef, Directive, afterNextRender, untracked, HostListener, Renderer2, ViewEncapsulation, CUSTOM_ELEMENTS_SCHEMA, forwardRef, afterRenderEffect, Input, linkedSignal } from '@angular/core';
4
4
  import { TranslateService, TranslatePipe, translate } from '@ngx-translate/core';
5
5
  import { evaluateCustomGeometryPathData, getShapeClipPath, getAdjustmentAwareClipPath, getShapeClipPathFromPreset, getCloudPathForRendering, evaluateCustomGeometryPaths, customGeometryPathsToSvgSubpaths, evaluatePresetShape, hasShapeProperties, ooxmlGradientAngleToCssDegrees, getShapeType, isImageLikeElement as isImageLikeElement$1, 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, resolveOoxmlPresetMapping, getCapturedPreset, resolveDirectionSubtype, capturedPresetNativeAnimation, timingCurveToAccelDecel, rebuildTableStructureInRawXml, updateCellTextInRawXml, deepCloneData, cloneTemplateElementsBySlideId, cloneSlide, MIN_ELEMENT_SIZE as MIN_ELEMENT_SIZE$1, EMU_PER_PX as EMU_PER_PX$6, DEFAULT_POWERPOINT_TABLE_STYLE_ID, DEFAULT_SCHEME_COLOR_MAP as DEFAULT_SCHEME_COLOR_MAP$1, formatAutoNumberMarker, createAutoNumberSequence, nextAutoNumber, breakAutoNumberRun, ELEMENT_PARAGRAPH_GEOMETRY_KEYS, getLinkedTextBoxSegments, deriveSlideTitle, svgPathToPolygons, THEME_COLOR_SCHEME_KEYS, createBuiltinVariables, resolveCoordinate, getPresetConnectionSites, getConnectorPathGeometry, resolveCustomGeometryToken, resolveCustomGeometryGuideContext, lookupPresetShape, normalizeStShapeType, PptxHandler, styleStroke, strokeFor, fitFontSize, nodeTextStyle, truncate, nodeOpacity, nodeStroke, nodeFill, styleShadow, buildTree, treeWidth, treeDepth, gearPoints, flattenNodes, interpretSmartArtLayout, smartArtQuickStyleHas3d, relayoutSmartArt, addSmartArtNode, removeSmartArtNode, demoteSmartArtNode, promoteSmartArtNode, reorderSmartArtNode, createEditorId, makeStoreAwareId, reassignDescendantIds, checkMissingAltText, checkMissingSlideTitle, checkLowContrast, checkComplexTables, checkBlankSlide, checkDuplicateTitles, createChartElement, createImageElement, THEME_COLOR_PALETTE_COLUMNS, hexToRgbChannels as hexToRgbChannels$2, rgbToHsl as rgbToHsl$1, renameSlideMaster, deleteSlideMaster, duplicateSlideMaster, insertSlideMaster, renameLayout, deleteLayout, duplicateLayout, insertLayout, detectFileFormat, themeColorRefFromColorChoice, cropShapeForPresetGeometry, cloneElement, duplicateElement, resolveModifyVerifierAlgorithmName, verifyModifyPassword, TABLE_STYLE_PART_SEQUENCE, douglasPeucker, THEME_PRESETS, themeColorSchemesEqual, guideEmuToPx, serializePptxToJson, PPTX_JSON_MIME_TYPE, PptxMarkdownConverter, ThemePresets, formatCommentTimestamp as formatCommentTimestamp$1, EncryptedFileError, decodeXmlEntities, parseSignatureXml, groupElements, ungroupElements, updateSmartArtNodeText, setSmartArtNodeStyle, isInkElement, isZoomElement, SvgExporter, applyThemeToData, reResolveElementFonts, 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, TRANSITION_PATTERN_OPTIONS, TRANSITION_THRUBLK_TYPES } from 'pptx-viewer-core';
6
6
  import * as opentypeModule from 'opentype.js';
@@ -226,8 +226,11 @@ function markWebControlContract(ctor) {
226
226
 
227
227
  const RIBBON_COMMAND_STYLES = `
228
228
  :host { display: inline-flex; flex: none; }
229
+ :host([hidden]) { display: none !important; }
230
+ .badge { position:absolute; top:0; right:0; border-radius:99px; padding:0 3px; background:var(--pptx-primary,#6366f1); color:var(--pptx-primary-foreground,#fff); font-size:9px; }
231
+ .badge[hidden] { display:none; }
229
232
  button {
230
- box-sizing: border-box; display: inline-flex; flex-direction: column; align-items: center;
233
+ box-sizing: border-box; position:relative; display: inline-flex; flex-direction: column; align-items: center;
231
234
  justify-content: flex-start; gap: 2px; min-width: 54px; max-width: 78px; height: 58px;
232
235
  padding: 4px; border: 0; border-radius: 4px; background: transparent;
233
236
  color: var(--pptx-foreground, #f9fafb); cursor: pointer; font: inherit;
@@ -253,6 +256,24 @@ button:focus-visible { outline: 2px solid var(--pptx-ring, #6366f1); outline-off
253
256
 
254
257
  /** Trusted, shared SVG paths. No host-supplied markup is inserted into the icon. */
255
258
  const RIBBON_ICON_PATHS = {
259
+ spelling: 'M2 14 6 5l4 9M3.4 11.4h5.2M12 13.5l2 2 4-4.5',
260
+ book: 'M3 4h5a2 2 0 0 1 2 2v10a2 2 0 0 0-2-2H3zM17 4h-5a2 2 0 0 0-2 2v10a2 2 0 0 1 2-2h5z',
261
+ shield: 'M10 3 4 5.4v4.1c0 3.3 2.5 6 6 7.1 3.5-1.1 6-3.8 6-7.1V5.4zM7 10l2 2 4-4',
262
+ globe: 'M3 10a7 7 0 1 0 14 0 7 7 0 1 0-14 0M3 10h14M10 3c-4 4-4 10 0 14 4-4 4-10 0-14',
263
+ languages: 'M2 5h9M6 3v2M4 5c0 5 5 7 7 8M9 5c0 5-5 7-7 8M11 17l4-9 4 9M12.5 14h5',
264
+ copy: 'M7 7h10v10H7ZM3 13V3h10',
265
+ compare: 'M5 3v11M15 6v11M5 5h7l3 3M15 15H8l-3-3M3 14h4M13 6h4',
266
+ message: 'M3 4h14v9H8l-5 4z',
267
+ messagePlus: 'M3 4h14v9H8l-5 4zM10 6v5M7.5 8.5h5',
268
+ trash: 'M4 6h12M8 6V4h4v2M6 6l.8 10h6.4L14 6',
269
+ chevronLeft: 'm12 4-6 6 6 6',
270
+ chevronRight: 'm8 4 6 6-6 6',
271
+ lock: 'M4 9h12v8H4ZM7 9V6.5a3 3 0 0 1 6 0V9',
272
+ eyeOff: 'M2.5 10S5.5 5 10 5s7.5 5 7.5 5-3 5-7.5 5-7.5-5-7.5-5zM4 4l12 12',
273
+ palette: 'M10 2a8 8 0 1 0 0 16h1a2 2 0 0 0 1-3.7 1.5 1.5 0 0 1 1-2.3h2a3 3 0 0 0 3-3c0-4-4-7-8-7M6 6h.1M10 5h.1M14 7h.1M5 10h.1',
274
+ pencil: 'M12 3l5 5M3 17l1-5L13 3l4 4-9 9Z',
275
+ monitor: 'M2 3h16v11H2ZM7 18h6M10 14v4',
276
+ paint: 'M3 9l6-6 8 8-6 6ZM4 4l8 8M3 18h12M17 13s-2 3-2 4a2 2 0 0 0 4 0c0-1-2-4-2-4',
256
277
  camera: 'M2 6h4l2-3h4l2 3h4v11H2ZM7 11a3 3 0 1 0 6 0 3 3 0 1 0-6 0',
257
278
  eraser: 'M3 12l8-8 6 6-7 7H7ZM3 17h14M7 8l6 6',
258
279
  reset: 'M4 10a6 6 0 1 1 1.8 4.2M4 6v4h4',
@@ -288,6 +309,7 @@ function definePptxRibbonCommand(registry) {
288
309
  'expanded',
289
310
  'title',
290
311
  'data-ribbon-control',
312
+ 'badge',
291
313
  ]; }
292
314
  constructor() {
293
315
  super();
@@ -303,6 +325,10 @@ function definePptxRibbonCommand(registry) {
303
325
  svg.append(this.path);
304
326
  this.text = document.createElement('span');
305
327
  this.button.append(svg, this.text);
328
+ this.badge = document.createElement('span');
329
+ this.badge.className = 'badge';
330
+ this.badge.setAttribute('aria-hidden', 'true');
331
+ this.button.append(this.badge);
306
332
  root.append(this.button);
307
333
  this.button.addEventListener('keydown', (event) => {
308
334
  // Keep native activation out of the viewer's slide-navigation handlers.
@@ -328,6 +354,8 @@ function definePptxRibbonCommand(registry) {
328
354
  }
329
355
  sync() {
330
356
  this.text.textContent = this.getAttribute('label') ?? '';
357
+ this.badge.textContent = this.getAttribute('badge') ?? '';
358
+ this.badge.hidden = !this.badge.textContent;
331
359
  this.button.title = this.getAttribute('title') ?? this.text.textContent;
332
360
  this.button.disabled = this.hasAttribute('disabled');
333
361
  this.path.setAttribute('d', RIBBON_ICON_PATHS[this.getAttribute('icon') ?? ''] ?? '');
@@ -345,871 +373,6 @@ function definePptxRibbonCommand(registry) {
345
373
  registry.define('pptx-ui-ribbon-command', RibbonCommand);
346
374
  }
347
375
 
348
- const STYLES = `
349
- :host { display: inline-flex; flex: none; align-self: stretch; }
350
- .group { box-sizing: border-box; display: flex; flex-direction: column; justify-content: space-between;
351
- min-height: 78px; padding: 4px 8px 2px; border-right: 1px solid color-mix(in srgb, var(--pptx-border, #33334d) 60%, transparent); }
352
- :host(:last-child) .group { border-right: 0; }
353
- .row { display: flex; align-items: flex-start; gap: 4px; }
354
- ::slotted(*) { flex-shrink: 0; }
355
- .caption { padding-top: 2px; color: var(--pptx-muted-foreground, #94a3b8); font: inherit;
356
- font-size: 9px; line-height: 12px; text-align: center; white-space: nowrap; }
357
- `;
358
- /** Slotted view boundary; customization ids remain in the light DOM. */
359
- function definePptxRibbonGroup(registry) {
360
- if (registry.get('pptx-ui-ribbon-group')) {
361
- return;
362
- }
363
- class RibbonGroup extends HTMLElement {
364
- static { this.observedAttributes = ['label']; }
365
- constructor() {
366
- super();
367
- const root = this.attachShadow({ mode: 'open' });
368
- attachControlStyles(root, STYLES);
369
- const group = document.createElement('div');
370
- group.className = 'group';
371
- const row = document.createElement('div');
372
- row.className = 'row';
373
- row.append(document.createElement('slot'));
374
- this.caption = document.createElement('span');
375
- this.caption.className = 'caption';
376
- group.append(row, this.caption);
377
- root.append(group);
378
- }
379
- connectedCallback() {
380
- this.setAttribute('role', 'group');
381
- this.sync();
382
- }
383
- attributeChangedCallback() {
384
- this.sync();
385
- }
386
- sync() {
387
- const label = this.getAttribute('label') ?? '';
388
- this.caption.textContent = label;
389
- this.setAttribute('aria-label', label);
390
- }
391
- }
392
- registry.define('pptx-ui-ribbon-group', RibbonGroup);
393
- }
394
-
395
- /** Controlled checkbox row sharing the existing checkbox's keyboard and focus behavior. */
396
- function definePptxRibbonToggle(registry) {
397
- if (registry.get('pptx-ui-ribbon-toggle')) {
398
- return;
399
- }
400
- class RibbonToggle extends HTMLElement {
401
- static { this.observedAttributes = ['label', 'checked', 'disabled', 'title']; }
402
- constructor() {
403
- super();
404
- const root = this.attachShadow({ mode: 'open' });
405
- attachControlStyles(root, `
406
- :host { display: block; }
407
- label { display: flex; align-items: center; gap: 4px; min-height: 22px; padding: 0 4px;
408
- color: var(--pptx-foreground, #f9fafb); font: inherit; font-size: 10px; white-space: nowrap; cursor: pointer; }
409
- :host([disabled]) label { color: var(--pptx-muted-foreground, #9ca3af); cursor: not-allowed; }
410
- @media (pointer: coarse), (max-width: 767px) { label { min-height: 44px; font-size: 12px; } }
411
- `);
412
- const label = document.createElement('label');
413
- this.checkbox = document.createElement('pptx-ui-checkbox');
414
- this.text = document.createTextNode('');
415
- label.append(this.checkbox, this.text);
416
- label.addEventListener('click', (event) => {
417
- event.preventDefault();
418
- if (event.target !== this.checkbox) {
419
- this.checkbox.click();
420
- }
421
- });
422
- this.checkbox.addEventListener('input', (event) => event.stopPropagation());
423
- this.checkbox.addEventListener('change', (event) => {
424
- event.stopPropagation();
425
- const checked = this.checkbox.checked;
426
- this.sync();
427
- const id = this.getAttribute('data-ribbon-control');
428
- if (!this.hasAttribute('disabled') && id) {
429
- this.dispatchEvent(new CustomEvent('toggle-request', {
430
- detail: { id, checked },
431
- bubbles: true,
432
- composed: true,
433
- }));
434
- }
435
- });
436
- root.append(label);
437
- }
438
- connectedCallback() {
439
- this.sync();
440
- }
441
- attributeChangedCallback() {
442
- this.sync();
443
- }
444
- sync() {
445
- const label = this.getAttribute('label') ?? '';
446
- this.text.textContent = label;
447
- this.checkbox.setAttribute('aria-label', label);
448
- this.checkbox.title = this.getAttribute('title') ?? label;
449
- this.checkbox.checked = this.hasAttribute('checked');
450
- this.checkbox.disabled = this.hasAttribute('disabled');
451
- }
452
- }
453
- registry.define('pptx-ui-ribbon-toggle', RibbonToggle);
454
- }
455
-
456
- const SEARCH_STYLES = `
457
- :host {
458
- display: flex;
459
- align-items: center;
460
- gap: 8px;
461
- box-sizing: border-box;
462
- width: 100%;
463
- height: 40px;
464
- padding: 0 12px;
465
- border: 1px solid var(--pptx-input, #374151);
466
- background: var(--pptx-card, #111827);
467
- color: var(--pptx-muted-foreground, #9ca3af);
468
- font: inherit;
469
- }
470
- :host(:focus-within) { border-color: var(--pptx-ring, #6366f1); }
471
- :host([variant="titlebar"]) {
472
- height: 28px;
473
- gap: 7px;
474
- padding-inline: 14px;
475
- border-color: var(--pptx-border, #374151);
476
- border-radius: 6px;
477
- background: var(--pptx-background, #030712);
478
- }
479
- :host([variant="titlebar"]:focus-within) {
480
- border-color: var(--pptx-ring, #6366f1);
481
- color: var(--pptx-foreground, #f3f4f6);
482
- }
483
- :host([disabled]) { opacity: .5; cursor: not-allowed; }
484
- svg { width: 16px; height: 16px; flex: none; }
485
- :host([variant="titlebar"]) svg { width: 14px; height: 14px; }
486
- input {
487
- min-width: 0;
488
- width: 100%;
489
- height: 100%;
490
- flex: 1;
491
- padding: 0;
492
- border: 0;
493
- outline: 0;
494
- background: transparent;
495
- color: var(--pptx-card-foreground, #f3f4f6);
496
- font: inherit;
497
- font-size: 13px;
498
- }
499
- :host([variant="titlebar"]) input {
500
- font-size: 11px;
501
- color: var(--pptx-foreground, #f3f4f6);
502
- }
503
- input::placeholder {
504
- color: var(--pptx-muted-foreground, #9ca3af);
505
- opacity: .8;
506
- }
507
- input::-webkit-search-cancel-button { display: none; }
508
- @media (forced-colors: active) {
509
- :host {
510
- border-color: CanvasText;
511
- background: Canvas;
512
- color: CanvasText;
513
- }
514
- :host(:focus-within) {
515
- outline: 2px solid Highlight;
516
- outline-offset: 2px;
517
- }
518
- input { color: CanvasText; }
519
- }
520
- `;
521
-
522
- const SEARCH_ICON = `<svg part="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>`;
523
- /** A single styled search input for the title bar and recent-files surface. */
524
- function definePptxSearchField(registry) {
525
- if (registry.get('pptx-ui-search')) {
526
- return;
527
- }
528
- class PptxSearchField extends HTMLElement {
529
- static { this.observedAttributes = ['placeholder', 'aria-label', 'disabled', 'value']; }
530
- constructor() {
531
- super();
532
- this.currentValue = '';
533
- const root = this.attachShadow({ mode: 'open', delegatesFocus: true });
534
- attachControlStyles(root, SEARCH_STYLES);
535
- const icon = document.createElement('template');
536
- icon.innerHTML = SEARCH_ICON;
537
- root.append(icon.content.cloneNode(true));
538
- this.input = document.createElement('input');
539
- this.input.type = 'search';
540
- this.input.setAttribute('part', 'input');
541
- this.input.addEventListener('input', (event) => {
542
- event.stopPropagation();
543
- this.currentValue = this.input.value;
544
- this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
545
- });
546
- this.input.addEventListener('change', (event) => {
547
- event.stopPropagation();
548
- this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
549
- });
550
- root.append(this.input);
551
- }
552
- connectedCallback() {
553
- this.sync();
554
- if (this.hasAttribute('value')) {
555
- this.value = this.getAttribute('value') ?? '';
556
- }
557
- }
558
- attributeChangedCallback(name) {
559
- if (name === 'value') {
560
- this.value = this.getAttribute('value') ?? '';
561
- }
562
- else {
563
- this.sync();
564
- }
565
- }
566
- get value() {
567
- return this.currentValue;
568
- }
569
- set value(next) {
570
- this.currentValue = String(next ?? '');
571
- if (this.input.value !== this.currentValue) {
572
- this.input.value = this.currentValue;
573
- }
574
- }
575
- get disabled() {
576
- return this.hasAttribute('disabled');
577
- }
578
- set disabled(next) {
579
- this.toggleAttribute('disabled', Boolean(next));
580
- }
581
- focus(options) {
582
- this.input.focus(options);
583
- }
584
- select() {
585
- this.input.select();
586
- }
587
- sync() {
588
- this.input.placeholder = this.getAttribute('placeholder') ?? '';
589
- this.input.setAttribute('aria-label', this.getAttribute('aria-label') ?? this.input.placeholder);
590
- this.input.disabled = this.hasAttribute('disabled');
591
- }
592
- }
593
- registry.define('pptx-ui-search', PptxSearchField);
594
- }
595
-
596
- /** Mutations that can change a select's value, labels or font preview. */
597
- const SELECT_OPTION_ATTRIBUTES = [
598
- 'value',
599
- 'disabled',
600
- 'label',
601
- 'selected',
602
- 'hidden',
603
- 'data-display-label',
604
- 'data-description',
605
- 'style',
606
- ];
607
- /** Flatten options while retaining optgroup labels and disabled state. */
608
- function collectSelectChoices(options) {
609
- return options.map((option) => {
610
- const group = option.parentElement instanceof HTMLOptGroupElement ? option.parentElement : null;
611
- return {
612
- value: option.value,
613
- label: option.label || option.textContent?.trim() || '',
614
- disabled: option.disabled || Boolean(group?.disabled),
615
- hidden: Boolean(option.hidden) || Boolean(group?.hidden),
616
- group: group?.label ?? '',
617
- ...(option.dataset.displayLabel ? { displayLabel: option.dataset.displayLabel } : {}),
618
- ...(option.dataset.description ? { description: option.dataset.description } : {}),
619
- ...(option.style.fontFamily ? { fontFamily: option.style.fontFamily } : {}),
620
- };
621
- });
622
- }
623
- /** Build popup options only when the select first opens. */
624
- function renderSelectMenu(menu, choices, value) {
625
- const menuItems = [];
626
- let previousGroup = '';
627
- choices.forEach((choice, index) => {
628
- if (choice.hidden) {
629
- return;
630
- }
631
- if (choice.group && choice.group !== previousGroup) {
632
- const heading = document.createElement('div');
633
- heading.className = 'group';
634
- heading.setAttribute('role', 'presentation');
635
- heading.textContent = choice.group;
636
- menuItems.push(heading);
637
- }
638
- previousGroup = choice.group;
639
- const item = document.createElement('div');
640
- item.className = 'option';
641
- item.setAttribute('role', 'option');
642
- item.setAttribute('aria-selected', String(choice.value === value));
643
- item.setAttribute('aria-disabled', String(choice.disabled));
644
- item.id = `${menu.id}-${index}`;
645
- item.dataset.index = String(index);
646
- item.textContent = choice.displayLabel ?? choice.label;
647
- if (choice.fontFamily) {
648
- item.style.fontFamily = choice.fontFamily;
649
- }
650
- if (choice.description) {
651
- const description = document.createElement('span');
652
- description.className = 'description';
653
- description.textContent = choice.description;
654
- item.append(description);
655
- }
656
- menuItems.push(item);
657
- });
658
- menu.replaceChildren(...menuItems);
659
- }
660
- /** Prefer below the trigger, flipping above when it offers more room. */
661
- function positionSelectMenu(menu, trigger) {
662
- const rect = trigger.getBoundingClientRect();
663
- const margin = 8;
664
- const gap = 4;
665
- const width = Math.max(0, window.innerWidth - margin * 2);
666
- const below = Math.max(0, window.innerHeight - rect.bottom - gap - margin);
667
- const above = Math.max(0, rect.top - gap - margin);
668
- menu.style.minWidth = `${Math.min(rect.width, width)}px`;
669
- menu.style.maxWidth = `${width}px`;
670
- // Measure at the normal height cap before choosing a side. Reset the cap
671
- // on every reposition so a previously constrained menu can grow again.
672
- const heightCap = trigger.getRootNode() instanceof ShadowRoot &&
673
- trigger.getRootNode().host.getAttribute('data-font-picker') === 'family'
674
- ? 320
675
- : 240;
676
- menu.style.maxHeight = `${heightCap}px`;
677
- const preferredHeight = menu.getBoundingClientRect().height;
678
- const flip = below < preferredHeight && above > below;
679
- menu.style.maxHeight = `${Math.min(heightCap, flip ? above : below)}px`;
680
- const { height, width: menuWidth } = menu.getBoundingClientRect();
681
- menu.style.top = `${Math.max(margin, flip ? rect.top - gap - height : rect.bottom + gap)}px`;
682
- menu.style.left = `${Math.max(margin, Math.min(rect.left, window.innerWidth - menuWidth - margin))}px`;
683
- }
684
- /** Expose the keyboard target while keeping the selected state separate. */
685
- function markSelectActive(menu, trigger, active, open) {
686
- for (const item of menu.querySelectorAll('[data-index]')) {
687
- item.toggleAttribute('data-active', Number(item.dataset.index) === active && open);
688
- }
689
- if (open && active >= 0) {
690
- trigger.setAttribute('aria-activedescendant', `${menu.id}-${active}`);
691
- }
692
- menu.querySelector('[data-active]')?.scrollIntoView?.({ block: 'nearest' });
693
- }
694
- /** Find the next enabled option when navigating with the arrow keys. */
695
- function nextSelectActive(choices, active, step) {
696
- for (let index = 0; index < choices.length; index++) {
697
- active = (active + step + choices.length) % choices.length;
698
- if (!choices[active].disabled && !choices[active].hidden) {
699
- return active;
700
- }
701
- }
702
- return active;
703
- }
704
-
705
- /** React's ribbon presentation, isolated from inspector and dialog selects. */
706
- const SELECT_RIBBON_STYLES = `
707
- :host([variant^="ribbon-"][disabled]) { opacity: .4; }
708
- :host([variant^="ribbon-"]) button {
709
- height: 28px; min-height: 28px; padding: 4px 8px; gap: 4px;
710
- border: 1px solid color-mix(in oklab, var(--pptx-border) 60%, transparent);
711
- border-radius: 3px; font-size: 12px; line-height: 18px;
712
- background: color-mix(in oklab, var(--pptx-background) 60%, transparent);
713
- color: var(--pptx-foreground);
714
- }
715
- :host([variant^="ribbon-"]) .value { flex: 1; min-width: 0; }
716
- :host([variant^="ribbon-"]) .chevron {
717
- width: 16px; height: 16px; margin: 0; border: 0; transform: none;
718
- }
719
- :host([variant^="ribbon-"]) .chevron svg { display: block; width: 16px; height: 16px; }
720
- :host([variant="ribbon-font"]) .chevron { color: var(--pptx-muted-foreground); }
721
- :host([variant="ribbon-font"][data-font-picker="size"]) button { padding-inline: 6px; }
722
- :host([variant="ribbon-icon"]) button {
723
- width: 36px; gap: 6px; padding: 6px 10px; border: 0; font-size: 12px; line-height: 16px;
724
- background: var(--pptx-muted); justify-content: center;
725
- }
726
- :host([variant="ribbon-icon"]) :is(.value, .chevron) { display: none; }
727
- ::slotted(svg[slot="icon"]) { display: block; width: 16px; height: 16px; flex: none; }
728
- :host([variant^="ribbon-"]) button:hover:not(:disabled) { background: var(--pptx-accent); }
729
- :host([variant^="ribbon-"]) .menu {
730
- width: 192px; padding: 4px 0; border-radius: 8px; font-size: 12px; line-height: 16px;
731
- }
732
- :host([data-font-picker="family"]) .menu { width: 256px; }
733
- :host([variant^="ribbon-"]) .option {
734
- display: flex; justify-content: space-between; gap: 12px; padding: 6px 12px; border-radius: 0;
735
- }
736
- :host([variant^="ribbon-"]) .option[aria-selected="true"] {
737
- background: transparent; color: var(--pptx-foreground);
738
- }
739
- :host([variant^="ribbon-"]) .option:hover,
740
- :host([variant^="ribbon-"]) .option[data-active] { background: var(--pptx-muted); filter: none; }
741
- :host([variant^="ribbon-"]) .group {
742
- padding: 8px 12px 4px; text-transform: uppercase; letter-spacing: .25px;
743
- font-size: 10px; line-height: 15px;
744
- }
745
- @media (max-width: 767px) {
746
- :host([variant^="ribbon-"]) button { height: 44px; min-height: 44px; }
747
- }
748
- .description { flex: none; color: var(--pptx-muted-foreground); font-size: 10px; line-height: 15px; }
749
- `;
750
-
751
- const SELECT_STYLES = `
752
- :host {
753
- display: inline-block;
754
- box-sizing: border-box;
755
- min-width: 0;
756
- max-width: 100%;
757
- border: 0 !important;
758
- padding: 0 !important;
759
- background: transparent !important;
760
- box-shadow: none !important;
761
- color: var(--pptx-foreground, #e2e8f0);
762
- font: inherit;
763
- font-size: 12px;
764
- vertical-align: middle;
765
- }
766
- :host([disabled]) { opacity: .5; cursor: not-allowed; }
767
- button {
768
- box-sizing: border-box;
769
- width: 100%;
770
- min-height: 28px;
771
- display: flex;
772
- align-items: center;
773
- justify-content: space-between;
774
- gap: 10px;
775
- padding: 4px 7px;
776
- border: 1px solid var(--pptx-border, #3f3f52);
777
- border-radius: 5px;
778
- background: var(--pptx-select-control-bg, var(--pptx-background, #11111b));
779
- color: inherit;
780
- font: inherit;
781
- font-size: inherit;
782
- text-align: left;
783
- cursor: pointer;
784
- }
785
- :host(.bg-muted) button { background: var(--pptx-muted, #1f2937); }
786
- :host(.bg-popover) button { background: var(--pptx-popover, #111827); }
787
- button:focus-visible {
788
- outline: 2px solid var(--pptx-ring, #6366f1);
789
- outline-offset: 2px;
790
- }
791
- button:disabled { cursor: not-allowed; }
792
- @media (pointer: coarse), (max-width: 767px) {
793
- button { min-height: 44px; }
794
- }
795
- .value {
796
- overflow: hidden;
797
- text-overflow: ellipsis;
798
- white-space: nowrap;
799
- }
800
- .chevron svg { display: none; }
801
- .chevron {
802
- flex: none;
803
- width: 6px;
804
- height: 6px;
805
- margin: 0 2px 3px 0;
806
- border-right: 1.5px solid currentColor;
807
- border-bottom: 1.5px solid currentColor;
808
- transform: rotate(45deg);
809
- }
810
- :host([open]) .chevron {
811
- margin: 3px 2px 0 0;
812
- transform: rotate(225deg);
813
- }
814
- .menu {
815
- box-sizing: border-box;
816
- position: fixed;
817
- margin: 0;
818
- padding: 4px;
819
- min-width: 90px;
820
- max-height: min(240px, 50vh);
821
- overflow: auto;
822
- border: 1px solid var(--pptx-border, #3f3f52);
823
- border-radius: 5px;
824
- background: var(--pptx-popover, var(--pptx-background, #11111b));
825
- color: var(--pptx-popover-foreground, var(--pptx-foreground, #e2e8f0));
826
- box-shadow: 0 8px 20px #0004;
827
- font: inherit;
828
- font-size: inherit;
829
- }
830
- .menu:not(:popover-open):not([data-fallback-open]) { display: none; }
831
- .option {
832
- display: block;
833
- box-sizing: border-box;
834
- width: 100%;
835
- padding: 6px 8px;
836
- border-radius: 3px;
837
- cursor: pointer;
838
- white-space: nowrap;
839
- }
840
- .group {
841
- padding: 7px 8px 3px;
842
- color: var(--pptx-muted-foreground, #9ca3af);
843
- font-size: .9em;
844
- font-weight: 600;
845
- }
846
- .option:not([aria-disabled="true"]):hover,
847
- .option[data-active]:not([aria-selected="true"]) {
848
- background: color-mix(in srgb, var(--pptx-primary, #e86a40) 20%, var(--pptx-popover, #11111b));
849
- }
850
- .option[aria-selected="true"] {
851
- background: var(--pptx-primary, #e86a40);
852
- color: var(--pptx-primary-foreground, #fff);
853
- }
854
- .option[aria-selected="true"]:hover { filter: brightness(1.08); }
855
- .option[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
856
- @media (forced-colors: active) {
857
- button, .menu {
858
- border-color: CanvasText;
859
- background: Canvas;
860
- color: CanvasText;
861
- }
862
- .option[aria-selected="true"],
863
- .option[data-active],
864
- .option:not([aria-disabled="true"]):hover {
865
- background: Highlight;
866
- color: HighlightText;
867
- }
868
- }
869
- ${SELECT_RIBBON_STYLES}
870
- `;
871
-
872
- /** Slots let ribbon controls retain their canonical icon and optional custom entry. */
873
- function createSelectTrigger() {
874
- const trigger = document.createElement('button');
875
- trigger.type = 'button';
876
- trigger.setAttribute('part', 'trigger');
877
- trigger.setAttribute('role', 'combobox');
878
- trigger.setAttribute('aria-haspopup', 'listbox');
879
- trigger.setAttribute('aria-expanded', 'false');
880
- const icon = document.createElement('slot');
881
- icon.name = 'icon';
882
- const text = document.createElement('span');
883
- text.className = 'value';
884
- text.setAttribute('part', 'value');
885
- const chevron = document.createElement('span');
886
- chevron.className = 'chevron';
887
- chevron.setAttribute('part', 'indicator');
888
- chevron.setAttribute('aria-hidden', 'true');
889
- const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
890
- svg.setAttribute('viewBox', '0 0 24 24');
891
- svg.setAttribute('fill', 'none');
892
- svg.setAttribute('stroke', 'currentColor');
893
- svg.setAttribute('stroke-width', '2');
894
- svg.setAttribute('stroke-linecap', 'round');
895
- svg.setAttribute('stroke-linejoin', 'round');
896
- const path = document.createElementNS(svg.namespaceURI, 'path');
897
- path.setAttribute('d', 'm6 9 6 6 6-6');
898
- svg.append(path);
899
- chevron.append(svg);
900
- trigger.append(icon, text, chevron);
901
- return { trigger, text };
902
- }
903
- /** Optional editable content stays in the light DOM so bindings own its events. */
904
- function prependSelectCustomSlot(host, menu) {
905
- if (host.querySelector('[slot="custom"]')) {
906
- const custom = document.createElement('slot');
907
- custom.name = 'custom';
908
- menu.prepend(custom);
909
- }
910
- }
911
-
912
- /** Create the base only in a browser; shared imports also run during SSR. */
913
- function createSelectValueElement() {
914
- class SelectValueElement extends HTMLElement {
915
- get value() {
916
- const requested = this.getAttribute('value');
917
- const options = this.options;
918
- if (this.getAttribute('variant') === 'ribbon-font' && requested !== null) {
919
- return requested;
920
- }
921
- if (requested !== null &&
922
- (!options.length || options.some((option) => option.value === requested))) {
923
- return requested;
924
- }
925
- return (options.find((option) => option.selected)?.value ??
926
- options.find((option) => !option.disabled && !option.closest('optgroup[disabled]') && !option.hidden)?.value ??
927
- options[0]?.value ??
928
- requested ??
929
- '');
930
- }
931
- set value(next) {
932
- this.setAttribute('value', String(next ?? ''));
933
- }
934
- get options() {
935
- return [...this.querySelectorAll('option')];
936
- }
937
- get selectedIndex() {
938
- return this.options.findIndex((option) => option.value === this.value);
939
- }
940
- set selectedIndex(index) {
941
- this.value = this.options[index]?.value ?? '';
942
- }
943
- }
944
- return SelectValueElement;
945
- }
946
-
947
- let nextSelectId = 0;
948
- /** A select-only combobox with one popup and event contract in every binding. */
949
- function definePptxSelect(registry) {
950
- if (registry.get('pptx-ui-select')) {
951
- return;
952
- }
953
- class PptxSelect extends createSelectValueElement() {
954
- static { this.formAssociated = true; }
955
- static { this.observedAttributes = ['value', 'disabled', 'aria-label']; }
956
- constructor() {
957
- super();
958
- this.refreshFrame = 0;
959
- this.choices = [];
960
- this.active = -1;
961
- this.open = false;
962
- this.search = '';
963
- this.searchTimer = 0;
964
- this.defaultValue = '';
965
- this.onOutside = (event) => {
966
- if (!event.composedPath().includes(this)) {
967
- this.close();
968
- }
969
- };
970
- this.position = () => {
971
- if (!this.open) {
972
- return;
973
- }
974
- positionSelectMenu(this.menu, this.trigger);
975
- };
976
- try {
977
- this.internals = this.attachInternals();
978
- }
979
- catch {
980
- this.internals = undefined;
981
- }
982
- const root = this.attachShadow({ mode: 'open', delegatesFocus: true });
983
- attachControlStyles(root, SELECT_STYLES);
984
- ({ trigger: this.trigger, text: this.text } = createSelectTrigger());
985
- this.menu = document.createElement('div');
986
- this.menu.className = 'menu';
987
- this.menu.id = `pptx-ui-select-options-${++nextSelectId}`;
988
- this.menu.setAttribute('role', 'listbox');
989
- this.menu.setAttribute('popover', 'manual');
990
- this.menu.setAttribute('part', 'popup');
991
- this.trigger.setAttribute('aria-controls', this.menu.id);
992
- root.append(this.trigger, this.menu);
993
- this.trigger.addEventListener('click', () => (this.open ? this.close() : this.show()));
994
- this.trigger.addEventListener('keydown', (event) => this.onKeyDown(event));
995
- this.menu.addEventListener('pointerdown', (event) => {
996
- if (event.target.closest('[data-index]')) {
997
- event.preventDefault();
998
- }
999
- });
1000
- this.menu.addEventListener('click', (event) => {
1001
- const target = event.target.closest('[data-index]');
1002
- if (target) {
1003
- this.commit(Number(target.dataset.index));
1004
- }
1005
- });
1006
- this.observer = new MutationObserver(() => {
1007
- // Let bindings finish updating their option nodes before touching the shadow DOM.
1008
- if (!this.refreshFrame) {
1009
- this.refreshFrame = requestAnimationFrame(() => {
1010
- this.refreshFrame = 0;
1011
- this.refresh();
1012
- });
1013
- }
1014
- });
1015
- }
1016
- connectedCallback() {
1017
- this.defaultValue = this.getAttribute('value') ?? '';
1018
- this.observer.observe(this, {
1019
- childList: true,
1020
- subtree: true,
1021
- attributes: true,
1022
- characterData: true,
1023
- attributeFilter: SELECT_OPTION_ATTRIBUTES,
1024
- });
1025
- this.refresh();
1026
- }
1027
- disconnectedCallback() {
1028
- this.close();
1029
- window.clearTimeout(this.searchTimer);
1030
- this.searchTimer = 0;
1031
- this.search = '';
1032
- this.observer.disconnect();
1033
- cancelAnimationFrame(this.refreshFrame);
1034
- this.refreshFrame = 0;
1035
- }
1036
- attributeChangedCallback() {
1037
- this.refresh();
1038
- }
1039
- get disabled() {
1040
- return this.hasAttribute('disabled');
1041
- }
1042
- set disabled(next) {
1043
- this.toggleAttribute('disabled', Boolean(next));
1044
- }
1045
- focus(options) {
1046
- this.trigger.focus(options);
1047
- }
1048
- formResetCallback() {
1049
- this.value = this.defaultValue;
1050
- }
1051
- formDisabledCallback(disabled) {
1052
- this.disabled = disabled;
1053
- }
1054
- refresh() {
1055
- if (!this.trigger) {
1056
- return;
1057
- }
1058
- const options = [...this.querySelectorAll('option')];
1059
- this.choices = collectSelectChoices(options);
1060
- if (!this.hasAttribute('value') && this.choices.length) {
1061
- this.value =
1062
- options.find((option) => option.selected)?.value ??
1063
- this.choices.find((choice) => !choice.disabled && !choice.hidden)?.value ??
1064
- this.choices[0].value;
1065
- }
1066
- this.text.textContent =
1067
- this.choices.find((choice) => choice.value === this.value)?.displayLabel ??
1068
- this.choices.find((choice) => choice.value === this.value)?.label ??
1069
- this.value;
1070
- this.trigger.disabled = this.disabled;
1071
- if (this.disabled) {
1072
- this.close();
1073
- }
1074
- this.trigger.setAttribute('aria-label', this.getAttribute('aria-label') ?? '');
1075
- this.internals?.setFormValue?.(this.disabled ? null : this.value);
1076
- if (this.open || this.menu.childElementCount) {
1077
- this.renderMenu();
1078
- }
1079
- }
1080
- renderMenu() {
1081
- renderSelectMenu(this.menu, this.choices, this.value);
1082
- prependSelectCustomSlot(this, this.menu);
1083
- markSelectActive(this.menu, this.trigger, this.active, this.open);
1084
- }
1085
- show() {
1086
- if (this.disabled ||
1087
- !this.choices.some((choice) => !choice.disabled && !choice.hidden) ||
1088
- this.open) {
1089
- return;
1090
- }
1091
- this.open = true;
1092
- this.setAttribute('open', '');
1093
- const selected = this.choices.findIndex((choice) => choice.value === this.value && !choice.disabled && !choice.hidden);
1094
- this.active =
1095
- selected >= 0
1096
- ? selected
1097
- : this.choices.findIndex((choice) => !choice.disabled && !choice.hidden);
1098
- this.renderMenu();
1099
- if (typeof this.menu.showPopover === 'function') {
1100
- this.menu.showPopover();
1101
- }
1102
- else {
1103
- this.menu.dataset.fallbackOpen = '';
1104
- }
1105
- this.trigger.setAttribute('aria-expanded', 'true');
1106
- this.position();
1107
- markSelectActive(this.menu, this.trigger, this.active, this.open);
1108
- document.addEventListener('pointerdown', this.onOutside, true);
1109
- window.addEventListener('resize', this.position);
1110
- window.addEventListener('scroll', this.position, true);
1111
- }
1112
- close() {
1113
- if (!this.open) {
1114
- return;
1115
- }
1116
- this.open = false;
1117
- window.clearTimeout(this.searchTimer);
1118
- this.search = '';
1119
- this.removeAttribute('open');
1120
- if (this.menu.matches(':popover-open')) {
1121
- this.menu.hidePopover();
1122
- }
1123
- delete this.menu.dataset.fallbackOpen;
1124
- this.trigger.setAttribute('aria-expanded', 'false');
1125
- this.trigger.removeAttribute('aria-activedescendant');
1126
- document.removeEventListener('pointerdown', this.onOutside, true);
1127
- window.removeEventListener('resize', this.position);
1128
- window.removeEventListener('scroll', this.position, true);
1129
- }
1130
- move(step) {
1131
- if (!this.open) {
1132
- this.show();
1133
- }
1134
- if (!this.open) {
1135
- return;
1136
- }
1137
- this.active = nextSelectActive(this.choices, this.active, step);
1138
- markSelectActive(this.menu, this.trigger, this.active, this.open);
1139
- }
1140
- commit(index) {
1141
- const choice = this.choices[index];
1142
- if (!choice || choice.disabled || choice.hidden) {
1143
- return;
1144
- }
1145
- const changed = this.value !== choice.value;
1146
- this.value = choice.value;
1147
- this.close();
1148
- this.trigger.focus();
1149
- if (changed) {
1150
- this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
1151
- this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
1152
- }
1153
- }
1154
- onKeyDown(event) {
1155
- if (this.disabled) {
1156
- return;
1157
- }
1158
- if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
1159
- event.preventDefault();
1160
- event.stopPropagation();
1161
- this.move(event.key === 'ArrowDown' ? 1 : -1);
1162
- }
1163
- else if (event.key === 'Home' || event.key === 'End') {
1164
- event.preventDefault();
1165
- event.stopPropagation();
1166
- this.show();
1167
- this.active =
1168
- event.key === 'Home'
1169
- ? nextSelectActive(this.choices, -1, 1)
1170
- : nextSelectActive(this.choices, 0, -1);
1171
- markSelectActive(this.menu, this.trigger, this.active, this.open);
1172
- }
1173
- else if (event.key === 'Enter' || event.key === ' ') {
1174
- event.preventDefault();
1175
- event.stopPropagation();
1176
- if (this.open) {
1177
- this.commit(this.active);
1178
- }
1179
- else {
1180
- this.show();
1181
- }
1182
- }
1183
- else if (event.key === 'Escape' && this.open) {
1184
- event.preventDefault();
1185
- event.stopPropagation();
1186
- this.close();
1187
- this.trigger.focus();
1188
- }
1189
- else if (event.key === 'Tab') {
1190
- this.close();
1191
- }
1192
- else if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
1193
- event.stopPropagation();
1194
- this.search += event.key.toLocaleLowerCase();
1195
- window.clearTimeout(this.searchTimer);
1196
- this.searchTimer = window.setTimeout(() => {
1197
- this.search = '';
1198
- }, 700);
1199
- this.show();
1200
- const index = this.choices.findIndex((choice) => !choice.disabled &&
1201
- !choice.hidden &&
1202
- choice.label.toLocaleLowerCase().startsWith(this.search));
1203
- if (index >= 0) {
1204
- this.active = index;
1205
- markSelectActive(this.menu, this.trigger, this.active, this.open);
1206
- }
1207
- }
1208
- }
1209
- }
1210
- registry.define('pptx-ui-select', PptxSelect);
1211
- }
1212
-
1213
376
  /**
1214
377
  * Resolve `element`'s custom-geometry outline, re-evaluating it against
1215
378
  * `element.shapeAdjustments` when `customGeometryRawData` is available so an
@@ -28719,7 +27882,10 @@ function buildChartStylePresets(chartData) {
28719
27882
  id,
28720
27883
  labelKey,
28721
27884
  colors,
28722
- applied: paletteEquals(colors, chartData.colorPalette),
27885
+ applied: paletteEquals(colors, chartData.colorPalette) ||
27886
+ (!chartData.colorPalette &&
27887
+ Boolean(chartData.series?.length) &&
27888
+ chartData.series.every((series, index) => series.color?.toLowerCase() === colors[index % colors.length]?.toLowerCase())),
28723
27889
  };
28724
27890
  });
28725
27891
  }
@@ -57293,6 +56459,8 @@ const translationsEn = {
57293
56459
  'pptx.ribbon.width': 'Width',
57294
56460
  'pptx.ribbon.strokeWidth': 'Stroke width',
57295
56461
  'pptx.ribbon.browseThemes': 'Browse Themes',
56462
+ 'pptx.ribbon.groupThemes': 'Themes',
56463
+ 'pptx.ribbon.groupCustomize': 'Customize',
57296
56464
  'pptx.ribbon.browseThemesTitle': 'Browse and apply built-in themes',
57297
56465
  'pptx.ribbon.theme.default': 'Default',
57298
56466
  'pptx.ribbon.theme.light': 'Light (Vermilion)',
@@ -58538,6 +57706,7 @@ const translationsEn = {
58538
57706
  'pptx.review.hideInk': 'Hide Ink',
58539
57707
  'pptx.review.markAllRead': 'Mark All as Read',
58540
57708
  'pptx.review.proofing': 'Proofing',
57709
+ 'pptx.review.ink': 'Ink',
58541
57710
  'pptx.review.protect': 'Protect',
58542
57711
  'pptx.review.readOnly': 'Always Open Read-Only',
58543
57712
  'pptx.review.restrictPermission': 'Restrict Permission',
@@ -84210,6 +83379,143 @@ const HELP_RIBBON_COMMANDS = [
84210
83379
  },
84211
83380
  ];
84212
83381
 
83382
+ const DESIGN_RIBBON_GROUPS = [
83383
+ { id: 'design.themes', labelKey: 'pptx.ribbon.groupThemes' },
83384
+ { id: 'design.variants', labelKey: 'pptx.ribbon.groupVariants' },
83385
+ { id: 'design.customize', labelKey: 'pptx.ribbon.groupCustomize' },
83386
+ ];
83387
+ function designCommandState(id, state) {
83388
+ const slideSize = id === 'design.customize.slideSize';
83389
+ const background = id === 'design.customize.formatBackground';
83390
+ const active = id === 'design.themes.browseThemes'
83391
+ ? state.galleryOpen
83392
+ : id === 'design.themes.editTheme'
83393
+ ? state.editorOpen
83394
+ : background
83395
+ ? state.backgroundOpen
83396
+ : false;
83397
+ return {
83398
+ disabled: !slideSize && !state.editable,
83399
+ active: Boolean(active),
83400
+ expanded: slideSize ? undefined : Boolean(active),
83401
+ hidden: (slideSize && state.hasSlideSize === false) || (background && state.hasBackground === false),
83402
+ };
83403
+ }
83404
+ /** Presentation only: adapters retain their gallery, editor and inspector actions. */
83405
+ const DESIGN_RIBBON_COMMANDS = [
83406
+ {
83407
+ id: 'design.themes.browseThemes',
83408
+ labelKey: 'pptx.ribbon.browseThemes',
83409
+ titleKey: 'pptx.ribbon.browseThemesTitle',
83410
+ icon: 'palette',
83411
+ },
83412
+ {
83413
+ id: 'design.themes.editTheme',
83414
+ labelKey: 'pptx.ribbon.editTheme',
83415
+ titleKey: 'pptx.design.editThemeTooltip',
83416
+ icon: 'pencil',
83417
+ },
83418
+ {
83419
+ id: 'design.customize.slideSize',
83420
+ labelKey: 'pptx.ribbon.slideSize',
83421
+ titleKey: 'pptx.ribbon.slideSizeTitle',
83422
+ icon: 'monitor',
83423
+ },
83424
+ {
83425
+ id: 'design.customize.formatBackground',
83426
+ labelKey: 'pptx.ribbon.formatBackground',
83427
+ titleKey: 'pptx.ribbon.formatBackgroundTitle',
83428
+ icon: 'paint',
83429
+ },
83430
+ ];
83431
+
83432
+ /** Seven canonical groups with host-controlled availability and native intents. */
83433
+ function buildReviewRibbon(t, state) {
83434
+ const label = (key, fallback) => {
83435
+ const value = t(key);
83436
+ return value && value !== key ? value : fallback;
83437
+ };
83438
+ const command = (id, key, fallback, icon, options = {}) => ({ id, label: label(key, fallback), icon, ...options });
83439
+ const group = (id, key, fallback, commands) => ({ id, label: label(key, fallback), commands });
83440
+ return [
83441
+ group('review.proofing', 'pptx.review.proofing', 'Proofing', [
83442
+ command('review.proofing.spelling', 'pptx.review.spelling', 'Spelling', 'spelling', {
83443
+ active: state.spellCheck,
83444
+ pressed: state.spellCheck,
83445
+ disabled: state.canSpellCheck === false,
83446
+ title: label('pptx.review.toggleSpellCheck', 'Toggle spell check'),
83447
+ }),
83448
+ command('review.proofing.thesaurus', 'pptx.review.thesaurus', 'Thesaurus', 'book', {
83449
+ disabled: true,
83450
+ }),
83451
+ ]),
83452
+ group('review.accessibility', 'pptx.review.accessibility', 'Accessibility', [
83453
+ command('review.accessibility.check', 'pptx.review.accessibilityCheck', 'Check Accessibility', 'shield', { disabled: state.canAccessibility === false, active: state.accessibilityOpen }),
83454
+ ]),
83455
+ group('review.language', 'pptx.review.language', 'Language', [
83456
+ command('review.language.translate', 'pptx.review.translate', 'Translate', 'languages', {
83457
+ disabled: true,
83458
+ }),
83459
+ command('review.language.language', 'pptx.review.language', 'Language', 'globe', {
83460
+ disabled: !state.canLanguage,
83461
+ hidden: state.languageHidden,
83462
+ }),
83463
+ ]),
83464
+ group('review.compare', 'pptx.review.changes', 'Changes', [
83465
+ command('review.compare.markAllRead', 'pptx.review.markAllRead', 'Mark All as Read', 'copy', {
83466
+ disabled: true,
83467
+ }),
83468
+ command('review.compare.compare', 'pptx.ribbon.compare', 'Compare', 'compare', {
83469
+ disabled: !state.editable || !state.canCompare,
83470
+ hidden: !state.canCompare,
83471
+ title: label('pptx.ribbon.compareTitle', 'Compare presentations'),
83472
+ }),
83473
+ ]),
83474
+ group('review.comments', 'pptx.toolbar.comments', 'Comments', [
83475
+ command('review.comments.newComment', 'pptx.toolbar.comments', 'Comments', 'messagePlus', {
83476
+ disabled: !state.canComments,
83477
+ active: state.commentsOpen,
83478
+ expanded: state.commentsOpen,
83479
+ badge: state.commentCount,
83480
+ title: label('pptx.review.toggleComments', 'Toggle comments'),
83481
+ }),
83482
+ command('review.comments.delete', 'pptx.common.delete', 'Delete', 'trash', {
83483
+ disabled: true,
83484
+ compact: true,
83485
+ column: 1,
83486
+ }),
83487
+ command('review.comments.previous', 'pptx.common.previous', 'Previous', 'chevronLeft', {
83488
+ disabled: true,
83489
+ compact: true,
83490
+ column: 1,
83491
+ }),
83492
+ command('review.comments.next', 'pptx.common.next', 'Next', 'chevronRight', {
83493
+ disabled: true,
83494
+ compact: true,
83495
+ column: 2,
83496
+ }),
83497
+ command('review.comments.showComments', 'pptx.review.showComments', 'Show Comments', 'message', {
83498
+ disabled: !state.canComments,
83499
+ active: state.commentsOpen,
83500
+ expanded: state.commentsOpen,
83501
+ compact: true,
83502
+ column: 2,
83503
+ }),
83504
+ ]),
83505
+ group('review.protect', 'pptx.review.protect', 'Protect', [
83506
+ command('review.protect.readOnly', 'pptx.review.readOnly', 'Always Open Read-only', 'lock', {
83507
+ disabled: true,
83508
+ }),
83509
+ command('review.protect.restrictPermission', 'pptx.review.restrictPermission', 'Restrict Permission', 'shield', { disabled: true }),
83510
+ ]),
83511
+ group('review.ink', 'pptx.review.ink', 'Ink', [
83512
+ command('review.ink.hideInk', 'pptx.review.hideInk', 'Hide Ink', 'eyeOff', {
83513
+ disabled: true,
83514
+ }),
83515
+ ]),
83516
+ ];
83517
+ }
83518
+
84213
83519
  /**
84214
83520
  * The layout PowerPoint's Home > Reset re-applies to the active slide,
84215
83521
  * restoring inherited placeholder geometry and formatting. Returns undefined
@@ -109700,7 +109006,7 @@ const RIBBON_CATALOG_TAIL_TABS = {
109700
109006
  review: {
109701
109007
  proofing: { label: 'Proofing', controls: { spelling: 'Spelling', thesaurus: 'Thesaurus' } },
109702
109008
  accessibility: { label: 'Accessibility', controls: { check: 'Check Accessibility' } },
109703
- language: { label: 'Language', controls: { translate: 'Translate' } },
109009
+ language: { label: 'Language', controls: { translate: 'Translate', language: 'Language' } },
109704
109010
  comments: {
109705
109011
  label: 'Comments',
109706
109012
  controls: {
@@ -113889,9 +113195,59 @@ function applyShapeStylesItem(itemId, ctx) {
113889
113195
  };
113890
113196
  }
113891
113197
 
113198
+ /** Update the editable node colors without changing authored geometry or connector styles. */
113199
+ function smartArtColorPatch(data, fillColors) {
113200
+ const original = data.colorTransform;
113201
+ const roles = original?.roleColors ??
113202
+ Object.fromEntries((original?.labels ?? [{ name: 'node0' }, { name: 'node1' }]).map((label) => [
113203
+ label.name,
113204
+ { fill: [], line: [] },
113205
+ ]));
113206
+ const roleColors = Object.fromEntries(Object.entries(roles).map(([name, colors]) => [
113207
+ name,
113208
+ /^node\d+$/u.test(name) ? { ...colors, fill: [...fillColors] } : colors,
113209
+ ]));
113210
+ const flat = flattenNodes(data.nodes);
113211
+ const shapes = data.drawingShapes;
113212
+ return {
113213
+ colorTransformDirty: true,
113214
+ colorTransform: {
113215
+ ...original,
113216
+ fillColors: [...fillColors],
113217
+ lineColors: original?.lineColors ?? [],
113218
+ roleColors,
113219
+ fillInterpolation: { method: 'cycle' },
113220
+ labels: original?.labels?.map((label) => /^node\d+$/u.test(label.name)
113221
+ ? { ...label, fill: { ...label.fill, method: 'cycle' } }
113222
+ : label),
113223
+ },
113224
+ drawingDirty: Boolean(shapes?.length),
113225
+ drawingShapes: shapes?.map((shape, index) => {
113226
+ const nodeId = resolveDrawingShapeNodeId(shape, index, shapes, data.nodes);
113227
+ const nodeIndex = flat.findIndex((node) => node.id === nodeId);
113228
+ return nodeIndex < 0
113229
+ ? shape
113230
+ : {
113231
+ ...shape,
113232
+ fillColor: fillColors[nodeIndex % fillColors.length],
113233
+ fillGradientStops: undefined,
113234
+ fillGradientType: undefined,
113235
+ fillGradientAngle: undefined,
113236
+ };
113237
+ }),
113238
+ };
113239
+ }
113240
+
113892
113241
  /** `data` with `patch` merged, drawing shapes rebuilt when a structural edit cleared them. */
113893
113242
  function applySmartArtDataPatch(data, patch, box, elementId = 'inspector') {
113894
113243
  const next = { ...data, ...patch };
113244
+ if (patch.style !== undefined) {
113245
+ next.quickStyleDirty = true;
113246
+ next.quickStyle = {
113247
+ ...next.quickStyle,
113248
+ effectIntensity: patch.style === 'flat' ? 'subtle' : patch.style,
113249
+ };
113250
+ }
113895
113251
  return box
113896
113252
  ? rebuildDrawingShapesIfCleared(next, next.layout, resolvePalette(next), next.style ?? 'flat', elementId, box)
113897
113253
  : next;
@@ -114002,8 +113358,15 @@ const SMARTART_COLORS_GALLERY = {
114002
113358
  build(ctx) {
114003
113359
  const element = ctx.element;
114004
113360
  const data = element?.type === 'smartArt' ? element.smartArtData : undefined;
114005
- const current = data ? (data.colorScheme ?? 'colorful1') : undefined;
114006
113361
  const scheme = galleryColorScheme(ctx);
113362
+ const fills = data?.colorTransform?.fillColors;
113363
+ const matched = fills?.length
113364
+ ? SMARTART_COLOR_ENTRIES.find((entry) => entry.accents.length === fills.length &&
113365
+ entry.accents.every((accent, index) => scheme[accent].toLowerCase() === fills[index].toLowerCase()))?.id
113366
+ : undefined;
113367
+ const current = data
113368
+ ? (data.colorScheme ?? matched ?? (fills?.length ? undefined : 'colorful1'))
113369
+ : undefined;
114007
113370
  const sections = SECTIONS.map((section) => ({
114008
113371
  id: section.id,
114009
113372
  titleKey: `pptx.gallery.smartArtColors.section.${section.id}`,
@@ -114033,7 +113396,14 @@ const SMARTART_COLORS_GALLERY = {
114033
113396
  },
114034
113397
  apply(itemId, ctx) {
114035
113398
  const entry = SMARTART_COLOR_ENTRIES.find((candidate) => candidate.id === itemId);
114036
- const patch = entry ? smartArtElementPatch(ctx.element, { colorScheme: entry.id }) : null;
113399
+ const data = ctx.element?.type === 'smartArt' ? ctx.element.smartArtData : undefined;
113400
+ const scheme = galleryColorScheme(ctx);
113401
+ const patch = entry && data
113402
+ ? smartArtElementPatch(ctx.element, {
113403
+ colorScheme: entry.id,
113404
+ ...smartArtColorPatch(data, entry.accents.map((accent) => scheme[accent])),
113405
+ })
113406
+ : null;
114037
113407
  return patch ? { kind: 'element', ...patch } : null;
114038
113408
  },
114039
113409
  };
@@ -114043,7 +113413,10 @@ const SMARTART_STYLES_GALLERY = {
114043
113413
  build(ctx) {
114044
113414
  const element = ctx.element;
114045
113415
  const data = element?.type === 'smartArt' ? element.smartArtData : undefined;
114046
- const current = data ? (data.style ?? 'flat') : undefined;
113416
+ const intensity = data?.quickStyle?.effectIntensity;
113417
+ const current = data
113418
+ ? (data.style ?? (intensity === 'moderate' || intensity === 'intense' ? intensity : 'flat'))
113419
+ : undefined;
114047
113420
  const accent1 = galleryColorScheme(ctx).accent1;
114048
113421
  return {
114049
113422
  id: 'smartArtStyles',
@@ -115576,6 +114949,13 @@ function galleryItemLabel(item, translate) {
115576
114949
  const translated = translate(item.labelKey, item.labelParams);
115577
114950
  return translated && translated !== item.labelKey ? translated : item.label;
115578
114951
  }
114952
+ function galleryTextLabel(translate, key, fallback) {
114953
+ if (!key) {
114954
+ return fallback;
114955
+ }
114956
+ const translated = translate(key);
114957
+ return translated && translated !== key ? translated : fallback;
114958
+ }
115579
114959
 
115580
114960
  function rect(x, y, width, height, rx) {
115581
114961
  return {
@@ -118463,8 +117843,8 @@ function resetThreeRendererHostForTests() {
118463
117843
  }
118464
117844
 
118465
117845
  const loaders = {
118466
- chart: async () => (await import('./pptx-angular-viewer-chart-3d-view-scene-D-8RhIEx.mjs')).mountChart3DView,
118467
- smartart: async () => (await import('./pptx-angular-viewer-view-scene-DK5uoxBI.mjs')).mountSmartArt3DView,
117846
+ chart: async () => (await import('./pptx-angular-viewer-chart-3d-view-scene-B2GMxwCZ.mjs')).mountChart3DView,
117847
+ smartart: async () => (await import('./pptx-angular-viewer-view-scene-yiGd2Mi4.mjs')).mountSmartArt3DView,
118468
117848
  };
118469
117849
  /** Resolve the scene factory for a spec kind. */
118470
117850
  async function loadThreeViewScene(kind) {
@@ -123807,6 +123187,1312 @@ function themeEditorHex(value) {
123807
123187
  * recalculation when connected shapes move + connection sites).
123808
123188
  */
123809
123189
 
123190
+ const host = 'pptx-ui-ribbon-gallery';
123191
+ const CSS$1 = `
123192
+ ${host} { display:inline-flex; position:relative; flex:none; color:var(--pptx-foreground,#f9fafb); }
123193
+ ${host} .gallery-view { display:contents; }
123194
+ ${host} button { box-sizing:border-box; font:inherit; color:inherit; cursor:pointer; border:1px solid var(--pptx-border,#374151); border-radius:4px; background:var(--pptx-background,#111827); }
123195
+ ${host} button:hover:not(:disabled) { background:var(--pptx-accent,#33334d); }
123196
+ ${host} button:disabled { opacity:.4; cursor:not-allowed; }
123197
+ ${host} button:focus-visible { outline:2px solid var(--pptx-ring,#6366f1); outline-offset:2px; }
123198
+ ${host} .trigger { display:inline-flex; align-items:center; gap:6px; min-height:26px; padding:4px 8px; font-size:11px; white-space:nowrap; }
123199
+ ${host} .trigger svg { width:16px; height:16px; fill:none; stroke:currentColor; stroke-width:1.6; stroke-linecap:round; stroke-linejoin:round; }
123200
+ ${host}[mode=inline] .trigger, ${host}[chevron-only] .trigger { align-self:stretch; padding:0 4px; }
123201
+ ${host} .strip { display:flex; gap:2px; padding:2px; align-items:center; }
123202
+ ${host} .tile { display:inline-flex; align-items:center; justify-content:center; flex:none; padding:2px; }
123203
+ ${host} .tile[aria-pressed=true] { border:2px solid var(--pptx-primary,#6366f1); background:color-mix(in srgb,var(--pptx-primary,#6366f1) 15%,var(--pptx-background,#111827)); }
123204
+ ${host} .tile svg { max-width:100%; max-height:100%; }
123205
+ ${host} .popup { box-sizing:border-box; position:fixed; z-index:1200; max-width:calc(100vw - 16px); max-height:65vh; overflow:auto; padding:8px; border:1px solid var(--pptx-border,#374151); border-radius:6px; background:var(--pptx-popover,#111827); color:var(--pptx-popover-foreground,#f9fafb); box-shadow:0 8px 24px #0006; }
123206
+ ${host} .popup[hidden] { display:none; }
123207
+ ${host} .grid { display:grid; gap:4px; width:max-content; max-width:100%; }
123208
+ ${host} .heading { margin:4px 0 6px; font-size:11px; font-weight:600; }
123209
+ ${host} .section + .section { margin-top:10px; }
123210
+ @media (pointer:coarse), (max-width:1023px) {
123211
+ ${host} .trigger, ${host} .tile { min-height:44px; min-width:44px; }
123212
+ ${host} .popup { max-height:60vh; }
123213
+ }
123214
+ @media (forced-colors:active) {
123215
+ ${host} button, ${host} .popup { color:ButtonText; background:Canvas; border-color:ButtonText; }
123216
+ ${host} button:disabled { color:GrayText; opacity:1; }
123217
+ ${host} button:focus-visible, ${host} .tile[aria-pressed=true] { outline:2px solid Highlight; border-color:Highlight; }
123218
+ }
123219
+ `;
123220
+ /** Preserve the public light-DOM gallery hooks while scoping every shared rule. */
123221
+ function attachRibbonGalleryStyles(doc) {
123222
+ if (!doc.getElementById('pptx-ui-gallery-styles')) {
123223
+ const style = doc.createElement('style');
123224
+ style.id = 'pptx-ui-gallery-styles';
123225
+ style.textContent = CSS$1;
123226
+ doc.head.append(style);
123227
+ }
123228
+ }
123229
+
123230
+ /** All gallery markup is owned here; callers only supply shared descriptors and intents. */
123231
+ function createRibbonGalleryView(doc, pick, toggle) {
123232
+ const root = doc.createElement('span');
123233
+ root.className = 'gallery-view';
123234
+ const strip = doc.createElement('div');
123235
+ strip.className = 'strip';
123236
+ const trigger = doc.createElement('button');
123237
+ trigger.type = 'button';
123238
+ trigger.className = 'trigger';
123239
+ trigger.setAttribute('data-pptx-compact', '');
123240
+ trigger.setAttribute('aria-haspopup', 'dialog');
123241
+ trigger.addEventListener('click', toggle);
123242
+ const popup = doc.createElement('div');
123243
+ popup.className = 'popup';
123244
+ popup.hidden = true;
123245
+ popup.setAttribute('role', 'dialog');
123246
+ root.append(strip, trigger);
123247
+ const caption = (t, key, fallback) => {
123248
+ const translated = t(key);
123249
+ return translated && translated !== key ? translated : fallback;
123250
+ };
123251
+ const tile = (item, width, height, disabled, t) => {
123252
+ const button = doc.createElement('button');
123253
+ button.type = 'button';
123254
+ button.className = 'tile';
123255
+ button.setAttribute('data-pptx-compact', '');
123256
+ button.dataset.galleryItem = item.id;
123257
+ button.disabled = disabled;
123258
+ button.setAttribute('aria-pressed', String(item.applied));
123259
+ button.setAttribute('aria-label', galleryItemLabel(item, t));
123260
+ button.title = galleryItemLabel(item, t);
123261
+ button.style.width = `${width + 6}px`;
123262
+ button.style.height = `${height + 6}px`;
123263
+ // Generated by the shared catalogue from trusted geometry and escaped theme data.
123264
+ button.innerHTML = item.previewSvg;
123265
+ button.addEventListener('click', () => pick(item.id));
123266
+ return button;
123267
+ };
123268
+ return {
123269
+ root,
123270
+ trigger,
123271
+ popup,
123272
+ clear() {
123273
+ strip.replaceChildren();
123274
+ popup.replaceChildren();
123275
+ trigger.removeAttribute('data-ribbon-gallery');
123276
+ trigger.removeAttribute('aria-label');
123277
+ trigger.textContent = '';
123278
+ },
123279
+ setOpen(open) {
123280
+ popup.hidden = !open;
123281
+ if (open) {
123282
+ root.append(popup);
123283
+ }
123284
+ else {
123285
+ popup.remove();
123286
+ }
123287
+ },
123288
+ paint(descriptor, t, disabled, inline, chevronOnly, icon, open, controlId) {
123289
+ const title = caption(t, descriptor.labelKey, descriptor.label);
123290
+ trigger.dataset.ribbonGallery = descriptor.id;
123291
+ popup.dataset.ribbonGalleryPopup = descriptor.id;
123292
+ const more = t('pptx.gallery.more', { name: title });
123293
+ trigger.title = inline ? (more === 'pptx.gallery.more' ? `More ${title}` : more) : title;
123294
+ trigger.setAttribute('aria-label', trigger.title);
123295
+ trigger.disabled = disabled;
123296
+ trigger.replaceChildren();
123297
+ if (!inline && !chevronOnly) {
123298
+ const svg = controlId && RIBBON_CONTROL_ICONS[controlId]
123299
+ ? createRibbonControlIcon(doc, controlId)
123300
+ : doc.createElementNS('http://www.w3.org/2000/svg', 'svg');
123301
+ if (!svg.hasAttribute('viewBox')) {
123302
+ svg.setAttribute('viewBox', '0 0 20 20');
123303
+ }
123304
+ svg.setAttribute('aria-hidden', 'true');
123305
+ const path = doc.createElementNS(svg.namespaceURI, 'path');
123306
+ path.setAttribute('d', RIBBON_ICON_PATHS[icon] ?? RIBBON_ICON_PATHS.palette);
123307
+ if (!svg.childElementCount) {
123308
+ svg.append(path);
123309
+ }
123310
+ const label = doc.createElement('span');
123311
+ label.textContent = title;
123312
+ trigger.append(svg, label);
123313
+ }
123314
+ const chevron = doc.createElement('span');
123315
+ chevron.textContent = '\u2304';
123316
+ chevron.setAttribute('aria-hidden', 'true');
123317
+ trigger.append(chevron);
123318
+ strip.hidden = !inline;
123319
+ strip.style.display = inline ? '' : 'none';
123320
+ strip.replaceChildren(...(inline
123321
+ ? inlineGalleryItems(descriptor).map((item) => tile(item, descriptor.sections[0]?.tileWidth ?? 40, descriptor.sections[0]?.tileHeight ?? 30, disabled, t))
123322
+ : []));
123323
+ popup.setAttribute('aria-label', title);
123324
+ popup.replaceChildren(...(open ? descriptor.sections : []).map((section) => {
123325
+ const container = doc.createElement('section');
123326
+ container.className = 'section';
123327
+ if (section.titleKey || section.title) {
123328
+ const heading = doc.createElement('div');
123329
+ heading.className = 'heading';
123330
+ heading.textContent = section.titleKey
123331
+ ? caption(t, section.titleKey, section.title ?? '')
123332
+ : (section.title ?? '');
123333
+ container.append(heading);
123334
+ }
123335
+ const grid = doc.createElement('div');
123336
+ grid.className = 'grid';
123337
+ grid.style.gridTemplateColumns = `repeat(${section.columns}, minmax(0, 1fr))`;
123338
+ grid.append(...section.items.map((item) => tile(item, section.tileWidth, section.tileHeight, disabled, t)));
123339
+ container.append(grid);
123340
+ return container;
123341
+ }));
123342
+ },
123343
+ };
123344
+ }
123345
+
123346
+ /** Shared light-DOM view preserves the established gallery selector/customization ABI. */
123347
+ function definePptxRibbonGallery(registry) {
123348
+ if (registry.get('pptx-ui-ribbon-gallery')) {
123349
+ return;
123350
+ }
123351
+ class RibbonGallery extends HTMLElement {
123352
+ static { this.observedAttributes = ['mode', 'chevron-only', 'icon', 'data-ribbon-control']; }
123353
+ constructor() {
123354
+ super();
123355
+ this.t = (key) => key;
123356
+ this.locked = false;
123357
+ this.opened = false;
123358
+ this.outside = (event) => {
123359
+ if (!event.composedPath().includes(this)) {
123360
+ this.close();
123361
+ }
123362
+ };
123363
+ this.escape = (event) => {
123364
+ if (event.key === 'Escape') {
123365
+ event.stopPropagation();
123366
+ this.close();
123367
+ this.view.trigger.focus();
123368
+ }
123369
+ };
123370
+ this.position = () => {
123371
+ const window = this.ownerDocument.defaultView;
123372
+ if (!window) {
123373
+ return;
123374
+ }
123375
+ const anchor = this.view.trigger.getBoundingClientRect();
123376
+ const width = this.view.popup.getBoundingClientRect().width;
123377
+ this.view.popup.style.left = `${Math.max(8, Math.min(anchor.left, window.innerWidth - width - 8))}px`;
123378
+ this.view.popup.style.top = `${Math.max(8, Math.min(anchor.bottom + 4, window.innerHeight - this.view.popup.getBoundingClientRect().height - 8))}px`;
123379
+ };
123380
+ this.view = createRibbonGalleryView(this.ownerDocument, (itemId) => this.pick(itemId), () => {
123381
+ this.open = !this.open;
123382
+ });
123383
+ this.view.root.addEventListener('keydown', (event) => {
123384
+ if (event.key === 'Escape' && this.open) {
123385
+ event.stopPropagation();
123386
+ event.preventDefault();
123387
+ this.close();
123388
+ this.view.trigger.focus();
123389
+ }
123390
+ if (event.key === 'ArrowDown' && event.target === this.view.trigger) {
123391
+ event.stopPropagation();
123392
+ event.preventDefault();
123393
+ this.open = true;
123394
+ this.view.popup.querySelector('button:not(:disabled)')?.focus();
123395
+ }
123396
+ if (event.key === 'Enter' || event.key === ' ') {
123397
+ event.stopPropagation();
123398
+ }
123399
+ });
123400
+ }
123401
+ get descriptor() {
123402
+ return this.value;
123403
+ }
123404
+ set descriptor(value) {
123405
+ this.value = value;
123406
+ this.paint();
123407
+ }
123408
+ get trigger() {
123409
+ return this.view.trigger;
123410
+ }
123411
+ get popup() {
123412
+ return this.view.popup;
123413
+ }
123414
+ get translateLabel() {
123415
+ return this.t;
123416
+ }
123417
+ set translateLabel(value) {
123418
+ this.t = value;
123419
+ this.paint();
123420
+ }
123421
+ get disabled() {
123422
+ return this.locked;
123423
+ }
123424
+ set disabled(value) {
123425
+ this.locked = Boolean(value);
123426
+ this.paint();
123427
+ }
123428
+ get open() {
123429
+ return this.opened;
123430
+ }
123431
+ set open(value) {
123432
+ const next = Boolean(value) && !this.unavailable();
123433
+ if (next === this.opened) {
123434
+ return;
123435
+ }
123436
+ this.opened = next;
123437
+ this.view.setOpen(next);
123438
+ this.paint();
123439
+ this.view.trigger.setAttribute('aria-expanded', String(next));
123440
+ this.cleanup();
123441
+ if (next && this.isConnected) {
123442
+ this.ownerDocument.addEventListener('pointerdown', this.outside, true);
123443
+ this.ownerDocument.addEventListener('keydown', this.escape);
123444
+ this.ownerDocument.defaultView?.addEventListener('resize', this.position);
123445
+ this.ownerDocument.addEventListener('scroll', this.position, true);
123446
+ this.position();
123447
+ }
123448
+ }
123449
+ close() {
123450
+ this.open = false;
123451
+ }
123452
+ connectedCallback() {
123453
+ attachRibbonGalleryStyles(this.ownerDocument);
123454
+ this.append(this.view.root);
123455
+ this.paint();
123456
+ }
123457
+ disconnectedCallback() {
123458
+ this.close();
123459
+ this.cleanup();
123460
+ }
123461
+ attributeChangedCallback() {
123462
+ this.paint();
123463
+ }
123464
+ unavailable() {
123465
+ return this.locked || !this.value || this.value.disabled || !galleryHasItems(this.value);
123466
+ }
123467
+ paint() {
123468
+ if (!this.value) {
123469
+ this.close();
123470
+ this.view.clear();
123471
+ this.view.trigger.disabled = true;
123472
+ return;
123473
+ }
123474
+ const hadFocus = this.contains(this.ownerDocument.activeElement);
123475
+ if (this.view.root.parentElement !== this) {
123476
+ this.append(this.view.root);
123477
+ }
123478
+ const focusedId = this.ownerDocument.activeElement?.getAttribute('data-gallery-item');
123479
+ const focusInPopup = this.view.popup.contains(this.ownerDocument.activeElement);
123480
+ this.view.paint(this.value, this.t, this.unavailable(), this.getAttribute('mode') === 'inline' && !this.hasAttribute('chevron-only'), this.hasAttribute('chevron-only'), this.getAttribute('icon') ?? 'palette', this.open, this.getAttribute('data-ribbon-control') ?? undefined);
123481
+ this.view.trigger.setAttribute('aria-expanded', String(this.open));
123482
+ if (this.unavailable()) {
123483
+ this.close();
123484
+ }
123485
+ if (this.open) {
123486
+ this.position();
123487
+ }
123488
+ if (focusedId && hadFocus) {
123489
+ (focusInPopup ? this.view.popup : this)
123490
+ .querySelector(`[data-gallery-item="${CSS.escape(focusedId)}"]`)
123491
+ ?.focus();
123492
+ }
123493
+ }
123494
+ pick(itemId) {
123495
+ if (this.unavailable() ||
123496
+ !this.value?.sections.some((section) => section.items.some((item) => item.id === itemId))) {
123497
+ return;
123498
+ }
123499
+ this.close();
123500
+ this.view.trigger.focus();
123501
+ this.dispatchEvent(new CustomEvent('gallery-pick', {
123502
+ detail: { gallery: this.value.id, itemId },
123503
+ bubbles: true,
123504
+ composed: true,
123505
+ }));
123506
+ }
123507
+ cleanup() {
123508
+ this.ownerDocument.removeEventListener('pointerdown', this.outside, true);
123509
+ this.ownerDocument.removeEventListener('keydown', this.escape);
123510
+ this.ownerDocument.defaultView?.removeEventListener('resize', this.position);
123511
+ this.ownerDocument.removeEventListener('scroll', this.position, true);
123512
+ }
123513
+ }
123514
+ registry.define('pptx-ui-ribbon-gallery', RibbonGallery);
123515
+ }
123516
+
123517
+ const STYLES = `
123518
+ :host { display: inline-flex; flex: none; align-self: stretch; }
123519
+ .group { box-sizing: border-box; display: flex; flex-direction: column; justify-content: space-between;
123520
+ min-height: 78px; padding: 4px 8px 2px; border-right: 1px solid color-mix(in srgb, var(--pptx-border, #33334d) 60%, transparent); }
123521
+ :host(:last-child) .group { border-right: 0; }
123522
+ .row { display: flex; align-items: flex-start; gap: 4px; }
123523
+ ::slotted(*) { flex-shrink: 0; }
123524
+ .caption { padding-top: 2px; color: var(--pptx-muted-foreground, #94a3b8); font: inherit;
123525
+ font-size: 9px; line-height: 12px; text-align: center; white-space: nowrap; }
123526
+ `;
123527
+ /** Slotted view boundary; customization ids remain in the light DOM. */
123528
+ function definePptxRibbonGroup(registry) {
123529
+ if (registry.get('pptx-ui-ribbon-group')) {
123530
+ return;
123531
+ }
123532
+ class RibbonGroup extends HTMLElement {
123533
+ static { this.observedAttributes = ['label']; }
123534
+ constructor() {
123535
+ super();
123536
+ const root = this.attachShadow({ mode: 'open' });
123537
+ attachControlStyles(root, STYLES);
123538
+ const group = document.createElement('div');
123539
+ group.className = 'group';
123540
+ const row = document.createElement('div');
123541
+ row.className = 'row';
123542
+ row.append(document.createElement('slot'));
123543
+ this.caption = document.createElement('span');
123544
+ this.caption.className = 'caption';
123545
+ group.append(row, this.caption);
123546
+ root.append(group);
123547
+ }
123548
+ connectedCallback() {
123549
+ this.setAttribute('role', 'group');
123550
+ this.sync();
123551
+ }
123552
+ attributeChangedCallback() {
123553
+ this.sync();
123554
+ }
123555
+ sync() {
123556
+ const label = this.getAttribute('label') ?? '';
123557
+ this.caption.textContent = label;
123558
+ this.setAttribute('aria-label', label);
123559
+ }
123560
+ }
123561
+ registry.define('pptx-ui-ribbon-group', RibbonGroup);
123562
+ }
123563
+
123564
+ function setBoolean(el, name, value) {
123565
+ el.toggleAttribute(name, Boolean(value));
123566
+ }
123567
+ function setOptionalBoolean(el, name, value) {
123568
+ if (value === undefined) {
123569
+ el.removeAttribute(name);
123570
+ }
123571
+ else {
123572
+ el.setAttribute(name, String(value));
123573
+ }
123574
+ }
123575
+ function syncCommand(el, command) {
123576
+ el.setAttribute('data-ribbon-control', command.id);
123577
+ el.setAttribute('label', command.label);
123578
+ el.setAttribute('title', command.title ?? command.label);
123579
+ el.setAttribute('icon', command.icon);
123580
+ if (command.badge) {
123581
+ el.setAttribute('badge', String(command.badge));
123582
+ }
123583
+ else {
123584
+ el.removeAttribute('badge');
123585
+ }
123586
+ for (const attr of ['disabled', 'active', 'compact', 'hidden']) {
123587
+ setBoolean(el, attr, command[attr]);
123588
+ }
123589
+ setOptionalBoolean(el, 'pressed', command.pressed);
123590
+ setOptionalBoolean(el, 'expanded', command.expanded);
123591
+ }
123592
+ /** Keyed updates preserve the focused native button and every customization ID. */
123593
+ function createRibbonSectionView(root) {
123594
+ const groups = new Map();
123595
+ const commands = new Map();
123596
+ return (model) => {
123597
+ const wantedGroups = new Set(model.map((group) => group.id));
123598
+ const wantedCommands = new Set(model.flatMap((group) => group.commands.map((command) => command.id)));
123599
+ for (const [id, el] of commands) {
123600
+ if (!wantedCommands.has(id)) {
123601
+ el.remove();
123602
+ commands.delete(id);
123603
+ }
123604
+ }
123605
+ for (const [id, group] of groups) {
123606
+ if (!wantedGroups.has(id)) {
123607
+ group.el.remove();
123608
+ groups.delete(id);
123609
+ }
123610
+ }
123611
+ for (const [index, group] of model.entries()) {
123612
+ let node = groups.get(group.id);
123613
+ if (!node) {
123614
+ node = { el: root.ownerDocument.createElement('pptx-ui-ribbon-group'), columns: new Map() };
123615
+ groups.set(group.id, node);
123616
+ }
123617
+ node.el.setAttribute('data-ribbon-group', group.id);
123618
+ node.el.setAttribute('label', group.label);
123619
+ if (root.children[index] !== node.el) {
123620
+ root.insertBefore(node.el, root.children[index] ?? null);
123621
+ }
123622
+ const offsets = new Map();
123623
+ for (const command of group.commands) {
123624
+ let parent = node.el;
123625
+ if (command.column !== undefined) {
123626
+ let column = node.columns.get(command.column);
123627
+ if (!column) {
123628
+ column = root.ownerDocument.createElement('div');
123629
+ Object.assign(column.style, { display: 'flex', flexDirection: 'column', gap: '2px' });
123630
+ node.columns.set(command.column, column);
123631
+ node.el.append(column);
123632
+ }
123633
+ parent = column;
123634
+ }
123635
+ let el = commands.get(command.id);
123636
+ if (!el) {
123637
+ el = root.ownerDocument.createElement('pptx-ui-ribbon-command');
123638
+ commands.set(command.id, el);
123639
+ }
123640
+ syncCommand(el, command);
123641
+ const offset = offsets.get(parent) ?? 0;
123642
+ if (parent.children[offset] !== el) {
123643
+ parent.insertBefore(el, parent.children[offset] ?? null);
123644
+ }
123645
+ offsets.set(parent, offset + 1);
123646
+ }
123647
+ }
123648
+ };
123649
+ }
123650
+
123651
+ /** Whole command/group families use one keyed view and the existing intent ABI. */
123652
+ function definePptxRibbonSection(registry) {
123653
+ if (registry.get('pptx-ui-ribbon-section')) {
123654
+ return;
123655
+ }
123656
+ class RibbonSection extends HTMLElement {
123657
+ constructor() {
123658
+ super(...arguments);
123659
+ this.model = [];
123660
+ this.render = createRibbonSectionView(this);
123661
+ }
123662
+ get groups() {
123663
+ return this.model;
123664
+ }
123665
+ set groups(value) {
123666
+ this.model = value;
123667
+ this.render(value);
123668
+ }
123669
+ connectedCallback() {
123670
+ this.style.display = 'inline-flex';
123671
+ this.style.alignItems = 'stretch';
123672
+ this.render(this.model);
123673
+ }
123674
+ }
123675
+ registry.define('pptx-ui-ribbon-section', RibbonSection);
123676
+ }
123677
+
123678
+ /** Controlled checkbox row sharing the existing checkbox's keyboard and focus behavior. */
123679
+ function definePptxRibbonToggle(registry) {
123680
+ if (registry.get('pptx-ui-ribbon-toggle')) {
123681
+ return;
123682
+ }
123683
+ class RibbonToggle extends HTMLElement {
123684
+ static { this.observedAttributes = ['label', 'checked', 'disabled', 'title']; }
123685
+ constructor() {
123686
+ super();
123687
+ const root = this.attachShadow({ mode: 'open' });
123688
+ attachControlStyles(root, `
123689
+ :host { display: block; }
123690
+ label { display: flex; align-items: center; gap: 4px; min-height: 22px; padding: 0 4px;
123691
+ color: var(--pptx-foreground, #f9fafb); font: inherit; font-size: 10px; white-space: nowrap; cursor: pointer; }
123692
+ :host([disabled]) label { color: var(--pptx-muted-foreground, #9ca3af); cursor: not-allowed; }
123693
+ @media (pointer: coarse), (max-width: 767px) { label { min-height: 44px; font-size: 12px; } }
123694
+ `);
123695
+ const label = document.createElement('label');
123696
+ this.checkbox = document.createElement('pptx-ui-checkbox');
123697
+ this.text = document.createTextNode('');
123698
+ label.append(this.checkbox, this.text);
123699
+ label.addEventListener('click', (event) => {
123700
+ event.preventDefault();
123701
+ if (event.target !== this.checkbox) {
123702
+ this.checkbox.click();
123703
+ }
123704
+ });
123705
+ this.checkbox.addEventListener('input', (event) => event.stopPropagation());
123706
+ this.checkbox.addEventListener('change', (event) => {
123707
+ event.stopPropagation();
123708
+ const checked = this.checkbox.checked;
123709
+ this.sync();
123710
+ const id = this.getAttribute('data-ribbon-control');
123711
+ if (!this.hasAttribute('disabled') && id) {
123712
+ this.dispatchEvent(new CustomEvent('toggle-request', {
123713
+ detail: { id, checked },
123714
+ bubbles: true,
123715
+ composed: true,
123716
+ }));
123717
+ }
123718
+ });
123719
+ root.append(label);
123720
+ }
123721
+ connectedCallback() {
123722
+ this.sync();
123723
+ }
123724
+ attributeChangedCallback() {
123725
+ this.sync();
123726
+ }
123727
+ sync() {
123728
+ const label = this.getAttribute('label') ?? '';
123729
+ this.text.textContent = label;
123730
+ this.checkbox.setAttribute('aria-label', label);
123731
+ this.checkbox.title = this.getAttribute('title') ?? label;
123732
+ this.checkbox.checked = this.hasAttribute('checked');
123733
+ this.checkbox.disabled = this.hasAttribute('disabled');
123734
+ }
123735
+ }
123736
+ registry.define('pptx-ui-ribbon-toggle', RibbonToggle);
123737
+ }
123738
+
123739
+ const SEARCH_STYLES = `
123740
+ :host {
123741
+ display: flex;
123742
+ align-items: center;
123743
+ gap: 8px;
123744
+ box-sizing: border-box;
123745
+ width: 100%;
123746
+ height: 40px;
123747
+ padding: 0 12px;
123748
+ border: 1px solid var(--pptx-input, #374151);
123749
+ background: var(--pptx-card, #111827);
123750
+ color: var(--pptx-muted-foreground, #9ca3af);
123751
+ font: inherit;
123752
+ }
123753
+ :host(:focus-within) { border-color: var(--pptx-ring, #6366f1); }
123754
+ :host([variant="titlebar"]) {
123755
+ height: 28px;
123756
+ gap: 7px;
123757
+ padding-inline: 14px;
123758
+ border-color: var(--pptx-border, #374151);
123759
+ border-radius: 6px;
123760
+ background: var(--pptx-background, #030712);
123761
+ }
123762
+ :host([variant="titlebar"]:focus-within) {
123763
+ border-color: var(--pptx-ring, #6366f1);
123764
+ color: var(--pptx-foreground, #f3f4f6);
123765
+ }
123766
+ :host([disabled]) { opacity: .5; cursor: not-allowed; }
123767
+ svg { width: 16px; height: 16px; flex: none; }
123768
+ :host([variant="titlebar"]) svg { width: 14px; height: 14px; }
123769
+ input {
123770
+ min-width: 0;
123771
+ width: 100%;
123772
+ height: 100%;
123773
+ flex: 1;
123774
+ padding: 0;
123775
+ border: 0;
123776
+ outline: 0;
123777
+ background: transparent;
123778
+ color: var(--pptx-card-foreground, #f3f4f6);
123779
+ font: inherit;
123780
+ font-size: 13px;
123781
+ }
123782
+ :host([variant="titlebar"]) input {
123783
+ font-size: 11px;
123784
+ color: var(--pptx-foreground, #f3f4f6);
123785
+ }
123786
+ input::placeholder {
123787
+ color: var(--pptx-muted-foreground, #9ca3af);
123788
+ opacity: .8;
123789
+ }
123790
+ input::-webkit-search-cancel-button { display: none; }
123791
+ @media (forced-colors: active) {
123792
+ :host {
123793
+ border-color: CanvasText;
123794
+ background: Canvas;
123795
+ color: CanvasText;
123796
+ }
123797
+ :host(:focus-within) {
123798
+ outline: 2px solid Highlight;
123799
+ outline-offset: 2px;
123800
+ }
123801
+ input { color: CanvasText; }
123802
+ }
123803
+ `;
123804
+
123805
+ const SEARCH_ICON = `<svg part="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg>`;
123806
+ /** A single styled search input for the title bar and recent-files surface. */
123807
+ function definePptxSearchField(registry) {
123808
+ if (registry.get('pptx-ui-search')) {
123809
+ return;
123810
+ }
123811
+ class PptxSearchField extends HTMLElement {
123812
+ static { this.observedAttributes = ['placeholder', 'aria-label', 'disabled', 'value']; }
123813
+ constructor() {
123814
+ super();
123815
+ this.currentValue = '';
123816
+ const root = this.attachShadow({ mode: 'open', delegatesFocus: true });
123817
+ attachControlStyles(root, SEARCH_STYLES);
123818
+ const icon = document.createElement('template');
123819
+ icon.innerHTML = SEARCH_ICON;
123820
+ root.append(icon.content.cloneNode(true));
123821
+ this.input = document.createElement('input');
123822
+ this.input.type = 'search';
123823
+ this.input.setAttribute('part', 'input');
123824
+ this.input.addEventListener('input', (event) => {
123825
+ event.stopPropagation();
123826
+ this.currentValue = this.input.value;
123827
+ this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
123828
+ });
123829
+ this.input.addEventListener('change', (event) => {
123830
+ event.stopPropagation();
123831
+ this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
123832
+ });
123833
+ root.append(this.input);
123834
+ }
123835
+ connectedCallback() {
123836
+ this.sync();
123837
+ if (this.hasAttribute('value')) {
123838
+ this.value = this.getAttribute('value') ?? '';
123839
+ }
123840
+ }
123841
+ attributeChangedCallback(name) {
123842
+ if (name === 'value') {
123843
+ this.value = this.getAttribute('value') ?? '';
123844
+ }
123845
+ else {
123846
+ this.sync();
123847
+ }
123848
+ }
123849
+ get value() {
123850
+ return this.currentValue;
123851
+ }
123852
+ set value(next) {
123853
+ this.currentValue = String(next ?? '');
123854
+ if (this.input.value !== this.currentValue) {
123855
+ this.input.value = this.currentValue;
123856
+ }
123857
+ }
123858
+ get disabled() {
123859
+ return this.hasAttribute('disabled');
123860
+ }
123861
+ set disabled(next) {
123862
+ this.toggleAttribute('disabled', Boolean(next));
123863
+ }
123864
+ focus(options) {
123865
+ this.input.focus(options);
123866
+ }
123867
+ select() {
123868
+ this.input.select();
123869
+ }
123870
+ sync() {
123871
+ this.input.placeholder = this.getAttribute('placeholder') ?? '';
123872
+ this.input.setAttribute('aria-label', this.getAttribute('aria-label') ?? this.input.placeholder);
123873
+ this.input.disabled = this.hasAttribute('disabled');
123874
+ }
123875
+ }
123876
+ registry.define('pptx-ui-search', PptxSearchField);
123877
+ }
123878
+
123879
+ /** Mutations that can change a select's value, labels or font preview. */
123880
+ const SELECT_OPTION_ATTRIBUTES = [
123881
+ 'value',
123882
+ 'disabled',
123883
+ 'label',
123884
+ 'selected',
123885
+ 'hidden',
123886
+ 'data-display-label',
123887
+ 'data-description',
123888
+ 'style',
123889
+ ];
123890
+ /** Flatten options while retaining optgroup labels and disabled state. */
123891
+ function collectSelectChoices(options) {
123892
+ return options.map((option) => {
123893
+ const group = option.parentElement instanceof HTMLOptGroupElement ? option.parentElement : null;
123894
+ return {
123895
+ value: option.value,
123896
+ label: option.label || option.textContent?.trim() || '',
123897
+ disabled: option.disabled || Boolean(group?.disabled),
123898
+ hidden: Boolean(option.hidden) || Boolean(group?.hidden),
123899
+ group: group?.label ?? '',
123900
+ ...(option.dataset.displayLabel ? { displayLabel: option.dataset.displayLabel } : {}),
123901
+ ...(option.dataset.description ? { description: option.dataset.description } : {}),
123902
+ ...(option.style.fontFamily ? { fontFamily: option.style.fontFamily } : {}),
123903
+ };
123904
+ });
123905
+ }
123906
+ /** Build popup options only when the select first opens. */
123907
+ function renderSelectMenu(menu, choices, value) {
123908
+ const menuItems = [];
123909
+ let previousGroup = '';
123910
+ choices.forEach((choice, index) => {
123911
+ if (choice.hidden) {
123912
+ return;
123913
+ }
123914
+ if (choice.group && choice.group !== previousGroup) {
123915
+ const heading = document.createElement('div');
123916
+ heading.className = 'group';
123917
+ heading.setAttribute('role', 'presentation');
123918
+ heading.textContent = choice.group;
123919
+ menuItems.push(heading);
123920
+ }
123921
+ previousGroup = choice.group;
123922
+ const item = document.createElement('div');
123923
+ item.className = 'option';
123924
+ item.setAttribute('role', 'option');
123925
+ item.setAttribute('aria-selected', String(choice.value === value));
123926
+ item.setAttribute('aria-disabled', String(choice.disabled));
123927
+ item.id = `${menu.id}-${index}`;
123928
+ item.dataset.index = String(index);
123929
+ item.textContent = choice.displayLabel ?? choice.label;
123930
+ if (choice.fontFamily) {
123931
+ item.style.fontFamily = choice.fontFamily;
123932
+ }
123933
+ if (choice.description) {
123934
+ const description = document.createElement('span');
123935
+ description.className = 'description';
123936
+ description.textContent = choice.description;
123937
+ item.append(description);
123938
+ }
123939
+ menuItems.push(item);
123940
+ });
123941
+ menu.replaceChildren(...menuItems);
123942
+ }
123943
+ /** Prefer below the trigger, flipping above when it offers more room. */
123944
+ function positionSelectMenu(menu, trigger) {
123945
+ const rect = trigger.getBoundingClientRect();
123946
+ const margin = 8;
123947
+ const gap = 4;
123948
+ const width = Math.max(0, window.innerWidth - margin * 2);
123949
+ const below = Math.max(0, window.innerHeight - rect.bottom - gap - margin);
123950
+ const above = Math.max(0, rect.top - gap - margin);
123951
+ menu.style.minWidth = `${Math.min(rect.width, width)}px`;
123952
+ menu.style.maxWidth = `${width}px`;
123953
+ // Measure at the normal height cap before choosing a side. Reset the cap
123954
+ // on every reposition so a previously constrained menu can grow again.
123955
+ const heightCap = trigger.getRootNode() instanceof ShadowRoot &&
123956
+ trigger.getRootNode().host.getAttribute('data-font-picker') === 'family'
123957
+ ? 320
123958
+ : 240;
123959
+ menu.style.maxHeight = `${heightCap}px`;
123960
+ const preferredHeight = menu.getBoundingClientRect().height;
123961
+ const flip = below < preferredHeight && above > below;
123962
+ menu.style.maxHeight = `${Math.min(heightCap, flip ? above : below)}px`;
123963
+ const { height, width: menuWidth } = menu.getBoundingClientRect();
123964
+ menu.style.top = `${Math.max(margin, flip ? rect.top - gap - height : rect.bottom + gap)}px`;
123965
+ menu.style.left = `${Math.max(margin, Math.min(rect.left, window.innerWidth - menuWidth - margin))}px`;
123966
+ }
123967
+ /** Expose the keyboard target while keeping the selected state separate. */
123968
+ function markSelectActive(menu, trigger, active, open) {
123969
+ for (const item of menu.querySelectorAll('[data-index]')) {
123970
+ item.toggleAttribute('data-active', Number(item.dataset.index) === active && open);
123971
+ }
123972
+ if (open && active >= 0) {
123973
+ trigger.setAttribute('aria-activedescendant', `${menu.id}-${active}`);
123974
+ }
123975
+ menu.querySelector('[data-active]')?.scrollIntoView?.({ block: 'nearest' });
123976
+ }
123977
+ /** Find the next enabled option when navigating with the arrow keys. */
123978
+ function nextSelectActive(choices, active, step) {
123979
+ for (let index = 0; index < choices.length; index++) {
123980
+ active = (active + step + choices.length) % choices.length;
123981
+ if (!choices[active].disabled && !choices[active].hidden) {
123982
+ return active;
123983
+ }
123984
+ }
123985
+ return active;
123986
+ }
123987
+
123988
+ /** React's ribbon presentation, isolated from inspector and dialog selects. */
123989
+ const SELECT_RIBBON_STYLES = `
123990
+ :host([variant^="ribbon-"][disabled]) { opacity: .4; }
123991
+ :host([variant^="ribbon-"]) button {
123992
+ height: 28px; min-height: 28px; padding: 4px 8px; gap: 4px;
123993
+ border: 1px solid color-mix(in oklab, var(--pptx-border) 60%, transparent);
123994
+ border-radius: 3px; font-size: 12px; line-height: 18px;
123995
+ background: color-mix(in oklab, var(--pptx-background) 60%, transparent);
123996
+ color: var(--pptx-foreground);
123997
+ }
123998
+ :host([variant^="ribbon-"]) .value { flex: 1; min-width: 0; }
123999
+ :host([variant^="ribbon-"]) .chevron {
124000
+ width: 16px; height: 16px; margin: 0; border: 0; transform: none;
124001
+ }
124002
+ :host([variant^="ribbon-"]) .chevron svg { display: block; width: 16px; height: 16px; }
124003
+ :host([variant="ribbon-font"]) .chevron { color: var(--pptx-muted-foreground); }
124004
+ :host([variant="ribbon-font"][data-font-picker="size"]) button { padding-inline: 6px; }
124005
+ :host([variant="ribbon-icon"]) button {
124006
+ width: 36px; gap: 6px; padding: 6px 10px; border: 0; font-size: 12px; line-height: 16px;
124007
+ background: var(--pptx-muted); justify-content: center;
124008
+ }
124009
+ :host([variant="ribbon-icon"]) :is(.value, .chevron) { display: none; }
124010
+ ::slotted(svg[slot="icon"]) { display: block; width: 16px; height: 16px; flex: none; }
124011
+ :host([variant^="ribbon-"]) button:hover:not(:disabled) { background: var(--pptx-accent); }
124012
+ :host([variant^="ribbon-"]) .menu {
124013
+ width: 192px; padding: 4px 0; border-radius: 8px; font-size: 12px; line-height: 16px;
124014
+ }
124015
+ :host([data-font-picker="family"]) .menu { width: 256px; }
124016
+ :host([variant^="ribbon-"]) .option {
124017
+ display: flex; justify-content: space-between; gap: 12px; padding: 6px 12px; border-radius: 0;
124018
+ }
124019
+ :host([variant^="ribbon-"]) .option[aria-selected="true"] {
124020
+ background: transparent; color: var(--pptx-foreground);
124021
+ }
124022
+ :host([variant^="ribbon-"]) .option:hover,
124023
+ :host([variant^="ribbon-"]) .option[data-active] { background: var(--pptx-muted); filter: none; }
124024
+ :host([variant^="ribbon-"]) .group {
124025
+ padding: 8px 12px 4px; text-transform: uppercase; letter-spacing: .25px;
124026
+ font-size: 10px; line-height: 15px;
124027
+ }
124028
+ @media (max-width: 767px) {
124029
+ :host([variant^="ribbon-"]) button { height: 44px; min-height: 44px; }
124030
+ }
124031
+ .description { flex: none; color: var(--pptx-muted-foreground); font-size: 10px; line-height: 15px; }
124032
+ `;
124033
+
124034
+ const SELECT_STYLES = `
124035
+ :host {
124036
+ display: inline-block;
124037
+ box-sizing: border-box;
124038
+ min-width: 0;
124039
+ max-width: 100%;
124040
+ border: 0 !important;
124041
+ padding: 0 !important;
124042
+ background: transparent !important;
124043
+ box-shadow: none !important;
124044
+ color: var(--pptx-foreground, #e2e8f0);
124045
+ font: inherit;
124046
+ font-size: 12px;
124047
+ vertical-align: middle;
124048
+ }
124049
+ :host([disabled]) { opacity: .5; cursor: not-allowed; }
124050
+ button {
124051
+ box-sizing: border-box;
124052
+ width: 100%;
124053
+ min-height: 28px;
124054
+ display: flex;
124055
+ align-items: center;
124056
+ justify-content: space-between;
124057
+ gap: 10px;
124058
+ padding: 4px 7px;
124059
+ border: 1px solid var(--pptx-border, #3f3f52);
124060
+ border-radius: 5px;
124061
+ background: var(--pptx-select-control-bg, var(--pptx-background, #11111b));
124062
+ color: inherit;
124063
+ font: inherit;
124064
+ font-size: inherit;
124065
+ text-align: left;
124066
+ cursor: pointer;
124067
+ }
124068
+ :host(.bg-muted) button { background: var(--pptx-muted, #1f2937); }
124069
+ :host(.bg-popover) button { background: var(--pptx-popover, #111827); }
124070
+ button:focus-visible {
124071
+ outline: 2px solid var(--pptx-ring, #6366f1);
124072
+ outline-offset: 2px;
124073
+ }
124074
+ button:disabled { cursor: not-allowed; }
124075
+ @media (pointer: coarse), (max-width: 767px) {
124076
+ button { min-height: 44px; }
124077
+ }
124078
+ .value {
124079
+ overflow: hidden;
124080
+ text-overflow: ellipsis;
124081
+ white-space: nowrap;
124082
+ }
124083
+ .chevron svg { display: none; }
124084
+ .chevron {
124085
+ flex: none;
124086
+ width: 6px;
124087
+ height: 6px;
124088
+ margin: 0 2px 3px 0;
124089
+ border-right: 1.5px solid currentColor;
124090
+ border-bottom: 1.5px solid currentColor;
124091
+ transform: rotate(45deg);
124092
+ }
124093
+ :host([open]) .chevron {
124094
+ margin: 3px 2px 0 0;
124095
+ transform: rotate(225deg);
124096
+ }
124097
+ .menu {
124098
+ box-sizing: border-box;
124099
+ position: fixed;
124100
+ margin: 0;
124101
+ padding: 4px;
124102
+ min-width: 90px;
124103
+ max-height: min(240px, 50vh);
124104
+ overflow: auto;
124105
+ border: 1px solid var(--pptx-border, #3f3f52);
124106
+ border-radius: 5px;
124107
+ background: var(--pptx-popover, var(--pptx-background, #11111b));
124108
+ color: var(--pptx-popover-foreground, var(--pptx-foreground, #e2e8f0));
124109
+ box-shadow: 0 8px 20px #0004;
124110
+ font: inherit;
124111
+ font-size: inherit;
124112
+ }
124113
+ .menu:not(:popover-open):not([data-fallback-open]) { display: none; }
124114
+ .option {
124115
+ display: block;
124116
+ box-sizing: border-box;
124117
+ width: 100%;
124118
+ padding: 6px 8px;
124119
+ border-radius: 3px;
124120
+ cursor: pointer;
124121
+ white-space: nowrap;
124122
+ }
124123
+ .group {
124124
+ padding: 7px 8px 3px;
124125
+ color: var(--pptx-muted-foreground, #9ca3af);
124126
+ font-size: .9em;
124127
+ font-weight: 600;
124128
+ }
124129
+ .option:not([aria-disabled="true"]):hover,
124130
+ .option[data-active]:not([aria-selected="true"]) {
124131
+ background: color-mix(in srgb, var(--pptx-primary, #e86a40) 20%, var(--pptx-popover, #11111b));
124132
+ }
124133
+ .option[aria-selected="true"] {
124134
+ background: var(--pptx-primary, #e86a40);
124135
+ color: var(--pptx-primary-foreground, #fff);
124136
+ }
124137
+ .option[aria-selected="true"]:hover { filter: brightness(1.08); }
124138
+ .option[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
124139
+ @media (forced-colors: active) {
124140
+ button, .menu {
124141
+ border-color: CanvasText;
124142
+ background: Canvas;
124143
+ color: CanvasText;
124144
+ }
124145
+ .option[aria-selected="true"],
124146
+ .option[data-active],
124147
+ .option:not([aria-disabled="true"]):hover {
124148
+ background: Highlight;
124149
+ color: HighlightText;
124150
+ }
124151
+ }
124152
+ ${SELECT_RIBBON_STYLES}
124153
+ `;
124154
+
124155
+ /** Slots let ribbon controls retain their canonical icon and optional custom entry. */
124156
+ function createSelectTrigger() {
124157
+ const trigger = document.createElement('button');
124158
+ trigger.type = 'button';
124159
+ trigger.setAttribute('part', 'trigger');
124160
+ trigger.setAttribute('role', 'combobox');
124161
+ trigger.setAttribute('aria-haspopup', 'listbox');
124162
+ trigger.setAttribute('aria-expanded', 'false');
124163
+ const icon = document.createElement('slot');
124164
+ icon.name = 'icon';
124165
+ const text = document.createElement('span');
124166
+ text.className = 'value';
124167
+ text.setAttribute('part', 'value');
124168
+ const chevron = document.createElement('span');
124169
+ chevron.className = 'chevron';
124170
+ chevron.setAttribute('part', 'indicator');
124171
+ chevron.setAttribute('aria-hidden', 'true');
124172
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
124173
+ svg.setAttribute('viewBox', '0 0 24 24');
124174
+ svg.setAttribute('fill', 'none');
124175
+ svg.setAttribute('stroke', 'currentColor');
124176
+ svg.setAttribute('stroke-width', '2');
124177
+ svg.setAttribute('stroke-linecap', 'round');
124178
+ svg.setAttribute('stroke-linejoin', 'round');
124179
+ const path = document.createElementNS(svg.namespaceURI, 'path');
124180
+ path.setAttribute('d', 'm6 9 6 6 6-6');
124181
+ svg.append(path);
124182
+ chevron.append(svg);
124183
+ trigger.append(icon, text, chevron);
124184
+ return { trigger, text };
124185
+ }
124186
+ /** Optional editable content stays in the light DOM so bindings own its events. */
124187
+ function prependSelectCustomSlot(host, menu) {
124188
+ if (host.querySelector('[slot="custom"]')) {
124189
+ const custom = document.createElement('slot');
124190
+ custom.name = 'custom';
124191
+ menu.prepend(custom);
124192
+ }
124193
+ }
124194
+
124195
+ /** Create the base only in a browser; shared imports also run during SSR. */
124196
+ function createSelectValueElement() {
124197
+ class SelectValueElement extends HTMLElement {
124198
+ get value() {
124199
+ const requested = this.getAttribute('value');
124200
+ const options = this.options;
124201
+ if (this.getAttribute('variant') === 'ribbon-font' && requested !== null) {
124202
+ return requested;
124203
+ }
124204
+ if (requested !== null &&
124205
+ (!options.length || options.some((option) => option.value === requested))) {
124206
+ return requested;
124207
+ }
124208
+ return (options.find((option) => option.selected)?.value ??
124209
+ options.find((option) => !option.disabled && !option.closest('optgroup[disabled]') && !option.hidden)?.value ??
124210
+ options[0]?.value ??
124211
+ requested ??
124212
+ '');
124213
+ }
124214
+ set value(next) {
124215
+ this.setAttribute('value', String(next ?? ''));
124216
+ }
124217
+ get options() {
124218
+ return [...this.querySelectorAll('option')];
124219
+ }
124220
+ get selectedIndex() {
124221
+ return this.options.findIndex((option) => option.value === this.value);
124222
+ }
124223
+ set selectedIndex(index) {
124224
+ this.value = this.options[index]?.value ?? '';
124225
+ }
124226
+ }
124227
+ return SelectValueElement;
124228
+ }
124229
+
124230
+ let nextSelectId = 0;
124231
+ /** A select-only combobox with one popup and event contract in every binding. */
124232
+ function definePptxSelect(registry) {
124233
+ if (registry.get('pptx-ui-select')) {
124234
+ return;
124235
+ }
124236
+ class PptxSelect extends createSelectValueElement() {
124237
+ static { this.formAssociated = true; }
124238
+ static { this.observedAttributes = ['value', 'disabled', 'aria-label']; }
124239
+ constructor() {
124240
+ super();
124241
+ this.refreshFrame = 0;
124242
+ this.choices = [];
124243
+ this.active = -1;
124244
+ this.open = false;
124245
+ this.search = '';
124246
+ this.searchTimer = 0;
124247
+ this.defaultValue = '';
124248
+ this.onOutside = (event) => {
124249
+ if (!event.composedPath().includes(this)) {
124250
+ this.close();
124251
+ }
124252
+ };
124253
+ this.position = () => {
124254
+ if (!this.open) {
124255
+ return;
124256
+ }
124257
+ positionSelectMenu(this.menu, this.trigger);
124258
+ };
124259
+ try {
124260
+ this.internals = this.attachInternals();
124261
+ }
124262
+ catch {
124263
+ this.internals = undefined;
124264
+ }
124265
+ const root = this.attachShadow({ mode: 'open', delegatesFocus: true });
124266
+ attachControlStyles(root, SELECT_STYLES);
124267
+ ({ trigger: this.trigger, text: this.text } = createSelectTrigger());
124268
+ this.menu = document.createElement('div');
124269
+ this.menu.className = 'menu';
124270
+ this.menu.id = `pptx-ui-select-options-${++nextSelectId}`;
124271
+ this.menu.setAttribute('role', 'listbox');
124272
+ this.menu.setAttribute('popover', 'manual');
124273
+ this.menu.setAttribute('part', 'popup');
124274
+ this.trigger.setAttribute('aria-controls', this.menu.id);
124275
+ root.append(this.trigger, this.menu);
124276
+ this.trigger.addEventListener('click', () => (this.open ? this.close() : this.show()));
124277
+ this.trigger.addEventListener('keydown', (event) => this.onKeyDown(event));
124278
+ this.menu.addEventListener('pointerdown', (event) => {
124279
+ if (event.target.closest('[data-index]')) {
124280
+ event.preventDefault();
124281
+ }
124282
+ });
124283
+ this.menu.addEventListener('click', (event) => {
124284
+ const target = event.target.closest('[data-index]');
124285
+ if (target) {
124286
+ this.commit(Number(target.dataset.index));
124287
+ }
124288
+ });
124289
+ this.observer = new MutationObserver(() => {
124290
+ // Let bindings finish updating their option nodes before touching the shadow DOM.
124291
+ if (!this.refreshFrame) {
124292
+ this.refreshFrame = requestAnimationFrame(() => {
124293
+ this.refreshFrame = 0;
124294
+ this.refresh();
124295
+ });
124296
+ }
124297
+ });
124298
+ }
124299
+ connectedCallback() {
124300
+ this.defaultValue = this.getAttribute('value') ?? '';
124301
+ this.observer.observe(this, {
124302
+ childList: true,
124303
+ subtree: true,
124304
+ attributes: true,
124305
+ characterData: true,
124306
+ attributeFilter: SELECT_OPTION_ATTRIBUTES,
124307
+ });
124308
+ this.refresh();
124309
+ }
124310
+ disconnectedCallback() {
124311
+ this.close();
124312
+ window.clearTimeout(this.searchTimer);
124313
+ this.searchTimer = 0;
124314
+ this.search = '';
124315
+ this.observer.disconnect();
124316
+ cancelAnimationFrame(this.refreshFrame);
124317
+ this.refreshFrame = 0;
124318
+ }
124319
+ attributeChangedCallback() {
124320
+ this.refresh();
124321
+ }
124322
+ get disabled() {
124323
+ return this.hasAttribute('disabled');
124324
+ }
124325
+ set disabled(next) {
124326
+ this.toggleAttribute('disabled', Boolean(next));
124327
+ }
124328
+ focus(options) {
124329
+ this.trigger.focus(options);
124330
+ }
124331
+ formResetCallback() {
124332
+ this.value = this.defaultValue;
124333
+ }
124334
+ formDisabledCallback(disabled) {
124335
+ this.disabled = disabled;
124336
+ }
124337
+ refresh() {
124338
+ if (!this.trigger) {
124339
+ return;
124340
+ }
124341
+ const options = [...this.querySelectorAll('option')];
124342
+ this.choices = collectSelectChoices(options);
124343
+ if (!this.hasAttribute('value') && this.choices.length) {
124344
+ this.value =
124345
+ options.find((option) => option.selected)?.value ??
124346
+ this.choices.find((choice) => !choice.disabled && !choice.hidden)?.value ??
124347
+ this.choices[0].value;
124348
+ }
124349
+ this.text.textContent =
124350
+ this.choices.find((choice) => choice.value === this.value)?.displayLabel ??
124351
+ this.choices.find((choice) => choice.value === this.value)?.label ??
124352
+ this.value;
124353
+ this.trigger.disabled = this.disabled;
124354
+ if (this.disabled) {
124355
+ this.close();
124356
+ }
124357
+ this.trigger.setAttribute('aria-label', this.getAttribute('aria-label') ?? '');
124358
+ this.internals?.setFormValue?.(this.disabled ? null : this.value);
124359
+ if (this.open || this.menu.childElementCount) {
124360
+ this.renderMenu();
124361
+ }
124362
+ }
124363
+ renderMenu() {
124364
+ renderSelectMenu(this.menu, this.choices, this.value);
124365
+ prependSelectCustomSlot(this, this.menu);
124366
+ markSelectActive(this.menu, this.trigger, this.active, this.open);
124367
+ }
124368
+ show() {
124369
+ if (this.disabled ||
124370
+ !this.choices.some((choice) => !choice.disabled && !choice.hidden) ||
124371
+ this.open) {
124372
+ return;
124373
+ }
124374
+ this.open = true;
124375
+ this.setAttribute('open', '');
124376
+ const selected = this.choices.findIndex((choice) => choice.value === this.value && !choice.disabled && !choice.hidden);
124377
+ this.active =
124378
+ selected >= 0
124379
+ ? selected
124380
+ : this.choices.findIndex((choice) => !choice.disabled && !choice.hidden);
124381
+ this.renderMenu();
124382
+ if (typeof this.menu.showPopover === 'function') {
124383
+ this.menu.showPopover();
124384
+ }
124385
+ else {
124386
+ this.menu.dataset.fallbackOpen = '';
124387
+ }
124388
+ this.trigger.setAttribute('aria-expanded', 'true');
124389
+ this.position();
124390
+ markSelectActive(this.menu, this.trigger, this.active, this.open);
124391
+ document.addEventListener('pointerdown', this.onOutside, true);
124392
+ window.addEventListener('resize', this.position);
124393
+ window.addEventListener('scroll', this.position, true);
124394
+ }
124395
+ close() {
124396
+ if (!this.open) {
124397
+ return;
124398
+ }
124399
+ this.open = false;
124400
+ window.clearTimeout(this.searchTimer);
124401
+ this.search = '';
124402
+ this.removeAttribute('open');
124403
+ if (this.menu.matches(':popover-open')) {
124404
+ this.menu.hidePopover();
124405
+ }
124406
+ delete this.menu.dataset.fallbackOpen;
124407
+ this.trigger.setAttribute('aria-expanded', 'false');
124408
+ this.trigger.removeAttribute('aria-activedescendant');
124409
+ document.removeEventListener('pointerdown', this.onOutside, true);
124410
+ window.removeEventListener('resize', this.position);
124411
+ window.removeEventListener('scroll', this.position, true);
124412
+ }
124413
+ move(step) {
124414
+ if (!this.open) {
124415
+ this.show();
124416
+ }
124417
+ if (!this.open) {
124418
+ return;
124419
+ }
124420
+ this.active = nextSelectActive(this.choices, this.active, step);
124421
+ markSelectActive(this.menu, this.trigger, this.active, this.open);
124422
+ }
124423
+ commit(index) {
124424
+ const choice = this.choices[index];
124425
+ if (!choice || choice.disabled || choice.hidden) {
124426
+ return;
124427
+ }
124428
+ const changed = this.value !== choice.value;
124429
+ this.value = choice.value;
124430
+ this.close();
124431
+ this.trigger.focus();
124432
+ if (changed) {
124433
+ this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
124434
+ this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));
124435
+ }
124436
+ }
124437
+ onKeyDown(event) {
124438
+ if (this.disabled) {
124439
+ return;
124440
+ }
124441
+ if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
124442
+ event.preventDefault();
124443
+ event.stopPropagation();
124444
+ this.move(event.key === 'ArrowDown' ? 1 : -1);
124445
+ }
124446
+ else if (event.key === 'Home' || event.key === 'End') {
124447
+ event.preventDefault();
124448
+ event.stopPropagation();
124449
+ this.show();
124450
+ this.active =
124451
+ event.key === 'Home'
124452
+ ? nextSelectActive(this.choices, -1, 1)
124453
+ : nextSelectActive(this.choices, 0, -1);
124454
+ markSelectActive(this.menu, this.trigger, this.active, this.open);
124455
+ }
124456
+ else if (event.key === 'Enter' || event.key === ' ') {
124457
+ event.preventDefault();
124458
+ event.stopPropagation();
124459
+ if (this.open) {
124460
+ this.commit(this.active);
124461
+ }
124462
+ else {
124463
+ this.show();
124464
+ }
124465
+ }
124466
+ else if (event.key === 'Escape' && this.open) {
124467
+ event.preventDefault();
124468
+ event.stopPropagation();
124469
+ this.close();
124470
+ this.trigger.focus();
124471
+ }
124472
+ else if (event.key === 'Tab') {
124473
+ this.close();
124474
+ }
124475
+ else if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
124476
+ event.stopPropagation();
124477
+ this.search += event.key.toLocaleLowerCase();
124478
+ window.clearTimeout(this.searchTimer);
124479
+ this.searchTimer = window.setTimeout(() => {
124480
+ this.search = '';
124481
+ }, 700);
124482
+ this.show();
124483
+ const index = this.choices.findIndex((choice) => !choice.disabled &&
124484
+ !choice.hidden &&
124485
+ choice.label.toLocaleLowerCase().startsWith(this.search));
124486
+ if (index >= 0) {
124487
+ this.active = index;
124488
+ markSelectActive(this.menu, this.trigger, this.active, this.open);
124489
+ }
124490
+ }
124491
+ }
124492
+ }
124493
+ registry.define('pptx-ui-select', PptxSelect);
124494
+ }
124495
+
123810
124496
  const SLIDE_SHOW_OPTIONS_STYLES = `
123811
124497
  :host {
123812
124498
  display: inline-flex;
@@ -124468,6 +125154,8 @@ const controls = [
124468
125154
  ['pptx-ui-slide-show-options', definePptxSlideShowOptions],
124469
125155
  ['pptx-ui-ribbon-command', definePptxRibbonCommand],
124470
125156
  ['pptx-ui-ribbon-group', definePptxRibbonGroup],
125157
+ ['pptx-ui-ribbon-section', definePptxRibbonSection],
125158
+ ['pptx-ui-ribbon-gallery', definePptxRibbonGallery],
124471
125159
  ['pptx-ui-ribbon-toggle', definePptxRibbonToggle],
124472
125160
  ['pptx-ui-subtitle-settings', definePptxSubtitleSettings],
124473
125161
  ['pptx-ui-theme-editor', definePptxThemeEditor],
@@ -131988,7 +132676,7 @@ function createLocalStorageBackend(namespace) {
131988
132676
  /** Try IndexedDB first; fall back to localStorage on any failure. */
131989
132677
  async function resolveBackend(dbName, namespace) {
131990
132678
  try {
131991
- const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-CV-VR2z1.mjs');
132679
+ const { openChatDb, createIdbBackend } = await import('./pptx-angular-viewer-chat-history-idb-Bb82Jssm.mjs');
131992
132680
  const db = await openChatDb(dbName);
131993
132681
  return createIdbBackend(db);
131994
132682
  }
@@ -171338,151 +172026,6 @@ function dispatchGalleryResult(result, targets) {
171338
172026
  return true;
171339
172027
  }
171340
172028
 
171341
- /**
171342
- * ribbon-gallery-svg.pipe.ts: `| pptxGallerySvg` marks a gallery tile's
171343
- * `previewSvg` as trusted markup for an `[innerHTML]` binding.
171344
- *
171345
- * Angular's default HTML sanitiser strips `<svg>` content, which would leave
171346
- * every tile blank. The preview strings come from `pptx-viewer-shared`'s
171347
- * gallery modules, which build them only from catalogue data and theme
171348
- * colours (never from user text), so bypassing the sanitiser here is the
171349
- * same trust decision React's `dangerouslySetInnerHTML`, Vue's `v-html`,
171350
- * Svelte's `{@html}` and vanilla's `innerHTML` make for the same string.
171351
- */
171352
- class RibbonGallerySvgPipe {
171353
- constructor() {
171354
- this.sanitizer = inject(DomSanitizer);
171355
- }
171356
- transform(svg) {
171357
- return this.sanitizer.bypassSecurityTrustHtml(svg);
171358
- }
171359
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RibbonGallerySvgPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
171360
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "22.1.6", ngImport: i0, type: RibbonGallerySvgPipe, isStandalone: true, name: "pptxGallerySvg" }); }
171361
- }
171362
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RibbonGallerySvgPipe, decorators: [{
171363
- type: Pipe,
171364
- args: [{ name: 'pptxGallerySvg', standalone: true }]
171365
- }] });
171366
-
171367
- /**
171368
- * ribbon-gallery-popup.component.ts: the dropped-down panel of a
171369
- * {@link RibbonGalleryComponent}: every descriptor section (optional heading,
171370
- * then a `section.columns`-wide grid of preview tiles), pinned under the
171371
- * gallery with `[pptxAnchoredPopup]`. Emits the picked tile; the parent
171372
- * applies it and closes. Split out only to keep both files inside the repo's
171373
- * 300-LOC budget. Classic `@Input`s so it also binds under the JIT test runner.
171374
- */
171375
- class RibbonGalleryPopupComponent {
171376
- constructor() {
171377
- this.translateService = inject(TranslateService, { optional: true });
171378
- /** The translated gallery name (the panel's accessible name). */
171379
- this.name = '';
171380
- /** The element the panel hangs below. */
171381
- this.anchor = null;
171382
- this.pick = new EventEmitter();
171383
- }
171384
- label(item) {
171385
- return galleryItemLabel(item, (key, params) => this.t(key, params));
171386
- }
171387
- sectionTitle(section) {
171388
- if (!section.titleKey) {
171389
- return section.title ?? null;
171390
- }
171391
- const out = this.t(section.titleKey);
171392
- return out && out !== section.titleKey ? out : (section.title ?? section.titleKey);
171393
- }
171394
- t(key, params) {
171395
- return this.translateService ? this.translateService.instant(key, params) : key;
171396
- }
171397
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RibbonGalleryPopupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
171398
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RibbonGalleryPopupComponent, isStandalone: true, selector: "pptx-ribbon-gallery-popup", inputs: { descriptor: "descriptor", name: "name", anchor: "anchor" }, outputs: { pick: "pick" }, ngImport: i0, template: `
171399
- <div
171400
- class="pptx-rb-gallery-popup"
171401
- role="dialog"
171402
- [attr.aria-label]="name"
171403
- [attr.data-ribbon-gallery-popup]="descriptor.id"
171404
- [pptxAnchoredPopup]="anchor"
171405
- >
171406
- @for (section of descriptor.sections; track section.id) {
171407
- @if (sectionTitle(section); as heading) {
171408
- <div class="pptx-rb-gallery-heading">{{ heading }}</div>
171409
- }
171410
- <div
171411
- class="grid gap-1"
171412
- [style.grid-template-columns]="'repeat(' + section.columns + ', max-content)'"
171413
- >
171414
- @for (item of section.items; track item.id) {
171415
- <button
171416
- type="button"
171417
- class="pptx-rb-gallery-tile"
171418
- [class.pptx-rb-gallery-tile-applied]="item.applied"
171419
- [attr.data-gallery-item]="item.id"
171420
- [attr.aria-pressed]="item.applied ? 'true' : 'false'"
171421
- [attr.aria-label]="label(item)"
171422
- [title]="label(item)"
171423
- [innerHTML]="item.previewSvg | pptxGallerySvg"
171424
- (mousedown)="$event.preventDefault()"
171425
- (click)="pick.emit(item)"
171426
- ></button>
171427
- }
171428
- </div>
171429
- }
171430
- </div>
171431
- `, isInline: true, dependencies: [{ kind: "directive", type: AnchoredPopupDirective, selector: "[pptxAnchoredPopup]", inputs: ["pptxAnchoredPopup", "pptxAnchoredPopupAlignRight"] }, { kind: "pipe", type: RibbonGallerySvgPipe, name: "pptxGallerySvg" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
171432
- }
171433
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RibbonGalleryPopupComponent, decorators: [{
171434
- type: Component,
171435
- args: [{
171436
- selector: 'pptx-ribbon-gallery-popup',
171437
- standalone: true,
171438
- changeDetection: ChangeDetectionStrategy.OnPush,
171439
- imports: [AnchoredPopupDirective, RibbonGallerySvgPipe],
171440
- template: `
171441
- <div
171442
- class="pptx-rb-gallery-popup"
171443
- role="dialog"
171444
- [attr.aria-label]="name"
171445
- [attr.data-ribbon-gallery-popup]="descriptor.id"
171446
- [pptxAnchoredPopup]="anchor"
171447
- >
171448
- @for (section of descriptor.sections; track section.id) {
171449
- @if (sectionTitle(section); as heading) {
171450
- <div class="pptx-rb-gallery-heading">{{ heading }}</div>
171451
- }
171452
- <div
171453
- class="grid gap-1"
171454
- [style.grid-template-columns]="'repeat(' + section.columns + ', max-content)'"
171455
- >
171456
- @for (item of section.items; track item.id) {
171457
- <button
171458
- type="button"
171459
- class="pptx-rb-gallery-tile"
171460
- [class.pptx-rb-gallery-tile-applied]="item.applied"
171461
- [attr.data-gallery-item]="item.id"
171462
- [attr.aria-pressed]="item.applied ? 'true' : 'false'"
171463
- [attr.aria-label]="label(item)"
171464
- [title]="label(item)"
171465
- [innerHTML]="item.previewSvg | pptxGallerySvg"
171466
- (mousedown)="$event.preventDefault()"
171467
- (click)="pick.emit(item)"
171468
- ></button>
171469
- }
171470
- </div>
171471
- }
171472
- </div>
171473
- `,
171474
- }]
171475
- }], propDecorators: { descriptor: [{
171476
- type: Input,
171477
- args: [{ required: true }]
171478
- }], name: [{
171479
- type: Input
171480
- }], anchor: [{
171481
- type: Input
171482
- }], pick: [{
171483
- type: Output
171484
- }] } });
171485
-
171486
172029
  /**
171487
172030
  * ribbon-gallery.component.ts: `<pptx-ribbon-gallery>`, the Angular view of a
171488
172031
  * `pptx-viewer-shared` ribbon style gallery (Shape Styles, Shape Effects,
@@ -171494,8 +172037,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
171494
172037
  * the descriptor onto markup and hands the result to
171495
172038
  * {@link dispatchGalleryResult}. Two modes (from the shared placement):
171496
172039
  * `dropdown` (one trigger button) and `inline` (a strip of the first tiles
171497
- * plus a "more" button). Both open the same popup, pinned with the ribbon's
171498
- * `[pptxAnchoredPopup]`, closed by a pick, an outside pointerdown or Escape.
172040
+ * plus a "more" button). The shared control owns positioning, keyboard focus,
172041
+ * outside-pointer dismissal and listener cleanup.
171499
172042
  *
171500
172043
  * DOM contract (identical in all five bindings; see `gallery-view.ts`): the
171501
172044
  * root wrapper carries `data-ribbon-control` when `control` is set, the trigger /
@@ -171512,6 +172055,26 @@ const DEFAULT_INPUTS = {
171512
172055
  chevronOnly: false,
171513
172056
  };
171514
172057
  class RibbonGalleryComponent {
172058
+ constructor() {
172059
+ this.editor = inject(EditorStateService);
172060
+ this.loader = inject(LoadContentService, { optional: true });
172061
+ this.themes = inject(ViewerThemeGalleryService, { optional: true });
172062
+ this.translateService = inject(TranslateService, { optional: true });
172063
+ this.hostEl = inject((ElementRef)).nativeElement;
172064
+ /**
172065
+ * Inputs are classic `@Input` accessors backed by ONE signal (not `input()`),
172066
+ * so the gallery also binds when a parent is JIT-compiled (this package's
172067
+ * TestBed suite has no signal-input transform) while every computed below
172068
+ * still tracks them.
172069
+ */
172070
+ this.inputs = signal(DEFAULT_INPUTS, /* @ts-ignore */
172071
+ ...(ngDevMode ? [{ debugName: "inputs" }] : /* istanbul ignore next */ []));
172072
+ this.descriptor = computed(() => buildRibbonGallery(this.gallery, galleryContextFor(this.element, this.loader)), /* @ts-ignore */
172073
+ ...(ngDevMode ? [{ debugName: "descriptor" }] : /* istanbul ignore next */ []));
172074
+ this.isDisabled = computed(() => !this.canEdit || this.descriptor().disabled || !galleryHasItems(this.descriptor()), /* @ts-ignore */
172075
+ ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
172076
+ this.translate = (key, params) => this.translateService ? this.translateService.instant(key, params) : key;
172077
+ }
171515
172078
  get gallery() {
171516
172079
  return this.inputs().gallery;
171517
172080
  }
@@ -171556,76 +172119,18 @@ class RibbonGalleryComponent {
171556
172119
  set chevronOnly(chevronOnly) {
171557
172120
  this.inputs.update((s) => ({ ...s, chevronOnly }));
171558
172121
  }
171559
- label(item) {
171560
- return galleryItemLabel(item, this.t);
171561
- }
171562
- constructor() {
171563
- this.editor = inject(EditorStateService);
171564
- this.loader = inject(LoadContentService, { optional: true });
171565
- this.themes = inject(ViewerThemeGalleryService, { optional: true });
171566
- this.translateService = inject(TranslateService, { optional: true });
171567
- this.hostEl = inject((ElementRef)).nativeElement;
171568
- /**
171569
- * Inputs are classic `@Input` accessors backed by ONE signal (not `input()`),
171570
- * so the gallery also binds when a parent is JIT-compiled (this package's
171571
- * TestBed suite has no signal-input transform) while every computed below
171572
- * still tracks them.
171573
- */
171574
- this.inputs = signal(DEFAULT_INPUTS, /* @ts-ignore */
171575
- ...(ngDevMode ? [{ debugName: "inputs" }] : /* istanbul ignore next */ []));
171576
- this.openState = signal(false, /* @ts-ignore */
171577
- ...(ngDevMode ? [{ debugName: "openState" }] : /* istanbul ignore next */ []));
171578
- /** Whether the popup is dropped down (read-only; see {@link setOpen}). */
171579
- this.open = this.openState.asReadonly();
171580
- this.descriptor = computed(() => buildRibbonGallery(this.gallery, galleryContextFor(this.element, this.loader)), /* @ts-ignore */
171581
- ...(ngDevMode ? [{ debugName: "descriptor" }] : /* istanbul ignore next */ []));
171582
- this.stripItems = computed(() => inlineGalleryItems(this.descriptor()), /* @ts-ignore */
171583
- ...(ngDevMode ? [{ debugName: "stripItems" }] : /* istanbul ignore next */ []));
171584
- this.isDisabled = computed(() => !this.canEdit || this.descriptor().disabled || !galleryHasItems(this.descriptor()), /* @ts-ignore */
171585
- ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
171586
- this.title = computed(() => this.translated(this.descriptor().labelKey, this.descriptor().label), /* @ts-ignore */
171587
- ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
171588
- this.t = (key, params) => this.translateService ? this.translateService.instant(key, params) : key;
171589
- this.onDocumentPointerDown = (event) => {
171590
- if (!this.hostEl.contains(event.target)) {
171591
- this.setOpen(false);
171592
- }
171593
- };
171594
- this.onDocumentKeyDown = (event) => {
171595
- if (event.key === 'Escape') {
171596
- this.setOpen(false);
171597
- }
171598
- };
171599
- inject(DestroyRef, { optional: true })?.onDestroy(() => this.setOpen(false));
171600
- }
171601
- toggle() {
171602
- this.setOpen(!this.open() && !this.isDisabled());
171603
- }
171604
- /**
171605
- * Open or close the popup. While open, a pointerdown outside this gallery
171606
- * or Escape closes it (listeners are attached only while open, rather than
171607
- * through `host` metadata, which some Angular linkers drop).
171608
- */
171609
- setOpen(next) {
171610
- if (next === this.openState()) {
171611
- return;
171612
- }
171613
- this.openState.set(next);
171614
- if (typeof document === 'undefined') {
171615
- return;
171616
- }
171617
- if (next) {
171618
- document.addEventListener('pointerdown', this.onDocumentPointerDown, true);
171619
- document.addEventListener('keydown', this.onDocumentKeyDown, true);
171620
- }
171621
- else {
171622
- document.removeEventListener('pointerdown', this.onDocumentPointerDown, true);
171623
- document.removeEventListener('keydown', this.onDocumentKeyDown, true);
172122
+ pickId(event) {
172123
+ const id = event.detail.itemId;
172124
+ const item = this.descriptor()
172125
+ .sections.flatMap((section) => section.items)
172126
+ .find((entry) => entry.id === id);
172127
+ if (item) {
172128
+ this.pick(item);
171624
172129
  }
171625
172130
  }
171626
172131
  /** Apply `item` to the selection (or theme) and close the popup. */
171627
172132
  pick(item) {
171628
- this.setOpen(false);
172133
+ this.hostEl.querySelector('pptx-ui-ribbon-gallery')?.close();
171629
172134
  if (this.isDisabled()) {
171630
172135
  return;
171631
172136
  }
@@ -171636,23 +172141,36 @@ class RibbonGalleryComponent {
171636
172141
  themes: this.themes,
171637
172142
  });
171638
172143
  }
171639
- translated(key, fallback) {
171640
- const out = this.t(key);
171641
- return out && out !== key ? out : fallback;
171642
- }
171643
172144
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RibbonGalleryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
171644
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RibbonGalleryComponent, isStandalone: true, selector: "pptx-ribbon-gallery", inputs: { gallery: "gallery", mode: "mode", control: "control", element: "element", slideIndex: "slideIndex", canEdit: "canEdit", chevronOnly: "chevronOnly" }, host: { classAttribute: "contents" }, ngImport: i0, template: "<div\n\t#root\n\tclass=\"relative inline-flex shrink-0 items-center\"\n\t[attr.data-ribbon-control]=\"control || null\"\n>\n\t@if (mode === 'inline') {\n\t\t<div class=\"pptx-rb-gallery-strip\">\n\t\t\t@for (item of stripItems(); track item.id) {\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"pptx-rb-gallery-tile pptx-rb-gallery-tile-strip\"\n\t\t\t\t\t[class.pptx-rb-gallery-tile-applied]=\"item.applied\"\n\t\t\t\t\t[disabled]=\"isDisabled()\"\n\t\t\t\t\t[attr.data-gallery-item]=\"item.id\"\n\t\t\t\t\t[attr.aria-pressed]=\"item.applied ? 'true' : 'false'\"\n\t\t\t\t\t[attr.aria-label]=\"label(item)\"\n\t\t\t\t\t[title]=\"label(item)\"\n\t\t\t\t\t[innerHTML]=\"item.previewSvg | pptxGallerySvg\"\n\t\t\t\t\t(click)=\"pick(item)\"\n\t\t\t\t></button>\n\t\t\t}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"pptx-rb-gallery-more\"\n\t\t\t\t[disabled]=\"isDisabled()\"\n\t\t\t\t[attr.data-ribbon-gallery]=\"gallery\"\n\t\t\t\t[attr.aria-expanded]=\"open()\"\n\t\t\t\t[attr.aria-label]=\"'pptx.gallery.more' | translate: { name: title() }\"\n\t\t\t\t[title]=\"'pptx.gallery.more' | translate: { name: title() }\"\n\t\t\t\t(click)=\"toggle()\"\n\t\t\t>\n\t\t\t\t<svg lucideChevronDown class=\"h-3 w-3\"></svg>\n\t\t\t</button>\n\t\t</div>\n\t} @else {\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\t[attr.data-pptx-chrome]=\"chevronOnly ? 'gallery-caret' : null\"\n\t\t\t[class]=\"chevronOnly ? 'pptx-rb-gb px-1' : 'pptx-rb-pill'\"\n\t\t\t[disabled]=\"isDisabled()\"\n\t\t\t[attr.data-ribbon-gallery]=\"gallery\"\n\t\t\t[attr.aria-expanded]=\"open()\"\n\t\t\t[attr.aria-label]=\"title()\"\n\t\t\t[title]=\"title()\"\n\t\t\t(mousedown)=\"$event.preventDefault()\"\n\t\t\t(click)=\"toggle()\"\n\t\t>\n\t\t\t@if (!chevronOnly) {\n\t\t\t\t@if (gallery === 'shapeStyles' || gallery === 'shapeEffects') {\n\t\t\t\t\t<svg\n\t\t\t\t\t\t[pptxRibbonIcon]=\"\n\t\t\t\t\t\t\tgallery === 'shapeStyles' ? 'home.drawing.quickStyles' : 'home.drawing.shapeEffects'\n\t\t\t\t\t\t\"\n\t\t\t\t\t></svg>\n\t\t\t\t}\n\t\t\t\t<span class=\"whitespace-nowrap\">{{ title() }}</span>\n\t\t\t}\n\t\t\t<svg lucideChevronDown class=\"h-3 w-3\"></svg>\n\t\t</button>\n\t}\n\t@if (open()) {\n\t\t<pptx-ribbon-gallery-popup\n\t\t\t[descriptor]=\"descriptor()\"\n\t\t\t[name]=\"title()\"\n\t\t\t[anchor]=\"root\"\n\t\t\t(pick)=\"pick($event)\"\n\t\t/>\n\t}\n</div>\n", dependencies: [{ kind: "directive", type: RibbonIconDirective, selector: "svg[pptxRibbonIcon]", inputs: ["pptxRibbonIcon"] }, { kind: "component", type: LucideChevronDown, selector: "svg[lucideChevronDown]" }, { kind: "component", type: RibbonGalleryPopupComponent, selector: "pptx-ribbon-gallery-popup", inputs: ["descriptor", "name", "anchor"], outputs: ["pick"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }, { kind: "pipe", type: RibbonGallerySvgPipe, name: "pptxGallerySvg" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
172145
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: RibbonGalleryComponent, isStandalone: true, selector: "pptx-ribbon-gallery", inputs: { gallery: "gallery", mode: "mode", control: "control", element: "element", slideIndex: "slideIndex", canEdit: "canEdit", chevronOnly: "chevronOnly" }, host: { classAttribute: "contents" }, ngImport: i0, template: `<pptx-ui-ribbon-gallery
172146
+ [attr.data-ribbon-control]="control"
172147
+ [attr.mode]="mode"
172148
+ [attr.chevron-only]="chevronOnly ? '' : null"
172149
+ [descriptor]="descriptor()"
172150
+ [translateLabel]="translate"
172151
+ [disabled]="isDisabled()"
172152
+ (gallery-pick)="pickId($event)"
172153
+ />`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
171645
172154
  }
171646
172155
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RibbonGalleryComponent, decorators: [{
171647
172156
  type: Component,
171648
- args: [{ selector: 'pptx-ribbon-gallery', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'contents' }, imports: [
171649
- RibbonIconDirective,
171650
- TranslatePipe,
171651
- LucideChevronDown,
171652
- RibbonGalleryPopupComponent,
171653
- RibbonGallerySvgPipe,
171654
- ], template: "<div\n\t#root\n\tclass=\"relative inline-flex shrink-0 items-center\"\n\t[attr.data-ribbon-control]=\"control || null\"\n>\n\t@if (mode === 'inline') {\n\t\t<div class=\"pptx-rb-gallery-strip\">\n\t\t\t@for (item of stripItems(); track item.id) {\n\t\t\t\t<button\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t\tclass=\"pptx-rb-gallery-tile pptx-rb-gallery-tile-strip\"\n\t\t\t\t\t[class.pptx-rb-gallery-tile-applied]=\"item.applied\"\n\t\t\t\t\t[disabled]=\"isDisabled()\"\n\t\t\t\t\t[attr.data-gallery-item]=\"item.id\"\n\t\t\t\t\t[attr.aria-pressed]=\"item.applied ? 'true' : 'false'\"\n\t\t\t\t\t[attr.aria-label]=\"label(item)\"\n\t\t\t\t\t[title]=\"label(item)\"\n\t\t\t\t\t[innerHTML]=\"item.previewSvg | pptxGallerySvg\"\n\t\t\t\t\t(click)=\"pick(item)\"\n\t\t\t\t></button>\n\t\t\t}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"pptx-rb-gallery-more\"\n\t\t\t\t[disabled]=\"isDisabled()\"\n\t\t\t\t[attr.data-ribbon-gallery]=\"gallery\"\n\t\t\t\t[attr.aria-expanded]=\"open()\"\n\t\t\t\t[attr.aria-label]=\"'pptx.gallery.more' | translate: { name: title() }\"\n\t\t\t\t[title]=\"'pptx.gallery.more' | translate: { name: title() }\"\n\t\t\t\t(click)=\"toggle()\"\n\t\t\t>\n\t\t\t\t<svg lucideChevronDown class=\"h-3 w-3\"></svg>\n\t\t\t</button>\n\t\t</div>\n\t} @else {\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\t[attr.data-pptx-chrome]=\"chevronOnly ? 'gallery-caret' : null\"\n\t\t\t[class]=\"chevronOnly ? 'pptx-rb-gb px-1' : 'pptx-rb-pill'\"\n\t\t\t[disabled]=\"isDisabled()\"\n\t\t\t[attr.data-ribbon-gallery]=\"gallery\"\n\t\t\t[attr.aria-expanded]=\"open()\"\n\t\t\t[attr.aria-label]=\"title()\"\n\t\t\t[title]=\"title()\"\n\t\t\t(mousedown)=\"$event.preventDefault()\"\n\t\t\t(click)=\"toggle()\"\n\t\t>\n\t\t\t@if (!chevronOnly) {\n\t\t\t\t@if (gallery === 'shapeStyles' || gallery === 'shapeEffects') {\n\t\t\t\t\t<svg\n\t\t\t\t\t\t[pptxRibbonIcon]=\"\n\t\t\t\t\t\t\tgallery === 'shapeStyles' ? 'home.drawing.quickStyles' : 'home.drawing.shapeEffects'\n\t\t\t\t\t\t\"\n\t\t\t\t\t></svg>\n\t\t\t\t}\n\t\t\t\t<span class=\"whitespace-nowrap\">{{ title() }}</span>\n\t\t\t}\n\t\t\t<svg lucideChevronDown class=\"h-3 w-3\"></svg>\n\t\t</button>\n\t}\n\t@if (open()) {\n\t\t<pptx-ribbon-gallery-popup\n\t\t\t[descriptor]=\"descriptor()\"\n\t\t\t[name]=\"title()\"\n\t\t\t[anchor]=\"root\"\n\t\t\t(pick)=\"pick($event)\"\n\t\t/>\n\t}\n</div>\n" }]
171655
- }], ctorParameters: () => [], propDecorators: { gallery: [{
172157
+ args: [{
172158
+ selector: 'pptx-ribbon-gallery',
172159
+ standalone: true,
172160
+ changeDetection: ChangeDetectionStrategy.OnPush,
172161
+ host: { class: 'contents' },
172162
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
172163
+ template: `<pptx-ui-ribbon-gallery
172164
+ [attr.data-ribbon-control]="control"
172165
+ [attr.mode]="mode"
172166
+ [attr.chevron-only]="chevronOnly ? '' : null"
172167
+ [descriptor]="descriptor()"
172168
+ [translateLabel]="translate"
172169
+ [disabled]="isDisabled()"
172170
+ (gallery-pick)="pickId($event)"
172171
+ />`,
172172
+ }]
172173
+ }], propDecorators: { gallery: [{
171656
172174
  type: Input,
171657
172175
  args: [{ required: true }]
171658
172176
  }], mode: [{
@@ -172824,27 +173342,22 @@ class RibbonContextualSectionComponent {
172824
173342
  }
172825
173343
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RibbonContextualSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
172826
173344
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RibbonContextualSectionComponent, isStandalone: true, selector: "pptx-ribbon-contextual-section", inputs: { tab: { classPropertyName: "tab", publicName: "tab", isSignal: true, isRequired: true, transformFunction: null }, selectedElement: { classPropertyName: "selectedElement", publicName: "selectedElement", isSignal: true, isRequired: false, transformFunction: null }, slideIndex: { classPropertyName: "slideIndex", publicName: "slideIndex", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "contents" }, ngImport: i0, template: `
172827
- @for (group of groups(); track group.group; let last = $last) {
172828
- <div class="flex flex-col items-center gap-0.5" [attr.data-ribbon-group]="group.group">
172829
- <div class="flex items-center gap-1">
172830
- @for (placement of group.galleries; track placement.control) {
172831
- <pptx-ribbon-gallery
172832
- [gallery]="placement.gallery"
172833
- [mode]="placement.mode"
172834
- [control]="placement.control"
172835
- [element]="selectedElement()"
172836
- [slideIndex]="slideIndex()"
172837
- [canEdit]="canEdit()"
172838
- />
172839
- }
172840
- </div>
172841
- <span class="text-[9px] leading-none text-muted-foreground">
172842
- {{ group.labelKey | translate }}
172843
- </span>
172844
- </div>
172845
- @if (!last) {
172846
- <span class="pptx-rb-sep"></span>
172847
- }
173345
+ @for (group of groups(); track group.group) {
173346
+ <pptx-ui-ribbon-group
173347
+ [attr.label]="group.labelKey | translate"
173348
+ [attr.data-ribbon-group]="group.group"
173349
+ >
173350
+ @for (placement of group.galleries; track placement.control) {
173351
+ <pptx-ribbon-gallery
173352
+ [gallery]="placement.gallery"
173353
+ [mode]="placement.mode"
173354
+ [control]="placement.control"
173355
+ [element]="selectedElement()"
173356
+ [slideIndex]="slideIndex()"
173357
+ [canEdit]="canEdit()"
173358
+ />
173359
+ }
173360
+ </pptx-ui-ribbon-group>
172848
173361
  }
172849
173362
  `, isInline: true, dependencies: [{ kind: "component", type: RibbonGalleryComponent, selector: "pptx-ribbon-gallery", inputs: ["gallery", "mode", "control", "element", "slideIndex", "canEdit", "chevronOnly"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
172850
173363
  }
@@ -172856,28 +173369,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
172856
173369
  changeDetection: ChangeDetectionStrategy.OnPush,
172857
173370
  host: { class: 'contents' },
172858
173371
  imports: [TranslatePipe, RibbonGalleryComponent],
173372
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
172859
173373
  template: `
172860
- @for (group of groups(); track group.group; let last = $last) {
172861
- <div class="flex flex-col items-center gap-0.5" [attr.data-ribbon-group]="group.group">
172862
- <div class="flex items-center gap-1">
172863
- @for (placement of group.galleries; track placement.control) {
172864
- <pptx-ribbon-gallery
172865
- [gallery]="placement.gallery"
172866
- [mode]="placement.mode"
172867
- [control]="placement.control"
172868
- [element]="selectedElement()"
172869
- [slideIndex]="slideIndex()"
172870
- [canEdit]="canEdit()"
172871
- />
172872
- }
172873
- </div>
172874
- <span class="text-[9px] leading-none text-muted-foreground">
172875
- {{ group.labelKey | translate }}
172876
- </span>
172877
- </div>
172878
- @if (!last) {
172879
- <span class="pptx-rb-sep"></span>
172880
- }
173374
+ @for (group of groups(); track group.group) {
173375
+ <pptx-ui-ribbon-group
173376
+ [attr.label]="group.labelKey | translate"
173377
+ [attr.data-ribbon-group]="group.group"
173378
+ >
173379
+ @for (placement of group.galleries; track placement.control) {
173380
+ <pptx-ribbon-gallery
173381
+ [gallery]="placement.gallery"
173382
+ [mode]="placement.mode"
173383
+ [control]="placement.control"
173384
+ [element]="selectedElement()"
173385
+ [slideIndex]="slideIndex()"
173386
+ [canEdit]="canEdit()"
173387
+ />
173388
+ }
173389
+ </pptx-ui-ribbon-group>
172881
173390
  }
172882
173391
  `,
172883
173392
  }]
@@ -172907,23 +173416,12 @@ function isContextualRibbonTab(tab) {
172907
173416
  return RIBBON_CONTEXTUAL_TABS.some((t) => t.id === tab);
172908
173417
  }
172909
173418
 
172910
- /**
172911
- * ribbon-design-section.component.ts: the Design ribbon tab (Browse Themes / Edit
172912
- * Theme, the Variants Colors / Fonts galleries, Slide Size, Format Background).
172913
- * Split out of {@link RibbonComponent}.
172914
- *
172915
- * Edit Theme and Slide Size used to emit `info`, which opens the Document
172916
- * Properties dialog: two controls with the right label pointing at an unrelated
172917
- * dialog. Both viewer surfaces they name already exist, so each now has its own
172918
- * output and the host routes it to the real thing: Edit Theme opens the theme
172919
- * gallery straight in its customise (theme-editor) mode, Slide Size opens the
172920
- * inspector's deck panel, whose SLIDE SIZE card is the real control.
172921
- */
172922
173419
  class RibbonDesignSectionComponent {
172923
173420
  constructor() {
173421
+ this.groups = DESIGN_RIBBON_GROUPS;
173422
+ this.commands = DESIGN_RIBBON_COMMANDS;
172924
173423
  this.themeGalleryOpen = input(false, /* @ts-ignore */
172925
173424
  ...(ngDevMode ? [{ debugName: "themeGalleryOpen" }] : /* istanbul ignore next */ []));
172926
- /** Selection + editability for the Variants galleries. */
172927
173425
  this.selectedElement = input(null, /* @ts-ignore */
172928
173426
  ...(ngDevMode ? [{ debugName: "selectedElement" }] : /* istanbul ignore next */ []));
172929
173427
  this.slideIndex = input(0, /* @ts-ignore */
@@ -172931,82 +173429,74 @@ class RibbonDesignSectionComponent {
172931
173429
  this.canEdit = input(false, /* @ts-ignore */
172932
173430
  ...(ngDevMode ? [{ debugName: "canEdit" }] : /* istanbul ignore next */ []));
172933
173431
  this.toggleThemeGallery = output();
172934
- /** "Edit Theme": open the theme gallery already in its customise mode. */
172935
173432
  this.editTheme = output();
172936
- /** "Slide Size": surface the inspector deck panel that owns the size card. */
172937
173433
  this.openSlideSize = output();
172938
173434
  this.toggleInspector = output();
172939
173435
  }
173436
+ view(id) {
173437
+ return designCommandState(id, {
173438
+ editable: this.canEdit(),
173439
+ galleryOpen: this.themeGalleryOpen(),
173440
+ });
173441
+ }
173442
+ request(id) {
173443
+ if (this.view(id).disabled) {
173444
+ return;
173445
+ }
173446
+ if (id === 'design.themes.browseThemes') {
173447
+ this.toggleThemeGallery.emit();
173448
+ }
173449
+ else if (id === 'design.themes.editTheme') {
173450
+ this.editTheme.emit();
173451
+ }
173452
+ else if (id === 'design.customize.slideSize') {
173453
+ this.openSlideSize.emit();
173454
+ }
173455
+ else if (id === 'design.customize.formatBackground') {
173456
+ this.toggleInspector.emit();
173457
+ }
173458
+ }
172940
173459
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RibbonDesignSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
172941
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.6", type: RibbonDesignSectionComponent, isStandalone: true, selector: "pptx-ribbon-design-section", inputs: { themeGalleryOpen: { classPropertyName: "themeGalleryOpen", publicName: "themeGalleryOpen", isSignal: true, isRequired: false, transformFunction: null }, selectedElement: { classPropertyName: "selectedElement", publicName: "selectedElement", isSignal: true, isRequired: false, transformFunction: null }, slideIndex: { classPropertyName: "slideIndex", publicName: "slideIndex", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { toggleThemeGallery: "toggleThemeGallery", editTheme: "editTheme", openSlideSize: "openSlideSize", toggleInspector: "toggleInspector" }, host: { classAttribute: "contents" }, ngImport: i0, template: `
172942
- <span class="contents" data-ribbon-group="design.themes">
172943
- <!-- Themes -->
172944
- <button
172945
- type="button"
172946
- class="pptx-rb-pill"
172947
- data-ribbon-control="design.themes.browseThemes"
172948
- [ngClass]="themeGalleryOpen() ? 'bg-primary text-primary-foreground' : ''"
172949
- [title]="'pptx.ribbon.browseThemesTitle' | translate"
172950
- (click)="toggleThemeGallery.emit()"
172951
- >
172952
- {{ 'pptx.ribbon.browseThemes' | translate }}
172953
- </button>
172954
- <button
172955
- type="button"
172956
- class="pptx-rb-pill"
172957
- data-ribbon-control="design.themes.editTheme"
172958
- [title]="'pptx.ribbon.editThemeTitle' | translate"
172959
- (click)="editTheme.emit()"
172960
- >
172961
- {{ 'pptx.ribbon.editTheme' | translate }}
172962
- </button>
172963
- </span>
172964
- <span class="pptx-rb-sep"></span>
172965
- <!-- Variants: the shared theme Colors / Fonts galleries (FIXED_TAB_GALLERIES). -->
172966
- <div class="flex flex-col items-center gap-0.5" data-ribbon-group="design.variants">
172967
- <div class="flex items-center gap-1">
172968
- <pptx-ribbon-gallery
172969
- gallery="themeColors"
172970
- control="design.variants.colors"
172971
- [element]="selectedElement()"
172972
- [slideIndex]="slideIndex()"
172973
- [canEdit]="canEdit()"
172974
- />
172975
- <pptx-ribbon-gallery
172976
- gallery="themeFonts"
172977
- control="design.variants.fonts"
172978
- [element]="selectedElement()"
172979
- [slideIndex]="slideIndex()"
172980
- [canEdit]="canEdit()"
172981
- />
172982
- </div>
172983
- <span class="text-[9px] leading-none text-muted-foreground">
172984
- {{ 'pptx.ribbon.groupVariants' | translate }}
172985
- </span>
172986
- </div>
172987
- <span class="pptx-rb-sep"></span>
172988
- <span class="contents" data-ribbon-group="design.customize">
172989
- <!-- Customize -->
172990
- <button
172991
- type="button"
172992
- class="pptx-rb-pill"
172993
- data-ribbon-control="design.customize.slideSize"
172994
- [title]="'pptx.ribbon.slideSizeTitle' | translate"
172995
- (click)="openSlideSize.emit()"
172996
- >
172997
- {{ 'pptx.ribbon.slideSize' | translate }}
172998
- </button>
172999
- <button
173000
- type="button"
173001
- class="pptx-rb-pill"
173002
- data-ribbon-control="design.customize.formatBackground"
173003
- [title]="'pptx.ribbon.formatBackgroundTitle' | translate"
173004
- (click)="toggleInspector.emit()"
173460
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RibbonDesignSectionComponent, isStandalone: true, selector: "pptx-ribbon-design-section", inputs: { themeGalleryOpen: { classPropertyName: "themeGalleryOpen", publicName: "themeGalleryOpen", isSignal: true, isRequired: false, transformFunction: null }, selectedElement: { classPropertyName: "selectedElement", publicName: "selectedElement", isSignal: true, isRequired: false, transformFunction: null }, slideIndex: { classPropertyName: "slideIndex", publicName: "slideIndex", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { toggleThemeGallery: "toggleThemeGallery", editTheme: "editTheme", openSlideSize: "openSlideSize", toggleInspector: "toggleInspector" }, host: { classAttribute: "contents" }, ngImport: i0, template: `
173461
+ @for (group of groups; track group.id) {
173462
+ <pptx-ui-ribbon-group
173463
+ [attr.label]="group.labelKey | translate"
173464
+ [attr.data-ribbon-group]="group.id"
173005
173465
  >
173006
- {{ 'pptx.ribbon.formatBackground' | translate }}
173007
- </button>
173008
- </span>
173009
- `, isInline: true, dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: RibbonGalleryComponent, selector: "pptx-ribbon-gallery", inputs: ["gallery", "mode", "control", "element", "slideIndex", "canEdit", "chevronOnly"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
173466
+ @for (command of commands; track command.id) {
173467
+ @if (command.id.startsWith(group.id + '.')) {
173468
+ <pptx-ui-ribbon-command
173469
+ [attr.data-ribbon-control]="command.id"
173470
+ [attr.label]="command.labelKey | translate"
173471
+ [attr.title]="command.titleKey | translate"
173472
+ [attr.icon]="command.icon"
173473
+ compact
173474
+ [attr.disabled]="view(command.id).disabled ? '' : null"
173475
+ [attr.active]="view(command.id).active ? '' : null"
173476
+ [attr.expanded]="view(command.id).expanded"
173477
+ (command-request)="request(command.id)"
173478
+ />
173479
+ }
173480
+ }
173481
+ @if (group.id === 'design.variants') {
173482
+ <pptx-ribbon-gallery
173483
+ gallery="themeColors"
173484
+ control="design.variants.colors"
173485
+ [element]="selectedElement()"
173486
+ [slideIndex]="slideIndex()"
173487
+ [canEdit]="canEdit()"
173488
+ />
173489
+ <pptx-ribbon-gallery
173490
+ gallery="themeFonts"
173491
+ control="design.variants.fonts"
173492
+ [element]="selectedElement()"
173493
+ [slideIndex]="slideIndex()"
173494
+ [canEdit]="canEdit()"
173495
+ />
173496
+ }
173497
+ </pptx-ui-ribbon-group>
173498
+ }
173499
+ `, isInline: true, dependencies: [{ kind: "component", type: RibbonGalleryComponent, selector: "pptx-ribbon-gallery", inputs: ["gallery", "mode", "control", "element", "slideIndex", "canEdit", "chevronOnly"] }, { kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
173010
173500
  }
173011
173501
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RibbonDesignSectionComponent, decorators: [{
173012
173502
  type: Component,
@@ -173015,75 +173505,47 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
173015
173505
  standalone: true,
173016
173506
  changeDetection: ChangeDetectionStrategy.OnPush,
173017
173507
  host: { class: 'contents' },
173018
- imports: [NgClass, TranslatePipe, RibbonGalleryComponent],
173508
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
173509
+ imports: [TranslatePipe, RibbonGalleryComponent],
173019
173510
  template: `
173020
- <span class="contents" data-ribbon-group="design.themes">
173021
- <!-- Themes -->
173022
- <button
173023
- type="button"
173024
- class="pptx-rb-pill"
173025
- data-ribbon-control="design.themes.browseThemes"
173026
- [ngClass]="themeGalleryOpen() ? 'bg-primary text-primary-foreground' : ''"
173027
- [title]="'pptx.ribbon.browseThemesTitle' | translate"
173028
- (click)="toggleThemeGallery.emit()"
173029
- >
173030
- {{ 'pptx.ribbon.browseThemes' | translate }}
173031
- </button>
173032
- <button
173033
- type="button"
173034
- class="pptx-rb-pill"
173035
- data-ribbon-control="design.themes.editTheme"
173036
- [title]="'pptx.ribbon.editThemeTitle' | translate"
173037
- (click)="editTheme.emit()"
173038
- >
173039
- {{ 'pptx.ribbon.editTheme' | translate }}
173040
- </button>
173041
- </span>
173042
- <span class="pptx-rb-sep"></span>
173043
- <!-- Variants: the shared theme Colors / Fonts galleries (FIXED_TAB_GALLERIES). -->
173044
- <div class="flex flex-col items-center gap-0.5" data-ribbon-group="design.variants">
173045
- <div class="flex items-center gap-1">
173046
- <pptx-ribbon-gallery
173047
- gallery="themeColors"
173048
- control="design.variants.colors"
173049
- [element]="selectedElement()"
173050
- [slideIndex]="slideIndex()"
173051
- [canEdit]="canEdit()"
173052
- />
173053
- <pptx-ribbon-gallery
173054
- gallery="themeFonts"
173055
- control="design.variants.fonts"
173056
- [element]="selectedElement()"
173057
- [slideIndex]="slideIndex()"
173058
- [canEdit]="canEdit()"
173059
- />
173060
- </div>
173061
- <span class="text-[9px] leading-none text-muted-foreground">
173062
- {{ 'pptx.ribbon.groupVariants' | translate }}
173063
- </span>
173064
- </div>
173065
- <span class="pptx-rb-sep"></span>
173066
- <span class="contents" data-ribbon-group="design.customize">
173067
- <!-- Customize -->
173068
- <button
173069
- type="button"
173070
- class="pptx-rb-pill"
173071
- data-ribbon-control="design.customize.slideSize"
173072
- [title]="'pptx.ribbon.slideSizeTitle' | translate"
173073
- (click)="openSlideSize.emit()"
173074
- >
173075
- {{ 'pptx.ribbon.slideSize' | translate }}
173076
- </button>
173077
- <button
173078
- type="button"
173079
- class="pptx-rb-pill"
173080
- data-ribbon-control="design.customize.formatBackground"
173081
- [title]="'pptx.ribbon.formatBackgroundTitle' | translate"
173082
- (click)="toggleInspector.emit()"
173511
+ @for (group of groups; track group.id) {
173512
+ <pptx-ui-ribbon-group
173513
+ [attr.label]="group.labelKey | translate"
173514
+ [attr.data-ribbon-group]="group.id"
173083
173515
  >
173084
- {{ 'pptx.ribbon.formatBackground' | translate }}
173085
- </button>
173086
- </span>
173516
+ @for (command of commands; track command.id) {
173517
+ @if (command.id.startsWith(group.id + '.')) {
173518
+ <pptx-ui-ribbon-command
173519
+ [attr.data-ribbon-control]="command.id"
173520
+ [attr.label]="command.labelKey | translate"
173521
+ [attr.title]="command.titleKey | translate"
173522
+ [attr.icon]="command.icon"
173523
+ compact
173524
+ [attr.disabled]="view(command.id).disabled ? '' : null"
173525
+ [attr.active]="view(command.id).active ? '' : null"
173526
+ [attr.expanded]="view(command.id).expanded"
173527
+ (command-request)="request(command.id)"
173528
+ />
173529
+ }
173530
+ }
173531
+ @if (group.id === 'design.variants') {
173532
+ <pptx-ribbon-gallery
173533
+ gallery="themeColors"
173534
+ control="design.variants.colors"
173535
+ [element]="selectedElement()"
173536
+ [slideIndex]="slideIndex()"
173537
+ [canEdit]="canEdit()"
173538
+ />
173539
+ <pptx-ribbon-gallery
173540
+ gallery="themeFonts"
173541
+ control="design.variants.fonts"
173542
+ [element]="selectedElement()"
173543
+ [slideIndex]="slideIndex()"
173544
+ [canEdit]="canEdit()"
173545
+ />
173546
+ }
173547
+ </pptx-ui-ribbon-group>
173548
+ }
173087
173549
  `,
173088
173550
  }]
173089
173551
  }], propDecorators: { themeGalleryOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "themeGalleryOpen", required: false }] }], selectedElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedElement", required: false }] }], slideIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "slideIndex", required: false }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], toggleThemeGallery: [{ type: i0.Output, args: ["toggleThemeGallery"] }], editTheme: [{ type: i0.Output, args: ["editTheme"] }], openSlideSize: [{ type: i0.Output, args: ["openSlideSize"] }], toggleInspector: [{ type: i0.Output, args: ["toggleInspector"] }] } });
@@ -173452,190 +173914,63 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
173452
173914
  }]
173453
173915
  }], propDecorators: { recordFromBeginning: [{ type: i0.Output, args: ["recordFromBeginning"] }], recordFromCurrent: [{ type: i0.Output, args: ["recordFromCurrent"] }] } });
173454
173916
 
173455
- /**
173456
- * ribbon-review-section.component.ts: the Review ribbon tab (Proofing,
173457
- * Accessibility, Language, Changes, Comments and Protect groups). Split out of
173458
- * {@link RibbonComponent}.
173459
- *
173460
- * Several entries are rendered disabled rather than left out: Thesaurus,
173461
- * Translate, Mark All Read, comment Delete/Previous/Next, and the three
173462
- * Protect commands. None of them has a backend in this viewer yet, but a user
173463
- * looking for "Restrict Permission" should find where it will be instead of
173464
- * concluding the tab is broken, and every other binding lists them.
173465
- */
173466
173917
  class RibbonReviewSectionComponent {
173467
173918
  constructor() {
173468
- this.editor = inject(EditorStateService);
173469
- this.spellCheckEnabled = input(false, /* @ts-ignore */
173470
- ...(ngDevMode ? [{ debugName: "spellCheckEnabled" }] : /* istanbul ignore next */ []));
173471
- this.canEdit = input(false, /* @ts-ignore */
173472
- ...(ngDevMode ? [{ debugName: "canEdit" }] : /* istanbul ignore next */ []));
173919
+ this.translator = inject(TranslateService);
173920
+ this.state = signal({ spellCheck: false, editable: false }, /* @ts-ignore */
173921
+ ...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
173473
173922
  this.comments = output();
173474
173923
  this.spellCheckChange = output();
173475
173924
  this.a11y = output();
173476
173925
  this.openCompare = output();
173477
173926
  this.language = output();
173478
173927
  this.link = output();
173928
+ this.groups = computed(() => buildReviewRibbon((key) => this.translator.instant(key), {
173929
+ editable: this.canEdit,
173930
+ spellCheck: this.spellCheckEnabled,
173931
+ canAccessibility: true,
173932
+ canLanguage: true,
173933
+ canCompare: true,
173934
+ canComments: true,
173935
+ }), /* @ts-ignore */
173936
+ ...(ngDevMode ? [{ debugName: "groups" }] : /* istanbul ignore next */ []));
173479
173937
  }
173480
- hasSel() {
173481
- return this.editor.selectedIds().length > 0;
173938
+ get spellCheckEnabled() {
173939
+ return this.state().spellCheck;
173940
+ }
173941
+ set spellCheckEnabled(value) {
173942
+ this.state.update((state) => ({ ...state, spellCheck: value }));
173943
+ }
173944
+ get canEdit() {
173945
+ return this.state().editable;
173946
+ }
173947
+ set canEdit(value) {
173948
+ this.state.update((state) => ({ ...state, editable: value }));
173949
+ }
173950
+ request(event) {
173951
+ switch (event.detail.id) {
173952
+ case 'review.proofing.spelling':
173953
+ this.spellCheckChange.emit(!this.spellCheckEnabled);
173954
+ break;
173955
+ case 'review.accessibility.check':
173956
+ this.a11y.emit();
173957
+ break;
173958
+ case 'review.language.language':
173959
+ this.language.emit();
173960
+ break;
173961
+ case 'review.compare.compare':
173962
+ if (this.canEdit) {
173963
+ this.openCompare.emit();
173964
+ }
173965
+ break;
173966
+ case 'review.comments.newComment':
173967
+ case 'review.comments.showComments':
173968
+ this.comments.emit();
173969
+ break;
173970
+ }
173482
173971
  }
173483
173972
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RibbonReviewSectionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
173484
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: RibbonReviewSectionComponent, isStandalone: true, selector: "pptx-ribbon-review-section", inputs: { spellCheckEnabled: { classPropertyName: "spellCheckEnabled", publicName: "spellCheckEnabled", isSignal: true, isRequired: false, transformFunction: null }, canEdit: { classPropertyName: "canEdit", publicName: "canEdit", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { comments: "comments", spellCheckChange: "spellCheckChange", a11y: "a11y", openCompare: "openCompare", language: "language", link: "link" }, host: { classAttribute: "contents" }, ngImport: i0, template: `
173485
- <!-- Proofing -->
173486
- <span class="contents" data-ribbon-group="review.proofing">
173487
- <button
173488
- data-ribbon-control="review.proofing.spelling"
173489
- type="button"
173490
- class="pptx-rb-pill"
173491
- [class.is-active]="spellCheckEnabled()"
173492
- [attr.aria-pressed]="spellCheckEnabled()"
173493
- [title]="'pptx.review.toggleSpellCheck' | translate"
173494
- (click)="spellCheckChange.emit(!spellCheckEnabled())"
173495
- >
173496
- {{ 'pptx.review.spelling' | translate }}
173497
- </button>
173498
- <button
173499
- data-ribbon-control="review.proofing.thesaurus"
173500
- type="button"
173501
- class="pptx-rb-pill"
173502
- disabled
173503
- >
173504
- {{ 'pptx.review.thesaurus' | translate }}
173505
- </button>
173506
- </span>
173507
- <span class="pptx-rb-sep"></span>
173508
- <!-- Accessibility -->
173509
- <button
173510
- data-ribbon-group="review.accessibility"
173511
- data-ribbon-control="review.accessibility.check"
173512
- type="button"
173513
- class="pptx-rb-pill"
173514
- [title]="'pptx.review.accessibilityCheckTooltip' | translate"
173515
- (click)="a11y.emit()"
173516
- >
173517
- {{ 'pptx.review.accessibilityCheck' | translate }}
173518
- </button>
173519
- <span class="pptx-rb-sep"></span>
173520
- <!-- Language -->
173521
- <span class="contents" data-ribbon-group="review.language">
173522
- <button
173523
- data-ribbon-control="review.language.translate"
173524
- type="button"
173525
- class="pptx-rb-pill"
173526
- disabled
173527
- >
173528
- {{ 'pptx.review.translate' | translate }}
173529
- </button>
173530
- <button
173531
- type="button"
173532
- class="pptx-rb-pill"
173533
- [title]="'pptx.review.languageTooltip' | translate"
173534
- (click)="language.emit()"
173535
- >
173536
- {{ 'pptx.review.language' | translate }}
173537
- </button>
173538
- </span>
173539
- <span class="pptx-rb-sep"></span>
173540
- <!-- Changes -->
173541
- <span class="contents" data-ribbon-group="review.compare">
173542
- <button
173543
- data-ribbon-control="review.compare.markAllRead"
173544
- type="button"
173545
- class="pptx-rb-pill"
173546
- disabled
173547
- >
173548
- {{ 'pptx.review.markAllRead' | translate }}
173549
- </button>
173550
- <button
173551
- data-ribbon-control="review.compare.compare"
173552
- type="button"
173553
- class="pptx-rb-pill"
173554
- [disabled]="!canEdit()"
173555
- [title]="'pptx.ribbon.compareTitle' | translate"
173556
- (click)="openCompare.emit()"
173557
- >
173558
- {{ 'pptx.ribbon.compare' | translate }}
173559
- </button>
173560
- </span>
173561
- <span class="pptx-rb-sep"></span>
173562
- <!-- Comments -->
173563
- <span class="contents" data-ribbon-group="review.comments">
173564
- <button type="button" class="pptx-rb-pill" (click)="comments.emit()">
173565
- {{ 'pptx.toolbar.comments' | translate }}
173566
- </button>
173567
- <div class="flex flex-col justify-center gap-0.5">
173568
- <button
173569
- data-ribbon-control="review.comments.delete"
173570
- type="button"
173571
- class="pptx-rb-toggle"
173572
- disabled
173573
- >
173574
- {{ 'pptx.common.delete' | translate }}
173575
- </button>
173576
- <button
173577
- data-ribbon-control="review.comments.previous"
173578
- type="button"
173579
- class="pptx-rb-toggle"
173580
- disabled
173581
- >
173582
- {{ 'pptx.common.previous' | translate }}
173583
- </button>
173584
- </div>
173585
- <div class="flex flex-col justify-center gap-0.5">
173586
- <button
173587
- data-ribbon-control="review.comments.next"
173588
- type="button"
173589
- class="pptx-rb-toggle"
173590
- disabled
173591
- >
173592
- {{ 'pptx.common.next' | translate }}
173593
- </button>
173594
- <button
173595
- data-ribbon-control="review.comments.showComments"
173596
- type="button"
173597
- class="pptx-rb-toggle hover:bg-accent"
173598
- (click)="comments.emit()"
173599
- >
173600
- {{ 'pptx.review.showComments' | translate }}
173601
- </button>
173602
- </div>
173603
- </span>
173604
- <span class="pptx-rb-sep"></span>
173605
- <!-- Protect -->
173606
- <span class="contents" data-ribbon-group="review.protect">
173607
- <button
173608
- data-ribbon-control="review.protect.readOnly"
173609
- type="button"
173610
- class="pptx-rb-pill"
173611
- disabled
173612
- >
173613
- {{ 'pptx.review.readOnly' | translate }}
173614
- </button>
173615
- <button
173616
- data-ribbon-control="review.protect.restrictPermission"
173617
- type="button"
173618
- class="pptx-rb-pill"
173619
- disabled
173620
- >
173621
- {{ 'pptx.review.restrictPermission' | translate }}
173622
- </button>
173623
- </span>
173624
- <button
173625
- data-ribbon-group="review.ink"
173626
- data-ribbon-control="review.ink.hideInk"
173627
- type="button"
173628
- class="pptx-rb-pill"
173629
- disabled
173630
- >
173631
- {{ 'pptx.review.hideInk' | translate }}
173632
- </button>
173633
- @if (hasSel()) {
173634
- <button type="button" class="pptx-rb-pill" (click)="link.emit()">
173635
- {{ 'pptx.ribbon.link' | translate }}
173636
- </button>
173637
- }
173638
- `, isInline: true, dependencies: [{ kind: "pipe", type: TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
173973
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: RibbonReviewSectionComponent, isStandalone: true, selector: "pptx-ribbon-review-section", inputs: { spellCheckEnabled: "spellCheckEnabled", canEdit: "canEdit" }, outputs: { comments: "comments", spellCheckChange: "spellCheckChange", a11y: "a11y", openCompare: "openCompare", language: "language", link: "link" }, host: { classAttribute: "contents" }, ngImport: i0, template: `<pptx-ui-ribbon-section [groups]="groups()" (command-request)="request($event)" />`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
173639
173974
  }
173640
173975
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: RibbonReviewSectionComponent, decorators: [{
173641
173976
  type: Component,
@@ -173644,164 +173979,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
173644
173979
  standalone: true,
173645
173980
  changeDetection: ChangeDetectionStrategy.OnPush,
173646
173981
  host: { class: 'contents' },
173647
- imports: [TranslatePipe],
173648
- template: `
173649
- <!-- Proofing -->
173650
- <span class="contents" data-ribbon-group="review.proofing">
173651
- <button
173652
- data-ribbon-control="review.proofing.spelling"
173653
- type="button"
173654
- class="pptx-rb-pill"
173655
- [class.is-active]="spellCheckEnabled()"
173656
- [attr.aria-pressed]="spellCheckEnabled()"
173657
- [title]="'pptx.review.toggleSpellCheck' | translate"
173658
- (click)="spellCheckChange.emit(!spellCheckEnabled())"
173659
- >
173660
- {{ 'pptx.review.spelling' | translate }}
173661
- </button>
173662
- <button
173663
- data-ribbon-control="review.proofing.thesaurus"
173664
- type="button"
173665
- class="pptx-rb-pill"
173666
- disabled
173667
- >
173668
- {{ 'pptx.review.thesaurus' | translate }}
173669
- </button>
173670
- </span>
173671
- <span class="pptx-rb-sep"></span>
173672
- <!-- Accessibility -->
173673
- <button
173674
- data-ribbon-group="review.accessibility"
173675
- data-ribbon-control="review.accessibility.check"
173676
- type="button"
173677
- class="pptx-rb-pill"
173678
- [title]="'pptx.review.accessibilityCheckTooltip' | translate"
173679
- (click)="a11y.emit()"
173680
- >
173681
- {{ 'pptx.review.accessibilityCheck' | translate }}
173682
- </button>
173683
- <span class="pptx-rb-sep"></span>
173684
- <!-- Language -->
173685
- <span class="contents" data-ribbon-group="review.language">
173686
- <button
173687
- data-ribbon-control="review.language.translate"
173688
- type="button"
173689
- class="pptx-rb-pill"
173690
- disabled
173691
- >
173692
- {{ 'pptx.review.translate' | translate }}
173693
- </button>
173694
- <button
173695
- type="button"
173696
- class="pptx-rb-pill"
173697
- [title]="'pptx.review.languageTooltip' | translate"
173698
- (click)="language.emit()"
173699
- >
173700
- {{ 'pptx.review.language' | translate }}
173701
- </button>
173702
- </span>
173703
- <span class="pptx-rb-sep"></span>
173704
- <!-- Changes -->
173705
- <span class="contents" data-ribbon-group="review.compare">
173706
- <button
173707
- data-ribbon-control="review.compare.markAllRead"
173708
- type="button"
173709
- class="pptx-rb-pill"
173710
- disabled
173711
- >
173712
- {{ 'pptx.review.markAllRead' | translate }}
173713
- </button>
173714
- <button
173715
- data-ribbon-control="review.compare.compare"
173716
- type="button"
173717
- class="pptx-rb-pill"
173718
- [disabled]="!canEdit()"
173719
- [title]="'pptx.ribbon.compareTitle' | translate"
173720
- (click)="openCompare.emit()"
173721
- >
173722
- {{ 'pptx.ribbon.compare' | translate }}
173723
- </button>
173724
- </span>
173725
- <span class="pptx-rb-sep"></span>
173726
- <!-- Comments -->
173727
- <span class="contents" data-ribbon-group="review.comments">
173728
- <button type="button" class="pptx-rb-pill" (click)="comments.emit()">
173729
- {{ 'pptx.toolbar.comments' | translate }}
173730
- </button>
173731
- <div class="flex flex-col justify-center gap-0.5">
173732
- <button
173733
- data-ribbon-control="review.comments.delete"
173734
- type="button"
173735
- class="pptx-rb-toggle"
173736
- disabled
173737
- >
173738
- {{ 'pptx.common.delete' | translate }}
173739
- </button>
173740
- <button
173741
- data-ribbon-control="review.comments.previous"
173742
- type="button"
173743
- class="pptx-rb-toggle"
173744
- disabled
173745
- >
173746
- {{ 'pptx.common.previous' | translate }}
173747
- </button>
173748
- </div>
173749
- <div class="flex flex-col justify-center gap-0.5">
173750
- <button
173751
- data-ribbon-control="review.comments.next"
173752
- type="button"
173753
- class="pptx-rb-toggle"
173754
- disabled
173755
- >
173756
- {{ 'pptx.common.next' | translate }}
173757
- </button>
173758
- <button
173759
- data-ribbon-control="review.comments.showComments"
173760
- type="button"
173761
- class="pptx-rb-toggle hover:bg-accent"
173762
- (click)="comments.emit()"
173763
- >
173764
- {{ 'pptx.review.showComments' | translate }}
173765
- </button>
173766
- </div>
173767
- </span>
173768
- <span class="pptx-rb-sep"></span>
173769
- <!-- Protect -->
173770
- <span class="contents" data-ribbon-group="review.protect">
173771
- <button
173772
- data-ribbon-control="review.protect.readOnly"
173773
- type="button"
173774
- class="pptx-rb-pill"
173775
- disabled
173776
- >
173777
- {{ 'pptx.review.readOnly' | translate }}
173778
- </button>
173779
- <button
173780
- data-ribbon-control="review.protect.restrictPermission"
173781
- type="button"
173782
- class="pptx-rb-pill"
173783
- disabled
173784
- >
173785
- {{ 'pptx.review.restrictPermission' | translate }}
173786
- </button>
173787
- </span>
173788
- <button
173789
- data-ribbon-group="review.ink"
173790
- data-ribbon-control="review.ink.hideInk"
173791
- type="button"
173792
- class="pptx-rb-pill"
173793
- disabled
173794
- >
173795
- {{ 'pptx.review.hideInk' | translate }}
173796
- </button>
173797
- @if (hasSel()) {
173798
- <button type="button" class="pptx-rb-pill" (click)="link.emit()">
173799
- {{ 'pptx.ribbon.link' | translate }}
173800
- </button>
173801
- }
173802
- `,
173982
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
173983
+ template: `<pptx-ui-ribbon-section [groups]="groups()" (command-request)="request($event)" />`,
173803
173984
  }]
173804
- }], propDecorators: { spellCheckEnabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "spellCheckEnabled", required: false }] }], canEdit: [{ type: i0.Input, args: [{ isSignal: true, alias: "canEdit", required: false }] }], comments: [{ type: i0.Output, args: ["comments"] }], spellCheckChange: [{ type: i0.Output, args: ["spellCheckChange"] }], a11y: [{ type: i0.Output, args: ["a11y"] }], openCompare: [{ type: i0.Output, args: ["openCompare"] }], language: [{ type: i0.Output, args: ["language"] }], link: [{ type: i0.Output, args: ["link"] }] } });
173985
+ }], propDecorators: { spellCheckEnabled: [{
173986
+ type: Input
173987
+ }], canEdit: [{
173988
+ type: Input
173989
+ }], comments: [{ type: i0.Output, args: ["comments"] }], spellCheckChange: [{ type: i0.Output, args: ["spellCheckChange"] }], a11y: [{ type: i0.Output, args: ["a11y"] }], openCompare: [{ type: i0.Output, args: ["openCompare"] }], language: [{ type: i0.Output, args: ["language"] }], link: [{ type: i0.Output, args: ["link"] }] } });
173805
173990
 
173806
173991
  class SubtitleSettingsControlComponent {
173807
173992
  constructor() {
@@ -176194,7 +176379,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImpor
176194
176379
  }], 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 }] }] } });
176195
176380
 
176196
176381
  // Generated by scripts/inline-shared.mjs from package.json. Do not edit.
176197
- const PPTX_ANGULAR_VIEWER_VERSION = "4.15.0";
176382
+ const PPTX_ANGULAR_VIEWER_VERSION = "4.16.0";
176198
176383
 
176199
176384
  /**
176200
176385
  * account-page.component.ts: File > Account content.
@@ -214563,4 +214748,4 @@ function cn(...values) {
214563
214748
  */
214564
214749
 
214565
214750
  export { AiProposalCardComponent as $, smartArt3DEyeInDiagram as A, resolveSmartArt3DLightModel as B, AFTER_ANIMATION_VALUES as C, DEFAULT_PALETTE$1 as D, ALIGN_OPTIONS as E, ANIMATION_PRESET_CATEGORIES as F, AUDIENCE_HASH as G, AUDIENCE_NONCE_KEY as H, AVATAR_COLOR_SWATCHES as I, AXIS_LABEL_COLOR as J, AccessibilityPanelComponent as K, AccessibilityService as L, AccessibilityTextPanelComponent as M, NO_THREE_VIEW_OVERFLOW as N, AccountPageComponent as O, ActionSettingsPanelComponent as P, AdvancedChartEditorComponent as Q, AiChangeOverlayComponent as R, AiChatPanelComponent as S, AiChatService as T, AiComposerComponent as U, AiFocusBarComponent as V, AiFocusHighlightOverlayComponent as W, AiHistoryMenuComponent as X, AiHistoryService as Y, AiMessageListComponent as Z, AiPanelStore as _, appendChartLegendSvg as a, ELEMENT_CONTEXT_MENU_COMMAND_IDS as a$, AiSettingsSectionComponent as a0, AiToolCallCardComponent as a1, AnimationAuthorPanelComponent as a2, AnimationPanelComponent as a3, AnimationPlaybackService as a4, AutosaveRecoveryDialogComponent as a5, AutosaveService as a6, BACKSTAGE_CARD_IDS as a7, BACKSTAGE_PAGE_IDS as a8, BroadcastDialogComponent as a9, CommentsService as aA, ComparePanelComponent as aB, ConnectorRendererComponent as aC, ConnectorTextOverlayComponent as aD, CustomShowsComponent as aE, DEFAULT_BOUNDS as aF, DEFAULT_BROADCAST_SERVER_URL as aG, DEFAULT_CANVAS_HEIGHT as aH, DEFAULT_CANVAS_WIDTH as aI, DEFAULT_COLOR_SCHEME as aJ, DEFAULT_FILL_COLOR$1 as aK, DEFAULT_LAYOUT as aL, DEFAULT_MORPH_DURATION_MS as aM, DEFAULT_PATTERN_FILL_PRESET as aN, DEFAULT_PRINT_SETTINGS as aO, DEFAULT_SLIDE_BACKGROUND as aP, DEFAULT_STROKE_COLOR as aQ, DEFAULT_STYLE as aR, DEFAULT_TABLE_ROW_HEIGHT as aS, DEFAULT_TEXT_COLOR$2 as aT, DEFAULT_VIEWER_PROFILE as aU, DIRECTIONAL_PRESETS as aV, DIRECTION_OPTIONS as aW, DocumentPropertiesCardComponent as aX, EASE as aY, EDITOR_SHORTCUT_ACTION_IDS as aZ, EFFECT_SOUND_CATALOGUE as a_, CANVAS_CONTEXT_MENU_COMMAND_IDS as aa, CHART_EDITOR_STYLES as ab, CINEMATIC_TRANSITION_KEYFRAMES as ac, CURSOR_PALETTE as ad, CanvasFitService as ae, ChartAxisOptionsComponent as af, ChartAxisStyleOptionsComponent as ag, ChartComboTypeOptionsComponent as ah, ChartDataEditorComponent as ai, ChartDataLabelOptionsComponent as aj, ChartDatapointMarkerOptionsComponent as ak, ChartDatapointOptionsComponent as al, ChartDisplayOptionsComponent as am, ChartElementViewComponent as an, ChartErrorBarOptionsComponent as ao, ChartMarkerOptionsComponent as ap, ChartPartSelectionService as aq, ChartPrimitivesComponent as ar, ChartRendererComponent as as, ChartTrendlineOptionsComponent as at, ChartTypeSelectorComponent as au, CollaborationCursorsComponent as av, CollaborationService as aw, ColorChangedImageComponent as ax, CommentMarkersOverlayComponent as ay, CommentsPanelComponent as az, renderChartTextSvg as b, NotesToolbarComponent as b$, EMBEDDED_FONTS_STYLE_ID as b0, EMPHASIS_PRESETS as b1, ENTRANCE_PRESETS as b2, TEMPLATES as b3, EXIT_PRESETS as b4, EditorContextMenuComponent as b5, EditorHistory as b6, EditorStateService as b7, EditorToolbarComponent as b8, EffectsPanelComponent as b9, InsertSmartArtDialogComponent as bA, InspectorPaneHeaderComponent as bB, InspectorPanelComponent as bC, IsMobileService as bD, KeepAnnotationsDialogComponent as bE, LOCALE_CATALOG as bF, LONG_PRESS_DURATION_MS as bG, LONG_PRESS_MOVE_TOLERANCE_PX as bH, LoadContentService as bI, LocalPresencePublisher as bJ, MAX_ZOOM_SCALE as bK, MIN_ZOOM_SCALE as bL, MOTION_PATH_COLUMNS as bM, MediaPreviewComponent as bN, MediaPropertiesPanelComponent as bO, MediaRendererComponent as bP, MediaTrimTimelineComponent as bQ, MobileBottomBarComponent as bR, MobileMenuSheetComponent as bS, MobilePresenterViewComponent as bT, MobileSheetComponent as bU, MobileSlidesSheetComponent as bV, MobileToolbarComponent as bW, ModalDialogComponent as bX, Model3DRendererComponent as bY, NotesHandoutCardComponent as bZ, NotesPanelComponent as b_, ElementRendererComponent as ba, EmbeddedFontsService as bb, EncryptedFileDialogComponent as bc, EquationEditorDialogComponent as bd, EquationRendererComponent as be, EquationTemplateGalleryComponent as bf, ExportProgressModalComponent as bg, ExportService as bh, FieldContextService as bi, FindBarComponent as bj, FindReplaceBarComponent as bk, FollowModeBarComponent as bl, FontEmbeddingListComponent as bm, FontEmbeddingPanelComponent as bn, GALLERY_THEME_PRESETS as bo, GOOGLE_WEBFONTS_LINK_ID as bp, GRIDLINE_COLOR$1 as bq, GoogleWebfontsService as br, GradientPickerComponent as bs, HANDOUT_OPTIONS as bt, HeaderFooterDialogComponent as bu, HyperlinkDialogComponent as bv, INSTANT as bw, ImagePropertiesPanelComponent as bx, InkDrawingService as by, InkRendererComponent as bz, createSvgEl as c, RibbonShapeExtrasComponent as c$, OPTIONS_PAGE_IDS as c0, OPTIONS_SECTION_IDS as c1, OPTIONS_SETTING_IDS as c2, OleRendererComponent as c3, OutlineViewOverlayComponent as c4, P14_TRANSITION_KEYFRAMES as c5, P14_TRANSITION_KEYFRAMES_2 as c6, P14_TRANSITION_KEYFRAMES_ALL as c7, PIE_AUTO_INSET_PX as c8, POWER_POINT_VIEWER_PROVIDERS as c9, REPEAT_MODE_OPTIONS as cA, RESIZE_HANDLES as cB, RIBBON_TAB_IDS as cC, RULER_FONT_SIZE as cD, RULER_THICKNESS as cE, ReadingViewOverlayComponent as cF, RemoteSelectionOverlayComponent as cG, Rendering3DService as cH, RibbonAnimationGalleryComponent as cI, RibbonAnimationsSectionComponent as cJ, RibbonArrangeSectionComponent as cK, RibbonColorPopoverComponent as cL, RibbonComponent as cM, RibbonDesignSectionComponent as cN, RibbonDrawSectionComponent as cO, RibbonDrawingGroupComponent as cP, RibbonEditingSectionComponent as cQ, RibbonFileSectionComponent as cR, RibbonFontControlsComponent as cS, RibbonHomeSectionComponent as cT, RibbonHyperlinkButtonComponent as cU, RibbonInsertFieldsComponent as cV, RibbonInsertSectionComponent as cW, RibbonMotionPathGalleryComponent as cX, RibbonParagraphControlsComponent as cY, RibbonPrimaryRowComponent as cZ, RibbonReviewSectionComponent as c_, PPTX_OPEN_ACCEPT as ca, PRESENTATION_OPEN_EXTENSIONS as cb, PRESENTER_CHANNEL_NAME as cc, PRESENTER_MSG_ORIGIN as cd, PRESENTER_TIMER_SEGMENT_MS as ce, PX_PER_CM as cf, PX_PER_INCH as cg, PasswordProtectionDialogComponent as ch, PasswordStrengthMeterComponent as ci, PowerPointViewerComponent as cj, PresentToolbarAutoHide as ck, PresentationAnnotationOverlayComponent as cl, PresentationAnnotationsService as cm, PresentationOverlayComponent as cn, PresentationPropertiesPanelComponent as co, PresentationSettingsCardComponent as cp, PresentationSubtitleBarComponent as cq, PresentationToolbarComponent as cr, PresentationTransitionOverlayComponent as cs, PresenterViewComponent as ct, PresenterWindowService as cu, PrintDialogComponent as cv, PrintService as cw, PrintSettingsPanelComponent as cx, PropertiesDialogComponent as cy, RANDOM_ELIGIBLE_TYPES as cz, buildBarChart3DHoverTooltip as d, TableResizeOverlayComponent as d$, RibbonSlideshowSectionComponent as d0, RibbonTransitionsSectionComponent as d1, RibbonViewSectionComponent as d2, RulerGuidesService as d3, SEQUENCE_OPTIONS as d4, SEVERITY_GROUPS as d5, SEVERITY_LABELS as d6, DEFAULT_TRANSITION_DURATION_MS$1 as d7, SHORTCUT_REFERENCE_ITEMS as d8, SLIDE_TRANSITION_KEYFRAMES as d9, SlideDiffRowComponent as dA, SlideDiffThumbnailsComponent as dB, SlideSizeCardComponent as dC, SlideSorterOverlayComponent as dD, SlideThemeOverridePanelComponent as dE, SlideTransitionCardComponent as dF, SlidesPanelComponent as dG, SmartArt3DRendererComponent as dH, SmartArtPreviewComponent as dI, SmartArtPropertiesComponent as dJ, SmartArtRendererComponent as dK, StatusBarComponent as dL, TABLE_STRUCTURE_TOGGLES as dM, TEXT_3D_BOTTOM_BEVEL_KEYS as dN, TEXT_3D_TOP_BEVEL_KEYS as dO, TEXT_DIRECTION_OPTIONS$1 as dP, THEME_CATALOG as dQ, TIMING_CURVE_OPTIONS as dR, TOOLBAR_BUTTON_IDS as dS, TRANSITION_SPEED_DURATION_MS as dT, TRIGGER_OPTIONS as dU, TYPE_LABELS as dV, TableCellAdvancedFillComponent as dW, TableCellFormattingComponent as dX, TableDataEditorComponent as dY, TablePropertiesComponent as dZ, TableRendererComponent as d_, SLIDE_TRANSITION_KEYFRAMES_CSS as da, DEFAULT_PALETTE as db, PALETTES as dc, SMART_ART_COLOR_SCHEMES as dd, SMART_ART_STYLE_OPTIONS as de, SUB_ITEM_LABEL as df, SVG_WARP_PRESETS as dg, SWIPE_MAX_VERTICAL_PX as dh, SWIPE_THRESHOLD_PX as di, SelectionPaneComponent as dj, SetUpSlideShowDialogComponent as dk, SettingsAppearanceTabComponent as dl, SettingsDialogComponent as dm, SettingsLanguageTabComponent as dn, ShareDialogComponent as dp, ShortcutPanelComponent as dq, ShowOptionsFieldsetComponent as dr, ShowSlidesFieldsetComponent as ds, SignatureStrippedDialogComponent as dt, SignaturesPanelComponent as du, SignaturesService as dv, SlideBackgroundCardComponent as dw, SlideCanvasComponent as dx, SlideDefaultInspectorComponent as dy, SlideDiffChangesComponent as dz, roundDragValue as e, applyFindReplacements as e$, TableSelectionService as e0, TagsCardComponent as e1, Text3DBevelSectionComponent as e2, Text3DPanelComponent as e3, TextAdvancedPanelComponent as e4, ThemeEditorFieldsComponent as e5, ThemeGalleryComponent as e6, ThemeSelectorCardComponent as e7, TitleBarComponent as e8, TitleBarSearchComponent as e9, ViewerMobileSheetService as eA, ViewerPresentationModeService as eB, ViewerThemeGalleryService as eC, ViewerTouchGesturesService as eD, ViewerZoomService as eE, WEBM_MIME_CANDIDATES as eF, WHEEL_SPOKE_COUNTS as eG, WriteBackScheduler as eH, ZERO_LINE_COLOR as eI, ZoomNavigationService as eJ, ZoomRendererComponent as eK, ZoomTargetService as eL, addCategory as eM, addCommentToList as eN, addGradientStopPatch as eO, addItem as eP, addSeries as eQ, addSubItem as eR, advanceStep as eS, affordanceElements as eT, aiToggleVisible as eU, alignPatch as eV, animationFor as eW, animationPresetLabelKey as eX, annotationMapToInkInserts as eY, applyAcceptedDiff as eZ, applyAnimationPreset as e_, TransitionDirectionPickerComponent as ea, TransitionPreviewComponent as eb, VALIGN_OPTIONS as ec, VIEWER_DIALOG_IDS as ed, VIEWER_EXPORT_FORMAT_IDS as ee, VIEWER_FEATURE_IDS as ef, VIEWER_PANEL_IDS as eg, VIEWER_THEME as eh, VersionHistoryPanelComponent as ei, ViewerCanvasEditingService as ej, ViewerCollabCursorService as ek, ViewerCollaborationSessionService as el, ViewerCollaborationShellService as em, ViewerCompareService as en, ViewerCustomShowsService as eo, ViewerCustomizationHandle as ep, ViewerCustomizationService as eq, ViewerDialogsService as er, ViewerDocumentPropertiesService as es, ViewerExportService as et, ViewerExtraDialogsComponent as eu, ViewerFileIOService as ev, ViewerFindReplaceService as ew, ViewerFormatPainterService as ex, ViewerInspectorPanelService as ey, ViewerKeyboardService as ez, buildPerspCamera as f, buildTrimFragment as f$, applyFormatToElement as f0, applyMove as f1, applyResize as f2, asMediaElement as f3, assignUserColor as f4, attachShowVisibilityPause as f5, attachTouchGestures as f6, axisTickValues as f7, beginDrawingNodeEdit as f8, beginNodeEdit as f9, buildGradientFillCss as fA, buildGridlinesAndLabels as fB, buildHyperlinkPatch as fC, buildInkContainerStyle as fD, buildInkStrokes as fE, buildLegend as fF, buildLiveInkStrokeView as fG, buildMarkTooltip as fH, buildModel3DContainerStyle as fI, buildModel3DMountOptions as fJ, buildModel3DViewModel as fK, buildOleActionModel as fL, buildOleInfoRows as fM, buildPatternFillCss as fN, buildPieViewModel as fO, buildPrintHtmlDocument as fP, buildPropertiesPatch as fQ, buildRadarViewModel as fR, buildRegionMapViewModel as fS, buildSaveSlides as fT, buildShareUrl as fU, buildSmartArtInsertElement as fV, buildSmartArtNodes as fW, buildStockViewModel as fX, buildSurfaceViewModel as fY, buildTableViewModel as fZ, buildTreemapViewModel as f_, bevelSizePatch as fa, boolFromEvent as fb, bringForward as fc, bringToFront as fd, buildBarActions as fe, buildBroadcastConfig as ff, buildBroadcastViewerUrl as fg, buildCategoryLabels as fh, buildCellParagraphs as fi, buildChartViewModel as fj, buildChatLogExport as fk, buildChatLogMarkdown as fl, buildChromeStyle as fm, buildClearHyperlinkPatch as fn, buildClickGroups as fo, buildColStyles as fp, buildCollaborationConfig as fq, buildComboViewModel as fr, buildCssGradientFromShapeStyle as fs, buildDuotoneFilter as ft, buildDuotoneFilterId as fu, buildEmbeddedFontStyles as fv, buildEquationElement as fw, buildEquationSegment as fx, buildFallbackViewModel as fy, buildFontFaceRule as fz, perspToScreen as g, computeRotateHandleBox as g$, buildWaterfallViewModel as g0, buildZeroLine as g1, buildZoomContainerStyle as g2, buildZoomViewModel as g3, bulletIndentPx as g4, canAddTopLevelNode as g5, canEditSmartArtNodes as g6, canGroupSelection as g7, canRemoveTopLevelNode as g8, canSetStrokeWidth as g9, collectUsedFontFamilies as gA, columnWidthStyle as gB, commitNodeText as gC, computeAlign as gD, computeAxisTitlePrimitives as gE, computeBarRects as gF, computeBubbleRadius as gG, computeCornerHandle as gH, computeDistribute as gI, computeDrawingViewBox as gJ, computeErrorBarPrimitives as gK, computeFocusTargets as gL, computeGridSpacingPx as gM, computeHandleBoxes as gN, computeHandoutLayout as gO, computeIsMobile as gP, computeIsTablet as gQ, computeLinePoints as gR, computeLinearRegression as gS, computePageCount as gT, computePieLayout as gU, computePieSlicePath as gV, computePieSlices as gW, computePlotLayout as gX, computeRSquared as gY, computeRadarPoints as gZ, computeResizeHandleBoxes as g_, canStartBroadcast as ga, canStartShare as gb, canUngroupSelection as gc, canUseClipboard as gd, captionDisplayText as ge, cellRunStyle as gf, cellStyleToStyleMap as gg, cellTdStyle as gh, changeCountLabel as gi, changeIcon as gj, characterSpacingPatch as gk, chartPreserveAspectRatio as gl, checkFontAvailable as gm, clampCursorPosition as gn, clampGifDimensions as go, clampIndex as gp, clampNotesFontSize as gq, clampScale as gr, clampStep as gs, clearAllLocalViewerData as gt, clearAudienceContent as gu, cn as gv, collectAccessibilityIssues as gw, collectElementText as gx, collectSlideText as gy, collectStoredChats as gz, pieRimPoint as h, fontMimeForFormat as h$, computeScatterDots as h0, computeScatterXDomain as h1, computeSelectionBoxes as h2, computeSingleSelected as h3, computeSlideIndices as h4, computeSnap as h5, computeStackedBarRects as h6, computeStackedValueRange as h7, computeTrendlinePrimitives as h8, computeValueRange as h9, disableInnerShadowPatch as hA, disableOuterShadowPatch as hB, disableReflectionPatch as hC, disableSoftEdgePatch as hD, duplicateElementById as hE, durationOf as hF, effectsStateOf as hG, enableGlowPatch as hH, enableInnerShadowPatch as hI, enableOuterShadowPatch as hJ, enableReflectionPatch as hK, enableSoftEdgePatch as hL, encodeGif as hM, endShowMediaCleanup as hN, estimatePageCount as hO, exitPresentationFullscreen as hP, exportAiChatLogs as hQ, extractPathPoints as hR, eyedropperAvailable as hS, fillColorOf$1 as hT, findInSlides as hU, findOwningSlideIndex as hV, findSlideIndexByElementId as hW, firstVisibleIndex as hX, fitPolynomial as hY, fitZoom as hZ, focusTargetChips as h_, convertOmmlToMathMl as ha, copyFormatFromElement as hb, countAccessibilityIssues as hc, countAnnotationStrokes as hd, createAngularAiBridge as he, createCustomShow as hf, createImageElementFromFile as hg, createSwipeDismissDrag as hh, createWebrtcBundle as hi, createWebsocketBundle as hj, cssObjectToStyleMap as hk, currentColorScheme as hl, currentLayout as hm, currentStyle as hn, defaultCssVars as ho, defaultRadius as hp, defaultThemeColors as hq, deleteElementsByIds as hr, deleteVersion as hs, demoteNode as ht, deriveModel3DBlobUrl as hu, derivePresenceList as hv, describeCollaborationShellState as hw, describeSmartArtBounds as hx, directionPickerState as hy, disableGlowPatch as hz, isChartInteractionArmed as i, headerLabel as i$, fontSizeOf as i0, forgetSessionDeck as i1, formatAxisValue as i2, formatBytes as i3, formatCursorLabel as i4, formatElapsed as i5, formatFileSize as i6, formatInlineListStyle as i7, formatPropertyDate as i8, formatTime as i9, getVersions as iA, getResolvedShapeClipPath as iB, getResolvedShapeClipPathFor as iC, getSessionTabId as iD, getShapeFillStrokeStyle as iE, getSlideBackgroundStyle as iF, getSlideTransitionAnimations as iG, getSmartArtNodeBounds as iH, getSpeechRecognitionCtor as iI, getTextBlockStyle as iJ, getTextWarp as iK, getTouchDistance as iL, getWarpCategory as iM, getWarpPath as iN, gradientStateFromStyle as iO, gradientStateOf as iP, gradientStatePatch as iQ, gradientStopColorCommitPatch as iR, gridColumns as iS, groupIssuesBySeverity as iT, hasAnimation as iU, hasCopyableFormat as iV, hasExistingLink as iW, hasExitedFullscreen as iX, hasGradientFill as iY, hasPressureVariation as iZ, hasVisibleSlideAfter as i_, fpsToFrameIntervalMs as ia, generateBroadcastRoomId as ib, generateCommentId as ic, generateCustomShowId as id, generatePressureCircles as ie, generateTicks as ig, getCinematicTransitionAnimations as ih, getClrChangeParams as ii, getContainerStyle as ij, getDuotoneFilterDef as ik, getEffectSoundAsset as il, getEffectSoundState as im, getImageSrc as io, getLocalStorageUsageSummary as ip, getOleAriaLabel as iq, getOleBadgeLabel as ir, getOleDisplayName as is, getOleDownloadFileName as it, getOleTypeColor as iu, getOleTypeLabel as iv, getP14TransitionAnimations as iw, getPasswordStrength as ix, getPatternSvg as iy, getPlaceholderStyle as iz, computePieChartLayout as j, nodeItalic as j$, imageDimensions as j0, injectResolvedCustomization as j1, inkViewBox as j2, insertTableElementColumn as j3, insertTableElementRow as j4, interpolateWidth as j5, isAudienceTab as j6, isBold as j7, isBrowserOpenableMime as j8, isChildNode as j9, mediaFallbackFor as jA, mediaSurfaceFor as jB, mergeCaptionResults as jC, mergeDown as jD, mergeRight as jE, mergeSelection as jF, mergeTablesDirective as jG, moveElementBy as jH, moveNodeDown as jI, moveNodeUp as jJ, msToFrameDelayCs as jK, narrowToCircle as jL, narrowToPolygon as jM, narrowToRect as jN, newChartElement as jO, newEquationElement as jP, newPresetShapeElement as jQ, newShapeElement as jR, newSmartArtElement as jS, newTableElement as jT, newTextElement as jU, nextVisibleIndex as jV, nodeBold as jW, nodeEditBox as jX, nodeFillColor as jY, nodeFontColor as jZ, nodeIdFromKey as j_, isElementInteractive as ja, isInjectableUrl as jb, isItalic as jc, isLegacyBinaryPresentation as jd, isPpactionUrl as je, isPresenterMessage as jf, isSigned as jg, isSupportedPresentationFile as jh, isTextElement as ji, isTwoTableFocus as jj, isUnderline as jk, isUrlSafe as jl, isValidRoomId as jm, isViewportBackgroundPressTarget as jn, isZoomActivationKey as jo, issueTrackKey as jp, issueTypeLabel as jq, keyToLabel as jr, lastVisibleIndex as js, latexToMathml as jt, layoutConnectorPaints as ju, layoutNodeLabels as jv, linePointsToSvgString as jw, lineSpacingPatch as jx, loadAudienceContent as jy, loadSessionDeck as jz, perspScreenToPlaneY as k, resolveDirection8 as k$, nodeStyle as k0, normalizeFontFormat as k1, normalizeSlidesPerPage as k2, normalizeValue as k3, numFromEvent as k4, oleActionsVisibleFor as k5, ommlToMathml as k6, ooxmlDashToCssBorderStyle as k7, openNativeEyeDropper as k8, overallStatus as k9, promoteNode as kA, provideViewerTheme as kB, radarAngle as kC, radarRingPoints as kD, readAsDataUrl as kE, recordWebm as kF, registerCrossSlideAudio as kG, rememberSessionDeck as kH, removeAnimation as kI, removeCategory as kJ, removeTableElementColumn as kK, removeCommentFromList as kL, removeElementAnimation as kM, removeGradientStopPatch as kN, removeNode as kO, removeTableElementRow as kP, removeSeries as kQ, renderToCanvas as kR, reorderAnimationDown as kS, reorderAnimationUp as kT, replaceInSlides as kU, replaceMatch as kV, requestPresentationFullscreen as kW, resizeElement as kX, resolveCaptionTracks as kY, resolveChartKind as kZ, resolveDirection as k_, paletteColor as ka, parseAudienceNonce as kb, parseNodeTextarea as kc, partitionSlides as kd, patchChartData as ke, patchChartStyle as kf, patchTableData as kg, patchTextStyle as kh, patternPresetOptions as ki, pendingElementStyles as kj, pickColorByClickFallback as kk, pickFile as kl, pickSupportedMimeType as km, planGifFrames as kn, planVideoSegments as ko, pointFromPointerEvent as kp, pointsToSvgPathD as kq, presenceToCursors as kr, presentationBaseName as ks, presentationStageStyle as kt, presenterTimerProgress as ku, presetByLayout as kv, presetsForCategory as kw, pressuresToWidths as kx, prevVisibleIndex as ky, projectDrawingShapes as kz, resolvePieSliceShareValue as l, setDirection as l$, resolveFontVariant as l0, resolveHyperlinkHref as l1, resolveInteractiveElementId as l2, resolveLegendAnchorPosition as l3, resolveMediaSrc as l4, resolveOleType as l5, resolveOrientation as l6, resolveParagraphBullet as l7, resolvePresenterNotes as l8, resolveProfileInitial as l9, seedPropertiesDraft as lA, seedShareFields as lB, segmentFrameCount as lC, selectValue$3 as lD, sendBackward as lE, sendToBack as lF, sequentialColorScale as lG, serializeWriteBack as lH, seriesColor as lI, seriesXValues as lJ, setAfterAnimation as lK, setAfterAnimationColor as lL, setAnimationEmphasis as lM, setAnimationEntrance as lN, setAnimationExit as lO, setAxis as lP, setAxisLogScale as lQ, setAxisTitleStyle as lR, setCategoryLabel as lS, setCellText as lT, setColorScheme as lU, setDataLabels as lV, setDataPointExplosion as lW, setDataPointFill as lX, setDataPointLabel as lY, setDataPointMarker as lZ, setDelay as l_, resolveRegionCode as la, resolveRibbonCanGroup as lb, resolveSlideAutoAdvanceMs as lc, resolveSlideTransition as ld, resolvePalette as le, resolveThemeCatalogEntry as lf, resolveTransitionDuration as lg, resolveTransitionDurationMs as lh, resolveWheelSpokeCount as li, restoreSessionDeck as lj, revealedElementStyles as lk, routeOrthogonalConnector as ll, rowStyle as lm, rulerDragToGuidePosition as ln, rulerHighlight as lo, rulerStripTicks as lp, sampleColorFromSlide as lq, sanitizeColor as lr, sanitizeSlideIndex as ls, sanitizeUserName as lt, saveViewerProfile as lu, savedPresentationFileName as lv, scanAvailableFonts as lw, searchSlides as lx, seedBroadcastFields as ly, seedHyperlinkDraft as lz, hexToRgb as m, toggleCommentResolvedInList as m$, setDuration as m0, setEffectSound as m1, setEffectStockSound as m2, setElementPosition as m3, setGridlineStyle as m4, setLayout as m5, setLegend as m6, setNodeStyle as m7, setNodeText as m8, setRepeatCount as m9, slidesWithReappliedLayout as mA, smartArtNodes as mB, paletteColour as mC, snapToGridStep as mD, splitCursorCell as mE, splitMergedCell as mF, statusKind as mG, statusLabel$1 as mH, storeAudienceContent as mI, stringFromEvent$5 as mJ, strokeColorOf as mK, strokeToInkElement as mL, strokeWidthOf as mM, styleShadowFilter as mN, surfaceColor as mO, textAdvancedPatch as mP, textAdvancedStateFromStyle as mQ, textAdvancedStateOf as mR, textColorOf as mS, textDirectionPatch as mT, textFontSizePatch as mU, textStyleOf as mV, textStylePatch as mW, themeStyle as mX, themeToCssVars as mY, thumbnailHeight as mZ, thumbnailZoom as m_, setRepeatMode as ma, setSequence as mb, setSeriesChartType as mc, setSeriesColor as md, setSeriesErrorBars as me, setSeriesMarker as mf, setSeriesName as mg, setSeriesTrendline as mh, setSeriesValue as mi, setStyle as mj, setTimingCurve as mk, setTitle as ml, setTrigger as mm, setTriggerShapeId as mn, shapeStylePatch$1 as mo, sheetAfterNavigate as mp, shouldBlockClickAdvance as mq, shouldUseSvgWarp as mr, showDirectionPicker as ms, showsTemplateAffordance as mt, signatureCountLabel as mu, signatureKey as mv, signatureTimestamp as mw, signerName as mx, statusLabel as my, slideNumberOf as mz, smartArt3DGradientColor as n, toggleNodeBold as n0, toggleNodeItalic as n1, toggleSheet as n2, topLevelNodeCount as n3, transformSelectedTextCase as n4, translationsEn as n5, updateElementById as n6, updateGlowPatch as n7, updateGradientStopPatch as n8, updateInnerShadowPatch as n9, updateOuterShadowPatch as na, updateReflectionPatch as nb, vAlignPatch as nc, validatePassword as nd, validatePrintSettings as ne, validateRoomId as nf, valueToY as ng, vermilionDarkColors as nh, vermilionDarkTheme as ni, vermilionLightColors as nj, vermilionLightTheme as nk, vermilionRadius as nl, waypointsToPathD as nm, withManualLayouts as nn, worstStatus as no, zoomTargetSlideIndex as np, obliqueBarTaper as o, perspBoxMatrix as p, shadeSmartArt3DVertices as q, renderChartLineSvg as r, shade as s, toChatSummary as t, smartArt3DGradientCoordinate as u, threeViewOverflowFromNdc as v, widenPieViewModel as w, hasThreeViewOverflow as x, overflowViewOffset as y, smartArt3DCameraMatrix as z };
214566
- //# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-Bc1e9poJ.mjs.map
214751
+ //# sourceMappingURL=pptx-angular-viewer-pptx-angular-viewer-ByBs8vwz.mjs.map