@3ddv/software-division-components 2.0.14 → 2.0.15

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, ChangeDetectorRef, input, EventEmitter, computed, Output, ViewChild, ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { input, EventEmitter, computed, signal, Output, ViewChild, ChangeDetectionStrategy, Component } from '@angular/core';
3
3
 
4
4
  class NeighborsComponent {
5
5
  // VIEWCHILD
@@ -8,13 +8,10 @@ class NeighborsComponent {
8
8
  currentSection3d;
9
9
  leftSectionElement;
10
10
  rightSectionElement;
11
- // SERVICES changes
12
- cdr = inject(ChangeDetectorRef);
13
11
  // REQUIRED INPUTS
14
- neighborsData = input.required(...(ngDevMode ? [{ debugName: "neighborsData" }] : []));
12
+ translate = input((id) => id, ...(ngDevMode ? [{ debugName: "translate" }] : []));
13
+ dvmService = input.required(...(ngDevMode ? [{ debugName: "dvmService" }] : []));
15
14
  currentSectionId = input.required(...(ngDevMode ? [{ debugName: "currentSectionId" }] : []));
16
- translateTdcToMmc = input.required(...(ngDevMode ? [{ debugName: "translateTdcToMmc" }] : []));
17
- translateMmcToTdc = input.required(...(ngDevMode ? [{ debugName: "translateMmcToTdc" }] : []));
18
15
  hasAvailability = input.required(...(ngDevMode ? [{ debugName: "hasAvailability" }] : []));
19
16
  // OPTIONAL INPUTS
20
17
  isLoading = input(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
@@ -36,6 +33,8 @@ class NeighborsComponent {
36
33
  }, ...(ngDevMode ? [{ debugName: "computedClass" }] : []));
37
34
  // COMPONENT STATE
38
35
  subscriptions = [];
36
+ relatedMaps = signal({}, ...(ngDevMode ? [{ debugName: "relatedMaps" }] : []));
37
+ fetchingIds = new Set();
39
38
  // COMPUTED STATE
40
39
  leftSectionId = computed(() => {
41
40
  try {
@@ -64,12 +63,7 @@ class NeighborsComponent {
64
63
  const currentId = this.currentSectionId();
65
64
  if (!currentId)
66
65
  return 'Loading';
67
- // Translate TDC ID to MMC ID for display
68
- const mmcId = this.translateTdcToMmc()(currentId);
69
- if (!mmcId)
70
- return currentId; // Fallback to TDC ID if translation fails
71
- // Extract section number from MMC ID (assuming format like "S_31" or similar)
72
- return mmcId.replace(/^S_/, '');
66
+ return this.translate()(currentId) || currentId;
73
67
  }
74
68
  catch (error) {
75
69
  return 'Loading';
@@ -80,12 +74,7 @@ class NeighborsComponent {
80
74
  const leftId = this.leftSectionId();
81
75
  if (!leftId)
82
76
  return null;
83
- // Translate TDC ID to MMC ID for display
84
- const mmcId = this.translateTdcToMmc()(leftId);
85
- if (!mmcId)
86
- return leftId; // Fallback to TDC ID if translation fails
87
- // Extract section number from MMC ID
88
- return mmcId.replace(/^S_/, '');
77
+ return this.translate()(leftId) || leftId;
89
78
  }
90
79
  catch (error) {
91
80
  return null;
@@ -96,12 +85,7 @@ class NeighborsComponent {
96
85
  const rightId = this.rightSectionId();
97
86
  if (!rightId)
98
87
  return null;
99
- // Translate TDC ID to MMC ID for display
100
- const mmcId = this.translateTdcToMmc()(rightId);
101
- if (!mmcId)
102
- return rightId; // Fallback to TDC ID if translation fails
103
- // Extract section number from MMC ID
104
- return mmcId.replace(/^S_/, '');
88
+ return this.translate()(rightId) || rightId;
105
89
  }
106
90
  catch (error) {
107
91
  return null;
@@ -112,33 +96,48 @@ class NeighborsComponent {
112
96
  try {
113
97
  const neighborKey = type === 'prev' ? 'l' : 'r';
114
98
  const noNeighborValue = 'none';
115
- // 1. Translate TDC MMC
116
- const currentSectionMmcId = this.translateTdcToMmc()(currentSectionTdcId);
117
- if (!currentSectionMmcId)
118
- return null;
119
- // 2. Look up neighbor in data
120
- const neighbors = this.neighborsData();
121
- const neighbor = neighbors[currentSectionMmcId];
122
- const neighborSectionMmcId = neighbor ? neighbor[neighborKey] : noNeighborValue;
123
- // 3. Handle 'none' boundary
124
- if (neighborSectionMmcId === noNeighborValue) {
99
+ const neighbor = this.relatedMaps()[currentSectionTdcId] ?? null;
100
+ if (!neighbor) {
101
+ this.fetchSection(currentSectionTdcId);
125
102
  return null;
126
103
  }
127
- // 4. Translate MMC TDC
128
- const neighborSectionTdcId = this.translateMmcToTdc()(neighborSectionMmcId);
129
- if (!neighborSectionTdcId)
104
+ const neighborSectionTdcId = neighbor[neighborKey] ?? noNeighborValue;
105
+ // Handle 'none' boundary
106
+ if (!neighborSectionTdcId || neighborSectionTdcId === noNeighborValue) {
130
107
  return null;
131
- // 5. Check availability
108
+ }
109
+ // Skip general admission sections — not navigable as neighbors
110
+ if (neighborSectionTdcId.includes('general_admission')) {
111
+ return this.findAvailableNeighbor(type, neighborSectionTdcId);
112
+ }
113
+ // Check availability using TDC ID
132
114
  if (this.hasAvailability()(neighborSectionTdcId)) {
133
115
  return neighborSectionTdcId;
134
116
  }
135
- // 6. Recursively find next available (skip unavailable sections)
117
+ // Recursively find next available (skip unavailable sections)
136
118
  return this.findAvailableNeighbor(type, neighborSectionTdcId);
137
119
  }
138
120
  catch (error) {
139
121
  return null;
140
122
  }
141
123
  }
124
+ fetchSection(sectionId) {
125
+ if (this.relatedMaps()[sectionId] || this.fetchingIds.has(sectionId)) {
126
+ return;
127
+ }
128
+ this.fetchingIds.add(sectionId);
129
+ void this.dvmService().getRelatedMapsForSection(sectionId).then(related => {
130
+ this.fetchingIds.delete(sectionId);
131
+ if (!related)
132
+ return;
133
+ const entry = {};
134
+ if (related['left']?.map_id)
135
+ entry.l = related['left'].map_id;
136
+ if (related['right']?.map_id)
137
+ entry.r = related['right'].map_id;
138
+ this.relatedMaps.update(prev => ({ ...prev, [sectionId]: entry }));
139
+ });
140
+ }
142
141
  // GETTERS
143
142
  get leftSection() {
144
143
  return this.leftSectionId();
@@ -172,7 +171,7 @@ class NeighborsComponent {
172
171
  this.sectionChange.emit({ direction, sectionId: section });
173
172
  }
174
173
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: NeighborsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
175
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: NeighborsComponent, isStandalone: true, selector: "sdc-neighbors", inputs: { neighborsData: { classPropertyName: "neighborsData", publicName: "neighborsData", isSignal: true, isRequired: true, transformFunction: null }, currentSectionId: { classPropertyName: "currentSectionId", publicName: "currentSectionId", isSignal: true, isRequired: true, transformFunction: null }, translateTdcToMmc: { classPropertyName: "translateTdcToMmc", publicName: "translateTdcToMmc", isSignal: true, isRequired: true, transformFunction: null }, translateMmcToTdc: { classPropertyName: "translateMmcToTdc", publicName: "translateMmcToTdc", isSignal: true, isRequired: true, transformFunction: null }, hasAvailability: { classPropertyName: "hasAvailability", publicName: "hasAvailability", isSignal: true, isRequired: true, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, showElement: { classPropertyName: "showElement", publicName: "showElement", isSignal: true, isRequired: false, transformFunction: null }, modeLr: { classPropertyName: "modeLr", publicName: "modeLr", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sectionChange: "sectionChange" }, viewQueries: [{ propertyName: "neighborsContainer", first: true, predicate: ["neighborsContainer"], descendants: true }, { propertyName: "currentSection", first: true, predicate: ["currentSection"], descendants: true }, { propertyName: "currentSection3d", first: true, predicate: ["currentSection3d"], descendants: true }, { propertyName: "leftSectionElement", first: true, predicate: ["leftSectionNumber"], descendants: true }, { propertyName: "rightSectionElement", first: true, predicate: ["rightSectionNumber"], descendants: true }], ngImport: i0, template: "<div #neighborsContainer class=\"neighbors-container\" [class]=\"computedClass()\" [class.hidden]=\"!showElement()\">\n <!-- LEFT SECTION BUTTON -->\n @if (leftSection) {\n <div\n class=\"neighbor-button-left neighbor-button\"\n [class.is-none]=\"leftSection === 'none'\"\n tabindex=\"0\"\n (click)=\"navigateToSection(leftSection!)\"\n (keypress.enter)=\"navigateToSection(leftSection!)\">\n <!-- ARROW ICON -->\n <div class=\"neighbor-button-icon\">\n <i>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"3\"\n stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15.75 19.5 8.25 12l7.5-7.5\" />\n </svg>\n </i>\n </div>\n\n <!-- SECTION LABEL -->\n <div class=\"neighbor-button-label\">\n <p>\n <span class=\"prefix\"> {{ modeLr() ? 'Left Section' : 'Section' }}&nbsp; </span>\n @if (leftSection !== 'none' && !modeLr()) {\n <span #leftSectionNumber class=\"section-number\">\n {{ leftSectionLabel() }}\n </span>\n }\n </p>\n </div>\n </div>\n }\n\n <!-- CURRENT SECTION TEXT -->\n <div class=\"current-section-wrapper\">\n @if (isLoading()) {\n <p class=\"current-section-loading\">\n <span>Loading</span>\n </p>\n } @else {\n @if (section) {\n <h3 class=\"current-section-text\">\n <span class=\"prefix\">Section&nbsp;</span>\n <span #currentSection class=\"section-number\">{{ section }}</span>\n </h3>\n }\n }\n </div>\n\n <!-- RIGHT SECTION BUTTON -->\n @if (rightSection) {\n <div\n class=\"neighbor-button-right neighbor-button\"\n [class.is-none]=\"rightSection === 'none'\"\n tabindex=\"1\"\n (click)=\"navigateToSection(rightSection!)\"\n (keypress.enter)=\"navigateToSection(rightSection!)\">\n <!-- ARROW ICON -->\n <div class=\"neighbor-button-icon\">\n <i>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"3\"\n stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m8.25 4.5 7.5 7.5-7.5 7.5\" />\n </svg>\n </i>\n </div>\n\n <!-- SECTION LABEL -->\n <div class=\"neighbor-button-label\">\n <p>\n <span class=\"prefix\"> {{ modeLr() ? 'Right Section' : 'Section' }}&nbsp; </span>\n @if (rightSection !== 'none' && !modeLr()) {\n <span #rightSectionNumber class=\"section-number\">\n {{ rightSectionLabel() }}\n </span>\n }\n </p>\n </div>\n </div>\n }\n</div>\n", styles: [".sdc-neighbors{--sdc-neighbors-background-color: rgba(0, 0, 0, .85);--sdc-neighbors-text-color: #ffffff;--sdc-neighbors-border-radius: 9999px;--sdc-neighbors-padding-x: .75rem;--sdc-neighbors-padding-y: .625rem;--sdc-neighbors-height: 2rem;--sdc-neighbors-max-width: 10rem;--sdc-neighbors-button-width: 75px;--sdc-neighbors-button-height: 2rem;--sdc-neighbors-button-offset: -31%;--sdc-neighbors-button-icon-color: #ffffff;--sdc-neighbors-button-hover-background-color: rgba(0, 0, 0, .85);--sdc-neighbors-button-text-font-weight: 600;--sdc-neighbors-button-text-font-size: .625rem;--sdc-neighbors-button-text-transform: uppercase;--sdc-neighbors-prefix-opacity: .7;--sdc-neighbors-current-section-loading-font-weight: 600;--sdc-neighbors-current-section-loading-font-size: .75rem;--sdc-neighbors-current-section-text-font-weight: 600;--sdc-neighbors-current-section-text-font-size: .625rem;--sdc-neighbors-current-section-text-transform: uppercase}.neighbors-container{position:relative;display:flex;justify-content:center;align-items:center;background-color:var(--sdc-neighbors-background-color);margin-left:auto;margin-right:auto;padding-left:var(--sdc-neighbors-padding-x);padding-right:var(--sdc-neighbors-padding-x);padding-top:var(--sdc-neighbors-padding-y);padding-bottom:var(--sdc-neighbors-padding-y);border-radius:var(--sdc-neighbors-border-radius);height:var(--sdc-neighbors-height);max-width:var(--sdc-neighbors-max-width);pointer-events:auto}.neighbor-button{position:absolute;width:var(--sdc-neighbors-button-width);height:var(--sdc-neighbors-button-height);display:flex;align-items:center;justify-content:space-between;cursor:pointer;transition:opacity .15s cubic-bezier(.4,0,.2,1)}.neighbor-button-left{left:var(--sdc-neighbors-button-offset);flex-direction:row-reverse}.neighbor-button-right{right:var(--sdc-neighbors-button-offset);flex-direction:row}.neighbor-button.is-none{opacity:0;pointer-events:none}.neighbor-button-icon{display:flex;align-items:center;height:100%;transition:background-color .15s cubic-bezier(.4,0,.2,1)}.neighbor-button:hover .neighbor-button-icon{background-color:var(--sdc-neighbors-button-hover-background-color)}.neighbor-button-icon i{display:block;color:var(--sdc-neighbors-button-icon-color);margin-top:auto;margin-bottom:auto}.neighbor-button-icon svg{width:.875rem;height:.875rem}.neighbor-button-label{opacity:0;transition:opacity .15s cubic-bezier(.4,0,.2,1);display:flex;flex-grow:1;height:100%;align-items:center;background-color:var(--sdc-neighbors-button-hover-background-color)}.neighbor-button:hover .neighbor-button-label{opacity:1}.neighbor-button-left .neighbor-button-label{padding-left:1.25rem;padding-right:.5rem;border-top-left-radius:9999px;border-bottom-left-radius:9999px}.neighbor-button-right .neighbor-button-label{padding-left:.5rem;padding-right:1.25rem;border-top-right-radius:9999px;border-bottom-right-radius:9999px}.neighbor-button-label p{color:var(--sdc-neighbors-text-color);font-size:var(--sdc-neighbors-button-text-font-size);font-weight:var(--sdc-neighbors-button-text-font-weight);text-transform:var(--sdc-neighbors-button-text-transform)}.neighbor-button-label .prefix{opacity:var(--sdc-neighbors-prefix-opacity);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:calc(var(--sdc-neighbors-button-width) - 1.875rem)}.neighbor-button-label .section-number{white-space:nowrap}.current-section-wrapper{display:block;margin-left:auto;margin-right:auto;cursor:default;min-width:0;overflow:hidden}.current-section-loading{font-weight:var(--sdc-neighbors-current-section-loading-font-weight);font-size:var(--sdc-neighbors-current-section-loading-font-size);color:var(--sdc-neighbors-text-color)}.current-section-text{display:flex;font-weight:var(--sdc-neighbors-current-section-text-font-weight);font-size:var(--sdc-neighbors-current-section-text-font-size);color:var(--sdc-neighbors-text-color);text-transform:var(--sdc-neighbors-current-section-text-transform);overflow:hidden;min-width:0}.current-section-text .prefix{opacity:var(--sdc-neighbors-prefix-opacity);flex-shrink:0;white-space:nowrap}.current-section-text .section-number{display:inline-block;max-width:3rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@media(max-width:640px){.current-section-text .prefix,.neighbor-button-label .prefix{display:none}.neighbors-container{max-width:7.5rem}.current-section-text .section-number{max-width:2.5rem}.neighbor-button{width:60px}}@media(max-width:420px){.neighbors-container{max-width:6rem}.current-section-text .section-number{max-width:2rem}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
174
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.4", type: NeighborsComponent, isStandalone: true, selector: "sdc-neighbors", inputs: { translate: { classPropertyName: "translate", publicName: "translate", isSignal: true, isRequired: false, transformFunction: null }, dvmService: { classPropertyName: "dvmService", publicName: "dvmService", isSignal: true, isRequired: true, transformFunction: null }, currentSectionId: { classPropertyName: "currentSectionId", publicName: "currentSectionId", isSignal: true, isRequired: true, transformFunction: null }, hasAvailability: { classPropertyName: "hasAvailability", publicName: "hasAvailability", isSignal: true, isRequired: true, transformFunction: null }, isLoading: { classPropertyName: "isLoading", publicName: "isLoading", isSignal: true, isRequired: false, transformFunction: null }, showElement: { classPropertyName: "showElement", publicName: "showElement", isSignal: true, isRequired: false, transformFunction: null }, modeLr: { classPropertyName: "modeLr", publicName: "modeLr", isSignal: true, isRequired: false, transformFunction: null }, className: { classPropertyName: "className", publicName: "className", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sectionChange: "sectionChange" }, viewQueries: [{ propertyName: "neighborsContainer", first: true, predicate: ["neighborsContainer"], descendants: true }, { propertyName: "currentSection", first: true, predicate: ["currentSection"], descendants: true }, { propertyName: "currentSection3d", first: true, predicate: ["currentSection3d"], descendants: true }, { propertyName: "leftSectionElement", first: true, predicate: ["leftSectionNumber"], descendants: true }, { propertyName: "rightSectionElement", first: true, predicate: ["rightSectionNumber"], descendants: true }], ngImport: i0, template: "<div #neighborsContainer class=\"neighbors-container\" [class]=\"computedClass()\" [class.hidden]=\"!showElement()\">\n <!-- LEFT SECTION BUTTON -->\n @if (leftSection) {\n <div\n class=\"neighbor-button-left neighbor-button\"\n [class.is-none]=\"leftSection === 'none'\"\n tabindex=\"0\"\n (click)=\"navigateToSection(leftSection!)\"\n (keypress.enter)=\"navigateToSection(leftSection!)\">\n <!-- ARROW ICON -->\n <div class=\"neighbor-button-icon\">\n <i>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"3\"\n stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15.75 19.5 8.25 12l7.5-7.5\" />\n </svg>\n </i>\n </div>\n\n <!-- SECTION LABEL -->\n <div class=\"neighbor-button-label\">\n <p>\n <span class=\"prefix\"> {{ modeLr() ? 'Left Section' : 'Section' }}&nbsp; </span>\n @if (leftSection !== 'none' && !modeLr()) {\n <span #leftSectionNumber class=\"section-number\">\n {{ leftSectionLabel() }}\n </span>\n }\n </p>\n </div>\n </div>\n }\n\n <!-- CURRENT SECTION TEXT -->\n <div class=\"current-section-wrapper\">\n @if (isLoading()) {\n <p class=\"current-section-loading\">\n <span>Loading</span>\n </p>\n } @else {\n @if (section) {\n <h3 class=\"current-section-text\">\n <span class=\"prefix\">Section&nbsp;</span>\n <span #currentSection class=\"section-number\">{{ section }}</span>\n </h3>\n }\n }\n </div>\n\n <!-- RIGHT SECTION BUTTON -->\n @if (rightSection) {\n <div\n class=\"neighbor-button-right neighbor-button\"\n [class.is-none]=\"rightSection === 'none'\"\n tabindex=\"1\"\n (click)=\"navigateToSection(rightSection!)\"\n (keypress.enter)=\"navigateToSection(rightSection!)\">\n <!-- ARROW ICON -->\n <div class=\"neighbor-button-icon\">\n <i>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"3\"\n stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m8.25 4.5 7.5 7.5-7.5 7.5\" />\n </svg>\n </i>\n </div>\n\n <!-- SECTION LABEL -->\n <div class=\"neighbor-button-label\">\n <p>\n <span class=\"prefix\"> {{ modeLr() ? 'Right Section' : 'Section' }}&nbsp; </span>\n @if (rightSection !== 'none' && !modeLr()) {\n <span #rightSectionNumber class=\"section-number\">\n {{ rightSectionLabel() }}\n </span>\n }\n </p>\n </div>\n </div>\n }\n</div>\n", styles: [".sdc-neighbors{--sdc-neighbors-background-color: rgba(0, 0, 0, .85);--sdc-neighbors-text-color: #ffffff;--sdc-neighbors-border-radius: 9999px;--sdc-neighbors-padding-x: .75rem;--sdc-neighbors-padding-y: .625rem;--sdc-neighbors-height: 2rem;--sdc-neighbors-max-width: 10rem;--sdc-neighbors-button-width: 75px;--sdc-neighbors-button-height: 2rem;--sdc-neighbors-button-offset: -31%;--sdc-neighbors-button-icon-color: #ffffff;--sdc-neighbors-button-hover-background-color: rgba(0, 0, 0, .85);--sdc-neighbors-button-text-font-weight: 600;--sdc-neighbors-button-text-font-size: .625rem;--sdc-neighbors-button-text-transform: uppercase;--sdc-neighbors-prefix-opacity: .7;--sdc-neighbors-current-section-loading-font-weight: 600;--sdc-neighbors-current-section-loading-font-size: .75rem;--sdc-neighbors-current-section-text-font-weight: 600;--sdc-neighbors-current-section-text-font-size: .625rem;--sdc-neighbors-current-section-text-transform: uppercase}.neighbors-container{position:relative;display:flex;justify-content:center;align-items:center;background-color:var(--sdc-neighbors-background-color);margin-left:auto;margin-right:auto;padding-left:var(--sdc-neighbors-padding-x);padding-right:var(--sdc-neighbors-padding-x);padding-top:var(--sdc-neighbors-padding-y);padding-bottom:var(--sdc-neighbors-padding-y);border-radius:var(--sdc-neighbors-border-radius);height:var(--sdc-neighbors-height);max-width:var(--sdc-neighbors-max-width);pointer-events:auto}.neighbor-button{position:absolute;width:var(--sdc-neighbors-button-width);height:var(--sdc-neighbors-button-height);display:flex;align-items:center;justify-content:space-between;cursor:pointer;transition:opacity .15s cubic-bezier(.4,0,.2,1)}.neighbor-button-left{left:var(--sdc-neighbors-button-offset);flex-direction:row-reverse}.neighbor-button-right{right:var(--sdc-neighbors-button-offset);flex-direction:row}.neighbor-button.is-none{opacity:0;pointer-events:none}.neighbor-button-icon{display:flex;align-items:center;height:100%;transition:background-color .15s cubic-bezier(.4,0,.2,1)}.neighbor-button:hover .neighbor-button-icon{background-color:var(--sdc-neighbors-button-hover-background-color)}.neighbor-button-icon i{display:block;color:var(--sdc-neighbors-button-icon-color);margin-top:auto;margin-bottom:auto}.neighbor-button-icon svg{width:.875rem;height:.875rem}.neighbor-button-label{opacity:0;transition:opacity .15s cubic-bezier(.4,0,.2,1);display:flex;flex-grow:1;height:100%;align-items:center;background-color:var(--sdc-neighbors-button-hover-background-color)}.neighbor-button:hover .neighbor-button-label{opacity:1}.neighbor-button-left .neighbor-button-label{padding-left:1.25rem;padding-right:.5rem;border-top-left-radius:9999px;border-bottom-left-radius:9999px}.neighbor-button-right .neighbor-button-label{padding-left:.5rem;padding-right:1.25rem;border-top-right-radius:9999px;border-bottom-right-radius:9999px}.neighbor-button-label p{color:var(--sdc-neighbors-text-color);font-size:var(--sdc-neighbors-button-text-font-size);font-weight:var(--sdc-neighbors-button-text-font-weight);text-transform:var(--sdc-neighbors-button-text-transform)}.neighbor-button-label .prefix{opacity:var(--sdc-neighbors-prefix-opacity);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:calc(var(--sdc-neighbors-button-width) - 1.875rem)}.neighbor-button-label .section-number{white-space:nowrap}.current-section-wrapper{display:block;margin-left:auto;margin-right:auto;cursor:default;min-width:0;overflow:hidden}.current-section-loading{font-weight:var(--sdc-neighbors-current-section-loading-font-weight);font-size:var(--sdc-neighbors-current-section-loading-font-size);color:var(--sdc-neighbors-text-color)}.current-section-text{display:flex;font-weight:var(--sdc-neighbors-current-section-text-font-weight);font-size:var(--sdc-neighbors-current-section-text-font-size);color:var(--sdc-neighbors-text-color);text-transform:var(--sdc-neighbors-current-section-text-transform);overflow:hidden;min-width:0}.current-section-text .prefix{opacity:var(--sdc-neighbors-prefix-opacity);flex-shrink:0;white-space:nowrap}.current-section-text .section-number{display:inline-block;max-width:3rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@media(max-width:640px){.current-section-text .prefix,.neighbor-button-label .prefix{display:none}.neighbors-container{max-width:7.5rem}.current-section-text .section-number{max-width:2.5rem}.neighbor-button{width:60px}}@media(max-width:420px){.neighbors-container{max-width:6rem}.current-section-text .section-number{max-width:2rem}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
176
175
  }
177
176
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImport: i0, type: NeighborsComponent, decorators: [{
178
177
  type: Component,
@@ -192,7 +191,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.4", ngImpor
192
191
  }], rightSectionElement: [{
193
192
  type: ViewChild,
194
193
  args: ['rightSectionNumber', { static: false }]
195
- }], neighborsData: [{ type: i0.Input, args: [{ isSignal: true, alias: "neighborsData", required: true }] }], currentSectionId: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentSectionId", required: true }] }], translateTdcToMmc: [{ type: i0.Input, args: [{ isSignal: true, alias: "translateTdcToMmc", required: true }] }], translateMmcToTdc: [{ type: i0.Input, args: [{ isSignal: true, alias: "translateMmcToTdc", required: true }] }], hasAvailability: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasAvailability", required: true }] }], isLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLoading", required: false }] }], showElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "showElement", required: false }] }], modeLr: [{ type: i0.Input, args: [{ isSignal: true, alias: "modeLr", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], sectionChange: [{
194
+ }], translate: [{ type: i0.Input, args: [{ isSignal: true, alias: "translate", required: false }] }], dvmService: [{ type: i0.Input, args: [{ isSignal: true, alias: "dvmService", required: true }] }], currentSectionId: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentSectionId", required: true }] }], hasAvailability: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasAvailability", required: true }] }], isLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLoading", required: false }] }], showElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "showElement", required: false }] }], modeLr: [{ type: i0.Input, args: [{ isSignal: true, alias: "modeLr", required: false }] }], className: [{ type: i0.Input, args: [{ isSignal: true, alias: "className", required: false }] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], sectionChange: [{
196
195
  type: Output
197
196
  }] } });
