@virtualdisplay.io/client 4.0.0-alpha.7 → 4.0.0-alpha.8

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,4 +1,4 @@
1
- import { n as e } from "./chunk-efA98nb6.js";
1
+ import { n as e } from "./chunk-C_CI6nMA.js";
2
2
  //#region src/client/error.ts
3
3
  var t = {
4
4
  NO_MAPPING: "NO_MAPPING",
@@ -66,7 +66,7 @@ var t = {
66
66
  }
67
67
  buildUrl() {
68
68
  let e = this.getServerUrl(), t = new URL(e);
69
- return t.searchParams.set("license", this.options.license), t.searchParams.set("model", this.options.model), this.options.language !== void 0 && t.searchParams.set("language", this.options.language), this.options.debug === !0 && t.searchParams.set("debug", "true"), t.toString();
69
+ return t.searchParams.set("license", this.options.license), t.searchParams.set("model", this.options.model), this.options.language !== void 0 && t.searchParams.set("language", this.options.language), this.options.debug === !0 && t.searchParams.set("debug", "true"), this.options.traceparent !== void 0 && t.searchParams.set("traceparent", this.options.traceparent), t.toString();
70
70
  }
71
71
  getServerUrl() {
72
72
  return this.defaultServer;
@@ -101,28 +101,48 @@ function o(e, t) {
101
101
  e.level === "error" ? console.error(n) : e.level === "warn" ? console.warn(n) : console.log(n);
102
102
  }
103
103
  //#endregion
104
+ //#region ../logger/src/serialise.ts
105
+ function s(e, t = 0) {
106
+ let n = {
107
+ name: e.name,
108
+ message: e.message
109
+ };
110
+ e.stack !== void 0 && (n.stack = e.stack);
111
+ for (let t of Object.getOwnPropertyNames(e)) {
112
+ if (t === "name" || t === "message" || t === "stack" || t === "cause") continue;
113
+ let r = e[t];
114
+ r !== void 0 && (n[t] = r);
115
+ }
116
+ return e.cause !== void 0 && e.cause !== null && (n.cause = e.cause instanceof Error && t < 5 ? s(e.cause, t + 1) : String(e.cause)), n;
117
+ }
118
+ function c(e) {
119
+ let t = {};
120
+ for (let [n, r] of Object.entries(e)) t[n] = r instanceof Error ? s(r) : r;
121
+ return t;
122
+ }
123
+ //#endregion
104
124
  //#region ../utils/src/date.ts
105
- function s() {
125
+ function l() {
106
126
  return /* @__PURE__ */ new Date();
107
127
  }
108
- function c(e) {
128
+ function u(e) {
109
129
  return e.toISOString();
110
130
  }
111
131
  //#endregion
112
132
  //#region ../logger/src/logger.ts
113
- var l = class e {
133
+ var d = class e {
114
134
  constructor(e) {
115
135
  this.config = e;
116
136
  }
117
137
  log(e, t, n = {}) {
118
138
  let r = this.config.traceProvider?.() ?? {};
119
139
  o({
120
- timestamp: c(s()),
140
+ timestamp: u(l()),
121
141
  level: e,
122
142
  msg: t,
123
143
  service: this.config.service,
124
144
  ...r,
125
- ...n
145
+ ...c(n)
126
146
  }, this.config.isDev);
127
147
  }
128
148
  debug(e, t) {
@@ -147,8 +167,8 @@ var l = class e {
147
167
  }).bind(this), n;
148
168
  }
149
169
  };
150
- function u(e, t) {
151
- return new l({
170
+ function f(e, t) {
171
+ return new d({
152
172
  service: e,
153
173
  isDev: t?.isDev === void 0 ? typeof process < "u" ? process.env.NODE_ENV !== "production" : !0 : t.isDev,
154
174
  traceProvider: t?.traceProvider
@@ -156,34 +176,34 @@ function u(e, t) {
156
176
  }
157
177
  //#endregion
158
178
  //#region src/utils/logger.ts
159
- function d(e) {
179
+ function p(e) {
160
180
  if (e !== void 0) return typeof e == "object" && e && !Array.isArray(e) && !(e instanceof Error) ? e : e instanceof Error ? { error: e.message } : { value: e };
161
181
  }
162
- function f(e) {
182
+ function m(e) {
163
183
  return {
164
- debug: (t, n) => e.debug(t, d(n)),
165
- info: (t, n) => e.info(t, d(n)),
166
- warn: (t, n) => e.warn(t, d(n)),
167
- error: (t, n) => e.error(t, d(n))
184
+ debug: (t, n) => e.debug(t, p(n)),
185
+ info: (t, n) => e.info(t, p(n)),
186
+ warn: (t, n) => e.warn(t, p(n)),
187
+ error: (t, n) => e.error(t, p(n))
168
188
  };
169
189
  }
170
- var p = !1, m = f(u("client", { isDev: !1 }));
171
- function h() {
172
- p = !0, m = f(u("client", { isDev: !0 }));
190
+ var h = !1, g = m(f("client", { isDev: !1 }));
191
+ function _() {
192
+ h = !0, g = m(f("client", { isDev: !0 }));
173
193
  }
174
- function g() {
175
- return p;
194
+ function ee() {
195
+ return h;
176
196
  }
177
197
  //#endregion
178
198
  //#region src/client/ready-state-tracker.ts
179
- var _ = class {
199
+ var te = class {
180
200
  ready = !1;
181
201
  onReady;
182
202
  constructor(e) {
183
203
  this.onReady = e;
184
204
  }
185
205
  handleMappingReceived() {
186
- this.ready || (this.ready = !0, m.info("Mapping received from server, client is now ready"), this.onReady?.());
206
+ this.ready || (this.ready = !0, g.info("Mapping received from server, client is now ready"), this.onReady?.());
187
207
  }
188
208
  get isReady() {
189
209
  return this.ready;
@@ -191,102 +211,7 @@ var _ = class {
191
211
  clear() {
192
212
  this.ready = !1;
193
213
  }
194
- }, v = class {
195
- isSelectedValue = !1;
196
- constructor(e, t) {
197
- this.value = e, this.attribute = t;
198
- }
199
- get isSelected() {
200
- return this.isSelectedValue;
201
- }
202
- setSelected(e) {
203
- this.isSelectedValue = e;
204
- }
205
- }, ee = class {
206
- name;
207
- defaultValue;
208
- values;
209
- onSelect;
210
- onChangeCallback;
211
- constructor(e) {
212
- this.name = e.name, this.defaultValue = e.defaultValue, this.onSelect = e.onSelect, this.values = this.createValues(e.values);
213
- }
214
- select(e) {
215
- if (!this.values.has(e)) throw n.valueNotFound(this.name, e);
216
- this.onSelect(this.name, e);
217
- }
218
- getValues() {
219
- return Array.from(this.values.values());
220
- }
221
- getValue(e) {
222
- return this.values.get(e);
223
- }
224
- onChange(e) {
225
- this.onChangeCallback = e;
226
- }
227
- handleResult(e) {
228
- let t;
229
- for (let n of this.values.values()) {
230
- let r = n.value === e;
231
- n.setSelected(r), r && (t = n);
232
- }
233
- t !== void 0 && this.onChangeCallback !== void 0 && this.onChangeCallback(t);
234
- }
235
- createValues(e) {
236
- let t = /* @__PURE__ */ new Map();
237
- for (let n of e) {
238
- let e = new v(n, this.name);
239
- n === this.defaultValue && e.setSelected(!0), t.set(n, e);
240
- }
241
- return t;
242
- }
243
- }, te = class {
244
- attributes = /* @__PURE__ */ new Map();
245
- constructor(e, t, n) {
246
- for (let n of e) {
247
- let e = this.buildOptions(n, t);
248
- this.attributes.set(n.name, new ee(e));
249
- }
250
- this.onMutationFailed = n;
251
- }
252
- onMutationFailed;
253
- get(e) {
254
- return this.attributes.get(e);
255
- }
256
- defaults() {
257
- let e = [];
258
- for (let t of this.attributes.values()) t.defaultValue !== void 0 && e.push({
259
- name: t.name,
260
- value: t.defaultValue
261
- });
262
- return e;
263
- }
264
- handleResults(e) {
265
- for (let t of e) {
266
- if (!t.success) {
267
- this.onMutationFailed?.(t.name, t.value);
268
- continue;
269
- }
270
- this.get(t.name)?.handleResult(t.value);
271
- }
272
- }
273
- buildOptions(e, t) {
274
- let n = {
275
- name: e.name,
276
- values: e.values,
277
- onSelect: (e, n) => {
278
- t([{
279
- name: e,
280
- value: n
281
- }], !1);
282
- }
283
- };
284
- return e.defaultValue === void 0 ? n : {
285
- ...n,
286
- defaultValue: e.defaultValue
287
- };
288
- }
289
- }, y = {
214
+ }, v = {
290
215
  HANDSHAKE: "handshake",
291
216
  MUTATION: "mutation",
292
217
  STATE: "state",
@@ -296,47 +221,54 @@ var _ = class {
296
221
  MAPPING: "mapping",
297
222
  AR_ACTIVATE: "ar_activate",
298
223
  CONFIG: "config",
299
- INTERACTION: "interaction"
300
- }, ne = new Set(Object.values(y));
224
+ INTERACTION: "interaction",
225
+ ANNOTATION_PLACE_MODE: "annotation_place_mode",
226
+ ANNOTATION_PLACED: "annotation_placed",
227
+ ANNOTATION_TOGGLE: "annotation_toggle"
228
+ }, ne = new Set(Object.values(v));
301
229
  function re(e) {
302
230
  if (typeof e != "object" || !e) return !1;
303
231
  let t = e;
304
232
  return typeof t.target == "string" ? !1 : typeof t.type == "string" && ne.has(t.type);
305
233
  }
306
234
  function ie(e) {
307
- let t = b(e);
308
- return t !== null && t.type === y.HANDSHAKE;
235
+ let t = y(e);
236
+ return t !== null && t.type === v.HANDSHAKE;
309
237
  }
310
238
  function ae(e) {
311
- let t = b(e);
312
- return t !== null && t.type === y.MUTATION && Array.isArray(t.results);
239
+ let t = y(e);
240
+ return t !== null && t.type === v.MUTATION && Array.isArray(t.results);
313
241
  }
314
242
  function oe(e) {
315
- let t = b(e);
316
- return t !== null && t.type === y.SNAPSHOT && ("data" in t || "error" in t);
243
+ let t = y(e);
244
+ return t !== null && t.type === v.SNAPSHOT && ("data" in t || "error" in t);
317
245
  }
318
246
  function se(e) {
319
- let t = b(e);
320
- return t !== null && t.type === y.CAMERA && Array.isArray(t.transforms);
247
+ let t = y(e);
248
+ return t !== null && t.type === v.CAMERA && Array.isArray(t.transforms);
321
249
  }
322
250
  function ce(e) {
323
- let t = b(e);
324
- return t !== null && t.type === y.MAPPING && Array.isArray(t.attributes);
251
+ let t = y(e);
252
+ return t !== null && t.type === v.MAPPING && Array.isArray(t.attributes);
325
253
  }
326
254
  function le(e) {
327
- let t = b(e);
328
- return t !== null && t.type === y.LOADING_INDICATOR && typeof t.progress == "number";
255
+ let t = y(e);
256
+ return t !== null && t.type === v.LOADING_INDICATOR && typeof t.progress == "number";
329
257
  }
330
258
  function ue(e) {
331
- let t = b(e);
332
- return t !== null && t.type === y.CONFIG && typeof t.viewerSettings == "object";
259
+ let t = y(e);
260
+ return t !== null && t.type === v.CONFIG && typeof t.viewerSettings == "object";
261
+ }
262
+ function de(e) {
263
+ let t = y(e);
264
+ return t !== null && t.type === v.ANNOTATION_PLACED && typeof t.position == "object" && t.position !== null;
333
265
  }
334
- function b(e) {
266
+ function y(e) {
335
267
  return typeof e != "object" || !e ? null : e;
336
268
  }
337
269
  //#endregion
338
270
  //#region ../messaging/src/queue.ts
339
- var de = class {
271
+ var b = class {
340
272
  pending = [];
341
273
  isReady = !1;
342
274
  constructor(e) {
@@ -374,8 +306,9 @@ var de = class {
374
306
  shouldBuffer;
375
307
  listener = null;
376
308
  sourceId;
309
+ targetOrigin;
377
310
  constructor(e, t) {
378
- this.getTarget = e, this.sourceId = `vd-${Math.random().toString(36).slice(2, 8)}`, this.publisher = new de((e) => this.post(e)), this.consumer = new de((e) => this.routeToHandler(e)), this.shouldBuffer = t?.shouldBuffer ?? null, t?.bufferIncoming !== !0 && this.consumer.markReady();
311
+ this.getTarget = e, this.sourceId = `vd-${Math.random().toString(36).slice(2, 8)}`, this.targetOrigin = t?.targetOrigin ?? "*", this.publisher = new b((e) => this.post(e)), this.consumer = new b((e) => this.routeToHandler(e)), this.shouldBuffer = t?.shouldBuffer ?? null, t?.bufferIncoming !== !0 && this.consumer.markReady();
379
312
  }
380
313
  on(e, t) {
381
314
  this.handlers.set(e, t);
@@ -383,6 +316,9 @@ var de = class {
383
316
  off(e) {
384
317
  this.handlers.delete(e);
385
318
  }
319
+ setTargetOrigin(e) {
320
+ this.targetOrigin = e;
321
+ }
386
322
  send(e) {
387
323
  this.publisher.enqueue(e);
388
324
  }
@@ -421,7 +357,7 @@ var de = class {
421
357
  t !== null && t.postMessage({
422
358
  ...e,
423
359
  _source: this.sourceId
424
- }, "*");
360
+ }, this.targetOrigin);
425
361
  }
426
362
  routeToHandler(e) {
427
363
  let t = this.handlers.get(e.type);
@@ -433,17 +369,141 @@ var de = class {
433
369
  });
434
370
  }
435
371
  };
436
- new Set([y.CAMERA]);
372
+ new Set([v.CAMERA]);
437
373
  //#endregion
438
- //#region src/attributes/attributes.ts
374
+ //#region src/annotations/annotations.ts
439
375
  var pe = class {
376
+ placedCallbacks = [];
377
+ constructor(e) {
378
+ this.send = e;
379
+ }
380
+ setEnabled(e) {
381
+ this.send({
382
+ type: v.ANNOTATION_TOGGLE,
383
+ enabled: e
384
+ });
385
+ }
386
+ startPlacing() {
387
+ this.send({
388
+ type: v.ANNOTATION_PLACE_MODE,
389
+ enabled: !0
390
+ });
391
+ }
392
+ stopPlacing() {
393
+ this.send({
394
+ type: v.ANNOTATION_PLACE_MODE,
395
+ enabled: !1
396
+ });
397
+ }
398
+ onPlaced(e) {
399
+ this.placedCallbacks.push(e);
400
+ }
401
+ handlePlaced(e) {
402
+ for (let t of this.placedCallbacks) t(e);
403
+ }
404
+ }, me = class {
405
+ isSelectedValue = !1;
406
+ constructor(e, t) {
407
+ this.value = e, this.attribute = t;
408
+ }
409
+ get isSelected() {
410
+ return this.isSelectedValue;
411
+ }
412
+ setSelected(e) {
413
+ this.isSelectedValue = e;
414
+ }
415
+ }, x = class {
416
+ name;
417
+ defaultValue;
418
+ values;
419
+ onSelect;
420
+ onChangeCallback;
421
+ constructor(e) {
422
+ this.name = e.name, this.defaultValue = e.defaultValue, this.onSelect = e.onSelect, this.values = this.createValues(e.values);
423
+ }
424
+ select(e) {
425
+ if (!this.values.has(e)) throw n.valueNotFound(this.name, e);
426
+ this.onSelect(this.name, e);
427
+ }
428
+ getValues() {
429
+ return Array.from(this.values.values());
430
+ }
431
+ getValue(e) {
432
+ return this.values.get(e);
433
+ }
434
+ onChange(e) {
435
+ this.onChangeCallback = e;
436
+ }
437
+ handleResult(e) {
438
+ let t;
439
+ for (let n of this.values.values()) {
440
+ let r = n.value === e;
441
+ n.setSelected(r), r && (t = n);
442
+ }
443
+ t !== void 0 && this.onChangeCallback !== void 0 && this.onChangeCallback(t);
444
+ }
445
+ createValues(e) {
446
+ let t = /* @__PURE__ */ new Map();
447
+ for (let n of e) {
448
+ let e = new me(n, this.name);
449
+ n === this.defaultValue && e.setSelected(!0), t.set(n, e);
450
+ }
451
+ return t;
452
+ }
453
+ }, he = class {
454
+ attributes = /* @__PURE__ */ new Map();
455
+ constructor(e, t, n) {
456
+ for (let n of e) {
457
+ let e = this.buildOptions(n, t);
458
+ this.attributes.set(n.name, new x(e));
459
+ }
460
+ this.onMutationFailed = n;
461
+ }
462
+ onMutationFailed;
463
+ get(e) {
464
+ return this.attributes.get(e);
465
+ }
466
+ defaults() {
467
+ let e = [];
468
+ for (let t of this.attributes.values()) t.defaultValue !== void 0 && e.push({
469
+ name: t.name,
470
+ value: t.defaultValue
471
+ });
472
+ return e;
473
+ }
474
+ handleResults(e) {
475
+ for (let t of e) {
476
+ if (!t.success) {
477
+ this.onMutationFailed?.(t.name, t.value);
478
+ continue;
479
+ }
480
+ this.get(t.name)?.handleResult(t.value);
481
+ }
482
+ }
483
+ buildOptions(e, t) {
484
+ let n = {
485
+ name: e.name,
486
+ values: e.values,
487
+ onSelect: (e, n) => {
488
+ t([{
489
+ name: e,
490
+ value: n
491
+ }], !1);
492
+ }
493
+ };
494
+ return e.defaultValue === void 0 ? n : {
495
+ ...n,
496
+ defaultValue: e.defaultValue
497
+ };
498
+ }
499
+ }, ge = class {
440
500
  registry;
441
501
  pendingCallbacks = [];
442
502
  constructor(e, t) {
443
503
  this.send = e, this.onMutationFailed = t;
444
504
  }
445
505
  handleMappingReceived(e) {
446
- m.debug("Initializing from server mapping", { attributeCount: e.attributes.length }), this.registry = new te(e.attributes, (e, t) => this.sendMutation(e, t), this.onMutationFailed), this.replayPendingCallbacks();
506
+ g.debug("Initializing from server mapping", { attributeCount: e.attributes.length }), this.registry = new he(e.attributes, (e, t) => this.sendMutation(e, t), this.onMutationFailed), this.replayPendingCallbacks();
447
507
  }
448
508
  handleMutationResult(e) {
449
509
  this.registry?.handleResults(e.results);
@@ -470,7 +530,7 @@ var pe = class {
470
530
  }
471
531
  let n = this.registry.get(e);
472
532
  if (n === void 0) {
473
- m.warn(`onChange: attribute "${e}" not found — callback will not fire`);
533
+ g.warn(`onChange: attribute "${e}" not found — callback will not fire`);
474
534
  return;
475
535
  }
476
536
  n.onChange(t);
@@ -483,7 +543,7 @@ var pe = class {
483
543
  }
484
544
  sendMutation(e, t) {
485
545
  let n = {
486
- type: y.MUTATION,
546
+ type: v.MUTATION,
487
547
  mutations: e,
488
548
  isInitial: t
489
549
  };
@@ -492,11 +552,11 @@ var pe = class {
492
552
  replayPendingCallbacks() {
493
553
  for (let { name: e, callback: t } of this.pendingCallbacks) {
494
554
  let n = this.registry?.get(e);
495
- n === void 0 && m.warn(`onChange: attribute "${e}" not found — buffered callback will not fire`), n?.onChange(t);
555
+ n === void 0 && g.warn(`onChange: attribute "${e}" not found — buffered callback will not fire`), n?.onChange(t);
496
556
  }
497
557
  this.pendingCallbacks.length = 0;
498
558
  }
499
- }, x = class {
559
+ }, _e = class {
500
560
  commands = [];
501
561
  constructor(e) {
502
562
  this.send = e;
@@ -522,7 +582,7 @@ var pe = class {
522
582
  set() {
523
583
  if (this.commands.length === 0) throw n.invalidParameter("No camera commands to execute. Call rotate(), tilt(), or zoom() before set().");
524
584
  let e = {
525
- type: y.CAMERA,
585
+ type: v.CAMERA,
526
586
  commands: this.commands
527
587
  };
528
588
  this.send(e), this.commands = [];
@@ -532,12 +592,12 @@ var pe = class {
532
592
  }
533
593
  reset() {
534
594
  let e = {
535
- type: y.CAMERA,
595
+ type: v.CAMERA,
536
596
  commands: [{ action: "reset" }]
537
597
  };
538
598
  this.send(e);
539
599
  }
540
- }, me = class {
600
+ }, ve = class {
541
601
  state;
542
602
  limitsState;
543
603
  changeCallbacks = [];
@@ -598,7 +658,7 @@ var pe = class {
598
658
  for (let t of this.changeCallbacks) t(e);
599
659
  }
600
660
  }
601
- }, S = class {
661
+ }, ye = class {
602
662
  developedCallbacks = /* @__PURE__ */ new Set();
603
663
  errorCallbacks = /* @__PURE__ */ new Set();
604
664
  developed = !1;
@@ -626,24 +686,24 @@ var pe = class {
626
686
  t(e);
627
687
  }), this.developedCallbacks.clear(), this.errorCallbacks.clear());
628
688
  }
629
- }, C = class {
689
+ }, S = class {
630
690
  validExtensions = [".png"];
631
691
  pendingPhotos = /* @__PURE__ */ new Map();
632
692
  constructor(e) {
633
693
  this.send = e;
634
694
  }
635
695
  take(e) {
636
- this.validateFilename(e), m.debug("Taking snapshot", { filename: e });
637
- let t = new S(e);
696
+ this.validateFilename(e), g.debug("Taking snapshot", { filename: e });
697
+ let t = new ye(e);
638
698
  return this.pendingPhotos.set(t.getFilename(), t), this.send({
639
- type: y.SNAPSHOT,
699
+ type: v.SNAPSHOT,
640
700
  filename: e
641
701
  }), t;
642
702
  }
643
703
  handleSnapshotResult(e) {
644
704
  let r = this.pendingPhotos.get(e.filename);
645
705
  if (r === void 0) {
646
- m.warn("No pending photo found for filename", {
706
+ g.warn("No pending photo found for filename", {
647
707
  filename: e.filename,
648
708
  pendingFilenames: Array.from(this.pendingPhotos.keys())
649
709
  });
@@ -663,7 +723,7 @@ var pe = class {
663
723
  if (!this.validExtensions.some((t) => e.toLowerCase().endsWith(t))) throw new n(`Invalid filename: "${e}". Filename must end with one of: ${this.validExtensions.join(", ")}`, t.INVALID_PARAMETER);
664
724
  if (e.includes("..") || e.includes("/") || e.includes("\\")) throw new n("Filename cannot contain path separators or \"..\"", t.INVALID_PARAMETER);
665
725
  }
666
- }, he = class {
726
+ }, be = class {
667
727
  container = null;
668
728
  attach(e) {
669
729
  this.container = e;
@@ -689,70 +749,70 @@ var pe = class {
689
749
  this.container?.removeEventListener(e, n);
690
750
  };
691
751
  }
692
- }, ge = {}, w = [
752
+ }, xe = {}, C = [
693
753
  "en",
694
754
  "nl",
695
755
  "de"
696
- ], T = ["baseLocale"], _e = [], ve, ye;
697
- function be(e) {
698
- if (_e.length === 0) return;
756
+ ], w = ["baseLocale"], T = [], E, D;
757
+ function Se(e) {
758
+ if (T.length === 0) return;
699
759
  let t = typeof e == "string" ? e : e.href;
700
- if (ve === t) return ye;
760
+ if (E === t) return D;
701
761
  let n = new URL(t, "http://dummy.com"), r;
702
- for (let e of _e) if (new ge(e.match, n.href).exec(n.href)) {
762
+ for (let e of T) if (new xe(e.match, n.href).exec(n.href)) {
703
763
  r = e;
704
764
  break;
705
765
  }
706
- return ve = t, ye = r, r;
766
+ return E = t, D = r, r;
707
767
  }
708
- function E(e) {
709
- let t = be(e);
710
- return t && t.exclude !== !0 && Array.isArray(t.strategy) ? t.strategy : T;
768
+ function O(e) {
769
+ let t = Se(e);
770
+ return t && t.exclude !== !0 && Array.isArray(t.strategy) ? t.strategy : w;
711
771
  }
712
- var D = void 0, O = typeof window > "u";
772
+ var k = void 0, A = typeof window > "u";
713
773
  globalThis.__paraglide = globalThis.__paraglide ?? {}, globalThis.__paraglide.ssr = globalThis.__paraglide.ssr ?? {};
714
- var k = !1, A = () => {
715
- if (D) {
716
- let e = D?.getStore()?.locale;
774
+ var j = !1, M = () => {
775
+ if (k) {
776
+ let e = k?.getStore()?.locale;
717
777
  if (e) return e;
718
778
  }
719
- let e = T;
720
- !O && typeof window < "u" && window.location?.href && (e = E(window.location.href));
721
- let t = xe(e, typeof window < "u" ? window.location?.href : void 0);
722
- if (t) return k || (k = !0, j(t, { reload: !1 })), t;
779
+ let e = w;
780
+ !A && typeof window < "u" && window.location?.href && (e = O(window.location.href));
781
+ let t = Ce(e, typeof window < "u" ? window.location?.href : void 0);
782
+ if (t) return j || (j = !0, N(t, { reload: !1 })), t;
723
783
  throw Error("No locale found. Read the docs https://inlang.com/m/gerre34r/library-inlang-paraglideJs/errors#no-locale-found");
724
784
  };
725
- function xe(e, t) {
785
+ function Ce(e, t) {
726
786
  let n;
727
787
  for (let t of e) {
728
788
  if (t === "baseLocale") n = "en";
729
- else if (we(t) && N.has(t)) {
730
- let e = N.get(t);
789
+ else if (Ee(t) && F.has(t)) {
790
+ let e = F.get(t);
731
791
  if (e) {
732
792
  let t = e.getLocale();
733
793
  if (t instanceof Promise) continue;
734
- if (t !== void 0) return Ce(t);
794
+ if (t !== void 0) return Te(t);
735
795
  }
736
796
  }
737
- let e = M(n);
797
+ let e = P(n);
738
798
  if (e) return e;
739
799
  }
740
800
  }
741
- var Se = (e) => {
801
+ var we = (e) => {
742
802
  e ? window.location.href = e : window.location.reload();
743
- }, j = (e, t) => {
803
+ }, N = (e, t) => {
744
804
  let n = {
745
805
  reload: !0,
746
806
  ...t
747
807
  }, r;
748
808
  try {
749
- r = A();
809
+ r = M();
750
810
  } catch {}
751
- let i = [], a = T;
752
- !O && typeof window < "u" && window.location?.href && (a = E(window.location.href));
811
+ let i = [], a = w;
812
+ !A && typeof window < "u" && window.location?.href && (a = O(window.location.href));
753
813
  for (let t of a) if (t === "baseLocale") continue;
754
- else if (we(t) && N.has(t)) {
755
- let n = N.get(t);
814
+ else if (Ee(t) && F.has(t)) {
815
+ let n = F.get(t);
756
816
  if (n) {
757
817
  let r = n.setLocale(e);
758
818
  r instanceof Promise && (r = r.catch((e) => {
@@ -761,78 +821,78 @@ var Se = (e) => {
761
821
  }
762
822
  }
763
823
  let o = () => {
764
- !O && n.reload && window.location && e !== r && Se(void 0);
824
+ !A && n.reload && window.location && e !== r && we(void 0);
765
825
  };
766
826
  if (i.length) return Promise.all(i).then(() => {
767
827
  o();
768
828
  });
769
829
  o();
770
830
  };
771
- function M(e) {
831
+ function P(e) {
772
832
  if (typeof e != "string") return;
773
833
  let t = e.toLowerCase();
774
- for (let e of w) if (e.toLowerCase() === t) return e;
834
+ for (let e of C) if (e.toLowerCase() === t) return e;
775
835
  }
776
- function Ce(e) {
777
- let t = M(e);
836
+ function Te(e) {
837
+ let t = P(e);
778
838
  if (t) return t;
779
- throw Error(`Invalid locale: ${e}. Expected one of: ${w.join(", ")}`);
839
+ throw Error(`Invalid locale: ${e}. Expected one of: ${C.join(", ")}`);
780
840
  }
781
- var N = /* @__PURE__ */ new Map();
782
- function we(e) {
841
+ var F = /* @__PURE__ */ new Map();
842
+ function Ee(e) {
783
843
  return typeof e == "string" && /^custom-[A-Za-z0-9_-]+$/.test(e);
784
844
  }
785
845
  //#endregion
786
846
  //#region ../i18n/src/paraglide-viewer/messages/controls_ar_buttonlabel1.js
787
- var Te = () => "Activate AR", Ee = () => "AR activeren", De = () => "AR aktivieren", Oe = ((e = {}, t = {}) => {
788
- let n = t.locale ?? A();
789
- return n === "en" ? Te(e) : n === "nl" ? Ee(e) : De(e);
790
- }), ke = () => "Scan to view in AR", Ae = () => "Scan om in AR te bekijken", je = () => "Scannen für AR-Ansicht", Me = ((e = {}, t = {}) => {
791
- let n = t.locale ?? A();
792
- return n === "en" ? ke(e) : n === "nl" ? Ae(e) : je(e);
793
- }), Ne = () => "Use your smartphone camera to scan this QR code", Pe = () => "Gebruik de camera van uw smartphone om deze QR-code te scannen", Fe = () => "Verwenden Sie die Kamera Ihres Smartphones, um diesen QR-Code zu scannen", Ie = ((e = {}, t = {}) => {
794
- let n = t.locale ?? A();
795
- return n === "en" ? Ne(e) : n === "nl" ? Pe(e) : Fe(e);
796
- }), Le = () => "The 3D model will open in your phone's AR mode", Re = () => "Het 3D-model wordt geopend in de AR-modus van uw telefoon", ze = () => "Das 3D-Modell wird im AR-Modus Ihres Telefons geöffnet", Be = ((e = {}, t = {}) => {
797
- let n = t.locale ?? A();
798
- return n === "en" ? Le(e) : n === "nl" ? Re(e) : ze(e);
799
- }), Ve = () => "Close", He = () => "Sluiten", Ue = () => "Schließen", We = ((e = {}, t = {}) => {
800
- let n = t.locale ?? A();
801
- return n === "en" ? Ve(e) : n === "nl" ? He(e) : Ue(e);
802
- }), Ge = () => "Toggle fullscreen", Ke = () => "Volledig scherm", qe = () => "Vollbild umschalten", Je = ((e = {}, t = {}) => {
803
- let n = t.locale ?? A();
804
- return n === "en" ? Ge(e) : n === "nl" ? Ke(e) : qe(e);
805
- }), Ye = () => "Downloading", Xe = () => "Downloaden", Ze = () => "Herunterladen", Qe = ((e = {}, t = {}) => {
806
- let n = t.locale ?? A();
807
- return n === "en" ? Ye(e) : n === "nl" ? Xe(e) : Ze(e);
808
- }), $e = () => "Rendering", et = () => "Renderen", tt = () => "Rendern", nt = ((e = {}, t = {}) => {
809
- let n = t.locale ?? A();
810
- return n === "en" ? $e(e) : n === "nl" ? et(e) : tt(e);
811
- }), rt = () => "Screenshot", it = () => "Screenshot", at = () => "Screenshot", ot = ((e = {}, t = {}) => {
812
- let n = t.locale ?? A();
813
- return n === "en" ? rt(e) : n === "nl" ? it(e) : at(e);
814
- }), st = () => "Reset camera", ct = () => "Camera resetten", lt = () => "Kamera zurücksetzen", ut = ((e = {}, t = {}) => {
815
- let n = t.locale ?? A();
816
- return n === "en" ? st(e) : n === "nl" ? ct(e) : lt(e);
817
- }), dt = () => "Zoom in", ft = () => "Inzoomen", pt = () => "Hineinzoomen", mt = ((e = {}, t = {}) => {
818
- let n = t.locale ?? A();
819
- return n === "en" ? dt(e) : n === "nl" ? ft(e) : pt(e);
820
- }), ht = () => "Zoom out", gt = () => "Uitzoomen", _t = () => "Herauszoomen", vt = ((e = {}, t = {}) => {
821
- let n = t.locale ?? A();
822
- return n === "en" ? ht(e) : n === "nl" ? gt(e) : _t(e);
823
- }), yt = () => "Rotate left", bt = () => "Naar links draaien", xt = () => "Nach links drehen", St = ((e = {}, t = {}) => {
824
- let n = t.locale ?? A();
825
- return n === "en" ? yt(e) : n === "nl" ? bt(e) : xt(e);
826
- }), Ct = () => "Rotate right", wt = () => "Naar rechts draaien", Tt = () => "Nach rechts drehen", Et = ((e = {}, t = {}) => {
827
- let n = t.locale ?? A();
828
- return n === "en" ? Ct(e) : n === "nl" ? wt(e) : Tt(e);
829
- }), Dt = () => "Tilt up", Ot = () => "Omhoog kantelen", kt = () => "Nach oben kippen", At = ((e = {}, t = {}) => {
830
- let n = t.locale ?? A();
831
- return n === "en" ? Dt(e) : n === "nl" ? Ot(e) : kt(e);
832
- }), jt = () => "Tilt down", Mt = () => "Omlaag kantelen", Nt = () => "Nach unten kippen", Pt = ((e = {}, t = {}) => {
833
- let n = t.locale ?? A();
834
- return n === "en" ? jt(e) : n === "nl" ? Mt(e) : Nt(e);
835
- }), Ft = {
847
+ var De = () => "Activate AR", Oe = () => "AR activeren", ke = () => "AR aktivieren", Ae = ((e = {}, t = {}) => {
848
+ let n = t.locale ?? M();
849
+ return n === "en" ? De(e) : n === "nl" ? Oe(e) : ke(e);
850
+ }), je = () => "Scan to view in AR", Me = () => "Scan om in AR te bekijken", Ne = () => "Scannen für AR-Ansicht", Pe = ((e = {}, t = {}) => {
851
+ let n = t.locale ?? M();
852
+ return n === "en" ? je(e) : n === "nl" ? Me(e) : Ne(e);
853
+ }), Fe = () => "Use your smartphone camera to scan this QR code", Ie = () => "Gebruik de camera van je smartphone om deze QR-code te scannen", Le = () => "Verwenden Sie die Kamera Ihres Smartphones, um diesen QR-Code zu scannen", Re = ((e = {}, t = {}) => {
854
+ let n = t.locale ?? M();
855
+ return n === "en" ? Fe(e) : n === "nl" ? Ie(e) : Le(e);
856
+ }), ze = () => "The 3D model will open in your phone's AR mode", Be = () => "Het 3D-model wordt geopend in de AR-modus van je telefoon", Ve = () => "Das 3D-Modell wird im AR-Modus Ihres Telefons geöffnet", He = ((e = {}, t = {}) => {
857
+ let n = t.locale ?? M();
858
+ return n === "en" ? ze(e) : n === "nl" ? Be(e) : Ve(e);
859
+ }), Ue = () => "Close", We = () => "Sluiten", Ge = () => "Schließen", Ke = ((e = {}, t = {}) => {
860
+ let n = t.locale ?? M();
861
+ return n === "en" ? Ue(e) : n === "nl" ? We(e) : Ge(e);
862
+ }), qe = () => "Toggle fullscreen", Je = () => "Volledig scherm", Ye = () => "Vollbild umschalten", Xe = ((e = {}, t = {}) => {
863
+ let n = t.locale ?? M();
864
+ return n === "en" ? qe(e) : n === "nl" ? Je(e) : Ye(e);
865
+ }), Ze = () => "Downloading", Qe = () => "Downloaden", $e = () => "Herunterladen", et = ((e = {}, t = {}) => {
866
+ let n = t.locale ?? M();
867
+ return n === "en" ? Ze(e) : n === "nl" ? Qe(e) : $e(e);
868
+ }), tt = () => "Rendering", nt = () => "Renderen", rt = () => "Rendern", it = ((e = {}, t = {}) => {
869
+ let n = t.locale ?? M();
870
+ return n === "en" ? tt(e) : n === "nl" ? nt(e) : rt(e);
871
+ }), at = () => "Screenshot", ot = () => "Screenshot", st = () => "Screenshot", ct = ((e = {}, t = {}) => {
872
+ let n = t.locale ?? M();
873
+ return n === "en" ? at(e) : n === "nl" ? ot(e) : st(e);
874
+ }), lt = () => "Reset camera", ut = () => "Camera resetten", dt = () => "Kamera zurücksetzen", ft = ((e = {}, t = {}) => {
875
+ let n = t.locale ?? M();
876
+ return n === "en" ? lt(e) : n === "nl" ? ut(e) : dt(e);
877
+ }), pt = () => "Zoom in", mt = () => "Inzoomen", ht = () => "Hineinzoomen", gt = ((e = {}, t = {}) => {
878
+ let n = t.locale ?? M();
879
+ return n === "en" ? pt(e) : n === "nl" ? mt(e) : ht(e);
880
+ }), _t = () => "Zoom out", vt = () => "Uitzoomen", yt = () => "Herauszoomen", bt = ((e = {}, t = {}) => {
881
+ let n = t.locale ?? M();
882
+ return n === "en" ? _t(e) : n === "nl" ? vt(e) : yt(e);
883
+ }), xt = () => "Rotate left", St = () => "Naar links draaien", Ct = () => "Nach links drehen", wt = ((e = {}, t = {}) => {
884
+ let n = t.locale ?? M();
885
+ return n === "en" ? xt(e) : n === "nl" ? St(e) : Ct(e);
886
+ }), Tt = () => "Rotate right", Et = () => "Naar rechts draaien", Dt = () => "Nach rechts drehen", Ot = ((e = {}, t = {}) => {
887
+ let n = t.locale ?? M();
888
+ return n === "en" ? Tt(e) : n === "nl" ? Et(e) : Dt(e);
889
+ }), kt = () => "Tilt up", At = () => "Omhoog kantelen", jt = () => "Nach oben kippen", Mt = ((e = {}, t = {}) => {
890
+ let n = t.locale ?? M();
891
+ return n === "en" ? kt(e) : n === "nl" ? At(e) : jt(e);
892
+ }), Nt = () => "Tilt down", Pt = () => "Omlaag kantelen", Ft = () => "Nach unten kippen", It = ((e = {}, t = {}) => {
893
+ let n = t.locale ?? M();
894
+ return n === "en" ? Nt(e) : n === "nl" ? Pt(e) : Ft(e);
895
+ }), Lt = {
836
896
  xmlns: "http://www.w3.org/2000/svg",
837
897
  width: 24,
838
898
  height: 24,
@@ -842,40 +902,40 @@ var Te = () => "Activate AR", Ee = () => "AR activeren", De = () => "AR aktivier
842
902
  "stroke-width": 2,
843
903
  "stroke-linecap": "round",
844
904
  "stroke-linejoin": "round"
845
- }, It = ([e, t, n]) => {
905
+ }, Rt = ([e, t, n]) => {
846
906
  let r = document.createElementNS("http://www.w3.org/2000/svg", e);
847
907
  return Object.keys(t).forEach((e) => {
848
908
  r.setAttribute(e, String(t[e]));
849
909
  }), n?.length && n.forEach((e) => {
850
- let t = It(e);
910
+ let t = Rt(e);
851
911
  r.appendChild(t);
852
912
  }), r;
853
- }, Lt = (e, t = {}) => It([
913
+ }, zt = (e, t = {}) => Rt([
854
914
  "svg",
855
915
  {
856
- ...Ft,
916
+ ...Lt,
857
917
  ...t
858
918
  },
859
919
  e
860
- ]), Rt = [
920
+ ]), Bt = [
861
921
  ["path", { d: "M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z" }],
862
922
  ["path", { d: "m3.3 7 8.7 5 8.7-5" }],
863
923
  ["path", { d: "M12 22V12" }]
864
- ], zt = [["path", { d: "M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z" }], ["circle", {
924
+ ], Vt = [["path", { d: "M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z" }], ["circle", {
865
925
  cx: "12",
866
926
  cy: "13",
867
927
  r: "3"
868
- }]], Bt = [["path", { d: "m6 9 6 6 6-6" }]], Vt = [["path", { d: "m15 18-6-6 6-6" }]], Ht = [["path", { d: "m9 18 6-6-6-6" }]], Ut = [["path", { d: "m18 15-6-6-6 6" }]], Wt = [
928
+ }]], Ht = [["path", { d: "m6 9 6 6 6-6" }]], Ut = [["path", { d: "m15 18-6-6 6-6" }]], Wt = [["path", { d: "m9 18 6-6-6-6" }]], Gt = [["path", { d: "m18 15-6-6-6 6" }]], Kt = [
869
929
  ["path", { d: "M15 3h6v6" }],
870
930
  ["path", { d: "m21 3-7 7" }],
871
931
  ["path", { d: "m3 21 7-7" }],
872
932
  ["path", { d: "M9 21H3v-6" }]
873
- ], Gt = [
933
+ ], qt = [
874
934
  ["path", { d: "m14 10 7-7" }],
875
935
  ["path", { d: "M20 10h-6V4" }],
876
936
  ["path", { d: "m3 21 7-7" }],
877
937
  ["path", { d: "M4 14h6v6" }]
878
- ], Kt = [["path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }], ["path", { d: "M3 3v5h5" }]], qt = [
938
+ ], Jt = [["path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }], ["path", { d: "M3 3v5h5" }]], Yt = [
879
939
  ["circle", {
880
940
  cx: "11",
881
941
  cy: "11",
@@ -899,7 +959,7 @@ var Te = () => "Activate AR", Ee = () => "AR activeren", De = () => "AR aktivier
899
959
  y1: "11",
900
960
  y2: "11"
901
961
  }]
902
- ], Jt = [
962
+ ], Xt = [
903
963
  ["circle", {
904
964
  cx: "11",
905
965
  cy: "11",
@@ -920,26 +980,26 @@ var Te = () => "Activate AR", Ee = () => "AR activeren", De = () => "AR aktivier
920
980
  ];
921
981
  //#endregion
922
982
  //#region ../ui/src/icons.ts
923
- function P(e, { size: t = 20, strokeWidth: n = 1.75 } = {}) {
924
- return Lt(e, {
983
+ function I(e, { size: t = 20, strokeWidth: n = 1.75 } = {}) {
984
+ return zt(e, {
925
985
  width: t,
926
986
  height: t,
927
987
  "stroke-width": n
928
988
  });
929
989
  }
930
- var F = {
931
- ar: (e) => P(Rt, e),
932
- fullscreen: (e) => P(Wt, e),
933
- exitFullscreen: (e) => P(Gt, e),
934
- screenshot: (e) => P(zt, e),
935
- tiltUp: (e) => P(Ut, e),
936
- tiltDown: (e) => P(Bt, e),
937
- rotateLeft: (e) => P(Vt, e),
938
- rotateRight: (e) => P(Ht, e),
939
- zoomIn: (e) => P(qt, e),
940
- zoomOut: (e) => P(Jt, e),
941
- reset: (e) => P(Kt, e)
942
- }, I = class {
990
+ var L = {
991
+ ar: (e) => I(Bt, e),
992
+ fullscreen: (e) => I(Kt, e),
993
+ exitFullscreen: (e) => I(qt, e),
994
+ screenshot: (e) => I(Vt, e),
995
+ tiltUp: (e) => I(Gt, e),
996
+ tiltDown: (e) => I(Ht, e),
997
+ rotateLeft: (e) => I(Ut, e),
998
+ rotateRight: (e) => I(Wt, e),
999
+ zoomIn: (e) => I(Yt, e),
1000
+ zoomOut: (e) => I(Xt, e),
1001
+ reset: (e) => I(Jt, e)
1002
+ }, R = class {
943
1003
  element;
944
1004
  constructor({ variant: e = "default", size: t = "default", label: n, icon: r, onClick: i, disabled: a = !1 } = {}) {
945
1005
  this.element = document.createElement("button"), this.element.className = `ui-btn ui-btn--${e} ui-btn--size-${t}`, n !== void 0 && (this.element.setAttribute("aria-label", n), this.element.title = n), r === void 0 ? n !== void 0 && (this.element.textContent = n) : this.element.appendChild(r), i && this.element.addEventListener("click", i), this.element.disabled = a;
@@ -948,7 +1008,7 @@ var F = {
948
1008
  let t = this.element.querySelector("svg");
949
1009
  t === null ? this.element.appendChild(e) : t.replaceWith(e);
950
1010
  }
951
- }, L = {
1011
+ }, z = {
952
1012
  brand: {
953
1013
  DEFAULT: "#171717",
954
1014
  primary: "#171717",
@@ -987,7 +1047,7 @@ var F = {
987
1047
  },
988
1048
  white: "#ffffff",
989
1049
  black: "#000000"
990
- }, R = {
1050
+ }, B = {
991
1051
  px: "1px",
992
1052
  0: "0",
993
1053
  .5: "0.125rem",
@@ -1010,27 +1070,27 @@ var F = {
1010
1070
  20: "5rem",
1011
1071
  24: "6rem"
1012
1072
  };
1013
- R[1], R[2], R[4], R[6], R[8], R[12];
1073
+ B[1], B[2], B[4], B[6], B[8], B[12];
1014
1074
  //#endregion
1015
1075
  //#region ../ui/src/vanilla/components/card/index.ts
1016
- var Yt = class {
1076
+ var Zt = class {
1017
1077
  element;
1018
1078
  constructor() {
1019
1079
  this.element = document.createElement("div"), Object.assign(this.element.style, {
1020
- background: L.white,
1021
- borderRadius: R[3],
1022
- padding: R[6],
1023
- boxShadow: `0 ${R[2]} ${R[8]} oklch(0% 0 0 / 20%)`,
1080
+ background: z.white,
1081
+ borderRadius: B[3],
1082
+ padding: B[6],
1083
+ boxShadow: `0 ${B[2]} ${B[8]} oklch(0% 0 0 / 20%)`,
1024
1084
  maxWidth: "20rem",
1025
1085
  width: "100%"
1026
1086
  });
1027
1087
  }
1028
- }, Xt = class {
1088
+ }, Qt = class {
1029
1089
  card;
1030
1090
  backdrop;
1031
1091
  keyHandler = null;
1032
1092
  constructor(e = {}) {
1033
- this.options = e, this.card = new Yt(), this.backdrop = this.createBackdrop(), this.backdrop.appendChild(this.card.element);
1093
+ this.options = e, this.card = new Zt(), this.backdrop = this.createBackdrop(), this.backdrop.appendChild(this.card.element);
1034
1094
  }
1035
1095
  open() {
1036
1096
  document.body.appendChild(this.backdrop), this.keyHandler = (e) => {
@@ -1044,7 +1104,7 @@ var Yt = class {
1044
1104
  let e = document.createElement("div");
1045
1105
  return Object.assign(e.style, {
1046
1106
  position: "fixed",
1047
- inset: R[0],
1107
+ inset: B[0],
1048
1108
  background: "oklch(0% 0 0 / 50%)",
1049
1109
  zIndex: "9999",
1050
1110
  display: "flex",
@@ -1054,7 +1114,7 @@ var Yt = class {
1054
1114
  t.target === e && this.close();
1055
1115
  }), e;
1056
1116
  }
1057
- }, Zt = class {
1117
+ }, $t = class {
1058
1118
  element;
1059
1119
  selectCallback = null;
1060
1120
  constructor(e, t, n) {
@@ -1072,7 +1132,7 @@ var Yt = class {
1072
1132
  onSelect(e) {
1073
1133
  this.selectCallback = e;
1074
1134
  }
1075
- }, Qt = class {
1135
+ }, en = class {
1076
1136
  element;
1077
1137
  select;
1078
1138
  constructor(e, t, n, r, i) {
@@ -1085,7 +1145,7 @@ var Yt = class {
1085
1145
  a.value = n, a.textContent = i?.[e] ?? n, n === r && (a.selected = !0, o = !0), this.select.appendChild(a);
1086
1146
  }
1087
1147
  o || (a.selected = !0);
1088
- let s = Lt(Bt, {
1148
+ let s = zt(Ht, {
1089
1149
  width: 16,
1090
1150
  height: 16,
1091
1151
  "stroke-width": 2
@@ -1100,7 +1160,7 @@ var Yt = class {
1100
1160
  e(this.select.value);
1101
1161
  });
1102
1162
  }
1103
- }, z = {
1163
+ }, V = {
1104
1164
  fontFamily: {
1105
1165
  sans: [
1106
1166
  "Mona Sans",
@@ -1139,42 +1199,42 @@ var Yt = class {
1139
1199
  normal: "1.5",
1140
1200
  relaxed: "1.75"
1141
1201
  }
1142
- }, $t = z.fontFamily.sans.join(", "), en = class {
1202
+ }, tn = V.fontFamily.sans.join(", "), nn = class {
1143
1203
  qrLib = null;
1144
1204
  dialog = null;
1145
1205
  async show(t) {
1146
- this.hide(), this.qrLib ??= await import("./browser-DbgxVbZp.js").then((t) => /* @__PURE__ */ e(t.default, 1));
1206
+ this.hide(), this.qrLib ??= await import("./browser-DxtIwHNu.js").then((t) => /* @__PURE__ */ e(t.default, 1));
1147
1207
  let n = await this.qrLib.toDataURL(t, {
1148
1208
  width: 256,
1149
1209
  margin: 4,
1150
1210
  errorCorrectionLevel: "M",
1151
1211
  color: {
1152
- dark: L.black,
1153
- light: L.white
1212
+ dark: z.black,
1213
+ light: z.white
1154
1214
  }
1155
1215
  });
1156
- this.dialog = new Xt({ onClose: () => {
1216
+ this.dialog = new Qt({ onClose: () => {
1157
1217
  this.dialog = null;
1158
1218
  } }), Object.assign(this.dialog.card.element.style, {
1159
1219
  display: "flex",
1160
1220
  flexDirection: "column",
1161
1221
  alignItems: "center",
1162
- gap: R[3],
1163
- fontFamily: $t
1164
- }), this.dialog.card.element.appendChild(this.createText(Me(), {
1165
- fontSize: z.fontSize.base,
1166
- fontWeight: z.fontWeight.semibold,
1167
- color: L.neutral[900]
1168
- })), this.dialog.card.element.appendChild(this.createText(Ie(), {
1169
- fontSize: z.fontSize.sm,
1170
- color: L.neutral[600]
1171
- })), this.dialog.card.element.appendChild(this.createQrImage(n)), this.dialog.card.element.appendChild(this.createText(Be(), {
1172
- fontSize: z.fontSize.xs,
1173
- color: L.neutral[500]
1222
+ gap: B[3],
1223
+ fontFamily: tn
1224
+ }), this.dialog.card.element.appendChild(this.createText(Pe(), {
1225
+ fontSize: V.fontSize.base,
1226
+ fontWeight: V.fontWeight.semibold,
1227
+ color: z.neutral[900]
1228
+ })), this.dialog.card.element.appendChild(this.createText(Re(), {
1229
+ fontSize: V.fontSize.sm,
1230
+ color: z.neutral[600]
1231
+ })), this.dialog.card.element.appendChild(this.createQrImage(n)), this.dialog.card.element.appendChild(this.createText(He(), {
1232
+ fontSize: V.fontSize.xs,
1233
+ color: z.neutral[500]
1174
1234
  }));
1175
- let r = new I({
1235
+ let r = new R({
1176
1236
  variant: "outline",
1177
- label: We(),
1237
+ label: Ke(),
1178
1238
  onClick: () => {
1179
1239
  this.hide();
1180
1240
  }
@@ -1195,12 +1255,12 @@ var Yt = class {
1195
1255
  createQrImage(e) {
1196
1256
  let t = document.createElement("img");
1197
1257
  return t.src = e, t.alt = "QR code", Object.assign(t.style, {
1198
- width: R[24],
1199
- height: R[24],
1200
- borderRadius: R[1]
1258
+ width: B[24],
1259
+ height: B[24],
1260
+ borderRadius: B[1]
1201
1261
  }), t;
1202
1262
  }
1203
- }, B = z.fontFamily.sans.join(", "), tn = `
1263
+ }, H = V.fontFamily.sans.join(", "), rn = `
1204
1264
  :root {
1205
1265
  --primary: oklch(5% 0 0);
1206
1266
  --primary-foreground: oklch(100% 0 0);
@@ -1224,7 +1284,7 @@ var Yt = class {
1224
1284
  gap: 0.5rem;
1225
1285
  border: 1px solid transparent;
1226
1286
  border-radius: var(--radius);
1227
- font-family: ${B};
1287
+ font-family: ${H};
1228
1288
  font-size: 0.875rem;
1229
1289
  font-weight: 600;
1230
1290
  white-space: nowrap;
@@ -1281,7 +1341,7 @@ var Yt = class {
1281
1341
  border-radius: var(--radius);
1282
1342
  background: var(--background);
1283
1343
  color: var(--foreground);
1284
- font-family: ${B};
1344
+ font-family: ${H};
1285
1345
  font-size: 0.875rem;
1286
1346
  font-weight: 600;
1287
1347
  cursor: pointer;
@@ -1315,7 +1375,7 @@ var Yt = class {
1315
1375
  background: var(--background);
1316
1376
  appearance: none;
1317
1377
  color: var(--foreground);
1318
- font-family: ${B};
1378
+ font-family: ${H};
1319
1379
  font-size: 0.875rem;
1320
1380
  font-weight: 400;
1321
1381
  cursor: pointer;
@@ -1337,20 +1397,95 @@ var Yt = class {
1337
1397
  color: var(--muted-foreground);
1338
1398
  pointer-events: none;
1339
1399
  }
1340
- `, V = !1;
1341
- function nn() {
1342
- if (V || typeof document > "u") return;
1343
- V = !0;
1400
+
1401
+ /* ── Annotation layer ───────────────────────────────────── */
1402
+ .vd-annotations-layer {
1403
+ position: absolute;
1404
+ inset-block-start: 0;
1405
+ inset-inline-start: 0;
1406
+ inline-size: 100%;
1407
+ block-size: 100%;
1408
+ pointer-events: none;
1409
+ overflow: visible !important; /* override CSS2DRenderer inline style */
1410
+ }
1411
+
1412
+ .vd-annotation-marker {
1413
+ display: flex;
1414
+ align-items: center;
1415
+ justify-content: center;
1416
+ inline-size: 1.75rem;
1417
+ block-size: 1.75rem;
1418
+ border-radius: 50%;
1419
+ border: 2px solid oklch(100% 0 0);
1420
+ background: var(--primary);
1421
+ color: var(--primary-foreground);
1422
+ font-family: ${H};
1423
+ font-size: 0.8125rem;
1424
+ font-weight: 600;
1425
+ cursor: pointer;
1426
+ pointer-events: auto;
1427
+ box-shadow: 0 2px 8px oklch(5% 0 0 / 20%);
1428
+ transition: transform 100ms ease;
1429
+ position: relative;
1430
+ }
1431
+ .vd-annotation-marker:hover { transform: scale(1.1); }
1432
+
1433
+ .vd-annotation-popup {
1434
+ position: absolute;
1435
+ inset-block-end: calc(100% + 0.5rem);
1436
+ inset-inline-start: 50%;
1437
+ transform: translateX(-50%);
1438
+ background: var(--background);
1439
+ color: var(--foreground);
1440
+ border: 1px solid var(--border);
1441
+ border-radius: var(--radius);
1442
+ padding: 0.75rem 1rem;
1443
+ max-inline-size: 15rem;
1444
+ box-shadow: 0 4px 6px oklch(5% 0 0 / 8%), 0 2px 4px oklch(5% 0 0 / 6%);
1445
+ pointer-events: auto;
1446
+ white-space: normal;
1447
+ }
1448
+
1449
+ @media (prefers-reduced-motion: no-preference) {
1450
+ .vd-annotation-popup {
1451
+ animation: vd-popup-in 150ms ease;
1452
+ }
1453
+ }
1454
+
1455
+ @keyframes vd-popup-in {
1456
+ from { opacity: 0; transform: translateX(-50%) translateY(4px); }
1457
+ to { opacity: 1; transform: translateX(-50%) translateY(0); }
1458
+ }
1459
+
1460
+ .vd-annotation-popup-title {
1461
+ font-family: ${H};
1462
+ font-size: 0.875rem;
1463
+ font-weight: 600;
1464
+ line-height: 1.25rem;
1465
+ }
1466
+
1467
+ .vd-annotation-popup-description {
1468
+ font-family: ${H};
1469
+ font-size: 0.8125rem;
1470
+ font-weight: 400;
1471
+ line-height: 1.125rem;
1472
+ color: var(--muted-foreground);
1473
+ margin-block-start: 0.25rem;
1474
+ }
1475
+ `, an = !1;
1476
+ function on() {
1477
+ if (an || typeof document > "u") return;
1478
+ an = !0;
1344
1479
  let e = document.createElement("style");
1345
- e.id = "vd-ui-vanilla", e.textContent = tn, document.head.appendChild(e);
1480
+ e.id = "vd-ui-vanilla", e.textContent = rn, document.head.appendChild(e);
1346
1481
  }
1347
1482
  //#endregion
1348
1483
  //#region src/ui/loading.ts
1349
- function H(e) {
1484
+ function sn(e) {
1350
1485
  let t = Math.max(0, Math.min(1, e));
1351
1486
  return t * t * (3 - 2 * t);
1352
1487
  }
1353
- function rn(e, t, n, r, i, a) {
1488
+ function cn(e, t, n, r, i, a) {
1354
1489
  let [o, s, c] = e, l = Math.cos(t), u = Math.sin(t), d = l * o + u * c, f = -u * o + l * c, p = Math.cos(n), m = Math.sin(n), h = p * s - m * f, g = m * s + p * f, _ = .55;
1355
1490
  return [
1356
1491
  r + d * a * _,
@@ -1358,12 +1493,12 @@ function rn(e, t, n, r, i, a) {
1358
1493
  g
1359
1494
  ];
1360
1495
  }
1361
- function an(e, t, n) {
1496
+ function ln(e, t, n) {
1362
1497
  e.beginPath(), e.moveTo(t[0], t[1]), e.lineTo(n[0], n[1]), e.strokeStyle = "#000", e.lineWidth = 2, e.stroke();
1363
1498
  }
1364
- function on(e, t, n, r, i) {
1499
+ function un(e, t, n, r, i) {
1365
1500
  let a = t(n), o = t(r);
1366
- an(e, a, [
1501
+ ln(e, a, [
1367
1502
  a[0] + (o[0] - a[0]) * i,
1368
1503
  a[1] + (o[1] - a[1]) * i,
1369
1504
  a[2]
@@ -1401,7 +1536,7 @@ var U = [
1401
1536
  -1,
1402
1537
  1,
1403
1538
  -1
1404
- ], sn = [
1539
+ ], dn = [
1405
1540
  [U, W],
1406
1541
  [W, G],
1407
1542
  [G, K],
@@ -1414,8 +1549,8 @@ var U = [
1414
1549
  [J, Y],
1415
1550
  [Y, X],
1416
1551
  [X, q]
1417
- ], cn = 400, ln = "-apple-system, BlinkMacSystemFont, \"Segoe UI\", system-ui, sans-serif";
1418
- function un() {
1552
+ ], fn = 400, pn = "-apple-system, BlinkMacSystemFont, \"Segoe UI\", system-ui, sans-serif";
1553
+ function mn() {
1419
1554
  let e = document.createElement("div");
1420
1555
  Object.assign(e.style, {
1421
1556
  position: "absolute",
@@ -1451,21 +1586,21 @@ function un() {
1451
1586
  fontWeight: "400",
1452
1587
  color: "#000",
1453
1588
  fontVariantNumeric: "tabular-nums",
1454
- fontFamily: ln
1589
+ fontFamily: pn
1455
1590
  });
1456
1591
  let i = document.createElement("span");
1457
1592
  return Object.assign(i.style, {
1458
1593
  fontSize: "13px",
1459
1594
  color: "#000",
1460
- fontFamily: ln
1461
- }), i.textContent = Qe(), n.appendChild(r), n.appendChild(i), e.appendChild(t), e.appendChild(n), {
1595
+ fontFamily: pn
1596
+ }), i.textContent = et(), n.appendChild(r), n.appendChild(i), e.appendChild(t), e.appendChild(n), {
1462
1597
  overlay: e,
1463
1598
  canvas: t,
1464
1599
  pctEl: r,
1465
1600
  phaseEl: i
1466
1601
  };
1467
1602
  }
1468
- var dn = class {
1603
+ var hn = class {
1469
1604
  overlay;
1470
1605
  canvas;
1471
1606
  ctx;
@@ -1478,17 +1613,17 @@ var dn = class {
1478
1613
  visible = !1;
1479
1614
  constructor(e, t = {}) {
1480
1615
  this.startTime = performance.now();
1481
- let n = un();
1616
+ let n = mn();
1482
1617
  this.overlay = n.overlay, this.canvas = n.canvas, this.pctEl = n.pctEl, this.phaseEl = n.phaseEl, e.appendChild(this.overlay), this.ctx = this.canvas.getContext("2d"), this.ctx !== null && (this.sizeCanvas(), this.tick());
1483
- let r = t.showDelay ?? cn;
1618
+ let r = t.showDelay ?? fn;
1484
1619
  this.showTimerId = setTimeout(() => {
1485
1620
  this.reveal();
1486
1621
  }, r);
1487
1622
  }
1488
1623
  get loadingTexts() {
1489
1624
  return {
1490
- downloading: Qe(),
1491
- rendering: nt()
1625
+ downloading: et(),
1626
+ rendering: it()
1492
1627
  };
1493
1628
  }
1494
1629
  updateProgress(e, t) {
@@ -1535,26 +1670,29 @@ var dn = class {
1535
1670
  if (this.ctx === null) return;
1536
1671
  let e = this.canvas.width / Math.min(devicePixelRatio, 2), t = this.canvas.height / Math.min(devicePixelRatio, 2), n = (performance.now() - this.startTime) / 1e3;
1537
1672
  this.ctx.fillStyle = "#fff", this.ctx.fillRect(0, 0, e, t);
1538
- let r = e / 2, i = t * .44, a = Math.min(e, t) * .08, o = (e) => rn(e, .785, .615, r, i, a), s = n % 6 / 6, c = sn.length, l;
1539
- l = s < .35 ? H(s / .35) * c : s < .55 ? c : s < .9 ? (1 - H((s - .55) / .35)) * c : 0, this.ctx.shadowBlur = 5, this.ctx.shadowColor = "rgba(30,30,30,0.08)";
1673
+ let r = e / 2, i = t * .44, a = Math.min(e, t) * .08, o = (e) => cn(e, .785, .615, r, i, a), s = n % 6 / 6, c = dn.length, l;
1674
+ l = s < .35 ? sn(s / .35) * c : s < .55 ? c : s < .9 ? (1 - sn((s - .55) / .35)) * c : 0, this.ctx.shadowBlur = 5, this.ctx.shadowColor = "rgba(30,30,30,0.08)";
1540
1675
  for (let e = 0; e < c && !(e >= l); e++) {
1541
- let t = sn[e];
1676
+ let t = dn[e];
1542
1677
  if (t === void 0) continue;
1543
1678
  let n = Math.min(1, l - e);
1544
- on(this.ctx, o, t[0], t[1], n);
1679
+ un(this.ctx, o, t[0], t[1], n);
1545
1680
  }
1546
1681
  this.ctx.shadowBlur = 0;
1547
1682
  }
1548
- }, fn = class {
1683
+ }, gn = class {
1549
1684
  element;
1550
1685
  arBtn = null;
1551
1686
  fullscreenBtn = null;
1552
1687
  onFullscreenChange;
1553
1688
  constructor(e) {
1554
- this.options = e, this.element = document.createElement("div"), this.onFullscreenChange = () => {
1689
+ this.options = e, this.element = document.createElement("div"), Object.assign(this.element.style, {
1690
+ display: "flex",
1691
+ gap: "0.375rem"
1692
+ }), this.onFullscreenChange = () => {
1555
1693
  if (this.fullscreenBtn === null) return;
1556
1694
  let e = document.fullscreenElement !== null;
1557
- this.fullscreenBtn.setIcon(e ? F.exitFullscreen() : F.fullscreen());
1695
+ this.fullscreenBtn.setIcon(e ? L.exitFullscreen() : L.fullscreen());
1558
1696
  }, document.addEventListener("fullscreenchange", this.onFullscreenChange);
1559
1697
  }
1560
1698
  syncButton(e, t, n) {
@@ -1565,19 +1703,19 @@ var dn = class {
1565
1703
  return !t && e !== null ? (e.element.remove(), null) : e;
1566
1704
  }
1567
1705
  applySettings(e) {
1568
- this.arBtn = this.syncButton(this.arBtn, e.ar !== !1 && this.options.onAr !== void 0, () => new I({
1706
+ this.arBtn = this.syncButton(this.arBtn, e.ar !== !1 && this.options.onAr !== void 0, () => new R({
1569
1707
  variant: "outline",
1570
1708
  size: "icon",
1571
- label: Oe(),
1572
- icon: F.ar(),
1709
+ label: Ae(),
1710
+ icon: L.ar(),
1573
1711
  onClick: () => {
1574
1712
  this.options.onAr?.();
1575
1713
  }
1576
- })), this.fullscreenBtn = this.syncButton(this.fullscreenBtn, e.fullscreen !== !1 && this.options.onFullscreen !== void 0, () => new I({
1714
+ })), this.fullscreenBtn = this.syncButton(this.fullscreenBtn, e.fullscreen !== !1 && this.options.onFullscreen !== void 0, () => new R({
1577
1715
  variant: "outline",
1578
1716
  size: "icon",
1579
- label: Je(),
1580
- icon: F.fullscreen(),
1717
+ label: Xe(),
1718
+ icon: L.fullscreen(),
1581
1719
  onClick: () => {
1582
1720
  this.options.onFullscreen?.();
1583
1721
  }
@@ -1586,112 +1724,133 @@ var dn = class {
1586
1724
  destroy() {
1587
1725
  document.removeEventListener("fullscreenchange", this.onFullscreenChange);
1588
1726
  }
1589
- }, Z = .5, pn = class e {
1727
+ }, Z = .5, _n = class e {
1590
1728
  element;
1591
1729
  constructor(t, n) {
1592
1730
  this.element = Object.assign(document.createElement("div"), { className: "vd-camera-controls" });
1593
- let r = n.rotation, i = n.tilt, a = n.zoom, o = 0, s = (e) => Math.max(n.limits?.minZoom ?? 1, Math.min(n.limits?.maxZoom ?? Infinity, e)), c = (e) => {
1594
- let t = n.limits?.minRotate, r = n.limits?.maxRotate;
1595
- return t !== void 0 || r !== void 0 ? Math.max(t ?? -Infinity, Math.min(r ?? Infinity, e)) : e;
1596
- }, l = (e) => {
1597
- let a = n.limits?.minTilt, s = n.limits?.maxTilt;
1598
- if (a !== void 0 || s !== void 0) {
1599
- i = Math.max(a ?? 0, Math.min(s ?? 180, i + e)), t.tilt(i).set();
1600
- return;
1601
- }
1602
- let c = i + e;
1603
- c > 180 || c < 0 ? (i = c > 180 ? 360 - c : -c, o = (o + 180) % 360, t.tilt(i).rotate(r + o).set()) : (i = c, t.tilt(i).set());
1604
- }, u = new I({
1731
+ let r = {
1732
+ targetRotation: n.rotation,
1733
+ targetTilt: n.tilt,
1734
+ targetZoom: n.zoom,
1735
+ thetaOffset: 0
1736
+ }, i = vn(t, n, r);
1737
+ n.onChange((e) => {
1738
+ r.targetRotation = e.rotation - r.thetaOffset, r.targetTilt = e.tilt, r.targetZoom = e.zoom, yn(i, n, e);
1739
+ }), this.element.appendChild(e.buildZoom(i.zoomOut, i.zoomIn)), this.element.appendChild(e.buildDpad(i.tiltUp, i.rotateLeft, i.reset, i.rotateRight, i.tiltDown));
1740
+ }
1741
+ static buildZoom(e, t) {
1742
+ let n = document.createElement("div");
1743
+ return n.className = "vd-zoom", n.appendChild(e.element), n.appendChild(t.element), n;
1744
+ }
1745
+ static buildDpad(e, t, n, r, i) {
1746
+ let a = document.createElement("div");
1747
+ a.className = "vd-dpad";
1748
+ for (let [o, s] of [
1749
+ [e, "up"],
1750
+ [t, "left"],
1751
+ [n, "center"],
1752
+ [r, "right"],
1753
+ [i, "down"]
1754
+ ]) o.element.classList.add(`vd-dpad-${s}`), a.appendChild(o.element);
1755
+ return a;
1756
+ }
1757
+ };
1758
+ function vn(e, t, n) {
1759
+ let r = (e) => Math.max(t.limits?.minZoom ?? 1, Math.min(t.limits?.maxZoom ?? Infinity, e)), i = (e) => {
1760
+ let n = t.limits?.minRotate, r = t.limits?.maxRotate;
1761
+ return n !== void 0 || r !== void 0 ? Math.max(n ?? -Infinity, Math.min(r ?? Infinity, e)) : e;
1762
+ }, a = (r) => {
1763
+ let i = t.limits?.minTilt, a = t.limits?.maxTilt;
1764
+ if (i !== void 0 || a !== void 0) {
1765
+ n.targetTilt = Math.max(i ?? 0, Math.min(a ?? 180, n.targetTilt + r)), e.tilt(n.targetTilt).set();
1766
+ return;
1767
+ }
1768
+ let o = n.targetTilt + r;
1769
+ o > 180 || o < 0 ? (n.targetTilt = o > 180 ? 360 - o : -o, n.thetaOffset = (n.thetaOffset + 180) % 360, e.tilt(n.targetTilt).rotate(n.targetRotation + n.thetaOffset).set()) : (n.targetTilt = o, e.tilt(n.targetTilt).set());
1770
+ };
1771
+ return {
1772
+ zoomOut: new R({
1605
1773
  variant: "outline",
1606
1774
  size: "icon",
1607
- label: vt(),
1608
- icon: F.zoomOut(),
1775
+ label: bt(),
1776
+ icon: L.zoomOut(),
1609
1777
  onClick: () => {
1610
- a = s(a - 10), t.zoom(a).set();
1778
+ n.targetZoom = r(n.targetZoom - 10), e.zoom(n.targetZoom).set();
1611
1779
  }
1612
- }), d = new I({
1780
+ }),
1781
+ zoomIn: new R({
1613
1782
  variant: "outline",
1614
1783
  size: "icon",
1615
- label: mt(),
1616
- icon: F.zoomIn(),
1784
+ label: gt(),
1785
+ icon: L.zoomIn(),
1617
1786
  onClick: () => {
1618
- a = s(a + 10), t.zoom(a).set();
1787
+ n.targetZoom = r(n.targetZoom + 10), e.zoom(n.targetZoom).set();
1619
1788
  }
1620
- }), f = new I({
1789
+ }),
1790
+ tiltUp: new R({
1621
1791
  variant: "outline",
1622
1792
  size: "icon",
1623
- label: At(),
1624
- icon: F.tiltUp(),
1793
+ label: Mt(),
1794
+ icon: L.tiltUp(),
1625
1795
  onClick: () => {
1626
- l(-15);
1796
+ a(-15);
1627
1797
  }
1628
- }), p = new I({
1798
+ }),
1799
+ rotateLeft: new R({
1629
1800
  variant: "outline",
1630
1801
  size: "icon",
1631
- label: St(),
1632
- icon: F.rotateLeft(),
1802
+ label: wt(),
1803
+ icon: L.rotateLeft(),
1633
1804
  onClick: () => {
1634
- r = c(r - 15), t.rotate(r + o).set();
1805
+ n.targetRotation = i(n.targetRotation - 15), e.rotate(n.targetRotation + n.thetaOffset).set();
1635
1806
  }
1636
- }), m = new I({
1807
+ }),
1808
+ reset: new R({
1637
1809
  variant: "outline",
1638
1810
  size: "icon",
1639
- label: ut(),
1640
- icon: F.reset(),
1811
+ label: ft(),
1812
+ icon: L.reset(),
1641
1813
  onClick: () => {
1642
- o = 0, t.reset();
1814
+ n.thetaOffset = 0, e.reset();
1643
1815
  }
1644
- }), h = new I({
1816
+ }),
1817
+ rotateRight: new R({
1645
1818
  variant: "outline",
1646
1819
  size: "icon",
1647
- label: Et(),
1648
- icon: F.rotateRight(),
1820
+ label: Ot(),
1821
+ icon: L.rotateRight(),
1649
1822
  onClick: () => {
1650
- r = c(r + 15), t.rotate(r + o).set();
1823
+ n.targetRotation = i(n.targetRotation + 15), e.rotate(n.targetRotation + n.thetaOffset).set();
1651
1824
  }
1652
- }), g = new I({
1825
+ }),
1826
+ tiltDown: new R({
1653
1827
  variant: "outline",
1654
1828
  size: "icon",
1655
- label: Pt(),
1656
- icon: F.tiltDown(),
1829
+ label: It(),
1830
+ icon: L.tiltDown(),
1657
1831
  onClick: () => {
1658
- l(15);
1832
+ a(15);
1659
1833
  }
1660
- }), _ = (e) => {
1661
- let t = n.limits;
1662
- t !== void 0 && (u.element.disabled = t.minZoom !== void 0 && e.zoom <= t.minZoom + Z, d.element.disabled = t.maxZoom !== void 0 && e.zoom >= t.maxZoom - Z, f.element.disabled = t.minTilt !== void 0 && e.tilt <= t.minTilt + Z, g.element.disabled = t.maxTilt !== void 0 && e.tilt >= t.maxTilt - Z, p.element.disabled = t.minRotate !== void 0 && e.rotation <= t.minRotate + Z, h.element.disabled = t.maxRotate !== void 0 && e.rotation >= t.maxRotate - Z);
1663
- };
1664
- n.onChange((e) => {
1665
- r = e.rotation - o, i = e.tilt, a = e.zoom, _(e);
1666
- }), this.element.appendChild(e.buildZoom(u, d)), this.element.appendChild(e.buildDpad(f, p, m, h, g));
1667
- }
1668
- static buildZoom(e, t) {
1669
- let n = document.createElement("div");
1670
- return n.className = "vd-zoom", n.appendChild(e.element), n.appendChild(t.element), n;
1671
- }
1672
- static buildDpad(e, t, n, r, i) {
1673
- let a = document.createElement("div");
1674
- a.className = "vd-dpad";
1675
- for (let [o, s] of [
1676
- [e, "up"],
1677
- [t, "left"],
1678
- [n, "center"],
1679
- [r, "right"],
1680
- [i, "down"]
1681
- ]) o.element.classList.add(`vd-dpad-${s}`), a.appendChild(o.element);
1682
- return a;
1683
- }
1684
- }, mn = 5;
1834
+ })
1835
+ };
1836
+ }
1837
+ function yn(e, t, n) {
1838
+ let r = t.limits;
1839
+ r !== void 0 && (e.zoomOut.element.disabled = r.minZoom !== void 0 && n.zoom <= r.minZoom + Z, e.zoomIn.element.disabled = r.maxZoom !== void 0 && n.zoom >= r.maxZoom - Z, e.tiltUp.element.disabled = r.minTilt !== void 0 && n.tilt <= r.minTilt + Z, e.tiltDown.element.disabled = r.maxTilt !== void 0 && n.tilt >= r.maxTilt - Z, e.rotateLeft.element.disabled = r.minRotate !== void 0 && n.rotation <= r.minRotate + Z, e.rotateRight.element.disabled = r.maxRotate !== void 0 && n.rotation >= r.maxRotate - Z);
1840
+ }
1841
+ //#endregion
1842
+ //#region src/ui/controls/attribute-group.ts
1843
+ var bn = 5;
1685
1844
  function Q(e) {
1686
1845
  let t = e.replace(/([A-Z])/g, " $1").trim();
1687
1846
  return t.charAt(0).toUpperCase() + t.slice(1).toLowerCase();
1688
1847
  }
1689
- function hn(e, t, n, r, i) {
1848
+ function xn(e, t, n, r, i) {
1690
1849
  let a = document.createElement("div");
1691
1850
  a.className = "vd-attribute", a.dataset.name = e.name;
1692
1851
  let o = document.createElement("span");
1693
1852
  o.className = "vd-attribute-label", o.textContent = Q(e.name), a.appendChild(o);
1694
- let s = e.values.find((n) => t.getValue(e.name, n)?.isSelected === !0), c = e.values.map(Q), l = e.values.length <= mn ? new Zt(e.values, s, c) : new Qt(e.name, e.values, Q(e.name), s, c);
1853
+ let s = e.values.find((n) => t.getValue(e.name, n)?.isSelected === !0), c = e.values.map(Q), l = e.values.length <= bn ? new $t(e.values, s, c) : new en(e.name, e.values, Q(e.name), s, c);
1695
1854
  return l.onSelect((t) => {
1696
1855
  n.dispatch("ui:select", {
1697
1856
  attribute: e.name,
@@ -1706,7 +1865,7 @@ function hn(e, t, n, r, i) {
1706
1865
  }
1707
1866
  //#endregion
1708
1867
  //#region src/ui/styles.ts
1709
- var gn = z.fontFamily.sans.join(", "), $ = "\n position: absolute;\n display: flex;\n z-index: 10;\n", _n = `
1868
+ var Sn = V.fontFamily.sans.join(", "), $ = "\n position: absolute;\n display: flex;\n z-index: 10;\n", Cn = `
1710
1869
  /* Override browser's default black fullscreen backdrop */
1711
1870
  .vd-container:fullscreen {
1712
1871
  background: oklch(100% 0 0);
@@ -1715,51 +1874,51 @@ var gn = z.fontFamily.sans.join(", "), $ = "\n position: absolute;\n display:
1715
1874
  /* Layout slots — four corners */
1716
1875
  .vd-slot-top-right {
1717
1876
  ${$}
1718
- inset-block-start: ${R[3]};
1719
- inset-inline-end: ${R[3]};
1877
+ inset-block-start: ${B[3]};
1878
+ inset-inline-end: ${B[3]};
1720
1879
  flex-direction: column;
1721
1880
  align-items: flex-end;
1722
- gap: ${R[1.5]};
1881
+ gap: ${B[1.5]};
1723
1882
  }
1724
1883
 
1725
1884
  .vd-slot-bottom-left {
1726
1885
  ${$}
1727
- inset-block-end: ${R[3]};
1728
- inset-inline-start: ${R[3]};
1886
+ inset-block-end: ${B[3]};
1887
+ inset-inline-start: ${B[3]};
1729
1888
  flex-direction: column;
1730
1889
  align-items: flex-start;
1731
- gap: ${R[1.5]};
1890
+ gap: ${B[1.5]};
1732
1891
  }
1733
1892
 
1734
1893
  .vd-slot-bottom-right {
1735
1894
  ${$}
1736
- inset-block-end: ${R[3]};
1737
- inset-inline-end: ${R[3]};
1895
+ inset-block-end: ${B[3]};
1896
+ inset-inline-end: ${B[3]};
1738
1897
  flex-direction: row;
1739
- gap: ${R[1.5]};
1898
+ gap: ${B[1.5]};
1740
1899
  }
1741
1900
 
1742
1901
  /* Component styles — no positioning */
1743
1902
  .vd-camera-controls {
1744
1903
  display: flex;
1745
1904
  flex-direction: column;
1746
- gap: ${R[1]};
1747
- background: color-mix(in oklch, ${L.white} 85%, transparent);
1905
+ gap: ${B[1]};
1906
+ background: color-mix(in oklch, ${z.white} 85%, transparent);
1748
1907
  backdrop-filter: blur(8px);
1749
- border-radius: ${R[2]};
1750
- padding: ${R[2]};
1908
+ border-radius: ${B[2]};
1909
+ padding: ${B[2]};
1751
1910
  }
1752
1911
 
1753
1912
  .vd-zoom {
1754
1913
  display: flex;
1755
- gap: ${R[.5]};
1914
+ gap: ${B[.5]};
1756
1915
  }
1757
1916
 
1758
1917
  .vd-dpad {
1759
1918
  display: grid;
1760
- grid-template-columns: repeat(3, ${R[9]});
1761
- grid-template-rows: repeat(3, ${R[9]});
1762
- gap: ${R[.5]};
1919
+ grid-template-columns: repeat(3, ${B[9]});
1920
+ grid-template-rows: repeat(3, ${B[9]});
1921
+ gap: ${B[.5]};
1763
1922
  }
1764
1923
 
1765
1924
  .vd-dpad-up { grid-column: 2; grid-row: 1; }
@@ -1771,40 +1930,40 @@ var gn = z.fontFamily.sans.join(", "), $ = "\n position: absolute;\n display:
1771
1930
  .vd-attributes {
1772
1931
  display: flex;
1773
1932
  flex-direction: column;
1774
- gap: ${R[2]};
1775
- background: color-mix(in oklch, ${L.white} 85%, transparent);
1933
+ gap: ${B[2]};
1934
+ background: color-mix(in oklch, ${z.white} 85%, transparent);
1776
1935
  backdrop-filter: blur(8px);
1777
- border-radius: ${R[2]};
1778
- padding: ${R[2]};
1779
- font-family: ${gn};
1936
+ border-radius: ${B[2]};
1937
+ padding: ${B[2]};
1938
+ font-family: ${Sn};
1780
1939
  }
1781
1940
 
1782
1941
  .vd-attribute {
1783
1942
  display: flex;
1784
1943
  flex-direction: column;
1785
- gap: ${R[1]};
1944
+ gap: ${B[1]};
1786
1945
  }
1787
1946
 
1788
1947
  .vd-attribute-label {
1789
- font-size: ${z.fontSize.xs};
1790
- font-weight: ${z.fontWeight.medium};
1791
- color: ${L.neutral[900]};
1792
- font-family: ${gn};
1948
+ font-size: ${V.fontSize.xs};
1949
+ font-weight: ${V.fontWeight.medium};
1950
+ color: ${z.neutral[900]};
1951
+ font-family: ${Sn};
1793
1952
  }
1794
1953
 
1795
1954
  `;
1796
- function vn() {
1797
- if (nn(), document.getElementById("vd-styles") !== null) return;
1955
+ function wn() {
1956
+ if (on(), document.getElementById("vd-styles") !== null) return;
1798
1957
  let e = document.createElement("style");
1799
- e.id = "vd-styles", e.textContent = _n, document.head.appendChild(e);
1958
+ e.id = "vd-styles", e.textContent = Cn, document.head.appendChild(e);
1800
1959
  }
1801
1960
  //#endregion
1802
1961
  //#region src/ui/standard-interface.ts
1803
- function yn(e, t) {
1962
+ function Tn(e, t) {
1804
1963
  let n = document.createElement("a");
1805
1964
  n.href = `data:image/png;base64,${e}`, n.download = t, n.click();
1806
1965
  }
1807
- var bn = class {
1966
+ var En = class {
1808
1967
  options;
1809
1968
  settings = {};
1810
1969
  container = null;
@@ -1822,15 +1981,18 @@ var bn = class {
1822
1981
  this.options = e;
1823
1982
  }
1824
1983
  attach(e) {
1825
- vn(), this.container = e, this.loading = new dn(e), this.slots.topRight = this.createSlot(e, "vd-slot-top-right"), this.slots.bottomLeft = this.createSlot(e, "vd-slot-bottom-left"), this.slots.bottomRight = this.createSlot(e, "vd-slot-bottom-right"), this.actionBar = new fn({
1984
+ wn(), this.container = e, this.loading = new hn(e), this.slots.topRight = this.createSlot(e, "vd-slot-top-right"), this.slots.bottomLeft = this.createSlot(e, "vd-slot-bottom-left"), this.slots.bottomRight = this.createSlot(e, "vd-slot-bottom-right");
1985
+ }
1986
+ onReady() {
1987
+ this.loading?.hide(), this.loading = null, this.mountToolbar(), this.cameraControls !== null && (this.cameraControls.element.style.display = "flex"), this.attributes !== null && (this.attributes.style.display = "flex");
1988
+ }
1989
+ mountToolbar() {
1990
+ this.actionBar !== null || this.slots.bottomRight === null || (this.actionBar = new gn({
1826
1991
  onAr: this.options.onAr,
1827
1992
  onFullscreen: () => {
1828
1993
  document.fullscreenElement === null ? this.container?.requestFullscreen() : document.exitFullscreen();
1829
1994
  }
1830
- }), this.actionBar.applySettings(this.settings), this.slots.bottomRight.appendChild(this.actionBar.element), this.syncScreenshotButton(), this.placeScreenshotButton();
1831
- }
1832
- onReady() {
1833
- this.loading?.hide(), this.loading = null, this.cameraControls !== null && (this.cameraControls.element.style.display = "flex"), this.attributes !== null && (this.attributes.style.display = "flex");
1995
+ }), this.actionBar.applySettings(this.settings), this.slots.bottomRight.appendChild(this.actionBar.element), this.syncScreenshotButton(), this.placeScreenshotButton());
1834
1996
  }
1835
1997
  updateProgress(e, t) {
1836
1998
  this.loading?.updateProgress(e, t);
@@ -1839,12 +2001,12 @@ var bn = class {
1839
2001
  this.loading?.showError(e);
1840
2002
  }
1841
2003
  applyViewerSettings(e) {
1842
- this.settings = e, e.language !== void 0 && j(e.language), this.syncScreenshotButton(), this.actionBar?.applySettings(e), this.cameraControls !== null && (this.cameraControls.element.style.display = e.cameraControls === !0 ? "flex" : "none"), this.placeScreenshotButton();
2004
+ this.settings = e, e.language !== void 0 && N(e.language, { reload: !1 }), this.syncScreenshotButton(), this.actionBar?.applySettings(e), this.cameraControls !== null && (this.cameraControls.element.style.display = e.cameraControls === !0 ? "flex" : "none"), this.placeScreenshotButton();
1843
2005
  }
1844
2006
  renderAttributeControls(e, t) {
1845
- if (!(this.container === null || this.slots.topRight === null) && (this.cameraControls?.element.remove(), this.cameraControls = null, this.attributes?.remove(), this.attributes = null, this.settings.cameraControls === !0 && (this.cameraControls = new pn(this.options.cameraApi, this.options.cameraPositionApi), this.cameraControls.element.style.display = "none", this.slots.topRight.appendChild(this.cameraControls.element)), this.placeScreenshotButton(), t.length !== 0)) {
2007
+ if (!(this.container === null || this.slots.topRight === null) && (this.cameraControls?.element.remove(), this.cameraControls = null, this.attributes?.remove(), this.attributes = null, this.settings.cameraControls === !0 && (this.cameraControls = new _n(this.options.cameraApi, this.options.cameraPositionApi), this.cameraControls.element.style.display = "none", this.slots.topRight.appendChild(this.cameraControls.element)), this.placeScreenshotButton(), !(t.length === 0 || this.settings.attributeControls === !1))) {
1846
2008
  this.attributes = document.createElement("div"), this.attributes.className = "vd-attributes", this.attributes.style.display = "none";
1847
- for (let n of t) this.attributes.appendChild(hn(n, e, this.options.eventBus, this.options.onSelect, this.options.onSubscribe));
2009
+ for (let n of t) this.attributes.appendChild(xn(n, e, this.options.eventBus, this.options.onSelect, this.options.onSubscribe));
1848
2010
  this.slots.bottomLeft.appendChild(this.attributes);
1849
2011
  }
1850
2012
  }
@@ -1862,14 +2024,14 @@ var bn = class {
1862
2024
  }
1863
2025
  syncScreenshotButton() {
1864
2026
  let e = this.settings.screenshot === !0;
1865
- e && this.screenshotBtn === null && (this.screenshotBtn = new I({
2027
+ e && this.screenshotBtn === null && (this.screenshotBtn = new R({
1866
2028
  variant: "outline",
1867
2029
  size: "icon",
1868
- label: ot(),
1869
- icon: F.screenshot(),
2030
+ label: ct(),
2031
+ icon: L.screenshot(),
1870
2032
  onClick: () => {
1871
2033
  this.options.snapshotApi.take("snapshot.png").onDeveloped(({ data: e, filename: t }) => {
1872
- yn(e, t);
2034
+ Tn(e, t);
1873
2035
  });
1874
2036
  }
1875
2037
  })), !e && this.screenshotBtn !== null && (this.screenshotBtn.element.remove(), this.screenshotBtn = null);
@@ -1877,13 +2039,14 @@ var bn = class {
1877
2039
  placeScreenshotButton() {
1878
2040
  this.screenshotBtn === null || this.slots.topRight === null || (this.cameraControls === null ? this.slots.topRight.appendChild(this.screenshotBtn.element) : this.cameraControls.element.appendChild(this.screenshotBtn.element));
1879
2041
  }
1880
- }, xn = class {
2042
+ }, Dn = class {
1881
2043
  attributes;
1882
2044
  readyStateTracker;
1883
2045
  messenger;
1884
2046
  cameraApi;
1885
2047
  cameraPositionApi;
1886
2048
  snapshotApi;
2049
+ annotationsApi;
1887
2050
  eventBus;
1888
2051
  ui;
1889
2052
  qrModal;
@@ -1897,17 +2060,17 @@ var bn = class {
1897
2060
  let t = (e) => {
1898
2061
  this.messenger.send(e);
1899
2062
  };
1900
- this.attributes = new pe(t, (e, t) => {
2063
+ this.attributes = new ge(t, (e, t) => {
1901
2064
  for (let n of this.mutationFailedCallbacks) n({
1902
2065
  attribute: e,
1903
2066
  value: t
1904
2067
  });
1905
- }), this.snapshotApi = new C(t), this.cameraApi = new x(t), this.cameraPositionApi = new me(), this.eventBus = new he(), this.qrModal = new en(), this.readyStateTracker = new _(() => {
2068
+ }), this.snapshotApi = new S(t), this.annotationsApi = new pe(t), this.cameraApi = new _e(t), this.cameraPositionApi = new ve(), this.eventBus = new be(), this.qrModal = new nn(), this.readyStateTracker = new te(() => {
1906
2069
  let e = this.readyCallbacks;
1907
2070
  this.readyCallbacks = [];
1908
2071
  for (let t of e) t(this);
1909
2072
  this.ui.onReady();
1910
- }), this.ui = new bn({
2073
+ }), this.ui = new En({
1911
2074
  snapshotApi: this.snapshotApi,
1912
2075
  cameraApi: this.cameraApi,
1913
2076
  cameraPositionApi: this.cameraPositionApi,
@@ -1920,28 +2083,49 @@ var bn = class {
1920
2083
  }), this.registerHandlers(), this.messenger.start(), this.createAndConnectIframe();
1921
2084
  }
1922
2085
  registerHandlers() {
1923
- this.messenger.on(y.HANDSHAKE, (e) => {
1924
- ie(e) && (m.info("Server handshake received, flushing publisher queue"), this.messenger.markReady());
1925
- }), this.messenger.on(y.MUTATION, (e) => {
2086
+ this.messenger.on(v.HANDSHAKE, (e) => {
2087
+ ie(e) && (g.info("Server handshake received, flushing publisher queue"), this.messenger.markReady());
2088
+ }), this.messenger.on(v.MUTATION, (e) => {
1926
2089
  ae(e) && this.attributes.handleMutationResult(e);
1927
- }), this.messenger.on(y.SNAPSHOT, (e) => {
2090
+ }), this.messenger.on(v.SNAPSHOT, (e) => {
1928
2091
  oe(e) && this.snapshotApi.handleSnapshotResult(e);
1929
- }), this.messenger.on(y.CAMERA, (e) => {
2092
+ }), this.messenger.on(v.CAMERA, (e) => {
1930
2093
  se(e) && this.cameraPositionApi.handlePositionUpdate(e);
1931
- }), this.messenger.on(y.LOADING_INDICATOR, (e) => {
2094
+ }), this.messenger.on(v.LOADING_INDICATOR, (e) => {
1932
2095
  le(e) && (e.error === void 0 ? this.ui.updateProgress(e.progress, e.phase) : this.ui.showError(e.error));
1933
- }), this.messenger.on(y.CONFIG, (e) => {
1934
- ue(e) && (e.viewerSettings !== void 0 && this.ui.applyViewerSettings(e.viewerSettings), this.cameraPositionApi.applyLimits(e.cameraLimits));
1935
- }), this.messenger.on(y.MAPPING, (e) => {
2096
+ }), this.messenger.on(v.CONFIG, (e) => {
2097
+ ue(e) && this.handleConfig(e);
2098
+ }), this.messenger.on(v.ANNOTATION_PLACED, (e) => {
2099
+ de(e) && this.annotationsApi.handlePlaced(e.position);
2100
+ }), this.messenger.on(v.MAPPING, (e) => {
1936
2101
  ce(e) && (this.attributes.handleMappingReceived(e), this.ui.renderAttributeControls(this.attributes, e.attributes), this.readyStateTracker.handleMappingReceived());
1937
2102
  });
1938
2103
  }
2104
+ handleConfig(e) {
2105
+ let t = e.viewerSettings, n = this.options.viewerSettings;
2106
+ if (t !== void 0 || n !== void 0) {
2107
+ let e = n === void 0 ? t : {
2108
+ ...t ?? {},
2109
+ ...n
2110
+ };
2111
+ if (n !== void 0 && t !== void 0) {
2112
+ let e = Object.entries(n).filter(([e, n]) => t[e] !== n).map(([e, n]) => `${e} (metadata: ${t[e] ?? "undefined"}, override: ${n})`);
2113
+ e.length > 0 && g.warn(`Viewer settings override active: ${e.join(", ")}`);
2114
+ }
2115
+ this.ui.applyViewerSettings(e), this.annotationsApi.setEnabled(e.annotations !== !1);
2116
+ }
2117
+ this.cameraPositionApi.applyLimits(e.cameraLimits);
2118
+ }
1939
2119
  initializeLogging() {
1940
- this.options.debug === !0 && h(), m.info("Initializing Virtualdisplay client", { model: this.options.model });
2120
+ this.options.debug === !0 && _(), g.info("Initializing Virtualdisplay client", { model: this.options.model });
1941
2121
  }
1942
2122
  createAndConnectIframe() {
1943
2123
  let e = new r(this.options).create();
1944
2124
  this.container = e.container, this.iframe = e.iframe, this.eventBus.attach(this.container), this.ui.attach(this.container);
2125
+ try {
2126
+ let e = new URL(this.iframe.src).origin;
2127
+ this.messenger.setTargetOrigin(e);
2128
+ } catch {}
1945
2129
  }
1946
2130
  select(e, t) {
1947
2131
  this.attributes.select(e, t);
@@ -1974,6 +2158,9 @@ var bn = class {
1974
2158
  on(e, t) {
1975
2159
  this.eventBus.on(e, t);
1976
2160
  }
2161
+ get annotations() {
2162
+ return this.annotationsApi;
2163
+ }
1977
2164
  get camera() {
1978
2165
  return this.cameraApi;
1979
2166
  }
@@ -1991,4 +2178,4 @@ var bn = class {
1991
2178
  }
1992
2179
  };
1993
2180
  //#endregion
1994
- export { ee as Attribute, v as AttributeValue, x as Camera, t as ERROR_CODES, S as Photo, C as Snapshot, xn as VirtualdisplayClient, n as VirtualdisplayError, h as enableDebugMode, g as isDebugMode, m as logger };
2181
+ export { pe as Annotations, x as Attribute, me as AttributeValue, _e as Camera, t as ERROR_CODES, ye as Photo, S as Snapshot, Dn as VirtualdisplayClient, n as VirtualdisplayError, _ as enableDebugMode, ee as isDebugMode, g as logger };