@virtualdisplay.io/client 4.0.0-alpha.25 → 4.0.0-alpha.27

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.
@@ -15,76 +15,81 @@ const c = {
15
15
  PRICING: "pricing",
16
16
  QR_SHOWN: "qr_shown",
17
17
  SYNC: "sync",
18
- SELECTABLE: "selectable"
19
- }, tt = {
18
+ SELECTABLE: "selectable",
19
+ APP_RESOLVED: "app_resolved"
20
+ }, F = "main", te = {
20
21
  FOCUS: "focus",
21
22
  UNFOCUS: "unfocus"
22
- }, Tt = {
23
+ }, Ie = {
23
24
  FOCUSED: "focused"
24
- }, Rt = {
25
+ }, Le = {
25
26
  /** Behaves exactly like an unpriced combination: no price, no button. */
26
27
  HIDDEN: "hidden"
27
- }, It = new Set(Object.values(c));
28
- function Lt(n) {
28
+ }, Oe = new Set(Object.values(c));
29
+ function Ne(n) {
29
30
  if (typeof n != "object" || n === null)
30
31
  return !1;
31
- const t = n;
32
- return typeof t.target == "string" ? !1 : typeof t.type == "string" && It.has(t.type);
32
+ const e = n;
33
+ return typeof e.target == "string" ? !1 : typeof e.type == "string" && Oe.has(e.type);
33
34
  }
