@panoramax/web-viewer 5.0.0-develop-d7206514 → 5.0.0-develop-d26305dd

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 (152) hide show
  1. package/build/bundle.cjs +3399 -0
  2. package/build/bundle.cjs.map +1 -0
  3. package/build/bundle_photoviewer.cjs +2510 -0
  4. package/build/bundle_photoviewer.cjs.map +1 -0
  5. package/build/cjs/index.js +1 -1
  6. package/build/cjs/index_photoviewer.js +1 -1
  7. package/build/components/core/Basic.css +56 -0
  8. package/build/components/core/Basic.js +378 -0
  9. package/build/components/core/CoverageMap.css +10 -0
  10. package/build/components/core/CoverageMap.js +169 -0
  11. package/build/components/core/Editor.css +33 -0
  12. package/build/components/core/Editor.js +398 -0
  13. package/build/components/core/PhotoViewer.css +70 -0
  14. package/build/components/core/PhotoViewer.js +650 -0
  15. package/build/components/core/Viewer.css +130 -0
  16. package/build/components/core/Viewer.js +711 -0
  17. package/build/components/core/index.js +10 -0
  18. package/build/components/index.js +11 -0
  19. package/build/components/index_photoviewer.js +6 -0
  20. package/build/components/layout/BottomDrawer.js +258 -0
  21. package/build/components/layout/CorneredGrid.js +143 -0
  22. package/build/components/layout/Mini.js +121 -0
  23. package/build/components/layout/Tabs.js +140 -0
  24. package/build/components/layout/index.js +9 -0
  25. package/build/components/menus/LocationPrecisionDoc.js +42 -0
  26. package/build/components/menus/MapBackground.js +110 -0
  27. package/build/components/menus/MapFilters.js +567 -0
  28. package/build/components/menus/MapLayers.js +238 -0
  29. package/build/components/menus/MapLegend.js +68 -0
  30. package/build/components/menus/MiniPictureLegend.js +73 -0
  31. package/build/components/menus/PictureLegend.js +379 -0
  32. package/build/components/menus/PictureMetadata.js +380 -0
  33. package/build/components/menus/PlayerOptions.js +93 -0
  34. package/build/components/menus/QualityScoreDoc.js +42 -0
  35. package/build/components/menus/ReportForm.js +132 -0
  36. package/build/components/menus/SemanticsDoc.js +38 -0
  37. package/build/components/menus/SemanticsDownload.js +33 -0
  38. package/build/components/menus/SemanticsFilters.js +153 -0
  39. package/build/components/menus/SemanticsList.js +413 -0
  40. package/build/components/menus/SemanticsMetadata.js +368 -0
  41. package/build/components/menus/Share.js +105 -0
  42. package/build/components/menus/index.js +22 -0
  43. package/build/components/menus/index_photoviewer.js +11 -0
  44. package/build/components/styles.js +557 -0
  45. package/build/components/ui/AnnotationsSwitch.js +159 -0
  46. package/build/components/ui/Button.js +77 -0
  47. package/build/components/ui/ButtonGroup.css +59 -0
  48. package/build/components/ui/ButtonGroup.js +69 -0
  49. package/build/components/ui/CopyButton.js +110 -0
  50. package/build/components/ui/Grade.js +54 -0
  51. package/build/components/ui/GradeFilter.js +122 -0
  52. package/build/components/ui/IconSwitch.js +193 -0
  53. package/build/components/ui/LinkButton.js +67 -0
  54. package/build/components/ui/ListGroup.js +66 -0
  55. package/build/components/ui/ListItem.js +90 -0
  56. package/build/components/ui/Loader.js +203 -0
  57. package/build/components/ui/Map.css +63 -0
  58. package/build/components/ui/Map.js +853 -0
  59. package/build/components/ui/MapMore.js +175 -0
  60. package/build/components/ui/Photo.css +50 -0
  61. package/build/components/ui/Photo.js +1502 -0
  62. package/build/components/ui/Popup.js +145 -0
  63. package/build/components/ui/ProgressBar.js +104 -0
  64. package/build/components/ui/QualityScore.js +147 -0
  65. package/build/components/ui/SearchBar.js +374 -0
  66. package/build/components/ui/SemanticsEditor.js +191 -0
  67. package/build/components/ui/SemanticsTable.js +88 -0
  68. package/build/components/ui/Switch.js +139 -0
  69. package/build/components/ui/TogglableGroup.js +157 -0
  70. package/build/components/ui/index.js +29 -0
  71. package/build/components/ui/index_photoviewer.js +21 -0
  72. package/build/components/ui/widgets/CopyCoordinates.js +75 -0
  73. package/build/components/ui/widgets/GeoSearch.css +21 -0
  74. package/build/components/ui/widgets/GeoSearch.js +150 -0
  75. package/build/components/ui/widgets/Legend.js +190 -0
  76. package/build/components/ui/widgets/LevelSelect.css +51 -0
  77. package/build/components/ui/widgets/LevelSelect.js +143 -0
  78. package/build/components/ui/widgets/MapFiltersButton.js +114 -0
  79. package/build/components/ui/widgets/MapLayersButton.js +79 -0
  80. package/build/components/ui/widgets/OSMEditors.js +155 -0
  81. package/build/components/ui/widgets/PictureLegendActions.js +99 -0
  82. package/build/components/ui/widgets/Player.css +7 -0
  83. package/build/components/ui/widgets/Player.js +154 -0
  84. package/build/components/ui/widgets/SemanticsFiltersButton.js +65 -0
  85. package/build/components/ui/widgets/Zoom.js +84 -0
  86. package/build/components/ui/widgets/index.js +16 -0
  87. package/build/components/ui/widgets/index_photoviewer.js +7 -0
  88. package/build/esm/components/core/Basic.js +1 -1
  89. package/build/img/arrow_360.svg +14 -0
  90. package/build/img/arrow_flat.svg +11 -0
  91. package/build/img/arrow_triangle.svg +9 -0
  92. package/build/img/arrow_turn.svg +8 -0
  93. package/build/img/bg_aerial.jpg +0 -0
  94. package/build/img/bg_streets.jpg +0 -0
  95. package/build/img/loader_base.jpg +0 -0
  96. package/build/img/logo_dead.svg +91 -0
  97. package/build/img/marker.svg +17 -0
  98. package/build/img/marker_blue.svg +20 -0
  99. package/build/img/osm.svg +49 -0
  100. package/build/img/panoramax.svg +13 -0
  101. package/build/img/switch_big.svg +54 -0
  102. package/build/img/switch_mini.svg +48 -0
  103. package/build/img/wd.svg +1 -0
  104. package/build/index_photoviewer.js +4 -0
  105. package/build/package.json +148 -0
  106. package/build/servers.js +14 -0
  107. package/build/translations/ar.json +1 -0
  108. package/build/translations/be.json +257 -0
  109. package/build/translations/br.json +81 -0
  110. package/build/translations/cy.json +117 -0
  111. package/build/translations/da.json +300 -0
  112. package/build/translations/de.json +309 -0
  113. package/build/translations/en.json +294 -0
  114. package/build/translations/eo.json +235 -0
  115. package/build/translations/es.json +292 -0
  116. package/build/translations/fi.json +1 -0
  117. package/build/translations/fr.json +294 -0
  118. package/build/translations/hr.json +294 -0
  119. package/build/translations/hu.json +294 -0
  120. package/build/translations/it.json +306 -0
  121. package/build/translations/ja.json +182 -0
  122. package/build/translations/ko.json +1 -0
  123. package/build/translations/nl.json +305 -0
  124. package/build/translations/nn.json +1 -0
  125. package/build/translations/pl.json +169 -0
  126. package/build/translations/pt.json +296 -0
  127. package/build/translations/pt_BR.json +304 -0
  128. package/build/translations/sv.json +182 -0
  129. package/build/translations/ti.json +9 -0
  130. package/build/translations/tr.json +297 -0
  131. package/build/translations/uk.json +268 -0
  132. package/build/translations/zh_Hant.json +309 -0
  133. package/build/utils/API.js +928 -0
  134. package/build/utils/InitParameters.js +521 -0
  135. package/build/utils/MapStyleComposer.js +889 -0
  136. package/build/utils/PanoraMapProtocol.js +49 -0
  137. package/build/utils/PhotoAdapter.js +49 -0
  138. package/build/utils/PresetsManager.js +148 -0
  139. package/build/utils/SemanticsMapProtocol.js +144 -0
  140. package/build/utils/URLHandler.js +426 -0
  141. package/build/utils/geocoder.js +203 -0
  142. package/build/utils/i18n.js +128 -0
  143. package/build/utils/index.js +17 -0
  144. package/build/utils/index_photoviewer.js +14 -0
  145. package/build/utils/indoor.js +200 -0
  146. package/build/utils/map.js +788 -0
  147. package/build/utils/picture.js +507 -0
  148. package/build/utils/semantics.js +321 -0
  149. package/build/utils/services.js +148 -0
  150. package/build/utils/utils.js +433 -0
  151. package/build/utils/widgets.js +110 -0
  152. package/package.json +1 -1
