@virtualdisplay.io/client 4.0.0-alpha.19 → 4.0.0-alpha.20
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.
- package/CHANGELOG.md +6 -0
- package/README.md +1 -22
- package/dist/index.d.ts +453 -543
- package/dist/virtualdisplay.client.cjs.js +12 -12
- package/dist/virtualdisplay.client.es.js +1988 -2007
- package/dist/virtualdisplay.client.umd.js +21 -21
- package/package.json +1 -1
|
@@ -1,530 +1,174 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const St = {};
|
|
31
|
-
class At {
|
|
32
|
-
defaultServer = "https://server.virtualdisplay.io";
|
|
33
|
-
options;
|
|
34
|
-
constructor(t) {
|
|
35
|
-
this.options = t;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* Create container and iframe, attach to parent element
|
|
39
|
-
*/
|
|
40
|
-
create() {
|
|
41
|
-
const t = this.createContainer(), e = this.createIframe();
|
|
42
|
-
return t.appendChild(e), this.attachToParent(t), { container: t, iframe: e };
|
|
43
|
-
}
|
|
44
|
-
createContainer() {
|
|
45
|
-
const t = document.createElement("div");
|
|
46
|
-
return t.className = "vd-container", Object.assign(t.style, {
|
|
47
|
-
position: "relative",
|
|
48
|
-
width: "100%",
|
|
49
|
-
height: "100%",
|
|
50
|
-
overflow: "hidden"
|
|
51
|
-
}), t;
|
|
52
|
-
}
|
|
53
|
-
createIframe() {
|
|
54
|
-
const t = document.createElement("iframe");
|
|
55
|
-
return t.src = this.buildUrl(), Object.assign(t.style, {
|
|
56
|
-
width: "100%",
|
|
57
|
-
height: "100%",
|
|
58
|
-
border: "none",
|
|
59
|
-
display: "block"
|
|
60
|
-
}), t.setAttribute("allow", "xr-spatial-tracking; fullscreen"), t;
|
|
61
|
-
}
|
|
62
|
-
attachToParent(t) {
|
|
63
|
-
this.getParentElement().appendChild(t);
|
|
64
|
-
}
|
|
65
|
-
buildUrl() {
|
|
66
|
-
const t = this.getServerUrl(), e = new URL(t);
|
|
67
|
-
return 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.debug === !0 && e.searchParams.set("debug", "true"), this.options.traceparent !== void 0 && e.searchParams.set("traceparent", this.options.traceparent), e.toString();
|
|
68
|
-
}
|
|
69
|
-
getServerUrl() {
|
|
70
|
-
if (St?.VITE_VIRTUALDISPLAY_SERVER_HOST === void 0)
|
|
71
|
-
return this.defaultServer;
|
|
72
|
-
}
|
|
73
|
-
getParentElement() {
|
|
74
|
-
if (typeof this.options.parent != "string")
|
|
75
|
-
return this.options.parent;
|
|
76
|
-
const t = document.querySelector(this.options.parent);
|
|
77
|
-
if (t === null)
|
|
78
|
-
throw f.parentNotFound(this.options.parent);
|
|
79
|
-
return t;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
function Et(n) {
|
|
83
|
-
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 = ["timestamp", "level", "msg", "service", "trace_id", "span_id"], r = Object.entries(n).filter(([l]) => !s.includes(l)).map(([l, d]) => `${l}=${JSON.stringify(d)}`).join(" ");
|
|
84
|
-
return `${t} ${e} [${i}] ${o}${r ? " " + r : ""}`;
|
|
1
|
+
const c = {
|
|
2
|
+
HANDSHAKE: "handshake",
|
|
3
|
+
SESSION: "session",
|
|
4
|
+
MUTATION: "mutation",
|
|
5
|
+
STATE: "state",
|
|
6
|
+
LOADING_INDICATOR: "loading_indicator",
|
|
7
|
+
CAMERA: "camera",
|
|
8
|
+
SNAPSHOT: "snapshot",
|
|
9
|
+
MAPPING: "mapping",
|
|
10
|
+
AR_ACTIVATE: "ar_activate",
|
|
11
|
+
FULLSCREEN: "fullscreen",
|
|
12
|
+
CONFIG: "config",
|
|
13
|
+
ANNOTATION_TOGGLE: "annotation_toggle",
|
|
14
|
+
FOCUS: "focus",
|
|
15
|
+
PRICING: "pricing"
|
|
16
|
+
}, Y = {
|
|
17
|
+
FOCUS: "focus",
|
|
18
|
+
UNFOCUS: "unfocus"
|
|
19
|
+
}, kt = {
|
|
20
|
+
FOCUSED: "focused"
|
|
21
|
+
}, St = {
|
|
22
|
+
/** Behaves exactly like an unpriced combination: no price, no button. */
|
|
23
|
+
HIDDEN: "hidden"
|
|
24
|
+
}, Et = new Set(Object.values(c));
|
|
25
|
+
function At(n) {
|
|
26
|
+
if (typeof n != "object" || n === null)
|
|
27
|
+
return !1;
|
|
28
|
+
const t = n;
|
|
29
|
+
return typeof t.target == "string" ? !1 : typeof t.type == "string" && Et.has(t.type);
|
|
85
30
|
}
|
|
86
31
|
function xt(n) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
function Tt(n, t) {
|
|
90
|
-
const e = t ? Et(n) : xt(n);
|
|
91
|
-
n.level === "error" ? console.error(e) : n.level === "warn" ? console.warn(e) : console.log(e);
|
|
32
|
+
const t = k(n);
|
|
33
|
+
return t !== null && t.type === c.HANDSHAKE;
|
|
92
34
|
}
|
|
93
|
-
function
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
message: n.message
|
|
97
|
-
};
|
|
98
|
-
n.stack !== void 0 && (e.stack = n.stack);
|
|
99
|
-
for (const i of Object.getOwnPropertyNames(n)) {
|
|
100
|
-
if (i === "name" || i === "message" || i === "stack" || i === "cause")
|
|
101
|
-
continue;
|
|
102
|
-
const o = n[i];
|
|
103
|
-
o !== void 0 && (e[i] = o);
|
|
104
|
-
}
|
|
105
|
-
return n.cause !== void 0 && n.cause !== null && (e.cause = n.cause instanceof Error && t < 5 ? ct(n.cause, t + 1) : String(n.cause)), e;
|
|
35
|
+
function Tt(n) {
|
|
36
|
+
const t = k(n);
|
|
37
|
+
return t !== null && t.type === c.SESSION && typeof t.sessionId == "string";
|
|
106
38
|
}
|
|
107
39
|
function Rt(n) {
|
|
108
|
-
const t =
|
|
109
|
-
|
|
110
|
-
t[e] = i instanceof Error ? ct(i) : i;
|
|
111
|
-
return t;
|
|
40
|
+
const t = k(n);
|
|
41
|
+
return t !== null && t.type === c.MUTATION && Array.isArray(t.results);
|
|
112
42
|
}
|
|
113
|
-
function
|
|
114
|
-
|
|
43
|
+
function It(n) {
|
|
44
|
+
const t = k(n);
|
|
45
|
+
return t !== null && t.type === c.SNAPSHOT && ("data" in t || "error" in t);
|
|
46
|
+
}
|
|
47
|
+
function Ot(n) {
|
|
48
|
+
const t = k(n);
|
|
49
|
+
return t !== null && t.type === c.CAMERA && Array.isArray(t.transforms);
|
|
115
50
|
}
|
|
116
51
|
function Nt(n) {
|
|
117
|
-
|
|
52
|
+
const t = k(n);
|
|
53
|
+
return t !== null && t.type === c.MAPPING && Array.isArray(t.attributes);
|
|
118
54
|
}
|
|
119
|
-
function
|
|
120
|
-
|
|
55
|
+
function Lt(n) {
|
|
56
|
+
const t = k(n);
|
|
57
|
+
return t !== null && t.type === c.LOADING_INDICATOR && typeof t.progress == "number";
|
|
121
58
|
}
|
|
122
|
-
function
|
|
123
|
-
|
|
59
|
+
function Mt(n) {
|
|
60
|
+
const t = k(n);
|
|
61
|
+
return t !== null && t.type === c.CONFIG && typeof t.viewerSettings == "object";
|
|
124
62
|
}
|
|
125
|
-
function
|
|
126
|
-
|
|
63
|
+
function zt(n) {
|
|
64
|
+
const t = k(n);
|
|
65
|
+
return t !== null && t.type === c.FOCUS && typeof t.state == "string";
|
|
127
66
|
}
|
|
128
|
-
function
|
|
129
|
-
|
|
67
|
+
function Ft(n) {
|
|
68
|
+
const t = k(n);
|
|
69
|
+
return t !== null && t.type === c.PRICING && typeof t.pricing == "object" && t.pricing !== null;
|
|
130
70
|
}
|
|
131
|
-
function
|
|
132
|
-
return
|
|
71
|
+
function k(n) {
|
|
72
|
+
return typeof n != "object" || n === null ? null : n;
|
|
133
73
|
}
|
|
134
|
-
class
|
|
74
|
+
class X {
|
|
135
75
|
constructor(t) {
|
|
136
|
-
this.
|
|
76
|
+
this.processor = t;
|
|
137
77
|
}
|
|
138
|
-
|
|
78
|
+
processor;
|
|
79
|
+
pending = [];
|
|
80
|
+
isReady = !1;
|
|
139
81
|
/**
|
|
140
|
-
*
|
|
82
|
+
* Add a message — processed immediately if ready, queued otherwise
|
|
141
83
|
*/
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
...o,
|
|
149
|
-
...Rt(i)
|
|
150
|
-
};
|
|
151
|
-
Tt(s, this.config.isDev);
|
|
84
|
+
enqueue(t) {
|
|
85
|
+
if (this.isReady) {
|
|
86
|
+
this.processor(t);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
this.pending.push(t);
|
|
152
90
|
}
|
|
153
91
|
/**
|
|
154
|
-
*
|
|
92
|
+
* Mark as ready and flush all pending messages
|
|
155
93
|
*/
|
|
156
|
-
|
|
157
|
-
this.
|
|
94
|
+
markReady() {
|
|
95
|
+
if (this.isReady || (this.isReady = !0, this.pending.length === 0))
|
|
96
|
+
return;
|
|
97
|
+
const t = [...this.pending];
|
|
98
|
+
this.pending.length = 0;
|
|
99
|
+
for (const e of t)
|
|
100
|
+
this.processor(e);
|
|
101
|
+
}
|
|
102
|
+
get ready() {
|
|
103
|
+
return this.isReady;
|
|
104
|
+
}
|
|
105
|
+
get pendingCount() {
|
|
106
|
+
return this.pending.length;
|
|
158
107
|
}
|
|
159
108
|
/**
|
|
160
|
-
*
|
|
109
|
+
* Check if a message of a specific type is pending
|
|
161
110
|
*/
|
|
162
|
-
|
|
163
|
-
this.
|
|
111
|
+
hasPending(t) {
|
|
112
|
+
return this.pending.some((e) => e.type === t);
|
|
164
113
|
}
|
|
165
114
|
/**
|
|
166
|
-
*
|
|
115
|
+
* Clear all pending messages
|
|
167
116
|
*/
|
|
168
|
-
|
|
169
|
-
this.
|
|
117
|
+
clear() {
|
|
118
|
+
this.pending.length = 0;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
class Pt {
|
|
122
|
+
constructor(t, e) {
|
|
123
|
+
this.getTarget = t, this.sourceId = `vd-${Math.random().toString(36).slice(2, 8)}`, this.targetOrigin = e?.targetOrigin ?? "*", this.isValid = e?.isValid ?? At, this.publisher = new X((i) => this.post(i)), this.consumer = new X((i) => this.routeToHandler(i)), this.shouldBuffer = e?.shouldBuffer ?? null, e?.bufferIncoming !== !0 && this.consumer.markReady();
|
|
170
124
|
}
|
|
125
|
+
getTarget;
|
|
126
|
+
handlers = /* @__PURE__ */ new Map();
|
|
127
|
+
publisher;
|
|
128
|
+
consumer;
|
|
129
|
+
shouldBuffer;
|
|
130
|
+
listener = null;
|
|
131
|
+
sourceId;
|
|
132
|
+
targetOrigin;
|
|
133
|
+
isValid;
|
|
171
134
|
/**
|
|
172
|
-
*
|
|
135
|
+
* Register a handler for a specific message type
|
|
173
136
|
*/
|
|
174
|
-
|
|
175
|
-
this.
|
|
137
|
+
on(t, e) {
|
|
138
|
+
this.handlers.set(t, e);
|
|
176
139
|
}
|
|
177
140
|
/**
|
|
178
|
-
*
|
|
141
|
+
* Remove a handler for a specific message type
|
|
179
142
|
*/
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
return e.log = ((i, o, s = {}) => {
|
|
183
|
-
this.log(i, o, { ...t, ...s });
|
|
184
|
-
}).bind(this), e;
|
|
143
|
+
off(t) {
|
|
144
|
+
this.handlers.delete(t);
|
|
185
145
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
if (n !== void 0)
|
|
193
|
-
return typeof n == "object" && n !== null && !Array.isArray(n) && !(n instanceof Error) ? n : n instanceof Error ? { error: n.message } : { value: n };
|
|
194
|
-
}
|
|
195
|
-
function ht(n) {
|
|
196
|
-
return {
|
|
197
|
-
debug: (t, e) => n.debug(t, N(e)),
|
|
198
|
-
info: (t, e) => n.info(t, N(e)),
|
|
199
|
-
warn: (t, e) => n.warn(t, N(e)),
|
|
200
|
-
error: (t, e) => n.error(t, N(e))
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
let mt = !1, C = ht(dt("client", { isDev: !1 }));
|
|
204
|
-
function Pt() {
|
|
205
|
-
mt = !0, C = ht(dt("client", { isDev: !0 }));
|
|
206
|
-
}
|
|
207
|
-
function ji() {
|
|
208
|
-
return mt;
|
|
209
|
-
}
|
|
210
|
-
class Ft {
|
|
211
|
-
ready = !1;
|
|
212
|
-
onReady;
|
|
213
|
-
constructor(t) {
|
|
214
|
-
this.onReady = t;
|
|
146
|
+
/**
|
|
147
|
+
* Update the target origin for outgoing postMessage calls.
|
|
148
|
+
* Use when the target origin is discovered at runtime (e.g. from the first incoming message).
|
|
149
|
+
*/
|
|
150
|
+
setTargetOrigin(t) {
|
|
151
|
+
this.targetOrigin = t;
|
|
215
152
|
}
|
|
216
|
-
|
|
217
|
-
|
|
153
|
+
/**
|
|
154
|
+
* Send a message to the target window
|
|
155
|
+
* Queued until markReady() is called
|
|
156
|
+
*/
|
|
157
|
+
send(t) {
|
|
158
|
+
this.publisher.enqueue(t);
|
|
218
159
|
}
|
|
219
|
-
|
|
220
|
-
|
|
160
|
+
/**
|
|
161
|
+
* Enable sending and flush queued outgoing messages
|
|
162
|
+
*/
|
|
163
|
+
markReady() {
|
|
164
|
+
this.publisher.markReady();
|
|
221
165
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
SELECT: "ui:select",
|
|
229
|
-
/** Attribute selection applied. `detail`: `{ attribute, value }`. */
|
|
230
|
-
SELECTED: "ui:selected",
|
|
231
|
-
/** Focus changed (bubbles). `detail`: `{ component, attributes }`, or `null` for the overview. */
|
|
232
|
-
FOCUS_CHANGE: "vd:focus-change",
|
|
233
|
-
/** Resolved configuration changed (bubbles). `detail`: the resolved configuration, or `null` when nothing matches. */
|
|
234
|
-
CONFIGURATION_CHANGE: "vd:configuration-change",
|
|
235
|
-
/** Configuration submitted (bubbles). `detail`: the resolved configuration handed to the host. */
|
|
236
|
-
CONFIGURATION_SUBMIT: "vd:configuration-submit"
|
|
237
|
-
};
|
|
238
|
-
class $t {
|
|
239
|
-
constructor(t, e) {
|
|
240
|
-
this.value = t, this.attribute = e;
|
|
241
|
-
}
|
|
242
|
-
value;
|
|
243
|
-
attribute;
|
|
244
|
-
isSelectedValue = !1;
|
|
245
|
-
get isSelected() {
|
|
246
|
-
return this.isSelectedValue;
|
|
247
|
-
}
|
|
248
|
-
setSelected(t) {
|
|
249
|
-
this.isSelectedValue = t;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
class Dt {
|
|
253
|
-
name;
|
|
254
|
-
defaultValue;
|
|
255
|
-
values;
|
|
256
|
-
onSelect;
|
|
257
|
-
onChangeCallback;
|
|
258
|
-
constructor(t) {
|
|
259
|
-
this.name = t.name, this.defaultValue = t.defaultValue, this.onSelect = t.onSelect, this.values = this.createValues(t.values);
|
|
260
|
-
}
|
|
261
|
-
/**
|
|
262
|
-
* Select a value for this attribute
|
|
263
|
-
* @throws {VirtualdisplayError} When value not found
|
|
264
|
-
*/
|
|
265
|
-
select(t) {
|
|
266
|
-
if (!this.values.has(t))
|
|
267
|
-
throw f.valueNotFound(this.name, t);
|
|
268
|
-
this.onSelect(this.name, t);
|
|
269
|
-
}
|
|
270
|
-
getValues() {
|
|
271
|
-
return Array.from(this.values.values());
|
|
272
|
-
}
|
|
273
|
-
getValue(t) {
|
|
274
|
-
return this.values.get(t);
|
|
275
|
-
}
|
|
276
|
-
/** The currently selected value, or undefined before any selection lands. */
|
|
277
|
-
get selected() {
|
|
278
|
-
for (const t of this.values.values())
|
|
279
|
-
if (t.isSelected)
|
|
280
|
-
return t.value;
|
|
281
|
-
}
|
|
282
|
-
/**
|
|
283
|
-
* Register callback that fires when selection changes
|
|
284
|
-
* Receives the newly selected AttributeValue
|
|
285
|
-
*/
|
|
286
|
-
onChange(t) {
|
|
287
|
-
this.onChangeCallback = t;
|
|
288
|
-
}
|
|
289
|
-
/**
|
|
290
|
-
* Update selection state from server mutation result
|
|
291
|
-
* Direct value comparison - no source/target translation
|
|
292
|
-
*/
|
|
293
|
-
handleResult(t) {
|
|
294
|
-
let e;
|
|
295
|
-
for (const i of this.values.values()) {
|
|
296
|
-
const o = i.value === t;
|
|
297
|
-
i.setSelected(o), o && (e = i);
|
|
298
|
-
}
|
|
299
|
-
e !== void 0 && this.onChangeCallback !== void 0 && this.onChangeCallback(e);
|
|
300
|
-
}
|
|
301
|
-
createValues(t) {
|
|
302
|
-
const e = /* @__PURE__ */ new Map();
|
|
303
|
-
for (const i of t) {
|
|
304
|
-
const o = new $t(i, this.name);
|
|
305
|
-
i === this.defaultValue && o.setSelected(!0), e.set(i, o);
|
|
306
|
-
}
|
|
307
|
-
return e;
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
class Bt {
|
|
311
|
-
attributes = /* @__PURE__ */ new Map();
|
|
312
|
-
constructor(t, e, i) {
|
|
313
|
-
for (const o of t) {
|
|
314
|
-
const s = this.buildOptions(o, e);
|
|
315
|
-
this.attributes.set(o.name, new Dt(s));
|
|
316
|
-
}
|
|
317
|
-
this.onMutationFailed = i;
|
|
318
|
-
}
|
|
319
|
-
onMutationFailed;
|
|
320
|
-
get(t) {
|
|
321
|
-
return this.attributes.get(t);
|
|
322
|
-
}
|
|
323
|
-
/** The current selection as attribute name→value pairs, skipping unset attributes. */
|
|
324
|
-
getSelection() {
|
|
325
|
-
const t = {};
|
|
326
|
-
for (const [e, i] of this.attributes) {
|
|
327
|
-
const o = i.selected;
|
|
328
|
-
o !== void 0 && (t[e] = o);
|
|
329
|
-
}
|
|
330
|
-
return t;
|
|
331
|
-
}
|
|
332
|
-
handleResults(t) {
|
|
333
|
-
for (const e of t) {
|
|
334
|
-
if (!e.success) {
|
|
335
|
-
this.onMutationFailed?.(e.name, e.value);
|
|
336
|
-
continue;
|
|
337
|
-
}
|
|
338
|
-
this.get(e.name)?.handleResult(e.value);
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
buildOptions(t, e) {
|
|
342
|
-
const i = {
|
|
343
|
-
name: t.name,
|
|
344
|
-
values: t.values,
|
|
345
|
-
onSelect: (o, s) => {
|
|
346
|
-
e([{ name: o, value: s }], !1);
|
|
347
|
-
}
|
|
348
|
-
};
|
|
349
|
-
return t.defaultValue !== void 0 ? { ...i, defaultValue: t.defaultValue } : i;
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
const c = {
|
|
353
|
-
HANDSHAKE: "handshake",
|
|
354
|
-
SESSION: "session",
|
|
355
|
-
MUTATION: "mutation",
|
|
356
|
-
STATE: "state",
|
|
357
|
-
LOADING_INDICATOR: "loading_indicator",
|
|
358
|
-
CAMERA: "camera",
|
|
359
|
-
SNAPSHOT: "snapshot",
|
|
360
|
-
MAPPING: "mapping",
|
|
361
|
-
AR_ACTIVATE: "ar_activate",
|
|
362
|
-
FULLSCREEN: "fullscreen",
|
|
363
|
-
CONFIG: "config",
|
|
364
|
-
ANNOTATION_PLACE_MODE: "annotation_place_mode",
|
|
365
|
-
ANNOTATION_PLACED: "annotation_placed",
|
|
366
|
-
ANNOTATION_TOGGLE: "annotation_toggle",
|
|
367
|
-
FOCUS: "focus",
|
|
368
|
-
PRICING: "pricing"
|
|
369
|
-
}, X = {
|
|
370
|
-
FOCUS: "focus",
|
|
371
|
-
UNFOCUS: "unfocus"
|
|
372
|
-
}, Ut = {
|
|
373
|
-
FOCUSED: "focused"
|
|
374
|
-
}, Vt = {
|
|
375
|
-
/** Behaves exactly like an unpriced combination: no price, no button. */
|
|
376
|
-
HIDDEN: "hidden"
|
|
377
|
-
}, jt = new Set(Object.values(c));
|
|
378
|
-
function Ht(n) {
|
|
379
|
-
if (typeof n != "object" || n === null)
|
|
380
|
-
return !1;
|
|
381
|
-
const t = n;
|
|
382
|
-
return typeof t.target == "string" ? !1 : typeof t.type == "string" && jt.has(t.type);
|
|
383
|
-
}
|
|
384
|
-
function Gt(n) {
|
|
385
|
-
const t = w(n);
|
|
386
|
-
return t !== null && t.type === c.HANDSHAKE;
|
|
387
|
-
}
|
|
388
|
-
function qt(n) {
|
|
389
|
-
const t = w(n);
|
|
390
|
-
return t !== null && t.type === c.SESSION && typeof t.sessionId == "string";
|
|
391
|
-
}
|
|
392
|
-
function Zt(n) {
|
|
393
|
-
const t = w(n);
|
|
394
|
-
return t !== null && t.type === c.MUTATION && Array.isArray(t.results);
|
|
395
|
-
}
|
|
396
|
-
function Wt(n) {
|
|
397
|
-
const t = w(n);
|
|
398
|
-
return t !== null && t.type === c.SNAPSHOT && ("data" in t || "error" in t);
|
|
399
|
-
}
|
|
400
|
-
function Yt(n) {
|
|
401
|
-
const t = w(n);
|
|
402
|
-
return t !== null && t.type === c.CAMERA && Array.isArray(t.transforms);
|
|
403
|
-
}
|
|
404
|
-
function Xt(n) {
|
|
405
|
-
const t = w(n);
|
|
406
|
-
return t !== null && t.type === c.MAPPING && Array.isArray(t.attributes);
|
|
407
|
-
}
|
|
408
|
-
function Kt(n) {
|
|
409
|
-
const t = w(n);
|
|
410
|
-
return t !== null && t.type === c.LOADING_INDICATOR && typeof t.progress == "number";
|
|
411
|
-
}
|
|
412
|
-
function Qt(n) {
|
|
413
|
-
const t = w(n);
|
|
414
|
-
return t !== null && t.type === c.CONFIG && typeof t.viewerSettings == "object";
|
|
415
|
-
}
|
|
416
|
-
function Jt(n) {
|
|
417
|
-
const t = w(n);
|
|
418
|
-
return t !== null && t.type === c.ANNOTATION_PLACED && typeof t.position == "object" && t.position !== null;
|
|
419
|
-
}
|
|
420
|
-
function te(n) {
|
|
421
|
-
const t = w(n);
|
|
422
|
-
return t !== null && t.type === c.FOCUS && typeof t.state == "string";
|
|
423
|
-
}
|
|
424
|
-
function ee(n) {
|
|
425
|
-
const t = w(n);
|
|
426
|
-
return t !== null && t.type === c.PRICING && typeof t.pricing == "object" && t.pricing !== null;
|
|
427
|
-
}
|
|
428
|
-
function w(n) {
|
|
429
|
-
return typeof n != "object" || n === null ? null : n;
|
|
430
|
-
}
|
|
431
|
-
class K {
|
|
432
|
-
constructor(t) {
|
|
433
|
-
this.processor = t;
|
|
434
|
-
}
|
|
435
|
-
processor;
|
|
436
|
-
pending = [];
|
|
437
|
-
isReady = !1;
|
|
438
|
-
/**
|
|
439
|
-
* Add a message — processed immediately if ready, queued otherwise
|
|
440
|
-
*/
|
|
441
|
-
enqueue(t) {
|
|
442
|
-
if (this.isReady) {
|
|
443
|
-
this.processor(t);
|
|
444
|
-
return;
|
|
445
|
-
}
|
|
446
|
-
this.pending.push(t);
|
|
447
|
-
}
|
|
448
|
-
/**
|
|
449
|
-
* Mark as ready and flush all pending messages
|
|
450
|
-
*/
|
|
451
|
-
markReady() {
|
|
452
|
-
if (this.isReady || (this.isReady = !0, this.pending.length === 0))
|
|
453
|
-
return;
|
|
454
|
-
const t = [...this.pending];
|
|
455
|
-
this.pending.length = 0;
|
|
456
|
-
for (const e of t)
|
|
457
|
-
this.processor(e);
|
|
458
|
-
}
|
|
459
|
-
get ready() {
|
|
460
|
-
return this.isReady;
|
|
461
|
-
}
|
|
462
|
-
get pendingCount() {
|
|
463
|
-
return this.pending.length;
|
|
464
|
-
}
|
|
465
|
-
/**
|
|
466
|
-
* Check if a message of a specific type is pending
|
|
467
|
-
*/
|
|
468
|
-
hasPending(t) {
|
|
469
|
-
return this.pending.some((e) => e.type === t);
|
|
470
|
-
}
|
|
471
|
-
/**
|
|
472
|
-
* Clear all pending messages
|
|
473
|
-
*/
|
|
474
|
-
clear() {
|
|
475
|
-
this.pending.length = 0;
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
class ne {
|
|
479
|
-
constructor(t, e) {
|
|
480
|
-
this.getTarget = t, this.sourceId = `vd-${Math.random().toString(36).slice(2, 8)}`, this.targetOrigin = e?.targetOrigin ?? "*", this.publisher = new K((i) => this.post(i)), this.consumer = new K((i) => this.routeToHandler(i)), this.shouldBuffer = e?.shouldBuffer ?? null, e?.bufferIncoming !== !0 && this.consumer.markReady();
|
|
481
|
-
}
|
|
482
|
-
getTarget;
|
|
483
|
-
handlers = /* @__PURE__ */ new Map();
|
|
484
|
-
publisher;
|
|
485
|
-
consumer;
|
|
486
|
-
shouldBuffer;
|
|
487
|
-
listener = null;
|
|
488
|
-
sourceId;
|
|
489
|
-
targetOrigin;
|
|
490
|
-
/**
|
|
491
|
-
* Register a handler for a specific message type
|
|
492
|
-
*/
|
|
493
|
-
on(t, e) {
|
|
494
|
-
this.handlers.set(t, e);
|
|
495
|
-
}
|
|
496
|
-
/**
|
|
497
|
-
* Remove a handler for a specific message type
|
|
498
|
-
*/
|
|
499
|
-
off(t) {
|
|
500
|
-
this.handlers.delete(t);
|
|
501
|
-
}
|
|
502
|
-
/**
|
|
503
|
-
* Update the target origin for outgoing postMessage calls.
|
|
504
|
-
* Use when the target origin is discovered at runtime (e.g. from the first incoming message).
|
|
505
|
-
*/
|
|
506
|
-
setTargetOrigin(t) {
|
|
507
|
-
this.targetOrigin = t;
|
|
508
|
-
}
|
|
509
|
-
/**
|
|
510
|
-
* Send a message to the target window
|
|
511
|
-
* Queued until markReady() is called
|
|
512
|
-
*/
|
|
513
|
-
send(t) {
|
|
514
|
-
this.publisher.enqueue(t);
|
|
515
|
-
}
|
|
516
|
-
/**
|
|
517
|
-
* Enable sending and flush queued outgoing messages
|
|
518
|
-
*/
|
|
519
|
-
markReady() {
|
|
520
|
-
this.publisher.markReady();
|
|
521
|
-
}
|
|
522
|
-
/**
|
|
523
|
-
* Enable processing of buffered incoming messages
|
|
524
|
-
* Only relevant when constructed with bufferIncoming: true
|
|
525
|
-
*/
|
|
526
|
-
markConsumerReady() {
|
|
527
|
-
this.consumer.markReady();
|
|
166
|
+
/**
|
|
167
|
+
* Enable processing of buffered incoming messages
|
|
168
|
+
* Only relevant when constructed with bufferIncoming: true
|
|
169
|
+
*/
|
|
170
|
+
markConsumerReady() {
|
|
171
|
+
this.consumer.markReady();
|
|
528
172
|
}
|
|
529
173
|
/**
|
|
530
174
|
* Check if an incoming message of a specific type is pending in the consumer buffer
|
|
@@ -538,7 +182,7 @@ class ne {
|
|
|
538
182
|
start() {
|
|
539
183
|
this.listener === null && (this.listener = (t) => {
|
|
540
184
|
const { data: e } = t;
|
|
541
|
-
if (!
|
|
185
|
+
if (!this.isValid(e) || e._source === this.sourceId)
|
|
542
186
|
return;
|
|
543
187
|
const i = this.getTarget();
|
|
544
188
|
if (i !== null && t.source !== null && t.source !== i)
|
|
@@ -584,1816 +228,2088 @@ class ne {
|
|
|
584
228
|
});
|
|
585
229
|
}
|
|
586
230
|
}
|
|
587
|
-
class
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
send;
|
|
592
|
-
onMutationFailed;
|
|
593
|
-
registry;
|
|
594
|
-
pendingCallbacks = [];
|
|
595
|
-
/**
|
|
596
|
-
* Handle incoming MAPPING message from server
|
|
597
|
-
*/
|
|
598
|
-
handleMappingReceived(t) {
|
|
599
|
-
C.debug("Initializing from server mapping", {
|
|
600
|
-
attributeCount: t.attributes.length
|
|
601
|
-
}), this.registry = new Bt(
|
|
602
|
-
t.attributes,
|
|
603
|
-
(e, i) => this.sendMutation(e, i),
|
|
604
|
-
this.onMutationFailed
|
|
605
|
-
), this.replayPendingCallbacks();
|
|
606
|
-
}
|
|
607
|
-
handleMutationResult(t) {
|
|
608
|
-
this.registry?.handleResults(t.results);
|
|
609
|
-
}
|
|
610
|
-
/**
|
|
611
|
-
* Select a value for an attribute - sends mutation to server.
|
|
612
|
-
* Can be called before the mapping arrives — the mutation is sent immediately
|
|
613
|
-
* and the messenger's publisher queue holds it until the iframe is ready.
|
|
614
|
-
*/
|
|
615
|
-
select(t, e) {
|
|
616
|
-
this.sendMutation([{ name: t, value: e }], !1);
|
|
617
|
-
}
|
|
618
|
-
getValues(t) {
|
|
619
|
-
return this.registry?.get(t)?.getValues() ?? [];
|
|
231
|
+
class g {
|
|
232
|
+
element;
|
|
233
|
+
constructor({ variant: t = "default", size: e = "default", label: i, icon: o, onClick: s, disabled: r = !1 } = {}) {
|
|
234
|
+
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;
|
|
620
235
|
}
|
|
621
|
-
|
|
622
|
-
|
|
236
|
+
setIcon(t) {
|
|
237
|
+
const e = this.element.querySelector("svg");
|
|
238
|
+
e !== null ? e.replaceWith(t) : this.element.appendChild(t);
|
|
623
239
|
}
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
240
|
+
}
|
|
241
|
+
const $t = {
|
|
242
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
243
|
+
width: 24,
|
|
244
|
+
height: 24,
|
|
245
|
+
viewBox: "0 0 24 24",
|
|
246
|
+
fill: "none",
|
|
247
|
+
stroke: "currentColor",
|
|
248
|
+
"stroke-width": 2,
|
|
249
|
+
"stroke-linecap": "round",
|
|
250
|
+
"stroke-linejoin": "round"
|
|
251
|
+
};
|
|
252
|
+
const lt = ([n, t, e]) => {
|
|
253
|
+
const i = document.createElementNS("http://www.w3.org/2000/svg", n);
|
|
254
|
+
return Object.keys(t).forEach((o) => {
|
|
255
|
+
i.setAttribute(o, String(t[o]));
|
|
256
|
+
}), e?.length && e.forEach((o) => {
|
|
257
|
+
const s = lt(o);
|
|
258
|
+
i.appendChild(s);
|
|
259
|
+
}), i;
|
|
260
|
+
}, ct = (n, t = {}) => {
|
|
261
|
+
const i = {
|
|
262
|
+
...$t,
|
|
263
|
+
...t
|
|
264
|
+
};
|
|
265
|
+
return lt(["svg", i, n]);
|
|
266
|
+
};
|
|
267
|
+
const Dt = [
|
|
268
|
+
[
|
|
269
|
+
"path",
|
|
270
|
+
{
|
|
271
|
+
d: "M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"
|
|
632
272
|
}
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
273
|
+
],
|
|
274
|
+
["path", { d: "m3.3 7 8.7 5 8.7-5" }],
|
|
275
|
+
["path", { d: "M12 22V12" }]
|
|
276
|
+
];
|
|
277
|
+
const Bt = [
|
|
278
|
+
[
|
|
279
|
+
"path",
|
|
280
|
+
{
|
|
281
|
+
d: "M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z"
|
|
637
282
|
}
|
|
638
|
-
|
|
283
|
+
],
|
|
284
|
+
["circle", { cx: "12", cy: "13", r: "3" }]
|
|
285
|
+
];
|
|
286
|
+
const ut = [["path", { d: "m6 9 6 6 6-6" }]];
|
|
287
|
+
const Ut = [["path", { d: "m15 18-6-6 6-6" }]];
|
|
288
|
+
const Vt = [["path", { d: "m9 18 6-6-6-6" }]];
|
|
289
|
+
const jt = [["path", { d: "m18 15-6-6-6 6" }]];
|
|
290
|
+
const Ht = [
|
|
291
|
+
["path", { d: "M15 3h6v6" }],
|
|
292
|
+
["path", { d: "m21 3-7 7" }],
|
|
293
|
+
["path", { d: "m3 21 7-7" }],
|
|
294
|
+
["path", { d: "M9 21H3v-6" }]
|
|
295
|
+
];
|
|
296
|
+
const Gt = [
|
|
297
|
+
["path", { d: "m14 10 7-7" }],
|
|
298
|
+
["path", { d: "M20 10h-6V4" }],
|
|
299
|
+
["path", { d: "m3 21 7-7" }],
|
|
300
|
+
["path", { d: "M4 14h6v6" }]
|
|
301
|
+
];
|
|
302
|
+
const qt = [
|
|
303
|
+
["path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }],
|
|
304
|
+
["path", { d: "M3 3v5h5" }]
|
|
305
|
+
];
|
|
306
|
+
const Zt = [
|
|
307
|
+
["path", { d: "M10 5H3" }],
|
|
308
|
+
["path", { d: "M12 19H3" }],
|
|
309
|
+
["path", { d: "M14 3v4" }],
|
|
310
|
+
["path", { d: "M16 17v4" }],
|
|
311
|
+
["path", { d: "M21 12h-9" }],
|
|
312
|
+
["path", { d: "M21 19h-5" }],
|
|
313
|
+
["path", { d: "M21 5h-7" }],
|
|
314
|
+
["path", { d: "M8 10v4" }],
|
|
315
|
+
["path", { d: "M8 12H3" }]
|
|
316
|
+
];
|
|
317
|
+
const Wt = [
|
|
318
|
+
["path", { d: "M18 6 6 18" }],
|
|
319
|
+
["path", { d: "m6 6 12 12" }]
|
|
320
|
+
];
|
|
321
|
+
const Yt = [
|
|
322
|
+
["circle", { cx: "11", cy: "11", r: "8" }],
|
|
323
|
+
["line", { x1: "21", x2: "16.65", y1: "21", y2: "16.65" }],
|
|
324
|
+
["line", { x1: "11", x2: "11", y1: "8", y2: "14" }],
|
|
325
|
+
["line", { x1: "8", x2: "14", y1: "11", y2: "11" }]
|
|
326
|
+
];
|
|
327
|
+
const Xt = [
|
|
328
|
+
["circle", { cx: "11", cy: "11", r: "8" }],
|
|
329
|
+
["line", { x1: "21", x2: "16.65", y1: "21", y2: "16.65" }],
|
|
330
|
+
["line", { x1: "8", x2: "14", y1: "11", y2: "11" }]
|
|
331
|
+
], m = {
|
|
332
|
+
semantic: {
|
|
333
|
+
// eslint-disable-next-line vd-custom/enforce-error-codes -- This is a hex color, not an error code
|
|
334
|
+
error: "#dc2626"
|
|
335
|
+
},
|
|
336
|
+
neutral: {
|
|
337
|
+
500: "#737373",
|
|
338
|
+
600: "#525252",
|
|
339
|
+
900: "#171717"
|
|
340
|
+
},
|
|
341
|
+
white: "#ffffff",
|
|
342
|
+
black: "#000000"
|
|
343
|
+
}, a = {
|
|
344
|
+
0: "0",
|
|
345
|
+
0.5: "0.125rem",
|
|
346
|
+
// 2px
|
|
347
|
+
1: "0.25rem",
|
|
348
|
+
// 4px
|
|
349
|
+
1.5: "0.375rem",
|
|
350
|
+
// 6px
|
|
351
|
+
2: "0.5rem",
|
|
352
|
+
// 10px
|
|
353
|
+
3: "0.75rem",
|
|
354
|
+
// 14px
|
|
355
|
+
4: "1rem",
|
|
356
|
+
// 16px
|
|
357
|
+
5: "1.25rem",
|
|
358
|
+
// 20px
|
|
359
|
+
6: "1.5rem",
|
|
360
|
+
// 28px
|
|
361
|
+
8: "2rem",
|
|
362
|
+
// 32px
|
|
363
|
+
9: "2.25rem",
|
|
364
|
+
// 80px
|
|
365
|
+
24: "6rem"
|
|
366
|
+
// 96px
|
|
367
|
+
};
|
|
368
|
+
class Kt {
|
|
369
|
+
element;
|
|
370
|
+
constructor() {
|
|
371
|
+
this.element = document.createElement("div"), Object.assign(this.element.style, {
|
|
372
|
+
background: m.white,
|
|
373
|
+
borderRadius: a[3],
|
|
374
|
+
padding: a[6],
|
|
375
|
+
boxShadow: `0 ${a[2]} ${a[8]} oklch(0% 0 0 / 20%)`,
|
|
376
|
+
maxWidth: "20rem",
|
|
377
|
+
width: "100%"
|
|
378
|
+
});
|
|
639
379
|
}
|
|
640
|
-
|
|
641
|
-
|
|
380
|
+
}
|
|
381
|
+
class Qt {
|
|
382
|
+
constructor(t = {}) {
|
|
383
|
+
this.options = t, this.card = new Kt(), this.backdrop = this.createBackdrop(), this.backdrop.appendChild(this.card.element);
|
|
642
384
|
}
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
385
|
+
options;
|
|
386
|
+
card;
|
|
387
|
+
backdrop;
|
|
388
|
+
keyHandler = null;
|
|
389
|
+
open() {
|
|
390
|
+
document.body.appendChild(this.backdrop), this.keyHandler = (t) => {
|
|
391
|
+
t.key === "Escape" && this.close();
|
|
392
|
+
}, document.addEventListener("keydown", this.keyHandler);
|
|
646
393
|
}
|
|
647
|
-
|
|
648
|
-
|
|
394
|
+
close() {
|
|
395
|
+
this.backdrop.remove(), this.keyHandler !== null && (document.removeEventListener("keydown", this.keyHandler), this.keyHandler = null), this.options.onClose?.();
|
|
649
396
|
}
|
|
650
|
-
|
|
651
|
-
const
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
397
|
+
createBackdrop() {
|
|
398
|
+
const t = document.createElement("div");
|
|
399
|
+
return Object.assign(t.style, {
|
|
400
|
+
position: "fixed",
|
|
401
|
+
inset: a[0],
|
|
402
|
+
background: "oklch(0% 0 0 / 50%)",
|
|
403
|
+
zIndex: "9999",
|
|
404
|
+
display: "flex",
|
|
405
|
+
alignItems: "center",
|
|
406
|
+
justifyContent: "center"
|
|
407
|
+
}), t.addEventListener("click", (e) => {
|
|
408
|
+
e.target === t && this.close();
|
|
409
|
+
}), t;
|
|
657
410
|
}
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
411
|
+
}
|
|
412
|
+
class Jt {
|
|
413
|
+
element;
|
|
414
|
+
selectCallback = null;
|
|
415
|
+
constructor(t, e, i) {
|
|
416
|
+
this.element = document.createElement("div"), this.element.className = "ui-toggle-group";
|
|
417
|
+
for (let o = 0; o < t.length; o++) {
|
|
418
|
+
const s = t[o], r = document.createElement("button");
|
|
419
|
+
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", () => {
|
|
420
|
+
this.selectCallback?.(s);
|
|
421
|
+
}), this.element.appendChild(r);
|
|
662
422
|
}
|
|
663
|
-
this.pendingCallbacks.length = 0;
|
|
664
423
|
}
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
424
|
+
setSelected(t) {
|
|
425
|
+
for (const e of this.element.querySelectorAll(".ui-toggle-group-item")) {
|
|
426
|
+
const i = e.dataset.value === t;
|
|
427
|
+
e.dataset.state = i ? "on" : "off", e.setAttribute("aria-pressed", i ? "true" : "false");
|
|
428
|
+
}
|
|
669
429
|
}
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
/**
|
|
673
|
-
* Rotate camera horizontally
|
|
674
|
-
* @param degrees - Absolute rotation in degrees (0 = front view)
|
|
675
|
-
* @throws VirtualdisplayError if value is not a finite number
|
|
676
|
-
*/
|
|
677
|
-
rotate(t) {
|
|
678
|
-
return this.validateFiniteNumber(t, "rotate"), this.commands.push({ action: "rotate", value: t }), this;
|
|
430
|
+
onSelect(t) {
|
|
431
|
+
this.selectCallback = t;
|
|
679
432
|
}
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
433
|
+
}
|
|
434
|
+
class te {
|
|
435
|
+
element;
|
|
436
|
+
select;
|
|
437
|
+
constructor(t, e, i, o, s) {
|
|
438
|
+
this.select = document.createElement("select"), this.select.className = "ui-native-select", this.select.dataset.name = t, this.select.setAttribute("aria-label", i);
|
|
439
|
+
const r = document.createElement("option");
|
|
440
|
+
r.value = "", r.disabled = !0, r.textContent = i, this.select.appendChild(r);
|
|
441
|
+
let l = !1;
|
|
442
|
+
for (let u = 0; u < e.length; u++) {
|
|
443
|
+
const p = e[u], v = document.createElement("option");
|
|
444
|
+
v.value = p, v.textContent = s?.[u] ?? p, p === o && (v.selected = !0, l = !0), this.select.appendChild(v);
|
|
445
|
+
}
|
|
446
|
+
l || (r.selected = !0);
|
|
447
|
+
const d = ct(ut, { width: 16, height: 16, "stroke-width": 2 });
|
|
448
|
+
d.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(d);
|
|
687
449
|
}
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
* @param percentage - Zoom percentage (100 = normal, >100 = zoom in, <100 = zoom out)
|
|
691
|
-
* @throws VirtualdisplayError if value is not a finite number
|
|
692
|
-
*/
|
|
693
|
-
zoom(t) {
|
|
694
|
-
return this.validateFiniteNumber(t, "zoom"), this.commands.push({ action: "zoom", value: t }), this;
|
|
695
|
-
}
|
|
696
|
-
/**
|
|
697
|
-
* Execute accumulated camera commands
|
|
698
|
-
* @throws VirtualdisplayError if no commands have been accumulated
|
|
699
|
-
*/
|
|
700
|
-
set() {
|
|
701
|
-
if (this.commands.length === 0)
|
|
702
|
-
throw f.invalidParameter(
|
|
703
|
-
"No camera commands to execute. Call rotate(), tilt(), or zoom() before set()."
|
|
704
|
-
);
|
|
705
|
-
const t = {
|
|
706
|
-
type: c.CAMERA,
|
|
707
|
-
commands: this.commands
|
|
708
|
-
};
|
|
709
|
-
this.send(t), this.commands = [];
|
|
710
|
-
}
|
|
711
|
-
validateFiniteNumber(t, e) {
|
|
712
|
-
if (!Number.isFinite(t))
|
|
713
|
-
throw f.invalidParameter(
|
|
714
|
-
`${e}() requires a finite number, got ${String(t)}`
|
|
715
|
-
);
|
|
450
|
+
setSelected(t) {
|
|
451
|
+
this.select.value = t;
|
|
716
452
|
}
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
reset() {
|
|
722
|
-
const t = {
|
|
723
|
-
type: c.CAMERA,
|
|
724
|
-
commands: [{ action: "reset" }]
|
|
725
|
-
};
|
|
726
|
-
this.send(t);
|
|
453
|
+
onSelect(t) {
|
|
454
|
+
this.select.addEventListener("change", () => {
|
|
455
|
+
t(this.select.value);
|
|
456
|
+
});
|
|
727
457
|
}
|
|
458
|
+
}
|
|
459
|
+
const ee = {}, ne = "en", dt = (
|
|
460
|
+
/** @type {const} */
|
|
461
|
+
["en", "nl", "de"]
|
|
462
|
+
), Z = [
|
|
463
|
+
"baseLocale"
|
|
464
|
+
], K = [];
|
|
465
|
+
let Q, J;
|
|
466
|
+
function ie(n) {
|
|
467
|
+
if (K.length === 0)
|
|
468
|
+
return;
|
|
469
|
+
const t = typeof n == "string" ? n : n.href;
|
|
470
|
+
if (Q === t)
|
|
471
|
+
return J;
|
|
472
|
+
const e = new URL(t, "http://dummy.com");
|
|
473
|
+
let i;
|
|
474
|
+
for (const o of K)
|
|
475
|
+
if (new ee(o.match, e.href).exec(e.href)) {
|
|
476
|
+
i = o;
|
|
477
|
+
break;
|
|
478
|
+
}
|
|
479
|
+
return Q = t, J = i, i;
|
|
480
|
+
}
|
|
481
|
+
function ht(n) {
|
|
482
|
+
const t = ie(n);
|
|
483
|
+
return t && t.exclude !== !0 && Array.isArray(t.strategy) ? t.strategy : Z;
|
|
484
|
+
}
|
|
485
|
+
const q = typeof window > "u";
|
|
486
|
+
globalThis.__paraglide = /** @type {any} */
|
|
487
|
+
globalThis.__paraglide ?? {};
|
|
488
|
+
globalThis.__paraglide.ssr = /** @type {any} */
|
|
489
|
+
globalThis.__paraglide.ssr ?? {};
|
|
490
|
+
let tt = !1, h = () => {
|
|
491
|
+
let n = Z;
|
|
492
|
+
!q && typeof window < "u" && window.location?.href && (n = ht(window.location.href));
|
|
493
|
+
const t = oe(n);
|
|
494
|
+
if (t)
|
|
495
|
+
return tt || (tt = !0, mt(t, { reload: !1 })), t;
|
|
496
|
+
throw new Error("No locale found. Read the docs https://paraglidejs.com/errors#no-locale-found");
|
|
728
497
|
};
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
*/
|
|
743
|
-
get rotation() {
|
|
744
|
-
return this.state.rotation;
|
|
745
|
-
}
|
|
746
|
-
/**
|
|
747
|
-
* Get current tilt in degrees
|
|
748
|
-
*/
|
|
749
|
-
get tilt() {
|
|
750
|
-
return this.state.tilt;
|
|
751
|
-
}
|
|
752
|
-
/**
|
|
753
|
-
* Get current zoom percentage
|
|
754
|
-
*/
|
|
755
|
-
get zoom() {
|
|
756
|
-
return this.state.zoom;
|
|
757
|
-
}
|
|
758
|
-
/**
|
|
759
|
-
* Subscribe to camera position changes.
|
|
760
|
-
* Also fires when limits are applied via applyLimits() so components
|
|
761
|
-
* can re-evaluate disabled states without a separate callback.
|
|
762
|
-
*/
|
|
763
|
-
onChange(t) {
|
|
764
|
-
this.changeCallbacks.push(t);
|
|
765
|
-
}
|
|
766
|
-
/**
|
|
767
|
-
* Current camera movement limits (set from CONFIG message).
|
|
768
|
-
* Undefined until the server sends limits in its CONFIG payload.
|
|
769
|
-
*/
|
|
770
|
-
get limits() {
|
|
771
|
-
return this.limitsState;
|
|
772
|
-
}
|
|
773
|
-
/**
|
|
774
|
-
* Apply camera limits received from the server CONFIG message.
|
|
775
|
-
* Fires onChange callbacks so button disabled states update immediately.
|
|
776
|
-
*/
|
|
777
|
-
applyLimits(t) {
|
|
778
|
-
this.limitsState = t;
|
|
779
|
-
const e = { rotation: this.rotation, tilt: this.tilt, zoom: this.zoom };
|
|
780
|
-
for (const i of this.changeCallbacks)
|
|
781
|
-
i(e);
|
|
782
|
-
}
|
|
783
|
-
/**
|
|
784
|
-
* Handle incoming camera position message from server
|
|
785
|
-
*/
|
|
786
|
-
handlePositionUpdate(t) {
|
|
787
|
-
this.update(t.transforms);
|
|
788
|
-
}
|
|
789
|
-
/**
|
|
790
|
-
* Update camera position from server transforms
|
|
791
|
-
*/
|
|
792
|
-
update(t) {
|
|
793
|
-
let e = !1;
|
|
794
|
-
for (const i of t)
|
|
795
|
-
switch (i.type) {
|
|
796
|
-
case "rotation":
|
|
797
|
-
this.state.rotation = i.value, e = !0;
|
|
798
|
-
break;
|
|
799
|
-
case "tilt":
|
|
800
|
-
this.state.tilt = i.value, e = !0;
|
|
801
|
-
break;
|
|
802
|
-
case "zoom":
|
|
803
|
-
this.state.zoom = i.value, e = !0;
|
|
804
|
-
break;
|
|
498
|
+
function oe(n, t) {
|
|
499
|
+
let e;
|
|
500
|
+
for (const i of n) {
|
|
501
|
+
if (i === "baseLocale")
|
|
502
|
+
e = ne;
|
|
503
|
+
else if (ft(i) && N.has(i)) {
|
|
504
|
+
const s = N.get(i);
|
|
505
|
+
if (s) {
|
|
506
|
+
const r = s.getLocale();
|
|
507
|
+
if (r instanceof Promise)
|
|
508
|
+
continue;
|
|
509
|
+
if (r !== void 0)
|
|
510
|
+
return re(r);
|
|
805
511
|
}
|
|
806
|
-
if (e) {
|
|
807
|
-
const i = {
|
|
808
|
-
rotation: this.rotation,
|
|
809
|
-
tilt: this.tilt,
|
|
810
|
-
zoom: this.zoom
|
|
811
|
-
};
|
|
812
|
-
for (const o of this.changeCallbacks)
|
|
813
|
-
o(i);
|
|
814
512
|
}
|
|
513
|
+
const o = pt(e);
|
|
514
|
+
if (o)
|
|
515
|
+
return o;
|
|
815
516
|
}
|
|
816
517
|
}
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
}
|
|
830
|
-
/**
|
|
831
|
-
* Focus a component by name. Sends a focus message to the viewer.
|
|
832
|
-
* @throws VirtualdisplayError if component is not a non-empty string
|
|
833
|
-
*/
|
|
834
|
-
set(t) {
|
|
835
|
-
if (typeof t != "string" || t.length === 0)
|
|
836
|
-
throw f.invalidParameter(
|
|
837
|
-
`set() requires a non-empty component name, got ${String(t)}`
|
|
838
|
-
);
|
|
839
|
-
this.send({ type: c.FOCUS, action: X.FOCUS, component: t });
|
|
840
|
-
}
|
|
841
|
-
/** Return to the overview — unfocus the current component. */
|
|
842
|
-
clear() {
|
|
843
|
-
this.send({ type: c.FOCUS, action: X.UNFOCUS });
|
|
844
|
-
}
|
|
845
|
-
/**
|
|
846
|
-
* Subscribe to focus changes. The callback fires with the focus state when a
|
|
847
|
-
* component is focused, and with null when returning to overview.
|
|
848
|
-
*/
|
|
849
|
-
onChange(t) {
|
|
850
|
-
this.changeCallbacks.push(t);
|
|
851
|
-
}
|
|
852
|
-
/** Called by the client when a FocusStateMessage is received from the viewer. */
|
|
853
|
-
handleStateReceived(t) {
|
|
854
|
-
t.state === Ut.FOCUSED && t.component !== void 0 ? (this.focused = t.component, this.attributes = t.attributes ?? []) : (this.focused = null, this.attributes = []);
|
|
855
|
-
const e = this.focused !== null ? { component: this.focused, attributes: this.attributes } : null;
|
|
856
|
-
for (const i of this.changeCallbacks)
|
|
857
|
-
i(e);
|
|
858
|
-
this.dispatch(e);
|
|
518
|
+
const se = (n) => {
|
|
519
|
+
window.location.reload();
|
|
520
|
+
};
|
|
521
|
+
let mt = (n, t) => {
|
|
522
|
+
const e = {
|
|
523
|
+
reload: !0,
|
|
524
|
+
...t
|
|
525
|
+
};
|
|
526
|
+
let i;
|
|
527
|
+
try {
|
|
528
|
+
i = h();
|
|
529
|
+
} catch {
|
|
859
530
|
}
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
531
|
+
const o = [];
|
|
532
|
+
let s = Z;
|
|
533
|
+
!q && typeof window < "u" && window.location?.href && (s = ht(window.location.href));
|
|
534
|
+
for (const l of s)
|
|
535
|
+
if (l !== "baseLocale" && ft(l) && N.has(l)) {
|
|
536
|
+
const d = N.get(l);
|
|
537
|
+
if (d) {
|
|
538
|
+
let u = d.setLocale(n);
|
|
539
|
+
u instanceof Promise && (u = u.catch((p) => {
|
|
540
|
+
throw new Error(`Custom strategy "${l}" setLocale failed.`, {
|
|
541
|
+
cause: p
|
|
542
|
+
});
|
|
543
|
+
}), o.push(u));
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
const r = () => {
|
|
547
|
+
!q && e.reload && window.location && n !== i && se();
|
|
548
|
+
};
|
|
549
|
+
if (o.length)
|
|
550
|
+
return Promise.all(o).then(() => {
|
|
551
|
+
r();
|
|
552
|
+
});
|
|
553
|
+
r();
|
|
554
|
+
};
|
|
555
|
+
function pt(n) {
|
|
556
|
+
if (typeof n != "string")
|
|
864
557
|
return;
|
|
865
|
-
const
|
|
866
|
-
|
|
558
|
+
const t = n.toLowerCase();
|
|
559
|
+
for (const e of dt)
|
|
560
|
+
if (e.toLowerCase() === t)
|
|
561
|
+
return e;
|
|
867
562
|
}
|
|
868
|
-
function
|
|
869
|
-
|
|
563
|
+
function re(n) {
|
|
564
|
+
const t = pt(n);
|
|
565
|
+
if (t)
|
|
566
|
+
return t;
|
|
567
|
+
throw new Error(`Invalid locale: ${n}. Expected one of: ${dt.join(", ")}`);
|
|
870
568
|
}
|
|
871
|
-
|
|
872
|
-
|
|
569
|
+
const N = /* @__PURE__ */ new Map();
|
|
570
|
+
function ft(n) {
|
|
571
|
+
return typeof n == "string" && /^custom-[A-Za-z0-9_-]+$/.test(n);
|
|
873
572
|
}
|
|
874
|
-
|
|
875
|
-
constructor(t, e) {
|
|
876
|
-
this.dispatchChange = t, this.dispatchSubmit = e;
|
|
877
|
-
}
|
|
878
|
-
dispatchChange;
|
|
879
|
-
dispatchSubmit;
|
|
880
|
-
pricing;
|
|
881
|
-
selection = {};
|
|
882
|
-
resolved;
|
|
883
|
-
changeCallbacks = [];
|
|
884
|
-
renderCallbacks = [];
|
|
885
|
-
submitCallback;
|
|
886
|
-
submitDefaultLabel;
|
|
887
|
-
/** The resolved configuration, or undefined when nothing matches. */
|
|
888
|
-
get current() {
|
|
889
|
-
return this.resolved;
|
|
890
|
-
}
|
|
891
|
-
/** The VAT label for bare embeds (e.g. "incl. btw"), or undefined without pricing. */
|
|
892
|
-
get vatDisplay() {
|
|
893
|
-
return this.pricing?.vatDisplay;
|
|
894
|
-
}
|
|
895
|
-
/**
|
|
896
|
-
* The CTA label: the customer's `button_label`, or the adapter's `defaultLabel`
|
|
897
|
-
* when that is empty. Undefined when neither is set — a button must know what
|
|
898
|
-
* it says, so the CTA does not render.
|
|
899
|
-
*/
|
|
900
|
-
get buttonLabel() {
|
|
901
|
-
const t = this.pricing?.buttonLabel;
|
|
902
|
-
if (t != null && t !== "")
|
|
903
|
-
return t;
|
|
904
|
-
if (this.submitDefaultLabel !== void 0 && this.submitDefaultLabel !== "")
|
|
905
|
-
return this.submitDefaultLabel;
|
|
906
|
-
}
|
|
907
|
-
/**
|
|
908
|
-
* Whether the current configuration may be submitted: a handler is registered
|
|
909
|
-
* and the configuration is either price-less or an `available` priced one. The
|
|
910
|
-
* CTA's visibility ({@link submitEnabled}) layers a label requirement on top of
|
|
911
|
-
* this; a programmatic `submit()` does not need a label.
|
|
912
|
-
*/
|
|
913
|
-
get submittable() {
|
|
914
|
-
return this.submitCallback === void 0 ? !1 : this.pricing === void 0 ? !0 : this.resolved?.availability === "available";
|
|
915
|
-
}
|
|
916
|
-
/**
|
|
917
|
-
* Whether the CTA should render: the configuration is submittable and a label
|
|
918
|
-
* exists. A button must say something, so an empty label hides the CTA rather
|
|
919
|
-
* than rendering blank.
|
|
920
|
-
*/
|
|
921
|
-
get submitEnabled() {
|
|
922
|
-
return this.submittable && this.buttonLabel !== void 0;
|
|
923
|
-
}
|
|
924
|
-
/**
|
|
925
|
-
* Subscribe to configuration changes. Fires after every selection change with
|
|
926
|
-
* the resolved configuration, including undefined when nothing matches.
|
|
927
|
-
*/
|
|
928
|
-
onChange(t) {
|
|
929
|
-
this.changeCallbacks.push(t);
|
|
930
|
-
}
|
|
931
|
-
/**
|
|
932
|
-
* Register the submit handler the CTA hands the configuration to. Registering
|
|
933
|
-
* one is what switches the button on (capability driven). `defaultLabel` fills
|
|
934
|
-
* in when the customer authored no button label.
|
|
935
|
-
*/
|
|
936
|
-
onSubmit(t, e) {
|
|
937
|
-
this.submitCallback = t, this.submitDefaultLabel = e?.defaultLabel, this.notifyRender();
|
|
938
|
-
}
|
|
939
|
-
/**
|
|
940
|
-
* Subscribe the built-in UI to re-render the price + CTA. Fires on every
|
|
941
|
-
* resolve and when a submit handler is registered (which can switch the button
|
|
942
|
-
* on without a configuration change). Separate from `onChange`, which stays the
|
|
943
|
-
* host-facing, mutation-driven contract. Returns a disposer.
|
|
944
|
-
*/
|
|
945
|
-
onRender(t) {
|
|
946
|
-
return this.renderCallbacks.push(t), () => {
|
|
947
|
-
const e = this.renderCallbacks.indexOf(t);
|
|
948
|
-
e !== -1 && this.renderCallbacks.splice(e, 1);
|
|
949
|
-
};
|
|
950
|
-
}
|
|
951
|
-
/**
|
|
952
|
-
* Hand the current configuration to the registered handler and fire the
|
|
953
|
-
* bubbling `vd:configuration-submit` event. No-op without a handler or a
|
|
954
|
-
* resolved configuration. Returns the handler's promise so the caller can
|
|
955
|
-
* reflect the result (bezig / gelukt / mislukt).
|
|
956
|
-
*/
|
|
957
|
-
async submit() {
|
|
958
|
-
if (!this.submittable)
|
|
959
|
-
return;
|
|
960
|
-
const t = this.resolved !== void 0 ? { attributes: this.resolved.attributes, reference: this.resolved.reference } : { attributes: { ...this.selection }, reference: "" };
|
|
961
|
-
this.dispatchSubmit(t), await this.submitCallback?.(t);
|
|
962
|
-
}
|
|
963
|
-
/** Called by the client when a PRICING message arrives from the viewer. */
|
|
964
|
-
handlePricingReceived(t) {
|
|
965
|
-
this.pricing = t, this.recompute();
|
|
966
|
-
}
|
|
967
|
-
/** Called by the client after every mutation result, with the full selection. */
|
|
968
|
-
handleSelectionChanged(t) {
|
|
969
|
-
this.selection = t, this.recompute();
|
|
970
|
-
}
|
|
971
|
-
recompute() {
|
|
972
|
-
this.resolved = this.resolve();
|
|
973
|
-
for (const t of this.changeCallbacks)
|
|
974
|
-
t(this.resolved);
|
|
975
|
-
this.dispatchChange(this.resolved), this.notifyRender();
|
|
976
|
-
}
|
|
977
|
-
notifyRender() {
|
|
978
|
-
for (const t of this.renderCallbacks)
|
|
979
|
-
t();
|
|
980
|
-
}
|
|
981
|
-
resolve() {
|
|
982
|
-
if (this.pricing === void 0)
|
|
983
|
-
return;
|
|
984
|
-
const t = ae(this.pricing.rules, this.selection);
|
|
985
|
-
if (!(t === void 0 || t.availability === Vt.HIDDEN))
|
|
986
|
-
return {
|
|
987
|
-
attributes: { ...this.selection },
|
|
988
|
-
reference: t.reference,
|
|
989
|
-
price: t.priceCents,
|
|
990
|
-
currency: this.pricing.currency,
|
|
991
|
-
availability: t.availability
|
|
992
|
-
};
|
|
993
|
-
}
|
|
994
|
-
}
|
|
995
|
-
class ue {
|
|
996
|
-
constructor(t) {
|
|
997
|
-
this.filename = t;
|
|
998
|
-
}
|
|
999
|
-
filename;
|
|
1000
|
-
developedCallbacks = /* @__PURE__ */ new Set();
|
|
1001
|
-
errorCallbacks = /* @__PURE__ */ new Set();
|
|
1002
|
-
developed = !1;
|
|
1003
|
-
failed = !1;
|
|
1004
|
-
photoData = null;
|
|
1005
|
-
/**
|
|
1006
|
-
* Register a callback for when the photo is developed
|
|
1007
|
-
* If the photo is already developed, the callback is called immediately
|
|
1008
|
-
*
|
|
1009
|
-
* @param callback Function to call with photo data
|
|
1010
|
-
* @returns This Photo instance for chaining
|
|
1011
|
-
*/
|
|
1012
|
-
onDeveloped(t) {
|
|
1013
|
-
return this.developed && this.photoData !== null ? (t(this.photoData), this) : (this.developedCallbacks.add(t), this);
|
|
1014
|
-
}
|
|
1015
|
-
/**
|
|
1016
|
-
* Register a callback for when the photo capture fails
|
|
1017
|
-
*
|
|
1018
|
-
* @param callback Function to call with error
|
|
1019
|
-
* @returns This Photo instance for chaining
|
|
1020
|
-
*/
|
|
1021
|
-
onError(t) {
|
|
1022
|
-
return this.errorCallbacks.add(t), this;
|
|
1023
|
-
}
|
|
1024
|
-
/**
|
|
1025
|
-
* Get the filename for this photo
|
|
1026
|
-
*/
|
|
1027
|
-
getFilename() {
|
|
1028
|
-
return this.filename;
|
|
1029
|
-
}
|
|
1030
|
-
/**
|
|
1031
|
-
* Mark the photo as developed and notify all callbacks
|
|
1032
|
-
* This method is called by Snapshot when the photo data arrives from the server
|
|
1033
|
-
*/
|
|
1034
|
-
develop(t) {
|
|
1035
|
-
this.developed || this.failed || (this.photoData = t, this.developed = !0, this.developedCallbacks.forEach((e) => {
|
|
1036
|
-
e(this.photoData);
|
|
1037
|
-
}), this.developedCallbacks.clear(), this.errorCallbacks.clear());
|
|
1038
|
-
}
|
|
1039
|
-
/**
|
|
1040
|
-
* Mark the photo as failed and notify error callbacks
|
|
1041
|
-
*/
|
|
1042
|
-
fail(t) {
|
|
1043
|
-
this.developed || this.failed || (this.failed = !0, this.errorCallbacks.forEach((e) => {
|
|
1044
|
-
e(t);
|
|
1045
|
-
}), this.developedCallbacks.clear(), this.errorCallbacks.clear());
|
|
1046
|
-
}
|
|
1047
|
-
}
|
|
1048
|
-
const J = 3e4;
|
|
1049
|
-
class de {
|
|
1050
|
-
constructor(t) {
|
|
1051
|
-
this.send = t;
|
|
1052
|
-
}
|
|
1053
|
-
send;
|
|
1054
|
-
validExtensions = [".png"];
|
|
1055
|
-
pendingPhotos = /* @__PURE__ */ new Map();
|
|
1056
|
-
/**
|
|
1057
|
-
* Take a snapshot of the current 3D model view
|
|
1058
|
-
*
|
|
1059
|
-
* @param filename The filename for the snapshot (must include valid extension)
|
|
1060
|
-
* @returns Photo object for registering callbacks
|
|
1061
|
-
* @throws VirtualdisplayError if filename is invalid
|
|
1062
|
-
*/
|
|
1063
|
-
take(t) {
|
|
1064
|
-
this.validateFilename(t), C.debug("Taking snapshot", { filename: t });
|
|
1065
|
-
const e = new ue(t), i = setTimeout(() => {
|
|
1066
|
-
this.pendingPhotos.delete(t), C.warn("Snapshot timed out", { filename: t }), e.fail(new f(
|
|
1067
|
-
`Snapshot timed out: the viewer did not respond within ${J}ms`,
|
|
1068
|
-
A.SNAPSHOT_FAILED
|
|
1069
|
-
));
|
|
1070
|
-
}, J);
|
|
1071
|
-
return this.pendingPhotos.set(t, { photo: e, timeout: i }), this.send({
|
|
1072
|
-
type: c.SNAPSHOT,
|
|
1073
|
-
filename: t
|
|
1074
|
-
}), e;
|
|
1075
|
-
}
|
|
1076
|
-
/**
|
|
1077
|
-
* Handle incoming snapshot result from server
|
|
1078
|
-
* Matches the message to a pending photo by filename, then develops or fails it
|
|
1079
|
-
*/
|
|
1080
|
-
handleSnapshotResult(t) {
|
|
1081
|
-
const e = this.pendingPhotos.get(t.filename);
|
|
1082
|
-
if (e === void 0) {
|
|
1083
|
-
C.warn("No pending photo found for filename", {
|
|
1084
|
-
filename: t.filename,
|
|
1085
|
-
pendingFilenames: Array.from(this.pendingPhotos.keys())
|
|
1086
|
-
});
|
|
1087
|
-
return;
|
|
1088
|
-
}
|
|
1089
|
-
clearTimeout(e.timeout), this.pendingPhotos.delete(t.filename);
|
|
1090
|
-
const { photo: i } = e;
|
|
1091
|
-
if (t.error !== void 0) {
|
|
1092
|
-
i.fail(new f(t.error, A.SNAPSHOT_FAILED));
|
|
1093
|
-
return;
|
|
1094
|
-
}
|
|
1095
|
-
t.data !== void 0 && i.develop({ filename: t.filename, data: t.data });
|
|
1096
|
-
}
|
|
1097
|
-
/**
|
|
1098
|
-
* Fail any pending photos and forget them. Called from client destroy
|
|
1099
|
-
* so callers awaiting onError() see a deterministic outcome instead of
|
|
1100
|
-
* leaking captures whose results will never arrive.
|
|
1101
|
-
*/
|
|
1102
|
-
clear() {
|
|
1103
|
-
if (this.pendingPhotos.size === 0)
|
|
1104
|
-
return;
|
|
1105
|
-
const t = new f(
|
|
1106
|
-
"Client destroyed before snapshot completed",
|
|
1107
|
-
A.SNAPSHOT_FAILED
|
|
1108
|
-
);
|
|
1109
|
-
for (const { photo: e, timeout: i } of this.pendingPhotos.values())
|
|
1110
|
-
clearTimeout(i), e.fail(t);
|
|
1111
|
-
this.pendingPhotos.clear();
|
|
1112
|
-
}
|
|
1113
|
-
/**
|
|
1114
|
-
* Validate filename has a valid image extension
|
|
1115
|
-
*/
|
|
1116
|
-
validateFilename(t) {
|
|
1117
|
-
if (t === "" || typeof t != "string")
|
|
1118
|
-
throw new f(
|
|
1119
|
-
"Filename must be a non-empty string",
|
|
1120
|
-
A.INVALID_PARAMETER
|
|
1121
|
-
);
|
|
1122
|
-
if (!this.validExtensions.some(
|
|
1123
|
-
(i) => t.toLowerCase().endsWith(i)
|
|
1124
|
-
))
|
|
1125
|
-
throw new f(
|
|
1126
|
-
`Invalid filename: "${t}". Filename must end with one of: ${this.validExtensions.join(", ")}`,
|
|
1127
|
-
A.INVALID_PARAMETER
|
|
1128
|
-
);
|
|
1129
|
-
if (t.includes("..") || t.includes("/") || t.includes("\\"))
|
|
1130
|
-
throw new f(
|
|
1131
|
-
'Filename cannot contain path separators or ".."',
|
|
1132
|
-
A.INVALID_PARAMETER
|
|
1133
|
-
);
|
|
1134
|
-
}
|
|
1135
|
-
}
|
|
1136
|
-
class he {
|
|
1137
|
-
container = null;
|
|
1138
|
-
attach(t) {
|
|
1139
|
-
this.container = t;
|
|
1140
|
-
}
|
|
1141
|
-
dispatch(t, e, i = !1) {
|
|
1142
|
-
const o = new CustomEvent(t, { detail: e, cancelable: i });
|
|
1143
|
-
return this.container?.dispatchEvent(o), o;
|
|
1144
|
-
}
|
|
1145
|
-
on(t, e) {
|
|
1146
|
-
const i = (o) => {
|
|
1147
|
-
const s = o, r = { ...s.detail, preventDefault: () => {
|
|
1148
|
-
s.preventDefault();
|
|
1149
|
-
} };
|
|
1150
|
-
e(r);
|
|
1151
|
-
};
|
|
1152
|
-
return this.container?.addEventListener(t, i), () => {
|
|
1153
|
-
this.container?.removeEventListener(t, i);
|
|
1154
|
-
};
|
|
1155
|
-
}
|
|
1156
|
-
}
|
|
1157
|
-
const me = {}, pe = "en", pt = (
|
|
1158
|
-
/** @type {const} */
|
|
1159
|
-
["en", "nl", "de"]
|
|
1160
|
-
), W = [
|
|
1161
|
-
"baseLocale"
|
|
1162
|
-
], tt = [];
|
|
1163
|
-
let et, nt;
|
|
1164
|
-
function fe(n) {
|
|
1165
|
-
if (tt.length === 0)
|
|
1166
|
-
return;
|
|
1167
|
-
const t = typeof n == "string" ? n : n.href;
|
|
1168
|
-
if (et === t)
|
|
1169
|
-
return nt;
|
|
1170
|
-
const e = new URL(t, "http://dummy.com");
|
|
1171
|
-
let i;
|
|
1172
|
-
for (const o of tt)
|
|
1173
|
-
if (new me(o.match, e.href).exec(e.href)) {
|
|
1174
|
-
i = o;
|
|
1175
|
-
break;
|
|
1176
|
-
}
|
|
1177
|
-
return et = t, nt = i, i;
|
|
1178
|
-
}
|
|
1179
|
-
function ft(n) {
|
|
1180
|
-
const t = fe(n);
|
|
1181
|
-
return t && t.exclude !== !0 && Array.isArray(t.strategy) ? t.strategy : W;
|
|
1182
|
-
}
|
|
1183
|
-
const q = typeof window > "u";
|
|
1184
|
-
globalThis.__paraglide = /** @type {any} */
|
|
1185
|
-
globalThis.__paraglide ?? {};
|
|
1186
|
-
globalThis.__paraglide.ssr = /** @type {any} */
|
|
1187
|
-
globalThis.__paraglide.ssr ?? {};
|
|
1188
|
-
let it = !1, h = () => {
|
|
1189
|
-
let n = W;
|
|
1190
|
-
!q && typeof window < "u" && window.location?.href && (n = ft(window.location.href));
|
|
1191
|
-
const t = ge(n);
|
|
1192
|
-
if (t)
|
|
1193
|
-
return it || (it = !0, gt(t, { reload: !1 })), t;
|
|
1194
|
-
throw new Error("No locale found. Read the docs https://paraglidejs.com/errors#no-locale-found");
|
|
1195
|
-
};
|
|
1196
|
-
function ge(n, t) {
|
|
1197
|
-
let e;
|
|
1198
|
-
for (const i of n) {
|
|
1199
|
-
if (i === "baseLocale")
|
|
1200
|
-
e = pe;
|
|
1201
|
-
else if (vt(i) && I.has(i)) {
|
|
1202
|
-
const s = I.get(i);
|
|
1203
|
-
if (s) {
|
|
1204
|
-
const r = s.getLocale();
|
|
1205
|
-
if (r instanceof Promise)
|
|
1206
|
-
continue;
|
|
1207
|
-
if (r !== void 0)
|
|
1208
|
-
return ve(r);
|
|
1209
|
-
}
|
|
1210
|
-
}
|
|
1211
|
-
const o = bt(e);
|
|
1212
|
-
if (o)
|
|
1213
|
-
return o;
|
|
1214
|
-
}
|
|
1215
|
-
}
|
|
1216
|
-
const be = (n) => {
|
|
1217
|
-
window.location.reload();
|
|
1218
|
-
};
|
|
1219
|
-
let gt = (n, t) => {
|
|
1220
|
-
const e = {
|
|
1221
|
-
reload: !0,
|
|
1222
|
-
...t
|
|
1223
|
-
};
|
|
1224
|
-
let i;
|
|
1225
|
-
try {
|
|
1226
|
-
i = h();
|
|
1227
|
-
} catch {
|
|
1228
|
-
}
|
|
1229
|
-
const o = [];
|
|
1230
|
-
let s = W;
|
|
1231
|
-
!q && typeof window < "u" && window.location?.href && (s = ft(window.location.href));
|
|
1232
|
-
for (const l of s)
|
|
1233
|
-
if (l !== "baseLocale" && vt(l) && I.has(l)) {
|
|
1234
|
-
const d = I.get(l);
|
|
1235
|
-
if (d) {
|
|
1236
|
-
let u = d.setLocale(n);
|
|
1237
|
-
u instanceof Promise && (u = u.catch((p) => {
|
|
1238
|
-
throw new Error(`Custom strategy "${l}" setLocale failed.`, {
|
|
1239
|
-
cause: p
|
|
1240
|
-
});
|
|
1241
|
-
}), o.push(u));
|
|
1242
|
-
}
|
|
1243
|
-
}
|
|
1244
|
-
const r = () => {
|
|
1245
|
-
!q && e.reload && window.location && n !== i && be();
|
|
1246
|
-
};
|
|
1247
|
-
if (o.length)
|
|
1248
|
-
return Promise.all(o).then(() => {
|
|
1249
|
-
r();
|
|
1250
|
-
});
|
|
1251
|
-
r();
|
|
1252
|
-
};
|
|
1253
|
-
function bt(n) {
|
|
1254
|
-
if (typeof n != "string")
|
|
1255
|
-
return;
|
|
1256
|
-
const t = n.toLowerCase();
|
|
1257
|
-
for (const e of pt)
|
|
1258
|
-
if (e.toLowerCase() === t)
|
|
1259
|
-
return e;
|
|
1260
|
-
}
|
|
1261
|
-
function ve(n) {
|
|
1262
|
-
const t = bt(n);
|
|
1263
|
-
if (t)
|
|
1264
|
-
return t;
|
|
1265
|
-
throw new Error(`Invalid locale: ${n}. Expected one of: ${pt.join(", ")}`);
|
|
1266
|
-
}
|
|
1267
|
-
const I = /* @__PURE__ */ new Map();
|
|
1268
|
-
function vt(n) {
|
|
1269
|
-
return typeof n == "string" && /^custom-[A-Za-z0-9_-]+$/.test(n);
|
|
1270
|
-
}
|
|
1271
|
-
const ye = (
|
|
573
|
+
const ae = (
|
|
1272
574
|
/** @type {(inputs: Controls_Ar_Buttonlabel1Inputs) => LocalizedString} */
|
|
1273
575
|
() => (
|
|
1274
576
|
/** @type {LocalizedString} */
|
|
1275
577
|
"Activate AR"
|
|
1276
578
|
)
|
|
1277
|
-
),
|
|
579
|
+
), le = (
|
|
1278
580
|
/** @type {(inputs: Controls_Ar_Buttonlabel1Inputs) => LocalizedString} */
|
|
1279
581
|
() => (
|
|
1280
582
|
/** @type {LocalizedString} */
|
|
1281
583
|
"AR activeren"
|
|
1282
584
|
)
|
|
1283
|
-
),
|
|
585
|
+
), ce = (
|
|
1284
586
|
/** @type {(inputs: Controls_Ar_Buttonlabel1Inputs) => LocalizedString} */
|
|
1285
587
|
() => (
|
|
1286
588
|
/** @type {LocalizedString} */
|
|
1287
589
|
"AR aktivieren"
|
|
1288
590
|
)
|
|
1289
|
-
),
|
|
591
|
+
), ue = (
|
|
1290
592
|
/** @type {((inputs?: Controls_Ar_Buttonlabel1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Ar_Buttonlabel1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
|
|
1291
593
|
((n = {}, t = {}) => {
|
|
1292
594
|
const e = t.locale ?? h();
|
|
1293
|
-
return e === "en" ?
|
|
595
|
+
return e === "en" ? ae() : e === "nl" ? le() : ce();
|
|
1294
596
|
})
|
|
1295
|
-
),
|
|
597
|
+
), de = (
|
|
1296
598
|
/** @type {(inputs: Controls_Qr_Modaltitle1Inputs) => LocalizedString} */
|
|
1297
599
|
() => (
|
|
1298
600
|
/** @type {LocalizedString} */
|
|
1299
601
|
"Scan to view in AR"
|
|
1300
602
|
)
|
|
1301
|
-
),
|
|
603
|
+
), he = (
|
|
1302
604
|
/** @type {(inputs: Controls_Qr_Modaltitle1Inputs) => LocalizedString} */
|
|
1303
605
|
() => (
|
|
1304
606
|
/** @type {LocalizedString} */
|
|
1305
607
|
"Scan om in AR te bekijken"
|
|
1306
608
|
)
|
|
1307
|
-
),
|
|
609
|
+
), me = (
|
|
1308
610
|
/** @type {(inputs: Controls_Qr_Modaltitle1Inputs) => LocalizedString} */
|
|
1309
611
|
() => (
|
|
1310
612
|
/** @type {LocalizedString} */
|
|
1311
613
|
"Scannen für AR-Ansicht"
|
|
1312
614
|
)
|
|
1313
|
-
),
|
|
615
|
+
), pe = (
|
|
1314
616
|
/** @type {((inputs?: Controls_Qr_Modaltitle1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Qr_Modaltitle1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
|
|
1315
617
|
((n = {}, t = {}) => {
|
|
1316
618
|
const e = t.locale ?? h();
|
|
1317
|
-
return e === "en" ?
|
|
619
|
+
return e === "en" ? de() : e === "nl" ? he() : me();
|
|
1318
620
|
})
|
|
1319
|
-
),
|
|
621
|
+
), fe = (
|
|
1320
622
|
/** @type {(inputs: Controls_Qr_Modaldescription1Inputs) => LocalizedString} */
|
|
1321
623
|
() => (
|
|
1322
624
|
/** @type {LocalizedString} */
|
|
1323
625
|
"Use your smartphone camera to scan this QR code"
|
|
1324
626
|
)
|
|
1325
|
-
),
|
|
627
|
+
), ge = (
|
|
1326
628
|
/** @type {(inputs: Controls_Qr_Modaldescription1Inputs) => LocalizedString} */
|
|
1327
629
|
() => (
|
|
1328
630
|
/** @type {LocalizedString} */
|
|
1329
631
|
"Gebruik de camera van je smartphone om deze QR-code te scannen"
|
|
1330
632
|
)
|
|
1331
|
-
),
|
|
633
|
+
), be = (
|
|
1332
634
|
/** @type {(inputs: Controls_Qr_Modaldescription1Inputs) => LocalizedString} */
|
|
1333
635
|
() => (
|
|
1334
636
|
/** @type {LocalizedString} */
|
|
1335
637
|
"Verwende die Kamera deines Smartphones, um diesen QR-Code zu scannen"
|
|
1336
638
|
)
|
|
1337
|
-
),
|
|
639
|
+
), ve = (
|
|
1338
640
|
/** @type {((inputs?: Controls_Qr_Modaldescription1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Qr_Modaldescription1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
|
|
1339
641
|
((n = {}, t = {}) => {
|
|
1340
642
|
const e = t.locale ?? h();
|
|
1341
|
-
return e === "en" ?
|
|
643
|
+
return e === "en" ? fe() : e === "nl" ? ge() : be();
|
|
1342
644
|
})
|
|
1343
|
-
),
|
|
645
|
+
), ye = (
|
|
1344
646
|
/** @type {(inputs: Controls_Qr_Modalinstructions1Inputs) => LocalizedString} */
|
|
1345
647
|
() => (
|
|
1346
648
|
/** @type {LocalizedString} */
|
|
1347
649
|
"Your phone will open the 3D model in AR mode."
|
|
1348
650
|
)
|
|
1349
|
-
),
|
|
651
|
+
), _e = (
|
|
1350
652
|
/** @type {(inputs: Controls_Qr_Modalinstructions1Inputs) => LocalizedString} */
|
|
1351
653
|
() => (
|
|
1352
654
|
/** @type {LocalizedString} */
|
|
1353
655
|
"Je telefoon opent het 3D-model in AR-modus."
|
|
1354
656
|
)
|
|
1355
|
-
),
|
|
657
|
+
), we = (
|
|
1356
658
|
/** @type {(inputs: Controls_Qr_Modalinstructions1Inputs) => LocalizedString} */
|
|
1357
659
|
() => (
|
|
1358
660
|
/** @type {LocalizedString} */
|
|
1359
661
|
"Dein Telefon öffnet das 3D-Modell im AR-Modus."
|
|
1360
662
|
)
|
|
1361
|
-
),
|
|
663
|
+
), Ce = (
|
|
1362
664
|
/** @type {((inputs?: Controls_Qr_Modalinstructions1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Qr_Modalinstructions1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
|
|
1363
665
|
((n = {}, t = {}) => {
|
|
1364
666
|
const e = t.locale ?? h();
|
|
1365
|
-
return e === "en" ?
|
|
667
|
+
return e === "en" ? ye() : e === "nl" ? _e() : we();
|
|
1366
668
|
})
|
|
1367
|
-
),
|
|
669
|
+
), ke = (
|
|
1368
670
|
/** @type {(inputs: Controls_Qr_Closebutton1Inputs) => LocalizedString} */
|
|
1369
671
|
() => (
|
|
1370
672
|
/** @type {LocalizedString} */
|
|
1371
673
|
"Close"
|
|
1372
674
|
)
|
|
1373
|
-
),
|
|
675
|
+
), Se = (
|
|
1374
676
|
/** @type {(inputs: Controls_Qr_Closebutton1Inputs) => LocalizedString} */
|
|
1375
677
|
() => (
|
|
1376
678
|
/** @type {LocalizedString} */
|
|
1377
679
|
"Sluiten"
|
|
1378
680
|
)
|
|
1379
|
-
),
|
|
681
|
+
), Ee = (
|
|
1380
682
|
/** @type {(inputs: Controls_Qr_Closebutton1Inputs) => LocalizedString} */
|
|
1381
683
|
() => (
|
|
1382
684
|
/** @type {LocalizedString} */
|
|
1383
685
|
"Schließen"
|
|
1384
686
|
)
|
|
1385
|
-
),
|
|
687
|
+
), Ae = (
|
|
1386
688
|
/** @type {((inputs?: Controls_Qr_Closebutton1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Qr_Closebutton1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
|
|
1387
689
|
((n = {}, t = {}) => {
|
|
1388
690
|
const e = t.locale ?? h();
|
|
1389
|
-
return e === "en" ?
|
|
691
|
+
return e === "en" ? ke() : e === "nl" ? Se() : Ee();
|
|
1390
692
|
})
|
|
1391
|
-
),
|
|
693
|
+
), xe = (
|
|
1392
694
|
/** @type {(inputs: Controls_Fullscreen_Buttonlabel1Inputs) => LocalizedString} */
|
|
1393
695
|
() => (
|
|
1394
696
|
/** @type {LocalizedString} */
|
|
1395
697
|
"Fullscreen"
|
|
1396
698
|
)
|
|
1397
|
-
),
|
|
699
|
+
), Te = (
|
|
1398
700
|
/** @type {(inputs: Controls_Fullscreen_Buttonlabel1Inputs) => LocalizedString} */
|
|
1399
701
|
() => (
|
|
1400
702
|
/** @type {LocalizedString} */
|
|
1401
703
|
"Volledig scherm"
|
|
1402
704
|
)
|
|
1403
|
-
),
|
|
705
|
+
), Re = (
|
|
1404
706
|
/** @type {(inputs: Controls_Fullscreen_Buttonlabel1Inputs) => LocalizedString} */
|
|
1405
707
|
() => (
|
|
1406
708
|
/** @type {LocalizedString} */
|
|
1407
709
|
"Vollbild"
|
|
1408
710
|
)
|
|
1409
|
-
),
|
|
711
|
+
), Ie = (
|
|
1410
712
|
/** @type {((inputs?: Controls_Fullscreen_Buttonlabel1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Fullscreen_Buttonlabel1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
|
|
1411
713
|
((n = {}, t = {}) => {
|
|
1412
714
|
const e = t.locale ?? h();
|
|
1413
|
-
return e === "en" ?
|
|
715
|
+
return e === "en" ? xe() : e === "nl" ? Te() : Re();
|
|
1414
716
|
})
|
|
1415
|
-
),
|
|
717
|
+
), Oe = (
|
|
1416
718
|
/** @type {(inputs: Loading_Downloadingshort1Inputs) => LocalizedString} */
|
|
1417
719
|
() => (
|
|
1418
720
|
/** @type {LocalizedString} */
|
|
1419
721
|
"Downloading"
|
|
1420
722
|
)
|
|
1421
|
-
),
|
|
723
|
+
), Ne = (
|
|
1422
724
|
/** @type {(inputs: Loading_Downloadingshort1Inputs) => LocalizedString} */
|
|
1423
725
|
() => (
|
|
1424
726
|
/** @type {LocalizedString} */
|
|
1425
727
|
"Downloaden"
|
|
1426
728
|
)
|
|
1427
|
-
),
|
|
729
|
+
), Le = (
|
|
1428
730
|
/** @type {(inputs: Loading_Downloadingshort1Inputs) => LocalizedString} */
|
|
1429
731
|
() => (
|
|
1430
732
|
/** @type {LocalizedString} */
|
|
1431
733
|
"Herunterladen"
|
|
1432
734
|
)
|
|
1433
|
-
),
|
|
735
|
+
), gt = (
|
|
1434
736
|
/** @type {((inputs?: Loading_Downloadingshort1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Loading_Downloadingshort1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
|
|
1435
737
|
((n = {}, t = {}) => {
|
|
1436
738
|
const e = t.locale ?? h();
|
|
1437
|
-
return e === "en" ?
|
|
739
|
+
return e === "en" ? Oe() : e === "nl" ? Ne() : Le();
|
|
1438
740
|
})
|
|
1439
|
-
),
|
|
741
|
+
), Me = (
|
|
1440
742
|
/** @type {(inputs: Loading_RenderingInputs) => LocalizedString} */
|
|
1441
743
|
() => (
|
|
1442
744
|
/** @type {LocalizedString} */
|
|
1443
745
|
"Rendering"
|
|
1444
746
|
)
|
|
1445
|
-
),
|
|
747
|
+
), ze = (
|
|
1446
748
|
/** @type {(inputs: Loading_RenderingInputs) => LocalizedString} */
|
|
1447
749
|
() => (
|
|
1448
750
|
/** @type {LocalizedString} */
|
|
1449
751
|
"Renderen"
|
|
1450
752
|
)
|
|
1451
|
-
),
|
|
753
|
+
), Fe = (
|
|
1452
754
|
/** @type {(inputs: Loading_RenderingInputs) => LocalizedString} */
|
|
1453
755
|
() => (
|
|
1454
756
|
/** @type {LocalizedString} */
|
|
1455
757
|
"Rendern"
|
|
1456
758
|
)
|
|
1457
|
-
),
|
|
759
|
+
), Pe = (
|
|
1458
760
|
/** @type {((inputs?: Loading_RenderingInputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Loading_RenderingInputs, { locale?: "en" | "nl" | "de" }, {}>} */
|
|
1459
761
|
((n = {}, t = {}) => {
|
|
1460
762
|
const e = t.locale ?? h();
|
|
1461
|
-
return e === "en" ?
|
|
763
|
+
return e === "en" ? Me() : e === "nl" ? ze() : Fe();
|
|
1462
764
|
})
|
|
1463
|
-
),
|
|
765
|
+
), $e = (
|
|
1464
766
|
/** @type {(inputs: Controls_Screenshot_Buttonlabel1Inputs) => LocalizedString} */
|
|
1465
767
|
() => (
|
|
1466
768
|
/** @type {LocalizedString} */
|
|
1467
769
|
"Screenshot"
|
|
1468
770
|
)
|
|
1469
|
-
),
|
|
771
|
+
), De = (
|
|
1470
772
|
/** @type {(inputs: Controls_Screenshot_Buttonlabel1Inputs) => LocalizedString} */
|
|
1471
773
|
() => (
|
|
1472
774
|
/** @type {LocalizedString} */
|
|
1473
775
|
"Screenshot"
|
|
1474
776
|
)
|
|
1475
|
-
),
|
|
777
|
+
), Be = (
|
|
1476
778
|
/** @type {(inputs: Controls_Screenshot_Buttonlabel1Inputs) => LocalizedString} */
|
|
1477
779
|
() => (
|
|
1478
780
|
/** @type {LocalizedString} */
|
|
1479
781
|
"Screenshot"
|
|
1480
782
|
)
|
|
1481
|
-
),
|
|
783
|
+
), Ue = (
|
|
1482
784
|
/** @type {((inputs?: Controls_Screenshot_Buttonlabel1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Screenshot_Buttonlabel1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
|
|
1483
785
|
((n = {}, t = {}) => {
|
|
1484
786
|
const e = t.locale ?? h();
|
|
1485
|
-
return e === "en" ?
|
|
787
|
+
return e === "en" ? $e() : e === "nl" ? De() : Be();
|
|
1486
788
|
})
|
|
1487
|
-
),
|
|
789
|
+
), Ve = (
|
|
1488
790
|
/** @type {(inputs: Controls_Configurator_OpenInputs) => LocalizedString} */
|
|
1489
791
|
() => (
|
|
1490
792
|
/** @type {LocalizedString} */
|
|
1491
793
|
"Configure"
|
|
1492
794
|
)
|
|
1493
|
-
),
|
|
795
|
+
), je = (
|
|
1494
796
|
/** @type {(inputs: Controls_Configurator_OpenInputs) => LocalizedString} */
|
|
1495
797
|
() => (
|
|
1496
798
|
/** @type {LocalizedString} */
|
|
1497
799
|
"Configureren"
|
|
1498
800
|
)
|
|
1499
|
-
),
|
|
801
|
+
), He = (
|
|
1500
802
|
/** @type {(inputs: Controls_Configurator_OpenInputs) => LocalizedString} */
|
|
1501
803
|
() => (
|
|
1502
804
|
/** @type {LocalizedString} */
|
|
1503
805
|
"Konfigurieren"
|
|
1504
806
|
)
|
|
1505
|
-
),
|
|
807
|
+
), Ge = (
|
|
1506
808
|
/** @type {((inputs?: Controls_Configurator_OpenInputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Configurator_OpenInputs, { locale?: "en" | "nl" | "de" }, {}>} */
|
|
1507
809
|
((n = {}, t = {}) => {
|
|
1508
810
|
const e = t.locale ?? h();
|
|
1509
|
-
return e === "en" ?
|
|
811
|
+
return e === "en" ? Ve() : e === "nl" ? je() : He();
|
|
1510
812
|
})
|
|
1511
|
-
),
|
|
813
|
+
), qe = (
|
|
1512
814
|
/** @type {(inputs: Controls_Configurator_CloseInputs) => LocalizedString} */
|
|
1513
815
|
() => (
|
|
1514
816
|
/** @type {LocalizedString} */
|
|
1515
817
|
"Close"
|
|
1516
818
|
)
|
|
1517
|
-
),
|
|
819
|
+
), Ze = (
|
|
1518
820
|
/** @type {(inputs: Controls_Configurator_CloseInputs) => LocalizedString} */
|
|
1519
821
|
() => (
|
|
1520
822
|
/** @type {LocalizedString} */
|
|
1521
823
|
"Sluiten"
|
|
1522
824
|
)
|
|
1523
|
-
),
|
|
825
|
+
), We = (
|
|
1524
826
|
/** @type {(inputs: Controls_Configurator_CloseInputs) => LocalizedString} */
|
|
1525
827
|
() => (
|
|
1526
828
|
/** @type {LocalizedString} */
|
|
1527
829
|
"Schließen"
|
|
1528
830
|
)
|
|
1529
|
-
),
|
|
831
|
+
), Ye = (
|
|
1530
832
|
/** @type {((inputs?: Controls_Configurator_CloseInputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Configurator_CloseInputs, { locale?: "en" | "nl" | "de" }, {}>} */
|
|
1531
833
|
((n = {}, t = {}) => {
|
|
1532
834
|
const e = t.locale ?? h();
|
|
1533
|
-
return e === "en" ?
|
|
835
|
+
return e === "en" ? qe() : e === "nl" ? Ze() : We();
|
|
1534
836
|
})
|
|
1535
|
-
),
|
|
837
|
+
), Xe = (
|
|
1536
838
|
/** @type {(inputs: Controls_Camera_ResetInputs) => LocalizedString} */
|
|
1537
839
|
() => (
|
|
1538
840
|
/** @type {LocalizedString} */
|
|
1539
841
|
"Reset camera"
|
|
1540
842
|
)
|
|
1541
|
-
),
|
|
843
|
+
), Ke = (
|
|
1542
844
|
/** @type {(inputs: Controls_Camera_ResetInputs) => LocalizedString} */
|
|
1543
845
|
() => (
|
|
1544
846
|
/** @type {LocalizedString} */
|
|
1545
847
|
"Camera resetten"
|
|
1546
848
|
)
|
|
1547
|
-
),
|
|
849
|
+
), Qe = (
|
|
1548
850
|
/** @type {(inputs: Controls_Camera_ResetInputs) => LocalizedString} */
|
|
1549
851
|
() => (
|
|
1550
852
|
/** @type {LocalizedString} */
|
|
1551
853
|
"Kamera zurücksetzen"
|
|
1552
854
|
)
|
|
1553
|
-
),
|
|
855
|
+
), Je = (
|
|
1554
856
|
/** @type {((inputs?: Controls_Camera_ResetInputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Camera_ResetInputs, { locale?: "en" | "nl" | "de" }, {}>} */
|
|
1555
857
|
((n = {}, t = {}) => {
|
|
1556
858
|
const e = t.locale ?? h();
|
|
1557
|
-
return e === "en" ?
|
|
859
|
+
return e === "en" ? Xe() : e === "nl" ? Ke() : Qe();
|
|
1558
860
|
})
|
|
1559
|
-
),
|
|
861
|
+
), tn = (
|
|
1560
862
|
/** @type {(inputs: Controls_Camera_Zoomin1Inputs) => LocalizedString} */
|
|
1561
863
|
() => (
|
|
1562
864
|
/** @type {LocalizedString} */
|
|
1563
865
|
"Zoom in"
|
|
1564
866
|
)
|
|
1565
|
-
),
|
|
867
|
+
), en = (
|
|
1566
868
|
/** @type {(inputs: Controls_Camera_Zoomin1Inputs) => LocalizedString} */
|
|
1567
869
|
() => (
|
|
1568
870
|
/** @type {LocalizedString} */
|
|
1569
871
|
"Inzoomen"
|
|
1570
872
|
)
|
|
1571
|
-
),
|
|
873
|
+
), nn = (
|
|
1572
874
|
/** @type {(inputs: Controls_Camera_Zoomin1Inputs) => LocalizedString} */
|
|
1573
875
|
() => (
|
|
1574
876
|
/** @type {LocalizedString} */
|
|
1575
877
|
"Hineinzoomen"
|
|
1576
878
|
)
|
|
1577
|
-
),
|
|
879
|
+
), on = (
|
|
1578
880
|
/** @type {((inputs?: Controls_Camera_Zoomin1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Camera_Zoomin1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
|
|
1579
881
|
((n = {}, t = {}) => {
|
|
1580
882
|
const e = t.locale ?? h();
|
|
1581
|
-
return e === "en" ?
|
|
883
|
+
return e === "en" ? tn() : e === "nl" ? en() : nn();
|
|
1582
884
|
})
|
|
1583
|
-
),
|
|
885
|
+
), sn = (
|
|
1584
886
|
/** @type {(inputs: Controls_Camera_Zoomout1Inputs) => LocalizedString} */
|
|
1585
887
|
() => (
|
|
1586
888
|
/** @type {LocalizedString} */
|
|
1587
889
|
"Zoom out"
|
|
1588
890
|
)
|
|
1589
|
-
),
|
|
891
|
+
), rn = (
|
|
1590
892
|
/** @type {(inputs: Controls_Camera_Zoomout1Inputs) => LocalizedString} */
|
|
1591
893
|
() => (
|
|
1592
894
|
/** @type {LocalizedString} */
|
|
1593
895
|
"Uitzoomen"
|
|
1594
896
|
)
|
|
1595
|
-
),
|
|
897
|
+
), an = (
|
|
1596
898
|
/** @type {(inputs: Controls_Camera_Zoomout1Inputs) => LocalizedString} */
|
|
1597
899
|
() => (
|
|
1598
900
|
/** @type {LocalizedString} */
|
|
1599
901
|
"Herauszoomen"
|
|
1600
902
|
)
|
|
1601
|
-
),
|
|
903
|
+
), ln = (
|
|
1602
904
|
/** @type {((inputs?: Controls_Camera_Zoomout1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Camera_Zoomout1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
|
|
1603
905
|
((n = {}, t = {}) => {
|
|
1604
906
|
const e = t.locale ?? h();
|
|
1605
|
-
return e === "en" ?
|
|
907
|
+
return e === "en" ? sn() : e === "nl" ? rn() : an();
|
|
1606
908
|
})
|
|
1607
|
-
),
|
|
909
|
+
), cn = (
|
|
1608
910
|
/** @type {(inputs: Controls_Camera_Rotateleft1Inputs) => LocalizedString} */
|
|
1609
911
|
() => (
|
|
1610
912
|
/** @type {LocalizedString} */
|
|
1611
913
|
"Rotate left"
|
|
1612
914
|
)
|
|
1613
|
-
),
|
|
915
|
+
), un = (
|
|
1614
916
|
/** @type {(inputs: Controls_Camera_Rotateleft1Inputs) => LocalizedString} */
|
|
1615
917
|
() => (
|
|
1616
918
|
/** @type {LocalizedString} */
|
|
1617
919
|
"Naar links draaien"
|
|
1618
920
|
)
|
|
1619
|
-
),
|
|
921
|
+
), dn = (
|
|
1620
922
|
/** @type {(inputs: Controls_Camera_Rotateleft1Inputs) => LocalizedString} */
|
|
1621
923
|
() => (
|
|
1622
924
|
/** @type {LocalizedString} */
|
|
1623
925
|
"Nach links drehen"
|
|
1624
926
|
)
|
|
1625
|
-
),
|
|
927
|
+
), hn = (
|
|
1626
928
|
/** @type {((inputs?: Controls_Camera_Rotateleft1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Camera_Rotateleft1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
|
|
1627
929
|
((n = {}, t = {}) => {
|
|
1628
930
|
const e = t.locale ?? h();
|
|
1629
|
-
return e === "en" ?
|
|
931
|
+
return e === "en" ? cn() : e === "nl" ? un() : dn();
|
|
1630
932
|
})
|
|
1631
|
-
),
|
|
933
|
+
), mn = (
|
|
1632
934
|
/** @type {(inputs: Controls_Camera_Rotateright1Inputs) => LocalizedString} */
|
|
1633
935
|
() => (
|
|
1634
936
|
/** @type {LocalizedString} */
|
|
1635
937
|
"Rotate right"
|
|
1636
938
|
)
|
|
1637
|
-
),
|
|
939
|
+
), pn = (
|
|
1638
940
|
/** @type {(inputs: Controls_Camera_Rotateright1Inputs) => LocalizedString} */
|
|
1639
941
|
() => (
|
|
1640
942
|
/** @type {LocalizedString} */
|
|
1641
943
|
"Naar rechts draaien"
|
|
1642
944
|
)
|
|
1643
|
-
),
|
|
945
|
+
), fn = (
|
|
1644
946
|
/** @type {(inputs: Controls_Camera_Rotateright1Inputs) => LocalizedString} */
|
|
1645
947
|
() => (
|
|
1646
948
|
/** @type {LocalizedString} */
|
|
1647
949
|
"Nach rechts drehen"
|
|
1648
950
|
)
|
|
1649
|
-
),
|
|
951
|
+
), gn = (
|
|
1650
952
|
/** @type {((inputs?: Controls_Camera_Rotateright1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Camera_Rotateright1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
|
|
1651
953
|
((n = {}, t = {}) => {
|
|
1652
954
|
const e = t.locale ?? h();
|
|
1653
|
-
return e === "en" ?
|
|
955
|
+
return e === "en" ? mn() : e === "nl" ? pn() : fn();
|
|
1654
956
|
})
|
|
1655
|
-
),
|
|
957
|
+
), bn = (
|
|
1656
958
|
/** @type {(inputs: Controls_Camera_Tiltup1Inputs) => LocalizedString} */
|
|
1657
959
|
() => (
|
|
1658
960
|
/** @type {LocalizedString} */
|
|
1659
961
|
"Tilt up"
|
|
1660
962
|
)
|
|
1661
|
-
),
|
|
963
|
+
), vn = (
|
|
1662
964
|
/** @type {(inputs: Controls_Camera_Tiltup1Inputs) => LocalizedString} */
|
|
1663
965
|
() => (
|
|
1664
966
|
/** @type {LocalizedString} */
|
|
1665
967
|
"Omhoog kantelen"
|
|
1666
968
|
)
|
|
1667
|
-
),
|
|
969
|
+
), yn = (
|
|
1668
970
|
/** @type {(inputs: Controls_Camera_Tiltup1Inputs) => LocalizedString} */
|
|
1669
971
|
() => (
|
|
1670
972
|
/** @type {LocalizedString} */
|
|
1671
973
|
"Nach oben kippen"
|
|
1672
974
|
)
|
|
1673
|
-
),
|
|
975
|
+
), _n = (
|
|
1674
976
|
/** @type {((inputs?: Controls_Camera_Tiltup1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Camera_Tiltup1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
|
|
1675
977
|
((n = {}, t = {}) => {
|
|
1676
978
|
const e = t.locale ?? h();
|
|
1677
|
-
return e === "en" ?
|
|
979
|
+
return e === "en" ? bn() : e === "nl" ? vn() : yn();
|
|
1678
980
|
})
|
|
1679
|
-
),
|
|
981
|
+
), wn = (
|
|
1680
982
|
/** @type {(inputs: Controls_Camera_Tiltdown1Inputs) => LocalizedString} */
|
|
1681
983
|
() => (
|
|
1682
984
|
/** @type {LocalizedString} */
|
|
1683
985
|
"Tilt down"
|
|
1684
986
|
)
|
|
1685
|
-
),
|
|
987
|
+
), Cn = (
|
|
1686
988
|
/** @type {(inputs: Controls_Camera_Tiltdown1Inputs) => LocalizedString} */
|
|
1687
989
|
() => (
|
|
1688
990
|
/** @type {LocalizedString} */
|
|
1689
991
|
"Omlaag kantelen"
|
|
1690
992
|
)
|
|
1691
|
-
),
|
|
993
|
+
), kn = (
|
|
1692
994
|
/** @type {(inputs: Controls_Camera_Tiltdown1Inputs) => LocalizedString} */
|
|
1693
995
|
() => (
|
|
1694
996
|
/** @type {LocalizedString} */
|
|
1695
997
|
"Nach unten kippen"
|
|
1696
998
|
)
|
|
1697
|
-
),
|
|
999
|
+
), Sn = (
|
|
1698
1000
|
/** @type {((inputs?: Controls_Camera_Tiltdown1Inputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Controls_Camera_Tiltdown1Inputs, { locale?: "en" | "nl" | "de" }, {}>} */
|
|
1699
1001
|
((n = {}, t = {}) => {
|
|
1700
1002
|
const e = t.locale ?? h();
|
|
1701
|
-
return e === "en" ?
|
|
1003
|
+
return e === "en" ? wn() : e === "nl" ? Cn() : kn();
|
|
1702
1004
|
})
|
|
1703
|
-
),
|
|
1005
|
+
), En = (
|
|
1704
1006
|
/** @type {(inputs: Commerce_Submit_BusyInputs) => LocalizedString} */
|
|
1705
1007
|
() => (
|
|
1706
1008
|
/** @type {LocalizedString} */
|
|
1707
1009
|
"Working…"
|
|
1708
1010
|
)
|
|
1709
|
-
),
|
|
1011
|
+
), An = (
|
|
1710
1012
|
/** @type {(inputs: Commerce_Submit_BusyInputs) => LocalizedString} */
|
|
1711
1013
|
() => (
|
|
1712
1014
|
/** @type {LocalizedString} */
|
|
1713
1015
|
"Bezig…"
|
|
1714
1016
|
)
|
|
1715
|
-
),
|
|
1017
|
+
), xn = (
|
|
1716
1018
|
/** @type {(inputs: Commerce_Submit_BusyInputs) => LocalizedString} */
|
|
1717
1019
|
() => (
|
|
1718
1020
|
/** @type {LocalizedString} */
|
|
1719
1021
|
"Läuft…"
|
|
1720
1022
|
)
|
|
1721
|
-
),
|
|
1023
|
+
), Tn = (
|
|
1722
1024
|
/** @type {((inputs?: Commerce_Submit_BusyInputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Commerce_Submit_BusyInputs, { locale?: "en" | "nl" | "de" }, {}>} */
|
|
1723
1025
|
((n = {}, t = {}) => {
|
|
1724
1026
|
const e = t.locale ?? h();
|
|
1725
|
-
return e === "en" ?
|
|
1027
|
+
return e === "en" ? En() : e === "nl" ? An() : xn();
|
|
1726
1028
|
})
|
|
1727
|
-
),
|
|
1029
|
+
), Rn = (
|
|
1728
1030
|
/** @type {(inputs: Commerce_Submit_SuccessInputs) => LocalizedString} */
|
|
1729
1031
|
() => (
|
|
1730
1032
|
/** @type {LocalizedString} */
|
|
1731
1033
|
"Done"
|
|
1732
1034
|
)
|
|
1733
|
-
),
|
|
1035
|
+
), In = (
|
|
1734
1036
|
/** @type {(inputs: Commerce_Submit_SuccessInputs) => LocalizedString} */
|
|
1735
1037
|
() => (
|
|
1736
1038
|
/** @type {LocalizedString} */
|
|
1737
1039
|
"Gelukt"
|
|
1738
1040
|
)
|
|
1739
|
-
),
|
|
1041
|
+
), On = (
|
|
1740
1042
|
/** @type {(inputs: Commerce_Submit_SuccessInputs) => LocalizedString} */
|
|
1741
1043
|
() => (
|
|
1742
1044
|
/** @type {LocalizedString} */
|
|
1743
1045
|
"Fertig"
|
|
1744
1046
|
)
|
|
1745
|
-
),
|
|
1047
|
+
), Nn = (
|
|
1746
1048
|
/** @type {((inputs?: Commerce_Submit_SuccessInputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Commerce_Submit_SuccessInputs, { locale?: "en" | "nl" | "de" }, {}>} */
|
|
1747
1049
|
((n = {}, t = {}) => {
|
|
1748
1050
|
const e = t.locale ?? h();
|
|
1749
|
-
return e === "en" ?
|
|
1051
|
+
return e === "en" ? Rn() : e === "nl" ? In() : On();
|
|
1750
1052
|
})
|
|
1751
|
-
),
|
|
1053
|
+
), Ln = (
|
|
1752
1054
|
/** @type {(inputs: Commerce_Submit_FailedInputs) => LocalizedString} */
|
|
1753
1055
|
() => (
|
|
1754
1056
|
/** @type {LocalizedString} */
|
|
1755
1057
|
"Failed"
|
|
1756
1058
|
)
|
|
1757
|
-
),
|
|
1059
|
+
), Mn = (
|
|
1758
1060
|
/** @type {(inputs: Commerce_Submit_FailedInputs) => LocalizedString} */
|
|
1759
1061
|
() => (
|
|
1760
1062
|
/** @type {LocalizedString} */
|
|
1761
1063
|
"Mislukt"
|
|
1762
1064
|
)
|
|
1763
|
-
),
|
|
1065
|
+
), zn = (
|
|
1764
1066
|
/** @type {(inputs: Commerce_Submit_FailedInputs) => LocalizedString} */
|
|
1765
1067
|
() => (
|
|
1766
1068
|
/** @type {LocalizedString} */
|
|
1767
1069
|
"Fehlgeschlagen"
|
|
1768
1070
|
)
|
|
1769
|
-
),
|
|
1071
|
+
), Fn = (
|
|
1770
1072
|
/** @type {((inputs?: Commerce_Submit_FailedInputs, options?: { locale?: "en" | "nl" | "de" }) => LocalizedString) & import('../runtime.js').MessageMetadata<Commerce_Submit_FailedInputs, { locale?: "en" | "nl" | "de" }, {}>} */
|
|
1771
1073
|
((n = {}, t = {}) => {
|
|
1772
1074
|
const e = t.locale ?? h();
|
|
1773
|
-
return e === "en" ?
|
|
1075
|
+
return e === "en" ? Ln() : e === "nl" ? Mn() : zn();
|
|
1774
1076
|
})
|
|
1775
|
-
)
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
}
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
const
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
const ni = [
|
|
1832
|
-
["path", { d: "m14 10 7-7" }],
|
|
1833
|
-
["path", { d: "M20 10h-6V4" }],
|
|
1834
|
-
["path", { d: "m3 21 7-7" }],
|
|
1835
|
-
["path", { d: "M4 14h6v6" }]
|
|
1836
|
-
];
|
|
1837
|
-
const ii = [
|
|
1838
|
-
["path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }],
|
|
1839
|
-
["path", { d: "M3 3v5h5" }]
|
|
1840
|
-
];
|
|
1841
|
-
const oi = [
|
|
1842
|
-
["path", { d: "M10 5H3" }],
|
|
1843
|
-
["path", { d: "M12 19H3" }],
|
|
1844
|
-
["path", { d: "M14 3v4" }],
|
|
1845
|
-
["path", { d: "M16 17v4" }],
|
|
1846
|
-
["path", { d: "M21 12h-9" }],
|
|
1847
|
-
["path", { d: "M21 19h-5" }],
|
|
1848
|
-
["path", { d: "M21 5h-7" }],
|
|
1849
|
-
["path", { d: "M8 10v4" }],
|
|
1850
|
-
["path", { d: "M8 12H3" }]
|
|
1851
|
-
];
|
|
1852
|
-
const si = [
|
|
1853
|
-
["path", { d: "M18 6 6 18" }],
|
|
1854
|
-
["path", { d: "m6 6 12 12" }]
|
|
1855
|
-
];
|
|
1856
|
-
const ri = [
|
|
1857
|
-
["circle", { cx: "11", cy: "11", r: "8" }],
|
|
1858
|
-
["line", { x1: "21", x2: "16.65", y1: "21", y2: "16.65" }],
|
|
1859
|
-
["line", { x1: "11", x2: "11", y1: "8", y2: "14" }],
|
|
1860
|
-
["line", { x1: "8", x2: "14", y1: "11", y2: "11" }]
|
|
1861
|
-
];
|
|
1862
|
-
const ai = [
|
|
1863
|
-
["circle", { cx: "11", cy: "11", r: "8" }],
|
|
1864
|
-
["line", { x1: "21", x2: "16.65", y1: "21", y2: "16.65" }],
|
|
1865
|
-
["line", { x1: "8", x2: "14", y1: "11", y2: "11" }]
|
|
1866
|
-
];
|
|
1867
|
-
function y(n, { size: t = 20, strokeWidth: e = 1.75 } = {}) {
|
|
1868
|
-
return Ct(n, { width: t, height: t, "stroke-width": e });
|
|
1869
|
-
}
|
|
1870
|
-
const g = {
|
|
1871
|
-
ar: (n) => y(Xn, n),
|
|
1872
|
-
fullscreen: (n) => y(ei, n),
|
|
1873
|
-
exitFullscreen: (n) => y(ni, n),
|
|
1874
|
-
screenshot: (n) => y(Kn, n),
|
|
1875
|
-
tiltUp: (n) => y(ti, n),
|
|
1876
|
-
tiltDown: (n) => y(wt, n),
|
|
1877
|
-
rotateLeft: (n) => y(Qn, n),
|
|
1878
|
-
rotateRight: (n) => y(Jn, n),
|
|
1879
|
-
zoomIn: (n) => y(ri, n),
|
|
1880
|
-
zoomOut: (n) => y(ai, n),
|
|
1881
|
-
reset: (n) => y(ii, n),
|
|
1882
|
-
configurator: (n) => y(oi, n),
|
|
1883
|
-
close: (n) => y(si, n)
|
|
1884
|
-
};
|
|
1885
|
-
class b {
|
|
1886
|
-
element;
|
|
1887
|
-
constructor({ variant: t = "default", size: e = "default", label: i, icon: o, onClick: s, disabled: r = !1 } = {}) {
|
|
1888
|
-
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;
|
|
1077
|
+
), _ = {
|
|
1078
|
+
fontFamily: {
|
|
1079
|
+
sans: ["Mona Sans", "ui-sans-serif", "system-ui", "sans-serif", "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"]
|
|
1080
|
+
},
|
|
1081
|
+
fontSize: {
|
|
1082
|
+
xs: "0.75rem",
|
|
1083
|
+
// 12px
|
|
1084
|
+
sm: "0.875rem",
|
|
1085
|
+
// 14px
|
|
1086
|
+
base: "1rem",
|
|
1087
|
+
// 16px
|
|
1088
|
+
lg: "1.125rem"
|
|
1089
|
+
},
|
|
1090
|
+
fontWeight: {
|
|
1091
|
+
medium: "500",
|
|
1092
|
+
semibold: "600"
|
|
1093
|
+
}
|
|
1094
|
+
}, Pn = _.fontFamily.sans.join(", ");
|
|
1095
|
+
class $n {
|
|
1096
|
+
qrLib = null;
|
|
1097
|
+
dialog = null;
|
|
1098
|
+
async show(t) {
|
|
1099
|
+
this.hide(), this.qrLib ??= await import("./browser-ey6Iih3j.js").then((o) => o.b);
|
|
1100
|
+
const e = await this.qrLib.toDataURL(t, {
|
|
1101
|
+
width: 256,
|
|
1102
|
+
margin: 4,
|
|
1103
|
+
errorCorrectionLevel: "M",
|
|
1104
|
+
color: { dark: m.black, light: m.white }
|
|
1105
|
+
});
|
|
1106
|
+
this.dialog = new Qt({ onClose: () => {
|
|
1107
|
+
this.dialog = null;
|
|
1108
|
+
} }), Object.assign(this.dialog.card.element.style, {
|
|
1109
|
+
display: "flex",
|
|
1110
|
+
flexDirection: "column",
|
|
1111
|
+
alignItems: "center",
|
|
1112
|
+
gap: a[3],
|
|
1113
|
+
fontFamily: Pn
|
|
1114
|
+
}), this.dialog.card.element.appendChild(this.createText(pe(), {
|
|
1115
|
+
fontSize: _.fontSize.base,
|
|
1116
|
+
fontWeight: _.fontWeight.semibold,
|
|
1117
|
+
color: m.neutral[900]
|
|
1118
|
+
})), this.dialog.card.element.appendChild(this.createText(ve(), {
|
|
1119
|
+
fontSize: _.fontSize.sm,
|
|
1120
|
+
color: m.neutral[600]
|
|
1121
|
+
})), this.dialog.card.element.appendChild(this.createQrImage(e)), this.dialog.card.element.appendChild(this.createText(Ce(), {
|
|
1122
|
+
fontSize: _.fontSize.xs,
|
|
1123
|
+
color: m.neutral[500]
|
|
1124
|
+
}));
|
|
1125
|
+
const i = new g({
|
|
1126
|
+
variant: "outline",
|
|
1127
|
+
label: Ae(),
|
|
1128
|
+
onClick: () => {
|
|
1129
|
+
this.hide();
|
|
1130
|
+
}
|
|
1131
|
+
});
|
|
1132
|
+
this.dialog.card.element.appendChild(i.element), this.dialog.open();
|
|
1889
1133
|
}
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1134
|
+
hide() {
|
|
1135
|
+
this.dialog?.close(), this.dialog = null;
|
|
1136
|
+
}
|
|
1137
|
+
createText(t, e) {
|
|
1138
|
+
const i = document.createElement("p");
|
|
1139
|
+
return i.textContent = t, Object.assign(i.style, { margin: "0", textAlign: "center", ...e }), i;
|
|
1140
|
+
}
|
|
1141
|
+
createQrImage(t) {
|
|
1142
|
+
const e = document.createElement("img");
|
|
1143
|
+
return e.src = t, e.alt = "QR code", Object.assign(e.style, {
|
|
1144
|
+
width: a[24],
|
|
1145
|
+
height: a[24],
|
|
1146
|
+
borderRadius: a[1]
|
|
1147
|
+
}), e;
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
const x = _.fontFamily.sans.join(", "), Dn = `
|
|
1151
|
+
--primary: oklch(5% 0 0);
|
|
1152
|
+
--primary-foreground: oklch(100% 0 0);
|
|
1153
|
+
--secondary: oklch(92% 0 0);
|
|
1154
|
+
--secondary-foreground: oklch(5% 0 0);
|
|
1155
|
+
--background: oklch(100% 0 0);
|
|
1156
|
+
--foreground: oklch(5% 0 0);
|
|
1157
|
+
--border: oklch(92% 0 0);
|
|
1158
|
+
--ring: oklch(44% 0 0);
|
|
1159
|
+
--radius: 0.625rem;
|
|
1160
|
+
--accent: oklch(92% 0 0);
|
|
1161
|
+
--accent-foreground: oklch(5% 0 0);
|
|
1162
|
+
--muted-foreground: oklch(44% 0 0);
|
|
1163
|
+
`, Bn = `
|
|
1164
|
+
:root { ${Dn} }
|
|
1165
|
+
|
|
1166
|
+
/* ── Button ──────────────────────────────────────────────── */
|
|
1167
|
+
.ui-btn {
|
|
1168
|
+
display: inline-flex;
|
|
1169
|
+
align-items: center;
|
|
1170
|
+
justify-content: center;
|
|
1171
|
+
gap: 0.5rem;
|
|
1172
|
+
border: 1px solid transparent;
|
|
1173
|
+
border-radius: var(--radius);
|
|
1174
|
+
font-family: ${x};
|
|
1175
|
+
font-size: 0.875rem;
|
|
1176
|
+
font-weight: 600;
|
|
1177
|
+
white-space: nowrap;
|
|
1178
|
+
cursor: pointer;
|
|
1179
|
+
transition: all 200ms;
|
|
1180
|
+
flex-shrink: 0;
|
|
1181
|
+
}
|
|
1182
|
+
.ui-btn:active { transform: scale(0.98); }
|
|
1183
|
+
.ui-btn:disabled { opacity: 0.5; pointer-events: none; }
|
|
1184
|
+
.ui-btn svg { inline-size: 1rem; block-size: 1rem; pointer-events: none; flex-shrink: 0; }
|
|
1185
|
+
|
|
1186
|
+
.ui-btn--default {
|
|
1187
|
+
background: var(--primary);
|
|
1188
|
+
color: var(--primary-foreground);
|
|
1189
|
+
box-shadow: 0 1px 3px oklch(5% 0 0 / 20%);
|
|
1190
|
+
}
|
|
1191
|
+
.ui-btn--default:hover { background: oklch(10% 0 0); }
|
|
1192
|
+
|
|
1193
|
+
.ui-btn--outline {
|
|
1194
|
+
background: var(--background);
|
|
1195
|
+
color: var(--foreground);
|
|
1196
|
+
border-color: var(--border);
|
|
1197
|
+
box-shadow: 0 1px 2px oklch(5% 0 0 / 8%);
|
|
1198
|
+
}
|
|
1199
|
+
.ui-btn--outline:hover { background: var(--accent); border-color: oklch(85% 0 0); }
|
|
1200
|
+
|
|
1201
|
+
.ui-btn--secondary {
|
|
1202
|
+
background: var(--secondary);
|
|
1203
|
+
color: var(--secondary-foreground);
|
|
1204
|
+
box-shadow: 0 1px 2px oklch(5% 0 0 / 8%);
|
|
1205
|
+
}
|
|
1206
|
+
.ui-btn--secondary:hover { background: oklch(88% 0 0); }
|
|
1207
|
+
|
|
1208
|
+
.ui-btn--ghost { background: transparent; color: var(--foreground); }
|
|
1209
|
+
.ui-btn--ghost:hover { background: var(--accent); }
|
|
1210
|
+
|
|
1211
|
+
.ui-btn--size-default { block-size: 2.25rem; padding: 0 1rem; }
|
|
1212
|
+
.ui-btn--size-sm { block-size: 2rem; padding: 0 0.75rem; border-radius: calc(var(--radius) - 0.125rem); }
|
|
1213
|
+
.ui-btn--size-lg { block-size: 2.5rem; padding: 0 1.5rem; }
|
|
1214
|
+
.ui-btn--size-icon { inline-size: 2.25rem; block-size: 2.25rem; padding: 0; }
|
|
1215
|
+
.ui-btn--size-icon-sm { inline-size: 2rem; block-size: 2rem; padding: 0; }
|
|
1216
|
+
.ui-btn--size-icon-lg { inline-size: 2.5rem; block-size: 2.5rem; padding: 0; }
|
|
1217
|
+
|
|
1218
|
+
/* ── Toggle group ────────────────────────────────────────── */
|
|
1219
|
+
.ui-toggle-group { display: inline-flex; flex-wrap: wrap; gap: 0.25rem; }
|
|
1220
|
+
|
|
1221
|
+
.ui-toggle-group-item {
|
|
1222
|
+
display: inline-flex;
|
|
1223
|
+
align-items: center;
|
|
1224
|
+
justify-content: center;
|
|
1225
|
+
block-size: 2rem;
|
|
1226
|
+
padding: 0 0.75rem;
|
|
1227
|
+
border: 1px solid var(--border);
|
|
1228
|
+
border-radius: var(--radius);
|
|
1229
|
+
background: var(--background);
|
|
1230
|
+
color: var(--foreground);
|
|
1231
|
+
font-family: ${x};
|
|
1232
|
+
font-size: 0.875rem;
|
|
1233
|
+
font-weight: 600;
|
|
1234
|
+
cursor: pointer;
|
|
1235
|
+
white-space: nowrap;
|
|
1236
|
+
transition: all 200ms;
|
|
1237
|
+
box-shadow: 0 1px 2px oklch(5% 0 0 / 8%);
|
|
1238
|
+
}
|
|
1239
|
+
.ui-toggle-group-item:hover { background: var(--accent); border-color: oklch(85% 0 0); }
|
|
1240
|
+
.ui-toggle-group-item:active { transform: scale(0.98); }
|
|
1241
|
+
.ui-toggle-group-item:focus-visible {
|
|
1242
|
+
outline: none;
|
|
1243
|
+
border-color: var(--ring);
|
|
1244
|
+
box-shadow: 0 0 0 3px oklch(5% 0 0 / 12%);
|
|
1245
|
+
}
|
|
1246
|
+
.ui-toggle-group-item[data-state="on"] {
|
|
1247
|
+
background: var(--primary);
|
|
1248
|
+
color: var(--primary-foreground);
|
|
1249
|
+
border-color: var(--primary);
|
|
1250
|
+
}
|
|
1251
|
+
.ui-toggle-group-item[data-state="on"]:hover { background: oklch(10% 0 0); }
|
|
1252
|
+
|
|
1253
|
+
/* ── Native select ───────────────────────────────────────── */
|
|
1254
|
+
.ui-native-select-wrap {
|
|
1255
|
+
position: relative;
|
|
1256
|
+
display: inline-flex;
|
|
1257
|
+
min-inline-size: 8rem;
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
.ui-native-select {
|
|
1261
|
+
display: block;
|
|
1262
|
+
inline-size: 100%;
|
|
1263
|
+
block-size: 2.25rem;
|
|
1264
|
+
padding: 0 2.25rem 0 0.75rem;
|
|
1265
|
+
border: 1px solid var(--border);
|
|
1266
|
+
border-radius: var(--radius);
|
|
1267
|
+
background: var(--background);
|
|
1268
|
+
appearance: none;
|
|
1269
|
+
color: var(--foreground);
|
|
1270
|
+
font-family: ${x};
|
|
1271
|
+
font-size: 0.875rem;
|
|
1272
|
+
font-weight: 400;
|
|
1273
|
+
cursor: pointer;
|
|
1274
|
+
transition: color 200ms, box-shadow 200ms, border-color 200ms;
|
|
1275
|
+
box-shadow: 0 1px 2px oklch(5% 0 0 / 8%);
|
|
1276
|
+
}
|
|
1277
|
+
.ui-native-select:hover { border-color: oklch(85% 0 0); }
|
|
1278
|
+
.ui-native-select:focus-visible {
|
|
1279
|
+
outline: none;
|
|
1280
|
+
border-color: var(--ring);
|
|
1281
|
+
box-shadow: 0 0 0 3px oklch(5% 0 0 / 12%);
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
.ui-native-select-icon {
|
|
1285
|
+
position: absolute;
|
|
1286
|
+
inset-block-start: 50%;
|
|
1287
|
+
inset-inline-end: 0.625rem;
|
|
1288
|
+
transform: translateY(-50%);
|
|
1289
|
+
color: var(--muted-foreground);
|
|
1290
|
+
pointer-events: none;
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
/* ── Annotation layer ───────────────────────────────────── */
|
|
1294
|
+
.vd-annotations-layer {
|
|
1295
|
+
position: absolute;
|
|
1296
|
+
inset-block-start: 0;
|
|
1297
|
+
inset-inline-start: 0;
|
|
1298
|
+
inline-size: 100%;
|
|
1299
|
+
block-size: 100%;
|
|
1300
|
+
pointer-events: none;
|
|
1301
|
+
overflow: visible !important; /* override CSS2DRenderer inline style */
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
.vd-annotation-anchor {
|
|
1305
|
+
position: relative;
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
.vd-annotation-marker {
|
|
1309
|
+
display: flex;
|
|
1310
|
+
align-items: center;
|
|
1311
|
+
justify-content: center;
|
|
1312
|
+
inline-size: 1.75rem;
|
|
1313
|
+
block-size: 1.75rem;
|
|
1314
|
+
border-radius: 50%;
|
|
1315
|
+
border: 2px solid oklch(100% 0 0);
|
|
1316
|
+
background: var(--primary);
|
|
1317
|
+
color: var(--primary-foreground);
|
|
1318
|
+
font-family: ${x};
|
|
1319
|
+
font-size: 0.8125rem;
|
|
1320
|
+
font-weight: 600;
|
|
1321
|
+
cursor: pointer;
|
|
1322
|
+
pointer-events: auto;
|
|
1323
|
+
box-shadow: 0 2px 8px oklch(5% 0 0 / 20%);
|
|
1324
|
+
transition: transform 100ms ease;
|
|
1325
|
+
position: relative;
|
|
1326
|
+
}
|
|
1327
|
+
.vd-annotation-marker:hover { transform: scale(1.1); }
|
|
1328
|
+
.vd-annotation-marker:focus-visible {
|
|
1329
|
+
outline: 2px solid var(--ring);
|
|
1330
|
+
outline-offset: 2px;
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
.vd-annotation-popup {
|
|
1334
|
+
position: absolute;
|
|
1335
|
+
inset-block-end: calc(100% + 0.5rem);
|
|
1336
|
+
inset-inline-start: 50%;
|
|
1337
|
+
transform: translateX(-50%);
|
|
1338
|
+
background: var(--background);
|
|
1339
|
+
color: var(--foreground);
|
|
1340
|
+
border: 1px solid var(--border);
|
|
1341
|
+
border-radius: var(--radius);
|
|
1342
|
+
padding: 0.75rem 1rem;
|
|
1343
|
+
max-inline-size: 15rem;
|
|
1344
|
+
box-shadow: 0 4px 6px oklch(5% 0 0 / 8%), 0 2px 4px oklch(5% 0 0 / 6%);
|
|
1345
|
+
pointer-events: auto;
|
|
1346
|
+
white-space: normal;
|
|
1347
|
+
}
|
|
1348
|
+
.vd-annotation-popup:focus { outline: none; }
|
|
1349
|
+
|
|
1350
|
+
.vd-annotation-popup-close {
|
|
1351
|
+
position: absolute;
|
|
1352
|
+
inset-block-start: 0.375rem;
|
|
1353
|
+
inset-inline-end: 0.375rem;
|
|
1354
|
+
display: flex;
|
|
1355
|
+
align-items: center;
|
|
1356
|
+
justify-content: center;
|
|
1357
|
+
inline-size: 1.25rem;
|
|
1358
|
+
block-size: 1.25rem;
|
|
1359
|
+
padding: 0;
|
|
1360
|
+
border: none;
|
|
1361
|
+
border-radius: calc(var(--radius) - 4px);
|
|
1362
|
+
background: transparent;
|
|
1363
|
+
color: var(--muted-foreground);
|
|
1364
|
+
cursor: pointer;
|
|
1365
|
+
pointer-events: auto;
|
|
1366
|
+
}
|
|
1367
|
+
.vd-annotation-popup-close:hover {
|
|
1368
|
+
color: var(--foreground);
|
|
1369
|
+
background: var(--secondary);
|
|
1370
|
+
}
|
|
1371
|
+
.vd-annotation-popup-close:focus-visible {
|
|
1372
|
+
outline: 2px solid var(--ring);
|
|
1373
|
+
outline-offset: 1px;
|
|
1374
|
+
}
|
|
1375
|
+
.vd-annotation-popup-close svg {
|
|
1376
|
+
inline-size: 0.875rem;
|
|
1377
|
+
block-size: 0.875rem;
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
1381
|
+
.vd-annotation-popup {
|
|
1382
|
+
animation: vd-popup-in 150ms ease;
|
|
1893
1383
|
}
|
|
1894
1384
|
}
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1385
|
+
|
|
1386
|
+
@keyframes vd-popup-in {
|
|
1387
|
+
from { opacity: 0; transform: translateX(-50%) translateY(4px); }
|
|
1388
|
+
to { opacity: 1; transform: translateX(-50%) translateY(0); }
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
.vd-annotation-popup-title {
|
|
1392
|
+
font-family: ${x};
|
|
1393
|
+
font-size: 0.875rem;
|
|
1394
|
+
font-weight: 600;
|
|
1395
|
+
line-height: 1.25rem;
|
|
1396
|
+
/* Keep the title clear of the absolutely positioned close button. */
|
|
1397
|
+
padding-inline-end: 1.5rem;
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
.vd-annotation-popup-description {
|
|
1401
|
+
font-family: ${x};
|
|
1402
|
+
font-size: 0.8125rem;
|
|
1403
|
+
font-weight: 400;
|
|
1404
|
+
line-height: 1.125rem;
|
|
1405
|
+
color: var(--muted-foreground);
|
|
1406
|
+
margin-block-start: 0.25rem;
|
|
1407
|
+
}
|
|
1408
|
+
`;
|
|
1409
|
+
let et = !1;
|
|
1410
|
+
function Un() {
|
|
1411
|
+
if (et || typeof document > "u")
|
|
1412
|
+
return;
|
|
1413
|
+
et = !0;
|
|
1414
|
+
const n = document.createElement("style");
|
|
1415
|
+
n.id = "vd-ui-vanilla", n.textContent = Bn, document.head.appendChild(n);
|
|
1416
|
+
}
|
|
1417
|
+
function Vn() {
|
|
1418
|
+
return /* @__PURE__ */ new Date();
|
|
1419
|
+
}
|
|
1420
|
+
function jn(n) {
|
|
1421
|
+
return n.toISOString();
|
|
1422
|
+
}
|
|
1423
|
+
function bt() {
|
|
1424
|
+
return typeof navigator > "u" ? "" : navigator.userAgent;
|
|
1425
|
+
}
|
|
1426
|
+
function Hn() {
|
|
1427
|
+
return typeof navigator > "u" ? !1 : navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1;
|
|
1428
|
+
}
|
|
1429
|
+
function Gn() {
|
|
1430
|
+
return /iPhone|iPad|iPod/i.test(bt()) || Hn();
|
|
1431
|
+
}
|
|
1432
|
+
function qn() {
|
|
1433
|
+
return /Android/i.test(bt());
|
|
1434
|
+
}
|
|
1435
|
+
function Zn() {
|
|
1436
|
+
return Gn() || qn();
|
|
1437
|
+
}
|
|
1438
|
+
class Wn {
|
|
1439
|
+
constructor(t) {
|
|
1440
|
+
this.send = t;
|
|
1441
|
+
}
|
|
1442
|
+
send;
|
|
1443
|
+
setEnabled(t) {
|
|
1444
|
+
this.send({
|
|
1445
|
+
type: c.ANNOTATION_TOGGLE,
|
|
1446
|
+
enabled: t
|
|
1942
1447
|
});
|
|
1943
1448
|
}
|
|
1944
1449
|
}
|
|
1945
|
-
class
|
|
1946
|
-
constructor(t
|
|
1947
|
-
this.
|
|
1948
|
-
}
|
|
1949
|
-
options;
|
|
1950
|
-
card;
|
|
1951
|
-
backdrop;
|
|
1952
|
-
keyHandler = null;
|
|
1953
|
-
open() {
|
|
1954
|
-
document.body.appendChild(this.backdrop), this.keyHandler = (t) => {
|
|
1955
|
-
t.key === "Escape" && this.close();
|
|
1956
|
-
}, document.addEventListener("keydown", this.keyHandler);
|
|
1450
|
+
class Yn {
|
|
1451
|
+
constructor(t, e) {
|
|
1452
|
+
this.value = t, this.attribute = e;
|
|
1957
1453
|
}
|
|
1958
|
-
|
|
1959
|
-
|
|
1454
|
+
value;
|
|
1455
|
+
attribute;
|
|
1456
|
+
isSelectedValue = !1;
|
|
1457
|
+
get isSelected() {
|
|
1458
|
+
return this.isSelectedValue;
|
|
1960
1459
|
}
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
return Object.assign(t.style, {
|
|
1964
|
-
position: "fixed",
|
|
1965
|
-
inset: a[0],
|
|
1966
|
-
background: "oklch(0% 0 0 / 50%)",
|
|
1967
|
-
zIndex: "9999",
|
|
1968
|
-
display: "flex",
|
|
1969
|
-
alignItems: "center",
|
|
1970
|
-
justifyContent: "center"
|
|
1971
|
-
}), t.addEventListener("click", (e) => {
|
|
1972
|
-
e.target === t && this.close();
|
|
1973
|
-
}), t;
|
|
1460
|
+
setSelected(t) {
|
|
1461
|
+
this.isSelectedValue = t;
|
|
1974
1462
|
}
|
|
1975
1463
|
}
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1464
|
+
const E = {
|
|
1465
|
+
NO_MAPPING: "NO_MAPPING",
|
|
1466
|
+
ATTRIBUTE_NOT_FOUND: "ATTRIBUTE_NOT_FOUND",
|
|
1467
|
+
VALUE_NOT_FOUND: "VALUE_NOT_FOUND",
|
|
1468
|
+
PARENT_NOT_FOUND: "PARENT_NOT_FOUND",
|
|
1469
|
+
INVALID_PARAMETER: "INVALID_PARAMETER",
|
|
1470
|
+
SNAPSHOT_FAILED: "SNAPSHOT_FAILED"
|
|
1471
|
+
};
|
|
1472
|
+
class f extends Error {
|
|
1473
|
+
code;
|
|
1474
|
+
constructor(t, e) {
|
|
1475
|
+
super(t), this.name = "VirtualdisplayError", this.code = e;
|
|
1987
1476
|
}
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1477
|
+
static valueNotFound(t, e) {
|
|
1478
|
+
return new f(
|
|
1479
|
+
`Value "${e}" not found for attribute "${t}"`,
|
|
1480
|
+
E.VALUE_NOT_FOUND
|
|
1481
|
+
);
|
|
1993
1482
|
}
|
|
1994
|
-
|
|
1995
|
-
|
|
1483
|
+
static parentNotFound(t) {
|
|
1484
|
+
return new f(
|
|
1485
|
+
`Parent element not found: ${t}`,
|
|
1486
|
+
E.PARENT_NOT_FOUND
|
|
1487
|
+
);
|
|
1488
|
+
}
|
|
1489
|
+
static invalidParameter(t) {
|
|
1490
|
+
return new f(t, E.INVALID_PARAMETER);
|
|
1996
1491
|
}
|
|
1997
1492
|
}
|
|
1998
|
-
class
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
for (let u = 0; u < e.length; u++) {
|
|
2007
|
-
const p = e[u], v = document.createElement("option");
|
|
2008
|
-
v.value = p, v.textContent = s?.[u] ?? p, p === o && (v.selected = !0, l = !0), this.select.appendChild(v);
|
|
2009
|
-
}
|
|
2010
|
-
l || (r.selected = !0);
|
|
2011
|
-
const d = Ct(wt, { width: 16, height: 16, "stroke-width": 2 });
|
|
2012
|
-
d.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(d);
|
|
1493
|
+
class Xn {
|
|
1494
|
+
name;
|
|
1495
|
+
defaultValue;
|
|
1496
|
+
values;
|
|
1497
|
+
onSelect;
|
|
1498
|
+
onChangeCallback;
|
|
1499
|
+
constructor(t) {
|
|
1500
|
+
this.name = t.name, this.defaultValue = t.defaultValue, this.onSelect = t.onSelect, this.values = this.createValues(t.values);
|
|
2013
1501
|
}
|
|
2014
|
-
|
|
2015
|
-
|
|
1502
|
+
/**
|
|
1503
|
+
* Select a value for this attribute
|
|
1504
|
+
* @throws {VirtualdisplayError} When value not found
|
|
1505
|
+
*/
|
|
1506
|
+
select(t) {
|
|
1507
|
+
if (!this.values.has(t))
|
|
1508
|
+
throw f.valueNotFound(this.name, t);
|
|
1509
|
+
this.onSelect(this.name, t);
|
|
2016
1510
|
}
|
|
2017
|
-
|
|
2018
|
-
this.
|
|
2019
|
-
|
|
2020
|
-
|
|
1511
|
+
getValues() {
|
|
1512
|
+
return Array.from(this.values.values());
|
|
1513
|
+
}
|
|
1514
|
+
getValue(t) {
|
|
1515
|
+
return this.values.get(t);
|
|
1516
|
+
}
|
|
1517
|
+
/** The currently selected value, or undefined before any selection lands. */
|
|
1518
|
+
get selected() {
|
|
1519
|
+
for (const t of this.values.values())
|
|
1520
|
+
if (t.isSelected)
|
|
1521
|
+
return t.value;
|
|
1522
|
+
}
|
|
1523
|
+
/**
|
|
1524
|
+
* Register callback that fires when selection changes
|
|
1525
|
+
* Receives the newly selected AttributeValue
|
|
1526
|
+
*/
|
|
1527
|
+
onChange(t) {
|
|
1528
|
+
this.onChangeCallback = t;
|
|
1529
|
+
}
|
|
1530
|
+
/**
|
|
1531
|
+
* Update selection state from server mutation result
|
|
1532
|
+
* Direct value comparison - no source/target translation
|
|
1533
|
+
*/
|
|
1534
|
+
handleResult(t) {
|
|
1535
|
+
let e;
|
|
1536
|
+
for (const i of this.values.values()) {
|
|
1537
|
+
const o = i.value === t;
|
|
1538
|
+
i.setSelected(o), o && (e = i);
|
|
1539
|
+
}
|
|
1540
|
+
e !== void 0 && this.onChangeCallback !== void 0 && this.onChangeCallback(e);
|
|
1541
|
+
}
|
|
1542
|
+
createValues(t) {
|
|
1543
|
+
const e = /* @__PURE__ */ new Map();
|
|
1544
|
+
for (const i of t) {
|
|
1545
|
+
const o = new Yn(i, this.name);
|
|
1546
|
+
i === this.defaultValue && o.setSelected(!0), e.set(i, o);
|
|
1547
|
+
}
|
|
1548
|
+
return e;
|
|
2021
1549
|
}
|
|
2022
1550
|
}
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
// 14px
|
|
2032
|
-
base: "1rem",
|
|
2033
|
-
// 16px
|
|
2034
|
-
lg: "1.125rem"
|
|
2035
|
-
},
|
|
2036
|
-
fontWeight: {
|
|
2037
|
-
medium: "500",
|
|
2038
|
-
semibold: "600"
|
|
1551
|
+
class Kn {
|
|
1552
|
+
attributes = /* @__PURE__ */ new Map();
|
|
1553
|
+
constructor(t, e, i) {
|
|
1554
|
+
for (const o of t) {
|
|
1555
|
+
const s = this.buildOptions(o, e);
|
|
1556
|
+
this.attributes.set(o.name, new Xn(s));
|
|
1557
|
+
}
|
|
1558
|
+
this.onMutationFailed = i;
|
|
2039
1559
|
}
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
dialog = null;
|
|
2044
|
-
async show(t) {
|
|
2045
|
-
this.hide(), this.qrLib ??= await import("./browser-ey6Iih3j.js").then((o) => o.b);
|
|
2046
|
-
const e = await this.qrLib.toDataURL(t, {
|
|
2047
|
-
width: 256,
|
|
2048
|
-
margin: 4,
|
|
2049
|
-
errorCorrectionLevel: "M",
|
|
2050
|
-
color: { dark: m.black, light: m.white }
|
|
2051
|
-
});
|
|
2052
|
-
this.dialog = new ci({ onClose: () => {
|
|
2053
|
-
this.dialog = null;
|
|
2054
|
-
} }), Object.assign(this.dialog.card.element.style, {
|
|
2055
|
-
display: "flex",
|
|
2056
|
-
flexDirection: "column",
|
|
2057
|
-
alignItems: "center",
|
|
2058
|
-
gap: a[3],
|
|
2059
|
-
fontFamily: hi
|
|
2060
|
-
}), this.dialog.card.element.appendChild(this.createText(Ee(), {
|
|
2061
|
-
fontSize: _.fontSize.base,
|
|
2062
|
-
fontWeight: _.fontWeight.semibold,
|
|
2063
|
-
color: m.neutral[900]
|
|
2064
|
-
})), this.dialog.card.element.appendChild(this.createText(Oe(), {
|
|
2065
|
-
fontSize: _.fontSize.sm,
|
|
2066
|
-
color: m.neutral[600]
|
|
2067
|
-
})), this.dialog.card.element.appendChild(this.createQrImage(e)), this.dialog.card.element.appendChild(this.createText(Me(), {
|
|
2068
|
-
fontSize: _.fontSize.xs,
|
|
2069
|
-
color: m.neutral[500]
|
|
2070
|
-
}));
|
|
2071
|
-
const i = new b({
|
|
2072
|
-
variant: "outline",
|
|
2073
|
-
label: $e(),
|
|
2074
|
-
onClick: () => {
|
|
2075
|
-
this.hide();
|
|
2076
|
-
}
|
|
2077
|
-
});
|
|
2078
|
-
this.dialog.card.element.appendChild(i.element), this.dialog.open();
|
|
1560
|
+
onMutationFailed;
|
|
1561
|
+
get(t) {
|
|
1562
|
+
return this.attributes.get(t);
|
|
2079
1563
|
}
|
|
2080
|
-
|
|
2081
|
-
|
|
1564
|
+
/** The current selection as attribute name→value pairs, skipping unset attributes. */
|
|
1565
|
+
getSelection() {
|
|
1566
|
+
const t = {};
|
|
1567
|
+
for (const [e, i] of this.attributes) {
|
|
1568
|
+
const o = i.selected;
|
|
1569
|
+
o !== void 0 && (t[e] = o);
|
|
1570
|
+
}
|
|
1571
|
+
return t;
|
|
2082
1572
|
}
|
|
2083
|
-
|
|
2084
|
-
const
|
|
2085
|
-
|
|
1573
|
+
handleResults(t) {
|
|
1574
|
+
for (const e of t) {
|
|
1575
|
+
if (!e.success) {
|
|
1576
|
+
this.onMutationFailed?.(e.name, e.value);
|
|
1577
|
+
continue;
|
|
1578
|
+
}
|
|
1579
|
+
this.get(e.name)?.handleResult(e.value);
|
|
1580
|
+
}
|
|
2086
1581
|
}
|
|
2087
|
-
|
|
2088
|
-
const
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
1582
|
+
buildOptions(t, e) {
|
|
1583
|
+
const i = {
|
|
1584
|
+
name: t.name,
|
|
1585
|
+
values: t.values,
|
|
1586
|
+
onSelect: (o, s) => {
|
|
1587
|
+
e([{ name: o, value: s }], !1);
|
|
1588
|
+
}
|
|
1589
|
+
};
|
|
1590
|
+
return t.defaultValue !== void 0 ? { ...i, defaultValue: t.defaultValue } : i;
|
|
2094
1591
|
}
|
|
2095
1592
|
}
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
--secondary: oklch(92% 0 0);
|
|
2100
|
-
--secondary-foreground: oklch(5% 0 0);
|
|
2101
|
-
--background: oklch(100% 0 0);
|
|
2102
|
-
--foreground: oklch(5% 0 0);
|
|
2103
|
-
--border: oklch(92% 0 0);
|
|
2104
|
-
--ring: oklch(44% 0 0);
|
|
2105
|
-
--radius: 0.625rem;
|
|
2106
|
-
--accent: oklch(92% 0 0);
|
|
2107
|
-
--accent-foreground: oklch(5% 0 0);
|
|
2108
|
-
--muted-foreground: oklch(44% 0 0);
|
|
2109
|
-
`, fi = `
|
|
2110
|
-
:root { ${pi} }
|
|
2111
|
-
|
|
2112
|
-
/* ── Button ──────────────────────────────────────────────── */
|
|
2113
|
-
.ui-btn {
|
|
2114
|
-
display: inline-flex;
|
|
2115
|
-
align-items: center;
|
|
2116
|
-
justify-content: center;
|
|
2117
|
-
gap: 0.5rem;
|
|
2118
|
-
border: 1px solid transparent;
|
|
2119
|
-
border-radius: var(--radius);
|
|
2120
|
-
font-family: ${x};
|
|
2121
|
-
font-size: 0.875rem;
|
|
2122
|
-
font-weight: 600;
|
|
2123
|
-
white-space: nowrap;
|
|
2124
|
-
cursor: pointer;
|
|
2125
|
-
transition: all 200ms;
|
|
2126
|
-
flex-shrink: 0;
|
|
2127
|
-
}
|
|
2128
|
-
.ui-btn:active { transform: scale(0.98); }
|
|
2129
|
-
.ui-btn:disabled { opacity: 0.5; pointer-events: none; }
|
|
2130
|
-
.ui-btn svg { inline-size: 1rem; block-size: 1rem; pointer-events: none; flex-shrink: 0; }
|
|
2131
|
-
|
|
2132
|
-
.ui-btn--default {
|
|
2133
|
-
background: var(--primary);
|
|
2134
|
-
color: var(--primary-foreground);
|
|
2135
|
-
box-shadow: 0 1px 3px oklch(5% 0 0 / 20%);
|
|
2136
|
-
}
|
|
2137
|
-
.ui-btn--default:hover { background: oklch(10% 0 0); }
|
|
2138
|
-
|
|
2139
|
-
.ui-btn--outline {
|
|
2140
|
-
background: var(--background);
|
|
2141
|
-
color: var(--foreground);
|
|
2142
|
-
border-color: var(--border);
|
|
2143
|
-
box-shadow: 0 1px 2px oklch(5% 0 0 / 8%);
|
|
2144
|
-
}
|
|
2145
|
-
.ui-btn--outline:hover { background: var(--accent); border-color: oklch(85% 0 0); }
|
|
2146
|
-
|
|
2147
|
-
.ui-btn--secondary {
|
|
2148
|
-
background: var(--secondary);
|
|
2149
|
-
color: var(--secondary-foreground);
|
|
2150
|
-
box-shadow: 0 1px 2px oklch(5% 0 0 / 8%);
|
|
1593
|
+
function Qn(n) {
|
|
1594
|
+
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 = ["timestamp", "level", "msg", "service", "trace_id", "span_id"], r = Object.entries(n).filter(([l]) => !s.includes(l)).map(([l, d]) => `${l}=${JSON.stringify(d)}`).join(" ");
|
|
1595
|
+
return `${t} ${e} [${i}] ${o}${r ? " " + r : ""}`;
|
|
2151
1596
|
}
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
.ui-btn--ghost { background: transparent; color: var(--foreground); }
|
|
2155
|
-
.ui-btn--ghost:hover { background: var(--accent); }
|
|
2156
|
-
|
|
2157
|
-
.ui-btn--size-default { block-size: 2.25rem; padding: 0 1rem; }
|
|
2158
|
-
.ui-btn--size-sm { block-size: 2rem; padding: 0 0.75rem; border-radius: calc(var(--radius) - 0.125rem); }
|
|
2159
|
-
.ui-btn--size-lg { block-size: 2.5rem; padding: 0 1.5rem; }
|
|
2160
|
-
.ui-btn--size-icon { inline-size: 2.25rem; block-size: 2.25rem; padding: 0; }
|
|
2161
|
-
.ui-btn--size-icon-sm { inline-size: 2rem; block-size: 2rem; padding: 0; }
|
|
2162
|
-
.ui-btn--size-icon-lg { inline-size: 2.5rem; block-size: 2.5rem; padding: 0; }
|
|
2163
|
-
|
|
2164
|
-
/* ── Toggle group ────────────────────────────────────────── */
|
|
2165
|
-
.ui-toggle-group { display: inline-flex; flex-wrap: wrap; gap: 0.25rem; }
|
|
2166
|
-
|
|
2167
|
-
.ui-toggle-group-item {
|
|
2168
|
-
display: inline-flex;
|
|
2169
|
-
align-items: center;
|
|
2170
|
-
justify-content: center;
|
|
2171
|
-
block-size: 2rem;
|
|
2172
|
-
padding: 0 0.75rem;
|
|
2173
|
-
border: 1px solid var(--border);
|
|
2174
|
-
border-radius: var(--radius);
|
|
2175
|
-
background: var(--background);
|
|
2176
|
-
color: var(--foreground);
|
|
2177
|
-
font-family: ${x};
|
|
2178
|
-
font-size: 0.875rem;
|
|
2179
|
-
font-weight: 600;
|
|
2180
|
-
cursor: pointer;
|
|
2181
|
-
white-space: nowrap;
|
|
2182
|
-
transition: all 200ms;
|
|
2183
|
-
box-shadow: 0 1px 2px oklch(5% 0 0 / 8%);
|
|
1597
|
+
function Jn(n) {
|
|
1598
|
+
return JSON.stringify(n);
|
|
2184
1599
|
}
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
.
|
|
2188
|
-
outline: none;
|
|
2189
|
-
border-color: var(--ring);
|
|
2190
|
-
box-shadow: 0 0 0 3px oklch(5% 0 0 / 12%);
|
|
1600
|
+
function ti(n, t) {
|
|
1601
|
+
const e = t ? Qn(n) : Jn(n);
|
|
1602
|
+
n.level === "error" ? console.error(e) : n.level === "warn" ? console.warn(e) : console.log(e);
|
|
2191
1603
|
}
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
1604
|
+
function vt(n, t = 0) {
|
|
1605
|
+
const e = {
|
|
1606
|
+
name: n.name,
|
|
1607
|
+
message: n.message
|
|
1608
|
+
};
|
|
1609
|
+
n.stack !== void 0 && (e.stack = n.stack);
|
|
1610
|
+
for (const i of Object.getOwnPropertyNames(n)) {
|
|
1611
|
+
if (i === "name" || i === "message" || i === "stack" || i === "cause")
|
|
1612
|
+
continue;
|
|
1613
|
+
const o = n[i];
|
|
1614
|
+
o !== void 0 && (e[i] = o);
|
|
1615
|
+
}
|
|
1616
|
+
return n.cause !== void 0 && n.cause !== null && (e.cause = n.cause instanceof Error && t < 5 ? vt(n.cause, t + 1) : String(n.cause)), e;
|
|
2196
1617
|
}
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
display: inline-flex;
|
|
2203
|
-
min-inline-size: 8rem;
|
|
1618
|
+
function ei(n) {
|
|
1619
|
+
const t = {};
|
|
1620
|
+
for (const [e, i] of Object.entries(n))
|
|
1621
|
+
t[e] = i instanceof Error ? vt(i) : i;
|
|
1622
|
+
return t;
|
|
2204
1623
|
}
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
1624
|
+
class ni {
|
|
1625
|
+
constructor(t) {
|
|
1626
|
+
this.config = t;
|
|
1627
|
+
}
|
|
1628
|
+
config;
|
|
1629
|
+
/**
|
|
1630
|
+
* Log at specified level with optional attributes.
|
|
1631
|
+
*/
|
|
1632
|
+
log(t, e, i = {}) {
|
|
1633
|
+
const o = this.config.traceProvider?.() ?? {}, s = {
|
|
1634
|
+
timestamp: jn(Vn()),
|
|
1635
|
+
level: t,
|
|
1636
|
+
msg: e,
|
|
1637
|
+
service: this.config.service,
|
|
1638
|
+
...o,
|
|
1639
|
+
...ei(i)
|
|
1640
|
+
};
|
|
1641
|
+
ti(s, this.config.isDev);
|
|
1642
|
+
}
|
|
1643
|
+
/**
|
|
1644
|
+
* Log at DEBUG level (development only).
|
|
1645
|
+
*/
|
|
1646
|
+
debug(t, e) {
|
|
1647
|
+
this.config.isDev && this.log("debug", t, e);
|
|
1648
|
+
}
|
|
1649
|
+
/**
|
|
1650
|
+
* Log at INFO level.
|
|
1651
|
+
*/
|
|
1652
|
+
info(t, e) {
|
|
1653
|
+
this.log("info", t, e);
|
|
1654
|
+
}
|
|
1655
|
+
/**
|
|
1656
|
+
* Log at WARN level.
|
|
1657
|
+
*/
|
|
1658
|
+
warn(t, e) {
|
|
1659
|
+
this.log("warn", t, e);
|
|
1660
|
+
}
|
|
1661
|
+
/**
|
|
1662
|
+
* Log at ERROR level.
|
|
1663
|
+
*/
|
|
1664
|
+
error(t, e) {
|
|
1665
|
+
this.log("error", t, e);
|
|
1666
|
+
}
|
|
2222
1667
|
}
|
|
2223
|
-
|
|
2224
|
-
.
|
|
2225
|
-
|
|
2226
|
-
border-color: var(--ring);
|
|
2227
|
-
box-shadow: 0 0 0 3px oklch(5% 0 0 / 12%);
|
|
1668
|
+
function yt(n, t) {
|
|
1669
|
+
const e = t?.isDev !== void 0 ? t.isDev : typeof process < "u" ? process.env.NODE_ENV !== "production" : !0;
|
|
1670
|
+
return new ni({ service: n, isDev: e, traceProvider: t?.traceProvider });
|
|
2228
1671
|
}
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
inset-block-start: 50%;
|
|
2233
|
-
inset-inline-end: 0.625rem;
|
|
2234
|
-
transform: translateY(-50%);
|
|
2235
|
-
color: var(--muted-foreground);
|
|
2236
|
-
pointer-events: none;
|
|
1672
|
+
function O(n) {
|
|
1673
|
+
if (n !== void 0)
|
|
1674
|
+
return typeof n == "object" && n !== null && !Array.isArray(n) && !(n instanceof Error) ? n : n instanceof Error ? { error: n.message } : { value: n };
|
|
2237
1675
|
}
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
.
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
block-size: 100%;
|
|
2246
|
-
pointer-events: none;
|
|
2247
|
-
overflow: visible !important; /* override CSS2DRenderer inline style */
|
|
1676
|
+
function _t(n) {
|
|
1677
|
+
return {
|
|
1678
|
+
debug: (t, e) => n.debug(t, O(e)),
|
|
1679
|
+
info: (t, e) => n.info(t, O(e)),
|
|
1680
|
+
warn: (t, e) => n.warn(t, O(e)),
|
|
1681
|
+
error: (t, e) => n.error(t, O(e))
|
|
1682
|
+
};
|
|
2248
1683
|
}
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
1684
|
+
let wt = !1, w = _t(yt("client", { isDev: !1 }));
|
|
1685
|
+
function ii() {
|
|
1686
|
+
wt = !0, w = _t(yt("client", { isDev: !0 }));
|
|
2252
1687
|
}
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
display: flex;
|
|
2256
|
-
align-items: center;
|
|
2257
|
-
justify-content: center;
|
|
2258
|
-
inline-size: 1.75rem;
|
|
2259
|
-
block-size: 1.75rem;
|
|
2260
|
-
border-radius: 50%;
|
|
2261
|
-
border: 2px solid oklch(100% 0 0);
|
|
2262
|
-
background: var(--primary);
|
|
2263
|
-
color: var(--primary-foreground);
|
|
2264
|
-
font-family: ${x};
|
|
2265
|
-
font-size: 0.8125rem;
|
|
2266
|
-
font-weight: 600;
|
|
2267
|
-
cursor: pointer;
|
|
2268
|
-
pointer-events: auto;
|
|
2269
|
-
box-shadow: 0 2px 8px oklch(5% 0 0 / 20%);
|
|
2270
|
-
transition: transform 100ms ease;
|
|
2271
|
-
position: relative;
|
|
1688
|
+
function Gi() {
|
|
1689
|
+
return wt;
|
|
2272
1690
|
}
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
1691
|
+
class oi {
|
|
1692
|
+
constructor(t, e) {
|
|
1693
|
+
this.send = t, this.onMutationFailed = e;
|
|
1694
|
+
}
|
|
1695
|
+
send;
|
|
1696
|
+
onMutationFailed;
|
|
1697
|
+
registry;
|
|
1698
|
+
pendingCallbacks = [];
|
|
1699
|
+
/**
|
|
1700
|
+
* Handle incoming MAPPING message from server
|
|
1701
|
+
*/
|
|
1702
|
+
handleMappingReceived(t) {
|
|
1703
|
+
w.debug("Initializing from server mapping", {
|
|
1704
|
+
attributeCount: t.attributes.length
|
|
1705
|
+
}), this.registry = new Kn(
|
|
1706
|
+
t.attributes,
|
|
1707
|
+
(e, i) => this.sendMutation(e, i),
|
|
1708
|
+
this.onMutationFailed
|
|
1709
|
+
), this.replayPendingCallbacks();
|
|
1710
|
+
}
|
|
1711
|
+
handleMutationResult(t) {
|
|
1712
|
+
this.registry?.handleResults(t.results);
|
|
1713
|
+
}
|
|
1714
|
+
/**
|
|
1715
|
+
* Select a value for an attribute - sends mutation to server.
|
|
1716
|
+
* Can be called before the mapping arrives — the mutation is sent immediately
|
|
1717
|
+
* and the messenger's publisher queue holds it until the iframe is ready.
|
|
1718
|
+
*/
|
|
1719
|
+
select(t, e) {
|
|
1720
|
+
this.sendMutation([{ name: t, value: e }], !1);
|
|
1721
|
+
}
|
|
1722
|
+
getValues(t) {
|
|
1723
|
+
return this.registry?.get(t)?.getValues() ?? [];
|
|
1724
|
+
}
|
|
1725
|
+
getValue(t, e) {
|
|
1726
|
+
return this.registry?.get(t)?.getValue(e);
|
|
1727
|
+
}
|
|
1728
|
+
/**
|
|
1729
|
+
* Register onChange callback for an attribute.
|
|
1730
|
+
* Buffers the callback if the mapping hasn't arrived yet.
|
|
1731
|
+
*/
|
|
1732
|
+
onChange(t, e) {
|
|
1733
|
+
if (this.registry === void 0) {
|
|
1734
|
+
this.pendingCallbacks.push({ name: t, callback: e });
|
|
1735
|
+
return;
|
|
1736
|
+
}
|
|
1737
|
+
const i = this.registry.get(t);
|
|
1738
|
+
if (i === void 0) {
|
|
1739
|
+
w.warn(`onChange: attribute "${t}" not found — callback will not fire`);
|
|
1740
|
+
return;
|
|
1741
|
+
}
|
|
1742
|
+
i.onChange(e);
|
|
1743
|
+
}
|
|
1744
|
+
getAttribute(t) {
|
|
1745
|
+
return this.registry?.get(t);
|
|
1746
|
+
}
|
|
1747
|
+
/** The current selection as attribute name→value pairs, empty before the mapping arrives. */
|
|
1748
|
+
getSelection() {
|
|
1749
|
+
return this.registry?.getSelection() ?? {};
|
|
1750
|
+
}
|
|
1751
|
+
get hasMapping() {
|
|
1752
|
+
return this.registry !== void 0;
|
|
1753
|
+
}
|
|
1754
|
+
sendMutation(t, e) {
|
|
1755
|
+
const i = {
|
|
1756
|
+
type: c.MUTATION,
|
|
1757
|
+
mutations: t,
|
|
1758
|
+
isInitial: e
|
|
1759
|
+
};
|
|
1760
|
+
this.send(i);
|
|
1761
|
+
}
|
|
1762
|
+
replayPendingCallbacks() {
|
|
1763
|
+
for (const { name: t, callback: e } of this.pendingCallbacks) {
|
|
1764
|
+
const i = this.registry?.get(t);
|
|
1765
|
+
i === void 0 && w.warn(`onChange: attribute "${t}" not found — buffered callback will not fire`), i?.onChange(e);
|
|
1766
|
+
}
|
|
1767
|
+
this.pendingCallbacks.length = 0;
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
class si {
|
|
1771
|
+
constructor(t) {
|
|
1772
|
+
this.send = t;
|
|
1773
|
+
}
|
|
1774
|
+
send;
|
|
1775
|
+
commands = [];
|
|
1776
|
+
/**
|
|
1777
|
+
* Rotate camera horizontally
|
|
1778
|
+
* @param degrees - Absolute rotation in degrees (0 = front view)
|
|
1779
|
+
* @throws VirtualdisplayError if value is not a finite number
|
|
1780
|
+
*/
|
|
1781
|
+
rotate(t) {
|
|
1782
|
+
return this.validateFiniteNumber(t, "rotate"), this.commands.push({ action: "rotate", value: t }), this;
|
|
1783
|
+
}
|
|
1784
|
+
/**
|
|
1785
|
+
* Tilt camera vertically
|
|
1786
|
+
* @param degrees - Absolute tilt in degrees (0 = top view, 90 = horizontal)
|
|
1787
|
+
* @throws VirtualdisplayError if value is not a finite number
|
|
1788
|
+
*/
|
|
1789
|
+
tilt(t) {
|
|
1790
|
+
return this.validateFiniteNumber(t, "tilt"), this.commands.push({ action: "tilt", value: t }), this;
|
|
1791
|
+
}
|
|
1792
|
+
/**
|
|
1793
|
+
* Zoom camera
|
|
1794
|
+
* @param percentage - Zoom percentage (100 = normal, >100 = zoom in, <100 = zoom out)
|
|
1795
|
+
* @throws VirtualdisplayError if value is not a finite number
|
|
1796
|
+
*/
|
|
1797
|
+
zoom(t) {
|
|
1798
|
+
return this.validateFiniteNumber(t, "zoom"), this.commands.push({ action: "zoom", value: t }), this;
|
|
1799
|
+
}
|
|
1800
|
+
/**
|
|
1801
|
+
* Execute accumulated camera commands
|
|
1802
|
+
* @throws VirtualdisplayError if no commands have been accumulated
|
|
1803
|
+
*/
|
|
1804
|
+
set() {
|
|
1805
|
+
if (this.commands.length === 0)
|
|
1806
|
+
throw f.invalidParameter(
|
|
1807
|
+
"No camera commands to execute. Call rotate(), tilt(), or zoom() before set()."
|
|
1808
|
+
);
|
|
1809
|
+
const t = {
|
|
1810
|
+
type: c.CAMERA,
|
|
1811
|
+
commands: this.commands
|
|
1812
|
+
};
|
|
1813
|
+
this.send(t), this.commands = [];
|
|
1814
|
+
}
|
|
1815
|
+
validateFiniteNumber(t, e) {
|
|
1816
|
+
if (!Number.isFinite(t))
|
|
1817
|
+
throw f.invalidParameter(
|
|
1818
|
+
`${e}() requires a finite number, got ${String(t)}`
|
|
1819
|
+
);
|
|
1820
|
+
}
|
|
1821
|
+
/**
|
|
1822
|
+
* Reset camera to initial position
|
|
1823
|
+
* This is not chainable and executes immediately
|
|
1824
|
+
*/
|
|
1825
|
+
reset() {
|
|
1826
|
+
const t = {
|
|
1827
|
+
type: c.CAMERA,
|
|
1828
|
+
commands: [{ action: "reset" }]
|
|
1829
|
+
};
|
|
1830
|
+
this.send(t);
|
|
1831
|
+
}
|
|
1832
|
+
}
|
|
1833
|
+
class ri {
|
|
1834
|
+
state;
|
|
1835
|
+
limitsState;
|
|
1836
|
+
changeCallbacks = [];
|
|
1837
|
+
constructor() {
|
|
1838
|
+
this.state = {
|
|
1839
|
+
rotation: 0,
|
|
1840
|
+
tilt: 0,
|
|
1841
|
+
zoom: 100
|
|
1842
|
+
};
|
|
1843
|
+
}
|
|
1844
|
+
/**
|
|
1845
|
+
* Get current rotation in degrees
|
|
1846
|
+
*/
|
|
1847
|
+
get rotation() {
|
|
1848
|
+
return this.state.rotation;
|
|
1849
|
+
}
|
|
1850
|
+
/**
|
|
1851
|
+
* Get current tilt in degrees
|
|
1852
|
+
*/
|
|
1853
|
+
get tilt() {
|
|
1854
|
+
return this.state.tilt;
|
|
1855
|
+
}
|
|
1856
|
+
/**
|
|
1857
|
+
* Get current zoom percentage
|
|
1858
|
+
*/
|
|
1859
|
+
get zoom() {
|
|
1860
|
+
return this.state.zoom;
|
|
1861
|
+
}
|
|
1862
|
+
/**
|
|
1863
|
+
* Subscribe to camera position changes.
|
|
1864
|
+
* Also fires when limits are applied via applyLimits() so components
|
|
1865
|
+
* can re-evaluate disabled states without a separate callback.
|
|
1866
|
+
*/
|
|
1867
|
+
onChange(t) {
|
|
1868
|
+
this.changeCallbacks.push(t);
|
|
1869
|
+
}
|
|
1870
|
+
/**
|
|
1871
|
+
* Current camera movement limits (set from CONFIG message).
|
|
1872
|
+
* Undefined until the server sends limits in its CONFIG payload.
|
|
1873
|
+
*/
|
|
1874
|
+
get limits() {
|
|
1875
|
+
return this.limitsState;
|
|
1876
|
+
}
|
|
1877
|
+
/**
|
|
1878
|
+
* Apply camera limits received from the server CONFIG message.
|
|
1879
|
+
* Fires onChange callbacks so button disabled states update immediately.
|
|
1880
|
+
*/
|
|
1881
|
+
applyLimits(t) {
|
|
1882
|
+
this.limitsState = t;
|
|
1883
|
+
const e = { rotation: this.rotation, tilt: this.tilt, zoom: this.zoom };
|
|
1884
|
+
for (const i of this.changeCallbacks)
|
|
1885
|
+
i(e);
|
|
1886
|
+
}
|
|
1887
|
+
/**
|
|
1888
|
+
* Handle incoming camera position message from server
|
|
1889
|
+
*/
|
|
1890
|
+
handlePositionUpdate(t) {
|
|
1891
|
+
this.update(t.transforms);
|
|
1892
|
+
}
|
|
1893
|
+
/**
|
|
1894
|
+
* Update camera position from server transforms
|
|
1895
|
+
*/
|
|
1896
|
+
update(t) {
|
|
1897
|
+
let e = !1;
|
|
1898
|
+
for (const i of t)
|
|
1899
|
+
switch (i.type) {
|
|
1900
|
+
case "rotation":
|
|
1901
|
+
this.state.rotation = i.value, e = !0;
|
|
1902
|
+
break;
|
|
1903
|
+
case "tilt":
|
|
1904
|
+
this.state.tilt = i.value, e = !0;
|
|
1905
|
+
break;
|
|
1906
|
+
case "zoom":
|
|
1907
|
+
this.state.zoom = i.value, e = !0;
|
|
1908
|
+
break;
|
|
1909
|
+
}
|
|
1910
|
+
if (e) {
|
|
1911
|
+
const i = {
|
|
1912
|
+
rotation: this.rotation,
|
|
1913
|
+
tilt: this.tilt,
|
|
1914
|
+
zoom: this.zoom
|
|
1915
|
+
};
|
|
1916
|
+
for (const o of this.changeCallbacks)
|
|
1917
|
+
o(i);
|
|
1918
|
+
}
|
|
1919
|
+
}
|
|
2277
1920
|
}
|
|
2278
|
-
|
|
2279
|
-
.
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
background: var(--background);
|
|
2285
|
-
color: var(--foreground);
|
|
2286
|
-
border: 1px solid var(--border);
|
|
2287
|
-
border-radius: var(--radius);
|
|
2288
|
-
padding: 0.75rem 1rem;
|
|
2289
|
-
max-inline-size: 15rem;
|
|
2290
|
-
box-shadow: 0 4px 6px oklch(5% 0 0 / 8%), 0 2px 4px oklch(5% 0 0 / 6%);
|
|
2291
|
-
pointer-events: auto;
|
|
2292
|
-
white-space: normal;
|
|
1921
|
+
function ai(n, t) {
|
|
1922
|
+
const e = n.filter((s) => li(s, t));
|
|
1923
|
+
if (e.length === 0)
|
|
1924
|
+
return;
|
|
1925
|
+
const i = Math.max(...e.map(nt)), o = e.filter((s) => nt(s) === i);
|
|
1926
|
+
return o.length === 1 ? o[0] : void 0;
|
|
2293
1927
|
}
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
.vd-annotation-popup-close {
|
|
2297
|
-
position: absolute;
|
|
2298
|
-
inset-block-start: 0.375rem;
|
|
2299
|
-
inset-inline-end: 0.375rem;
|
|
2300
|
-
display: flex;
|
|
2301
|
-
align-items: center;
|
|
2302
|
-
justify-content: center;
|
|
2303
|
-
inline-size: 1.25rem;
|
|
2304
|
-
block-size: 1.25rem;
|
|
2305
|
-
padding: 0;
|
|
2306
|
-
border: none;
|
|
2307
|
-
border-radius: calc(var(--radius) - 4px);
|
|
2308
|
-
background: transparent;
|
|
2309
|
-
color: var(--muted-foreground);
|
|
2310
|
-
cursor: pointer;
|
|
2311
|
-
pointer-events: auto;
|
|
1928
|
+
function li(n, t) {
|
|
1929
|
+
return Object.entries(n.attributes).every(([e, i]) => t[e] === i);
|
|
2312
1930
|
}
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
background: var(--secondary);
|
|
1931
|
+
function nt(n) {
|
|
1932
|
+
return Object.keys(n.attributes).length;
|
|
2316
1933
|
}
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
1934
|
+
class ci {
|
|
1935
|
+
constructor(t, e) {
|
|
1936
|
+
this.dispatchChange = t, this.dispatchSubmit = e;
|
|
1937
|
+
}
|
|
1938
|
+
dispatchChange;
|
|
1939
|
+
dispatchSubmit;
|
|
1940
|
+
pricing;
|
|
1941
|
+
selection = {};
|
|
1942
|
+
resolved;
|
|
1943
|
+
changeCallbacks = [];
|
|
1944
|
+
renderCallbacks = [];
|
|
1945
|
+
submitCallback;
|
|
1946
|
+
submitDefaultLabel;
|
|
1947
|
+
/** The resolved configuration, or undefined when nothing matches. */
|
|
1948
|
+
get current() {
|
|
1949
|
+
return this.resolved;
|
|
1950
|
+
}
|
|
1951
|
+
/** The VAT label for bare embeds (e.g. "incl. btw"), or undefined without pricing. */
|
|
1952
|
+
get vatDisplay() {
|
|
1953
|
+
return this.pricing?.vatDisplay;
|
|
1954
|
+
}
|
|
1955
|
+
/**
|
|
1956
|
+
* The CTA label: the customer's `button_label`, or the adapter's `defaultLabel`
|
|
1957
|
+
* when that is empty. Undefined when neither is set — a button must know what
|
|
1958
|
+
* it says, so the CTA does not render.
|
|
1959
|
+
*/
|
|
1960
|
+
get buttonLabel() {
|
|
1961
|
+
const t = this.pricing?.buttonLabel;
|
|
1962
|
+
if (t != null && t !== "")
|
|
1963
|
+
return t;
|
|
1964
|
+
if (this.submitDefaultLabel !== void 0 && this.submitDefaultLabel !== "")
|
|
1965
|
+
return this.submitDefaultLabel;
|
|
1966
|
+
}
|
|
1967
|
+
/**
|
|
1968
|
+
* Whether the current configuration may be submitted: a handler is registered
|
|
1969
|
+
* and the configuration is either price-less or an `available` priced one. The
|
|
1970
|
+
* CTA's visibility ({@link submitEnabled}) layers a label requirement on top of
|
|
1971
|
+
* this; a programmatic `submit()` does not need a label.
|
|
1972
|
+
*/
|
|
1973
|
+
get submittable() {
|
|
1974
|
+
return this.submitCallback === void 0 ? !1 : this.pricing === void 0 ? !0 : this.resolved?.availability === "available";
|
|
1975
|
+
}
|
|
1976
|
+
/**
|
|
1977
|
+
* Whether the CTA should render: the configuration is submittable and a label
|
|
1978
|
+
* exists. A button must say something, so an empty label hides the CTA rather
|
|
1979
|
+
* than rendering blank.
|
|
1980
|
+
*/
|
|
1981
|
+
get submitEnabled() {
|
|
1982
|
+
return this.submittable && this.buttonLabel !== void 0;
|
|
1983
|
+
}
|
|
1984
|
+
/**
|
|
1985
|
+
* Subscribe to configuration changes. Fires after every selection change with
|
|
1986
|
+
* the resolved configuration, including undefined when nothing matches.
|
|
1987
|
+
*/
|
|
1988
|
+
onChange(t) {
|
|
1989
|
+
this.changeCallbacks.push(t);
|
|
1990
|
+
}
|
|
1991
|
+
/**
|
|
1992
|
+
* Register the submit handler the CTA hands the configuration to. Registering
|
|
1993
|
+
* one is what switches the button on (capability driven). `defaultLabel` fills
|
|
1994
|
+
* in when the customer authored no button label.
|
|
1995
|
+
*/
|
|
1996
|
+
onSubmit(t, e) {
|
|
1997
|
+
this.submitCallback = t, this.submitDefaultLabel = e?.defaultLabel, this.notifyRender();
|
|
1998
|
+
}
|
|
1999
|
+
/**
|
|
2000
|
+
* Subscribe the built-in UI to re-render the price + CTA. Fires on every
|
|
2001
|
+
* resolve and when a submit handler is registered (which can switch the button
|
|
2002
|
+
* on without a configuration change). Separate from `onChange`, which stays the
|
|
2003
|
+
* host-facing, mutation-driven contract. Returns a disposer.
|
|
2004
|
+
*/
|
|
2005
|
+
onRender(t) {
|
|
2006
|
+
return this.renderCallbacks.push(t), () => {
|
|
2007
|
+
const e = this.renderCallbacks.indexOf(t);
|
|
2008
|
+
e !== -1 && this.renderCallbacks.splice(e, 1);
|
|
2009
|
+
};
|
|
2010
|
+
}
|
|
2011
|
+
/**
|
|
2012
|
+
* Hand the current configuration to the registered handler and fire the
|
|
2013
|
+
* bubbling `vd:configuration-submit` event. No-op without a handler or a
|
|
2014
|
+
* resolved configuration. Returns the handler's promise so the caller can
|
|
2015
|
+
* reflect the result (bezig / gelukt / mislukt).
|
|
2016
|
+
*/
|
|
2017
|
+
async submit() {
|
|
2018
|
+
if (!this.submittable)
|
|
2019
|
+
return;
|
|
2020
|
+
const t = this.resolved !== void 0 ? { attributes: this.resolved.attributes, reference: this.resolved.reference } : { attributes: { ...this.selection }, reference: "" };
|
|
2021
|
+
this.dispatchSubmit(t), await this.submitCallback?.(t);
|
|
2022
|
+
}
|
|
2023
|
+
/** Called by the client when a PRICING message arrives from the viewer. */
|
|
2024
|
+
handlePricingReceived(t) {
|
|
2025
|
+
this.pricing = t, this.recompute();
|
|
2026
|
+
}
|
|
2027
|
+
/** Called by the client after every mutation result, with the full selection. */
|
|
2028
|
+
handleSelectionChanged(t) {
|
|
2029
|
+
this.selection = t, this.recompute();
|
|
2030
|
+
}
|
|
2031
|
+
recompute() {
|
|
2032
|
+
this.resolved = this.resolve();
|
|
2033
|
+
for (const t of this.changeCallbacks)
|
|
2034
|
+
t(this.resolved);
|
|
2035
|
+
this.dispatchChange(this.resolved), this.notifyRender();
|
|
2036
|
+
}
|
|
2037
|
+
notifyRender() {
|
|
2038
|
+
for (const t of this.renderCallbacks)
|
|
2039
|
+
t();
|
|
2040
|
+
}
|
|
2041
|
+
resolve() {
|
|
2042
|
+
if (this.pricing === void 0)
|
|
2043
|
+
return;
|
|
2044
|
+
const t = ai(this.pricing.rules, this.selection);
|
|
2045
|
+
if (!(t === void 0 || t.availability === St.HIDDEN))
|
|
2046
|
+
return {
|
|
2047
|
+
attributes: { ...this.selection },
|
|
2048
|
+
reference: t.reference,
|
|
2049
|
+
price: t.priceCents,
|
|
2050
|
+
currency: this.pricing.currency,
|
|
2051
|
+
availability: t.availability
|
|
2052
|
+
};
|
|
2053
|
+
}
|
|
2320
2054
|
}
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2055
|
+
class ui {
|
|
2056
|
+
constructor(t, e) {
|
|
2057
|
+
this.send = t, this.dispatch = e;
|
|
2058
|
+
}
|
|
2059
|
+
send;
|
|
2060
|
+
dispatch;
|
|
2061
|
+
focused = null;
|
|
2062
|
+
attributes = [];
|
|
2063
|
+
changeCallbacks = [];
|
|
2064
|
+
/** The focused component name, or null in overview. */
|
|
2065
|
+
get current() {
|
|
2066
|
+
return this.focused;
|
|
2067
|
+
}
|
|
2068
|
+
/**
|
|
2069
|
+
* Focus a component by name. Sends a focus message to the viewer.
|
|
2070
|
+
* @throws VirtualdisplayError if component is not a non-empty string
|
|
2071
|
+
*/
|
|
2072
|
+
set(t) {
|
|
2073
|
+
if (typeof t != "string" || t.length === 0)
|
|
2074
|
+
throw f.invalidParameter(
|
|
2075
|
+
`set() requires a non-empty component name, got ${String(t)}`
|
|
2076
|
+
);
|
|
2077
|
+
this.send({ type: c.FOCUS, action: Y.FOCUS, component: t });
|
|
2078
|
+
}
|
|
2079
|
+
/** Return to the overview — unfocus the current component. */
|
|
2080
|
+
clear() {
|
|
2081
|
+
this.send({ type: c.FOCUS, action: Y.UNFOCUS });
|
|
2082
|
+
}
|
|
2083
|
+
/**
|
|
2084
|
+
* Subscribe to focus changes. The callback fires with the focus state when a
|
|
2085
|
+
* component is focused, and with null when returning to overview.
|
|
2086
|
+
*/
|
|
2087
|
+
onChange(t) {
|
|
2088
|
+
this.changeCallbacks.push(t);
|
|
2089
|
+
}
|
|
2090
|
+
/** Called by the client when a FocusStateMessage is received from the viewer. */
|
|
2091
|
+
handleStateReceived(t) {
|
|
2092
|
+
t.state === kt.FOCUSED && t.component !== void 0 ? (this.focused = t.component, this.attributes = t.attributes ?? []) : (this.focused = null, this.attributes = []);
|
|
2093
|
+
const e = this.focused !== null ? { component: this.focused, attributes: this.attributes } : null;
|
|
2094
|
+
for (const i of this.changeCallbacks)
|
|
2095
|
+
i(e);
|
|
2096
|
+
this.dispatch(e);
|
|
2097
|
+
}
|
|
2324
2098
|
}
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2099
|
+
class di {
|
|
2100
|
+
constructor(t) {
|
|
2101
|
+
this.filename = t;
|
|
2102
|
+
}
|
|
2103
|
+
filename;
|
|
2104
|
+
developedCallbacks = /* @__PURE__ */ new Set();
|
|
2105
|
+
errorCallbacks = /* @__PURE__ */ new Set();
|
|
2106
|
+
developed = !1;
|
|
2107
|
+
failed = !1;
|
|
2108
|
+
photoData = null;
|
|
2109
|
+
/**
|
|
2110
|
+
* Register a callback for when the photo is developed
|
|
2111
|
+
* If the photo is already developed, the callback is called immediately
|
|
2112
|
+
*
|
|
2113
|
+
* @param callback Function to call with photo data
|
|
2114
|
+
* @returns This Photo instance for chaining
|
|
2115
|
+
*/
|
|
2116
|
+
onDeveloped(t) {
|
|
2117
|
+
return this.developed && this.photoData !== null ? (t(this.photoData), this) : (this.developedCallbacks.add(t), this);
|
|
2118
|
+
}
|
|
2119
|
+
/**
|
|
2120
|
+
* Register a callback for when the photo capture fails
|
|
2121
|
+
*
|
|
2122
|
+
* @param callback Function to call with error
|
|
2123
|
+
* @returns This Photo instance for chaining
|
|
2124
|
+
*/
|
|
2125
|
+
onError(t) {
|
|
2126
|
+
return this.errorCallbacks.add(t), this;
|
|
2127
|
+
}
|
|
2128
|
+
/**
|
|
2129
|
+
* Get the filename for this photo
|
|
2130
|
+
*/
|
|
2131
|
+
getFilename() {
|
|
2132
|
+
return this.filename;
|
|
2133
|
+
}
|
|
2134
|
+
/**
|
|
2135
|
+
* Mark the photo as developed and notify all callbacks
|
|
2136
|
+
* This method is called by Snapshot when the photo data arrives from the server
|
|
2137
|
+
*/
|
|
2138
|
+
develop(t) {
|
|
2139
|
+
this.developed || this.failed || (this.photoData = t, this.developed = !0, this.developedCallbacks.forEach((e) => {
|
|
2140
|
+
e(this.photoData);
|
|
2141
|
+
}), this.developedCallbacks.clear(), this.errorCallbacks.clear());
|
|
2142
|
+
}
|
|
2143
|
+
/**
|
|
2144
|
+
* Mark the photo as failed and notify error callbacks
|
|
2145
|
+
*/
|
|
2146
|
+
fail(t) {
|
|
2147
|
+
this.developed || this.failed || (this.failed = !0, this.errorCallbacks.forEach((e) => {
|
|
2148
|
+
e(t);
|
|
2149
|
+
}), this.developedCallbacks.clear(), this.errorCallbacks.clear());
|
|
2329
2150
|
}
|
|
2330
2151
|
}
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
}
|
|
2336
|
-
|
|
2337
|
-
.
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2152
|
+
const it = 3e4;
|
|
2153
|
+
class hi {
|
|
2154
|
+
constructor(t) {
|
|
2155
|
+
this.send = t;
|
|
2156
|
+
}
|
|
2157
|
+
send;
|
|
2158
|
+
validExtensions = [".png"];
|
|
2159
|
+
pendingPhotos = /* @__PURE__ */ new Map();
|
|
2160
|
+
/**
|
|
2161
|
+
* Take a snapshot of the current 3D model view
|
|
2162
|
+
*
|
|
2163
|
+
* @param filename The filename for the snapshot (must include valid extension)
|
|
2164
|
+
* @returns Photo object for registering callbacks
|
|
2165
|
+
* @throws VirtualdisplayError if filename is invalid
|
|
2166
|
+
*/
|
|
2167
|
+
take(t) {
|
|
2168
|
+
this.validateFilename(t), w.debug("Taking snapshot", { filename: t });
|
|
2169
|
+
const e = new di(t), i = setTimeout(() => {
|
|
2170
|
+
this.pendingPhotos.delete(t), w.warn("Snapshot timed out", { filename: t }), e.fail(new f(
|
|
2171
|
+
`Snapshot timed out: the viewer did not respond within ${it}ms`,
|
|
2172
|
+
E.SNAPSHOT_FAILED
|
|
2173
|
+
));
|
|
2174
|
+
}, it);
|
|
2175
|
+
return this.pendingPhotos.set(t, { photo: e, timeout: i }), this.send({
|
|
2176
|
+
type: c.SNAPSHOT,
|
|
2177
|
+
filename: t
|
|
2178
|
+
}), e;
|
|
2179
|
+
}
|
|
2180
|
+
/**
|
|
2181
|
+
* Handle incoming snapshot result from server
|
|
2182
|
+
* Matches the message to a pending photo by filename, then develops or fails it
|
|
2183
|
+
*/
|
|
2184
|
+
handleSnapshotResult(t) {
|
|
2185
|
+
const e = this.pendingPhotos.get(t.filename);
|
|
2186
|
+
if (e === void 0) {
|
|
2187
|
+
w.warn("No pending photo found for filename", {
|
|
2188
|
+
filename: t.filename,
|
|
2189
|
+
pendingFilenames: Array.from(this.pendingPhotos.keys())
|
|
2190
|
+
});
|
|
2191
|
+
return;
|
|
2192
|
+
}
|
|
2193
|
+
clearTimeout(e.timeout), this.pendingPhotos.delete(t.filename);
|
|
2194
|
+
const { photo: i } = e;
|
|
2195
|
+
if (t.error !== void 0) {
|
|
2196
|
+
i.fail(new f(t.error, E.SNAPSHOT_FAILED));
|
|
2197
|
+
return;
|
|
2198
|
+
}
|
|
2199
|
+
t.data !== void 0 && i.develop({ filename: t.filename, data: t.data });
|
|
2200
|
+
}
|
|
2201
|
+
/**
|
|
2202
|
+
* Fail any pending photos and forget them. Called from client destroy
|
|
2203
|
+
* so callers awaiting onError() see a deterministic outcome instead of
|
|
2204
|
+
* leaking captures whose results will never arrive.
|
|
2205
|
+
*/
|
|
2206
|
+
clear() {
|
|
2207
|
+
if (this.pendingPhotos.size === 0)
|
|
2208
|
+
return;
|
|
2209
|
+
const t = new f(
|
|
2210
|
+
"Client destroyed before snapshot completed",
|
|
2211
|
+
E.SNAPSHOT_FAILED
|
|
2212
|
+
);
|
|
2213
|
+
for (const { photo: e, timeout: i } of this.pendingPhotos.values())
|
|
2214
|
+
clearTimeout(i), e.fail(t);
|
|
2215
|
+
this.pendingPhotos.clear();
|
|
2216
|
+
}
|
|
2217
|
+
/**
|
|
2218
|
+
* Validate filename has a valid image extension
|
|
2219
|
+
*/
|
|
2220
|
+
validateFilename(t) {
|
|
2221
|
+
if (t === "" || typeof t != "string")
|
|
2222
|
+
throw new f(
|
|
2223
|
+
"Filename must be a non-empty string",
|
|
2224
|
+
E.INVALID_PARAMETER
|
|
2225
|
+
);
|
|
2226
|
+
if (!this.validExtensions.some(
|
|
2227
|
+
(i) => t.toLowerCase().endsWith(i)
|
|
2228
|
+
))
|
|
2229
|
+
throw new f(
|
|
2230
|
+
`Invalid filename: "${t}". Filename must end with one of: ${this.validExtensions.join(", ")}`,
|
|
2231
|
+
E.INVALID_PARAMETER
|
|
2232
|
+
);
|
|
2233
|
+
if (t.includes("..") || t.includes("/") || t.includes("\\"))
|
|
2234
|
+
throw new f(
|
|
2235
|
+
'Filename cannot contain path separators or ".."',
|
|
2236
|
+
E.INVALID_PARAMETER
|
|
2237
|
+
);
|
|
2238
|
+
}
|
|
2353
2239
|
}
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2240
|
+
class mi {
|
|
2241
|
+
container = null;
|
|
2242
|
+
attach(t) {
|
|
2243
|
+
this.container = t;
|
|
2244
|
+
}
|
|
2245
|
+
dispatch(t, e, i = !1) {
|
|
2246
|
+
const o = new CustomEvent(t, { detail: e, cancelable: i });
|
|
2247
|
+
return this.container?.dispatchEvent(o), o;
|
|
2248
|
+
}
|
|
2249
|
+
on(t, e) {
|
|
2250
|
+
const i = (o) => {
|
|
2251
|
+
const s = o, r = { ...s.detail, preventDefault: () => {
|
|
2252
|
+
s.preventDefault();
|
|
2253
|
+
} };
|
|
2254
|
+
e(r);
|
|
2255
|
+
};
|
|
2256
|
+
return this.container?.addEventListener(t, i), () => {
|
|
2257
|
+
this.container?.removeEventListener(t, i);
|
|
2258
|
+
};
|
|
2259
|
+
}
|
|
2362
2260
|
}
|
|
2363
|
-
function
|
|
2261
|
+
function y(n, { size: t = 20, strokeWidth: e = 1.75 } = {}) {
|
|
2262
|
+
return ct(n, { width: t, height: t, "stroke-width": e });
|
|
2263
|
+
}
|
|
2264
|
+
const b = {
|
|
2265
|
+
ar: (n) => y(Dt, n),
|
|
2266
|
+
fullscreen: (n) => y(Ht, n),
|
|
2267
|
+
exitFullscreen: (n) => y(Gt, n),
|
|
2268
|
+
screenshot: (n) => y(Bt, n),
|
|
2269
|
+
tiltUp: (n) => y(jt, n),
|
|
2270
|
+
tiltDown: (n) => y(ut, n),
|
|
2271
|
+
rotateLeft: (n) => y(Ut, n),
|
|
2272
|
+
rotateRight: (n) => y(Vt, n),
|
|
2273
|
+
zoomIn: (n) => y(Yt, n),
|
|
2274
|
+
zoomOut: (n) => y(Xt, n),
|
|
2275
|
+
reset: (n) => y(qt, n),
|
|
2276
|
+
configurator: (n) => y(Zt, n),
|
|
2277
|
+
close: (n) => y(Wt, n)
|
|
2278
|
+
};
|
|
2279
|
+
function ot(n) {
|
|
2364
2280
|
const t = Math.max(0, Math.min(1, n));
|
|
2365
2281
|
return t * t * (3 - 2 * t);
|
|
2366
2282
|
}
|
|
2367
|
-
function
|
|
2368
|
-
const [r, l, d] = n, u = Math.cos(t), p = Math.sin(t), v = u * r + p * d,
|
|
2369
|
-
return [i + v * s *
|
|
2283
|
+
function pi(n, t, e, i, o, s) {
|
|
2284
|
+
const [r, l, d] = n, u = Math.cos(t), p = Math.sin(t), v = u * r + p * d, A = -p * r + u * d, S = Math.cos(e), C = Math.sin(e), R = S * l - C * A, M = C * l + S * A, W = 0.55;
|
|
2285
|
+
return [i + v * s * W, o - R * s * W, M];
|
|
2370
2286
|
}
|
|
2371
|
-
function
|
|
2287
|
+
function fi(n, t, e) {
|
|
2372
2288
|
n.beginPath(), n.moveTo(t[0], t[1]), n.lineTo(e[0], e[1]), n.strokeStyle = "#000", n.lineWidth = 2, n.stroke();
|
|
2373
2289
|
}
|
|
2374
|
-
function
|
|
2290
|
+
function gi(n, t, e, i, o) {
|
|
2375
2291
|
const s = t(e), r = t(i), l = [
|
|
2376
2292
|
s[0] + (r[0] - s[0]) * o,
|
|
2377
2293
|
s[1] + (r[1] - s[1]) * o,
|
|
2378
2294
|
s[2]
|
|
2379
2295
|
];
|
|
2380
|
-
|
|
2296
|
+
fi(n, s, l);
|
|
2381
2297
|
}
|
|
2382
|
-
const z = [-1, -1, 1],
|
|
2383
|
-
[z,
|
|
2384
|
-
[
|
|
2385
|
-
[
|
|
2298
|
+
const z = [-1, -1, 1], F = [1, -1, 1], P = [1, -1, -1], $ = [-1, -1, -1], D = [-1, 1, 1], B = [1, 1, 1], U = [1, 1, -1], V = [-1, 1, -1], st = [
|
|
2299
|
+
[z, F],
|
|
2300
|
+
[F, P],
|
|
2301
|
+
[P, $],
|
|
2386
2302
|
[$, z],
|
|
2387
2303
|
[z, D],
|
|
2388
|
-
[
|
|
2389
|
-
[
|
|
2304
|
+
[F, B],
|
|
2305
|
+
[P, U],
|
|
2390
2306
|
[$, V],
|
|
2391
2307
|
[D, B],
|
|
2392
2308
|
[B, U],
|
|
2393
2309
|
[U, V],
|
|
2394
2310
|
[V, D]
|
|
2395
|
-
],
|
|
2396
|
-
function
|
|
2311
|
+
], bi = 400, rt = '-apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif';
|
|
2312
|
+
function vi() {
|
|
2397
2313
|
const n = document.createElement("div");
|
|
2398
2314
|
Object.assign(n.style, {
|
|
2399
2315
|
position: "absolute",
|
|
@@ -2429,16 +2345,16 @@ function Ci() {
|
|
|
2429
2345
|
fontWeight: "400",
|
|
2430
2346
|
color: "#000",
|
|
2431
2347
|
fontVariantNumeric: "tabular-nums",
|
|
2432
|
-
fontFamily:
|
|
2348
|
+
fontFamily: rt
|
|
2433
2349
|
});
|
|
2434
2350
|
const o = document.createElement("span");
|
|
2435
2351
|
return Object.assign(o.style, {
|
|
2436
2352
|
fontSize: "13px",
|
|
2437
2353
|
color: "#000",
|
|
2438
|
-
fontFamily:
|
|
2439
|
-
}), o.textContent =
|
|
2354
|
+
fontFamily: rt
|
|
2355
|
+
}), o.textContent = gt(), e.appendChild(i), e.appendChild(o), n.appendChild(t), n.appendChild(e), { overlay: n, canvas: t, pctEl: i, phaseEl: o };
|
|
2440
2356
|
}
|
|
2441
|
-
class
|
|
2357
|
+
class yi {
|
|
2442
2358
|
overlay;
|
|
2443
2359
|
canvas;
|
|
2444
2360
|
ctx;
|
|
@@ -2451,17 +2367,17 @@ class wi {
|
|
|
2451
2367
|
visible = !1;
|
|
2452
2368
|
constructor(t, e = {}) {
|
|
2453
2369
|
this.startTime = performance.now();
|
|
2454
|
-
const i =
|
|
2370
|
+
const i = vi();
|
|
2455
2371
|
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());
|
|
2456
|
-
const o = e.showDelay ??
|
|
2372
|
+
const o = e.showDelay ?? bi;
|
|
2457
2373
|
this.showTimerId = setTimeout(() => {
|
|
2458
2374
|
this.reveal();
|
|
2459
2375
|
}, o);
|
|
2460
2376
|
}
|
|
2461
2377
|
get loadingTexts() {
|
|
2462
2378
|
return {
|
|
2463
|
-
downloading:
|
|
2464
|
-
rendering:
|
|
2379
|
+
downloading: gt(),
|
|
2380
|
+
rendering: Pe()
|
|
2465
2381
|
};
|
|
2466
2382
|
}
|
|
2467
2383
|
updateProgress(t, e) {
|
|
@@ -2514,20 +2430,20 @@ class wi {
|
|
|
2514
2430
|
return;
|
|
2515
2431
|
const t = this.canvas.width / Math.min(devicePixelRatio, 2), e = this.canvas.height / Math.min(devicePixelRatio, 2), i = (performance.now() - this.startTime) / 1e3;
|
|
2516
2432
|
this.ctx.fillStyle = "#fff", this.ctx.fillRect(0, 0, t, e);
|
|
2517
|
-
const o = t / 2, s = e * 0.44, r = Math.min(t, e) * 0.08, l = 0.785, d = 0.615, u = (
|
|
2433
|
+
const o = t / 2, s = e * 0.44, r = Math.min(t, e) * 0.08, l = 0.785, d = 0.615, u = (C) => pi(C, l, d, o, s, r), p = 6, v = i % p / p, A = st.length;
|
|
2518
2434
|
let S;
|
|
2519
|
-
v < 0.35 ? S =
|
|
2520
|
-
for (let
|
|
2521
|
-
const R =
|
|
2435
|
+
v < 0.35 ? S = ot(v / 0.35) * A : v < 0.55 ? S = A : v < 0.9 ? S = (1 - ot((v - 0.55) / 0.35)) * A : S = 0, this.ctx.shadowBlur = 5, this.ctx.shadowColor = "rgba(30,30,30,0.08)";
|
|
2436
|
+
for (let C = 0; C < A && !(C >= S); C++) {
|
|
2437
|
+
const R = st[C];
|
|
2522
2438
|
if (R === void 0)
|
|
2523
2439
|
continue;
|
|
2524
|
-
const M = Math.min(1, S -
|
|
2525
|
-
|
|
2440
|
+
const M = Math.min(1, S - C);
|
|
2441
|
+
gi(this.ctx, u, R[0], R[1], M);
|
|
2526
2442
|
}
|
|
2527
2443
|
this.ctx.shadowBlur = 0;
|
|
2528
2444
|
}
|
|
2529
2445
|
}
|
|
2530
|
-
class
|
|
2446
|
+
class _i {
|
|
2531
2447
|
constructor(t) {
|
|
2532
2448
|
this.options = t, this.element = document.createElement("div"), Object.assign(this.element.style, { display: "flex", gap: "0.375rem" }), this.onFullscreenChange = () => {
|
|
2533
2449
|
this.setFullscreenIcon(document.fullscreenElement !== null);
|
|
@@ -2539,7 +2455,7 @@ class ki {
|
|
|
2539
2455
|
fullscreenBtn = null;
|
|
2540
2456
|
onFullscreenChange;
|
|
2541
2457
|
setFullscreenIcon(t) {
|
|
2542
|
-
this.fullscreenBtn !== null && this.fullscreenBtn.setIcon(t ?
|
|
2458
|
+
this.fullscreenBtn !== null && this.fullscreenBtn.setIcon(t ? b.exitFullscreen() : b.fullscreen());
|
|
2543
2459
|
}
|
|
2544
2460
|
syncButton(t, e, i) {
|
|
2545
2461
|
if (e && t === null) {
|
|
@@ -2549,19 +2465,19 @@ class ki {
|
|
|
2549
2465
|
return !e && t !== null ? (t.element.remove(), null) : t;
|
|
2550
2466
|
}
|
|
2551
2467
|
applySettings(t) {
|
|
2552
|
-
this.arBtn = this.syncButton(this.arBtn, t.ar !== !1 && this.options.onAr !== void 0, () => new
|
|
2468
|
+
this.arBtn = this.syncButton(this.arBtn, t.ar !== !1 && this.options.onAr !== void 0, () => new g({
|
|
2553
2469
|
variant: "outline",
|
|
2554
2470
|
size: "icon",
|
|
2555
|
-
label:
|
|
2556
|
-
icon:
|
|
2471
|
+
label: ue(),
|
|
2472
|
+
icon: b.ar(),
|
|
2557
2473
|
onClick: () => {
|
|
2558
2474
|
this.options.onAr?.();
|
|
2559
2475
|
}
|
|
2560
|
-
})), this.fullscreenBtn = this.syncButton(this.fullscreenBtn, t.fullscreen !== !1 && this.options.onFullscreen !== void 0, () => new
|
|
2476
|
+
})), this.fullscreenBtn = this.syncButton(this.fullscreenBtn, t.fullscreen !== !1 && this.options.onFullscreen !== void 0, () => new g({
|
|
2561
2477
|
variant: "outline",
|
|
2562
2478
|
size: "icon",
|
|
2563
|
-
label:
|
|
2564
|
-
icon:
|
|
2479
|
+
label: Ie(),
|
|
2480
|
+
icon: b.fullscreen(),
|
|
2565
2481
|
onClick: () => {
|
|
2566
2482
|
this.options.onFullscreen?.();
|
|
2567
2483
|
}
|
|
@@ -2581,9 +2497,9 @@ class L {
|
|
|
2581
2497
|
targetTilt: e.tilt,
|
|
2582
2498
|
targetZoom: e.zoom,
|
|
2583
2499
|
thetaOffset: 0
|
|
2584
|
-
}, o =
|
|
2500
|
+
}, o = wi(t, e, i);
|
|
2585
2501
|
e.onChange((s) => {
|
|
2586
|
-
i.targetRotation = s.rotation - i.thetaOffset, i.targetTilt = s.tilt, i.targetZoom = s.zoom,
|
|
2502
|
+
i.targetRotation = s.rotation - i.thetaOffset, i.targetTilt = s.tilt, i.targetZoom = s.zoom, Ci(o, e, s);
|
|
2587
2503
|
}), this.element.appendChild(L.buildZoom(o.zoomOut, o.zoomIn)), this.element.appendChild(L.buildDpad(o.tiltUp, o.rotateLeft, o.reset, o.rotateRight, o.tiltDown));
|
|
2588
2504
|
}
|
|
2589
2505
|
static buildZoom(t, e) {
|
|
@@ -2604,7 +2520,7 @@ class L {
|
|
|
2604
2520
|
return r;
|
|
2605
2521
|
}
|
|
2606
2522
|
}
|
|
2607
|
-
function
|
|
2523
|
+
function wi(n, t, e) {
|
|
2608
2524
|
const i = (r) => Math.max(t.limits?.minZoom ?? 1, Math.min(t.limits?.maxZoom ?? 1 / 0, r)), o = (r) => {
|
|
2609
2525
|
const l = t.limits?.minRotate, d = t.limits?.maxRotate;
|
|
2610
2526
|
return l !== void 0 || d !== void 0 ? Math.max(l ?? -1 / 0, Math.min(d ?? 1 / 0, r)) : r;
|
|
@@ -2618,57 +2534,68 @@ function Si(n, t, e) {
|
|
|
2618
2534
|
u > 180 || u < 0 ? (e.targetTilt = u > 180 ? 360 - u : -u, e.thetaOffset = (e.thetaOffset + 180) % 360, n.tilt(e.targetTilt).rotate(e.targetRotation + e.thetaOffset).set()) : (e.targetTilt = u, n.tilt(e.targetTilt).set());
|
|
2619
2535
|
};
|
|
2620
2536
|
return {
|
|
2621
|
-
zoomOut: new
|
|
2537
|
+
zoomOut: new g({ variant: "outline", size: "icon", label: ln(), icon: b.zoomOut(), onClick: () => {
|
|
2622
2538
|
e.targetZoom = i(e.targetZoom - 10), n.zoom(e.targetZoom).set();
|
|
2623
2539
|
} }),
|
|
2624
|
-
zoomIn: new
|
|
2540
|
+
zoomIn: new g({ variant: "outline", size: "icon", label: on(), icon: b.zoomIn(), onClick: () => {
|
|
2625
2541
|
e.targetZoom = i(e.targetZoom + 10), n.zoom(e.targetZoom).set();
|
|
2626
2542
|
} }),
|
|
2627
|
-
tiltUp: new
|
|
2543
|
+
tiltUp: new g({ variant: "outline", size: "icon", label: _n(), icon: b.tiltUp(), onClick: () => {
|
|
2628
2544
|
s(-15);
|
|
2629
2545
|
} }),
|
|
2630
|
-
rotateLeft: new
|
|
2546
|
+
rotateLeft: new g({ variant: "outline", size: "icon", label: hn(), icon: b.rotateLeft(), onClick: () => {
|
|
2631
2547
|
e.targetRotation = o(e.targetRotation - 15), n.rotate(e.targetRotation + e.thetaOffset).set();
|
|
2632
2548
|
} }),
|
|
2633
|
-
reset: new
|
|
2549
|
+
reset: new g({ variant: "outline", size: "icon", label: Je(), icon: b.reset(), onClick: () => {
|
|
2634
2550
|
e.thetaOffset = 0, n.reset();
|
|
2635
2551
|
} }),
|
|
2636
|
-
rotateRight: new
|
|
2552
|
+
rotateRight: new g({ variant: "outline", size: "icon", label: gn(), icon: b.rotateRight(), onClick: () => {
|
|
2637
2553
|
e.targetRotation = o(e.targetRotation + 15), n.rotate(e.targetRotation + e.thetaOffset).set();
|
|
2638
2554
|
} }),
|
|
2639
|
-
tiltDown: new
|
|
2555
|
+
tiltDown: new g({ variant: "outline", size: "icon", label: Sn(), icon: b.tiltDown(), onClick: () => {
|
|
2640
2556
|
s(15);
|
|
2641
2557
|
} })
|
|
2642
2558
|
};
|
|
2643
2559
|
}
|
|
2644
|
-
function
|
|
2560
|
+
function Ci(n, t, e) {
|
|
2645
2561
|
const i = t.limits;
|
|
2646
2562
|
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);
|
|
2647
2563
|
}
|
|
2648
|
-
const
|
|
2649
|
-
|
|
2564
|
+
const I = {
|
|
2565
|
+
/** Attribute selection requested (cancelable). `detail`: `{ attribute, value }`. */
|
|
2566
|
+
SELECT: "ui:select",
|
|
2567
|
+
/** Attribute selection applied. `detail`: `{ attribute, value }`. */
|
|
2568
|
+
SELECTED: "ui:selected",
|
|
2569
|
+
/** Focus changed (bubbles). `detail`: `{ component, attributes }`, or `null` for the overview. */
|
|
2570
|
+
FOCUS_CHANGE: "vd:focus-change",
|
|
2571
|
+
/** Resolved configuration changed (bubbles). `detail`: the resolved configuration, or `null` when nothing matches. */
|
|
2572
|
+
CONFIGURATION_CHANGE: "vd:configuration-change",
|
|
2573
|
+
/** Configuration submitted (bubbles). `detail`: the resolved configuration handed to the host. */
|
|
2574
|
+
CONFIGURATION_SUBMIT: "vd:configuration-submit"
|
|
2575
|
+
}, ki = 5;
|
|
2576
|
+
let Si = 0;
|
|
2650
2577
|
function j(n) {
|
|
2651
2578
|
const t = n.replace(/([A-Z])/g, " $1").trim();
|
|
2652
2579
|
return t.charAt(0).toUpperCase() + t.slice(1).toLowerCase();
|
|
2653
2580
|
}
|
|
2654
|
-
function
|
|
2581
|
+
function Ei(n, t, e, i, o) {
|
|
2655
2582
|
const s = document.createElement("div");
|
|
2656
2583
|
s.className = "vd-attribute", s.dataset.name = n.name;
|
|
2657
2584
|
const r = document.createElement("span");
|
|
2658
|
-
r.className = "vd-attribute-label", r.textContent = j(n.name), r.id = `vd-attribute-label-${
|
|
2659
|
-
const l = n.values.find((p) => t.getValue(n.name, p)?.isSelected === !0), d = n.values.map(j), u = n.values.length <=
|
|
2585
|
+
r.className = "vd-attribute-label", r.textContent = j(n.name), r.id = `vd-attribute-label-${Si++}`, s.appendChild(r), s.setAttribute("role", "group"), s.setAttribute("aria-labelledby", r.id);
|
|
2586
|
+
const l = n.values.find((p) => t.getValue(n.name, p)?.isSelected === !0), d = n.values.map(j), u = n.values.length <= ki ? new Jt(n.values, l, d) : new te(n.name, n.values, j(n.name), l, d);
|
|
2660
2587
|
return u.onSelect((p) => {
|
|
2661
|
-
e.dispatch(
|
|
2588
|
+
e.dispatch(I.SELECT, { attribute: n.name, value: p }, !0).defaultPrevented || i(n.name, p);
|
|
2662
2589
|
}), o(n.name, (p) => {
|
|
2663
|
-
u.setSelected(p.value), e.dispatch(
|
|
2590
|
+
u.setSelected(p.value), e.dispatch(I.SELECTED, { attribute: n.name, value: p.value });
|
|
2664
2591
|
}), s.appendChild(u.element), s;
|
|
2665
2592
|
}
|
|
2666
|
-
const
|
|
2667
|
-
class
|
|
2668
|
-
constructor(t, e =
|
|
2593
|
+
const Ai = 80, xi = 2500;
|
|
2594
|
+
class Ti {
|
|
2595
|
+
constructor(t, e = xi) {
|
|
2669
2596
|
this.configuration = t, this.resetMs = e, this.element = document.createElement("div"), this.element.className = "vd-commerce vd-hidden";
|
|
2670
2597
|
const i = document.createElement("div");
|
|
2671
|
-
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
|
|
2598
|
+
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 g({ variant: "default", onClick: () => {
|
|
2672
2599
|
this.handleSubmit();
|
|
2673
2600
|
} }), this.button.element.classList.add("vd-cta", "vd-hidden"), this.element.append(i, this.button.element), this.unsubscribe = this.configuration.onRender(() => {
|
|
2674
2601
|
this.update();
|
|
@@ -2697,19 +2624,19 @@ class Ni {
|
|
|
2697
2624
|
this.priceEl.textContent = "", this.vatEl.textContent = "";
|
|
2698
2625
|
return;
|
|
2699
2626
|
}
|
|
2700
|
-
this.priceEl.textContent =
|
|
2627
|
+
this.priceEl.textContent = Ri(t.price, t.currency), this.vatEl.textContent = at(this.configuration.vatDisplay);
|
|
2701
2628
|
}
|
|
2702
2629
|
renderButton() {
|
|
2703
2630
|
const t = this.configuration.submitEnabled;
|
|
2704
|
-
this.button.element.classList.toggle("vd-hidden", !t), t && this.state === "idle" && this.setButtonText(
|
|
2631
|
+
this.button.element.classList.toggle("vd-hidden", !t), t && this.state === "idle" && this.setButtonText(at(this.configuration.buttonLabel));
|
|
2705
2632
|
}
|
|
2706
2633
|
async handleSubmit() {
|
|
2707
2634
|
if (this.state !== "busy") {
|
|
2708
|
-
this.setState("busy",
|
|
2635
|
+
this.setState("busy", Tn());
|
|
2709
2636
|
try {
|
|
2710
|
-
await this.configuration.submit(), this.setState("success",
|
|
2637
|
+
await this.configuration.submit(), this.setState("success", Nn());
|
|
2711
2638
|
} catch {
|
|
2712
|
-
this.setState("failed",
|
|
2639
|
+
this.setState("failed", Fn());
|
|
2713
2640
|
}
|
|
2714
2641
|
this.scheduleReset();
|
|
2715
2642
|
}
|
|
@@ -2726,10 +2653,10 @@ class Ni {
|
|
|
2726
2653
|
this.button.element.textContent = t, this.button.element.setAttribute("aria-label", t);
|
|
2727
2654
|
}
|
|
2728
2655
|
}
|
|
2729
|
-
function
|
|
2730
|
-
return (n ?? "").slice(0,
|
|
2656
|
+
function at(n) {
|
|
2657
|
+
return (n ?? "").slice(0, Ai);
|
|
2731
2658
|
}
|
|
2732
|
-
function
|
|
2659
|
+
function Ri(n, t) {
|
|
2733
2660
|
try {
|
|
2734
2661
|
const e = new Intl.NumberFormat(h(), { style: "currency", currency: t }), i = e.resolvedOptions().maximumFractionDigits ?? 2;
|
|
2735
2662
|
return e.format(n / 10 ** i);
|
|
@@ -2737,7 +2664,7 @@ function Ii(n, t) {
|
|
|
2737
2664
|
return `${t} ${(n / 100).toFixed(2)}`;
|
|
2738
2665
|
}
|
|
2739
2666
|
}
|
|
2740
|
-
class
|
|
2667
|
+
class Ct {
|
|
2741
2668
|
slot = null;
|
|
2742
2669
|
panel = null;
|
|
2743
2670
|
attach(t, e) {
|
|
@@ -2750,8 +2677,8 @@ class kt {
|
|
|
2750
2677
|
this.slot?.remove(), this.slot = null, this.panel = null;
|
|
2751
2678
|
}
|
|
2752
2679
|
}
|
|
2753
|
-
const
|
|
2754
|
-
class
|
|
2680
|
+
const Ii = 572;
|
|
2681
|
+
class Oi {
|
|
2755
2682
|
element = null;
|
|
2756
2683
|
body = null;
|
|
2757
2684
|
openButton = null;
|
|
@@ -2762,21 +2689,21 @@ class Mi {
|
|
|
2762
2689
|
expanded = !0;
|
|
2763
2690
|
visible = !1;
|
|
2764
2691
|
attach(t, e) {
|
|
2765
|
-
this.container = t, e.classList.add("vd-attributes-sidebar"), this.closeButton = new
|
|
2692
|
+
this.container = t, e.classList.add("vd-attributes-sidebar"), this.closeButton = new g({
|
|
2766
2693
|
variant: "ghost",
|
|
2767
2694
|
size: "icon-sm",
|
|
2768
|
-
label:
|
|
2769
|
-
icon:
|
|
2695
|
+
label: Ye(),
|
|
2696
|
+
icon: b.close({ size: 18 }),
|
|
2770
2697
|
onClick: () => {
|
|
2771
2698
|
this.expanded = !1, this.render();
|
|
2772
2699
|
}
|
|
2773
2700
|
});
|
|
2774
2701
|
const i = document.createElement("div");
|
|
2775
|
-
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
|
|
2702
|
+
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 g({
|
|
2776
2703
|
variant: "outline",
|
|
2777
2704
|
size: "default",
|
|
2778
|
-
label:
|
|
2779
|
-
icon:
|
|
2705
|
+
label: Ge(),
|
|
2706
|
+
icon: b.configurator({ size: 18 }),
|
|
2780
2707
|
onClick: () => {
|
|
2781
2708
|
this.expanded = !0, this.render();
|
|
2782
2709
|
}
|
|
@@ -2791,7 +2718,7 @@ class Mi {
|
|
|
2791
2718
|
observe() {
|
|
2792
2719
|
typeof ResizeObserver > "u" || this.container === null || (this.observer = new ResizeObserver((t) => {
|
|
2793
2720
|
const e = t[0]?.contentRect.width ?? 0;
|
|
2794
|
-
this.setCollapsible(e > 0 && e <
|
|
2721
|
+
this.setCollapsible(e > 0 && e < Ii);
|
|
2795
2722
|
}), this.observer.observe(this.container));
|
|
2796
2723
|
}
|
|
2797
2724
|
setCollapsible(t) {
|
|
@@ -2804,7 +2731,7 @@ class Mi {
|
|
|
2804
2731
|
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-collapsed", e);
|
|
2805
2732
|
}
|
|
2806
2733
|
}
|
|
2807
|
-
class
|
|
2734
|
+
class Ni {
|
|
2808
2735
|
attach(t, e) {
|
|
2809
2736
|
}
|
|
2810
2737
|
setVisible(t) {
|
|
@@ -2812,20 +2739,20 @@ class zi {
|
|
|
2812
2739
|
destroy() {
|
|
2813
2740
|
}
|
|
2814
2741
|
}
|
|
2815
|
-
const
|
|
2816
|
-
"inframe-bottom-left": () => new
|
|
2817
|
-
"sidebar-right": () => new
|
|
2818
|
-
hidden: () => new
|
|
2742
|
+
const Li = {
|
|
2743
|
+
"inframe-bottom-left": () => new Ct(),
|
|
2744
|
+
"sidebar-right": () => new Oi(),
|
|
2745
|
+
hidden: () => new Ni()
|
|
2819
2746
|
};
|
|
2820
|
-
function
|
|
2821
|
-
return (
|
|
2747
|
+
function Mi(n) {
|
|
2748
|
+
return (Li[n ?? ""] ?? (() => new Ct()))();
|
|
2822
2749
|
}
|
|
2823
2750
|
const H = _.fontFamily.sans.join(", "), G = `
|
|
2824
2751
|
position: absolute;
|
|
2825
2752
|
display: flex;
|
|
2826
2753
|
z-index: 10;
|
|
2827
2754
|
transition: inset-inline-end 0.18s ease;
|
|
2828
|
-
`,
|
|
2755
|
+
`, zi = `
|
|
2829
2756
|
/* Override browser's default black fullscreen backdrop */
|
|
2830
2757
|
.vd-container:fullscreen {
|
|
2831
2758
|
background: oklch(100% 0 0);
|
|
@@ -3023,17 +2950,17 @@ const H = _.fontFamily.sans.join(", "), G = `
|
|
|
3023
2950
|
}
|
|
3024
2951
|
|
|
3025
2952
|
`;
|
|
3026
|
-
function
|
|
3027
|
-
if (
|
|
2953
|
+
function Fi() {
|
|
2954
|
+
if (Un(), document.getElementById("vd-styles") !== null)
|
|
3028
2955
|
return;
|
|
3029
2956
|
const n = document.createElement("style");
|
|
3030
|
-
n.id = "vd-styles", n.textContent =
|
|
2957
|
+
n.id = "vd-styles", n.textContent = zi, document.head.appendChild(n);
|
|
3031
2958
|
}
|
|
3032
|
-
function
|
|
2959
|
+
function Pi(n, t) {
|
|
3033
2960
|
const e = document.createElement("a");
|
|
3034
2961
|
e.href = `data:image/png;base64,${n}`, e.download = t, e.click();
|
|
3035
2962
|
}
|
|
3036
|
-
class
|
|
2963
|
+
class $i {
|
|
3037
2964
|
options;
|
|
3038
2965
|
settings = {};
|
|
3039
2966
|
container = null;
|
|
@@ -3049,7 +2976,7 @@ class Ui {
|
|
|
3049
2976
|
this.options = t;
|
|
3050
2977
|
}
|
|
3051
2978
|
attach(t) {
|
|
3052
|
-
|
|
2979
|
+
Fi(), this.container = t, this.loading = new yi(t), this.slots.topRight = this.createSlot(t, "vd-slot-top-right"), this.slots.bottomRight = this.createSlot(t, "vd-slot-bottom-right");
|
|
3053
2980
|
}
|
|
3054
2981
|
onReady() {
|
|
3055
2982
|
this.loading?.hide(), this.loading = null, this.mountToolbar(), this.cameraControls !== null && (this.cameraControls.element.style.display = "flex"), this.layout?.setVisible(!0);
|
|
@@ -3058,7 +2985,7 @@ class Ui {
|
|
|
3058
2985
|
if (this.actionBar !== null || this.slots.bottomRight === null || this.container === null)
|
|
3059
2986
|
return;
|
|
3060
2987
|
const t = typeof this.container.requestFullscreen == "function";
|
|
3061
|
-
this.actionBar = new
|
|
2988
|
+
this.actionBar = new _i({
|
|
3062
2989
|
onAr: this.options.onAr,
|
|
3063
2990
|
onFullscreen: t ? () => {
|
|
3064
2991
|
this.toggleFullscreen();
|
|
@@ -3075,20 +3002,20 @@ class Ui {
|
|
|
3075
3002
|
this.loading?.showError(t);
|
|
3076
3003
|
}
|
|
3077
3004
|
applyViewerSettings(t) {
|
|
3078
|
-
this.settings = t, t.language !== void 0 &&
|
|
3005
|
+
this.settings = t, t.language !== void 0 && mt(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();
|
|
3079
3006
|
}
|
|
3080
3007
|
renderAttributeControls(t, e) {
|
|
3081
3008
|
if (!(this.container === null || this.slots.topRight === null) && (this.cameraControls?.element.remove(), this.cameraControls = null, this.teardownConfigurator(), this.settings.cameraControls === !0 && (this.cameraControls = new L(this.options.cameraApi, this.options.cameraPositionApi), this.cameraControls.element.style.display = "none", this.slots.topRight.appendChild(this.cameraControls.element)), this.placeScreenshotButton(), e.length !== 0)) {
|
|
3082
3009
|
this.attributes = document.createElement("div"), this.attributes.className = "vd-attributes";
|
|
3083
3010
|
for (const i of e)
|
|
3084
|
-
this.attributes.appendChild(
|
|
3011
|
+
this.attributes.appendChild(Ei(
|
|
3085
3012
|
i,
|
|
3086
3013
|
t,
|
|
3087
3014
|
this.options.eventBus,
|
|
3088
3015
|
this.options.onSelect,
|
|
3089
3016
|
this.options.onSubscribe
|
|
3090
3017
|
));
|
|
3091
|
-
this.commerce = new
|
|
3018
|
+
this.commerce = new Ti(this.options.configuration), this.attributes.appendChild(this.commerce.element), this.layout = Mi(this.settings.configuratorLayout), this.layout.attach(this.container, this.attributes);
|
|
3092
3019
|
}
|
|
3093
3020
|
}
|
|
3094
3021
|
get viewerSettings() {
|
|
@@ -3110,14 +3037,14 @@ class Ui {
|
|
|
3110
3037
|
}
|
|
3111
3038
|
syncScreenshotButton() {
|
|
3112
3039
|
const t = this.settings.screenshot === !0;
|
|
3113
|
-
t && this.screenshotBtn === null && (this.screenshotBtn = new
|
|
3040
|
+
t && this.screenshotBtn === null && (this.screenshotBtn = new g({
|
|
3114
3041
|
variant: "outline",
|
|
3115
3042
|
size: "icon",
|
|
3116
|
-
label:
|
|
3117
|
-
icon:
|
|
3043
|
+
label: Ue(),
|
|
3044
|
+
icon: b.screenshot(),
|
|
3118
3045
|
onClick: () => {
|
|
3119
3046
|
this.options.snapshotApi.take("snapshot.png").onDeveloped(({ data: e, filename: i }) => {
|
|
3120
|
-
|
|
3047
|
+
Pi(e, i);
|
|
3121
3048
|
});
|
|
3122
3049
|
}
|
|
3123
3050
|
})), !t && this.screenshotBtn !== null && (this.screenshotBtn.element.remove(), this.screenshotBtn = null);
|
|
@@ -3126,40 +3053,106 @@ class Ui {
|
|
|
3126
3053
|
this.screenshotBtn === null || this.slots.topRight === null || (this.cameraControls !== null ? this.cameraControls.element.appendChild(this.screenshotBtn.element) : this.slots.topRight.appendChild(this.screenshotBtn.element));
|
|
3127
3054
|
}
|
|
3128
3055
|
}
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3056
|
+
const Di = {};
|
|
3057
|
+
class Bi {
|
|
3058
|
+
defaultServer = "https://server.virtualdisplay.io";
|
|
3059
|
+
options;
|
|
3060
|
+
serverHost;
|
|
3061
|
+
constructor(t, e) {
|
|
3062
|
+
this.options = t, this.serverHost = e;
|
|
3132
3063
|
}
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
});
|
|
3064
|
+
/**
|
|
3065
|
+
* Create container and iframe, attach to parent element
|
|
3066
|
+
*/
|
|
3067
|
+
create() {
|
|
3068
|
+
const t = this.createContainer(), e = this.createIframe();
|
|
3069
|
+
return t.appendChild(e), this.attachToParent(t), { container: t, iframe: e };
|
|
3140
3070
|
}
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3071
|
+
createContainer() {
|
|
3072
|
+
const t = document.createElement("div");
|
|
3073
|
+
return t.className = "vd-container", Object.assign(t.style, {
|
|
3074
|
+
position: "relative",
|
|
3075
|
+
width: "100%",
|
|
3076
|
+
height: "100%",
|
|
3077
|
+
overflow: "hidden"
|
|
3078
|
+
}), t;
|
|
3146
3079
|
}
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3080
|
+
createIframe() {
|
|
3081
|
+
const t = document.createElement("iframe");
|
|
3082
|
+
return t.src = this.buildUrl(), Object.assign(t.style, {
|
|
3083
|
+
width: "100%",
|
|
3084
|
+
height: "100%",
|
|
3085
|
+
border: "none",
|
|
3086
|
+
display: "block"
|
|
3087
|
+
}), t.setAttribute("allow", "xr-spatial-tracking; fullscreen"), t;
|
|
3152
3088
|
}
|
|
3153
|
-
|
|
3154
|
-
this.
|
|
3089
|
+
attachToParent(t) {
|
|
3090
|
+
this.getParentElement().appendChild(t);
|
|
3155
3091
|
}
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3092
|
+
buildUrl() {
|
|
3093
|
+
const t = this.getServerUrl(), e = new URL(t);
|
|
3094
|
+
return 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.debug === !0 && e.searchParams.set("debug", "true"), this.options.traceparent !== void 0 && e.searchParams.set("traceparent", this.options.traceparent), e.toString();
|
|
3095
|
+
}
|
|
3096
|
+
getServerUrl() {
|
|
3097
|
+
if (this.serverHost !== void 0)
|
|
3098
|
+
return this.serverHost;
|
|
3099
|
+
if (Di?.VITE_VIRTUALDISPLAY_SERVER_HOST === void 0)
|
|
3100
|
+
return this.defaultServer;
|
|
3101
|
+
}
|
|
3102
|
+
getParentElement() {
|
|
3103
|
+
if (typeof this.options.parent != "string")
|
|
3104
|
+
return this.options.parent;
|
|
3105
|
+
const t = document.querySelector(this.options.parent);
|
|
3106
|
+
if (t === null)
|
|
3107
|
+
throw f.parentNotFound(this.options.parent);
|
|
3108
|
+
return t;
|
|
3109
|
+
}
|
|
3110
|
+
}
|
|
3111
|
+
function Ui(n) {
|
|
3112
|
+
const { messenger: t } = n;
|
|
3113
|
+
t.on(c.HANDSHAKE, (e) => {
|
|
3114
|
+
xt(e) && (w.info("Server handshake received, flushing publisher queue"), t.markReady());
|
|
3115
|
+
}), t.on(c.SESSION, (e) => {
|
|
3116
|
+
Tt(e) && n.onSession(e.sessionId);
|
|
3117
|
+
}), t.on(c.MUTATION, (e) => {
|
|
3118
|
+
Rt(e) && (n.attributes.handleMutationResult(e), n.configuration.handleSelectionChanged(n.attributes.getSelection()));
|
|
3119
|
+
}), t.on(c.SNAPSHOT, (e) => {
|
|
3120
|
+
It(e) && n.snapshot.handleSnapshotResult(e);
|
|
3121
|
+
}), t.on(c.CAMERA, (e) => {
|
|
3122
|
+
Ot(e) && n.cameraPosition.handlePositionUpdate(e);
|
|
3123
|
+
}), t.on(c.LOADING_INDICATOR, (e) => {
|
|
3124
|
+
Lt(e) && (e.error !== void 0 ? n.ui.showError(e.error) : n.ui.updateProgress(e.progress, e.phase));
|
|
3125
|
+
}), t.on(c.CONFIG, (e) => {
|
|
3126
|
+
Mt(e) && n.applyConfig(e);
|
|
3127
|
+
}), t.on(c.MAPPING, (e) => {
|
|
3128
|
+
Nt(e) && (n.attributes.handleMappingReceived(e), n.configuration.handleSelectionChanged(n.attributes.getSelection()), n.ui.renderAttributeControls(n.attributes, e.attributes), n.readyStateTracker.handleMappingReceived());
|
|
3129
|
+
}), Vi(n);
|
|
3130
|
+
}
|
|
3131
|
+
function Vi(n) {
|
|
3132
|
+
const { messenger: t } = n;
|
|
3133
|
+
t.on(c.FOCUS, (e) => {
|
|
3134
|
+
zt(e) && n.focus.handleStateReceived(e);
|
|
3135
|
+
}), t.on(c.PRICING, (e) => {
|
|
3136
|
+
Ft(e) && n.configuration.handlePricingReceived(e.pricing);
|
|
3137
|
+
});
|
|
3138
|
+
}
|
|
3139
|
+
class ji {
|
|
3140
|
+
ready = !1;
|
|
3141
|
+
onReady;
|
|
3142
|
+
constructor(t) {
|
|
3143
|
+
this.onReady = t;
|
|
3144
|
+
}
|
|
3145
|
+
handleMappingReceived() {
|
|
3146
|
+
this.ready || (this.ready = !0, w.info("Mapping received from server, client is now ready"), this.onReady?.());
|
|
3147
|
+
}
|
|
3148
|
+
get isReady() {
|
|
3149
|
+
return this.ready;
|
|
3150
|
+
}
|
|
3151
|
+
clear() {
|
|
3152
|
+
this.ready = !1;
|
|
3160
3153
|
}
|
|
3161
3154
|
}
|
|
3162
|
-
class
|
|
3155
|
+
class Hi {
|
|
3163
3156
|
attributes;
|
|
3164
3157
|
readyStateTracker;
|
|
3165
3158
|
messenger;
|
|
@@ -3173,81 +3166,72 @@ class Gi {
|
|
|
3173
3166
|
ui;
|
|
3174
3167
|
qrModal;
|
|
3175
3168
|
options;
|
|
3169
|
+
serverHost;
|
|
3176
3170
|
iframe;
|
|
3177
3171
|
container;
|
|
3178
|
-
viewerSessionId;
|
|
3179
3172
|
readyCallbacks = [];
|
|
3180
3173
|
mutationFailedCallbacks = [];
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3174
|
+
/** The viewer's tracking session id, once the server announces it (SESSION). */
|
|
3175
|
+
viewerSessionId;
|
|
3176
|
+
constructor(t, e) {
|
|
3177
|
+
this.options = t, this.serverHost = e?.serverHost, this.initializeLogging(), this.messenger = new Pt(
|
|
3178
|
+
() => this.iframe?.contentWindow ?? null,
|
|
3179
|
+
e?.messengerOptions
|
|
3180
|
+
);
|
|
3181
|
+
const i = (o) => {
|
|
3182
|
+
this.messenger.send(o);
|
|
3185
3183
|
};
|
|
3186
|
-
this.attributes = new
|
|
3187
|
-
for (const
|
|
3188
|
-
|
|
3189
|
-
}), this.snapshotApi = new
|
|
3190
|
-
this.dispatchFocusChange(
|
|
3191
|
-
}), this.configurationApi = new
|
|
3192
|
-
(
|
|
3193
|
-
this.dispatchConfigurationChange(
|
|
3184
|
+
this.attributes = new oi(i, (o, s) => {
|
|
3185
|
+
for (const r of this.mutationFailedCallbacks)
|
|
3186
|
+
r({ attribute: o, value: s });
|
|
3187
|
+
}), this.snapshotApi = new hi(i), this.annotationsApi = new Wn(i), this.cameraApi = new si(i), this.cameraPositionApi = new ri(), this.focusApi = new ui(i, (o) => {
|
|
3188
|
+
this.dispatchFocusChange(o);
|
|
3189
|
+
}), this.configurationApi = new ci(
|
|
3190
|
+
(o) => {
|
|
3191
|
+
this.dispatchConfigurationChange(o);
|
|
3194
3192
|
},
|
|
3195
|
-
(
|
|
3196
|
-
this.dispatchConfigurationSubmit(
|
|
3193
|
+
(o) => {
|
|
3194
|
+
this.dispatchConfigurationSubmit(o);
|
|
3197
3195
|
}
|
|
3198
|
-
), this.eventBus = new
|
|
3199
|
-
const
|
|
3196
|
+
), this.eventBus = new mi(), this.qrModal = new $n(), this.readyStateTracker = new ji(() => {
|
|
3197
|
+
const o = this.readyCallbacks;
|
|
3200
3198
|
this.readyCallbacks = [];
|
|
3201
|
-
for (const
|
|
3202
|
-
|
|
3199
|
+
for (const s of o)
|
|
3200
|
+
s(this);
|
|
3203
3201
|
this.ui.onReady();
|
|
3204
|
-
}), this.ui = new
|
|
3202
|
+
}), this.ui = new $i({
|
|
3205
3203
|
snapshotApi: this.snapshotApi,
|
|
3206
3204
|
cameraApi: this.cameraApi,
|
|
3207
3205
|
cameraPositionApi: this.cameraPositionApi,
|
|
3208
3206
|
eventBus: this.eventBus,
|
|
3209
3207
|
configuration: this.configurationApi,
|
|
3210
|
-
onSelect: (
|
|
3211
|
-
onSubscribe: (
|
|
3208
|
+
onSelect: (o, s) => this.attributes.select(o, s),
|
|
3209
|
+
onSubscribe: (o, s) => this.attributes.onChange(o, s),
|
|
3212
3210
|
onAr: () => {
|
|
3213
3211
|
this.activateAr();
|
|
3214
3212
|
},
|
|
3215
3213
|
onFullscreenEnter: () => {
|
|
3216
3214
|
this.trackFullscreen();
|
|
3217
3215
|
}
|
|
3218
|
-
}), this.registerHandlers(), this.messenger.start(), this.createAndConnectIframe();
|
|
3219
|
-
}
|
|
3220
|
-
registerHandlers() {
|
|
3221
|
-
this.registerLifecycleHandlers(), this.messenger.on(c.MUTATION, (t) => {
|
|
3222
|
-
Zt(t) && (this.attributes.handleMutationResult(t), this.configurationApi.handleSelectionChanged(this.attributes.getSelection()));
|
|
3223
|
-
}), this.messenger.on(c.SNAPSHOT, (t) => {
|
|
3224
|
-
Wt(t) && this.snapshotApi.handleSnapshotResult(t);
|
|
3225
|
-
}), this.messenger.on(c.CAMERA, (t) => {
|
|
3226
|
-
Yt(t) && this.cameraPositionApi.handlePositionUpdate(t);
|
|
3227
|
-
}), this.messenger.on(c.LOADING_INDICATOR, (t) => {
|
|
3228
|
-
Kt(t) && (t.error !== void 0 ? this.ui.showError(t.error) : this.ui.updateProgress(t.progress, t.phase));
|
|
3229
|
-
}), this.messenger.on(c.CONFIG, (t) => {
|
|
3230
|
-
Qt(t) && this.handleConfig(t);
|
|
3231
|
-
}), this.messenger.on(c.ANNOTATION_PLACED, (t) => {
|
|
3232
|
-
Jt(t) && this.annotationsApi.handlePlaced(t.position);
|
|
3233
|
-
}), this.messenger.on(c.MAPPING, (t) => {
|
|
3234
|
-
Xt(t) && (this.attributes.handleMappingReceived(t), this.configurationApi.handleSelectionChanged(this.attributes.getSelection()), this.ui.renderAttributeControls(this.attributes, t.attributes), this.readyStateTracker.handleMappingReceived());
|
|
3235
|
-
}), this.registerFacadeStateHandlers();
|
|
3236
|
-
}
|
|
3237
|
-
/** Lifecycle handlers: the handshake (queue flush) and the tracking session id. */
|
|
3238
|
-
registerLifecycleHandlers() {
|
|
3239
|
-
this.messenger.on(c.HANDSHAKE, (t) => {
|
|
3240
|
-
Gt(t) && (C.info("Server handshake received, flushing publisher queue"), this.messenger.markReady());
|
|
3241
|
-
}), this.messenger.on(c.SESSION, (t) => {
|
|
3242
|
-
qt(t) && (this.viewerSessionId = t.sessionId);
|
|
3243
|
-
});
|
|
3216
|
+
}), this.wireIncomingMessages(), e?.registerHandlers?.(this.messenger, i), this.messenger.start(), this.createAndConnectIframe();
|
|
3244
3217
|
}
|
|
3245
|
-
/**
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3218
|
+
/** Wire the inbound viewer protocol to the facades. */
|
|
3219
|
+
wireIncomingMessages() {
|
|
3220
|
+
Ui({
|
|
3221
|
+
messenger: this.messenger,
|
|
3222
|
+
attributes: this.attributes,
|
|
3223
|
+
configuration: this.configurationApi,
|
|
3224
|
+
snapshot: this.snapshotApi,
|
|
3225
|
+
cameraPosition: this.cameraPositionApi,
|
|
3226
|
+
focus: this.focusApi,
|
|
3227
|
+
ui: this.ui,
|
|
3228
|
+
readyStateTracker: this.readyStateTracker,
|
|
3229
|
+
applyConfig: (t) => {
|
|
3230
|
+
this.handleConfig(t);
|
|
3231
|
+
},
|
|
3232
|
+
onSession: (t) => {
|
|
3233
|
+
this.viewerSessionId = t;
|
|
3234
|
+
}
|
|
3251
3235
|
});
|
|
3252
3236
|
}
|
|
3253
3237
|
/**
|
|
@@ -3256,7 +3240,7 @@ class Gi {
|
|
|
3256
3240
|
*/
|
|
3257
3241
|
dispatchFocusChange(t) {
|
|
3258
3242
|
this.container?.dispatchEvent(
|
|
3259
|
-
new CustomEvent(
|
|
3243
|
+
new CustomEvent(I.FOCUS_CHANGE, { detail: t, bubbles: !0 })
|
|
3260
3244
|
);
|
|
3261
3245
|
}
|
|
3262
3246
|
/**
|
|
@@ -3265,13 +3249,13 @@ class Gi {
|
|
|
3265
3249
|
*/
|
|
3266
3250
|
dispatchConfigurationChange(t) {
|
|
3267
3251
|
this.container?.dispatchEvent(
|
|
3268
|
-
new CustomEvent(
|
|
3252
|
+
new CustomEvent(I.CONFIGURATION_CHANGE, { detail: t ?? null, bubbles: !0 })
|
|
3269
3253
|
);
|
|
3270
3254
|
}
|
|
3271
3255
|
/** Dispatch a bubbling `vd:configuration-submit` event when the CTA is used. */
|
|
3272
3256
|
dispatchConfigurationSubmit(t) {
|
|
3273
3257
|
this.container?.dispatchEvent(
|
|
3274
|
-
new CustomEvent(
|
|
3258
|
+
new CustomEvent(I.CONFIGURATION_SUBMIT, { detail: t, bubbles: !0 })
|
|
3275
3259
|
);
|
|
3276
3260
|
}
|
|
3277
3261
|
handleConfig(t) {
|
|
@@ -3280,14 +3264,14 @@ class Gi {
|
|
|
3280
3264
|
const o = i !== void 0 ? { ...e ?? {}, ...i } : e;
|
|
3281
3265
|
if (i !== void 0 && e !== void 0) {
|
|
3282
3266
|
const s = Object.entries(i).filter(([r, l]) => e[r] !== l).map(([r, l]) => `${r} (metadata: ${e[r] ?? "undefined"}, override: ${l})`);
|
|
3283
|
-
s.length > 0 &&
|
|
3267
|
+
s.length > 0 && w.warn(`Viewer settings override active: ${s.join(", ")}`);
|
|
3284
3268
|
}
|
|
3285
3269
|
this.ui.applyViewerSettings(o), this.annotationsApi.setEnabled(o.annotations !== !1);
|
|
3286
3270
|
}
|
|
3287
3271
|
this.cameraPositionApi.applyLimits(t.cameraLimits);
|
|
3288
3272
|
}
|
|
3289
3273
|
activateAr() {
|
|
3290
|
-
if (
|
|
3274
|
+
if (Zn()) {
|
|
3291
3275
|
this.messenger.send({ type: c.AR_ACTIVATE });
|
|
3292
3276
|
return;
|
|
3293
3277
|
}
|
|
@@ -3298,10 +3282,10 @@ class Gi {
|
|
|
3298
3282
|
this.messenger.send({ type: c.FULLSCREEN });
|
|
3299
3283
|
}
|
|
3300
3284
|
initializeLogging() {
|
|
3301
|
-
this.options.debug === !0 &&
|
|
3285
|
+
this.options.debug === !0 && ii(), w.info("Initializing Virtualdisplay client", { model: this.options.model });
|
|
3302
3286
|
}
|
|
3303
3287
|
createAndConnectIframe() {
|
|
3304
|
-
const e = new
|
|
3288
|
+
const e = new Bi(this.options, this.serverHost).create();
|
|
3305
3289
|
this.container = e.container, this.iframe = e.iframe, this.eventBus.attach(this.container), this.ui.attach(this.container);
|
|
3306
3290
|
try {
|
|
3307
3291
|
const i = new URL(this.iframe.src).origin;
|
|
@@ -3358,36 +3342,33 @@ class Gi {
|
|
|
3358
3342
|
get snapshot() {
|
|
3359
3343
|
return this.snapshotApi;
|
|
3360
3344
|
}
|
|
3361
|
-
|
|
3362
|
-
return this.ui.viewerSettings;
|
|
3363
|
-
}
|
|
3364
|
-
/**
|
|
3365
|
-
* The viewer's tracking session id, once the viewer has established it (the id
|
|
3366
|
-
* is generated inside the iframe and announced to the client). `undefined`
|
|
3367
|
-
* until then. A host page can use it to correlate its own actions, e.g. a
|
|
3368
|
-
* configurator conversion, with the viewer session.
|
|
3369
|
-
*/
|
|
3345
|
+
/** The viewer's tracking session id, for a host page to correlate its own actions. */
|
|
3370
3346
|
get sessionId() {
|
|
3371
3347
|
return this.viewerSessionId;
|
|
3372
3348
|
}
|
|
3349
|
+
get viewerSettings() {
|
|
3350
|
+
return this.ui.viewerSettings;
|
|
3351
|
+
}
|
|
3373
3352
|
destroy() {
|
|
3374
3353
|
this.readyStateTracker.clear(), this.readyCallbacks = [], this.mutationFailedCallbacks.length = 0, this.snapshotApi.clear(), this.messenger.destroy(), this.qrModal.hide(), 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;
|
|
3375
3354
|
}
|
|
3376
3355
|
}
|
|
3356
|
+
class qi extends Hi {
|
|
3357
|
+
}
|
|
3377
3358
|
export {
|
|
3378
|
-
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3359
|
+
Wn as Annotations,
|
|
3360
|
+
Xn as Attribute,
|
|
3361
|
+
Yn as AttributeValue,
|
|
3362
|
+
si as Camera,
|
|
3363
|
+
ci as Configuration,
|
|
3364
|
+
E as ERROR_CODES,
|
|
3365
|
+
ui as Focus,
|
|
3366
|
+
di as Photo,
|
|
3367
|
+
hi as Snapshot,
|
|
3368
|
+
I as VD_EVENTS,
|
|
3369
|
+
qi as VirtualdisplayClient,
|
|
3389
3370
|
f as VirtualdisplayError,
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
|
|
3371
|
+
ii as enableDebugMode,
|
|
3372
|
+
Gi as isDebugMode,
|
|
3373
|
+
w as logger
|
|
3393
3374
|
};
|