198
197
 
@@ -1 +1 @@
1
- {"version":3,"file":"3ddv-software-division-components-dvm-neighbors.mjs","sources":["../../dvm/neighbors/neighbors.component.ts","../../dvm/neighbors/neighbors.component.html","../../dvm/neighbors/3ddv-software-division-components-dvm-neighbors.ts"],"sourcesContent":["import { ThemeClass } from '@3ddv/software-division-components/shared';\r\nimport {\r\n ChangeDetectionStrategy,\r\n ChangeDetectorRef,\r\n Component,\r\n computed,\r\n ElementRef,\r\n EventEmitter,\r\n inject,\r\n input,\r\n OnDestroy,\r\n Output,\r\n ViewChild,\r\n} from '@angular/core';\r\nimport { Subscription } from 'rxjs';\r\nimport { Direction, HasAvailabilityFn, NeighborsData, SectionChangeEvent, TranslateSectionIdFn } from './types';\r\n\r\n@Component({\r\n selector: 'sdc-neighbors',\r\n standalone: true,\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n templateUrl: './neighbors.component.html',\r\n styleUrl: './neighbors.component.css',\r\n})\r\nexport class NeighborsComponent implements OnDestroy {\r\n // VIEWCHILD\r\n @ViewChild('neighborsContainer')\r\n public readonly neighborsContainer!: ElementRef<HTMLDivElement>;\r\n\r\n @ViewChild('currentSection', { static: false })\r\n public readonly currentSection!: ElementRef<HTMLSpanElement>;\r\n\r\n @ViewChild('currentSection3d', { static: false })\r\n public readonly currentSection3d!: ElementRef<HTMLSpanElement>;\r\n\r\n @ViewChild('leftSectionNumber', { static: false })\r\n public readonly leftSectionElement!: ElementRef<HTMLSpanElement>;\r\n\r\n @ViewChild('rightSectionNumber', { static: false })\r\n public readonly rightSectionElement!: ElementRef<HTMLSpanElement>;\r\n\r\n // SERVICES changes\r\n private readonly cdr: ChangeDetectorRef = inject(ChangeDetectorRef);\r\n\r\n // REQUIRED INPUTS\r\n public readonly neighborsData = input.required<NeighborsData>();\r\n public readonly currentSectionId = input.required<string | null>();\r\n public readonly translateTdcToMmc = input.required<TranslateSectionIdFn>();\r\n public readonly translateMmcToTdc = input.required<TranslateSectionIdFn>();\r\n public readonly hasAvailability = input.required<HasAvailabilityFn>();\r\n\r\n // OPTIONAL INPUTS\r\n public readonly isLoading = input<boolean>(false);\r\n public readonly showElement = input<boolean>(true);\r\n public readonly modeLr = input<boolean>(false);\r\n public readonly className = input<string>('');\r\n public readonly theme = input<ThemeClass>('theme-sdc');\r\n\r\n // OUTPUTS\r\n @Output() sectionChange = new EventEmitter<SectionChangeEvent>();\r\n\r\n /**\r\n * Computed class string that combines theme and user classes.\r\n */\r\n protected readonly computedClass = computed(() => {\r\n const themeClass = this.theme();\r\n const className = this.className();\r\n return Array.from(new Set(['sdc-neighbors', themeClass, className]))\r\n .filter(Boolean)\r\n .join(' ');\r\n });\r\n\r\n // COMPONENT STATE\r\n private readonly subscriptions: Subscription[] = [];\r\n\r\n // COMPUTED STATE\r\n protected readonly leftSectionId = computed(() => {\r\n try {\r\n const currentId = this.currentSectionId();\r\n if (!currentId) return null;\r\n return this.findAvailableNeighbor('prev', currentId);\r\n } catch (error) {\r\n return null;\r\n }\r\n });\r\n\r\n protected readonly rightSectionId = computed(() => {\r\n try {\r\n const currentId = this.currentSectionId();\r\n if (!currentId) return null;\r\n return this.findAvailableNeighbor('next', currentId);\r\n } catch (error) {\r\n return null;\r\n }\r\n });\r\n\r\n protected readonly currentSectionLabel = computed(() => {\r\n try {\r\n const currentId = this.currentSectionId();\r\n if (!currentId) return 'Loading';\r\n\r\n // Translate TDC ID to MMC ID for display\r\n const mmcId = this.translateTdcToMmc()(currentId);\r\n if (!mmcId) return currentId; // Fallback to TDC ID if translation fails\r\n\r\n // Extract section number from MMC ID (assuming format like \"S_31\" or similar)\r\n return mmcId.replace(/^S_/, '');\r\n } catch (error) {\r\n return 'Loading';\r\n }\r\n });\r\n\r\n protected readonly leftSectionLabel = computed(() => {\r\n try {\r\n const leftId = this.leftSectionId();\r\n if (!leftId) return null;\r\n\r\n // Translate TDC ID to MMC ID for display\r\n const mmcId = this.translateTdcToMmc()(leftId);\r\n if (!mmcId) return leftId; // Fallback to TDC ID if translation fails\r\n\r\n // Extract section number from MMC ID\r\n return mmcId.replace(/^S_/, '');\r\n } catch (error) {\r\n return null;\r\n }\r\n });\r\n\r\n protected readonly rightSectionLabel = computed(() => {\r\n try {\r\n const rightId = this.rightSectionId();\r\n if (!rightId) return null;\r\n\r\n // Translate TDC ID to MMC ID for display\r\n const mmcId = this.translateTdcToMmc()(rightId);\r\n if (!mmcId) return rightId; // Fallback to TDC ID if translation fails\r\n\r\n // Extract section number from MMC ID\r\n return mmcId.replace(/^S_/, '');\r\n } catch (error) {\r\n return null;\r\n }\r\n });\r\n\r\n // NEIGHBOR RESOLUTION ALGORITHM\r\n private findAvailableNeighbor(type: Direction, currentSectionTdcId: string): string | null {\r\n try {\r\n const neighborKey = type === 'prev' ? 'l' : 'r';\r\n const noNeighborValue = 'none';\r\n\r\n // 1. Translate TDC → MMC\r\n const currentSectionMmcId = this.translateTdcToMmc()(currentSectionTdcId);\r\n if (!currentSectionMmcId) return null;\r\n\r\n // 2. Look up neighbor in data\r\n const neighbors = this.neighborsData();\r\n const neighbor = neighbors[currentSectionMmcId];\r\n const neighborSectionMmcId = neighbor ? neighbor[neighborKey] : noNeighborValue;\r\n\r\n // 3. Handle 'none' boundary\r\n if (neighborSectionMmcId === noNeighborValue) {\r\n return null;\r\n }\r\n\r\n // 4. Translate MMC → TDC\r\n const neighborSectionTdcId = this.translateMmcToTdc()(neighborSectionMmcId);\r\n if (!neighborSectionTdcId) return null;\r\n\r\n // 5. Check availability\r\n if (this.hasAvailability()(neighborSectionTdcId)) {\r\n return neighborSectionTdcId;\r\n }\r\n\r\n // 6. Recursively find next available (skip unavailable sections)\r\n return this.findAvailableNeighbor(type, neighborSectionTdcId);\r\n } catch (error) {\r\n return null;\r\n }\r\n }\r\n\r\n // GETTERS\r\n public get leftSection(): string | null {\r\n return this.leftSectionId();\r\n }\r\n\r\n public get rightSection(): string | null {\r\n return this.rightSectionId();\r\n }\r\n\r\n public get section(): string | null {\r\n return this.currentSectionLabel();\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.subscriptions.forEach((sub: Subscription): void => sub.unsubscribe());\r\n }\r\n\r\n // METHODS\r\n public navigateToSection(section: string): void {\r\n if (section === 'none' || !section) {\r\n return;\r\n }\r\n\r\n const leftId = this.leftSectionId();\r\n const rightId = this.rightSectionId();\r\n\r\n let direction: Direction;\r\n if (section === leftId) {\r\n direction = 'prev';\r\n } else if (section === rightId) {\r\n direction = 'next';\r\n } else {\r\n return;\r\n }\r\n\r\n this.sectionChange.emit({ direction, sectionId: section });\r\n }\r\n}\r\n","<div #neighborsContainer class=\"neighbors-container\" [class]=\"computedClass()\" [class.hidden]=\"!showElement()\">\n <!-- LEFT SECTION BUTTON -->\n @if (leftSection) {\n <div\n class=\"neighbor-button-left neighbor-button\"\n [class.is-none]=\"leftSection === 'none'\"\n tabindex=\"0\"\n (click)=\"navigateToSection(leftSection!)\"\n (keypress.enter)=\"navigateToSection(leftSection!)\">\n <!-- ARROW ICON -->\n <div class=\"neighbor-button-icon\">\n <i>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"3\"\n stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15.75 19.5 8.25 12l7.5-7.5\" />\n </svg>\n </i>\n </div>\n\n <!-- SECTION LABEL -->\n <div class=\"neighbor-button-label\">\n <p>\n <span class=\"prefix\"> {{ modeLr() ? 'Left Section' : 'Section' }}&nbsp; </span>\n @if (leftSection !== 'none' && !modeLr()) {\n <span #leftSectionNumber class=\"section-number\">\n {{ leftSectionLabel() }}\n </span>\n }\n </p>\n </div>\n </div>\n }\n\n <!-- CURRENT SECTION TEXT -->\n <div class=\"current-section-wrapper\">\n @if (isLoading()) {\n <p class=\"current-section-loading\">\n <span>Loading</span>\n </p>\n } @else {\n @if (section) {\n <h3 class=\"current-section-text\">\n <span class=\"prefix\">Section&nbsp;</span>\n <span #currentSection class=\"section-number\">{{ section }}</span>\n </h3>\n }\n }\n </div>\n\n <!-- RIGHT SECTION BUTTON -->\n @if (rightSection) {\n <div\n class=\"neighbor-button-right neighbor-button\"\n [class.is-none]=\"rightSection === 'none'\"\n tabindex=\"1\"\n (click)=\"navigateToSection(rightSection!)\"\n (keypress.enter)=\"navigateToSection(rightSection!)\">\n <!-- ARROW ICON -->\n <div class=\"neighbor-button-icon\">\n <i>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"3\"\n stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m8.25 4.5 7.5 7.5-7.5 7.5\" />\n </svg>\n </i>\n </div>\n\n <!-- SECTION LABEL -->\n <div class=\"neighbor-button-label\">\n <p>\n <span class=\"prefix\"> {{ modeLr() ? 'Right Section' : 'Section' }}&nbsp; </span>\n @if (rightSection !== 'none' && !modeLr()) {\n <span #rightSectionNumber class=\"section-number\">\n {{ rightSectionLabel() }}\n </span>\n }\n </p>\n </div>\n </div>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"3ddv-software-division-components-dvm-neighbors.mjs","sources":["../../dvm/neighbors/neighbors.component.ts","../../dvm/neighbors/neighbors.component.html","../../dvm/neighbors/3ddv-software-division-components-dvm-neighbors.ts"],"sourcesContent":["import { ThemeClass } from '@3ddv/software-division-components/shared';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n EventEmitter,\n input,\n OnDestroy,\n Output,\n signal,\n ViewChild,\n} from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport { Direction, HasAvailabilityFn, NeighborsDvmService, SectionChangeEvent, TranslateSectionIdFn } from './types';\n\n@Component({\n selector: 'sdc-neighbors',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './neighbors.component.html',\n styleUrl: './neighbors.component.css',\n})\nexport class NeighborsComponent implements OnDestroy {\n // VIEWCHILD\n @ViewChild('neighborsContainer')\n public readonly neighborsContainer!: ElementRef<HTMLDivElement>;\n\n @ViewChild('currentSection', { static: false })\n public readonly currentSection!: ElementRef<HTMLSpanElement>;\n\n @ViewChild('currentSection3d', { static: false })\n public readonly currentSection3d!: ElementRef<HTMLSpanElement>;\n\n @ViewChild('leftSectionNumber', { static: false })\n public readonly leftSectionElement!: ElementRef<HTMLSpanElement>;\n\n @ViewChild('rightSectionNumber', { static: false })\n public readonly rightSectionElement!: ElementRef<HTMLSpanElement>;\n\n // REQUIRED INPUTS\n public readonly translate = input<TranslateSectionIdFn>((id: string) => id);\n public readonly dvmService = input.required<NeighborsDvmService>();\n public readonly currentSectionId = input.required<string | null>();\n public readonly hasAvailability = input.required<HasAvailabilityFn>();\n\n // OPTIONAL INPUTS\n public readonly isLoading = input<boolean>(false);\n public readonly showElement = input<boolean>(true);\n public readonly modeLr = input<boolean>(false);\n public readonly className = input<string>('');\n public readonly theme = input<ThemeClass>('theme-sdc');\n\n // OUTPUTS\n @Output() sectionChange = new EventEmitter<SectionChangeEvent>();\n\n /**\n * Computed class string that combines theme and user classes.\n */\n protected readonly computedClass = computed(() => {\n const themeClass = this.theme();\n const className = this.className();\n return Array.from(new Set(['sdc-neighbors', themeClass, className]))\n .filter(Boolean)\n .join(' ');\n });\n\n // COMPONENT STATE\n private readonly subscriptions: Subscription[] = [];\n private readonly relatedMaps = signal<Record<string, { l?: string; r?: string }>>({});\n private readonly fetchingIds = new Set<string>();\n\n // COMPUTED STATE\n protected readonly leftSectionId = computed(() => {\n try {\n const currentId = this.currentSectionId();\n if (!currentId) return null;\n return this.findAvailableNeighbor('prev', currentId);\n } catch (error) {\n return null;\n }\n });\n\n protected readonly rightSectionId = computed(() => {\n try {\n const currentId = this.currentSectionId();\n if (!currentId) return null;\n return this.findAvailableNeighbor('next', currentId);\n } catch (error) {\n return null;\n }\n });\n\n protected readonly currentSectionLabel = computed(() => {\n try {\n const currentId = this.currentSectionId();\n if (!currentId) return 'Loading';\n return this.translate()(currentId) || currentId;\n } catch (error) {\n return 'Loading';\n }\n });\n\n protected readonly leftSectionLabel = computed(() => {\n try {\n const leftId = this.leftSectionId();\n if (!leftId) return null;\n return this.translate()(leftId) || leftId;\n } catch (error) {\n return null;\n }\n });\n\n protected readonly rightSectionLabel = computed(() => {\n try {\n const rightId = this.rightSectionId();\n if (!rightId) return null;\n return this.translate()(rightId) || rightId;\n } catch (error) {\n return null;\n }\n });\n\n // NEIGHBOR RESOLUTION ALGORITHM\n private findAvailableNeighbor(type: Direction, currentSectionTdcId: string): string | null {\n try {\n const neighborKey = type === 'prev' ? 'l' : 'r';\n const noNeighborValue = 'none';\n\n const neighbor = this.relatedMaps()[currentSectionTdcId] ?? null;\n\n if (!neighbor) {\n this.fetchSection(currentSectionTdcId);\n return null;\n }\n\n const neighborSectionTdcId = neighbor[neighborKey] ?? noNeighborValue;\n\n // Handle 'none' boundary\n if (!neighborSectionTdcId || neighborSectionTdcId === noNeighborValue) {\n return null;\n }\n\n // Skip general admission sections — not navigable as neighbors\n if (neighborSectionTdcId.includes('general_admission')) {\n return this.findAvailableNeighbor(type, neighborSectionTdcId);\n }\n\n // Check availability using TDC ID\n if (this.hasAvailability()(neighborSectionTdcId)) {\n return neighborSectionTdcId;\n }\n\n // Recursively find next available (skip unavailable sections)\n return this.findAvailableNeighbor(type, neighborSectionTdcId);\n } catch (error) {\n return null;\n }\n }\n\n private fetchSection(sectionId: string): void {\n if (this.relatedMaps()[sectionId] || this.fetchingIds.has(sectionId)) {\n return;\n }\n this.fetchingIds.add(sectionId);\n void this.dvmService().getRelatedMapsForSection(sectionId).then(related => {\n this.fetchingIds.delete(sectionId);\n if (!related) return;\n const entry: { l?: string; r?: string } = {};\n if (related['left']?.map_id) entry.l = related['left'].map_id;\n if (related['right']?.map_id) entry.r = related['right'].map_id;\n this.relatedMaps.update(prev => ({ ...prev, [sectionId]: entry }));\n });\n }\n\n // GETTERS\n public get leftSection(): string | null {\n return this.leftSectionId();\n }\n\n public get rightSection(): string | null {\n return this.rightSectionId();\n }\n\n public get section(): string | null {\n return this.currentSectionLabel();\n }\n\n ngOnDestroy(): void {\n this.subscriptions.forEach((sub: Subscription): void => sub.unsubscribe());\n }\n\n // METHODS\n public navigateToSection(section: string): void {\n if (section === 'none' || !section) {\n return;\n }\n\n const leftId = this.leftSectionId();\n const rightId = this.rightSectionId();\n\n let direction: Direction;\n if (section === leftId) {\n direction = 'prev';\n } else if (section === rightId) {\n direction = 'next';\n } else {\n return;\n }\n\n this.sectionChange.emit({ direction, sectionId: section });\n }\n}\n","<div #neighborsContainer class=\"neighbors-container\" [class]=\"computedClass()\" [class.hidden]=\"!showElement()\">\n <!-- LEFT SECTION BUTTON -->\n @if (leftSection) {\n <div\n class=\"neighbor-button-left neighbor-button\"\n [class.is-none]=\"leftSection === 'none'\"\n tabindex=\"0\"\n (click)=\"navigateToSection(leftSection!)\"\n (keypress.enter)=\"navigateToSection(leftSection!)\">\n <!-- ARROW ICON -->\n <div class=\"neighbor-button-icon\">\n <i>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"3\"\n stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M15.75 19.5 8.25 12l7.5-7.5\" />\n </svg>\n </i>\n </div>\n\n <!-- SECTION LABEL -->\n <div class=\"neighbor-button-label\">\n <p>\n <span class=\"prefix\"> {{ modeLr() ? 'Left Section' : 'Section' }}&nbsp; </span>\n @if (leftSection !== 'none' && !modeLr()) {\n <span #leftSectionNumber class=\"section-number\">\n {{ leftSectionLabel() }}\n </span>\n }\n </p>\n </div>\n </div>\n }\n\n <!-- CURRENT SECTION TEXT -->\n <div class=\"current-section-wrapper\">\n @if (isLoading()) {\n <p class=\"current-section-loading\">\n <span>Loading</span>\n </p>\n } @else {\n @if (section) {\n <h3 class=\"current-section-text\">\n <span class=\"prefix\">Section&nbsp;</span>\n <span #currentSection class=\"section-number\">{{ section }}</span>\n </h3>\n }\n }\n </div>\n\n <!-- RIGHT SECTION BUTTON -->\n @if (rightSection) {\n <div\n class=\"neighbor-button-right neighbor-button\"\n [class.is-none]=\"rightSection === 'none'\"\n tabindex=\"1\"\n (click)=\"navigateToSection(rightSection!)\"\n (keypress.enter)=\"navigateToSection(rightSection!)\">\n <!-- ARROW ICON -->\n <div class=\"neighbor-button-icon\">\n <i>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke-width=\"3\"\n stroke=\"currentColor\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"m8.25 4.5 7.5 7.5-7.5 7.5\" />\n </svg>\n </i>\n </div>\n\n <!-- SECTION LABEL -->\n <div class=\"neighbor-button-label\">\n <p>\n <span class=\"prefix\"> {{ modeLr() ? 'Right Section' : 'Section' }}&nbsp; </span>\n @if (rightSection !== 'none' && !modeLr()) {\n <span #rightSectionNumber class=\"section-number\">\n {{ rightSectionLabel() }}\n </span>\n }\n </p>\n </div>\n </div>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -839,7 +839,8 @@ class PopoverComponent {
839
839
  if (!viewer3dService?.isInitialized()) {
840
840
  return;
841
841
  }
842
- viewer3dService.getThumbnail(options, true).subscribe((thumbnailUrl) => {
842
+ // @ts-ignore
843
+ void viewer3dService.getThumbnail(options, true).then((thumbnailUrl) => {
843
844
  this.thumbnail = thumbnailUrl;
844
845
  this.cdr.markForCheck();
845
846
  });