@seatlayer/core 0.46.0 → 0.47.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 (40) hide show
  1. package/dist/chunk-AZODENEL.js +97 -0
  2. package/dist/chunk-AZODENEL.js.map +1 -0
  3. package/dist/chunk-FVCOOLJO.js +335 -0
  4. package/dist/chunk-FVCOOLJO.js.map +1 -0
  5. package/dist/{chunk-5MRJCIZP.js → chunk-TCTAS4Z2.js} +88 -14
  6. package/dist/chunk-TCTAS4Z2.js.map +1 -0
  7. package/dist/{de-UHAOVDS3.js → de-ST4H423D.js} +6 -3
  8. package/dist/{de-UHAOVDS3.js.map → de-ST4H423D.js.map} +1 -1
  9. package/dist/{es-6TJS2L7S.js → es-WEC5NHRT.js} +6 -3
  10. package/dist/{es-6TJS2L7S.js.map → es-WEC5NHRT.js.map} +1 -1
  11. package/dist/{fr-MMSY7FPE.js → fr-SGBFNAQV.js} +6 -3
  12. package/dist/{fr-MMSY7FPE.js.map → fr-SGBFNAQV.js.map} +1 -1
  13. package/dist/index.cjs +251 -39
  14. package/dist/index.cjs.map +1 -1
  15. package/dist/index.d.cts +119 -4
  16. package/dist/index.d.ts +119 -4
  17. package/dist/index.js +152 -24
  18. package/dist/index.js.map +1 -1
  19. package/dist/{types-DBnRO2hX.d.cts → types-CE63BK0j.d.cts} +88 -10
  20. package/dist/{types-DBnRO2hX.d.ts → types-CE63BK0j.d.ts} +88 -10
  21. package/dist/view/panoramaDelivery.cjs +126 -0
  22. package/dist/view/panoramaDelivery.cjs.map +1 -0
  23. package/dist/view/panoramaDelivery.d.cts +34 -0
  24. package/dist/view/panoramaDelivery.d.ts +34 -0
  25. package/dist/view/panoramaDelivery.js +17 -0
  26. package/dist/view/panoramaDelivery.js.map +1 -0
  27. package/dist/view3d/crossfade/panorama.cjs +453 -0
  28. package/dist/view3d/crossfade/panorama.cjs.map +1 -0
  29. package/dist/view3d/crossfade/panorama.d.cts +110 -0
  30. package/dist/view3d/crossfade/panorama.d.ts +110 -0
  31. package/dist/view3d/crossfade/panorama.js +30 -0
  32. package/dist/view3d/crossfade/panorama.js.map +1 -0
  33. package/dist/view3d/index.cjs +1176 -128
  34. package/dist/view3d/index.cjs.map +1 -1
  35. package/dist/view3d/index.d.cts +73 -35
  36. package/dist/view3d/index.d.ts +73 -35
  37. package/dist/view3d/index.js +960 -300
  38. package/dist/view3d/index.js.map +1 -1
  39. package/package.json +28 -1
  40. package/dist/chunk-5MRJCIZP.js.map +0 -1
package/dist/index.js CHANGED
@@ -38,7 +38,7 @@ import {
38
38
  stackFloors,
39
39
  tableInventoryCount,
40
40
  tableSeatCountsBySide
41
- } from "./chunk-5MRJCIZP.js";
41
+ } from "./chunk-TCTAS4Z2.js";
42
42
 
43
43
  // src/core/ga.ts
44
44
  var PREFIX = "__sl_ga__";