@@ -0,0 +1,238 @@
1
+ import { LitElement, css, html, nothing } from "lit";
2
+ import { fa, onceParentAvailable } from "../../utils/widgets.js";
3
+ import { faSvg, select, titles } from "../styles.js";
4
+ import { COLORS, GPS_VALUES } from "../../utils/utils.js";
5
+ import { faEarthEurope, faInfoCircle, faPalette } from "@fortawesome/free-solid-svg-icons";
6
+ import { MAP_THEMES_STYLES } from "../../utils/map.js";
7
+ import { DISABLED_LEVEL, initIndoorEqualOnMap } from "../../utils/indoor.js";
8
+ import { BASEMAPS_DEFAULT_IDS } from "../../utils/MapStyleComposer.js";
9
+
10
+ /**
11
+ * Map Layers menu allows user to select background and map theme.
12
+ * @class Panoramax.components.menus.MapLayers
13
+ * @element pnx-map-layers-menu
14
+ * @extends [lit.LitElement](https://lit.dev/docs/api/LitElement/)
15
+ * @example
16
+ * ```html
17
+ * <pnx-map-layers-menu _parent=${viewer} />
18
+ * ```
19
+ */
20
+ export default class MapLayers extends LitElement {
21
+ /** @private */
22
+ static styles = [ faSvg, titles, select, css`
23
+ .legend {
24
+ display: flex;
25
+ flex-wrap: wrap;
26
+ margin-top: 5px;
27
+ justify-content: space-evenly;
28
+ }
29
+
30
+ .legend-entry {
31
+ margin: 10px 8px 5px 0px;
32
+ line-height: 12px;
33
+ display: flex;
34
+ align-items: center;
35
+ font-size: 1.0em;
36
+ }
37
+
38
+ .legend-color {
39
+ display: inline-block;
40
+ width: 15px;
41
+ height: 15px;
42
+ border-radius: 3px;
43
+ margin-right: 5px;
44
+ }
45
+
46
+ .legend-score {
47
+ justify-content: center;
48
+ gap: 0;
49
+ }
50
+ ` ];
51
+
52
+ /** @private */
53
+ static properties = {
54
+ theme: {state: true},
55
+ };
56
+
57
+ /** @private */
58
+ connectedCallback() {
59
+ super.connectedCallback();
60
+ onceParentAvailable(this).then(() => this._parent?.onceMapReady?.().then(() => {
61
+ this.theme = this._parent.mapStyleComposer.panoramaxTheme;
62
+ this._parent.mapStyleComposer.addEventListener("theme-changed", e => this.theme = e.detail.theme);
63
+ this._parent.mapStyleComposer.addEventListener("panoramax-changed", () => this.requestUpdate()); // Don't bind(this) on requestUpdate, doesnt work
64
+ this._parent.mapStyleComposer.addEventListener("basemap-changed", () => this.requestUpdate());
65
+ this._parent.map.indoorEqual?.on("levelschange", () => this.requestUpdate());
66
+ this._parent.map.indoorEqual?.on("levelchange", () => this.requestUpdate());
67
+ }));
68
+ }
69
+
70
+ /** @private */
71
+ _onIndoorSwitchChange(e) {
72
+ if(this._parent?.map?.indoorEqual) {
73
+ this._parent.map.indoorEqual.setLevel(e.target.checked ? "0" : DISABLED_LEVEL);
74
+ }
75
+ else {
76
+ initIndoorEqualOnMap(this._parent.map, true);
77
+ }
78
+ }
79
+
80
+ /** @private */
81
+ _onThemeSelect(e) {
82
+ this.theme = e.target.value;
83
+ this._parent?.mapStyleComposer.setPanoramaxTheme(this.theme);
84
+ }
85
+
86
+ /** @private */
87
+ _onBgChange(e) {
88
+ this._parent?.mapStyleComposer.switchBasemap(e.target.value || "streets");
89
+ }
90
+
91
+ /** @private */
92
+ render() {
93
+ const parts = [];
94
+ const hasIndoor = this._parent?.map?.indoorEqual || this._parent?.map?._options?.indoor?.visible === false;
95
+
96
+ // Background selector
97
+ if(this._parent?.mapStyleComposer?.hasManyBasemaps?.()) {
98
+ parts.push(html`
99
+ <h4>${fa(faEarthEurope)} ${this._parent?._t.pnx.map_background}</h4>
100
+ `);
101
+
102
+ if(this._parent.mapStyleComposer.hasStreetsAerialBasemaps()) {
103
+ parts.push(html`
104
+ <pnx-map-background ._parent=${this._parent} style="margin-bottom: 10px"></pnx-map-background>
105
+ `);
106
+ }
107
+ if(this._parent.mapStyleComposer.hasComplementaryBasemaps()) {
108
+ const defaultOpt = html`
109
+ <option value="" .selected=${BASEMAPS_DEFAULT_IDS.includes(this._parent.mapStyleComposer.basemap)}>
110
+ ${this._parent.mapStyleComposer.hasStreetsAerialBasemaps()
111
+ ? this._parent?._t.pnx.map_background_more
112
+ : this._parent?._t.pnx.map_background_default
113
+ }
114
+ </option>
115
+ `;
116
+ const layers = Object
117
+ .entries(this._parent.mapStyleComposer.layerRanges.basemaps)
118
+ .filter(([bid,]) => !BASEMAPS_DEFAULT_IDS.includes(bid))
119
+ .map(([bid, b]) => html`
120
+ <option value="${bid}" .selected=${this._parent.mapStyleComposer.basemap === bid}>
121
+ ${b.layers[0]?.metadata?.name || bid}
122
+ </option>
123
+ `);
124
+ parts.push(html`
125
+ <select id="pnx-map-bg-more" style="width: 100%;" @change=${this._onBgChange}>
126
+ ${defaultOpt}
127
+ ${layers}
128
+ </select>
129
+ `);
130
+ }
131
+ }
132
+
133
+ // Level selector for indoor=
134
+ if(hasIndoor) {
135
+ const ieq = this._parent.map.indoorEqual;
136
+ parts.push(html`
137
+ <pnx-switch
138
+ .checked=${ieq && ieq.level !== DISABLED_LEVEL}
139
+ .disabled=${ieq && ieq.levels.length === 0}
140
+ @change=${this._onIndoorSwitchChange.bind(this)}
141
+ style="display: block; margin: 15px 0;"
142
+ name="pnx-level-switch"
143
+ >
144
+ ${this._parent?._t.pnx.indoor_switch}
145
+ </pnx-switch>
146
+ `);
147
+ }
148
+
149
+ // Map theme selector
150
+ parts.push(html`
151
+ <h4>${fa(faPalette)} ${this._parent?._t.pnx.map_theme}</h4>
152
+ <select id="pnx-map-theme" style="width: 100%;" @change=${this._onThemeSelect}>
153
+ <option value=${MAP_THEMES_STYLES.default.id} .selected=${this.theme === MAP_THEMES_STYLES.default.id}>${this._parent?._t.pnx.map_theme_default}</option>
154
+ <option value=${MAP_THEMES_STYLES.age.id} .selected=${this.theme === MAP_THEMES_STYLES.age.id}>${this._parent?._t.pnx.map_theme_age}</option>
155
+ <option value=${MAP_THEMES_STYLES.type.id} .selected=${this.theme === MAP_THEMES_STYLES.type.id}>${this._parent?._t.pnx.map_theme_type}</option>
156
+ ${this._parent?.map?._hasQualityScore?.() && html`
157
+ <option value=${MAP_THEMES_STYLES.score.id} .selected=${this.theme === MAP_THEMES_STYLES.score.id}>${this._parent?._t.pnx.map_theme_score}</option>
158
+ <option value=${MAP_THEMES_STYLES.gps.id} .selected=${this.theme === MAP_THEMES_STYLES.gps.id}>${this._parent?._t.pnx.map_theme_gps}</option>
159
+ `}
160
+ </select>
161
+ `);
162
+
163
+ // Map legend
164
+ parts.push(html`<div class="legend">
165
+ ${this.theme === MAP_THEMES_STYLES.age.id ? html`
166
+ <div>
167
+ <div class="legend-entry">
168
+ <span class="legend-color" style="background-color: ${COLORS["PALETTE_4"]}"></span>
169
+ ${this._parent?._t.pnx["map_theme_age_4"]}
170
+ </div>
171
+ <div class="legend-entry">
172
+ <span class="legend-color" style="background-color: ${COLORS["PALETTE_3"]}"></span>
173
+ ${this._parent?._t.pnx["map_theme_age_3"]}
174
+ </div>
175
+ </div>
176
+ <div>
177
+ <div class="legend-entry">
178
+ <span class="legend-color" style="background-color: ${COLORS["PALETTE_2"]}"></span>
179
+ ${this._parent?._t.pnx["map_theme_age_2"]}
180
+ </div>
181
+ <div class="legend-entry">
182
+ <span class="legend-color" style="background-color: ${COLORS["PALETTE_1"]}"></span>
183
+ ${this._parent?._t.pnx["map_theme_age_1"]}
184
+ </div>
185
+ </div>` : nothing}
186
+
187
+ ${this.theme === MAP_THEMES_STYLES.type.id ? html`
188
+ <div class="legend-entry">
189
+ <span class="legend-color" style="background-color: ${COLORS.QUALI_1}"></span>
190
+ ${this._parent?._t.pnx.picture_360}
191
+ </div>
192
+ <div class="legend-entry">
193
+ <span class="legend-color" style="background-color: ${COLORS.QUALI_2}"></span>
194
+ ${this._parent?._t.pnx.picture_flat}
195
+ </div>` : nothing}
196
+
197
+ ${this.theme === MAP_THEMES_STYLES.score.id ? html`<div>
198
+ <pnx-quality-score></pnx-quality-score>
199
+ <pnx-button
200
+ title="${this._parent?._t.pnx.metadata_quality_help}"
201
+ kind="superinline"
202
+ @click=${() => this._parent?._showQualityScoreDoc()}
203
+ >
204
+ ${fa(faInfoCircle)}
205
+ </pnx-button></div>` : nothing}
206
+
207
+ ${this.theme === MAP_THEMES_STYLES.gps.id ? html`
208
+ <div>
209
+ <div class="legend-entry">
210
+ <span class="legend-color" style="background-color: ${GPS_VALUES[0].color}"></span>
211
+ ${GPS_VALUES[0].label}
212
+ </div>
213
+ <div class="legend-entry">
214
+ <span class="legend-color" style="background-color: ${GPS_VALUES[2].color}"></span>
215
+ ${GPS_VALUES[2].label}
216
+ </div>
217
+ <div class="legend-entry">
218
+ <span class="legend-color" style="background-color: ${GPS_VALUES[4].color}"></span>
219
+ ${GPS_VALUES[4].label}
220
+ </div>
221
+ </div>
222
+ <div>
223
+ <div class="legend-entry">
224
+ <span class="legend-color" style="background-color: ${GPS_VALUES[1].color}"></span>
225
+ ${GPS_VALUES[1].label}
226
+ </div>
227
+ <div class="legend-entry">
228
+ <span class="legend-color" style="background-color: ${GPS_VALUES[3].color}"></span>
229
+ ${GPS_VALUES[3].label}
230
+ </div>
231
+ </div>` : nothing}
232
+ </div>`);
233
+
234
+ return parts;
235
+ }
236
+ }
237
+
238
+ customElements.define("pnx-map-layers-menu", MapLayers);
@@ -0,0 +1,68 @@
1
+ import {LitElement, css, html, nothing} from "lit";
2
+ import {onceParentAvailable} from "../../utils/widgets.js";
3
+
4
+ /**
5
+ * Map legend displays information about map sources.
6
+ * @class Panoramax.components.menus.MapLegend
7
+ * @element pnx-map-legend
8
+ * @extends [lit.LitElement](https://lit.dev/docs/api/LitElement/)
9
+ * @example
10
+ * ```html
11
+ * <pnx-map-legend ._parent=${viewer} />
12
+ * ```
13
+ */
14
+ export default class MapLegend extends LitElement {
15
+ /** @private */
16
+ static styles = css`
17
+ :host {
18
+ font-size: 0.7em;
19
+ }
20
+ small {
21
+ font-size: 1em;
22
+ }
23
+ .maplibregl-ctrl-attrib-inner {
24
+ display: inline-block;
25
+ }
26
+ `;
27
+
28
+ /**
29
+ * Component properties.
30
+ * @memberof Panoramax.components.menus.MapLegend#
31
+ * @type {Object}
32
+ * @property {boolean} [light=false] Lighter version (for iframes)
33
+ */
34
+ static properties = {
35
+ light: {type: Boolean},
36
+ };
37
+
38
+ constructor() {
39
+ super();
40
+ this.light = false;
41
+ }
42
+
43
+ /** @private */
44
+ connectedCallback() {
45
+ super.connectedCallback();
46
+ onceParentAvailable(this).then(() => this.requestUpdate());
47
+ onceParentAvailable(this).then(() => this._parent.onceMapReady?.().then(() => {
48
+ this._parent.map.on("styledata", () => this.requestUpdate());
49
+ this.requestUpdate();
50
+ }));
51
+ }
52
+
53
+ /** @private */
54
+ render() {
55
+ const mapAttrib = this._parent?.map?._attribution?._innerContainer;
56
+ const mapLabelParts = this._parent?._t.map.map_data.split("{m}");
57
+
58
+ return this.light ?
59
+ (mapAttrib && mapAttrib.innerHTML.length > 0 ? mapAttrib : nothing)
60
+ : html`
61
+ ${mapAttrib && mapAttrib.innerHTML.length > 0
62
+ ? html`${mapLabelParts.shift()}${mapAttrib}${mapLabelParts.shift()}`
63
+ : nothing}
64
+ `;
65
+ }
66
+ }
67
+
68
+ customElements.define("pnx-map-legend", MapLegend);
@@ -0,0 +1,73 @@
1
+ import { LitElement, css, html, nothing } from "lit";
2
+ import { onceParentAvailable } from "../../utils/widgets.js";
3
+ import { panel } from "../styles.js";
4
+
5
+ /**
6
+ * Mini picture legend shows info about picture capture date, when seen in mini component of viewer.
7
+ * @class Panoramax.components.menus.MiniPictureLegend
8
+ * @element pnx-mini-picture-legend
9
+ * @extends [lit.LitElement](https://lit.dev/docs/api/LitElement/)
10
+ * @example
11
+ * ```html
12
+ * <pnx-mini-picture-legend ._parent=${viewer} />
13
+ * ```
14
+ */
15
+ export default class MiniPictureLegend extends LitElement {
16
+ /** @private */
17
+ static styles = [panel, css`
18
+ .pnx-panel {
19
+ bottom: 0;
20
+ right: 0;
21
+ width: unset;
22
+ min-width: unset;
23
+ border-radius: 10px;
24
+ border-top-right-radius: 0;
25
+ border-bottom-left-radius: 0;
26
+ border-right: none;
27
+ border-bottom: none;
28
+ padding: 2px 5px;
29
+ font-size: 0.7em;
30
+ }
31
+ `];
32
+
33
+ /** @private */
34
+ static properties = {
35
+ _caption: {state: true},
36
+ };
37
+
38
+ /** @private */
39
+ connectedCallback() {
40
+ super.connectedCallback();
41
+
42
+ onceParentAvailable(this)
43
+ .then(() => this._parent.onceReady())
44
+ .then(() => {
45
+ this._onPicChange(this._parent.psv.getPictureMetadata());
46
+ this._parent.psv.addEventListener("picture-loaded", () => {
47
+ this._onPicChange(this._parent.psv.getPictureMetadata());
48
+ });
49
+ this._parent.psv.addEventListener("sequence-stopped", () => {
50
+ this._onPicChange(this._parent.psv.getPictureMetadata());
51
+ });
52
+ });
53
+ }
54
+
55
+ /** @private */
56
+ _onPicChange(picMeta) {
57
+ this._caption = picMeta?.caption;
58
+ }
59
+
60
+ /** @private */
61
+ render() {
62
+ return this._caption?.date ?
63
+ html`<div class="pnx-panel">${
64
+ this._caption.date.toLocaleDateString(
65
+ this._parent?.lang || window.navigator.language,
66
+ { year: "numeric", month: "long", day: "numeric" }
67
+ )
68
+ }</div>`
69
+ : nothing;
70
+ }
71
+ }
72
+
73
+ customElements.define("pnx-mini-picture-legend", MiniPictureLegend);