34
- function Ot(n) {
35
- const t = S(n);
36
- return t !== null && t.type === c.HANDSHAKE;
35
+ function Me(n) {
36
+ const e = S(n);
37
+ return e !== null && e.type === c.HANDSHAKE;
37
38
  }
38
- function Nt(n) {
39
- const t = S(n);
40
- return t !== null && t.type === c.SESSION && typeof t.sessionId == "string";
39
+ function ze(n) {
40
+ const e = S(n);
41
+ return e !== null && e.type === c.SESSION && typeof e.sessionId == "string";
42
+ }
43
+ function Pe(n) {
44
+ const e = S(n);
45
+ return e !== null && e.type === c.APP_RESOLVED && typeof e.appType == "string" && e.appType !== "" && typeof e.name == "string";
41
46
  }
42
- function Mt(n) {
43
- const t = S(n);
44
- return t !== null && t.type === c.MUTATION && Array.isArray(t.results);
47
+ function Fe(n) {
48
+ const e = S(n);
49
+ return e !== null && e.type === c.MUTATION && typeof e.instance == "string" && e.instance !== "" && Array.isArray(e.results);
45
50
  }
46
- function zt(n) {
47
- const t = S(n);
48
- return t !== null && t.type === c.SNAPSHOT && ("data" in t || "error" in t);
51
+ function De(n) {
52
+ const e = S(n);
53
+ return e !== null && e.type === c.SNAPSHOT && ("data" in e || "error" in e);
49
54
  }
50
- function Pt(n) {
51
- const t = S(n);
52
- return t !== null && t.type === c.CAMERA && Array.isArray(t.transforms);
55
+ function $e(n) {
56
+ const e = S(n);
57
+ return e !== null && e.type === c.CAMERA && Array.isArray(e.transforms);
53
58
  }
54
- function Ft(n) {
55
- const t = S(n);
56
- return t !== null && t.type === c.MAPPING && Array.isArray(t.attributes);
59
+ function Ue(n) {
60
+ const e = S(n);
61
+ return e !== null && e.type === c.MAPPING && typeof e.instance == "string" && e.instance !== "" && Array.isArray(e.attributes);
57
62
  }
58
- function $t(n) {
59
- const t = S(n);
60
- return t !== null && t.type === c.LOADING_INDICATOR && typeof t.progress == "number";
63
+ function Be(n) {
64
+ const e = S(n);
65
+ return e !== null && e.type === c.LOADING_INDICATOR && typeof e.progress == "number";
61
66
  }
62
- function Dt(n) {
63
- const t = S(n);
64
- return t !== null && t.type === c.SYNC && typeof t.connected == "boolean";
67
+ function Ve(n) {
68
+ const e = S(n);
69
+ return e !== null && e.type === c.SYNC && typeof e.connected == "boolean";
65
70
  }
66
- function Bt(n) {
67
- const t = S(n);
68
- return t !== null && t.type === c.SELECTABLE && Array.isArray(t.attributes);
71
+ function je(n) {
72
+ const e = S(n);
73
+ return e !== null && e.type === c.SELECTABLE && typeof e.instance == "string" && e.instance !== "" && Array.isArray(e.attributes);
69
74
  }
70
- function Ut(n) {
71
- const t = S(n);
72
- return t !== null && t.type === c.CONFIG && typeof t.viewerSettings == "object";
75
+ function He(n) {
76
+ const e = S(n);
77
+ return e !== null && e.type === c.CONFIG && typeof e.viewerSettings == "object";
73
78
  }
74
- function Vt(n) {
75
- const t = S(n);
76
- return t !== null && t.type === c.FOCUS && typeof t.state == "string";
79
+ function qe(n) {
80
+ const e = S(n);
81
+ return e !== null && e.type === c.FOCUS && typeof e.instance == "string" && e.instance !== "" && typeof e.state == "string";
77
82
  }
78
- function jt(n) {
79
- const t = S(n);
80
- return t !== null && t.type === c.PRICING && typeof t.pricing == "object" && t.pricing !== null;
83
+ function Ge(n) {
84
+ const e = S(n);
85
+ return e !== null && e.type === c.PRICING && typeof e.instance == "string" && e.instance !== "" && typeof e.pricing == "object" && e.pricing !== null;
81
86
  }
82
87
  function S(n) {
83
88
  return typeof n != "object" || n === null ? null : n;
84
89
  }
85
- class et {
86
- constructor(t) {
87
- this.processor = t;
90
+ class ne {
91
+ constructor(e) {
92
+ this.processor = e;
88
93
  }
89
94
  processor;
90
95
  pending = [];
@@ -92,12 +97,12 @@ class et {
92
97
  /**
93
98
  * Add a message — processed immediately if ready, queued otherwise
94
99
  */
95
- enqueue(t) {
100
+ enqueue(e) {
96
101
  if (this.isReady) {
97
- this.processor(t);
102
+ this.processor(e);
98
103
  return;
99
104
  }
100
- this.pending.push(t);
105
+ this.pending.push(e);
101
106
  }
102
107
  /**
103
108
  * Mark as ready and flush all pending messages
@@ -105,10 +110,10 @@ class et {
105
110
  markReady() {
106
111
  if (this.isReady || (this.isReady = !0, this.pending.length === 0))
107
112
  return;
108
- const t = [...this.pending];
113
+ const e = [...this.pending];
109
114
  this.pending.length = 0;
110
- for (const e of t)
111
- this.processor(e);
115
+ for (const t of e)
116
+ this.processor(t);
112
117
  }
113
118
  get ready() {
114
119
  return this.isReady;
@@ -119,8 +124,8 @@ class et {
119
124
  /**
120
125
  * Check if a message of a specific type is pending
121
126
  */
122
- hasPending(t) {
123
- return this.pending.some((e) => e.type === t);
127
+ hasPending(e) {
128
+ return this.pending.some((t) => t.type === e);
124
129
  }
125
130
  /**
126
131
  * Clear all pending messages
@@ -129,9 +134,9 @@ class et {
129
134
  this.pending.length = 0;
130
135
  }
131
136
  }
132
- class Ht {
133
- constructor(t, e) {
134
- this.getTarget = t, this.sourceId = `vd-${Math.random().toString(36).slice(2, 8)}`, this.targetOrigin = "*", this.isValid = e?.isValid ?? Lt, this.publisher = new et((i) => this.post(i)), this.consumer = new et((i) => this.routeToHandler(i)), e?.bufferIncoming !== !0 && this.consumer.markReady();
137
+ class Ze {
138
+ constructor(e, t) {
139
+ this.getTarget = e, this.sourceId = `vd-${Math.random().toString(36).slice(2, 8)}`, this.targetOrigin = "*", this.isValid = t?.isValid ?? Ne, this.publisher = new ne((i) => this.post(i)), this.consumer = new ne((i) => this.routeToHandler(i)), t?.bufferIncoming !== !0 && this.consumer.markReady();
135
140
  }
136
141
  getTarget;
137
142
  handlers = /* @__PURE__ */ new Map();
@@ -144,22 +149,22 @@ class Ht {
144
149
  /**
145
150
  * Register a handler for a specific message type
146
151
  */
147
- on(t, e) {
148
- this.handlers.set(t, e);
152
+ on(e, t) {
153
+ this.handlers.set(e, t);
149
154
  }
150
155
  /**
151
156
  * Update the target origin for outgoing postMessage calls.
152
157
  * Use when the target origin is discovered at runtime (e.g. from the first incoming message).
153
158
  */
154
- setTargetOrigin(t) {
155
- this.targetOrigin = t;
159
+ setTargetOrigin(e) {
160
+ this.targetOrigin = e;
156
161
  }
157
162
  /**
158
163
  * Send a message to the target window
159
164
  * Queued until markReady() is called
160
165
  */
161
- send(t) {
162
- this.publisher.enqueue(t);
166
+ send(e) {
167
+ this.publisher.enqueue(e);
163
168
  }
164
169
  /**
165
170
  * Feed a message through the same routing path as one that just arrived via
@@ -170,8 +175,8 @@ class Ht {
170
175
  * viewer engine's SSE-sourced live sync channel, ar-session-handoff) and
171
176
  * needs them to land exactly where a postMessage would.
172
177
  */
173
- receive(t) {
174
- this.isValid(t) && this.consumer.enqueue(t);
178
+ receive(e) {
179
+ this.isValid(e) && this.consumer.enqueue(e);
175
180
  }
176
181
  /**
177
182
  * Enable sending and flush queued outgoing messages
@@ -189,22 +194,22 @@ class Ht {
189
194
  /**
190
195
  * Check if an incoming message of a specific type is pending in the consumer buffer
191
196
  */
192
- consumerHasPending(t) {
193
- return this.consumer.hasPending(t);
197
+ consumerHasPending(e) {
198
+ return this.consumer.hasPending(e);
194
199
  }
195
200
  /**
196
201
  * Start listening for incoming messages
197
202
  */
198
203
  start() {
199
- this.listener === null && (this.listener = (t) => {
200
- const { data: e } = t;
201
- if (!this.isValid(e) || e._source === this.sourceId)
204
+ this.listener === null && (this.listener = (e) => {
205
+ const { data: t } = e;
206
+ if (!this.isValid(t) || t._source === this.sourceId)
202
207
  return;
203
208
  const i = this.getTarget();
204
- if (i !== null && t.source !== null && t.source !== i)
209
+ if (i !== null && e.source !== null && e.source !== i)
205
210
  return;
206
- const o = e;
207
- this.consumer.enqueue(o);
211
+ const s = t;
212
+ this.consumer.enqueue(s);
208
213
  }, window.addEventListener("message", this.listener));
209
214
  }
210
215
  /**
@@ -213,48 +218,38 @@ class Ht {
213
218
  destroy() {
214
219
  this.listener !== null && (window.removeEventListener("message", this.listener), this.listener = null), this.publisher.clear(), this.consumer.clear(), this.handlers.clear();
215
220
  }
216
- /**
217
- * Whether the messenger is ready to send
218
- */
219
- get ready() {
220
- return this.publisher.ready;
221
- }
222
- /**
223
- * Number of messages waiting in the outgoing queue
224
- */
225
- get pendingCount() {
226
- return this.publisher.pendingCount;
227
- }
228
- post(t) {
229
- const e = this.getTarget();
230
- e !== null && e.postMessage({ ...t, _source: this.sourceId }, this.targetOrigin);
221
+ post(e) {
222
+ const t = this.getTarget();
223
+ t !== null && t.postMessage({ ...e, _source: this.sourceId }, this.targetOrigin);
231
224
  }
232
- routeToHandler(t) {
233
- const e = this.handlers.get(t.type);
234
- if (e === void 0)
225
+ routeToHandler(e) {
226
+ const t = this.handlers.get(e.type);
227
+ if (t === void 0)
235
228
  return;
236
- const i = e(t);
237
- i instanceof Promise && i.catch((o) => {
238
- const s = o instanceof Error ? o.message : String(o);
239
- console.error(`Virtualdisplay: error handling ${t.type}: ${s}`);
229
+ const i = t(e);
230
+ i instanceof Promise && i.catch((s) => {
231
+ const o = s instanceof Error ? s.message : String(s);
232
+ console.error(`Virtualdisplay: error handling ${e.type}: ${o}`);
240
233
  });
241
234
  }
242
235
  }
243
- class qt {
244
- constructor(t) {
245
- this.send = t;
236
+ class We {
237
+ constructor(e, t) {
238
+ this.send = e, this.instance = t;
246
239
  }
247
240
  send;
248
- setEnabled(t) {
241
+ instance;
242
+ setEnabled(e) {
249
243
  this.send({
250
244
  type: c.ANNOTATION_TOGGLE,
251
- enabled: t
245
+ instance: this.instance,
246
+ enabled: e
252
247
  });
253
248
  }
254
249
  }
255
- class Gt {
256
- constructor(t, e) {
257
- this.value = t, this.attribute = e;
250
+ class Ye {
251
+ constructor(e, t) {
252
+ this.value = e, this.attribute = t;
258
253
  }
259
254
  value;
260
255
  attribute;
@@ -262,8 +257,8 @@ class Gt {
262
257
  get isSelected() {
263
258
  return this.isSelectedValue;
264
259
  }
265
- setSelected(t) {
266
- this.isSelectedValue = t;
260
+ setSelected(e) {
261
+ this.isSelectedValue = e;
267
262
  }
268
263
  }
269
264
  const A = {
@@ -274,385 +269,396 @@ const A = {
274
269
  INVALID_PARAMETER: "INVALID_PARAMETER",
275
270
  SNAPSHOT_FAILED: "SNAPSHOT_FAILED"
276
271
  };
277
- class f extends Error {
272
+ class g extends Error {
278
273
  code;
279
- constructor(t, e) {
280
- super(t), this.name = "VirtualdisplayError", this.code = e;
274
+ constructor(e, t) {
275
+ super(e), this.name = "VirtualdisplayError", this.code = t;
281
276
  }
282
- static valueNotFound(t, e) {
283
- return new f(
284
- `Value "${e}" not found for attribute "${t}"`,
277
+ static valueNotFound(e, t) {
278
+ return new g(
279
+ `Value "${t}" not found for attribute "${e}"`,
285
280
  A.VALUE_NOT_FOUND
286
281
  );
287
282
  }
288
- static parentNotFound(t) {
289
- return new f(
290
- `Parent element not found: ${t}`,
283
+ static parentNotFound(e) {
284
+ return new g(
285
+ `Parent element not found: ${e}`,
291
286
  A.PARENT_NOT_FOUND
292
287
  );
293
288
  }
294
- static invalidParameter(t) {
295
- return new f(t, A.INVALID_PARAMETER);
289
+ static invalidParameter(e) {
290
+ return new g(e, A.INVALID_PARAMETER);
296
291
  }
297
292
  }
298
- class Zt {
293
+ class Qe {
299
294
  name;
300
295
  defaultValue;
301
296
  values;
302
297
  onSelect;
303
298
  onChangeCallback;
304
- constructor(t) {
305
- this.name = t.name, this.defaultValue = t.defaultValue, this.onSelect = t.onSelect, this.values = this.createValues(t.values);
299
+ constructor(e) {
300
+ this.name = e.name, this.defaultValue = e.defaultValue, this.onSelect = e.onSelect, this.values = this.createValues(e.values);
306
301
  }
307
302
  /**
308
303
  * Select a value for this attribute
309
304
  * @throws {VirtualdisplayError} When value not found
310
305
  */
311
- select(t) {
312
- if (!this.values.has(t))
313
- throw f.valueNotFound(this.name, t);
314
- this.onSelect(this.name, t);
306
+ select(e) {
307
+ if (!this.values.has(e))
308
+ throw g.valueNotFound(this.name, e);
309
+ this.onSelect(this.name, e);
315
310
  }
316
311
  getValues() {
317
312
  return Array.from(this.values.values());
318
313
  }
319
- getValue(t) {
320
- return this.values.get(t);
314
+ getValue(e) {
315
+ return this.values.get(e);
321
316
  }
322
317
  /** The currently selected value, or undefined before any selection lands. */
323
318
  get selected() {
324
- for (const t of this.values.values())
325
- if (t.isSelected)
326
- return t.value;
319
+ for (const e of this.values.values())
320
+ if (e.isSelected)
321
+ return e.value;
327
322
  }
328
323
  /**
329
324
  * Register callback that fires when selection changes
330
325
  * Receives the newly selected AttributeValue
331
326
  */
332
- onChange(t) {
333
- this.onChangeCallback = t;
327
+ onChange(e) {
328
+ this.onChangeCallback = e;
334
329
  }
335
330
  /**
336
331
  * Update selection state from server mutation result
337
332
  * Direct value comparison - no source/target translation
338
333
  */
339
- handleResult(t) {
340
- let e;
334
+ handleResult(e) {
335
+ let t;
341
336
  for (const i of this.values.values()) {
342
- const o = i.value === t;
343
- i.setSelected(o), o && (e = i);
337
+ const s = i.value === e;
338
+ i.setSelected(s), s && (t = i);
344
339
  }
345
- e !== void 0 && this.onChangeCallback !== void 0 && this.onChangeCallback(e);
340
+ t !== void 0 && this.onChangeCallback !== void 0 && this.onChangeCallback(t);
346
341
  }
347
- createValues(t) {
348
- const e = /* @__PURE__ */ new Map();
349
- for (const i of t) {
350
- const o = new Gt(i, this.name);
351
- i === this.defaultValue && o.setSelected(!0), e.set(i, o);
342
+ createValues(e) {
343
+ const t = /* @__PURE__ */ new Map();
344
+ for (const i of e) {
345
+ const s = new Ye(i, this.name);
346
+ i === this.defaultValue && s.setSelected(!0), t.set(i, s);
352
347
  }
353
- return e;
348
+ return t;
354
349
  }
355
350
  }
356
- class Wt {
351
+ class Ke {
357
352
  attributes = /* @__PURE__ */ new Map();
358
- constructor(t, e, i) {
359
- for (const o of t) {
360
- const s = this.buildOptions(o, e);
361
- this.attributes.set(o.name, new Zt(s));
353
+ constructor(e, t, i) {
354
+ for (const s of e) {
355
+ const o = this.buildOptions(s, t);
356
+ this.attributes.set(s.name, new Qe(o));
362
357
  }
363
358
  this.onMutationFailed = i;
364
359
  }
365
360
  onMutationFailed;
366
- get(t) {
367
- return this.attributes.get(t);
361
+ get(e) {
362
+ return this.attributes.get(e);
368
363
  }
369
364
  /** The current selection as attribute name→value pairs, skipping unset attributes. */
370
365
  getSelection() {
371
- const t = {};
372
- for (const [e, i] of this.attributes) {
373
- const o = i.selected;
374
- o !== void 0 && (t[e] = o);
366
+ const e = {};
367
+ for (const [t, i] of this.attributes) {
368
+ const s = i.selected;
369
+ s !== void 0 && (e[t] = s);
375
370
  }
376
- return t;
371
+ return e;
377
372
  }
378
- handleResults(t) {
379
- for (const e of t) {
380
- if (!e.success) {
381
- this.onMutationFailed?.(e.name, e.value);
373
+ handleResults(e) {
374
+ for (const t of e) {
375
+ if (!t.success) {
376
+ this.onMutationFailed?.(t.name, t.value);
382
377
  continue;
383
378
  }
384
- this.get(e.name)?.handleResult(e.value);
379
+ this.get(t.name)?.handleResult(t.value);
385
380
  }
386
381
  }
387
- buildOptions(t, e) {
382
+ buildOptions(e, t) {
388
383
  const i = {
389
- name: t.name,
390
- values: t.values,
391
- onSelect: (o, s) => {
392
- e([{ name: o, value: s }], !1);
384
+ name: e.name,
385
+ values: e.values,
386
+ onSelect: (s, o) => {
387
+ t([{ name: s, value: o }], !1);
393
388
  }
394
389
  };
395
- return t.defaultValue !== void 0 ? { ...i, defaultValue: t.defaultValue } : i;
390
+ return e.defaultValue !== void 0 ? { ...i, defaultValue: e.defaultValue } : i;
396
391
  }
397
392
  }
398
- const N = 4096, F = 16384, Yt = [1024, 256, 64], Qt = 20, Y = ["timestamp", "level", "msg", "service", "trace_id", "span_id"];
399
- function Kt(n) {
400
- const t = new Date(n.timestamp).toLocaleTimeString("en-GB", { hour12: !1 }), e = n.level.toUpperCase().padEnd(5), i = n.trace_id?.slice(0, 8) ?? "--------", o = n.msg, s = Object.entries(n).filter(([r]) => !Y.includes(r)).map(([r, a]) => `${r}=${I(a, N).line}`).join(" ");
401
- return `${t} ${e} [${i}] ${o}${s ? " " + s : ""}`;
393
+ const N = 4096, D = 16384, Xe = [1024, 256, 64], Je = 20, Y = ["timestamp", "level", "msg", "service", "trace_id", "span_id"];
394
+ function et(n) {
395
+ const e = new Date(n.timestamp).toLocaleTimeString("en-GB", { hour12: !1 }), t = n.level.toUpperCase().padEnd(5), i = n.trace_id?.slice(0, 8) ?? "--------", s = n.msg, o = Object.entries(n).filter(([r]) => !Y.includes(r)).map(([r, a]) => `${r}=${L(a, N).line}`).join(" ");
396
+ return `${e} ${t} [${i}] ${s}${o ? " " + o : ""}`;
402
397
  }
403
- function Xt(n) {
404
- for (const o of [N, ...Yt]) {
405
- const { line: s, truncated: r } = I(n, o);
398
+ function tt(n) {
399
+ for (const s of [N, ...Xe]) {
400
+ const { line: o, truncated: r } = L(n, s);
406
401
  if (!r) {
407
- if (s.length <= F)
408
- return s;
402
+ if (o.length <= D)
403
+ return o;
409
404
  continue;
410
405
  }
411
- const { line: a } = I({ ...n, log_truncated: !0 }, o);
412
- if (a.length <= F)
406
+ const { line: a } = L({ ...n, log_truncated: !0 }, s);
407
+ if (a.length <= D)
413
408
  return a;
414
409
  }
415
- const t = Object.keys(n).filter((o) => !Y.includes(o)), e = { ...te(n, Y), log_truncated: !0, log_dropped_count: t.length }, i = I({ ...e, log_dropped_attrs: t.slice(0, Qt) }, N);
416
- return i.line.length <= F ? i.line : I(e, N).line;
410
+ const e = Object.keys(n).filter((s) => !Y.includes(s)), t = { ...it(n, Y), log_truncated: !0, log_dropped_count: e.length }, i = L({ ...t, log_dropped_attrs: e.slice(0, Je) }, N);
411
+ return i.line.length <= D ? i.line : L(t, N).line;
417
412
  }
418
- function I(n, t) {
419
- const e = [];
413
+ function L(n, e) {
414
+ const t = [];
420
415
  let i = !1;
421
416
  return { line: JSON.stringify(n, function(r, a) {
422
417
  if (typeof a == "string")
423
- return a.length > t && (i = !0), Jt(a, t);
418
+ return a.length > e && (i = !0), nt(a, e);
424
419
  if (typeof a == "bigint")
425
420
  return a.toString();
426
421
  if (typeof a != "object" || a === null)
427
422
  return a;
428
- for (; e.length > 0 && e.at(-1) !== this; )
429
- e.pop();
430
- return e.includes(a) ? "[Circular]" : (e.push(a), a);
423
+ for (; t.length > 0 && t.at(-1) !== this; )
424
+ t.pop();
425
+ return t.includes(a) ? "[Circular]" : (t.push(a), a);
431
426
  }), truncated: i };
432
427
  }
433
- function Jt(n, t) {
434
- return n.length <= t ? n : `${n.slice(0, t)}...[truncated ${n.length - t} chars]`;
428
+ function nt(n, e) {
429
+ return n.length <= e ? n : `${n.slice(0, e)}...[truncated ${n.length - e} chars]`;
435
430
  }
436
- function te(n, t) {
437
- const e = {};
438
- for (const i of t)
439
- n[i] !== void 0 && (e[i] = n[i]);
440
- return e;
431
+ function it(n, e) {
432
+ const t = {};
433
+ for (const i of e)
434
+ n[i] !== void 0 && (t[i] = n[i]);
435
+ return t;
441
436
  }
442
- function ee(n, t) {
443
- const e = t ? Kt(n) : Xt(n);
444
- n.level === "error" ? console.error(e) : n.level === "warn" ? console.warn(e) : console.log(e);
437
+ function st(n, e) {
438
+ const t = e ? et(n) : tt(n);
439
+ n.level === "error" ? console.error(t) : n.level === "warn" ? console.warn(t) : console.log(t);
445
440
  }
446
- function mt(n, t = 0) {
447
- const e = {
441
+ function fe(n, e = 0) {
442
+ const t = {
448
443
  name: n.name,
449
444
  message: n.message
450
445
  };
451
- n.stack !== void 0 && (e.stack = n.stack);
446
+ n.stack !== void 0 && (t.stack = n.stack);
452
447
  for (const i of Object.getOwnPropertyNames(n)) {
453
448
  if (i === "name" || i === "message" || i === "stack" || i === "cause")
454
449
  continue;
455
- const o = n[i];
456
- o !== void 0 && (e[i] = o);
450
+ const s = n[i];
451
+ s !== void 0 && (t[i] = s);
457
452
  }
458
- return n.cause !== void 0 && n.cause !== null && (e.cause = n.cause instanceof Error && t < 5 ? mt(n.cause, t + 1) : String(n.cause)), e;
453
+ return n.cause !== void 0 && n.cause !== null && (t.cause = n.cause instanceof Error && e < 5 ? fe(n.cause, e + 1) : String(n.cause)), t;
459
454
  }
460
- function ne(n) {
461
- const t = {};
462
- for (const [e, i] of Object.entries(n))
463
- t[e] = i instanceof Error ? mt(i) : i;
464
- return t;
455
+ function ot(n) {
456
+ const e = {};
457
+ for (const [t, i] of Object.entries(n))
458
+ e[t] = i instanceof Error ? fe(i) : i;
459
+ return e;
465
460
  }
466
- function ie() {
461
+ function rt() {
467
462
  return /* @__PURE__ */ new Date();
468
463
  }
469
- function oe(n) {
464
+ function at(n) {
470
465
  return n.toISOString();
471
466
  }
472
- function pt() {
467
+ function ge() {
473
468
  return typeof navigator > "u" ? "" : navigator.userAgent;
474
469
  }
475
- function se() {
470
+ function lt() {
476
471
  return typeof navigator > "u" ? !1 : navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1;
477
472
  }
478
- function re() {
479
- return /iPhone|iPad|iPod/i.test(pt()) || se();
473
+ function ct() {
474
+ return /iPhone|iPad|iPod/i.test(ge()) || lt();
480
475
  }
481
- function ae() {
482
- return /Android/i.test(pt());
476
+ function ut() {
477
+ return /Android/i.test(ge());
483
478
  }
484
- function le() {
485
- return re() || ae();
479
+ function dt() {
480
+ return ct() || ut();
486
481
  }
487
- class ce {
488
- constructor(t) {
489
- this.config = t;
482
+ class ht {
483
+ constructor(e) {
484
+ this.config = e;
490
485
  }
491
486
  config;
492
487
  /**
493
488
  * Log at specified level with optional attributes.
494
489
  */
495
- log(t, e, i = {}) {
496
- const o = this.config.traceProvider?.() ?? {}, s = {
497
- timestamp: oe(ie()),
498
- level: t,
499
- msg: e,
490
+ log(e, t, i = {}) {
491
+ const s = this.config.traceProvider?.() ?? {}, o = {
492
+ timestamp: at(rt()),
493
+ level: e,
494
+ msg: t,
500
495
  service: this.config.service,
501
- ...o,
502
- ...ne(i)
496
+ ...s,
497
+ ...ot(i)
503
498
  };
504
- ee(s, this.config.isDev);
499
+ st(o, this.config.isDev);
505
500
  }
506
501
  /**
507
502
  * Log at DEBUG level (development only).
508
503
  */
509
- debug(t, e) {
510
- this.config.isDev && this.log("debug", t, e);
504
+ debug(e, t) {
505
+ this.config.isDev && this.log("debug", e, t);
511
506
  }
512
507
  /**
513
508
  * Log at INFO level.
514
509
  */
515
- info(t, e) {
516
- this.log("info", t, e);
510
+ info(e, t) {
511
+ this.log("info", e, t);
517
512
  }
518
513
  /**
519
514
  * Log at WARN level.
520
515
  */
521
- warn(t, e) {
522
- this.log("warn", t, e);
516
+ warn(e, t) {
517
+ this.log("warn", e, t);
523
518
  }
524
519
  /**
525
520
  * Log at ERROR level.
526
521
  */
527
- error(t, e) {
528
- this.log("error", t, e);
522
+ error(e, t) {
523
+ this.log("error", e, t);
529
524
  }
530
525
  }
531
- function ft(n, t) {
532
- const e = t?.isDev !== void 0 ? t.isDev : typeof process < "u" ? process.env.NODE_ENV !== "production" : !0;
533
- return new ce({ service: n, isDev: e, traceProvider: t?.traceProvider });
526
+ function be(n, e) {
527
+ const t = e?.isDev !== void 0 ? e.isDev : typeof process < "u" ? process.env.NODE_ENV !== "production" : !0;
528
+ return new ht({ service: n, isDev: t, traceProvider: e?.traceProvider });
534
529
  }
535
530
  function O(n) {
536
531
  if (n !== void 0)
537
532
  return typeof n == "object" && n !== null && !Array.isArray(n) && !(n instanceof Error) ? n : n instanceof Error ? { error: n.message } : { value: n };
538
533
  }
539
- function gt(n) {
534
+ function ve(n) {
540
535
  return {
541
- debug: (t, e) => n.debug(t, O(e)),
542
- info: (t, e) => n.info(t, O(e)),
543
- warn: (t, e) => n.warn(t, O(e)),
544
- error: (t, e) => n.error(t, O(e))
536
+ debug: (e, t) => n.debug(e, O(t)),
537
+ info: (e, t) => n.info(e, O(t)),
538
+ warn: (e, t) => n.warn(e, O(t)),
539
+ error: (e, t) => n.error(e, O(t))
545
540
  };
546
541
  }
547
- let bt = !1, _ = gt(ft("client", { isDev: !1 }));
548
- function de() {
549
- bt = !0, _ = gt(ft("client", { isDev: !0 }));
542
+ let ye = !1, C = ve(be("client", { isDev: !1 }));
543
+ function mt() {
544
+ ye = !0, C = ve(be("client", { isDev: !0 }));
550
545
  }
551
- function uo() {
552
- return bt;
546
+ function gs() {
547
+ return ye;
553
548
  }
554
- class ue {
555
- constructor(t, e) {
556
- this.send = t, this.onMutationFailed = e;
549
+ class pt {
550
+ constructor(e, t, i) {
551
+ this.send = e, this.instance = t, this.onMutationFailed = i;
557
552
  }
558
553
  send;
554
+ instance;
559
555
  onMutationFailed;
560
556
  registry;
561
557
  pendingCallbacks = [];
562
558
  /**
563
559
  * Handle incoming MAPPING message from server
564
560
  */
565
- handleMappingReceived(t) {
566
- _.debug("Initializing from server mapping", {
567
- attributeCount: t.attributes.length
568
- }), this.registry = new Wt(
569
- t.attributes,
570
- (e, i) => this.sendMutation(e, i),
561
+ handleMappingReceived(e) {
562
+ C.debug("Initializing from server mapping", {
563
+ attributeCount: e.attributes.length
564
+ }), this.registry = new Ke(
565
+ e.attributes,
566
+ (t, i) => this.sendMutation(t, i),
571
567
  this.onMutationFailed
572
568
  ), this.replayPendingCallbacks();
573
569
  }
574
- handleMutationResult(t) {
575
- this.registry?.handleResults(t.results);
570
+ handleMutationResult(e) {
571
+ this.registry?.handleResults(e.results);
576
572
  }
577
573
  /**
578
574
  * Select a value for an attribute - sends mutation to server.
579
575
  * Can be called before the mapping arrives — the mutation is sent immediately
580
576
  * and the messenger's publisher queue holds it until the iframe is ready.
581
577
  */
582
- select(t, e) {
583
- this.sendMutation([{ name: t, value: e }], !1);
578
+ select(e, t) {
579
+ this.sendMutation([{ name: e, value: t }], !1);
580
+ }
581
+ /**
582
+ * A drag's intermediate step (parametric dimensions): the viewer applies it
583
+ * so the model follows the hand, but it is never recorded as a choice; the
584
+ * settling `select()` is the one tracked value. Used by the measurement
585
+ * slider per step crossed. Deliberately not delegated on the public client:
586
+ * `select()` staying the whole choice API is the spec's own evidence the
587
+ * shape is right, and no integrator has asked for live-follow yet.
588
+ */
589
+ selectTransient(e, t) {
590
+ this.sendMutation([{ name: e, value: t }], !1, !0);
584
591
  }
585
- getValues(t) {
586
- return this.registry?.get(t)?.getValues() ?? [];
592
+ getValues(e) {
593
+ return this.registry?.get(e)?.getValues() ?? [];
587
594
  }
588
- getValue(t, e) {
589
- return this.registry?.get(t)?.getValue(e);
595
+ getValue(e, t) {
596
+ return this.registry?.get(e)?.getValue(t);
590
597
  }
591
598
  /**
592
599
  * Register onChange callback for an attribute.
593
600
  * Buffers the callback if the mapping hasn't arrived yet.
594
601
  */
595
- onChange(t, e) {
602
+ onChange(e, t) {
596
603
  if (this.registry === void 0) {
597
- this.pendingCallbacks.push({ name: t, callback: e });
604
+ this.pendingCallbacks.push({ name: e, callback: t });
598
605
  return;
599
606
  }
600
- const i = this.registry.get(t);
607
+ const i = this.registry.get(e);
601
608
  if (i === void 0) {
602
- _.warn(`onChange: attribute "${t}" not found — callback will not fire`);
609
+ C.warn(`onChange: attribute "${e}" not found — callback will not fire`);
603
610
  return;
604
611
  }
605
- i.onChange(e);
612
+ i.onChange(t);
606
613
  }
607
- getAttribute(t) {
608
- return this.registry?.get(t);
614
+ getAttribute(e) {
615
+ return this.registry?.get(e);
609
616
  }
610
617
  /** The current selection as attribute name→value pairs, empty before the mapping arrives. */
611
618
  getSelection() {
612
619
  return this.registry?.getSelection() ?? {};
613
620
  }
614
- get hasMapping() {
615
- return this.registry !== void 0;
616
- }
617
- sendMutation(t, e) {
618
- const i = {
621
+ sendMutation(e, t, i = !1) {
622
+ const s = {
619
623
  type: c.MUTATION,
620
- mutations: t,
621
- isInitial: e
624
+ instance: this.instance,
625
+ mutations: e,
626
+ isInitial: t,
627
+ ...i && { transient: !0 }
622
628
  };
623
- this.send(i);
629
+ this.send(s);
624
630
  }
625
631
  replayPendingCallbacks() {
626
- for (const { name: t, callback: e } of this.pendingCallbacks) {
627
- const i = this.registry?.get(t);
628
- i === void 0 && _.warn(`onChange: attribute "${t}" not found — buffered callback will not fire`), i?.onChange(e);
632
+ for (const { name: e, callback: t } of this.pendingCallbacks) {
633
+ const i = this.registry?.get(e);
634
+ i === void 0 && C.warn(`onChange: attribute "${e}" not found — buffered callback will not fire`), i?.onChange(t);
629
635
  }
630
636
  this.pendingCallbacks.length = 0;
631
637
  }
632
638
  }
633
- class he {
639
+ class ft {
634
640
  snapshot;
635
641
  callbacks = [];
636
- handleSnapshot(t) {
637
- this.snapshot = t.attributes;
638
- for (const e of this.callbacks)
639
- e(t.attributes);
642
+ handleSnapshot(e) {
643
+ this.snapshot = e.attributes;
644
+ for (const t of this.callbacks)
645
+ t(e.attributes);
640
646
  }
641
- onChange(t) {
642
- this.callbacks.push(t), this.snapshot !== void 0 && t(this.snapshot);
647
+ onChange(e) {
648
+ this.callbacks.push(e), this.snapshot !== void 0 && e(this.snapshot);
643
649
  }
644
650
  /** The selectable values for one attribute, or null when unrestricted. */
645
- selectableFor(t) {
646
- return this.snapshot?.find((i) => i.name === t)?.selectable ?? null;
651
+ selectableFor(e) {
652
+ return this.snapshot?.find((i) => i.name === e)?.selectable ?? null;
647
653
  }
648
654
  /** The latest snapshot; empty before the viewer has reported anything. */
649
655
  get current() {
650
656
  return this.snapshot ?? [];
651
657
  }
652
658
  }
653
- let me = class {
654
- constructor(t) {
655
- this.send = t;
659
+ let gt = class {
660
+ constructor(e) {
661
+ this.send = e;
656
662
  }
657
663
  send;
658
664
  commands = [];
@@ -661,24 +667,24 @@ let me = class {
661
667
  * @param degrees - Absolute rotation in degrees (0 = front view)
662
668
  * @throws VirtualdisplayError if value is not a finite number
663
669
  */
664
- rotate(t) {
665
- return this.validateFiniteNumber(t, "rotate"), this.commands.push({ action: "rotate", value: t }), this;
670
+ rotate(e) {
671
+ return this.validateFiniteNumber(e, "rotate"), this.commands.push({ action: "rotate", value: e }), this;
666
672
  }
667
673
  /**
668
674
  * Tilt camera vertically
669
675
  * @param degrees - Absolute tilt in degrees (0 = top view, 90 = horizontal)
670
676
  * @throws VirtualdisplayError if value is not a finite number
671
677
  */
672
- tilt(t) {
673
- return this.validateFiniteNumber(t, "tilt"), this.commands.push({ action: "tilt", value: t }), this;
678
+ tilt(e) {
679
+ return this.validateFiniteNumber(e, "tilt"), this.commands.push({ action: "tilt", value: e }), this;
674
680
  }
675
681
  /**
676
682
  * Zoom camera
677
683
  * @param percentage - Zoom percentage (100 = normal, >100 = zoom in, <100 = zoom out)
678
684
  * @throws VirtualdisplayError if value is not a finite number
679
685
  */
680
- zoom(t) {
681
- return this.validateFiniteNumber(t, "zoom"), this.commands.push({ action: "zoom", value: t }), this;
686
+ zoom(e) {
687
+ return this.validateFiniteNumber(e, "zoom"), this.commands.push({ action: "zoom", value: e }), this;
682
688
  }
683
689
  /**
684
690
  * Execute accumulated camera commands
@@ -686,19 +692,19 @@ let me = class {
686
692
  */
687
693
  set() {
688
694
  if (this.commands.length === 0)
689
- throw f.invalidParameter(
695
+ throw g.invalidParameter(
690
696
  "No camera commands to execute. Call rotate(), tilt(), or zoom() before set()."
691
697
  );
692
- const t = {
698
+ const e = {
693
699
  type: c.CAMERA,
694
700
  commands: this.commands
695
701
  };
696
- this.send(t), this.commands = [];
702
+ this.send(e), this.commands = [];
697
703
  }
698
- validateFiniteNumber(t, e) {
699
- if (!Number.isFinite(t))
700
- throw f.invalidParameter(
701
- `${e}() requires a finite number, got ${String(t)}`
704
+ validateFiniteNumber(e, t) {
705
+ if (!Number.isFinite(e))
706
+ throw g.invalidParameter(
707
+ `${t}() requires a finite number, got ${String(e)}`
702
708
  );
703
709
  }
704
710
  /**
@@ -706,14 +712,14 @@ let me = class {
706
712
  * This is not chainable and executes immediately
707
713
  */
708
714
  reset() {
709
- const t = {
715
+ const e = {
710
716
  type: c.CAMERA,
711
717
  commands: [{ action: "reset" }]
712
718
  };
713
- this.send(t);
719
+ this.send(e);
714
720
  }
715
721
  };
716
- class pe {
722
+ class bt {
717
723
  state;
718
724
  limitsState;
719
725
  changeCallbacks = [];
@@ -747,8 +753,8 @@ class pe {
747
753
  * Also fires when limits are applied via applyLimits() so components
748
754
  * can re-evaluate disabled states without a separate callback.
749
755
  */
750
- onChange(t) {
751
- this.changeCallbacks.push(t);
756
+ onChange(e) {
757
+ this.changeCallbacks.push(e);
752
758
  }
753
759
  /**
754
760
  * Current camera movement limits (set from CONFIG message).
@@ -761,62 +767,62 @@ class pe {
761
767
  * Apply camera limits received from the server CONFIG message.
762
768
  * Fires onChange callbacks so button disabled states update immediately.
763
769
  */
764
- applyLimits(t) {
765
- this.limitsState = t;
766
- const e = { rotation: this.rotation, tilt: this.tilt, zoom: this.zoom };
770
+ applyLimits(e) {
771
+ this.limitsState = e;
772
+ const t = { rotation: this.rotation, tilt: this.tilt, zoom: this.zoom };
767
773
  for (const i of this.changeCallbacks)
768
- i(e);
774
+ i(t);
769
775
  }
770
776
  /**
771
777
  * Handle incoming camera position message from server
772
778
  */
773
- handlePositionUpdate(t) {
774
- this.update(t.transforms);
779
+ handlePositionUpdate(e) {
780
+ this.update(e.transforms);
775
781
  }
776
782
  /**
777
783
  * Update camera position from server transforms
778
784
  */
779
- update(t) {
780
- let e = !1;
781
- for (const i of t)
785
+ update(e) {
786
+ let t = !1;
787
+ for (const i of e)
782
788
  switch (i.type) {
783
789
  case "rotation":
784
- this.state.rotation = i.value, e = !0;
790
+ this.state.rotation = i.value, t = !0;
785
791
  break;
786
792
  case "tilt":
787
- this.state.tilt = i.value, e = !0;
793
+ this.state.tilt = i.value, t = !0;
788
794
  break;
789
795
  case "zoom":
790
- this.state.zoom = i.value, e = !0;
796
+ this.state.zoom = i.value, t = !0;
791
797
  break;
792
798
  }
793
- if (e) {
799
+ if (t) {
794
800
  const i = {
795
801
  rotation: this.rotation,
796
802
  tilt: this.tilt,
797
803
  zoom: this.zoom
798
804
  };
799
- for (const o of this.changeCallbacks)
800
- o(i);
805
+ for (const s of this.changeCallbacks)
806
+ s(i);
801
807
  }
802
808
  }
803
809
  }
804
- function fe(n, t) {
805
- const e = n.filter((s) => ge(s, t));
806
- if (e.length === 0)
810
+ function vt(n, e) {
811
+ const t = n.filter((o) => yt(o, e));
812
+ if (t.length === 0)
807
813
  return;
808
- const i = Math.max(...e.map(nt)), o = e.filter((s) => nt(s) === i);
809
- return o.length === 1 ? o[0] : void 0;
814
+ const i = Math.max(...t.map(ie)), s = t.filter((o) => ie(o) === i);
815
+ return s.length === 1 ? s[0] : void 0;
810
816
  }
811
- function ge(n, t) {
812
- return Object.entries(n.attributes).every(([e, i]) => t[e] === i);
817
+ function yt(n, e) {
818
+ return Object.entries(n.attributes).every(([t, i]) => e[t] === i);
813
819
  }
814
- function nt(n) {
820
+ function ie(n) {
815
821
  return Object.keys(n.attributes).length;
816
822
  }
817
- class be {
818
- constructor(t, e) {
819
- this.dispatchChange = t, this.dispatchSubmit = e;
823
+ class St {
824
+ constructor(e, t) {
825
+ this.dispatchChange = e, this.dispatchSubmit = t;
820
826
  }
821
827
  dispatchChange;
822
828
  dispatchSubmit;
@@ -841,9 +847,9 @@ class be {
841
847
  * it says, so the CTA does not render.
842
848
  */
843
849
  get buttonLabel() {
844
- const t = this.pricing?.buttonLabel;
845
- if (t != null && t !== "")
846
- return t;
850
+ const e = this.pricing?.buttonLabel;
851
+ if (e != null && e !== "")
852
+ return e;
847
853
  if (this.submitDefaultLabel !== void 0 && this.submitDefaultLabel !== "")
848
854
  return this.submitDefaultLabel;
849
855
  }
@@ -868,16 +874,16 @@ class be {
868
874
  * Subscribe to configuration changes. Fires after every selection change with
869
875
  * the resolved configuration, including undefined when nothing matches.
870
876
  */
871
- onChange(t) {
872
- this.changeCallbacks.push(t);
877
+ onChange(e) {
878
+ this.changeCallbacks.push(e);
873
879
  }
874
880
  /**
875
881
  * Register the submit handler the CTA hands the configuration to. Registering
876
882
  * one is what switches the button on (capability driven). `defaultLabel` fills
877
883
  * in when the customer authored no button label.
878
884
  */
879
- onSubmit(t, e) {
880
- this.submitCallback = t, this.submitDefaultLabel = e?.defaultLabel, this.notifyRender();
885
+ onSubmit(e, t) {
886
+ this.submitCallback = e, this.submitDefaultLabel = t?.defaultLabel, this.notifyRender();
881
887
  }
882
888
  /**
883
889
  * Subscribe the built-in UI to re-render the price + CTA. Fires on every
@@ -885,10 +891,10 @@ class be {
885
891
  * on without a configuration change). Separate from `onChange`, which stays the
886
892
  * host-facing, mutation-driven contract. Returns a disposer.
887
893
  */
888
- onRender(t) {
889
- return this.renderCallbacks.push(t), () => {
890
- const e = this.renderCallbacks.indexOf(t);
891
- e !== -1 && this.renderCallbacks.splice(e, 1);
894
+ onRender(e) {
895
+ return this.renderCallbacks.push(e), () => {
896
+ const t = this.renderCallbacks.indexOf(e);
897
+ t !== -1 && this.renderCallbacks.splice(t, 1);
892
898
  };
893
899
  }
894
900
  /**
@@ -900,47 +906,48 @@ class be {
900
906
  async submit() {
901
907
  if (!this.submittable)
902
908
  return;
903
- const t = this.resolved !== void 0 ? { attributes: this.resolved.attributes, reference: this.resolved.reference } : { attributes: { ...this.selection }, reference: "" };
904
- this.dispatchSubmit(t), await this.submitCallback?.(t);
909
+ const e = this.resolved !== void 0 ? { attributes: this.resolved.attributes, reference: this.resolved.reference } : { attributes: { ...this.selection }, reference: "" };
910
+ this.dispatchSubmit(e), await this.submitCallback?.(e);
905
911
  }
906
912
  /** Called by the client when a PRICING message arrives from the viewer. */
907
- handlePricingReceived(t) {
908
- this.pricing = t, this.recompute();
913
+ handlePricingReceived(e) {
914
+ this.pricing = e, this.recompute();
909
915
  }
910
916
  /** Called by the client after every mutation result, with the full selection. */
911
- handleSelectionChanged(t) {
912
- this.selection = t, this.recompute();
917
+ handleSelectionChanged(e) {
918
+ this.selection = e, this.recompute();
913
919
  }
914
920
  recompute() {
915
921
  this.resolved = this.resolve();
916
- for (const t of this.changeCallbacks)
917
- t(this.resolved);
922
+ for (const e of this.changeCallbacks)
923
+ e(this.resolved);
918
924
  this.dispatchChange(this.resolved), this.notifyRender();
919
925
  }
920
926
  notifyRender() {
921
- for (const t of this.renderCallbacks)
922
- t();
927
+ for (const e of this.renderCallbacks)
928
+ e();
923
929
  }
924
930
  resolve() {
925
931
  if (this.pricing === void 0)
926
932
  return;
927
- const t = fe(this.pricing.rules, this.selection);
928
- if (!(t === void 0 || t.availability === Rt.HIDDEN))
933
+ const e = vt(this.pricing.rules, this.selection);
934
+ if (!(e === void 0 || e.availability === Le.HIDDEN))
929
935
  return {
930
936
  attributes: { ...this.selection },
931
- reference: t.reference,
932
- price: t.priceCents,
937
+ reference: e.reference,
938
+ price: e.priceCents,
933
939
  currency: this.pricing.currency,
934
- availability: t.availability
940
+ availability: e.availability
935
941
  };
936
942
  }
937
943
  }
938
- class ve {
939
- constructor(t, e) {
940
- this.send = t, this.dispatch = e;
944
+ class wt {
945
+ constructor(e, t, i) {
946
+ this.send = e, this.dispatch = t, this.instance = i;
941
947
  }
942
948
  send;
943
949
  dispatch;
950
+ instance;
944
951
  focused = null;
945
952
  attributes = [];
946
953
  changeCallbacks = [];
@@ -952,36 +959,41 @@ class ve {
952
959
  * Focus a component by name. Sends a focus message to the viewer.
953
960
  * @throws VirtualdisplayError if component is not a non-empty string
954
961
  */
955
- set(t) {
956
- if (typeof t != "string" || t.length === 0)
957
- throw f.invalidParameter(
958
- `set() requires a non-empty component name, got ${String(t)}`
962
+ set(e) {
963
+ if (typeof e != "string" || e.length === 0)
964
+ throw g.invalidParameter(
965
+ `set() requires a non-empty component name, got ${String(e)}`
959
966
  );
960
- this.send({ type: c.FOCUS, action: tt.FOCUS, component: t });
967
+ this.send({
968
+ type: c.FOCUS,
969
+ instance: this.instance,
970
+ action: te.FOCUS,
971
+ component: e
972
+ });
961
973
  }
962
974
  /** Return to the overview — unfocus the current component. */
963
975
  clear() {
964
- this.send({ type: c.FOCUS, action: tt.UNFOCUS });
976
+ this.send({ type: c.FOCUS, instance: this.instance, action: te.UNFOCUS });
965
977
  }
966
978
  /**
967
979
  * Subscribe to focus changes. The callback fires with the focus state when a
968
980
  * component is focused, and with null when returning to overview.
969
981
  */
970
- onChange(t) {
971
- this.changeCallbacks.push(t);
982
+ onChange(e) {
983
+ this.changeCallbacks.push(e);
972
984
  }
973
985
  /** Called by the client when a FocusStateMessage is received from the viewer. */
974
- handleStateReceived(t) {
975
- t.state === Tt.FOCUSED && t.component !== void 0 ? (this.focused = t.component, this.attributes = t.attributes ?? []) : (this.focused = null, this.attributes = []);
976
- const e = this.focused !== null ? { component: this.focused, attributes: this.attributes } : null;
986
+ handleStateReceived(e) {
987
+ e.state === Ie.FOCUSED && e.component !== void 0 ? (this.focused = e.component, this.attributes = e.attributes ?? []) : (this.focused = null, this.attributes = []);
988
+ const t = this.focused !== null ? { component: this.focused, attributes: this.attributes } : null;
977
989
  for (const i of this.changeCallbacks)
978
- i(e);
979
- this.dispatch(e);
990
+ i(t);
991
+ this.dispatch(t);
980
992
  }
981
993
  }
982
- class ye {
983
- constructor(t) {
984
- this.filename = t;
994
+ class Ct {
995
+ constructor(e) {
996
+ this.filename = e;
985
997
  }
986
998
  filename;
987
999
  developedCallbacks = /* @__PURE__ */ new Set();
@@ -996,8 +1008,8 @@ class ye {
996
1008
  * @param callback Function to call with photo data
997
1009
  * @returns This Photo instance for chaining
998
1010
  */
999
- onDeveloped(t) {
1000
- return this.developed && this.photoData !== null ? (t(this.photoData), this) : (this.developedCallbacks.add(t), this);
1011
+ onDeveloped(e) {
1012
+ return this.developed && this.photoData !== null ? (e(this.photoData), this) : (this.developedCallbacks.add(e), this);
1001
1013
  }
1002
1014
  /**
1003
1015
  * Register a callback for when the photo capture fails
@@ -1005,8 +1017,8 @@ class ye {
1005
1017
  * @param callback Function to call with error
1006
1018
  * @returns This Photo instance for chaining
1007
1019
  */
1008
- onError(t) {
1009
- return this.errorCallbacks.add(t), this;
1020
+ onError(e) {
1021
+ return this.errorCallbacks.add(e), this;
1010
1022
  }
1011
1023
  /**
1012
1024
  * Get the filename for this photo
@@ -1018,24 +1030,24 @@ class ye {
1018
1030
  * Mark the photo as developed and notify all callbacks
1019
1031
  * This method is called by Snapshot when the photo data arrives from the server
1020
1032
  */
1021
- develop(t) {
1022
- this.developed || this.failed || (this.photoData = t, this.developed = !0, this.developedCallbacks.forEach((e) => {
1023
- e(this.photoData);
1033
+ develop(e) {
1034
+ this.developed || this.failed || (this.photoData = e, this.developed = !0, this.developedCallbacks.forEach((t) => {
1035
+ t(this.photoData);
1024
1036
  }), this.developedCallbacks.clear(), this.errorCallbacks.clear());
1025
1037
  }
1026
1038
  /**
1027
1039
  * Mark the photo as failed and notify error callbacks
1028
1040
  */
1029
- fail(t) {
1030
- this.developed || this.failed || (this.failed = !0, this.errorCallbacks.forEach((e) => {
1031
- e(t);
1041
+ fail(e) {
1042
+ this.developed || this.failed || (this.failed = !0, this.errorCallbacks.forEach((t) => {
1043
+ t(e);
1032
1044
  }), this.developedCallbacks.clear(), this.errorCallbacks.clear());
1033
1045
  }
1034
1046
  }
1035
- const it = 3e4;
1036
- class we {
1037
- constructor(t) {
1038
- this.send = t;
1047
+ const se = 3e4;
1048
+ class kt {
1049
+ constructor(e) {
1050
+ this.send = e;
1039
1051
  }
1040
1052
  send;
1041
1053
  validExtensions = [".png"];
@@ -1047,39 +1059,39 @@ class we {
1047
1059
  * @returns Photo object for registering callbacks
1048
1060
  * @throws VirtualdisplayError if filename is invalid
1049
1061
  */
1050
- take(t) {
1051
- this.validateFilename(t), _.debug("Taking snapshot", { filename: t });
1052
- const e = new ye(t), i = setTimeout(() => {
1053
- this.pendingPhotos.delete(t), _.warn("Snapshot timed out", { filename: t }), e.fail(new f(
1054
- `Snapshot timed out: the viewer did not respond within ${it}ms`,
1062
+ take(e) {
1063
+ this.validateFilename(e), C.debug("Taking snapshot", { filename: e });
1064
+ const t = new Ct(e), i = setTimeout(() => {
1065
+ this.pendingPhotos.delete(e), C.warn("Snapshot timed out", { filename: e }), t.fail(new g(
1066
+ `Snapshot timed out: the viewer did not respond within ${se}ms`,
1055
1067
  A.SNAPSHOT_FAILED
1056
1068
  ));
1057
- }, it);
1058
- return this.pendingPhotos.set(t, { photo: e, timeout: i }), this.send({
1069
+ }, se);
1070
+ return this.pendingPhotos.set(e, { photo: t, timeout: i }), this.send({
1059
1071
  type: c.SNAPSHOT,
1060
- filename: t
1061
- }), e;
1072
+ filename: e
1073
+ }), t;
1062
1074
  }
1063
1075
  /**
1064
1076
  * Handle incoming snapshot result from server
1065
1077
  * Matches the message to a pending photo by filename, then develops or fails it
1066
1078
  */
1067
- handleSnapshotResult(t) {
1068
- const e = this.pendingPhotos.get(t.filename);
1069
- if (e === void 0) {
1070
- _.warn("No pending photo found for filename", {
1071
- filename: t.filename,
1079
+ handleSnapshotResult(e) {
1080
+ const t = this.pendingPhotos.get(e.filename);
1081
+ if (t === void 0) {
1082
+ C.warn("No pending photo found for filename", {
1083
+ filename: e.filename,
1072
1084
  pendingFilenames: Array.from(this.pendingPhotos.keys())
1073
1085
  });
1074
1086
  return;
1075
1087
  }
1076
- clearTimeout(e.timeout), this.pendingPhotos.delete(t.filename);
1077
- const { photo: i } = e;
1078
- if (t.error !== void 0) {
1079
- i.fail(new f(t.error, A.SNAPSHOT_FAILED));
1088
+ clearTimeout(t.timeout), this.pendingPhotos.delete(e.filename);
1089
+ const { photo: i } = t;
1090
+ if (e.error !== void 0) {
1091
+ i.fail(new g(e.error, A.SNAPSHOT_FAILED));
1080
1092
  return;
1081
1093
  }
1082
- t.data !== void 0 && i.develop({ filename: t.filename, data: t.data });
1094
+ e.data !== void 0 && i.develop({ filename: e.filename, data: e.data });
1083
1095
  }
1084
1096
  /**
1085
1097
  * Fail any pending photos and forget them. Called from client destroy
@@ -1089,373 +1101,349 @@ class we {
1089
1101
  clear() {
1090
1102
  if (this.pendingPhotos.size === 0)
1091
1103
  return;
1092
- const t = new f(
1104
+ const e = new g(
1093
1105
  "Client destroyed before snapshot completed",
1094
1106
  A.SNAPSHOT_FAILED
1095
1107
  );
1096
- for (const { photo: e, timeout: i } of this.pendingPhotos.values())
1097
- clearTimeout(i), e.fail(t);
1108
+ for (const { photo: t, timeout: i } of this.pendingPhotos.values())
1109
+ clearTimeout(i), t.fail(e);
1098
1110
  this.pendingPhotos.clear();
1099
1111
  }
1100
1112
  /**
1101
1113
  * Validate filename has a valid image extension
1102
1114
  */
1103
- validateFilename(t) {
1104
- if (t === "" || typeof t != "string")
1105
- throw new f(
1115
+ validateFilename(e) {
1116
+ if (e === "" || typeof e != "string")
1117
+ throw new g(
1106
1118
  "Filename must be a non-empty string",
1107
1119
  A.INVALID_PARAMETER
1108
1120
  );
1109
1121
  if (!this.validExtensions.some(
1110
- (i) => t.toLowerCase().endsWith(i)
1122
+ (i) => e.toLowerCase().endsWith(i)
1111
1123
  ))
1112
- throw new f(
1113
- `Invalid filename: "${t}". Filename must end with one of: ${this.validExtensions.join(", ")}`,
1124
+ throw new g(
1125
+ `Invalid filename: "${e}". Filename must end with one of: ${this.validExtensions.join(", ")}`,
1114
1126
  A.INVALID_PARAMETER
1115
1127
  );
1116
- if (t.includes("..") || t.includes("/") || t.includes("\\"))
1117
- throw new f(
1128
+ if (e.includes("..") || e.includes("/") || e.includes("\\"))
1129
+ throw new g(
1118
1130
  'Filename cannot contain path separators or ".."',
1119
1131
  A.INVALID_PARAMETER
1120
1132
  );
1121
1133
  }
1122
1134
  }
1123
- class Se {
1135
+ class _t {
1124
1136
  container = null;
1125
- attach(t) {
1126
- this.container = t;
1137
+ attach(e) {
1138
+ this.container = e;
1127
1139
  }
1128
- dispatch(t, e, i = !1) {
1129
- const o = new CustomEvent(t, { detail: e, cancelable: i });
1130
- return this.container?.dispatchEvent(o), o;
1140
+ dispatch(e, t, i = !1) {
1141
+ const s = new CustomEvent(e, { detail: t, cancelable: i });
1142
+ return this.container?.dispatchEvent(s), s;
1131
1143
  }
1132
- on(t, e) {
1133
- const i = (o) => {
1134
- const s = o, r = { ...s.detail, preventDefault: () => {
1135
- s.preventDefault();
1144
+ on(e, t) {
1145
+ const i = (s) => {
1146
+ const o = s, r = { ...o.detail, preventDefault: () => {
1147
+ o.preventDefault();
1136
1148
  } };
1137
- e(r);
1149
+ t(r);
1138
1150
  };
1139
- return this.container?.addEventListener(t, i), () => {
1140
- this.container?.removeEventListener(t, i);
1151
+ return this.container?.addEventListener(e, i), () => {
1152
+ this.container?.removeEventListener(e, i);
1141
1153
  };
1142
1154
  }
1143
1155
  }
1144
- const _e = {}, Ce = "en", vt = (
1156
+ const At = {}, Et = "en", Se = (
1145
1157
  /** @type {const} */
1146
1158
  ["en", "nl", "de"]
1147
- ), K = [
1159
+ ), X = [
1148
1160
  "baseLocale"
1149
- ], ot = [], Q = typeof window > "u";
1161
+ ], oe = [], Q = typeof window > "u";
1150
1162
  globalThis.__paraglide = /** @type {any} */
1151
1163
  globalThis.__paraglide ?? {};
1152
1164
  globalThis.__paraglide.ssr = /** @type {any} */
1153
1165
  globalThis.__paraglide.ssr ?? {};
1154
- let st = !1, u = () => {
1155
- let n = K;
1156
- !Q && typeof window < "u" && window.location?.href && (n = wt(window.location.href));
1157
- const t = ke(n);
1158
- if (t)
1159
- return st || (st = !0, yt(t, { reload: !1 })), t;
1166
+ let re = !1, m = () => {
1167
+ let n = X;
1168
+ !Q && typeof window < "u" && window.location?.href && (n = Ce(window.location.href));
1169
+ const e = xt(n);
1170
+ if (e)
1171
+ return re || (re = !0, we(e, { reload: !1 })), e;
1160
1172
  throw new Error("No locale found. Read the docs https://paraglidejs.com/errors#no-locale-found");
1161
1173
  };
1162
- function ke(n, t) {
1163
- let e;
1174
+ function xt(n, e) {
1175
+ let t;
1164
1176
  for (const i of n) {
1165
1177
  if (i === "baseLocale")
1166
- e = Ce;
1167
- else if (St(i) && M.has(i)) {
1168
- const s = M.get(i);
1169
- if (s) {
1170
- const r = s.getLocale();
1178
+ t = Et;
1179
+ else if (ke(i) && M.has(i)) {
1180
+ const o = M.get(i);
1181
+ if (o) {
1182
+ const r = o.getLocale();
1171
1183
  if (r instanceof Promise)
1172
1184
  continue;
1173
1185
  if (r !== void 0)
1174
- return xe(r);
1186
+ return It(r);
1175
1187
  }
1176
1188
  }
1177
- const o = X(e);
1178
- if (o)
1179
- return o;
1189
+ const s = J(t);
1190
+ if (s)
1191
+ return s;
1180
1192
  }
1181
1193
  }
1182
- const Ae = (n) => {
1194
+ const Tt = (n) => {
1183
1195
  window.location.reload();
1184
1196
  };
1185
- let yt = (n, t) => {
1186
- const e = {
1197
+ let we = (n, e) => {
1198
+ const t = {
1187
1199
  reload: !0,
1188
- ...t
1200
+ ...e
1189
1201
  };
1190
1202
  let i;
1191
1203
  try {
1192
- i = u();
1204
+ i = m();
1193
1205
  } catch {
1194
1206
  }
1195
- const o = [];
1196
- let s = K;
1197
- !Q && typeof window < "u" && window.location?.href && (s = wt(window.location.href));
1198
- for (const a of s)
1199
- if (a !== "baseLocale" && St(a) && M.has(a)) {
1200
- const h = M.get(a);
1201
- if (h) {
1202
- let d = h.setLocale(n);
1203
- d instanceof Promise && (d = d.catch((m) => {
1207
+ const s = [];
1208
+ let o = X;
1209
+ !Q && typeof window < "u" && window.location?.href && (o = Ce(window.location.href));
1210
+ for (const a of o)
1211
+ if (a !== "baseLocale" && ke(a) && M.has(a)) {
1212
+ const u = M.get(a);
1213
+ if (u) {
1214
+ let d = u.setLocale(n);
1215
+ d instanceof Promise && (d = d.catch((f) => {
1204
1216
  throw new Error(`Custom strategy "${a}" setLocale failed.`, {
1205
- cause: m
1217
+ cause: f
1206
1218
  });
1207
- }), o.push(d));
1219
+ }), s.push(d));
1208
1220
  }
1209
1221
  }
1210
1222
  const r = () => {
1211
- !Q && e.reload && window.location && n !== i && Ae();
1223
+ !Q && t.reload && window.location && n !== i && Tt();
1212
1224
  };
1213
- if (o.length)
1214
- return Promise.all(o).then(() => {
1225
+ if (s.length)
1226
+ return Promise.all(s).then(() => {
1215
1227
  r();
1216
1228
  });
1217
1229
  r();
1218
- }, Ee = () => typeof window < "u" ? window.location.origin : "http://fallback.com";
1219
- function X(n) {
1230
+ }, Rt = () => typeof window < "u" ? window.location.origin : "http://fallback.com";
1231
+ function J(n) {
1220
1232
  if (typeof n != "string")
1221
1233
  return;
1222
- const t = n.toLowerCase();
1223
- for (const e of vt)
1224
- if (e.toLowerCase() === t)
1225
- return e;
1234
+ const e = n.toLowerCase();
1235
+ for (const t of Se)
1236
+ if (t.toLowerCase() === e)
1237
+ return t;
1226
1238
  }
1227
- function xe(n) {
1228
- const t = X(n);
1229
- if (t)
1230
- return t;
1231
- throw new Error(`Invalid locale: ${n}. Expected one of: ${vt.join(", ")}`);
1239
+ function It(n) {
1240
+ const e = J(n);
1241
+ if (e)
1242
+ return e;
1243
+ throw new Error(`Invalid locale: ${n}. Expected one of: ${Se.join(", ")}`);
1232
1244
  }
1233
- function Te(n) {
1234
- return Re(n);
1245
+ function Lt(n) {
1246
+ return Ot(n);
1235
1247
  }
1236
- function Re(n) {
1237
- const t = typeof n == "string" ? new URL(n, Ee()) : new URL(n), e = t.pathname.split("/").filter(Boolean);
1238
- return e.length > 0 && X(e[0]) && (t.pathname = "/" + e.slice(1).join("/")), t;
1248
+ function Ot(n) {
1249
+ const e = typeof n == "string" ? new URL(n, Rt()) : new URL(n), t = e.pathname.split("/").filter(Boolean);
1250
+ return t.length > 0 && J(t[0]) && (e.pathname = "/" + t.slice(1).join("/")), e;
1239
1251
  }
1240
- let rt, at;
1241
- function Ie(n) {
1242
- if (ot.length === 0)
1252
+ let ae, le;
1253
+ function Nt(n) {
1254
+ if (oe.length === 0)
1243
1255
  return;
1244
- const t = typeof n == "string" ? n : n.href;
1245
- if (rt === t)
1246
- return at;
1247
- const e = new URL(t, "http://example.com"), i = Te(e), o = i.href === e.href ? [e] : [e, i];
1248
- let s;
1249
- for (const r of o) {
1250
- for (const a of ot)
1251
- if (new _e(a.match, r.href).exec(r.href)) {
1252
- s = a;
1256
+ const e = typeof n == "string" ? n : n.href;
1257
+ if (ae === e)
1258
+ return le;
1259
+ const t = new URL(e, "http://example.com"), i = Lt(t), s = i.href === t.href ? [t] : [t, i];
1260
+ let o;
1261
+ for (const r of s) {
1262
+ for (const a of oe)
1263
+ if (new At(a.match, r.href).exec(r.href)) {
1264
+ o = a;
1253
1265
  break;
1254
1266
  }
1255
- if (s)
1267
+ if (o)
1256
1268
  break;
1257
1269
  }
1258
- return rt = t, at = s, s;
1270
+ return ae = e, le = o, o;
1259
1271
  }
1260
- function wt(n) {
1261
- const t = Ie(n);
1262
- return t && t.exclude !== !0 && Array.isArray(t.strategy) ? t.strategy : K;
1272
+ function Ce(n) {
1273
+ const e = Nt(n);
1274
+ return e && e.exclude !== !0 && Array.isArray(e.strategy) ? e.strategy : X;
1263
1275
  }
1264
1276
  const M = /* @__PURE__ */ new Map();
1265
- function St(n) {
1277
+ function ke(n) {
1266
1278
  return typeof n == "string" && /^custom-[A-Za-z0-9_-]+$/.test(n);
1267
1279
  }
1268
- const Le = (
1280
+ const Mt = (
1269
1281
  /** @type {(inputs: Controls_Ar_Buttonlabel1Inputs) => LocalizedString} */
1270
1282
  () => (
1271
1283
  /** @type {LocalizedString} */
1272
1284
  "Activate AR"
1273
1285
  )
1274
- ), Oe = (
1286
+ ), zt = (
1275
1287
  /** @type {(inputs: Controls_Ar_Buttonlabel1Inputs) => LocalizedString} */
1276
1288
  () => (
1277
1289
  /** @type {LocalizedString} */
1278
1290
  "AR activeren"
1279
1291
  )
1280
- ), Ne = (
1292
+ ), Pt = (
1281
1293
  /** @type {(inputs: Controls_Ar_Buttonlabel1Inputs) => LocalizedString} */
1282
1294
  () => (
1283
1295
  /** @type {LocalizedString} */
1284
1296
  "AR aktivieren"
1285
1297
  )
1286
- ), Me = (
1298
+ ), Ft = (
1287
1299
  /** @type {((inputs?: Controls_Ar_Buttonlabel1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Ar_Buttonlabel1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1288
- ((n = {}, t = {}) => {
1289
- const e = t.locale ?? u();
1290
- return e === "nl" ? Oe() : e === "de" ? Ne() : Le();
1300
+ ((n = {}, e = {}) => {
1301
+ const t = e.locale ?? m();
1302
+ return t === "nl" ? zt() : t === "de" ? Pt() : Mt();
1291
1303
  })
1292
- ), ze = (
1304
+ ), Dt = (
1293
1305
  /** @type {(inputs: Controls_Qr_Modaltitle1Inputs) => LocalizedString} */
1294
1306
  () => (
1295
1307
  /** @type {LocalizedString} */
1296
1308
  "Scan to view in AR"
1297
1309
  )
1298
- ), Pe = (
1310
+ ), $t = (
1299
1311
  /** @type {(inputs: Controls_Qr_Modaltitle1Inputs) => LocalizedString} */
1300
1312
  () => (
1301
1313
  /** @type {LocalizedString} */
1302
1314
  "Scan om in AR te bekijken"
1303
1315
  )
1304
- ), Fe = (
1316
+ ), Ut = (
1305
1317
  /** @type {(inputs: Controls_Qr_Modaltitle1Inputs) => LocalizedString} */
1306
1318
  () => (
1307
1319
  /** @type {LocalizedString} */
1308
1320
  "Scannen für AR-Ansicht"
1309
1321
  )
1310
- ), $e = (
1322
+ ), Bt = (
1311
1323
  /** @type {((inputs?: Controls_Qr_Modaltitle1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Qr_Modaltitle1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1312
- ((n = {}, t = {}) => {
1313
- const e = t.locale ?? u();
1314
- return e === "nl" ? Pe() : e === "de" ? Fe() : ze();
1324
+ ((n = {}, e = {}) => {
1325
+ const t = e.locale ?? m();
1326
+ return t === "nl" ? $t() : t === "de" ? Ut() : Dt();
1315
1327
  })
1316
- ), De = (
1328
+ ), Vt = (
1317
1329
  /** @type {(inputs: Controls_Qr_Modaldescription1Inputs) => LocalizedString} */
1318
1330
  () => (
1319
1331
  /** @type {LocalizedString} */
1320
1332
  "Use your smartphone camera to scan this QR code"
1321
1333
  )
1322
- ), Be = (
1334
+ ), jt = (
1323
1335
  /** @type {(inputs: Controls_Qr_Modaldescription1Inputs) => LocalizedString} */
1324
1336
  () => (
1325
1337
  /** @type {LocalizedString} */
1326
1338
  "Gebruik de camera van je smartphone om deze QR-code te scannen"
1327
1339
  )
1328
- ), Ue = (
1340
+ ), Ht = (
1329
1341
  /** @type {(inputs: Controls_Qr_Modaldescription1Inputs) => LocalizedString} */
1330
1342
  () => (
1331
1343
  /** @type {LocalizedString} */
1332
1344
  "Verwende die Kamera deines Smartphones, um diesen QR-Code zu scannen"
1333
1345
  )
1334
- ), Ve = (
1346
+ ), qt = (
1335
1347
  /** @type {((inputs?: Controls_Qr_Modaldescription1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Qr_Modaldescription1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1336
- ((n = {}, t = {}) => {
1337
- const e = t.locale ?? u();
1338
- return e === "nl" ? Be() : e === "de" ? Ue() : De();
1348
+ ((n = {}, e = {}) => {
1349
+ const t = e.locale ?? m();
1350
+ return t === "nl" ? jt() : t === "de" ? Ht() : Vt();
1339
1351
  })
1340
- ), je = (
1352
+ ), Gt = (
1341
1353
  /** @type {(inputs: Controls_Qr_Modalinstructions1Inputs) => LocalizedString} */
1342
1354
  () => (
1343
1355
  /** @type {LocalizedString} */
1344
1356
  "Your phone will open the 3D model in AR mode."
1345
1357
  )
1346
- ), He = (
1358
+ ), Zt = (
1347
1359
  /** @type {(inputs: Controls_Qr_Modalinstructions1Inputs) => LocalizedString} */
1348
1360
  () => (
1349
1361
  /** @type {LocalizedString} */
1350
1362
  "Je telefoon opent het 3D-model in AR-modus."
1351
1363
  )
1352
- ), qe = (
1364
+ ), Wt = (
1353
1365
  /** @type {(inputs: Controls_Qr_Modalinstructions1Inputs) => LocalizedString} */
1354
1366
  () => (
1355
1367
  /** @type {LocalizedString} */
1356
1368
  "Dein Telefon öffnet das 3D-Modell im AR-Modus."
1357
1369
  )
1358
- ), Ge = (
1370
+ ), Yt = (
1359
1371
  /** @type {((inputs?: Controls_Qr_Modalinstructions1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Qr_Modalinstructions1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1360
- ((n = {}, t = {}) => {
1361
- const e = t.locale ?? u();
1362
- return e === "nl" ? He() : e === "de" ? qe() : je();
1372
+ ((n = {}, e = {}) => {
1373
+ const t = e.locale ?? m();
1374
+ return t === "nl" ? Zt() : t === "de" ? Wt() : Gt();
1363
1375
  })
1364
- ), Ze = (
1376
+ ), Qt = (
1365
1377
  /** @type {(inputs: Controls_Qr_Closebutton1Inputs) => LocalizedString} */
1366
1378
  () => (
1367
1379
  /** @type {LocalizedString} */
1368
1380
  "Close"
1369
1381
  )
1370
- ), We = (
1382
+ ), Kt = (
1371
1383
  /** @type {(inputs: Controls_Qr_Closebutton1Inputs) => LocalizedString} */
1372
1384
  () => (
1373
1385
  /** @type {LocalizedString} */
1374
1386
  "Sluiten"
1375
1387
  )
1376
- ), Ye = (
1388
+ ), Xt = (
1377
1389
  /** @type {(inputs: Controls_Qr_Closebutton1Inputs) => LocalizedString} */
1378
1390
  () => (
1379
1391
  /** @type {LocalizedString} */
1380
1392
  "Schließen"
1381
1393
  )
1382
- ), Qe = (
1394
+ ), Jt = (
1383
1395
  /** @type {((inputs?: Controls_Qr_Closebutton1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Qr_Closebutton1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1384
- ((n = {}, t = {}) => {
1385
- const e = t.locale ?? u();
1386
- return e === "nl" ? We() : e === "de" ? Ye() : Ze();
1396
+ ((n = {}, e = {}) => {
1397
+ const t = e.locale ?? m();
1398
+ return t === "nl" ? Kt() : t === "de" ? Xt() : Qt();
1387
1399
  })
1388
- ), Ke = (
1400
+ ), en = (
1389
1401
  /** @type {(inputs: Controls_Fullscreen_Buttonlabel1Inputs) => LocalizedString} */
1390
1402
  () => (
1391
1403
  /** @type {LocalizedString} */
1392
1404
  "Fullscreen"
1393
1405
  )
1394
- ), Xe = (
1406
+ ), tn = (
1395
1407
  /** @type {(inputs: Controls_Fullscreen_Buttonlabel1Inputs) => LocalizedString} */
1396
1408
  () => (
1397
1409
  /** @type {LocalizedString} */
1398
1410
  "Volledig scherm"
1399
1411
  )
1400
- ), Je = (
1412
+ ), nn = (
1401
1413
  /** @type {(inputs: Controls_Fullscreen_Buttonlabel1Inputs) => LocalizedString} */
1402
1414
  () => (
1403
1415
  /** @type {LocalizedString} */
1404
1416
  "Vollbild"
1405
1417
  )
1406
- ), tn = (
1418
+ ), sn = (
1407
1419
  /** @type {((inputs?: Controls_Fullscreen_Buttonlabel1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Fullscreen_Buttonlabel1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1408
- ((n = {}, t = {}) => {
1409
- const e = t.locale ?? u();
1410
- return e === "nl" ? Xe() : e === "de" ? Je() : Ke();
1420
+ ((n = {}, e = {}) => {
1421
+ const t = e.locale ?? m();
1422
+ return t === "nl" ? tn() : t === "de" ? nn() : en();
1411
1423
  })
1412
- ), en = (
1424
+ ), on = (
1413
1425
  /** @type {(inputs: Loading_Downloadingshort1Inputs) => LocalizedString} */
1414
1426
  () => (
1415
1427
  /** @type {LocalizedString} */
1416
1428
  "Downloading"
1417
1429
  )
1418
- ), nn = (
1430
+ ), rn = (
1419
1431
  /** @type {(inputs: Loading_Downloadingshort1Inputs) => LocalizedString} */
1420
1432
  () => (
1421
1433
  /** @type {LocalizedString} */
1422
1434
  "Downloaden"
1423
1435
  )
1424
- ), on = (
1436
+ ), an = (
1425
1437
  /** @type {(inputs: Loading_Downloadingshort1Inputs) => LocalizedString} */
1426
1438
  () => (
1427
1439
  /** @type {LocalizedString} */
1428
1440
  "Herunterladen"
1429
1441
  )
1430
- ), _t = (
1431
- /** @type {((inputs?: Loading_Downloadingshort1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Loading_Downloadingshort1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1432
- ((n = {}, t = {}) => {
1433
- const e = t.locale ?? u();
1434
- return e === "nl" ? nn() : e === "de" ? on() : en();
1435
- })
1436
- ), sn = (
1437
- /** @type {(inputs: Loading_RenderingInputs) => LocalizedString} */
1438
- () => (
1439
- /** @type {LocalizedString} */
1440
- "Rendering"
1441
- )
1442
- ), rn = (
1443
- /** @type {(inputs: Loading_RenderingInputs) => LocalizedString} */
1444
- () => (
1445
- /** @type {LocalizedString} */
1446
- "Renderen"
1447
- )
1448
- ), an = (
1449
- /** @type {(inputs: Loading_RenderingInputs) => LocalizedString} */
1450
- () => (
1451
- /** @type {LocalizedString} */
1452
- "Rendern"
1453
- )
1454
1442
  ), ln = (
1455
- /** @type {((inputs?: Loading_RenderingInputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Loading_RenderingInputs, { locale?: "en" | "nl" | "de" }, {}>} */
1456
- ((n = {}, t = {}) => {
1457
- const e = t.locale ?? u();
1458
- return e === "nl" ? rn() : e === "de" ? an() : sn();
1443
+ /** @type {((inputs?: Loading_Downloadingshort1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Loading_Downloadingshort1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1444
+ ((n = {}, e = {}) => {
1445
+ const t = e.locale ?? m();
1446
+ return t === "nl" ? rn() : t === "de" ? an() : on();
1459
1447
  })
1460
1448
  ), cn = (
1461
1449
  /** @type {(inputs: Controls_Screenshot_Buttonlabel1Inputs) => LocalizedString} */
@@ -1463,13 +1451,13 @@ const Le = (
1463
1451
  /** @type {LocalizedString} */
1464
1452
  "Screenshot"
1465
1453
  )
1466
- ), dn = (
1454
+ ), un = (
1467
1455
  /** @type {(inputs: Controls_Screenshot_Buttonlabel1Inputs) => LocalizedString} */
1468
1456
  () => (
1469
1457
  /** @type {LocalizedString} */
1470
1458
  "Screenshot"
1471
1459
  )
1472
- ), un = (
1460
+ ), dn = (
1473
1461
  /** @type {(inputs: Controls_Screenshot_Buttonlabel1Inputs) => LocalizedString} */
1474
1462
  () => (
1475
1463
  /** @type {LocalizedString} */
@@ -1477,9 +1465,9 @@ const Le = (
1477
1465
  )
1478
1466
  ), hn = (
1479
1467
  /** @type {((inputs?: Controls_Screenshot_Buttonlabel1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Screenshot_Buttonlabel1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1480
- ((n = {}, t = {}) => {
1481
- const e = t.locale ?? u();
1482
- return e === "nl" ? dn() : e === "de" ? un() : cn();
1468
+ ((n = {}, e = {}) => {
1469
+ const t = e.locale ?? m();
1470
+ return t === "nl" ? un() : t === "de" ? dn() : cn();
1483
1471
  })
1484
1472
  ), mn = (
1485
1473
  /** @type {(inputs: Controls_Configurator_OpenInputs) => LocalizedString} */
@@ -1501,9 +1489,9 @@ const Le = (
1501
1489
  )
1502
1490
  ), gn = (
1503
1491
  /** @type {((inputs?: Controls_Configurator_OpenInputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Configurator_OpenInputs, { locale?: "en" | "nl" | "de" }, {}>} */
1504
- ((n = {}, t = {}) => {
1505
- const e = t.locale ?? u();
1506
- return e === "nl" ? pn() : e === "de" ? fn() : mn();
1492
+ ((n = {}, e = {}) => {
1493
+ const t = e.locale ?? m();
1494
+ return t === "nl" ? pn() : t === "de" ? fn() : mn();
1507
1495
  })
1508
1496
  ), bn = (
1509
1497
  /** @type {(inputs: Controls_Configurator_CloseInputs) => LocalizedString} */
@@ -1523,35 +1511,35 @@ const Le = (
1523
1511
  /** @type {LocalizedString} */
1524
1512
  "Schließen"
1525
1513
  )
1526
- ), wn = (
1514
+ ), Sn = (
1527
1515
  /** @type {((inputs?: Controls_Configurator_CloseInputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Configurator_CloseInputs, { locale?: "en" | "nl" | "de" }, {}>} */
1528
- ((n = {}, t = {}) => {
1529
- const e = t.locale ?? u();
1530
- return e === "nl" ? vn() : e === "de" ? yn() : bn();
1516
+ ((n = {}, e = {}) => {
1517
+ const t = e.locale ?? m();
1518
+ return t === "nl" ? vn() : t === "de" ? yn() : bn();
1531
1519
  })
1532
- ), Sn = (
1520
+ ), wn = (
1533
1521
  /** @type {(inputs: Controls_Camera_ResetInputs) => LocalizedString} */
1534
1522
  () => (
1535
1523
  /** @type {LocalizedString} */
1536
1524
  "Reset camera"
1537
1525
  )
1538
- ), _n = (
1526
+ ), Cn = (
1539
1527
  /** @type {(inputs: Controls_Camera_ResetInputs) => LocalizedString} */
1540
1528
  () => (
1541
1529
  /** @type {LocalizedString} */
1542
1530
  "Camera resetten"
1543
1531
  )
1544
- ), Cn = (
1532
+ ), kn = (
1545
1533
  /** @type {(inputs: Controls_Camera_ResetInputs) => LocalizedString} */
1546
1534
  () => (
1547
1535
  /** @type {LocalizedString} */
1548
1536
  "Kamera zurücksetzen"
1549
1537
  )
1550
- ), kn = (
1538
+ ), _n = (
1551
1539
  /** @type {((inputs?: Controls_Camera_ResetInputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Camera_ResetInputs, { locale?: "en" | "nl" | "de" }, {}>} */
1552
- ((n = {}, t = {}) => {
1553
- const e = t.locale ?? u();
1554
- return e === "nl" ? _n() : e === "de" ? Cn() : Sn();
1540
+ ((n = {}, e = {}) => {
1541
+ const t = e.locale ?? m();
1542
+ return t === "nl" ? Cn() : t === "de" ? kn() : wn();
1555
1543
  })
1556
1544
  ), An = (
1557
1545
  /** @type {(inputs: Controls_Camera_Zoomin1Inputs) => LocalizedString} */
@@ -1573,9 +1561,9 @@ const Le = (
1573
1561
  )
1574
1562
  ), Tn = (
1575
1563
  /** @type {((inputs?: Controls_Camera_Zoomin1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Camera_Zoomin1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1576
- ((n = {}, t = {}) => {
1577
- const e = t.locale ?? u();
1578
- return e === "nl" ? En() : e === "de" ? xn() : An();
1564
+ ((n = {}, e = {}) => {
1565
+ const t = e.locale ?? m();
1566
+ return t === "nl" ? En() : t === "de" ? xn() : An();
1579
1567
  })
1580
1568
  ), Rn = (
1581
1569
  /** @type {(inputs: Controls_Camera_Zoomout1Inputs) => LocalizedString} */
@@ -1597,9 +1585,9 @@ const Le = (
1597
1585
  )
1598
1586
  ), On = (
1599
1587
  /** @type {((inputs?: Controls_Camera_Zoomout1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Camera_Zoomout1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1600
- ((n = {}, t = {}) => {
1601
- const e = t.locale ?? u();
1602
- return e === "nl" ? In() : e === "de" ? Ln() : Rn();
1588
+ ((n = {}, e = {}) => {
1589
+ const t = e.locale ?? m();
1590
+ return t === "nl" ? In() : t === "de" ? Ln() : Rn();
1603
1591
  })
1604
1592
  ), Nn = (
1605
1593
  /** @type {(inputs: Controls_Camera_Rotateleft1Inputs) => LocalizedString} */
@@ -1621,9 +1609,9 @@ const Le = (
1621
1609
  )
1622
1610
  ), Pn = (
1623
1611
  /** @type {((inputs?: Controls_Camera_Rotateleft1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Camera_Rotateleft1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1624
- ((n = {}, t = {}) => {
1625
- const e = t.locale ?? u();
1626
- return e === "nl" ? Mn() : e === "de" ? zn() : Nn();
1612
+ ((n = {}, e = {}) => {
1613
+ const t = e.locale ?? m();
1614
+ return t === "nl" ? Mn() : t === "de" ? zn() : Nn();
1627
1615
  })
1628
1616
  ), Fn = (
1629
1617
  /** @type {(inputs: Controls_Camera_Rotateright1Inputs) => LocalizedString} */
@@ -1631,25 +1619,25 @@ const Le = (
1631
1619
  /** @type {LocalizedString} */
1632
1620
  "Rotate right"
1633
1621
  )
1634
- ), $n = (
1622
+ ), Dn = (
1635
1623
  /** @type {(inputs: Controls_Camera_Rotateright1Inputs) => LocalizedString} */
1636
1624
  () => (
1637
1625
  /** @type {LocalizedString} */
1638
1626
  "Naar rechts draaien"
1639
1627
  )
1640
- ), Dn = (
1628
+ ), $n = (
1641
1629
  /** @type {(inputs: Controls_Camera_Rotateright1Inputs) => LocalizedString} */
1642
1630
  () => (
1643
1631
  /** @type {LocalizedString} */
1644
1632
  "Nach rechts drehen"
1645
1633
  )
1646
- ), Bn = (
1634
+ ), Un = (
1647
1635
  /** @type {((inputs?: Controls_Camera_Rotateright1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Camera_Rotateright1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1648
- ((n = {}, t = {}) => {
1649
- const e = t.locale ?? u();
1650
- return e === "nl" ? $n() : e === "de" ? Dn() : Fn();
1636
+ ((n = {}, e = {}) => {
1637
+ const t = e.locale ?? m();
1638
+ return t === "nl" ? Dn() : t === "de" ? $n() : Fn();
1651
1639
  })
1652
- ), Un = (
1640
+ ), Bn = (
1653
1641
  /** @type {(inputs: Controls_Camera_Tiltup1Inputs) => LocalizedString} */
1654
1642
  () => (
1655
1643
  /** @type {LocalizedString} */
@@ -1669,9 +1657,9 @@ const Le = (
1669
1657
  )
1670
1658
  ), Hn = (
1671
1659
  /** @type {((inputs?: Controls_Camera_Tiltup1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Camera_Tiltup1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1672
- ((n = {}, t = {}) => {
1673
- const e = t.locale ?? u();
1674
- return e === "nl" ? Vn() : e === "de" ? jn() : Un();
1660
+ ((n = {}, e = {}) => {
1661
+ const t = e.locale ?? m();
1662
+ return t === "nl" ? Vn() : t === "de" ? jn() : Bn();
1675
1663
  })
1676
1664
  ), qn = (
1677
1665
  /** @type {(inputs: Controls_Camera_Tiltdown1Inputs) => LocalizedString} */
@@ -1693,9 +1681,9 @@ const Le = (
1693
1681
  )
1694
1682
  ), Wn = (
1695
1683
  /** @type {((inputs?: Controls_Camera_Tiltdown1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Camera_Tiltdown1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
1696
- ((n = {}, t = {}) => {
1697
- const e = t.locale ?? u();
1698
- return e === "nl" ? Gn() : e === "de" ? Zn() : qn();
1684
+ ((n = {}, e = {}) => {
1685
+ const t = e.locale ?? m();
1686
+ return t === "nl" ? Gn() : t === "de" ? Zn() : qn();
1699
1687
  })
1700
1688
  ), Yn = (
1701
1689
  /** @type {(inputs: Commerce_Submit_BusyInputs) => LocalizedString} */
@@ -1717,9 +1705,9 @@ const Le = (
1717
1705
  )
1718
1706
  ), Xn = (
1719
1707
  /** @type {((inputs?: Commerce_Submit_BusyInputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Commerce_Submit_BusyInputs, { locale?: "en" | "nl" | "de" }, {}>} */
1720
- ((n = {}, t = {}) => {
1721
- const e = t.locale ?? u();
1722
- return e === "nl" ? Qn() : e === "de" ? Kn() : Yn();
1708
+ ((n = {}, e = {}) => {
1709
+ const t = e.locale ?? m();
1710
+ return t === "nl" ? Qn() : t === "de" ? Kn() : Yn();
1723
1711
  })
1724
1712
  ), Jn = (
1725
1713
  /** @type {(inputs: Commerce_Submit_SuccessInputs) => LocalizedString} */
@@ -1727,13 +1715,13 @@ const Le = (
1727
1715
  /** @type {LocalizedString} */
1728
1716
  "Done"
1729
1717
  )
1730
- ), ti = (
1718
+ ), ei = (
1731
1719
  /** @type {(inputs: Commerce_Submit_SuccessInputs) => LocalizedString} */
1732
1720
  () => (
1733
1721
  /** @type {LocalizedString} */
1734
1722
  "Gelukt"
1735
1723
  )
1736
- ), ei = (
1724
+ ), ti = (
1737
1725
  /** @type {(inputs: Commerce_Submit_SuccessInputs) => LocalizedString} */
1738
1726
  () => (
1739
1727
  /** @type {LocalizedString} */
@@ -1741,9 +1729,9 @@ const Le = (
1741
1729
  )
1742
1730
  ), ni = (
1743
1731
  /** @type {((inputs?: Commerce_Submit_SuccessInputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Commerce_Submit_SuccessInputs, { locale?: "en" | "nl" | "de" }, {}>} */
1744
- ((n = {}, t = {}) => {
1745
- const e = t.locale ?? u();
1746
- return e === "nl" ? ti() : e === "de" ? ei() : Jn();
1732
+ ((n = {}, e = {}) => {
1733
+ const t = e.locale ?? m();
1734
+ return t === "nl" ? ei() : t === "de" ? ti() : Jn();
1747
1735
  })
1748
1736
  ), ii = (
1749
1737
  /** @type {(inputs: Commerce_Submit_FailedInputs) => LocalizedString} */
@@ -1751,13 +1739,13 @@ const Le = (
1751
1739
  /** @type {LocalizedString} */
1752
1740
  "Failed"
1753
1741
  )
1754
- ), oi = (
1742
+ ), si = (
1755
1743
  /** @type {(inputs: Commerce_Submit_FailedInputs) => LocalizedString} */
1756
1744
  () => (
1757
1745
  /** @type {LocalizedString} */
1758
1746
  "Mislukt"
1759
1747
  )
1760
- ), si = (
1748
+ ), oi = (
1761
1749
  /** @type {(inputs: Commerce_Submit_FailedInputs) => LocalizedString} */
1762
1750
  () => (
1763
1751
  /** @type {LocalizedString} */
@@ -1765,9 +1753,9 @@ const Le = (
1765
1753
  )
1766
1754
  ), ri = (
1767
1755
  /** @type {((inputs?: Commerce_Submit_FailedInputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Commerce_Submit_FailedInputs, { locale?: "en" | "nl" | "de" }, {}>} */
1768
- ((n = {}, t = {}) => {
1769
- const e = t.locale ?? u();
1770
- return e === "nl" ? oi() : e === "de" ? si() : ii();
1756
+ ((n = {}, e = {}) => {
1757
+ const t = e.locale ?? m();
1758
+ return t === "nl" ? si() : t === "de" ? oi() : ii();
1771
1759
  })
1772
1760
  );
1773
1761
  const ai = {
@@ -1781,20 +1769,20 @@ const ai = {
1781
1769
  "stroke-linecap": "round",
1782
1770
  "stroke-linejoin": "round"
1783
1771
  };
1784
- const Ct = ([n, t, e]) => {
1772
+ const _e = ([n, e, t]) => {
1785
1773
  const i = document.createElementNS("http://www.w3.org/2000/svg", n);
1786
- return Object.keys(t).forEach((o) => {
1787
- i.setAttribute(o, String(t[o]));
1788
- }), e?.length && e.forEach((o) => {
1789
- const s = Ct(o);
1790
- i.appendChild(s);
1774
+ return Object.keys(e).forEach((s) => {
1775
+ i.setAttribute(s, String(e[s]));
1776
+ }), t?.length && t.forEach((s) => {
1777
+ const o = _e(s);
1778
+ i.appendChild(o);
1791
1779
  }), i;
1792
- }, kt = (n, t = {}) => {
1780
+ }, Ae = (n, e = {}) => {
1793
1781
  const i = {
1794
1782
  ...ai,
1795
- ...t
1783
+ ...e
1796
1784
  };
1797
- return Ct(["svg", i, n]);
1785
+ return _e(["svg", i, n]);
1798
1786
  };
1799
1787
  const li = [
1800
1788
  [
@@ -1815,9 +1803,9 @@ const ci = [
1815
1803
  ],
1816
1804
  ["circle", { cx: "12", cy: "13", r: "3" }]
1817
1805
  ];
1818
- const At = [["path", { d: "m6 9 6 6 6-6" }]];
1819
- const di = [["path", { d: "m15 18-6-6 6-6" }]];
1820
- const ui = [["path", { d: "m9 18 6-6-6-6" }]];
1806
+ const Ee = [["path", { d: "m6 9 6 6 6-6" }]];
1807
+ const ui = [["path", { d: "m15 18-6-6 6-6" }]];
1808
+ const di = [["path", { d: "m9 18 6-6-6-6" }]];
1821
1809
  const hi = [["path", { d: "m18 15-6-6-6 6" }]];
1822
1810
  const mi = [
1823
1811
  ["path", { d: "M15 3h6v6" }],
@@ -1853,40 +1841,40 @@ const bi = [
1853
1841
  const vi = [
1854
1842
  ["circle", { cx: "11", cy: "11", r: "8" }],
1855
1843
  ["line", { x1: "21", x2: "16.65", y1: "21", y2: "16.65" }],
1844
+ ["line", { x1: "11", x2: "11", y1: "8", y2: "14" }],
1856
1845
  ["line", { x1: "8", x2: "14", y1: "11", y2: "11" }]
1857
1846
  ];
1858
1847
  const yi = [
1859
1848
  ["circle", { cx: "11", cy: "11", r: "8" }],
1860
1849
  ["line", { x1: "21", x2: "16.65", y1: "21", y2: "16.65" }],
1861
- ["line", { x1: "11", x2: "11", y1: "8", y2: "14" }],
1862
1850
  ["line", { x1: "8", x2: "14", y1: "11", y2: "11" }]
1863
1851
  ];
1864
- function y(n, { size: t = 20, strokeWidth: e = 1.75 } = {}) {
1865
- return kt(n, { width: t, height: t, "stroke-width": e });
1852
+ function y(n, { size: e = 20, strokeWidth: t = 1.75 } = {}) {
1853
+ return Ae(n, { width: e, height: e, "stroke-width": t });
1866
1854
  }
1867
- const g = {
1855
+ const b = {
1868
1856
  ar: (n) => y(li, n),
1869
1857
  fullscreen: (n) => y(mi, n),
1870
1858
  exitFullscreen: (n) => y(pi, n),
1871
1859
  screenshot: (n) => y(ci, n),
1872
1860
  tiltUp: (n) => y(hi, n),
1873
- tiltDown: (n) => y(At, n),
1874
- rotateLeft: (n) => y(di, n),
1875
- rotateRight: (n) => y(ui, n),
1876
- zoomIn: (n) => y(yi, n),
1877
- zoomOut: (n) => y(vi, n),
1861
+ tiltDown: (n) => y(Ee, n),
1862
+ rotateLeft: (n) => y(ui, n),
1863
+ rotateRight: (n) => y(di, n),
1864
+ zoomIn: (n) => y(vi, n),
1865
+ zoomOut: (n) => y(yi, n),
1878
1866
  reset: (n) => y(fi, n),
1879
1867
  configurator: (n) => y(gi, n),
1880
1868
  close: (n) => y(bi, n)
1881
1869
  };
1882
- class b {
1870
+ class v {
1883
1871
  element;
1884
- constructor({ variant: t = "default", size: e = "default", label: i, icon: o, onClick: s, disabled: r = !1 } = {}) {
1885
- this.element = document.createElement("button"), this.element.className = `ui-btn ui-btn--${t} ui-btn--size-${e}`, i !== void 0 && (this.element.setAttribute("aria-label", i), this.element.title = i), o !== void 0 ? this.element.appendChild(o) : i !== void 0 && (this.element.textContent = i), s && this.element.addEventListener("click", s), this.element.disabled = r;
1872
+ constructor({ variant: e = "default", size: t = "default", label: i, icon: s, onClick: o, disabled: r = !1 } = {}) {
1873
+ this.element = document.createElement("button"), this.element.className = `ui-btn ui-btn--${e} ui-btn--size-${t}`, i !== void 0 && (this.element.setAttribute("aria-label", i), this.element.title = i), s !== void 0 ? this.element.appendChild(s) : i !== void 0 && (this.element.textContent = i), o && this.element.addEventListener("click", o), this.element.disabled = r;
1886
1874
  }
1887
- setIcon(t) {
1888
- const e = this.element.querySelector("svg");
1889
- e !== null ? e.replaceWith(t) : this.element.appendChild(t);
1875
+ setIcon(e) {
1876
+ const t = this.element.querySelector("svg");
1877
+ t !== null ? t.replaceWith(e) : this.element.appendChild(e);
1890
1878
  }
1891
1879
  }
1892
1880
  const p = {
@@ -1923,7 +1911,7 @@ const p = {
1923
1911
  // 32px
1924
1912
  9: "2.25rem"
1925
1913
  };
1926
- class wi {
1914
+ class Si {
1927
1915
  element;
1928
1916
  constructor() {
1929
1917
  this.element = document.createElement("div"), Object.assign(this.element.style, {
@@ -1936,25 +1924,25 @@ class wi {
1936
1924
  });
1937
1925
  }
1938
1926
  }
1939
- class Si {
1940
- constructor(t = {}) {
1941
- this.options = t, this.card = new wi(), this.backdrop = this.createBackdrop(), this.backdrop.appendChild(this.card.element);
1927
+ class wi {
1928
+ constructor(e = {}) {
1929
+ this.options = e, this.card = new Si(), this.backdrop = this.createBackdrop(), this.backdrop.appendChild(this.card.element);
1942
1930
  }
1943
1931
  options;
1944
1932
  card;
1945
1933
  backdrop;
1946
1934
  keyHandler = null;
1947
1935
  open() {
1948
- document.body.appendChild(this.backdrop), this.keyHandler = (t) => {
1949
- t.key === "Escape" && this.close();
1936
+ document.body.appendChild(this.backdrop), this.keyHandler = (e) => {
1937
+ e.key === "Escape" && this.close();
1950
1938
  }, document.addEventListener("keydown", this.keyHandler);
1951
1939
  }
1952
1940
  close() {
1953
1941
  this.backdrop.remove(), this.keyHandler !== null && (document.removeEventListener("keydown", this.keyHandler), this.keyHandler = null), this.options.onClose?.();
1954
1942
  }
1955
1943
  createBackdrop() {
1956
- const t = document.createElement("div");
1957
- return Object.assign(t.style, {
1944
+ const e = document.createElement("div");
1945
+ return Object.assign(e.style, {
1958
1946
  position: "fixed",
1959
1947
  inset: l[0],
1960
1948
  background: "oklch(0% 0 0 / 50%)",
@@ -1962,72 +1950,137 @@ class Si {
1962
1950
  display: "flex",
1963
1951
  alignItems: "center",
1964
1952
  justifyContent: "center"
1965
- }), t.addEventListener("click", (e) => {
1966
- e.target === t && this.close();
1967
- }), t;
1953
+ }), e.addEventListener("click", (t) => {
1954
+ t.target === e && this.close();
1955
+ }), e;
1968
1956
  }
1969
1957
  }
1970
- class _i {
1958
+ class Ci {
1971
1959
  element;
1972
1960
  selectCallback = null;
1973
- constructor(t, e, i) {
1961
+ constructor(e, t, i) {
1974
1962
  this.element = document.createElement("div"), this.element.className = "ui-toggle-group";
1975
- for (let o = 0; o < t.length; o++) {
1976
- const s = t[o], r = document.createElement("button");
1977
- r.className = "ui-toggle-group-item", r.dataset.value = s, r.textContent = i?.[o] ?? s, r.dataset.state = s === e ? "on" : "off", r.setAttribute("aria-pressed", s === e ? "true" : "false"), r.addEventListener("click", () => {
1978
- this.selectCallback?.(s);
1963
+ for (let s = 0; s < e.length; s++) {
1964
+ const o = e[s], r = document.createElement("button");
1965
+ r.className = "ui-toggle-group-item", r.dataset.value = o, r.textContent = i?.[s] ?? o, r.dataset.state = o === t ? "on" : "off", r.setAttribute("aria-pressed", o === t ? "true" : "false"), r.addEventListener("click", () => {
1966
+ this.selectCallback?.(o);
1979
1967
  }), this.element.appendChild(r);
1980
1968
  }
1981
1969
  }
1982
- setSelected(t) {
1983
- for (const e of this.element.querySelectorAll(".ui-toggle-group-item")) {
1984
- const i = e.dataset.value === t;
1985
- e.dataset.state = i ? "on" : "off", e.setAttribute("aria-pressed", i ? "true" : "false");
1970
+ setSelected(e) {
1971
+ for (const t of this.element.querySelectorAll(".ui-toggle-group-item")) {
1972
+ const i = t.dataset.value === e;
1973
+ t.dataset.state = i ? "on" : "off", t.setAttribute("aria-pressed", i ? "true" : "false");
1986
1974
  }
1987
1975
  }
1988
- onSelect(t) {
1989
- this.selectCallback = t;
1976
+ onSelect(e) {
1977
+ this.selectCallback = e;
1990
1978
  }
1991
1979
  /**
1992
1980
  * Enable only the given values; null lifts every restriction. A disabled
1993
1981
  * value stays visible (the buyer sees the option exists) but cannot be
1994
1982
  * picked: the selectable snapshot's "not in the list = grey".
1995
1983
  */
1996
- setEnabled(t) {
1997
- for (const e of this.element.querySelectorAll(".ui-toggle-group-item")) {
1998
- const i = t === null || t.includes(e.dataset.value ?? "");
1999
- e.disabled = !i, e.setAttribute("aria-disabled", i ? "false" : "true");
1984
+ setEnabled(e) {
1985
+ for (const t of this.element.querySelectorAll(".ui-toggle-group-item")) {
1986
+ const i = e === null || e.includes(t.dataset.value ?? "");
1987
+ t.disabled = !i, t.setAttribute("aria-disabled", i ? "false" : "true");
2000
1988
  }
2001
1989
  }
2002
1990
  }
2003
- class Ci {
1991
+ class ki {
2004
1992
  element;
2005
1993
  select;
2006
- constructor(t, e, i, o, s) {
2007
- this.select = document.createElement("select"), this.select.className = "ui-native-select", this.select.dataset.name = t, this.select.setAttribute("aria-label", i);
1994
+ constructor(e, t, i, s, o) {
1995
+ this.select = document.createElement("select"), this.select.className = "ui-native-select", this.select.dataset.name = e, this.select.setAttribute("aria-label", i);
2008
1996
  const r = document.createElement("option");
2009
1997
  r.value = "", r.disabled = !0, r.textContent = i, this.select.appendChild(r);
2010
1998
  let a = !1;
2011
- for (let d = 0; d < e.length; d++) {
2012
- const m = e[d], v = document.createElement("option");
2013
- v.value = m, v.textContent = s?.[d] ?? m, m === o && (v.selected = !0, a = !0), this.select.appendChild(v);
1999
+ for (let d = 0; d < t.length; d++) {
2000
+ const f = t[d], h = document.createElement("option");
2001
+ h.value = f, h.textContent = o?.[d] ?? f, f === s && (h.selected = !0, a = !0), this.select.appendChild(h);
2014
2002
  }
2015
2003
  a || (r.selected = !0);
2016
- const h = kt(At, { width: 16, height: 16, "stroke-width": 2 });
2017
- h.classList.add("ui-native-select-icon"), this.element = document.createElement("div"), this.element.className = "ui-native-select-wrap", this.element.appendChild(this.select), this.element.appendChild(h);
2004
+ const u = Ae(Ee, { width: 16, height: 16, "stroke-width": 2 });
2005
+ u.classList.add("ui-native-select-icon"), this.element = document.createElement("div"), this.element.className = "ui-native-select-wrap", this.element.appendChild(this.select), this.element.appendChild(u);
2018
2006
  }
2019
- setSelected(t) {
2020
- this.select.value = t;
2007
+ setSelected(e) {
2008
+ this.select.value = e;
2021
2009
  }
2022
- onSelect(t) {
2010
+ onSelect(e) {
2023
2011
  this.select.addEventListener("change", () => {
2024
- t(this.select.value);
2012
+ e(this.select.value);
2025
2013
  });
2026
2014
  }
2027
2015
  /** Enable only the given values; null lifts every restriction (see ToggleGroup.setEnabled). */
2028
- setEnabled(t) {
2029
- for (const e of this.select.options)
2030
- e.value !== "" && (e.disabled = t !== null && !t.includes(e.value));
2016
+ setEnabled(e) {
2017
+ for (const t of this.select.options)
2018
+ t.value !== "" && (t.disabled = e !== null && !e.includes(t.value));
2019
+ }
2020
+ }
2021
+ class _i {
2022
+ element;
2023
+ input;
2024
+ valueText;
2025
+ values;
2026
+ options;
2027
+ selectCallback = null;
2028
+ settleCallback = null;
2029
+ constructor(e, t) {
2030
+ if (e.length === 0)
2031
+ throw new Error("Virtualdisplay: Slider needs at least one value");
2032
+ this.values = e, this.options = t, this.input = document.createElement("input"), this.input.type = "range", this.input.className = "ui-slider-input", this.input.min = "0", this.input.max = String(e.length - 1), this.input.step = "1", this.input.setAttribute("aria-label", t.label), this.valueText = document.createElement("span"), this.valueText.className = "ui-slider-value", this.valueText.setAttribute("aria-hidden", "true");
2033
+ const i = document.createElement("div");
2034
+ i.className = "ui-slider-track", i.appendChild(this.input), i.appendChild(this.buildEnds()), this.element = document.createElement("div"), this.element.className = "ui-slider", this.element.appendChild(i), this.element.appendChild(this.valueText);
2035
+ const s = t.initialSelected === void 0 ? 0 : e.indexOf(t.initialSelected);
2036
+ this.applyIndex(s === -1 ? 0 : s), this.listen();
2037
+ }
2038
+ setSelected(e) {
2039
+ const t = this.values.indexOf(e);
2040
+ t !== -1 && this.applyIndex(t);
2041
+ }
2042
+ /** Fires on every step a drag or keypress crosses, with the value it lands on. */
2043
+ onSelect(e) {
2044
+ this.selectCallback = e;
2045
+ }
2046
+ /** Fires once per interaction, when the value commits (drag released, key released). */
2047
+ onSettle(e) {
2048
+ this.settleCallback = e;
2049
+ }
2050
+ listen() {
2051
+ this.input.addEventListener("input", () => {
2052
+ const e = this.values[this.currentIndex];
2053
+ e !== void 0 && (this.applyIndex(this.currentIndex), this.selectCallback?.(e));
2054
+ }), this.input.addEventListener("change", () => {
2055
+ const e = this.values[this.currentIndex];
2056
+ e !== void 0 && this.settleCallback?.(e);
2057
+ });
2058
+ }
2059
+ get currentIndex() {
2060
+ return Number(this.input.value);
2061
+ }
2062
+ applyIndex(e) {
2063
+ this.input.value = String(e);
2064
+ const t = this.displayAt(e);
2065
+ this.valueText.textContent = t, this.input.setAttribute("aria-valuetext", t);
2066
+ const i = this.values.length === 1 ? 100 : e / (this.values.length - 1) * 100;
2067
+ this.element.style.setProperty("--ui-slider-pct", `${i}%`);
2068
+ }
2069
+ buildEnds() {
2070
+ const e = document.createElement("div");
2071
+ e.className = "ui-slider-ends", e.setAttribute("aria-hidden", "true");
2072
+ for (const t of [0, this.values.length - 1]) {
2073
+ const i = document.createElement("span");
2074
+ i.textContent = this.labelAt(t), e.appendChild(i);
2075
+ }
2076
+ return e;
2077
+ }
2078
+ labelAt(e) {
2079
+ return this.options.labels?.[e] ?? this.values[e] ?? "";
2080
+ }
2081
+ displayAt(e) {
2082
+ const t = this.labelAt(e);
2083
+ return this.options.unit === void 0 ? t : `${t} ${this.options.unit}`;
2031
2084
  }
2032
2085
  }
2033
2086
  const w = {
@@ -2047,7 +2100,7 @@ const w = {
2047
2100
  medium: "500",
2048
2101
  semibold: "600"
2049
2102
  }
2050
- }, x = w.fontFamily.sans.join(", "), ki = `
2103
+ }, x = w.fontFamily.sans.join(", "), Ai = `
2051
2104
  --primary: oklch(5% 0 0);
2052
2105
  --primary-foreground: oklch(100% 0 0);
2053
2106
  --secondary: oklch(92% 0 0);
@@ -2060,8 +2113,8 @@ const w = {
2060
2113
  --accent: oklch(92% 0 0);
2061
2114
  --accent-foreground: oklch(5% 0 0);
2062
2115
  --muted-foreground: oklch(44% 0 0);
2063
- `, Ai = `
2064
- :root { ${ki} }
2116
+ `, Ei = `
2117
+ :root { ${Ai} }
2065
2118
 
2066
2119
  /* ── Button ──────────────────────────────────────────────── */
2067
2120
  .ui-btn {
@@ -2192,6 +2245,97 @@ const w = {
2192
2245
  pointer-events: none;
2193
2246
  }
2194
2247
 
2248
+ /* ── Slider ──────────────────────────────────────────────── */
2249
+ .ui-slider {
2250
+ display: flex;
2251
+ align-items: center;
2252
+ gap: 0.75rem;
2253
+ inline-size: 100%;
2254
+ }
2255
+
2256
+ .ui-slider-track {
2257
+ flex: 1;
2258
+ min-inline-size: 0;
2259
+ }
2260
+
2261
+ /* Tabular figures keep the readout and layout steady mid-drag. */
2262
+ .ui-slider-value {
2263
+ font-family: ${x};
2264
+ font-size: 0.875rem;
2265
+ font-weight: 600;
2266
+ color: var(--foreground);
2267
+ font-variant-numeric: tabular-nums;
2268
+ white-space: nowrap;
2269
+ }
2270
+
2271
+ .ui-slider-ends {
2272
+ display: flex;
2273
+ justify-content: space-between;
2274
+ font-family: ${x};
2275
+ font-size: 0.75rem;
2276
+ color: var(--muted-foreground);
2277
+ font-variant-numeric: tabular-nums;
2278
+ }
2279
+
2280
+ /* 2.75rem tall: the whole input is the touch target (44px). */
2281
+ .ui-slider-input {
2282
+ appearance: none;
2283
+ display: block;
2284
+ inline-size: 100%;
2285
+ block-size: 2.75rem;
2286
+ margin: 0;
2287
+ padding: 0;
2288
+ background: transparent;
2289
+ cursor: pointer;
2290
+ }
2291
+ .ui-slider-input:focus-visible { outline: none; }
2292
+
2293
+ /* --ui-slider-pct is set by the component; it fills the track up to the thumb. */
2294
+ .ui-slider-input::-webkit-slider-runnable-track {
2295
+ block-size: 0.375rem;
2296
+ border-radius: 9999px;
2297
+ background: linear-gradient(to right, var(--primary) var(--ui-slider-pct, 0%), var(--secondary) var(--ui-slider-pct, 0%));
2298
+ }
2299
+ .ui-slider-input::-webkit-slider-thumb {
2300
+ appearance: none;
2301
+ inline-size: 1.25rem;
2302
+ block-size: 1.25rem;
2303
+ margin-block-start: -0.4375rem; /* centre the 1.25rem thumb on the 0.375rem track */
2304
+ border-radius: 50%;
2305
+ border: 2px solid var(--primary);
2306
+ background: var(--background);
2307
+ box-shadow: 0 1px 3px oklch(5% 0 0 / 20%);
2308
+ transition: box-shadow 200ms, border-color 200ms;
2309
+ }
2310
+ .ui-slider-input:focus-visible::-webkit-slider-thumb {
2311
+ border-color: var(--ring);
2312
+ box-shadow: 0 0 0 3px oklch(5% 0 0 / 12%);
2313
+ }
2314
+
2315
+ .ui-slider-input::-moz-range-track {
2316
+ block-size: 0.375rem;
2317
+ border-radius: 9999px;
2318
+ background: var(--secondary);
2319
+ }
2320
+ .ui-slider-input::-moz-range-progress {
2321
+ block-size: 0.375rem;
2322
+ border-radius: 9999px;
2323
+ background: var(--primary);
2324
+ }
2325
+ .ui-slider-input::-moz-range-thumb {
2326
+ inline-size: 1.25rem;
2327
+ block-size: 1.25rem;
2328
+ border-radius: 50%;
2329
+ border: 2px solid var(--primary);
2330
+ background: var(--background);
2331
+ box-shadow: 0 1px 3px oklch(5% 0 0 / 20%);
2332
+ transition: box-shadow 200ms, border-color 200ms;
2333
+ }
2334
+ .ui-slider-input:focus-visible::-moz-range-thumb {
2335
+ border-color: var(--ring);
2336
+ box-shadow: 0 0 0 3px oklch(5% 0 0 / 12%);
2337
+ }
2338
+
2195
2339
  /* ── Annotation layer ───────────────────────────────────── */
2196
2340
  .vd-annotations-layer {
2197
2341
  position: absolute;
@@ -2340,114 +2484,114 @@ const w = {
2340
2484
  50% { opacity: 0.55; }
2341
2485
  }
2342
2486
  `;
2343
- let lt = !1;
2344
- function Et() {
2345
- if (lt || typeof document > "u")
2487
+ let ce = !1;
2488
+ function xe() {
2489
+ if (ce || typeof document > "u")
2346
2490
  return;
2347
- lt = !0;
2491
+ ce = !0;
2348
2492
  const n = document.createElement("style");
2349
- n.id = "vd-ui-vanilla", n.textContent = Ai, document.head.appendChild(n);
2493
+ n.id = "vd-ui-vanilla", n.textContent = Ei, document.head.appendChild(n);
2350
2494
  }
2351
- const Ei = w.fontFamily.sans.join(", ");
2352
- class xi {
2495
+ const xi = w.fontFamily.sans.join(", ");
2496
+ class Ti {
2353
2497
  qrLib = null;
2354
2498
  dialog = null;
2355
2499
  qrSlot = null;
2356
2500
  /** Open the modal immediately, with a loading placeholder in the QR slot. */
2357
2501
  show() {
2358
- this.hide(), Et(), this.dialog = new Si({ onClose: () => {
2502
+ this.hide(), xe(), this.dialog = new wi({ onClose: () => {
2359
2503
  this.dialog = null, this.qrSlot = null;
2360
2504
  } }), Object.assign(this.dialog.card.element.style, {
2361
2505
  display: "flex",
2362
2506
  flexDirection: "column",
2363
2507
  alignItems: "center",
2364
2508
  gap: l[3],
2365
- fontFamily: Ei
2366
- }), this.dialog.card.element.appendChild(this.createText($e(), {
2509
+ fontFamily: xi
2510
+ }), this.dialog.card.element.appendChild(this.createText(Bt(), {
2367
2511
  fontSize: w.fontSize.base,
2368
2512
  fontWeight: w.fontWeight.semibold,
2369
2513
  color: p.neutral[900]
2370
- })), this.dialog.card.element.appendChild(this.createText(Ve(), {
2514
+ })), this.dialog.card.element.appendChild(this.createText(qt(), {
2371
2515
  fontSize: w.fontSize.sm,
2372
2516
  color: p.neutral[600]
2373
- })), this.qrSlot = this.createQrSlot(), this.dialog.card.element.appendChild(this.qrSlot), this.dialog.card.element.appendChild(this.createText(Ge(), {
2517
+ })), this.qrSlot = this.createQrSlot(), this.dialog.card.element.appendChild(this.qrSlot), this.dialog.card.element.appendChild(this.createText(Yt(), {
2374
2518
  fontSize: w.fontSize.xs,
2375
2519
  color: p.neutral[500]
2376
2520
  }));
2377
- const t = new b({
2521
+ const e = new v({
2378
2522
  variant: "outline",
2379
- label: Qe(),
2523
+ label: Jt(),
2380
2524
  onClick: () => {
2381
2525
  this.hide();
2382
2526
  }
2383
2527
  });
2384
- this.dialog.card.element.appendChild(t.element), this.dialog.open();
2528
+ this.dialog.card.element.appendChild(e.element), this.dialog.open();
2385
2529
  }
2386
2530
  /**
2387
2531
  * Render the QR for `url` into the open modal's slot, replacing the loading
2388
2532
  * placeholder. Resolves `true` once the QR is actually on screen; `false`
2389
2533
  * when the modal was closed before it could render (nothing reopens).
2390
2534
  */
2391
- async update(t) {
2535
+ async update(e) {
2392
2536
  this.qrLib ??= await import("./browser-ey6Iih3j.js").then((i) => i.b);
2393
- const e = await this.qrLib.toDataURL(t, {
2537
+ const t = await this.qrLib.toDataURL(e, {
2394
2538
  width: 256,
2395
2539
  margin: 4,
2396
2540
  errorCorrectionLevel: "M",
2397
2541
  color: { dark: p.black, light: p.white }
2398
2542
  });
2399
- return this.qrSlot === null ? !1 : (this.qrSlot.classList.remove("ui-qr-slot--loading"), this.qrSlot.replaceChildren(this.createQrImage(e)), !0);
2543
+ return this.qrSlot === null ? !1 : (this.qrSlot.classList.remove("ui-qr-slot--loading"), this.qrSlot.replaceChildren(this.createQrImage(t)), !0);
2400
2544
  }
2401
2545
  hide() {
2402
2546
  this.dialog?.close(), this.dialog = null, this.qrSlot = null;
2403
2547
  }
2404
- createText(t, e) {
2548
+ createText(e, t) {
2405
2549
  const i = document.createElement("p");
2406
- return i.textContent = t, Object.assign(i.style, { margin: "0", textAlign: "center", ...e }), i;
2550
+ return i.textContent = e, Object.assign(i.style, { margin: "0", textAlign: "center", ...t }), i;
2407
2551
  }
2408
2552
  createQrSlot() {
2409
- const t = document.createElement("div");
2410
- return t.className = "ui-qr-slot ui-qr-slot--loading", t;
2553
+ const e = document.createElement("div");
2554
+ return e.className = "ui-qr-slot ui-qr-slot--loading", e;
2411
2555
  }
2412
- createQrImage(t) {
2413
- const e = document.createElement("img");
2414
- return e.src = t, e.alt = "QR code", e;
2556
+ createQrImage(e) {
2557
+ const t = document.createElement("img");
2558
+ return t.src = e, t.alt = "QR code", t;
2415
2559
  }
2416
2560
  }
2417
- function ct(n) {
2418
- const t = Math.max(0, Math.min(1, n));
2419
- return t * t * (3 - 2 * t);
2561
+ function ue(n) {
2562
+ const e = Math.max(0, Math.min(1, n));
2563
+ return e * e * (3 - 2 * e);
2420
2564
  }
2421
- function Ti(n, t, e, i, o, s) {
2422
- const [r, a, h] = n, d = Math.cos(t), m = Math.sin(t), v = d * r + m * h, E = -m * r + d * h, k = Math.cos(e), C = Math.sin(e), R = k * a - C * E, P = C * a + k * E, J = 0.55;
2423
- return [i + v * s * J, o - R * s * J, P];
2565
+ function Ri(n, e, t, i, s, o) {
2566
+ const [r, a, u] = n, d = Math.cos(e), f = Math.sin(e), h = d * r + f * u, E = -f * r + d * u, _ = Math.cos(t), k = Math.sin(t), I = _ * a - k * E, P = k * a + _ * E, ee = 0.55;
2567
+ return [i + h * o * ee, s - I * o * ee, P];
2424
2568
  }
2425
- function Ri(n, t, e) {
2426
- n.beginPath(), n.moveTo(t[0], t[1]), n.lineTo(e[0], e[1]), n.strokeStyle = "#000", n.lineWidth = 2, n.stroke();
2569
+ function Ii(n, e, t) {
2570
+ n.beginPath(), n.moveTo(e[0], e[1]), n.lineTo(t[0], t[1]), n.strokeStyle = "#000", n.lineWidth = 2, n.stroke();
2427
2571
  }
2428
- function Ii(n, t, e, i, o) {
2429
- const s = t(e), r = t(i), a = [
2430
- s[0] + (r[0] - s[0]) * o,
2431
- s[1] + (r[1] - s[1]) * o,
2432
- s[2]
2572
+ function Li(n, e, t, i, s) {
2573
+ const o = e(t), r = e(i), a = [
2574
+ o[0] + (r[0] - o[0]) * s,
2575
+ o[1] + (r[1] - o[1]) * s,
2576
+ o[2]
2433
2577
  ];
2434
- Ri(n, s, a);
2435
- }
2436
- const $ = [-1, -1, 1], D = [1, -1, 1], B = [1, -1, -1], U = [-1, -1, -1], V = [-1, 1, 1], j = [1, 1, 1], H = [1, 1, -1], q = [-1, 1, -1], dt = [
2437
- [$, D],
2438
- [D, B],
2439
- [B, U],
2440
- [U, $],
2441
- [$, V],
2442
- [D, j],
2443
- [B, H],
2444
- [U, q],
2445
- [V, j],
2578
+ Ii(n, o, a);
2579
+ }
2580
+ const $ = [-1, -1, 1], U = [1, -1, 1], B = [1, -1, -1], V = [-1, -1, -1], j = [-1, 1, 1], H = [1, 1, 1], q = [1, 1, -1], G = [-1, 1, -1], de = [
2581
+ [$, U],
2582
+ [U, B],
2583
+ [B, V],
2584
+ [V, $],
2585
+ [$, j],
2586
+ [U, H],
2587
+ [B, q],
2588
+ [V, G],
2446
2589
  [j, H],
2447
2590
  [H, q],
2448
- [q, V]
2449
- ], Li = 400, ut = '-apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif';
2450
- function Oi() {
2591
+ [q, G],
2592
+ [G, j]
2593
+ ], Oi = 400, he = '-apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif';
2594
+ function Ni() {
2451
2595
  const n = document.createElement("div");
2452
2596
  Object.assign(n.style, {
2453
2597
  position: "absolute",
@@ -2461,15 +2605,15 @@ function Oi() {
2461
2605
  opacity: "0",
2462
2606
  transition: "opacity 0.3s ease-in-out"
2463
2607
  });
2464
- const t = document.createElement("canvas");
2465
- Object.assign(t.style, {
2608
+ const e = document.createElement("canvas");
2609
+ Object.assign(e.style, {
2466
2610
  width: "100%",
2467
2611
  height: "100%",
2468
2612
  position: "absolute",
2469
2613
  inset: "0"
2470
2614
  });
2471
- const e = document.createElement("div");
2472
- Object.assign(e.style, {
2615
+ const t = document.createElement("div");
2616
+ Object.assign(t.style, {
2473
2617
  position: "absolute",
2474
2618
  top: "56%",
2475
2619
  left: "0",
@@ -2483,16 +2627,16 @@ function Oi() {
2483
2627
  fontWeight: "400",
2484
2628
  color: "#000",
2485
2629
  fontVariantNumeric: "tabular-nums",
2486
- fontFamily: ut
2630
+ fontFamily: he
2487
2631
  });
2488
- const o = document.createElement("span");
2489
- return Object.assign(o.style, {
2632
+ const s = document.createElement("span");
2633
+ return Object.assign(s.style, {
2490
2634
  fontSize: "13px",
2491
2635
  color: "#000",
2492
- fontFamily: ut
2493
- }), o.textContent = _t(), e.appendChild(i), e.appendChild(o), n.appendChild(t), n.appendChild(e), { overlay: n, canvas: t, pctEl: i, phaseEl: o };
2636
+ fontFamily: he
2637
+ }), s.textContent = ln(), t.appendChild(i), t.appendChild(s), n.appendChild(e), n.appendChild(t), { overlay: n, canvas: e, pctEl: i, phaseEl: s };
2494
2638
  }
2495
- class Ni {
2639
+ class Mi {
2496
2640
  overlay;
2497
2641
  canvas;
2498
2642
  ctx;
@@ -2503,34 +2647,28 @@ class Ni {
2503
2647
  startTime;
2504
2648
  hidden = !1;
2505
2649
  visible = !1;
2506
- constructor(t, e = {}) {
2650
+ constructor(e, t = {}) {
2507
2651
  this.startTime = performance.now();
2508
- const i = Oi();
2509
- this.overlay = i.overlay, this.canvas = i.canvas, this.pctEl = i.pctEl, this.phaseEl = i.phaseEl, t.appendChild(this.overlay), this.ctx = this.canvas.getContext("2d"), this.ctx !== null && (this.sizeCanvas(), this.tick());
2510
- const o = e.showDelay ?? Li;
2652
+ const i = Ni();
2653
+ this.overlay = i.overlay, this.canvas = i.canvas, this.pctEl = i.pctEl, this.phaseEl = i.phaseEl, e.appendChild(this.overlay), this.ctx = this.canvas.getContext("2d"), this.ctx !== null && (this.sizeCanvas(), this.tick());
2654
+ const s = t.showDelay ?? Oi;
2511
2655
  this.showTimerId = setTimeout(() => {
2512
2656
  this.reveal();
2513
- }, o);
2514
- }
2515
- get loadingTexts() {
2516
- return {
2517
- downloading: _t(),
2518
- rendering: ln()
2519
- };
2657
+ }, s);
2520
2658
  }
2521
- updateProgress(t, e) {
2522
- this.hidden || (this.pctEl.textContent = `${Math.round(t)}%`, this.phaseEl.textContent = e !== "" ? ` · ${e}` : "");
2659
+ updateProgress(e, t) {
2660
+ this.hidden || (this.pctEl.textContent = `${Math.round(e)}%`, this.phaseEl.textContent = t !== "" ? ` · ${t}` : "");
2523
2661
  }
2524
2662
  /**
2525
2663
  * Show an error state — stops animation and displays the error message.
2526
2664
  * The overlay stays visible so the user knows something went wrong.
2527
2665
  */
2528
- showError(t) {
2666
+ showError(e) {
2529
2667
  if (this.hidden = !1, this.animationId !== null && (cancelAnimationFrame(this.animationId), this.animationId = null), this.ctx !== null) {
2530
- const e = Math.min(devicePixelRatio, 2), i = this.canvas.width / e, o = this.canvas.height / e;
2531
- this.ctx.fillStyle = "#fff", this.ctx.fillRect(0, 0, i * e, o * e);
2668
+ const t = Math.min(devicePixelRatio, 2), i = this.canvas.width / t, s = this.canvas.height / t;
2669
+ this.ctx.fillStyle = "#fff", this.ctx.fillRect(0, 0, i * t, s * t);
2532
2670
  }
2533
- this.pctEl.textContent = "", this.phaseEl.textContent = t, this.phaseEl.style.color = "#b91c1c", this.reveal();
2671
+ this.pctEl.textContent = "", this.phaseEl.textContent = e, this.phaseEl.style.color = "#b91c1c", this.reveal();
2534
2672
  }
2535
2673
  hide() {
2536
2674
  if (!this.hidden) {
@@ -2557,8 +2695,8 @@ class Ni {
2557
2695
  sizeCanvas() {
2558
2696
  if (this.ctx === null)
2559
2697
  return;
2560
- const t = Math.min(devicePixelRatio, 2), e = this.overlay.clientWidth || 440, i = this.overlay.clientHeight || 360;
2561
- this.canvas.width = e * t, this.canvas.height = i * t, this.ctx.scale(t, t), this.ctx.lineCap = "round", this.ctx.lineJoin = "round";
2698
+ const e = Math.min(devicePixelRatio, 2), t = this.overlay.clientWidth || 440, i = this.overlay.clientHeight || 360;
2699
+ this.canvas.width = t * e, this.canvas.height = i * e, this.ctx.scale(e, e), this.ctx.lineCap = "round", this.ctx.lineJoin = "round";
2562
2700
  }
2563
2701
  tick = () => {
2564
2702
  this.hidden || (this.drawFrame(), this.animationId = requestAnimationFrame(this.tick));
@@ -2566,24 +2704,24 @@ class Ni {
2566
2704
  drawFrame() {
2567
2705
  if (this.ctx === null)
2568
2706
  return;
2569
- const t = this.canvas.width / Math.min(devicePixelRatio, 2), e = this.canvas.height / Math.min(devicePixelRatio, 2), i = (performance.now() - this.startTime) / 1e3;
2570
- this.ctx.fillStyle = "#fff", this.ctx.fillRect(0, 0, t, e);
2571
- const o = t / 2, s = e * 0.44, r = Math.min(t, e) * 0.08, a = 0.785, h = 0.615, d = (C) => Ti(C, a, h, o, s, r), m = 6, v = i % m / m, E = dt.length;
2572
- let k;
2573
- v < 0.35 ? k = ct(v / 0.35) * E : v < 0.55 ? k = E : v < 0.9 ? k = (1 - ct((v - 0.55) / 0.35)) * E : k = 0, this.ctx.shadowBlur = 5, this.ctx.shadowColor = "rgba(30,30,30,0.08)";
2574
- for (let C = 0; C < E && !(C >= k); C++) {
2575
- const R = dt[C];
2576
- if (R === void 0)
2707
+ const e = this.canvas.width / Math.min(devicePixelRatio, 2), t = this.canvas.height / Math.min(devicePixelRatio, 2), i = (performance.now() - this.startTime) / 1e3;
2708
+ this.ctx.fillStyle = "#fff", this.ctx.fillRect(0, 0, e, t);
2709
+ const s = e / 2, o = t * 0.44, r = Math.min(e, t) * 0.08, a = 0.785, u = 0.615, d = (k) => Ri(k, a, u, s, o, r), f = 6, h = i % f / f, E = de.length;
2710
+ let _;
2711
+ h < 0.35 ? _ = ue(h / 0.35) * E : h < 0.55 ? _ = E : h < 0.9 ? _ = (1 - ue((h - 0.55) / 0.35)) * E : _ = 0, this.ctx.shadowBlur = 5, this.ctx.shadowColor = "rgba(30,30,30,0.08)";
2712
+ for (let k = 0; k < E && !(k >= _); k++) {
2713
+ const I = de[k];
2714
+ if (I === void 0)
2577
2715
  continue;
2578
- const P = Math.min(1, k - C);
2579
- Ii(this.ctx, d, R[0], R[1], P);
2716
+ const P = Math.min(1, _ - k);
2717
+ Li(this.ctx, d, I[0], I[1], P);
2580
2718
  }
2581
2719
  this.ctx.shadowBlur = 0;
2582
2720
  }
2583
2721
  }
2584
- class Mi {
2585
- constructor(t) {
2586
- this.options = t, this.element = document.createElement("div"), Object.assign(this.element.style, { display: "flex", gap: "0.375rem" }), this.onFullscreenChange = () => {
2722
+ class zi {
2723
+ constructor(e) {
2724
+ this.options = e, this.element = document.createElement("div"), Object.assign(this.element.style, { display: "flex", gap: "0.375rem" }), this.onFullscreenChange = () => {
2587
2725
  this.setFullscreenIcon(document.fullscreenElement !== null);
2588
2726
  }, document.addEventListener("fullscreenchange", this.onFullscreenChange);
2589
2727
  }
@@ -2592,30 +2730,30 @@ class Mi {
2592
2730
  arBtn = null;
2593
2731
  fullscreenBtn = null;
2594
2732
  onFullscreenChange;
2595
- setFullscreenIcon(t) {
2596
- this.fullscreenBtn !== null && this.fullscreenBtn.setIcon(t ? g.exitFullscreen() : g.fullscreen());
2733
+ setFullscreenIcon(e) {
2734
+ this.fullscreenBtn !== null && this.fullscreenBtn.setIcon(e ? b.exitFullscreen() : b.fullscreen());
2597
2735
  }
2598
- syncButton(t, e, i) {
2599
- if (e && t === null) {
2600
- const o = i();
2601
- return this.element.appendChild(o.element), o;
2736
+ syncButton(e, t, i) {
2737
+ if (t && e === null) {
2738
+ const s = i();
2739
+ return this.element.appendChild(s.element), s;
2602
2740
  }
2603
- return !e && t !== null ? (t.element.remove(), null) : t;
2741
+ return !t && e !== null ? (e.element.remove(), null) : e;
2604
2742
  }
2605
- applySettings(t) {
2606
- this.arBtn = this.syncButton(this.arBtn, t.ar !== !1 && this.options.onAr !== void 0, () => new b({
2743
+ applySettings(e) {
2744
+ this.arBtn = this.syncButton(this.arBtn, e.ar !== !1 && this.options.onAr !== void 0, () => new v({
2607
2745
  variant: "outline",
2608
2746
  size: "icon",
2609
- label: Me(),
2610
- icon: g.ar(),
2747
+ label: Ft(),
2748
+ icon: b.ar(),
2611
2749
  onClick: () => {
2612
2750
  this.options.onAr?.();
2613
2751
  }
2614
- })), this.fullscreenBtn = this.syncButton(this.fullscreenBtn, t.fullscreen !== !1 && this.options.onFullscreen !== void 0, () => new b({
2752
+ })), this.fullscreenBtn = this.syncButton(this.fullscreenBtn, e.fullscreen !== !1 && this.options.onFullscreen !== void 0, () => new v({
2615
2753
  variant: "outline",
2616
2754
  size: "icon",
2617
- label: tn(),
2618
- icon: g.fullscreen(),
2755
+ label: sn(),
2756
+ icon: b.fullscreen(),
2619
2757
  onClick: () => {
2620
2758
  this.options.onFullscreen?.();
2621
2759
  }
@@ -2625,81 +2763,81 @@ class Mi {
2625
2763
  document.removeEventListener("fullscreenchange", this.onFullscreenChange);
2626
2764
  }
2627
2765
  }
2628
- const T = 0.5;
2766
+ const R = 0.5;
2629
2767
  class z {
2630
2768
  element;
2631
- constructor(t, e) {
2769
+ constructor(e, t) {
2632
2770
  this.element = Object.assign(document.createElement("div"), { className: "vd-camera-controls" });
2633
2771
  const i = {
2634
- targetRotation: e.rotation,
2635
- targetTilt: e.tilt,
2636
- targetZoom: e.zoom,
2772
+ targetRotation: t.rotation,
2773
+ targetTilt: t.tilt,
2774
+ targetZoom: t.zoom,
2637
2775
  thetaOffset: 0
2638
- }, o = zi(t, e, i);
2639
- e.onChange((s) => {
2640
- i.targetRotation = s.rotation - i.thetaOffset, i.targetTilt = s.tilt, i.targetZoom = s.zoom, Pi(o, e, s);
2641
- }), this.element.appendChild(z.buildZoom(o.zoomOut, o.zoomIn)), this.element.appendChild(z.buildDpad(o.tiltUp, o.rotateLeft, o.reset, o.rotateRight, o.tiltDown));
2776
+ }, s = Pi(e, t, i);
2777
+ t.onChange((o) => {
2778
+ i.targetRotation = o.rotation - i.thetaOffset, i.targetTilt = o.tilt, i.targetZoom = o.zoom, Fi(s, t, o);
2779
+ }), this.element.appendChild(z.buildZoom(s.zoomOut, s.zoomIn)), this.element.appendChild(z.buildDpad(s.tiltUp, s.rotateLeft, s.reset, s.rotateRight, s.tiltDown));
2642
2780
  }
2643
- static buildZoom(t, e) {
2781
+ static buildZoom(e, t) {
2644
2782
  const i = document.createElement("div");
2645
- return i.className = "vd-zoom", i.appendChild(t.element), i.appendChild(e.element), i;
2783
+ return i.className = "vd-zoom", i.appendChild(e.element), i.appendChild(t.element), i;
2646
2784
  }
2647
- static buildDpad(t, e, i, o, s) {
2785
+ static buildDpad(e, t, i, s, o) {
2648
2786
  const r = document.createElement("div");
2649
2787
  r.className = "vd-dpad";
2650
- for (const [a, h] of [
2651
- [t, "up"],
2652
- [e, "left"],
2788
+ for (const [a, u] of [
2789
+ [e, "up"],
2790
+ [t, "left"],
2653
2791
  [i, "center"],
2654
- [o, "right"],
2655
- [s, "down"]
2792
+ [s, "right"],
2793
+ [o, "down"]
2656
2794
  ])
2657
- a.element.classList.add(`vd-dpad-${h}`), r.appendChild(a.element);
2795
+ a.element.classList.add(`vd-dpad-${u}`), r.appendChild(a.element);
2658
2796
  return r;
2659
2797
  }
2660
2798
  }
2661
- function zi(n, t, e) {
2662
- const i = (r) => Math.max(t.limits?.minZoom ?? 1, Math.min(t.limits?.maxZoom ?? 1 / 0, r)), o = (r) => {
2663
- const a = t.limits?.minRotate, h = t.limits?.maxRotate;
2664
- return a !== void 0 || h !== void 0 ? Math.max(a ?? -1 / 0, Math.min(h ?? 1 / 0, r)) : r;
2665
- }, s = (r) => {
2666
- const a = t.limits?.minTilt, h = t.limits?.maxTilt;
2667
- if (a !== void 0 || h !== void 0) {
2668
- e.targetTilt = Math.max(a ?? 0, Math.min(h ?? 180, e.targetTilt + r)), n.tilt(e.targetTilt).set();
2799
+ function Pi(n, e, t) {
2800
+ const i = (r) => Math.max(e.limits?.minZoom ?? 1, Math.min(e.limits?.maxZoom ?? 1 / 0, r)), s = (r) => {
2801
+ const a = e.limits?.minRotate, u = e.limits?.maxRotate;
2802
+ return a !== void 0 || u !== void 0 ? Math.max(a ?? -1 / 0, Math.min(u ?? 1 / 0, r)) : r;
2803
+ }, o = (r) => {
2804
+ const a = e.limits?.minTilt, u = e.limits?.maxTilt;
2805
+ if (a !== void 0 || u !== void 0) {
2806
+ t.targetTilt = Math.max(a ?? 0, Math.min(u ?? 180, t.targetTilt + r)), n.tilt(t.targetTilt).set();
2669
2807
  return;
2670
2808
  }
2671
- const d = e.targetTilt + r;
2672
- d > 180 || d < 0 ? (e.targetTilt = d > 180 ? 360 - d : -d, e.thetaOffset = (e.thetaOffset + 180) % 360, n.tilt(e.targetTilt).rotate(e.targetRotation + e.thetaOffset).set()) : (e.targetTilt = d, n.tilt(e.targetTilt).set());
2809
+ const d = t.targetTilt + r;
2810
+ d > 180 || d < 0 ? (t.targetTilt = d > 180 ? 360 - d : -d, t.thetaOffset = (t.thetaOffset + 180) % 360, n.tilt(t.targetTilt).rotate(t.targetRotation + t.thetaOffset).set()) : (t.targetTilt = d, n.tilt(t.targetTilt).set());
2673
2811
  };
2674
2812
  return {
2675
- zoomOut: new b({ variant: "outline", size: "icon", label: On(), icon: g.zoomOut(), onClick: () => {
2676
- e.targetZoom = i(e.targetZoom - 10), n.zoom(e.targetZoom).set();
2813
+ zoomOut: new v({ variant: "outline", size: "icon", label: On(), icon: b.zoomOut(), onClick: () => {
2814
+ t.targetZoom = i(t.targetZoom - 10), n.zoom(t.targetZoom).set();
2677
2815
  } }),
2678
- zoomIn: new b({ variant: "outline", size: "icon", label: Tn(), icon: g.zoomIn(), onClick: () => {
2679
- e.targetZoom = i(e.targetZoom + 10), n.zoom(e.targetZoom).set();
2816
+ zoomIn: new v({ variant: "outline", size: "icon", label: Tn(), icon: b.zoomIn(), onClick: () => {
2817
+ t.targetZoom = i(t.targetZoom + 10), n.zoom(t.targetZoom).set();
2680
2818
  } }),
2681
- tiltUp: new b({ variant: "outline", size: "icon", label: Hn(), icon: g.tiltUp(), onClick: () => {
2682
- s(-15);
2819
+ tiltUp: new v({ variant: "outline", size: "icon", label: Hn(), icon: b.tiltUp(), onClick: () => {
2820
+ o(-15);
2683
2821
  } }),
2684
- rotateLeft: new b({ variant: "outline", size: "icon", label: Pn(), icon: g.rotateLeft(), onClick: () => {
2685
- e.targetRotation = o(e.targetRotation - 15), n.rotate(e.targetRotation + e.thetaOffset).set();
2822
+ rotateLeft: new v({ variant: "outline", size: "icon", label: Pn(), icon: b.rotateLeft(), onClick: () => {
2823
+ t.targetRotation = s(t.targetRotation - 15), n.rotate(t.targetRotation + t.thetaOffset).set();
2686
2824
  } }),
2687
- reset: new b({ variant: "outline", size: "icon", label: kn(), icon: g.reset(), onClick: () => {
2688
- e.thetaOffset = 0, n.reset();
2825
+ reset: new v({ variant: "outline", size: "icon", label: _n(), icon: b.reset(), onClick: () => {
2826
+ t.thetaOffset = 0, n.reset();
2689
2827
  } }),
2690
- rotateRight: new b({ variant: "outline", size: "icon", label: Bn(), icon: g.rotateRight(), onClick: () => {
2691
- e.targetRotation = o(e.targetRotation + 15), n.rotate(e.targetRotation + e.thetaOffset).set();
2828
+ rotateRight: new v({ variant: "outline", size: "icon", label: Un(), icon: b.rotateRight(), onClick: () => {
2829
+ t.targetRotation = s(t.targetRotation + 15), n.rotate(t.targetRotation + t.thetaOffset).set();
2692
2830
  } }),
2693
- tiltDown: new b({ variant: "outline", size: "icon", label: Wn(), icon: g.tiltDown(), onClick: () => {
2694
- s(15);
2831
+ tiltDown: new v({ variant: "outline", size: "icon", label: Wn(), icon: b.tiltDown(), onClick: () => {
2832
+ o(15);
2695
2833
  } })
2696
2834
  };
2697
2835
  }
2698
- function Pi(n, t, e) {
2699
- const i = t.limits;
2700
- i !== void 0 && (n.zoomOut.element.disabled = i.minZoom !== void 0 && e.zoom <= i.minZoom + T, n.zoomIn.element.disabled = i.maxZoom !== void 0 && e.zoom >= i.maxZoom - T, n.tiltUp.element.disabled = i.minTilt !== void 0 && e.tilt <= i.minTilt + T, n.tiltDown.element.disabled = i.maxTilt !== void 0 && e.tilt >= i.maxTilt - T, n.rotateLeft.element.disabled = i.minRotate !== void 0 && e.rotation <= i.minRotate + T, n.rotateRight.element.disabled = i.maxRotate !== void 0 && e.rotation >= i.maxRotate - T);
2836
+ function Fi(n, e, t) {
2837
+ const i = e.limits;
2838
+ i !== void 0 && (n.zoomOut.element.disabled = i.minZoom !== void 0 && t.zoom <= i.minZoom + R, n.zoomIn.element.disabled = i.maxZoom !== void 0 && t.zoom >= i.maxZoom - R, n.tiltUp.element.disabled = i.minTilt !== void 0 && t.tilt <= i.minTilt + R, n.tiltDown.element.disabled = i.maxTilt !== void 0 && t.tilt >= i.maxTilt - R, n.rotateLeft.element.disabled = i.minRotate !== void 0 && t.rotation <= i.minRotate + R, n.rotateRight.element.disabled = i.maxRotate !== void 0 && t.rotation >= i.maxRotate - R);
2701
2839
  }
2702
- const L = {
2840
+ const T = {
2703
2841
  /** Attribute selection requested (cancelable). `detail`: `{ attribute, value }`. */
2704
2842
  SELECT: "ui:select",
2705
2843
  /** Attribute selection applied. `detail`: `{ attribute, value }`. */
@@ -2710,32 +2848,97 @@ const L = {
2710
2848
  CONFIGURATION_CHANGE: "vd:configuration-change",
2711
2849
  /** Configuration submitted (bubbles). `detail`: the resolved configuration handed to the host. */
2712
2850
  CONFIGURATION_SUBMIT: "vd:configuration-submit"
2713
- }, Fi = 5;
2714
- let $i = 0;
2715
- function G(n) {
2716
- const t = n.replace(/([A-Z])/g, " $1").trim();
2717
- return t.charAt(0).toUpperCase() + t.slice(1).toLowerCase();
2718
- }
2719
- function Di(n, t, e, i, o) {
2720
- const s = document.createElement("div");
2721
- s.className = "vd-attribute", s.dataset.name = n.name;
2722
- const r = document.createElement("span");
2723
- r.className = "vd-attribute-label", r.textContent = G(n.name), r.id = `vd-attribute-label-${$i++}`, s.appendChild(r), s.setAttribute("role", "group"), s.setAttribute("aria-labelledby", r.id);
2724
- const a = n.values.find((m) => t.getValue(n.name, m)?.isSelected === !0), h = n.values.map(G), d = n.values.length <= Fi ? new _i(n.values, a, h) : new Ci(n.name, n.values, G(n.name), a, h);
2725
- return d.onSelect((m) => {
2726
- e.dispatch(L.SELECT, { attribute: n.name, value: m }, !0).defaultPrevented || i(n.name, m);
2727
- }), o(n.name, (m) => {
2728
- d.setSelected(m.value), e.dispatch(L.SELECTED, { attribute: n.name, value: m.value });
2729
- }), s.appendChild(d.element), { element: s, setSelectable: (m) => {
2730
- d.setEnabled(m);
2731
- } };
2732
- }
2733
- const Bi = 80, Ui = 2500;
2734
- class Vi {
2735
- constructor(t, e = Ui) {
2736
- this.configuration = t, this.resetMs = e, this.element = document.createElement("div"), this.element.className = "vd-commerce vd-hidden";
2851
+ }, Te = {
2852
+ mm: 1,
2853
+ cm: 10,
2854
+ m: 1e3,
2855
+ in: 25.4
2856
+ }, me = 3;
2857
+ function Di(n) {
2858
+ const e = n.stepMm / Te[n.displayUnit];
2859
+ for (let t = 0; t <= me; t++) {
2860
+ const i = e * 10 ** t;
2861
+ if (Math.abs(i - Math.round(i)) < 1e-9)
2862
+ return t;
2863
+ }
2864
+ return me;
2865
+ }
2866
+ function $i(n, e, t) {
2867
+ const i = Di(e), s = n / Te[e.displayUnit];
2868
+ return new Intl.NumberFormat(t, {
2869
+ minimumFractionDigits: i,
2870
+ maximumFractionDigits: i
2871
+ }).format(s);
2872
+ }
2873
+ function Ui(n, e, t, i, s, o, r) {
2874
+ const a = m(), u = n.values.map((h) => $i(Number(h), e, a)), d = n.values.find((h) => t.getValue(n.name, h)?.isSelected === !0) ?? n.defaultValue, f = new _i(n.values, {
2875
+ label: n.name,
2876
+ labels: u,
2877
+ unit: e.displayUnit,
2878
+ ...d !== void 0 && { initialSelected: d }
2879
+ });
2880
+ return f.onSelect((h) => {
2881
+ s(n.name, h);
2882
+ }), f.onSettle((h) => {
2883
+ i.dispatch(T.SELECT, { attribute: n.name, value: h }, !0).defaultPrevented || o(n.name, h);
2884
+ }), r(n.name, (h) => {
2885
+ f.setSelected(h.value), i.dispatch(T.SELECTED, { attribute: n.name, value: h.value });
2886
+ }), {
2887
+ element: f.element,
2888
+ // No per-notch grey-out on the slider in v1: a range control cannot
2889
+ // honestly disable one notch. The exclusion still works, the way it
2890
+ // always does, on the other side: the viewer's selectable snapshot greys
2891
+ // the leg that cannot do this size. A slider-side treatment is a later
2892
+ // refinement, noted in task 040.
2893
+ setSelectable: () => {
2894
+ }
2895
+ };
2896
+ }
2897
+ const Bi = 5;
2898
+ let Vi = 0;
2899
+ function K(n) {
2900
+ const e = n.replace(/([A-Z])/g, " $1").trim();
2901
+ return e.charAt(0).toUpperCase() + e.slice(1).toLowerCase();
2902
+ }
2903
+ function ji(n, e, t, i, s, o) {
2904
+ const r = document.createElement("div");
2905
+ r.className = "vd-attribute", r.dataset.name = n.name;
2906
+ const a = document.createElement("span");
2907
+ a.className = "vd-attribute-label", a.textContent = K(n.name), a.id = `vd-attribute-label-${Vi++}`, r.appendChild(a), r.setAttribute("role", "group"), r.setAttribute("aria-labelledby", a.id);
2908
+ const u = (f) => {
2909
+ r.style.display = f ? "none" : "";
2910
+ }, d = n.dimension !== void 0 ? Ui(
2911
+ n,
2912
+ n.dimension,
2913
+ e,
2914
+ t,
2915
+ s,
2916
+ i,
2917
+ o
2918
+ ) : Hi(n, e, t, i, o);
2919
+ return r.appendChild(d.element), { element: r, setSelectable: d.setSelectable, setHidden: u };
2920
+ }
2921
+ function Hi(n, e, t, i, s) {
2922
+ const o = n.values.find(
2923
+ (u) => e.getValue(n.name, u)?.isSelected === !0
2924
+ ), r = n.values.map(K), a = n.values.length <= Bi ? new Ci(n.values, o, r) : new ki(n.name, n.values, K(n.name), o, r);
2925
+ return a.onSelect((u) => {
2926
+ t.dispatch(T.SELECT, { attribute: n.name, value: u }, !0).defaultPrevented || i(n.name, u);
2927
+ }), s(n.name, (u) => {
2928
+ a.setSelected(u.value), t.dispatch(T.SELECTED, { attribute: n.name, value: u.value });
2929
+ }), {
2930
+ element: a.element,
2931
+ setSelectable: (u) => {
2932
+ a.setEnabled(u);
2933
+ }
2934
+ };
2935
+ }
2936
+ const qi = 80, Gi = 2500;
2937
+ class Zi {
2938
+ constructor(e, t = Gi) {
2939
+ this.configuration = e, this.resetMs = t, this.element = document.createElement("div"), this.element.className = "vd-commerce vd-hidden";
2737
2940
  const i = document.createElement("div");
2738
- i.className = "vd-commerce-price", this.priceEl = document.createElement("span"), this.priceEl.className = "vd-price", this.vatEl = document.createElement("span"), this.vatEl.className = "vd-vat", i.append(this.priceEl, this.vatEl), this.button = new b({ variant: "default", onClick: () => {
2941
+ i.className = "vd-commerce-price", this.priceEl = document.createElement("span"), this.priceEl.className = "vd-price", this.vatEl = document.createElement("span"), this.vatEl.className = "vd-vat", i.append(this.priceEl, this.vatEl), this.button = new v({ variant: "default", onClick: () => {
2739
2942
  this.handleSubmit();
2740
2943
  } }), this.button.element.classList.add("vd-cta", "vd-hidden"), this.element.append(i, this.button.element), this.unsubscribe = this.configuration.onRender(() => {
2741
2944
  this.update();
@@ -2753,22 +2956,22 @@ class Vi {
2753
2956
  /** Re-render from the facade. Called on every resolve and on submit-handler registration. */
2754
2957
  update() {
2755
2958
  this.renderPrice(this.configuration.current), this.renderButton();
2756
- const t = this.configuration.current !== void 0 || this.configuration.submitEnabled;
2757
- this.element.classList.toggle("vd-hidden", !t);
2959
+ const e = this.configuration.current !== void 0 || this.configuration.submitEnabled;
2960
+ this.element.classList.toggle("vd-hidden", !e);
2758
2961
  }
2759
2962
  destroy() {
2760
2963
  this.unsubscribe(), this.resetTimer !== void 0 && clearTimeout(this.resetTimer), this.element.remove();
2761
2964
  }
2762
- renderPrice(t) {
2763
- if (t === void 0) {
2965
+ renderPrice(e) {
2966
+ if (e === void 0) {
2764
2967
  this.priceEl.textContent = "", this.vatEl.textContent = "";
2765
2968
  return;
2766
2969
  }
2767
- this.priceEl.textContent = ji(t.price, t.currency), this.vatEl.textContent = ht(this.configuration.vatDisplay);
2970
+ this.priceEl.textContent = Wi(e.price, e.currency), this.vatEl.textContent = pe(this.configuration.vatDisplay);
2768
2971
  }
2769
2972
  renderButton() {
2770
- const t = this.configuration.submitEnabled;
2771
- this.button.element.classList.toggle("vd-hidden", !t), t && this.state === "idle" && this.setButtonText(ht(this.configuration.buttonLabel));
2973
+ const e = this.configuration.submitEnabled;
2974
+ this.button.element.classList.toggle("vd-hidden", !e), e && this.state === "idle" && this.setButtonText(pe(this.configuration.buttonLabel));
2772
2975
  }
2773
2976
  async handleSubmit() {
2774
2977
  if (this.state !== "busy") {
@@ -2786,43 +2989,43 @@ class Vi {
2786
2989
  this.state = "idle", this.update();
2787
2990
  }, this.resetMs);
2788
2991
  }
2789
- setState(t, e) {
2790
- this.state = t, this.element.dataset.submit = t, this.button.element.disabled = t === "busy", this.setButtonText(e);
2992
+ setState(e, t) {
2993
+ this.state = e, this.element.dataset.submit = e, this.button.element.disabled = e === "busy", this.setButtonText(t);
2791
2994
  }
2792
- setButtonText(t) {
2793
- this.button.element.textContent = t, this.button.element.setAttribute("aria-label", t);
2995
+ setButtonText(e) {
2996
+ this.button.element.textContent = e, this.button.element.setAttribute("aria-label", e);
2794
2997
  }
2795
2998
  }
2796
- function ht(n) {
2797
- return (n ?? "").slice(0, Bi);
2999
+ function pe(n) {
3000
+ return (n ?? "").slice(0, qi);
2798
3001
  }
2799
- function ji(n, t) {
3002
+ function Wi(n, e) {
2800
3003
  try {
2801
- const e = new Intl.NumberFormat(u(), { style: "currency", currency: t }), i = e.resolvedOptions().maximumFractionDigits ?? 2;
2802
- return e.format(n / 10 ** i);
3004
+ const t = new Intl.NumberFormat(m(), { style: "currency", currency: e }), i = t.resolvedOptions().maximumFractionDigits ?? 2;
3005
+ return t.format(n / 10 ** i);
2803
3006
  } catch {
2804
- return `${t} ${(n / 100).toFixed(2)}`;
3007
+ return `${e} ${(n / 100).toFixed(2)}`;
2805
3008
  }
2806
3009
  }
2807
- class xt {
3010
+ class Re {
2808
3011
  slot = null;
2809
3012
  panel = null;
2810
- attach(t, e) {
2811
- this.panel = e, e.style.display = "none", this.slot = document.createElement("div"), this.slot.className = "vd-slot-bottom-left", this.slot.appendChild(e), t.appendChild(this.slot);
3013
+ attach(e, t) {
3014
+ this.panel = t, t.style.display = "none", this.slot = document.createElement("div"), this.slot.className = "vd-slot-bottom-left", this.slot.appendChild(t), e.appendChild(this.slot);
2812
3015
  }
2813
- setVisible(t) {
2814
- this.panel !== null && (this.panel.style.display = t ? "flex" : "none");
3016
+ setVisible(e) {
3017
+ this.panel !== null && (this.panel.style.display = e ? "flex" : "none");
2815
3018
  }
2816
3019
  destroy() {
2817
3020
  this.slot?.remove(), this.slot = null, this.panel = null;
2818
3021
  }
2819
3022
  }
2820
- const Hi = 572;
2821
- class qi {
3023
+ const Yi = 572;
3024
+ class Qi {
2822
3025
  /** @param actionBarSlot The shared corner slot the AR/fullscreen buttons live in — the
2823
3026
  * "open configurator" toggle joins them there instead of floating as its own overlay. */
2824
- constructor(t) {
2825
- this.actionBarSlot = t;
3027
+ constructor(e) {
3028
+ this.actionBarSlot = e;
2826
3029
  }
2827
3030
  actionBarSlot;
2828
3031
  element = null;
@@ -2834,71 +3037,71 @@ class qi {
2834
3037
  collapsible = !1;
2835
3038
  expanded = !0;
2836
3039
  visible = !1;
2837
- attach(t, e) {
2838
- this.container = t, e.classList.add("vd-attributes-sidebar"), this.closeButton = new b({
3040
+ attach(e, t) {
3041
+ this.container = e, t.classList.add("vd-attributes-sidebar"), this.closeButton = new v({
2839
3042
  variant: "ghost",
2840
3043
  size: "icon-sm",
2841
- label: wn(),
2842
- icon: g.close({ size: 18 }),
3044
+ label: Sn(),
3045
+ icon: b.close({ size: 18 }),
2843
3046
  onClick: () => {
2844
3047
  this.expanded = !1, this.render();
2845
3048
  }
2846
3049
  });
2847
3050
  const i = document.createElement("div");
2848
- i.className = "vd-sidebar-header", i.appendChild(this.closeButton.element), this.body = document.createElement("div"), this.body.className = "vd-sidebar-body", this.body.appendChild(e), this.element = document.createElement("div"), this.element.className = "vd-sidebar vd-hidden", this.element.append(i, this.body), t.appendChild(this.element), this.openButton = new b({
3051
+ i.className = "vd-sidebar-header", i.appendChild(this.closeButton.element), this.body = document.createElement("div"), this.body.className = "vd-sidebar-body", this.body.appendChild(t), this.element = document.createElement("div"), this.element.className = "vd-sidebar vd-hidden", this.element.append(i, this.body), e.appendChild(this.element), this.openButton = new v({
2849
3052
  variant: "outline",
2850
3053
  size: "icon",
2851
3054
  label: gn(),
2852
- icon: g.configurator({ size: 18 }),
3055
+ icon: b.configurator({ size: 18 }),
2853
3056
  onClick: () => {
2854
3057
  this.expanded = !0, this.render();
2855
3058
  }
2856
3059
  }), this.openButton.element.classList.add("vd-configurator-toggle", "vd-hidden"), this.actionBarSlot.appendChild(this.openButton.element), this.observe();
2857
3060
  }
2858
- setVisible(t) {
2859
- this.visible = t, this.render();
3061
+ setVisible(e) {
3062
+ this.visible = e, this.render();
2860
3063
  }
2861
3064
  destroy() {
2862
3065
  this.observer?.disconnect(), this.observer = null, this.openButton?.element.remove(), this.element?.remove(), this.container?.classList.remove("vd-layout-sidebar-right", "vd-layout-sidebar-permanent"), this.container = null;
2863
3066
  }
2864
3067
  observe() {
2865
- typeof ResizeObserver > "u" || this.container === null || (this.observer = new ResizeObserver((t) => {
2866
- const e = t[0]?.contentRect.width ?? 0;
2867
- this.setCollapsible(e > 0 && e < Hi);
3068
+ typeof ResizeObserver > "u" || this.container === null || (this.observer = new ResizeObserver((e) => {
3069
+ const t = e[0]?.contentRect.width ?? 0;
3070
+ this.setCollapsible(t > 0 && t < Yi);
2868
3071
  }), this.observer.observe(this.container));
2869
3072
  }
2870
- setCollapsible(t) {
2871
- t !== this.collapsible && (this.collapsible = t, this.expanded = !t, this.render());
3073
+ setCollapsible(e) {
3074
+ e !== this.collapsible && (this.collapsible = e, this.expanded = !e, this.render());
2872
3075
  }
2873
3076
  render() {
2874
3077
  if (this.element === null || this.openButton === null || this.closeButton === null || this.container === null)
2875
3078
  return;
2876
- const t = this.visible && this.expanded, e = this.visible && !this.expanded;
2877
- this.element.classList.toggle("vd-hidden", !this.visible), this.element.classList.toggle("vd-sidebar-collapsed", e), this.openButton.element.classList.toggle("vd-hidden", !e), this.closeButton.element.style.display = this.collapsible ? "" : "none", this.container.classList.toggle("vd-layout-sidebar-right", t), this.container.classList.toggle("vd-layout-sidebar-permanent", t && !this.collapsible);
3079
+ const e = this.visible && this.expanded, t = this.visible && !this.expanded;
3080
+ this.element.classList.toggle("vd-hidden", !this.visible), this.element.classList.toggle("vd-sidebar-collapsed", t), this.openButton.element.classList.toggle("vd-hidden", !t), this.closeButton.element.style.display = this.collapsible ? "" : "none", this.container.classList.toggle("vd-layout-sidebar-right", e), this.container.classList.toggle("vd-layout-sidebar-permanent", e && !this.collapsible);
2878
3081
  }
2879
3082
  }
2880
- class Gi {
2881
- attach(t, e) {
3083
+ class Ki {
3084
+ attach(e, t) {
2882
3085
  }
2883
- setVisible(t) {
3086
+ setVisible(e) {
2884
3087
  }
2885
3088
  destroy() {
2886
3089
  }
2887
3090
  }
2888
- const Zi = {
2889
- "inframe-bottom-left": () => new xt(),
2890
- "sidebar-right": (n) => new qi(n),
2891
- hidden: () => new Gi()
3091
+ const Xi = {
3092
+ "inframe-bottom-left": () => new Re(),
3093
+ "sidebar-right": (n) => new Qi(n),
3094
+ hidden: () => new Ki()
2892
3095
  };
2893
- function Wi(n, t) {
2894
- return (Zi[n ?? ""] ?? (() => new xt()))(t);
3096
+ function Ji(n, e) {
3097
+ return (Xi[n ?? ""] ?? (() => new Re()))(e);
2895
3098
  }
2896
3099
  const Z = w.fontFamily.sans.join(", "), W = `
2897
3100
  position: absolute;
2898
3101
  display: flex;
2899
3102
  z-index: 10;
2900
3103
  transition: inset-inline-end 0.18s ease;
2901
- `, Yi = `
3104
+ `, es = `
2902
3105
  /* Override browser's default black fullscreen backdrop */
2903
3106
  .vd-container:fullscreen {
2904
3107
  background: oklch(100% 0 0);
@@ -3101,17 +3304,17 @@ const Z = w.fontFamily.sans.join(", "), W = `
3101
3304
  }
3102
3305
 
3103
3306
  `;
3104
- function Qi() {
3105
- if (Et(), document.getElementById("vd-styles") !== null)
3307
+ function ts() {
3308
+ if (xe(), document.getElementById("vd-styles") !== null)
3106
3309
  return;
3107
3310
  const n = document.createElement("style");
3108
- n.id = "vd-styles", n.textContent = Yi, document.head.appendChild(n);
3311
+ n.id = "vd-styles", n.textContent = es, document.head.appendChild(n);
3109
3312
  }
3110
- function Ki(n, t) {
3111
- const e = document.createElement("a");
3112
- e.href = `data:image/png;base64,${n}`, e.download = t, e.click();
3313
+ function ns(n, e) {
3314
+ const t = document.createElement("a");
3315
+ t.href = `data:image/png;base64,${n}`, t.download = e, t.click();
3113
3316
  }
3114
- class Xi {
3317
+ class is {
3115
3318
  options;
3116
3319
  settings = {};
3117
3320
  container = null;
@@ -3127,11 +3330,11 @@ class Xi {
3127
3330
  lastSelectable = null;
3128
3331
  layout = null;
3129
3332
  commerce = null;
3130
- constructor(t) {
3131
- this.options = t;
3333
+ constructor(e) {
3334
+ this.options = e;
3132
3335
  }
3133
- attach(t) {
3134
- Qi(), this.container = t, this.loading = new Ni(t), this.slots.topRight = this.createSlot(t, "vd-slot-top-right"), this.slots.bottomRight = this.createSlot(t, "vd-slot-bottom-right");
3336
+ attach(e) {
3337
+ ts(), this.container = e, this.loading = new Mi(e), this.slots.topRight = this.createSlot(e, "vd-slot-top-right"), this.slots.bottomRight = this.createSlot(e, "vd-slot-bottom-right");
3135
3338
  }
3136
3339
  onReady() {
3137
3340
  this.loading?.hide(), this.loading = null, this.mountToolbar(), this.cameraControls !== null && (this.cameraControls.element.style.display = "flex"), this.layout?.setVisible(!0);
@@ -3139,10 +3342,10 @@ class Xi {
3139
3342
  mountToolbar() {
3140
3343
  if (this.actionBar !== null || this.slots.bottomRight === null || this.container === null)
3141
3344
  return;
3142
- const t = typeof this.container.requestFullscreen == "function";
3143
- this.actionBar = new Mi({
3345
+ const e = typeof this.container.requestFullscreen == "function";
3346
+ this.actionBar = new zi({
3144
3347
  onAr: this.options.onAr,
3145
- onFullscreen: t ? () => {
3348
+ onFullscreen: e ? () => {
3146
3349
  this.toggleFullscreen();
3147
3350
  } : void 0
3148
3351
  }), this.actionBar.applySettings(this.settings), this.slots.bottomRight.appendChild(this.actionBar.element), this.syncScreenshotButton(), this.placeScreenshotButton();
@@ -3150,29 +3353,36 @@ class Xi {
3150
3353
  toggleFullscreen() {
3151
3354
  this.container !== null && (document.fullscreenElement !== null ? document.exitFullscreen() : (this.options.onFullscreenEnter?.(), this.container.requestFullscreen()));
3152
3355
  }
3153
- updateProgress(t, e) {
3154
- this.loading?.updateProgress(t, e);
3356
+ updateProgress(e, t) {
3357
+ this.loading?.updateProgress(e, t);
3155
3358
  }
3156
- showError(t) {
3157
- this.loading?.showError(t);
3359
+ showError(e) {
3360
+ this.loading?.showError(e);
3158
3361
  }
3159
- applyViewerSettings(t) {
3160
- this.settings = t, t.language !== void 0 && yt(t.language, { reload: !1 }), this.syncScreenshotButton(), this.actionBar?.applySettings(t), this.cameraControls !== null && (this.cameraControls.element.style.display = t.cameraControls === !0 ? "flex" : "none"), this.placeScreenshotButton();
3362
+ applyViewerSettings(e) {
3363
+ this.settings = e, e.language !== void 0 && we(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();
3161
3364
  }
3162
- renderAttributeControls(t, e) {
3163
- if (!(this.container === null || this.slots.topRight === null || this.slots.bottomRight === null) && (this.cameraControls?.element.remove(), this.cameraControls = null, this.teardownConfigurator(), this.settings.cameraControls === !0 && (this.cameraControls = new z(this.options.cameraApi, this.options.cameraPositionApi), this.cameraControls.element.style.display = "none", this.slots.topRight.appendChild(this.cameraControls.element)), this.placeScreenshotButton(), e.length !== 0)) {
3365
+ renderAttributeControls(e, t) {
3366
+ if (!(this.container === null || this.slots.topRight === null || this.slots.bottomRight === null) && (this.cameraControls?.element.remove(), this.cameraControls = null, this.teardownConfigurator(), this.settings.cameraControls === !0 && (this.cameraControls = new z(
3367
+ this.options.cameraApi,
3368
+ this.options.cameraPositionApi
3369
+ ), this.cameraControls.element.style.display = "none", this.slots.topRight.appendChild(this.cameraControls.element)), this.placeScreenshotButton(), t.length !== 0)) {
3164
3370
  this.attributes = document.createElement("div"), this.attributes.className = "vd-attributes", this.groupHandles = /* @__PURE__ */ new Map();
3165
- for (const i of e) {
3166
- const o = Di(
3371
+ for (const i of t) {
3372
+ const s = ji(
3167
3373
  i,
3168
- t,
3374
+ e,
3169
3375
  this.options.eventBus,
3170
3376
  this.options.onSelect,
3377
+ this.options.onSelectTransient,
3171
3378
  this.options.onSubscribe
3172
3379
  );
3173
- this.groupHandles.set(i.name, o), this.attributes.appendChild(o.element);
3380
+ this.groupHandles.set(i.name, s), this.attributes.appendChild(s.element);
3174
3381
  }
3175
- this.commerce = new Vi(this.options.configuration), this.attributes.appendChild(this.commerce.element), this.layout = Wi(this.settings.configuratorLayout, this.slots.bottomRight), this.layout.attach(this.container, this.attributes), this.lastSelectable !== null && this.applySelectable(this.lastSelectable);
3382
+ this.commerce = new Zi(this.options.configuration), this.attributes.appendChild(this.commerce.element), this.layout = Ji(
3383
+ this.settings.configuratorLayout,
3384
+ this.slots.bottomRight
3385
+ ), this.layout.attach(this.container, this.attributes), this.lastSelectable !== null && this.applySelectable(this.lastSelectable);
3176
3386
  }
3177
3387
  }
3178
3388
  /**
@@ -3181,11 +3391,11 @@ class Xi {
3181
3391
  * does not name are unrestricted. The interface renders, it never knows
3182
3392
  * the exclusion rules (kiesbaarheid live, binding-studio task 17).
3183
3393
  */
3184
- applySelectable(t) {
3185
- this.lastSelectable = t;
3186
- for (const [e, i] of this.groupHandles) {
3187
- const o = t.find((s) => s.name === e);
3188
- i.setSelectable(o?.selectable ?? null);
3394
+ applySelectable(e) {
3395
+ this.lastSelectable = e;
3396
+ for (const [t, i] of this.groupHandles) {
3397
+ const s = e.find((o) => o.name === t);
3398
+ i.setSelectable(s?.selectable ?? null), i.setHidden(s?.hidden === !0);
3189
3399
  }
3190
3400
  }
3191
3401
  get viewerSettings() {
@@ -3197,126 +3407,141 @@ class Xi {
3197
3407
  }
3198
3408
  destroy() {
3199
3409
  this.loading?.destroy(), this.screenshotBtn?.element.remove(), this.actionBar?.destroy(), this.actionBar?.element.remove(), this.cameraControls?.element.remove(), this.teardownConfigurator();
3200
- for (const t of Object.values(this.slots))
3201
- t?.remove();
3410
+ for (const e of Object.values(this.slots))
3411
+ e?.remove();
3202
3412
  this.container = null;
3203
3413
  }
3204
- createSlot(t, e) {
3414
+ createSlot(e, t) {
3205
3415
  const i = document.createElement("div");
3206
- return i.className = e, t.appendChild(i), i;
3416
+ return i.className = t, e.appendChild(i), i;
3207
3417
  }
3208
3418
  syncScreenshotButton() {
3209
- const t = this.settings.screenshot === !0;
3210
- t && this.screenshotBtn === null && (this.screenshotBtn = new b({
3419
+ const e = this.settings.screenshot === !0;
3420
+ e && this.screenshotBtn === null && (this.screenshotBtn = new v({
3211
3421
  variant: "outline",
3212
3422
  size: "icon",
3213
3423
  label: hn(),
3214
- icon: g.screenshot(),
3424
+ icon: b.screenshot(),
3215
3425
  onClick: () => {
3216
- this.options.snapshotApi.take("snapshot.png").onDeveloped(({ data: e, filename: i }) => {
3217
- Ki(e, i);
3426
+ this.options.snapshotApi.take("snapshot.png").onDeveloped(({ data: t, filename: i }) => {
3427
+ ns(t, i);
3218
3428
  });
3219
3429
  }
3220
- })), !t && this.screenshotBtn !== null && (this.screenshotBtn.element.remove(), this.screenshotBtn = null);
3430
+ })), !e && this.screenshotBtn !== null && (this.screenshotBtn.element.remove(), this.screenshotBtn = null);
3221
3431
  }
3222
3432
  placeScreenshotButton() {
3223
3433
  this.screenshotBtn === null || this.slots.topRight === null || (this.cameraControls !== null ? this.cameraControls.element.appendChild(this.screenshotBtn.element) : this.slots.topRight.appendChild(this.screenshotBtn.element));
3224
3434
  }
3225
3435
  }
3226
- const Ji = {};
3227
- class to {
3436
+ const ss = {};
3437
+ class os {
3228
3438
  defaultServer = "https://server.virtualdisplay.io";
3229
3439
  options;
3230
3440
  serverHost;
3231
3441
  extraParams;
3232
- constructor(t, e, i) {
3233
- this.options = t, this.serverHost = e, this.extraParams = i;
3442
+ constructor(e, t, i) {
3443
+ this.options = e, this.serverHost = t, this.extraParams = i;
3234
3444
  }
3235
3445
  /**
3236
3446
  * Create container and iframe, attach to parent element
3237
3447
  */
3238
3448
  create() {
3239
- const t = this.createContainer(), e = this.createIframe();
3240
- return t.appendChild(e), this.attachToParent(t), { container: t, iframe: e };
3449
+ const e = this.createContainer(), t = this.createIframe();
3450
+ return e.appendChild(t), this.attachToParent(e), { container: e, iframe: t };
3241
3451
  }
3242
3452
  createContainer() {
3243
- const t = document.createElement("div");
3244
- return t.className = "vd-container", Object.assign(t.style, {
3453
+ const e = document.createElement("div");
3454
+ return e.className = "vd-container", Object.assign(e.style, {
3245
3455
  position: "relative",
3246
3456
  width: "100%",
3247
3457
  height: "100%",
3248
3458
  overflow: "hidden"
3249
- }), t;
3459
+ }), e;
3250
3460
  }
3251
3461
  createIframe() {
3252
- const t = document.createElement("iframe");
3253
- return t.src = this.buildUrl(), t.setAttribute("allow", "xr-spatial-tracking; fullscreen"), t;
3462
+ const e = document.createElement("iframe");
3463
+ return e.src = this.buildUrl(), e.setAttribute("allow", "xr-spatial-tracking; fullscreen"), e;
3254
3464
  }
3255
- attachToParent(t) {
3256
- this.getParentElement().appendChild(t);
3465
+ attachToParent(e) {
3466
+ this.getParentElement().appendChild(e);
3257
3467
  }
3258
3468
  buildUrl() {
3259
- const t = this.getServerUrl(), e = new URL(t);
3260
- e.searchParams.set("license", this.options.license), e.searchParams.set("model", this.options.model), this.options.language !== void 0 && e.searchParams.set("language", this.options.language), this.options.session !== void 0 && e.searchParams.set("session", this.options.session), this.options.debug === !0 && e.searchParams.set("debug", "true"), this.options.traceparent !== void 0 && e.searchParams.set("traceparent", this.options.traceparent);
3261
- for (const [i, o] of Object.entries(this.extraParams ?? {}))
3262
- e.searchParams.set(i, o);
3263
- return e.toString();
3469
+ const e = this.getServerUrl(), t = new URL(e);
3470
+ this.setAddressParams(t), this.options.language !== void 0 && t.searchParams.set("language", this.options.language), this.options.session !== void 0 && t.searchParams.set("session", this.options.session), this.options.debug === !0 && t.searchParams.set("debug", "true"), this.options.traceparent !== void 0 && t.searchParams.set("traceparent", this.options.traceparent);
3471
+ for (const [i, s] of Object.entries(this.extraParams ?? {}))
3472
+ t.searchParams.set(i, s);
3473
+ return t.toString();
3474
+ }
3475
+ /**
3476
+ * Put the address form on the URL. `app` names an app row; the
3477
+ * `license`/`model` pair resolves to the model's default app. When both are
3478
+ * given, `app` wins and the pair is ignored with a warning, so adding `app`
3479
+ * to an existing integration is additive rather than a swap.
3480
+ */
3481
+ setAddressParams(e) {
3482
+ if (this.options.app === void 0) {
3483
+ e.searchParams.set("license", this.options.license), e.searchParams.set("model", this.options.model);
3484
+ return;
3485
+ }
3486
+ e.searchParams.set("app", this.options.app), (this.options.license !== void 0 || this.options.model !== void 0) && C.warn("Both `app` and `license`/`model` were supplied: `app` wins, the pair was ignored");
3264
3487
  }
3265
3488
  getServerUrl() {
3266
3489
  if (this.serverHost !== void 0)
3267
3490
  return this.serverHost;
3268
- if (Ji?.VITE_VIRTUALDISPLAY_SERVER_HOST === void 0)
3491
+ if (ss?.VITE_VIRTUALDISPLAY_SERVER_HOST === void 0)
3269
3492
  return this.defaultServer;
3270
3493
  }
3271
3494
  getParentElement() {
3272
3495
  if (typeof this.options.parent != "string")
3273
3496
  return this.options.parent;
3274
- const t = document.querySelector(this.options.parent);
3275
- if (t === null)
3276
- throw f.parentNotFound(this.options.parent);
3277
- return t;
3497
+ const e = document.querySelector(this.options.parent);
3498
+ if (e === null)
3499
+ throw g.parentNotFound(this.options.parent);
3500
+ return e;
3278
3501
  }
3279
3502
  }
3280
- function eo(n) {
3281
- const { messenger: t } = n;
3282
- t.on(c.HANDSHAKE, (e) => {
3283
- Ot(e) && (_.info("Server handshake received, flushing publisher queue"), t.markReady());
3284
- }), t.on(c.SESSION, (e) => {
3285
- Nt(e) && n.onSession(e.sessionId);
3286
- }), t.on(c.MUTATION, (e) => {
3287
- Mt(e) && (n.attributes.handleMutationResult(e), n.configuration.handleSelectionChanged(n.attributes.getSelection()));
3288
- }), t.on(c.SNAPSHOT, (e) => {
3289
- zt(e) && n.snapshot.handleSnapshotResult(e);
3290
- }), t.on(c.CAMERA, (e) => {
3291
- Pt(e) && n.cameraPosition.handlePositionUpdate(e);
3292
- }), t.on(c.LOADING_INDICATOR, (e) => {
3293
- $t(e) && (e.error !== void 0 ? n.ui.showError(e.error) : n.ui.updateProgress(e.progress, e.phase));
3294
- }), t.on(c.CONFIG, (e) => {
3295
- Ut(e) && n.applyConfig(e);
3296
- }), t.on(c.MAPPING, (e) => {
3297
- Ft(e) && (n.attributes.handleMappingReceived(e), n.configuration.handleSelectionChanged(n.attributes.getSelection()), n.ui.renderAttributeControls(n.attributes, e.attributes), n.readyStateTracker.handleMappingReceived());
3298
- }), no(n);
3299
- }
3300
- function no(n) {
3301
- const { messenger: t } = n;
3302
- t.on(c.FOCUS, (e) => {
3303
- Vt(e) && n.focus.handleStateReceived(e);
3304
- }), t.on(c.PRICING, (e) => {
3305
- jt(e) && n.configuration.handlePricingReceived(e.pricing);
3306
- }), t.on(c.SYNC, (e) => {
3307
- Dt(e) && n.onSync(e.connected);
3308
- }), t.on(c.SELECTABLE, (e) => {
3309
- Bt(e) && (n.selectable.handleSnapshot(e), n.ui.applySelectable(e.attributes));
3503
+ function rs(n) {
3504
+ const { messenger: e } = n;
3505
+ e.on(c.HANDSHAKE, (t) => {
3506
+ Me(t) && (C.info("Server handshake received, flushing publisher queue"), e.markReady());
3507
+ }), e.on(c.SESSION, (t) => {
3508
+ ze(t) && n.onSession(t.sessionId);
3509
+ }), e.on(c.MUTATION, (t) => {
3510
+ Fe(t) && (n.attributes.handleMutationResult(t), n.configuration.handleSelectionChanged(n.attributes.getSelection()));
3511
+ }), e.on(c.SNAPSHOT, (t) => {
3512
+ De(t) && n.snapshot.handleSnapshotResult(t);
3513
+ }), e.on(c.CAMERA, (t) => {
3514
+ $e(t) && n.cameraPosition.handlePositionUpdate(t);
3515
+ }), e.on(c.LOADING_INDICATOR, (t) => {
3516
+ Be(t) && (t.error !== void 0 ? n.ui.showError(t.error) : n.ui.updateProgress(t.progress, t.phase));
3517
+ }), e.on(c.CONFIG, (t) => {
3518
+ He(t) && n.applyConfig(t);
3519
+ }), e.on(c.MAPPING, (t) => {
3520
+ Ue(t) && (n.attributes.handleMappingReceived(t), n.configuration.handleSelectionChanged(n.attributes.getSelection()), n.ui.renderAttributeControls(n.attributes, t.attributes), n.readyStateTracker.handleMappingReceived());
3521
+ }), as(n);
3522
+ }
3523
+ function as(n) {
3524
+ const { messenger: e } = n;
3525
+ e.on(c.FOCUS, (t) => {
3526
+ qe(t) && n.focus.handleStateReceived(t);
3527
+ }), e.on(c.PRICING, (t) => {
3528
+ Ge(t) && n.configuration.handlePricingReceived(t.pricing);
3529
+ }), e.on(c.SYNC, (t) => {
3530
+ Ve(t) && n.onSync(t.connected);
3531
+ }), e.on(c.SELECTABLE, (t) => {
3532
+ je(t) && (n.selectable.handleSnapshot(t), n.ui.applySelectable(t.attributes));
3533
+ }), e.on(c.APP_RESOLVED, (t) => {
3534
+ Pe(t) && n.onAppResolved(t);
3310
3535
  });
3311
3536
  }
3312
- class io {
3537
+ class ls {
3313
3538
  ready = !1;
3314
3539
  onReady;
3315
- constructor(t) {
3316
- this.onReady = t;
3540
+ constructor(e) {
3541
+ this.onReady = e;
3317
3542
  }
3318
3543
  handleMappingReceived() {
3319
- this.ready || (this.ready = !0, _.info("Mapping received from server, client is now ready"), this.onReady?.());
3544
+ this.ready || (this.ready = !0, C.info("Mapping received from server, client is now ready"), this.onReady?.());
3320
3545
  }
3321
3546
  get isReady() {
3322
3547
  return this.ready;
@@ -3325,7 +3550,13 @@ class io {
3325
3550
  this.ready = !1;
3326
3551
  }
3327
3552
  }
3328
- class oo {
3553
+ function cs(n) {
3554
+ if (n === void 0)
3555
+ return;
3556
+ const { annotations: e, ...t } = n;
3557
+ return e === void 0 ? t : e === !0 ? { ...t, annotations: "show" } : e === !1 ? { ...t, annotations: "hide" } : { ...t, annotations: e };
3558
+ }
3559
+ class us {
3329
3560
  attributes;
3330
3561
  selectableState;
3331
3562
  readyStateTracker;
@@ -3351,50 +3582,59 @@ class oo {
3351
3582
  mutationFailedCallbacks = [];
3352
3583
  /** The viewer's tracking session id, once the server announces it (SESSION). */
3353
3584
  viewerSessionId;
3354
- constructor(t, e) {
3355
- this.options = t;
3356
- const i = e ?? {};
3357
- this.serverHost = i.serverHost, this.iframeParams = i.iframeParams, this.initializeLogging(), this.messenger = new Ht(
3585
+ /** Which app the viewer resolved, once reported (APP_RESOLVED). */
3586
+ resolvedApp;
3587
+ appResolvedCallbacks = [];
3588
+ constructor(e, t) {
3589
+ this.options = e;
3590
+ const i = t ?? {};
3591
+ this.serverHost = i.serverHost, this.iframeParams = i.iframeParams, this.initializeLogging(), this.messenger = new Ze(
3358
3592
  () => this.iframe?.contentWindow ?? null,
3359
3593
  i.messengerOptions
3360
3594
  );
3361
- const o = (r) => {
3362
- this.messenger.send(r);
3595
+ const s = (o) => {
3596
+ this.messenger.send(o);
3363
3597
  };
3364
- this.attributes = new ue(o, (r, a) => {
3365
- this.notifyMutationFailed(r, a);
3366
- }), this.selectableState = new he(), this.snapshotApi = new we(o), this.annotationsApi = new qt(o), this.cameraApi = new me(o), this.cameraPositionApi = new pe(), this.focusApi = new ve(o, (r) => {
3367
- this.dispatchFocusChange(r);
3368
- }), this.configurationApi = new be(
3369
- (r) => {
3370
- this.dispatchConfigurationChange(r);
3598
+ this.attributes = new pt(s, F, (o, r) => {
3599
+ this.notifyMutationFailed(o, r);
3600
+ }), this.selectableState = new ft(), this.snapshotApi = new kt(s), this.annotationsApi = new We(s, F), this.cameraApi = new gt(s), this.cameraPositionApi = new bt(), this.focusApi = new wt(s, (o) => {
3601
+ this.dispatchFocusChange(o);
3602
+ }, F), this.configurationApi = new St(
3603
+ (o) => {
3604
+ this.dispatchConfigurationChange(o);
3371
3605
  },
3372
- (r) => {
3373
- this.dispatchConfigurationSubmit(r);
3606
+ (o) => {
3607
+ this.dispatchConfigurationSubmit(o);
3374
3608
  }
3375
- ), this.eventBus = new Se(), this.arActivation = i.createArActivation?.(o), this.syncTracker = i.createSyncTracker?.(), this.readyStateTracker = new io(() => {
3609
+ ), this.eventBus = new _t(), this.arActivation = i.createArActivation?.(s), this.syncTracker = i.createSyncTracker?.(), this.readyStateTracker = new ls(() => {
3376
3610
  this.notifyReady();
3377
- });
3378
- const s = this.arActivation;
3379
- this.ui = new Xi({
3611
+ }), this.ui = this.createStandardInterface(), this.wireIncomingMessages(), i.registerHandlers?.(this.messenger, s), this.messenger.start(), this.createAndConnectIframe();
3612
+ }
3613
+ /** The configurator UI, every callback bridging it to the facade that owns the action. */
3614
+ createStandardInterface() {
3615
+ const e = this.arActivation;
3616
+ return new is({
3380
3617
  snapshotApi: this.snapshotApi,
3381
3618
  cameraApi: this.cameraApi,
3382
3619
  cameraPositionApi: this.cameraPositionApi,
3383
3620
  eventBus: this.eventBus,
3384
3621
  configuration: this.configurationApi,
3385
- onSelect: (r, a) => this.attributes.select(r, a),
3386
- onSubscribe: (r, a) => this.attributes.onChange(r, a),
3387
- ...s !== void 0 && { onAr: () => {
3388
- s.activate();
3389
- } },
3622
+ onSelect: (t, i) => this.attributes.select(t, i),
3623
+ onSelectTransient: (t, i) => this.attributes.selectTransient(t, i),
3624
+ onSubscribe: (t, i) => this.attributes.onChange(t, i),
3625
+ ...e !== void 0 && {
3626
+ onAr: () => {
3627
+ e.activate();
3628
+ }
3629
+ },
3390
3630
  onFullscreenEnter: () => {
3391
3631
  this.trackFullscreen();
3392
3632
  }
3393
- }), this.wireIncomingMessages(), i.registerHandlers?.(this.messenger, o), this.messenger.start(), this.createAndConnectIframe();
3633
+ });
3394
3634
  }
3395
3635
  /** Wire the inbound viewer protocol to the facades. */
3396
3636
  wireIncomingMessages() {
3397
- eo({
3637
+ rs({
3398
3638
  messenger: this.messenger,
3399
3639
  attributes: this.attributes,
3400
3640
  selectable: this.selectableState,
@@ -3404,113 +3644,141 @@ class oo {
3404
3644
  focus: this.focusApi,
3405
3645
  ui: this.ui,
3406
3646
  readyStateTracker: this.readyStateTracker,
3407
- applyConfig: (t) => {
3408
- this.handleConfig(t);
3647
+ applyConfig: (e) => {
3648
+ this.handleConfig(e);
3649
+ },
3650
+ onSession: (e) => {
3651
+ this.handleSession(e);
3409
3652
  },
3410
- onSession: (t) => {
3411
- this.handleSession(t);
3653
+ onSync: (e) => {
3654
+ this.syncTracker?.handleSync(e);
3412
3655
  },
3413
- onSync: (t) => {
3414
- this.syncTracker?.handleSync(t);
3656
+ onAppResolved: (e) => {
3657
+ this.handleAppResolved({
3658
+ appType: e.appType,
3659
+ name: e.name,
3660
+ ...e.slug !== void 0 && { slug: e.slug },
3661
+ ...e.submit !== void 0 && { submit: e.submit }
3662
+ });
3415
3663
  }
3416
3664
  });
3417
3665
  }
3666
+ /** Store the resolved app and notify every registered `onAppResolved` callback. */
3667
+ handleAppResolved(e) {
3668
+ this.resolvedApp = e;
3669
+ for (const t of this.appResolvedCallbacks)
3670
+ t(e);
3671
+ }
3418
3672
  /** Store the tracking session id and hand it to the AR flow, which waits on it for the QR. */
3419
- handleSession(t) {
3420
- this.viewerSessionId = t, this.arActivation?.onSession(t);
3673
+ handleSession(e) {
3674
+ this.viewerSessionId = e, this.arActivation?.onSession(e);
3421
3675
  }
3422
3676
  /** Forward a failed mutation to every registered `onMutationFailed` callback. */
3423
- notifyMutationFailed(t, e) {
3677
+ notifyMutationFailed(e, t) {
3424
3678
  for (const i of this.mutationFailedCallbacks)
3425
- i({ attribute: t, value: e });
3679
+ i({ attribute: e, value: t });
3426
3680
  }
3427
3681
  /** Flush the queued `onReady` callbacks once, then let the standard interface know. */
3428
3682
  notifyReady() {
3429
- const t = this.readyCallbacks;
3683
+ const e = this.readyCallbacks;
3430
3684
  this.readyCallbacks = [];
3431
- for (const e of t)
3432
- e(this);
3685
+ for (const t of e)
3686
+ t(this);
3433
3687
  this.ui.onReady();
3434
3688
  }
3435
3689
  /**
3436
3690
  * Dispatch a bubbling `vd:focus-change` event on the container so a page can
3437
3691
  * react to focus without registering an `onChange` callback.
3438
3692
  */
3439
- dispatchFocusChange(t) {
3693
+ dispatchFocusChange(e) {
3440
3694
  this.container?.dispatchEvent(
3441
- new CustomEvent(L.FOCUS_CHANGE, { detail: t, bubbles: !0 })
3695
+ new CustomEvent(T.FOCUS_CHANGE, { detail: e, bubbles: !0 })
3442
3696
  );
3443
3697
  }
3444
3698
  /**
3445
3699
  * Dispatch a bubbling `vd:configuration-change` event on the container so a
3446
3700
  * page or tag manager can react to price changes without a client callback.
3447
3701
  */
3448
- dispatchConfigurationChange(t) {
3702
+ dispatchConfigurationChange(e) {
3449
3703
  this.container?.dispatchEvent(
3450
- new CustomEvent(L.CONFIGURATION_CHANGE, { detail: t ?? null, bubbles: !0 })
3704
+ new CustomEvent(T.CONFIGURATION_CHANGE, { detail: e ?? null, bubbles: !0 })
3451
3705
  );
3452
3706
  }
3453
3707
  /** Dispatch a bubbling `vd:configuration-submit` event when the CTA is used. */
3454
- dispatchConfigurationSubmit(t) {
3708
+ dispatchConfigurationSubmit(e) {
3455
3709
  this.container?.dispatchEvent(
3456
- new CustomEvent(L.CONFIGURATION_SUBMIT, { detail: t, bubbles: !0 })
3710
+ new CustomEvent(T.CONFIGURATION_SUBMIT, { detail: e, bubbles: !0 })
3457
3711
  );
3458
3712
  }
3459
- handleConfig(t) {
3460
- const e = t.viewerSettings, i = this.options.viewerSettings;
3461
- if (e !== void 0 || i !== void 0) {
3462
- const o = i !== void 0 ? { ...e ?? {}, ...i } : e;
3463
- if (i !== void 0 && e !== void 0) {
3464
- const s = Object.entries(i).filter(([r, a]) => e[r] !== a).map(([r, a]) => `${r} (metadata: ${e[r] ?? "undefined"}, override: ${a})`);
3465
- s.length > 0 && _.warn(`Viewer settings override active: ${s.join(", ")}`);
3713
+ handleConfig(e) {
3714
+ const t = e.viewerSettings, i = cs(this.options.viewerSettings);
3715
+ if (t !== void 0 || i !== void 0) {
3716
+ const s = i !== void 0 ? { ...t ?? {}, ...i } : t;
3717
+ if (i !== void 0 && t !== void 0) {
3718
+ const o = Object.entries(i).filter(([r, a]) => t[r] !== a).map(
3719
+ ([r, a]) => `${r} (metadata: ${t[r] ?? "undefined"}, override: ${a})`
3720
+ );
3721
+ o.length > 0 && C.warn(`Viewer settings override active: ${o.join(", ")}`);
3466
3722
  }
3467
- this.ui.applyViewerSettings(o), this.annotationsApi.setEnabled(o.annotations !== !1);
3723
+ this.ui.applyViewerSettings(s), this.echoAnnotationsDifference(t?.annotations, s.annotations);
3468
3724
  }
3469
- this.cameraPositionApi.applyLimits(t.cameraLimits);
3725
+ this.cameraPositionApi.applyLimits(e.cameraLimits);
3726
+ }
3727
+ /**
3728
+ * The difference echo: the viewer already applied the app-config mode
3729
+ * itself, so the client only speaks up when the merged mode (config plus
3730
+ * integrator override) differs from what CONFIG announced, in either
3731
+ * direction. Equal modes echo nothing, so a boot without overrides sends
3732
+ * no toggle at all.
3733
+ */
3734
+ echoAnnotationsDifference(e, t) {
3735
+ t === void 0 || t === e || this.annotationsApi.setEnabled(t === "show" || t === "toggle-shown");
3470
3736
  }
3471
3737
  /** Tell the viewer the user entered fullscreen, so it records the engagement. */
3472
3738
  trackFullscreen() {
3473
3739
  this.messenger.send({ type: c.FULLSCREEN });
3474
3740
  }
3475
3741
  initializeLogging() {
3476
- this.options.debug === !0 && de(), _.info("Initializing Virtualdisplay client", { model: this.options.model });
3742
+ this.options.debug === !0 && mt(), C.info("Initializing Virtualdisplay client", {
3743
+ ...this.options.app === void 0 ? { model: this.options.model } : { app: this.options.app }
3744
+ });
3477
3745
  }
3478
3746
  createAndConnectIframe() {
3479
- const e = new to(this.options, this.serverHost, this.iframeParams).create();
3480
- this.container = e.container, this.iframe = e.iframe, this.eventBus.attach(this.container), this.ui.attach(this.container);
3747
+ const t = new os(this.options, this.serverHost, this.iframeParams).create();
3748
+ this.container = t.container, this.iframe = t.iframe, this.eventBus.attach(this.container), this.ui.attach(this.container);
3481
3749
  try {
3482
3750
  const i = new URL(this.iframe.src).origin;
3483
3751
  this.messenger.setTargetOrigin(i);
3484
3752
  } catch {
3485
3753
  }
3486
3754
  }
3487
- select(t, e) {
3488
- this.attributes.select(t, e);
3755
+ select(e, t) {
3756
+ this.attributes.select(e, t);
3489
3757
  }
3490
- getValues(t) {
3491
- return this.attributes.getValues(t);
3758
+ getValues(e) {
3759
+ return this.attributes.getValues(e);
3492
3760
  }
3493
- getValue(t, e) {
3494
- return this.attributes.getValue(t, e);
3761
+ getValue(e, t) {
3762
+ return this.attributes.getValue(e, t);
3495
3763
  }
3496
- onChange(t, e) {
3497
- this.attributes.onChange(t, e);
3764
+ onChange(e, t) {
3765
+ this.attributes.onChange(e, t);
3498
3766
  }
3499
- getAttribute(t) {
3500
- return this.attributes.getAttribute(t);
3767
+ getAttribute(e) {
3768
+ return this.attributes.getAttribute(e);
3501
3769
  }
3502
3770
  get isReady() {
3503
3771
  return this.readyStateTracker.isReady;
3504
3772
  }
3505
- onReady(t) {
3773
+ onReady(e) {
3506
3774
  if (this.readyStateTracker.isReady) {
3507
- t(this);
3775
+ e(this);
3508
3776
  return;
3509
3777
  }
3510
- this.readyCallbacks.push(t);
3778
+ this.readyCallbacks.push(e);
3511
3779
  }
3512
- onMutationFailed(t) {
3513
- this.mutationFailedCallbacks.push(t);
3780
+ onMutationFailed(e) {
3781
+ this.mutationFailedCallbacks.push(e);
3514
3782
  }
3515
3783
  /**
3516
3784
  * Subscribe to the viewer's selectability snapshots (kiesbaarheid live):
@@ -3519,12 +3787,20 @@ class oo {
3519
3787
  * exclusions never sends one: everything stays selectable and this never
3520
3788
  * fires.
3521
3789
  */
3522
- onSelectableChange(t) {
3523
- this.selectableState.onChange(t);
3790
+ onSelectableChange(e) {
3791
+ this.selectableState.onChange(e);
3792
+ }
3793
+ /**
3794
+ * Subscribe to which app this viewer resolved (type, name, public submit
3795
+ * settings). Reported once by the viewer after its resolve; fires immediately
3796
+ * when the report already arrived, so registration order does not matter.
3797
+ */
3798
+ onAppResolved(e) {
3799
+ this.appResolvedCallbacks.push(e), this.resolvedApp !== void 0 && e(this.resolvedApp);
3524
3800
  }
3525
3801
  /** The selectable values for one attribute right now, or null when unrestricted. */
3526
- getSelectable(t) {
3527
- return this.selectableState.selectableFor(t);
3802
+ getSelectable(e) {
3803
+ return this.selectableState.selectableFor(e);
3528
3804
  }
3529
3805
  /**
3530
3806
  * Trigger the composed AR flow directly (ar-session-handoff task 035): a host
@@ -3536,8 +3812,8 @@ class oo {
3536
3812
  activateAr() {
3537
3813
  this.arActivation?.activate();
3538
3814
  }
3539
- on(t, e) {
3540
- this.eventBus.on(t, e);
3815
+ on(e, t) {
3816
+ this.eventBus.on(e, t);
3541
3817
  }
3542
3818
  get annotations() {
3543
3819
  return this.annotationsApi;
@@ -3568,15 +3844,15 @@ class oo {
3568
3844
  this.readyStateTracker.clear(), this.readyCallbacks = [], this.mutationFailedCallbacks.length = 0, this.snapshotApi.clear(), this.messenger.destroy(), this.arActivation?.destroy(), this.ui.destroy(), this.container?.parentElement !== null && this.container?.parentElement !== void 0 && this.container.parentElement.removeChild(this.container), this.container = void 0, this.iframe = void 0;
3569
3845
  }
3570
3846
  }
3571
- const so = "ar.virtualdisplay.io";
3572
- function ro(n) {
3573
- const t = new URL(`https://${so}/go`);
3574
- return n.sessionId !== void 0 ? t.searchParams.set("session", n.sessionId) : (t.searchParams.set("license", n.license), t.searchParams.set("model", n.model)), t.toString();
3847
+ const ds = "ar.virtualdisplay.io";
3848
+ function hs(n) {
3849
+ const e = new URL(`https://${ds}/go`);
3850
+ return n.sessionId !== void 0 ? e.searchParams.set("session", n.sessionId) : n.app !== void 0 ? e.searchParams.set("app", n.app) : n.license !== void 0 && n.model !== void 0 && (e.searchParams.set("license", n.license), e.searchParams.set("model", n.model)), e.toString();
3575
3851
  }
3576
- const ao = 1500;
3577
- class lo {
3852
+ const ms = 1500;
3853
+ class ps {
3578
3854
  options;
3579
- qrModal = new xi();
3855
+ qrModal = new Ti();
3580
3856
  /** The viewer's tracking session id, once the engine announces it (SESSION). */
3581
3857
  sessionId;
3582
3858
  /** Callbacks waiting on the SESSION message, resolved (or timed out) exactly once each. */
@@ -3585,20 +3861,20 @@ class lo {
3585
3861
  pendingTimers = /* @__PURE__ */ new Set();
3586
3862
  /** Set on destroy: an in-flight hand-off must not re-mount the modal or send QR_SHOWN. */
3587
3863
  destroyed = !1;
3588
- constructor(t) {
3589
- this.options = t;
3864
+ constructor(e) {
3865
+ this.options = e;
3590
3866
  }
3591
3867
  /** Store the engine-announced tracking session id and resolve anyone waiting on it. */
3592
- onSession(t) {
3593
- this.sessionId = t;
3594
- const e = this.waiters;
3868
+ onSession(e) {
3869
+ this.sessionId = e;
3870
+ const t = this.waiters;
3595
3871
  this.waiters = [];
3596
- for (const i of e)
3597
- i(t);
3872
+ for (const i of t)
3873
+ i(e);
3598
3874
  }
3599
3875
  /** The AR button handler: mobile activates AR in the engine, desktop shows the hand-off QR. */
3600
3876
  activate() {
3601
- if (le()) {
3877
+ if (dt()) {
3602
3878
  this.options.send({ type: c.AR_ACTIVATE });
3603
3879
  return;
3604
3880
  }
@@ -3606,8 +3882,8 @@ class lo {
3606
3882
  }
3607
3883
  destroy() {
3608
3884
  this.destroyed = !0;
3609
- for (const t of this.pendingTimers)
3610
- clearTimeout(t);
3885
+ for (const e of this.pendingTimers)
3886
+ clearTimeout(e);
3611
3887
  this.pendingTimers.clear(), this.waiters = [], this.qrModal.hide();
3612
3888
  }
3613
3889
  /**
@@ -3619,14 +3895,15 @@ class lo {
3619
3895
  */
3620
3896
  async showQrCode() {
3621
3897
  this.qrModal.show();
3622
- const t = await this.waitForSessionId();
3898
+ const e = await this.waitForSessionId();
3623
3899
  if (this.destroyed)
3624
3900
  return;
3625
- const e = ro({
3626
- sessionId: t,
3901
+ const t = hs({
3902
+ sessionId: e,
3903
+ app: this.options.app,
3627
3904
  license: this.options.license,
3628
3905
  model: this.options.model
3629
- }), i = await this.qrModal.update(e);
3906
+ }), i = await this.qrModal.update(t);
3630
3907
  if (this.destroyed) {
3631
3908
  this.qrModal.hide();
3632
3909
  return;
@@ -3640,60 +3917,61 @@ class lo {
3640
3917
  * rather than encoding a wrong one.
3641
3918
  */
3642
3919
  waitForSessionId() {
3643
- return this.sessionId !== void 0 ? Promise.resolve(this.sessionId) : new Promise((t) => {
3644
- const e = setTimeout(() => {
3645
- this.pendingTimers.delete(e), t(void 0);
3646
- }, ao);
3647
- this.pendingTimers.add(e), this.waiters.push((i) => {
3648
- this.pendingTimers.delete(e), clearTimeout(e), t(i);
3920
+ return this.sessionId !== void 0 ? Promise.resolve(this.sessionId) : new Promise((e) => {
3921
+ const t = setTimeout(() => {
3922
+ this.pendingTimers.delete(t), e(void 0);
3923
+ }, ms);
3924
+ this.pendingTimers.add(t), this.waiters.push((i) => {
3925
+ this.pendingTimers.delete(t), clearTimeout(t), e(i);
3649
3926
  });
3650
3927
  });
3651
3928
  }
3652
3929
  }
3653
- class co {
3930
+ class fs {
3654
3931
  callbacks = [];
3655
3932
  lastKnown;
3656
- handleSync(t) {
3657
- this.lastKnown = t;
3658
- for (const e of this.callbacks)
3659
- e(t);
3933
+ handleSync(e) {
3934
+ this.lastKnown = e;
3935
+ for (const t of this.callbacks)
3936
+ t(e);
3660
3937
  }
3661
- onChange(t) {
3662
- this.callbacks.push(t), this.lastKnown !== void 0 && t(this.lastKnown);
3938
+ onChange(e) {
3939
+ this.callbacks.push(e), this.lastKnown !== void 0 && e(this.lastKnown);
3663
3940
  }
3664
3941
  }
3665
- class mo extends oo {
3942
+ class vs extends us {
3666
3943
  syncStatusTracker;
3667
- constructor(t) {
3668
- const e = new co();
3669
- super(t, {
3670
- createArActivation: (i) => new lo({
3671
- license: t.license,
3672
- model: t.model,
3944
+ constructor(e) {
3945
+ const t = new fs();
3946
+ super(e, {
3947
+ createArActivation: (i) => new ps({
3948
+ app: e.app,
3949
+ license: e.license,
3950
+ model: e.model,
3673
3951
  send: i
3674
3952
  }),
3675
- createSyncTracker: () => e
3676
- }), this.syncStatusTracker = e;
3953
+ createSyncTracker: () => t
3954
+ }), this.syncStatusTracker = t;
3677
3955
  }
3678
3956
  /** Subscribe to the live sync channel's connection state (ar-session-handoff). Latest-wins, no buffering. */
3679
- onSyncChange(t) {
3680
- this.syncStatusTracker.onChange(t);
3957
+ onSyncChange(e) {
3958
+ this.syncStatusTracker.onChange(e);
3681
3959
  }
3682
3960
  }
3683
3961
  export {
3684
- qt as Annotations,
3685
- Zt as Attribute,
3686
- Gt as AttributeValue,
3687
- me as Camera,
3688
- be as Configuration,
3962
+ We as Annotations,
3963
+ Qe as Attribute,
3964
+ Ye as AttributeValue,
3965
+ gt as Camera,
3966
+ St as Configuration,
3689
3967
  A as ERROR_CODES,
3690
- ve as Focus,
3691
- ye as Photo,
3692
- we as Snapshot,
3693
- L as VD_EVENTS,
3694
- mo as VirtualdisplayClient,
3695
- f as VirtualdisplayError,
3696
- de as enableDebugMode,
3697
- uo as isDebugMode,
3698
- _ as logger
3968
+ wt as Focus,
3969
+ Ct as Photo,
3970
+ kt as Snapshot,
3971
+ T as VD_EVENTS,
3972
+ vs as VirtualdisplayClient,
3973
+ g as VirtualdisplayError,
3974
+ mt as enableDebugMode,
3975
+ gs as isDebugMode,
3976
+ C as logger
3699
3977
  };