@@ -1232,6 +1232,7 @@ function decomposeAffineLinear(affine) {
1232
1232
 
1233
1233
  // src/lib/money.ts
1234
1234
  var DEFAULT_CURRENCY = "USD";
1235
+ var CURRENCY_CHOICES = ["USD", "EUR", "GBP", "CAD", "AUD", "INR", "AED", "SGD", "JPY", "CHF", "SEK", "NZD", "ZAR", "MXN", "BRL"];
1235
1236
  var displayLocale;
1236
1237
  function setMoneyLocale(locale) {
1237
1238
  displayLocale = locale;
@@ -1312,7 +1313,7 @@ var en = {
1312
1313
  "picker.viewFromSeat": "View from seat {label}",
1313
1314
  "picker.real360": "REAL 360\xB0",
1314
1315
  "picker.preview": "PREVIEW",
1315
- "picker.sightline": "\u2248 {m} m to stage \xB7 clear sightline",
1316
+ "picker.sightline": "\u2248 {m} m to stage",
1316
1317
  "picker.panorama360": "360\xB0 venue photo",
1317
1318
  "picker.illustrationCaption": "illustration \xB7 \u2248 {m} m from stage",
1318
1319
  "picker.restrictedView": "Restricted view",
@@ -1320,7 +1321,10 @@ var en = {
1320
1321
  "picker.premiumSeat": "Premium seat",
1321
1322
  "picker.hideLimitedView": "Hide limited-view seats",
1322
1323
  "picker.bestSeatsPremium": "Best seats",
1323
- "picker.premiumFallbackNote": "No premium block of {count} \u2014 showing best overall"
1324
+ "picker.premiumFallbackNote": "No premium block of {count} \u2014 showing best overall",
1325
+ "picker.loading3d": "Building the 3D venue\u2026",
1326
+ "picker.unavailable3d": "3D could not start. The seat map is still available.",
1327
+ "picker.jumpToSection": "Jump to section"
1324
1328
  };
1325
1329
 
1326
1330
  // src/i18n/index.ts
@@ -4263,7 +4267,7 @@ var _SeatmapRenderer = class _SeatmapRenderer {
4263
4267
  this.freeTextById.set(obj.id, { node: label, background: "#232c40", kind: "table" });
4264
4268
  }
4265
4269
  renderText(obj) {
4266
- const background = this.canvasBackground;
4270
+ const background = obj.background?.color ?? this.canvasBackground;
4267
4271
  const preferredInk = obj.color ?? this.theme.textColor ?? DEF_TEXT;
4268
4272
  const iconPath = obj.semanticKind === "icon" ? venueIconPath(obj.iconKey) : void 0;
4269
4273
  if (iconPath) {
@@ -4287,23 +4291,54 @@ var _SeatmapRenderer = class _SeatmapRenderer {
4287
4291
  this.bgLayer.add(iconNode);
4288
4292
  return;
4289
4293
  }
4294
+ const padding = obj.background?.padding ?? 0;
4295
+ const opacity = obj.opacity ?? 1;
4290
4296
  const node = new Text({
4291
4297
  x: obj.position.x,
4292
4298
  y: obj.position.y,
4293
4299
  text: obj.text,
4294
4300
  fontSize: obj.fontSize,
4295
4301
  rotation: obj.rotation,
4296
- fontStyle: konvaFontStyle(obj.bold, obj.italic, "normal"),
4302
+ // Keep the buyer glyph metrics identical to Designer: wrapping must not
4303
+ // gain or lose a line when the authored chart is published.
4304
+ fontStyle: konvaFontStyle(obj.bold, obj.italic, "600"),
4297
4305
  // Authored ink remains preferred, but an embed/theme surface can change
4298
4306
  // the actual canvas. Fail over to readable black/white instead of
4299
4307
  // painting an otherwise valid caption invisibly on that active surface.
4300
4308
  fill: stateAwareBookableLabelInk(background, preferredInk),
4301
4309
  fontFamily: obj.fontFamily ?? this.labelFont(),
4310
+ ...obj.width != null ? { width: obj.width } : {},
4311
+ align: obj.align ?? "left",
4312
+ lineHeight: obj.lineHeight ?? 1.2,
4313
+ letterSpacing: obj.letterSpacing ?? 0,
4314
+ textDecoration: obj.underline ? "underline" : "",
4315
+ padding,
4316
+ opacity,
4317
+ wrap: "word",
4302
4318
  listening: false,
4303
- perfectDrawEnabled: false
4319
+ perfectDrawEnabled: false,
4320
+ name: "buyer-free-text"
4304
4321
  });
4322
+ let backdrop;
4323
+ if (obj.background) {
4324
+ backdrop = new Rect({
4325
+ x: obj.position.x,
4326
+ y: obj.position.y,
4327
+ width: node.width(),
4328
+ height: node.height(),
4329
+ rotation: obj.rotation,
4330
+ fill: obj.background.color,
4331
+ opacity: opacity * (obj.background.opacity ?? 0.9),
4332
+ cornerRadius: obj.background.cornerRadius ?? 4,
4333
+ listening: false,
4334
+ perfectDrawEnabled: false,
4335
+ name: "buyer-text-background"
4336
+ });
4337
+ this.bgLayer.add(backdrop);
4338
+ }
4305
4339
  this.freeTextById.set(obj.id, {
4306
4340
  node,
4341
+ backdrop,
4307
4342
  background,
4308
4343
  kind: "free-text"
4309
4344
  });
@@ -6083,10 +6118,12 @@ var _SeatmapRenderer = class _SeatmapRenderer {
6083
6118
  }
6084
6119
  updateFreeTextVisibility() {
6085
6120
  const effectiveScale = this.exportMode ? Math.max(this.effScale(), LABEL_SCALE) : this.effScale();
6086
- for (const { objectId, node, categoryKey, kind } of this.freeTextById.values()) {
6121
+ for (const { objectId, node, backdrop, categoryKey, kind } of this.freeTextById.values()) {
6087
6122
  const gaDimmed = categoryKey != null && (kind === "ga-label" || kind === "ga-capacity") && this.gaCategoryDimmed(categoryKey);
6088
6123
  const gaOverviewHidden = objectId != null && (kind === "ga-label" || kind === "ga-capacity") && this.gaById.get(objectId)?.sectionId != null && effectiveScale < CACHE_THRESHOLD;
6089
- node.visible(!gaDimmed && !gaOverviewHidden && isBookableLabelLegibleAtScale(node.fontSize(), effectiveScale));
6124
+ const visible = !gaDimmed && !gaOverviewHidden && isBookableLabelLegibleAtScale(node.fontSize(), effectiveScale);
6125
+ node.visible(visible);
6126
+ backdrop?.visible(visible);
6090
6127
  }
6091
6128
  for (const { node, fontSize } of this.iconNodeById.values()) {
6092
6129
  node.visible(isBookableLabelLegibleAtScale(fontSize, effectiveScale));
@@ -6573,6 +6610,11 @@ function groupedTableInventory(doc, modelVersion) {
6573
6610
  // src/picker/PickerController.ts
6574
6611
  var DEFAULT_MAX_SELECTION = 10;
6575
6612
  var MAX_BACKOFF_MS = 15e3;
6613
+ var MAP_THEME_KEYS = ["background", "rowLabelColor", "textColor", "selectionColor"];
6614
+ function sameMapTheme(a, b) {
6615
+ if (!a || !b) return !a && !b;
6616
+ return MAP_THEME_KEYS.every((key) => a[key] === b[key]);
6617
+ }
6576
6618
  function errInfo(err) {
6577
6619
  const e = err ?? {};
6578
6620
  return { status: e.status, conflicts: e.conflicts, reason: e.reason };
@@ -6588,6 +6630,8 @@ var PickerController = class {
6588
6630
  this._doc = null;
6589
6631
  /** Section/zone ids hidden from buyers this event (3.3) — seats vanish, not grey. */
6590
6632
  this.hidden = /* @__PURE__ */ new Set();
6633
+ /** Host overrides folded over the chart's own theme in `visibleDoc()`. */
6634
+ this.mapTheme = null;
6591
6635
  /** Section/zone ids in the `closed` event-state (Phase 2) — seats stay, greyed
6592
6636
  * + not pickable. Kept separate from `hidden` (which strips them). */
6593
6637
  this.closedSections = /* @__PURE__ */ new Set();
@@ -6623,6 +6667,16 @@ var PickerController = class {
6623
6667
  // hold state
6624
6668
  this.hold_ = null;
6625
6669
  this.liveStatuses = /* @__PURE__ */ new Map();
6670
+ /**
6671
+ * What a label absent from `liveStatuses` is.
6672
+ *
6673
+ * `free` while the verbose HTTP map is the source (it names every unit), but a
6674
+ * compact realtime frame names only its exceptions — so on a mostly-sold event
6675
+ * the seats NOT listed are the booked ones. Read through {@link statusOf};
6676
+ * a bare `liveStatuses.get()` silently answers `undefined` for the majority of
6677
+ * a sold-out venue.
6678
+ */
6679
+ this.liveDefault = "free";
6626
6680
  this.currency = "USD";
6627
6681
  this.expiryTimer = null;
6628
6682
  /** Whether the last emitted hint was non-null (avoids clearing repeatedly). */
@@ -6631,13 +6685,66 @@ var PickerController = class {
6631
6685
  this.api = options.transport;
6632
6686
  this.key = options.eventKey;
6633
6687
  this.maxSelection = options.maxSelection ?? DEFAULT_MAX_SELECTION;
6688
+ this.mapTheme = options.mapTheme ?? null;
6634
6689
  }
6635
6690
  get doc() {
6636
6691
  return this._doc;
6637
6692
  }
6638
- /** The chart with hidden sections' seats removed — what buyers actually see. */
6693
+ /**
6694
+ * The chart with hidden sections' seats removed, and the host's map theme
6695
+ * folded over the chart's own — what buyers actually see.
6696
+ *
6697
+ * THE THEME IS MERGED HERE rather than pushed at the renderer separately
6698
+ * because the renderer reads its theme out of the document it is given. One
6699
+ * merge point means every rebuild — a hidden section arriving mid-sale, a
6700
+ * floor switch, a theme change — repaints from the same resolved theme
6701
+ * instead of from whichever of two sources ran last.
6702
+ *
6703
+ * The chart's theme is the BASE and only named keys are overwritten, so a
6704
+ * host that overrides the ground does not thereby erase the organizer's
6705
+ * `seatScale`, `fontFamily`, logo or badge entitlement.
6706
+ */
6639
6707
  visibleDoc() {
6640
- return this._doc ? applyHidden(this._doc, this.hidden) : { objects: [] };
6708
+ if (!this._doc) return { objects: [] };
6709
+ const doc = applyHidden(this._doc, this.hidden);
6710
+ if (!this.mapTheme) return doc;
6711
+ const theme = { ...doc.theme ?? {} };
6712
+ for (const key of MAP_THEME_KEYS) {
6713
+ const value = this.mapTheme[key];
6714
+ if (value) theme[key] = value;
6715
+ }
6716
+ return { ...doc, theme };
6717
+ }
6718
+ /**
6719
+ * Re-ink the drawn map, in place, without losing the buyer's place in it.
6720
+ *
6721
+ * WHY THIS IS A SETTER AND NOT A MOUNT OPTION. On a templated event page the
6722
+ * palette is not known when the map mounts: the page config is a separate
6723
+ * cached read and the map is explicitly not allowed to wait for it. The
6724
+ * alternative — remounting the widget once the palette lands — would destroy
6725
+ * a hold the buyer may already be holding.
6726
+ *
6727
+ * The rebuild is the SAME recipe `render()` uses (setChart → colorblind →
6728
+ * closed sections → statuses), because setChart resets all four; the one
6729
+ * addition is restoring the selection, which `render()` has no need to do.
6730
+ * Statuses are repainted from the map already in memory rather than re-read,
6731
+ * so this costs no round trip and cannot flash a stale seat.
6732
+ *
6733
+ * Returns whether anything actually changed, so a caller may call it freely.
6734
+ */
6735
+ setMapTheme(theme) {
6736
+ if (sameMapTheme(this.mapTheme, theme ?? null)) return false;
6737
+ this.mapTheme = theme ?? null;
6738
+ const r = this.renderer;
6739
+ if (!r) return true;
6740
+ const selected = r.getSelection().map((seat) => seat.id);
6741
+ const floorId = this.getActiveFloorId();
6742
+ r.setChart(this.visibleDoc(), floorId ? { floorId } : void 0);
6743
+ if (this.opts.colorblindSafe) r.setColorblindSafe?.(true);
6744
+ if (this.closedSections.size) r.setClosedSections?.([...this.closedSections]);
6745
+ this.applySeatsMap(Object.fromEntries(this.liveStatuses), this.liveDefault);
6746
+ if (selected.length) r.select?.(selected);
6747
+ return true;
6641
6748
  }
6642
6749
  /** Adopt a new hidden set; rebuild the visible chart only if it differs. */
6643
6750
  syncHidden(ids) {
@@ -6826,12 +6933,14 @@ var PickerController = class {
6826
6933
  }
6827
6934
  this.renderer = renderer;
6828
6935
  let seats = null;
6936
+ let seatsDefault = "free";
6829
6937
  let closedIds = [];
6830
6938
  try {
6831
6939
  const objs = await this.api.objects(this.key);
6832
6940
  this.hidden = new Set(objs.hidden ?? []);
6833
6941
  closedIds = (objs.closed ?? []).filter((x) => typeof x === "string");
6834
6942
  seats = objs.seats;
6943
+ seatsDefault = objs.default ?? "free";
6835
6944
  } catch {
6836
6945
  }
6837
6946
  if (this.closed) {
@@ -6843,7 +6952,7 @@ var PickerController = class {
6843
6952
  if (this.opts.colorblindSafe) renderer.setColorblindSafe?.(true);
6844
6953
  this.closedSections = new Set(closedIds);
6845
6954
  if (closedIds.length) renderer.setClosedSections?.(closedIds);
6846
- if (seats) this.applySeatsMap(seats);
6955
+ if (seats) this.applySeatsMap(seats, seatsDefault);
6847
6956
  this.attachVisibilityListener();
6848
6957
  this.connect();
6849
6958
  return {
@@ -6852,6 +6961,7 @@ var PickerController = class {
6852
6961
  eventName: res.event.name,
6853
6962
  venue: res.event.venue,
6854
6963
  startsAt: res.event.startsAt,
6964
+ timezone: res.event.timezone ?? null,
6855
6965
  currency,
6856
6966
  // 'test' ⇒ sandbox event: hosts render a TEST MODE ribbon (Phase 11).
6857
6967
  mode: res.event.mode ?? "live"
@@ -7160,7 +7270,7 @@ var PickerController = class {
7160
7270
  ...area.displayLabel ? { displayLabel: area.displayLabel } : {},
7161
7271
  ...area.displayType ? { displayType: area.displayType } : {},
7162
7272
  capacity: Math.max(0, Math.floor(area.capacity)),
7163
- available: gaUnitLabels(area).filter((label) => (this.liveStatuses.get(label) ?? "free") === "free").length,
7273
+ available: gaUnitLabels(area).filter((label) => this.statusOf(label) === "free").length,
7164
7274
  categoryKey: area.categoryKey,
7165
7275
  tiers: category?.tiers,
7166
7276
  price: category?.tiers?.[0]?.price ?? category?.price ?? 0,
@@ -7174,7 +7284,7 @@ var PickerController = class {
7174
7284
  if (!doc || !Number.isFinite(qty) || qty < 1) return null;
7175
7285
  const area = gaAreasOf(doc).find((candidate) => candidate.id === areaId);
7176
7286
  if (!area) return null;
7177
- const labels = gaUnitLabels(area).filter((label) => !this.hold_?.labels.includes(label) && (this.liveStatuses.get(label) ?? "free") === "free").slice(0, Math.floor(qty));
7287
+ const labels = gaUnitLabels(area).filter((label) => !this.hold_?.labels.includes(label) && this.statusOf(label) === "free").slice(0, Math.floor(qty));
7178
7288
  if (labels.length !== Math.floor(qty)) return null;
7179
7289
  const selections = /* @__PURE__ */ new Map();
7180
7290
  for (const item of this.hold_?.items ?? []) selections.set(item.label, {
@@ -7869,7 +7979,7 @@ var PickerController = class {
7869
7979
  try {
7870
7980
  const snap = await this.api.objects(this.key);
7871
7981
  if (this.hold_?.holdId !== hold.holdId) return;
7872
- this.applySeatsMap(snap.seats);
7982
+ this.applySeatsMap(snap.seats, snap.default ?? "free");
7873
7983
  } catch {
7874
7984
  if (this.hold_?.holdId === hold.holdId) {
7875
7985
  this.expiryTimer = setTimeout(() => void this.expireActiveHold(), 2e3);
@@ -7877,18 +7987,30 @@ var PickerController = class {
7877
7987
  return;
7878
7988
  }
7879
7989
  if (this.hold_?.holdId !== hold.holdId) return;
7880
- if (hold.labels.some((label) => this.liveStatuses.get(label) === "held")) {
7990
+ if (hold.labels.some((label) => this.statusOf(label) === "held")) {
7881
7991
  this.expiryTimer = setTimeout(() => void this.expireActiveHold(), 1e3);
7882
7992
  return;
7883
7993
  }
7884
7994
  this.clearHold();
7885
7995
  this.opts.onHoldExpired?.();
7886
7996
  }
7887
- applySeatsMap(seats) {
7997
+ /**
7998
+ * Repaint from an authoritative map of unit statuses.
7999
+ *
8000
+ * `defaultStatus` is what every unit NOT named in `seats` is. The verbose HTTP
8001
+ * route names every unit and leaves it at `free`; the compact realtime frame
8002
+ * names only the exceptions and states its own default, which on a mostly-sold
8003
+ * event is `booked` rather than `free`. Applying a compact map while assuming
8004
+ * `free` would paint a sold-out stadium as fully available, so the default is
8005
+ * a parameter rather than a constant.
8006
+ */
8007
+ applySeatsMap(seats, defaultStatus = "free") {
7888
8008
  const r = this.renderer;
7889
8009
  if (!r) return;
7890
8010
  this.liveStatuses = new Map(Object.entries(seats));
7891
- if (this.allIds.length) r.setStatus(this.allIds, "free");
8011
+ this.liveDefault = defaultStatus;
8012
+ const defaultSeatStatus = mapStatus(defaultStatus);
8013
+ if (this.allIds.length) r.setStatus(this.allIds, defaultSeatStatus);
7892
8014
  r.setOwnedHold?.(
7893
8015
  this.idsForLabels(this.hold_?.labels ?? [])
7894
8016
  );
@@ -7896,15 +8018,19 @@ var PickerController = class {
7896
8018
  for (const [label, st] of Object.entries(seats)) {
7897
8019
  byStatus[mapStatus(st)].push(...this.idsForLabel(label));
7898
8020
  }
7899
- ["held", "booked", "not_for_sale"].forEach((st) => {
7900
- if (byStatus[st].length) r.setStatus(byStatus[st], st);
8021
+ ["free", "held", "booked", "not_for_sale"].forEach((st) => {
8022
+ if (st !== defaultSeatStatus && byStatus[st].length) r.setStatus(byStatus[st], st);
7901
8023
  });
7902
8024
  this.clearBookedHoldIfSettled();
7903
8025
  this.opts.onStatusChange?.();
7904
8026
  }
8027
+ /** The live status of one unit, honouring the projection's default. */
8028
+ statusOf(label) {
8029
+ return this.liveStatuses.get(label) ?? this.liveDefault;
8030
+ }
7905
8031
  clearBookedHoldIfSettled() {
7906
8032
  const hold = this.hold_;
7907
- if (hold?.labels.every((label) => this.liveStatuses.get(label) === "booked")) {
8033
+ if (hold?.labels.every((label) => this.statusOf(label) === "booked")) {
7908
8034
  this.clearHold();
7909
8035
  this.resetTableQuantitiesForLabels(hold.labels);
7910
8036
  }
@@ -7912,7 +8038,7 @@ var PickerController = class {
7912
8038
  async resnapshot() {
7913
8039
  try {
7914
8040
  const objs = await this.api.objects(this.key);
7915
- this.applySeatsMap(objs.seats);
8041
+ this.applySeatsMap(objs.seats, objs.default ?? "free");
7916
8042
  } catch {
7917
8043
  }
7918
8044
  }
@@ -7970,6 +8096,7 @@ var PickerController = class {
7970
8096
  realtimeSink() {
7971
8097
  return {
7972
8098
  applyStatuses: (changes) => this.applyStatusChanges(changes),
8099
+ applyProjection: (projection) => this.applySeatsMap(projection.exceptions, projection.default),
7973
8100
  resync: () => this.resnapshot(),
7974
8101
  onSections: (hidden, closed) => {
7975
8102
  const rebuilt = this.syncHidden(hidden);
@@ -9246,9 +9373,9 @@ function generateSeatThumb(seat, focalPoint, _neighborSeats) {
9246
9373
 
9247
9374
  // src/i18n/bundles.ts
9248
9375
  var LOADERS = {
9249
- es: () => import("./es-6TJS2L7S.js").then((m) => ({ default: m.es })),
9250
- de: () => import("./de-UHAOVDS3.js").then((m) => ({ default: m.de })),
9251
- fr: () => import("./fr-MMSY7FPE.js").then((m) => ({ default: m.fr }))
9376
+ es: () => import("./es-WEC5NHRT.js").then((m) => ({ default: m.es })),
9377
+ de: () => import("./de-ST4H423D.js").then((m) => ({ default: m.de })),
9378
+ fr: () => import("./fr-SGBFNAQV.js").then((m) => ({ default: m.fr }))
9252
9379
  };
9253
9380
  var loaded = /* @__PURE__ */ new Set(["en"]);
9254
9381
  async function loadLocale(code) {
@@ -9271,6 +9398,7 @@ export {
9271
9398
  ACCESSIBILITY_RING_COLOR,
9272
9399
  ACCESSIBILITY_TYPES,
9273
9400
  CHART_STORAGE_KEY,
9401
+ CURRENCY_CHOICES,
9274
9402
  DEFAULT_CURRENCY,
9275
9403
  LABEL_STYLE_MAX_SIZE,
9276
9404
  LABEL_STYLE_MIN_SIZE,