@limrun/ui 0.15.1 → 0.16.0

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.
@@ -0,0 +1,2516 @@
1
+ import { jsx as W, jsxs as te, Fragment as Ar } from "react/jsx-runtime";
2
+ import { memo as qt, useState as z, useEffect as ae, useMemo as Me, useCallback as mn, forwardRef as En, useRef as v, useImperativeHandle as pn } from "react";
3
+ import { createPortal as gn } from "react-dom";
4
+ import './index.css';function Mr(n) {
5
+ var t, c, a = "";
6
+ if (typeof n == "string" || typeof n == "number") a += n;
7
+ else if (typeof n == "object") if (Array.isArray(n)) {
8
+ var m = n.length;
9
+ for (t = 0; t < m; t++) n[t] && (c = Mr(n[t])) && (a && (a += " "), a += c);
10
+ } else for (c in n) n[c] && (a && (a += " "), a += c);
11
+ return a;
12
+ }
13
+ function Re() {
14
+ for (var n, t, c = 0, a = "", m = arguments.length; c < m; c++) (n = arguments[c]) && (t = Mr(n)) && (a && (a += " "), a += t);
15
+ return a;
16
+ }
17
+ const St = {
18
+ INJECT_KEYCODE: 0,
19
+ INJECT_TOUCH_EVENT: 2,
20
+ // iOS-specific: send two touch points in one message (Option/Alt+drag pinch)
21
+ INJECT_TWO_FINGER_TOUCH_EVENT: 18,
22
+ SET_CLIPBOARD: 9
23
+ }, L = {
24
+ ACTION_DOWN: 0,
25
+ ACTION_UP: 1,
26
+ ACTION_MOVE: 2,
27
+ ACTION_CANCEL: 3,
28
+ ACTION_POINTER_DOWN: 5,
29
+ ACTION_POINTER_UP: 6,
30
+ BUTTON_PRIMARY: 1,
31
+ BUTTON_SECONDARY: 2,
32
+ BUTTON_TERTIARY: 4
33
+ }, s = {
34
+ // Actions
35
+ ACTION_DOWN: 0,
36
+ ACTION_UP: 1,
37
+ // Meta state flags (from android.view.KeyEvent)
38
+ META_NONE: 0,
39
+ META_SHIFT_ON: 1,
40
+ META_ALT_ON: 2,
41
+ META_CTRL_ON: 4096,
42
+ // META_CTRL_LEFT_ON | META_CTRL_RIGHT_ON
43
+ META_META_ON: 65536,
44
+ KEYCODE_0: 7,
45
+ KEYCODE_1: 8,
46
+ KEYCODE_2: 9,
47
+ KEYCODE_3: 10,
48
+ KEYCODE_4: 11,
49
+ KEYCODE_5: 12,
50
+ KEYCODE_6: 13,
51
+ KEYCODE_7: 14,
52
+ KEYCODE_8: 15,
53
+ KEYCODE_9: 16,
54
+ DPAD_UP: 19,
55
+ // KEYCODE_DPAD_UP
56
+ DPAD_DOWN: 20,
57
+ // KEYCODE_DPAD_DOWN
58
+ DPAD_LEFT: 21,
59
+ // KEYCODE_DPAD_LEFT
60
+ DPAD_RIGHT: 22,
61
+ KEYCODE_A: 29,
62
+ KEYCODE_B: 30,
63
+ KEYCODE_C: 31,
64
+ KEYCODE_D: 32,
65
+ KEYCODE_E: 33,
66
+ KEYCODE_F: 34,
67
+ KEYCODE_G: 35,
68
+ KEYCODE_H: 36,
69
+ KEYCODE_I: 37,
70
+ KEYCODE_J: 38,
71
+ KEYCODE_K: 39,
72
+ KEYCODE_L: 40,
73
+ KEYCODE_M: 41,
74
+ KEYCODE_N: 42,
75
+ KEYCODE_O: 43,
76
+ KEYCODE_P: 44,
77
+ KEYCODE_Q: 45,
78
+ KEYCODE_R: 46,
79
+ KEYCODE_S: 47,
80
+ KEYCODE_T: 48,
81
+ KEYCODE_U: 49,
82
+ KEYCODE_V: 50,
83
+ KEYCODE_W: 51,
84
+ KEYCODE_X: 52,
85
+ KEYCODE_Y: 53,
86
+ KEYCODE_Z: 54,
87
+ KEYCODE_COMMA: 55,
88
+ KEYCODE_PERIOD: 56,
89
+ KEYCODE_ALT_LEFT: 57,
90
+ KEYCODE_ALT_RIGHT: 58,
91
+ KEYCODE_SHIFT_LEFT: 59,
92
+ KEYCODE_SHIFT_RIGHT: 60,
93
+ KEYCODE_TAB: 61,
94
+ KEYCODE_SPACE: 62,
95
+ ENTER: 66,
96
+ // KEYCODE_ENTER
97
+ DEL: 67,
98
+ // KEYCODE_DEL (Backspace)
99
+ KEYCODE_GRAVE: 68,
100
+ // `
101
+ KEYCODE_MINUS: 69,
102
+ // -
103
+ KEYCODE_EQUALS: 70,
104
+ // =
105
+ KEYCODE_LEFT_BRACKET: 71,
106
+ // [
107
+ KEYCODE_RIGHT_BRACKET: 72,
108
+ // ]
109
+ KEYCODE_BACKSLASH: 73,
110
+ // \
111
+ KEYCODE_SEMICOLON: 74,
112
+ // ;
113
+ KEYCODE_APOSTROPHE: 75,
114
+ // '
115
+ KEYCODE_SLASH: 76,
116
+ MENU: 82,
117
+ KEYCODE_PAGE_UP: 92,
118
+ KEYCODE_PAGE_DOWN: 93,
119
+ KEYCODE_ESCAPE: 111,
120
+ FORWARD_DEL: 112,
121
+ // KEYCODE_FORWARD_DEL (Delete key)
122
+ KEYCODE_CTRL_LEFT: 113,
123
+ KEYCODE_CTRL_RIGHT: 114,
124
+ KEYCODE_META_LEFT: 117,
125
+ KEYCODE_META_RIGHT: 118,
126
+ KEYCODE_MOVE_HOME: 122,
127
+ KEYCODE_MOVE_END: 123,
128
+ KEYCODE_INSERT: 124,
129
+ KEYCODE_F1: 131,
130
+ KEYCODE_F2: 132,
131
+ KEYCODE_F3: 133,
132
+ KEYCODE_F4: 134,
133
+ KEYCODE_F5: 135,
134
+ KEYCODE_F6: 136,
135
+ KEYCODE_F7: 137,
136
+ KEYCODE_F8: 138,
137
+ KEYCODE_F9: 139,
138
+ KEYCODE_F10: 140,
139
+ KEYCODE_F11: 141,
140
+ KEYCODE_F12: 142,
141
+ KEYCODE_NUMPAD_0: 144,
142
+ KEYCODE_NUMPAD_1: 145,
143
+ KEYCODE_NUMPAD_2: 146,
144
+ KEYCODE_NUMPAD_3: 147,
145
+ KEYCODE_NUMPAD_4: 148,
146
+ KEYCODE_NUMPAD_5: 149,
147
+ KEYCODE_NUMPAD_6: 150,
148
+ KEYCODE_NUMPAD_7: 151,
149
+ KEYCODE_NUMPAD_8: 152,
150
+ KEYCODE_NUMPAD_9: 153,
151
+ KEYCODE_NUMPAD_DIVIDE: 154,
152
+ KEYCODE_NUMPAD_MULTIPLY: 155,
153
+ KEYCODE_NUMPAD_SUBTRACT: 156,
154
+ KEYCODE_NUMPAD_ADD: 157,
155
+ KEYCODE_NUMPAD_DOT: 158,
156
+ KEYCODE_NUMPAD_COMMA: 159,
157
+ KEYCODE_NUMPAD_ENTER: 160,
158
+ KEYCODE_NUMPAD_EQUALS: 161
159
+ }, Rr = {
160
+ KeyA: s.KEYCODE_A,
161
+ KeyB: s.KEYCODE_B,
162
+ KeyC: s.KEYCODE_C,
163
+ KeyD: s.KEYCODE_D,
164
+ KeyE: s.KEYCODE_E,
165
+ KeyF: s.KEYCODE_F,
166
+ KeyG: s.KEYCODE_G,
167
+ KeyH: s.KEYCODE_H,
168
+ KeyI: s.KEYCODE_I,
169
+ KeyJ: s.KEYCODE_J,
170
+ KeyK: s.KEYCODE_K,
171
+ KeyL: s.KEYCODE_L,
172
+ KeyM: s.KEYCODE_M,
173
+ KeyN: s.KEYCODE_N,
174
+ KeyO: s.KEYCODE_O,
175
+ KeyP: s.KEYCODE_P,
176
+ KeyQ: s.KEYCODE_Q,
177
+ KeyR: s.KEYCODE_R,
178
+ KeyS: s.KEYCODE_S,
179
+ KeyT: s.KEYCODE_T,
180
+ KeyU: s.KEYCODE_U,
181
+ KeyV: s.KEYCODE_V,
182
+ KeyW: s.KEYCODE_W,
183
+ KeyX: s.KEYCODE_X,
184
+ KeyY: s.KEYCODE_Y,
185
+ KeyZ: s.KEYCODE_Z,
186
+ Digit0: s.KEYCODE_0,
187
+ Digit1: s.KEYCODE_1,
188
+ Digit2: s.KEYCODE_2,
189
+ Digit3: s.KEYCODE_3,
190
+ Digit4: s.KEYCODE_4,
191
+ Digit5: s.KEYCODE_5,
192
+ Digit6: s.KEYCODE_6,
193
+ Digit7: s.KEYCODE_7,
194
+ Digit8: s.KEYCODE_8,
195
+ Digit9: s.KEYCODE_9,
196
+ Backquote: s.KEYCODE_GRAVE,
197
+ Minus: s.KEYCODE_MINUS,
198
+ Equal: s.KEYCODE_EQUALS,
199
+ BracketLeft: s.KEYCODE_LEFT_BRACKET,
200
+ BracketRight: s.KEYCODE_RIGHT_BRACKET,
201
+ Backslash: s.KEYCODE_BACKSLASH,
202
+ Semicolon: s.KEYCODE_SEMICOLON,
203
+ Quote: s.KEYCODE_APOSTROPHE,
204
+ Comma: s.KEYCODE_COMMA,
205
+ Period: s.KEYCODE_PERIOD,
206
+ Slash: s.KEYCODE_SLASH,
207
+ Space: s.KEYCODE_SPACE,
208
+ Tab: s.KEYCODE_TAB,
209
+ Escape: s.KEYCODE_ESCAPE,
210
+ ArrowUp: s.DPAD_UP,
211
+ ArrowDown: s.DPAD_DOWN,
212
+ ArrowLeft: s.DPAD_LEFT,
213
+ ArrowRight: s.DPAD_RIGHT,
214
+ Enter: s.ENTER,
215
+ Backspace: s.DEL,
216
+ Delete: s.FORWARD_DEL,
217
+ Home: s.KEYCODE_MOVE_HOME,
218
+ End: s.KEYCODE_MOVE_END,
219
+ PageUp: s.KEYCODE_PAGE_UP,
220
+ PageDown: s.KEYCODE_PAGE_DOWN,
221
+ Insert: s.KEYCODE_INSERT,
222
+ F1: s.KEYCODE_F1,
223
+ F2: s.KEYCODE_F2,
224
+ F3: s.KEYCODE_F3,
225
+ F4: s.KEYCODE_F4,
226
+ F5: s.KEYCODE_F5,
227
+ F6: s.KEYCODE_F6,
228
+ F7: s.KEYCODE_F7,
229
+ F8: s.KEYCODE_F8,
230
+ F9: s.KEYCODE_F9,
231
+ F10: s.KEYCODE_F10,
232
+ F11: s.KEYCODE_F11,
233
+ F12: s.KEYCODE_F12,
234
+ ShiftLeft: s.KEYCODE_SHIFT_LEFT,
235
+ ShiftRight: s.KEYCODE_SHIFT_RIGHT,
236
+ ControlLeft: s.KEYCODE_CTRL_LEFT,
237
+ ControlRight: s.KEYCODE_CTRL_RIGHT,
238
+ AltLeft: s.KEYCODE_ALT_LEFT,
239
+ AltRight: s.KEYCODE_ALT_RIGHT,
240
+ MetaLeft: s.KEYCODE_META_LEFT,
241
+ MetaRight: s.KEYCODE_META_RIGHT,
242
+ // Windows/Command key
243
+ ContextMenu: s.MENU,
244
+ // Often the Menu key
245
+ // Numpad mappings
246
+ Numpad0: s.KEYCODE_NUMPAD_0,
247
+ Numpad1: s.KEYCODE_NUMPAD_1,
248
+ Numpad2: s.KEYCODE_NUMPAD_2,
249
+ Numpad3: s.KEYCODE_NUMPAD_3,
250
+ Numpad4: s.KEYCODE_NUMPAD_4,
251
+ Numpad5: s.KEYCODE_NUMPAD_5,
252
+ Numpad6: s.KEYCODE_NUMPAD_6,
253
+ Numpad7: s.KEYCODE_NUMPAD_7,
254
+ Numpad8: s.KEYCODE_NUMPAD_8,
255
+ Numpad9: s.KEYCODE_NUMPAD_9,
256
+ NumpadDivide: s.KEYCODE_NUMPAD_DIVIDE,
257
+ NumpadMultiply: s.KEYCODE_NUMPAD_MULTIPLY,
258
+ NumpadSubtract: s.KEYCODE_NUMPAD_SUBTRACT,
259
+ NumpadAdd: s.KEYCODE_NUMPAD_ADD,
260
+ NumpadDecimal: s.KEYCODE_NUMPAD_DOT,
261
+ NumpadComma: s.KEYCODE_NUMPAD_COMMA,
262
+ // Some numpads have comma
263
+ NumpadEnter: s.KEYCODE_NUMPAD_ENTER,
264
+ NumpadEqual: s.KEYCODE_NUMPAD_EQUALS
265
+ };
266
+ function At(n, t, c, a, m, E, g = 1, y = 0, Y = 0) {
267
+ const D = new ArrayBuffer(32), R = new DataView(D);
268
+ let b = 0;
269
+ return R.setUint8(b, St.INJECT_TOUCH_EVENT), b += 1, R.setUint8(b, n), b += 1, R.setBigInt64(b, BigInt(t), !0), b += 8, R.setInt32(b, Math.round(m), !0), b += 4, R.setInt32(b, Math.round(E), !0), b += 4, R.setUint16(b, c, !0), b += 2, R.setUint16(b, a, !0), b += 2, R.setInt16(b, Math.round(g * 65535), !0), b += 2, R.setInt32(b, y, !0), b += 4, R.setInt32(b, Y, !0), D;
270
+ }
271
+ function Cn(n, t, c, a, m, E, g) {
272
+ const y = new ArrayBuffer(24), Y = new DataView(y);
273
+ let D = 0;
274
+ return Y.setUint8(D, St.INJECT_TWO_FINGER_TOUCH_EVENT), D += 1, Y.setUint8(D, n), D += 1, Y.setInt32(D, Math.round(a), !0), D += 4, Y.setInt32(D, Math.round(m), !0), D += 4, Y.setInt32(D, Math.round(E), !0), D += 4, Y.setInt32(D, Math.round(g), !0), D += 4, Y.setUint16(D, t, !0), D += 2, Y.setUint16(D, c, !0), D += 2, Y.setUint16(D, 0, !0), y;
275
+ }
276
+ function yn(n, t = !0) {
277
+ const a = new TextEncoder().encode(n), m = new ArrayBuffer(14 + a.length), E = new DataView(m);
278
+ let g = 0;
279
+ return E.setUint8(g, St.SET_CLIPBOARD), g += 1, E.setBigInt64(g, BigInt(0), !1), g += 8, E.setUint8(g, t ? 1 : 0), g += 1, E.setUint32(g, a.length, !1), g += 4, new Uint8Array(m, g).set(a), m;
280
+ }
281
+ function ut(n, t, c = 0, a = 0) {
282
+ const m = new ArrayBuffer(14), E = new DataView(m);
283
+ let g = 0;
284
+ return E.setUint8(g, St.INJECT_KEYCODE), g += 1, E.setUint8(g, n), g += 1, E.setInt32(g, t, !0), g += 4, E.setInt32(g, c, !0), g += 4, E.setInt32(g, a, !0), m;
285
+ }
286
+ const Xt = "Accessibility unavailable on this device.", Rt = 500, Sr = (n, t) => Math.abs(n.x - t.x) < 0.5 && Math.abs(n.y - t.y) < 0.5 && Math.abs(n.width - t.width) < 0.5 && Math.abs(n.height - t.height) < 0.5, On = (n) => Math.max(0, n.width) * Math.max(0, n.height), vn = (n) => {
287
+ const t = n.find((c) => c.frame && c.frame.width > 0 && c.frame.height > 0);
288
+ return t?.frame ? ((Math.abs(t.frame.x) > 0.5 || Math.abs(t.frame.y) > 0.5) && console.warn(
289
+ `[ax-tree] iOS root frame is not anchored at (0,0): (${t.frame.x},${t.frame.y}). Element positions may be slightly off from the rendered video.`
290
+ ), { x: 0, y: 0, width: t.frame.width, height: t.frame.height }) : { x: 0, y: 0, width: 1, height: 1 };
291
+ }, _n = (n) => {
292
+ const t = {};
293
+ return typeof n.AXUniqueId == "string" && n.AXUniqueId.length > 0 && (t.AXUniqueId = n.AXUniqueId), typeof n.AXLabel == "string" && n.AXLabel.length > 0 && (t.AXLabel = n.AXLabel), typeof n.type == "string" && n.type.length > 0 && (t.className = n.type), t;
294
+ }, Dn = (n) => {
295
+ const t = {};
296
+ for (const [c, a] of Object.entries(n))
297
+ c !== "children" && (t[c] = a);
298
+ return t;
299
+ };
300
+ function Tn(n) {
301
+ const t = Array.isArray(n) ? n : [n], c = vn(t), a = [], m = (E, g) => {
302
+ if (a.length >= Rt) return;
303
+ const y = E.frame;
304
+ if (y && y.width > 0 && y.height > 0 && !Sr(y, c)) {
305
+ const D = E.role_description || E.role || "", R = (typeof E.AXLabel == "string" ? E.AXLabel : "") || (typeof E.title == "string" ? E.title : "") || "";
306
+ a.push({
307
+ id: typeof E.AXUniqueId == "string" && E.AXUniqueId.length > 0 ? E.AXUniqueId : g,
308
+ path: g,
309
+ label: R,
310
+ value: typeof E.AXValue == "string" ? E.AXValue : "",
311
+ role: D,
312
+ type: typeof E.type == "string" ? E.type : "",
313
+ enabled: E.enabled !== !1,
314
+ focused: E.focused === !0,
315
+ frame: { x: y.x, y: y.y, width: y.width, height: y.height },
316
+ selectors: _n(E),
317
+ raw: Dn(E)
318
+ });
319
+ }
320
+ const Y = Array.isArray(E.children) ? E.children : [];
321
+ for (let D = 0; D < Y.length && a.length < Rt; D++)
322
+ m(Y[D], `${g}.${D}`);
323
+ };
324
+ for (let E = 0; E < t.length && a.length < Rt; E++)
325
+ m(t[E], String(E));
326
+ return {
327
+ platform: "ios",
328
+ screen: { width: c.width, height: c.height },
329
+ elements: a,
330
+ capturedAt: Date.now()
331
+ };
332
+ }
333
+ const wn = (n) => {
334
+ let t = { x: 0, y: 0, width: 1, height: 1 }, c = 0;
335
+ for (const a of n) {
336
+ const m = a.parsedBounds;
337
+ if (!m) continue;
338
+ const E = m.right - m.left, g = m.bottom - m.top, y = Math.max(0, E) * Math.max(0, g);
339
+ y > c && (c = y, t = { x: 0, y: 0, width: E, height: g });
340
+ }
341
+ return t;
342
+ }, An = (n) => {
343
+ const t = {};
344
+ return typeof n.resourceId == "string" && n.resourceId.length > 0 && (t.resourceId = n.resourceId), typeof n.contentDesc == "string" && n.contentDesc.length > 0 && (t.contentDesc = n.contentDesc), typeof n.text == "string" && n.text.length > 0 && (t.text = n.text), typeof n.className == "string" && n.className.length > 0 && (t.className = n.className), t;
345
+ };
346
+ function Mn(n) {
347
+ const t = wn(n), c = [];
348
+ for (let a = 0; a < n.length && c.length < Rt; a++) {
349
+ const m = n[a], E = m.parsedBounds;
350
+ if (!E) continue;
351
+ const g = Math.max(0, E.right - E.left), y = Math.max(0, E.bottom - E.top);
352
+ if (g <= 0 || y <= 0) continue;
353
+ const Y = { x: E.left, y: E.top, width: g, height: y };
354
+ if (Sr(Y, { x: 0, y: 0, width: t.width, height: t.height })) continue;
355
+ const D = m.contentDesc || m.text || "", R = m.className || "";
356
+ c.push({
357
+ id: m.resourceId && m.resourceId.length > 0 ? m.resourceId : m.contentDesc && m.contentDesc.length > 0 ? `cd:${m.contentDesc}` : String(a),
358
+ path: String(a),
359
+ label: D,
360
+ value: typeof m.text == "string" ? m.text : "",
361
+ role: R,
362
+ type: R,
363
+ enabled: m.enabled !== !1,
364
+ focused: m.focused === !0,
365
+ frame: Y,
366
+ selectors: An(m),
367
+ raw: { ...m }
368
+ });
369
+ }
370
+ return {
371
+ platform: "android",
372
+ screen: { width: t.width, height: t.height },
373
+ elements: c,
374
+ capturedAt: Date.now()
375
+ };
376
+ }
377
+ function Rn(n, t) {
378
+ const c = Math.max(0, n.x), a = Math.max(0, n.y), m = Math.min(t.width, n.x + n.width), E = Math.min(t.height, n.y + n.height), g = Math.max(0, m - c), y = Math.max(0, E - a);
379
+ return g > 0 && y > 0 ? { x: c, y: a, width: g, height: y } : null;
380
+ }
381
+ function br(n, t) {
382
+ if (n === t) return !0;
383
+ if (n.id !== t.id || n.path !== t.path || n.label !== t.label || n.value !== t.value || n.role !== t.role || n.type !== t.type || n.enabled !== t.enabled || n.focused !== t.focused) return !1;
384
+ const c = n.frame, a = t.frame;
385
+ return c.x === a.x && c.y === a.y && c.width === a.width && c.height === a.height;
386
+ }
387
+ function Nr(n, t) {
388
+ if (n === t) return !0;
389
+ if (!n || !t || n.platform !== t.platform || n.screen.width !== t.screen.width || n.screen.height !== t.screen.height || n.elements.length !== t.elements.length) return !1;
390
+ for (let c = 0; c < n.elements.length; c++)
391
+ if (!br(n.elements[c], t.elements[c])) return !1;
392
+ return !0;
393
+ }
394
+ function Sn(n, t, c) {
395
+ let a = null, m = 1 / 0;
396
+ for (const E of n.elements) {
397
+ const g = E.frame;
398
+ if (t < g.x || c < g.y || t > g.x + g.width || c > g.y + g.height) continue;
399
+ const y = On(g);
400
+ y < m && (m = y, a = E);
401
+ }
402
+ return a;
403
+ }
404
+ function bn(n, t) {
405
+ if (t === "ios") {
406
+ if (n.selectors.AXUniqueId)
407
+ return `client.tapElement({ AXUniqueId: ${JSON.stringify(n.selectors.AXUniqueId)} })`;
408
+ if (n.selectors.AXLabel) {
409
+ const c = n.selectors.className ? `, type: ${JSON.stringify(n.selectors.className)}` : "";
410
+ return `client.tapElement({ AXLabel: ${JSON.stringify(n.selectors.AXLabel)}${c} })`;
411
+ }
412
+ return null;
413
+ }
414
+ return n.selectors.resourceId ? `client.tap({ selector: { resourceId: ${JSON.stringify(n.selectors.resourceId)} } })` : n.selectors.contentDesc ? `client.tap({ selector: { contentDesc: ${JSON.stringify(n.selectors.contentDesc)} } })` : n.selectors.text ? `client.tap({ selector: { text: ${JSON.stringify(n.selectors.text)} } })` : null;
415
+ }
416
+ function Ir(n) {
417
+ const t = n.role || n.type || "";
418
+ if (!t) return "element";
419
+ let c = t.replace(/^AX/, "");
420
+ return c.includes(".") && (c = c.split(".").pop()), c === "GenericElement" ? "Element" : (c = c.replace(/([a-z])([A-Z])/g, "$1 $2"), c);
421
+ }
422
+ const vr = 80;
423
+ function Yr(n) {
424
+ const t = Ir(n), c = n.label || n.value || "";
425
+ if (!c) return t;
426
+ const a = c.length > vr ? c.slice(0, vr).trimEnd() + "…" : c;
427
+ return `${t} · ${a}`;
428
+ }
429
+ const Nn = 500, In = 2e3, _r = 5e3, Yn = 8e3, Kn = 1200, kn = 250, Pn = () => `ax-rc-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
430
+ class Ln {
431
+ platform;
432
+ send;
433
+ onSnapshot;
434
+ onStatusChange;
435
+ baseIntervalMs;
436
+ maxBackoffMs;
437
+ androidElementTreeOptions;
438
+ pending = /* @__PURE__ */ new Map();
439
+ running = !1;
440
+ timer;
441
+ currentInterval;
442
+ lastSnapshot = null;
443
+ // Single-flight: only one outstanding request at a time. Avoids piling
444
+ // identical requests on a slow server.
445
+ inflight = !1;
446
+ // Rate-limit floor for bumpActivity so high-frequency input (drags,
447
+ // typing) doesn't trigger a request storm.
448
+ lastBumpAtMs = 0;
449
+ // Wall-clock timestamp until which we're in "activity boost" mode and
450
+ // schedule fetches at ACTIVITY_BOOST_INTERVAL_MS instead of the normal
451
+ // backed-off interval. Set by bumpActivity().
452
+ boostUntilMs = 0;
453
+ // Coarse-grained current status; deduplicated before emission so
454
+ // identical-to-current transitions are no-ops.
455
+ status = "idle";
456
+ constructor(t) {
457
+ this.platform = t.platform, this.send = t.send, this.onSnapshot = t.onSnapshot, this.onStatusChange = t.onStatusChange, this.baseIntervalMs = t.baseIntervalMs ?? Nn, this.maxBackoffMs = t.maxBackoffMs ?? In, this.androidElementTreeOptions = t.androidElementTreeOptions, this.currentInterval = this.baseIntervalMs;
458
+ }
459
+ start() {
460
+ this.running || (this.running = !0, this.currentInterval = this.baseIntervalMs, this.boostUntilMs = 0, this.setStatus("starting"), this.runOnce());
461
+ }
462
+ stop() {
463
+ this.running && (this.running = !1, this.timer !== void 0 && (window.clearTimeout(this.timer), this.timer = void 0), this.failAllPending("Inspector stopped"), this.lastSnapshot = null, this.setStatus("idle"), this.onSnapshot(null));
464
+ }
465
+ getStatus() {
466
+ return this.status;
467
+ }
468
+ setStatus(t, c) {
469
+ if (this.status !== t && (this.status = t, !!this.onStatusChange))
470
+ try {
471
+ this.onStatusChange(t, c);
472
+ } catch (a) {
473
+ console.error("[AxFetcher] onStatusChange threw:", a);
474
+ }
475
+ }
476
+ // Called after any user-driven action that's likely to change the UI
477
+ // (taps, scrolls, key events, openUrl, app termination, orientation
478
+ // change, etc.). Has two effects:
479
+ //
480
+ // 1. Resets the polling interval to base and triggers an immediate
481
+ // fetch (rate-limited so drags / rapid typing don't request-storm).
482
+ // 2. Enters a brief "boost" window during which scheduleNext() uses a
483
+ // shorter interval (ACTIVITY_BOOST_INTERVAL_MS), so we capture the
484
+ // mid- and post-animation tree without waiting for the next
485
+ // back-off cycle.
486
+ bumpActivity() {
487
+ if (!this.running) return;
488
+ const t = Date.now();
489
+ this.boostUntilMs = t + Kn;
490
+ const c = Math.max(150, Math.floor(this.baseIntervalMs / 2));
491
+ if (t - this.lastBumpAtMs < c) {
492
+ this.currentInterval = this.baseIntervalMs;
493
+ return;
494
+ }
495
+ this.lastBumpAtMs = t, this.currentInterval = this.baseIntervalMs, this.timer !== void 0 && (window.clearTimeout(this.timer), this.timer = void 0), this.inflight || this.runOnce();
496
+ }
497
+ // Fire a one-shot fetch independent of the poll loop. Useful for the
498
+ // imperative refresh() ref method customers may call.
499
+ //
500
+ // Goes through the same change-detect path as the regular poll loop —
501
+ // identical-to-last-snapshot responses do NOT re-emit via onSnapshot, so
502
+ // a customer calling refresh() in a tight loop doesn't see a stream of
503
+ // duplicate snapshots. The returned promise still resolves with the
504
+ // (possibly identical) snapshot for the caller's own use.
505
+ async refresh() {
506
+ const t = await this.requestOnce();
507
+ return this.running && this.deliver(t), t;
508
+ }
509
+ // Returns the latest snapshot delivered to onSnapshot. May be stale.
510
+ getLatest() {
511
+ return this.lastSnapshot;
512
+ }
513
+ // Called by RemoteControl's ws.onmessage when it sees a message type we own.
514
+ // Returns true when the message was a response we were waiting for.
515
+ handleMessage(t) {
516
+ if (!t || typeof t.id != "string") return !1;
517
+ const c = t.id;
518
+ if (!this.pending.get(c)) return !1;
519
+ if (this.platform === "ios") {
520
+ if (t.type !== "elementTreeResult") return !1;
521
+ const y = typeof t.error == "string" ? t.error : null;
522
+ if (y)
523
+ return this.settleReject(c, new Error(y)), !0;
524
+ const Y = typeof t.json == "string" ? t.json : "";
525
+ try {
526
+ const D = JSON.parse(Y), R = Tn(D);
527
+ this.settleResolve(c, R);
528
+ } catch (D) {
529
+ this.settleReject(c, D instanceof Error ? D : new Error(String(D)));
530
+ }
531
+ return !0;
532
+ }
533
+ if (t.type !== "getElementTreeResult") return !1;
534
+ const m = t.error;
535
+ if (m && typeof m == "object") {
536
+ const y = typeof m.message == "string" ? m.message : "getElementTree failed";
537
+ return this.settleReject(c, new Error(y)), !0;
538
+ }
539
+ const E = t.payload, g = Array.isArray(E?.nodes) ? E.nodes : [];
540
+ try {
541
+ const y = Mn(g);
542
+ this.settleResolve(c, y);
543
+ } catch (y) {
544
+ this.settleReject(c, y instanceof Error ? y : new Error(String(y)));
545
+ }
546
+ return !0;
547
+ }
548
+ buildRequest(t) {
549
+ return this.platform === "ios" ? { type: "elementTree", id: t } : { type: "getElementTree", id: t, ...this.androidElementTreeOptions };
550
+ }
551
+ async requestOnce() {
552
+ const t = Pn();
553
+ return new Promise((c, a) => {
554
+ const m = window.setTimeout(
555
+ () => {
556
+ this.pending.delete(t), a(new Error("elementTree request timed out"));
557
+ },
558
+ Yn + (this.androidElementTreeOptions?.waitForIdleTimeoutMs ?? 0)
559
+ );
560
+ this.pending.set(t, { resolve: c, reject: a, timer: m }), this.send(this.buildRequest(t)) || (window.clearTimeout(m), this.pending.delete(t), a(new Error("elementTree send failed (WebSocket not open)")));
561
+ });
562
+ }
563
+ async runOnce() {
564
+ if (this.running && !this.inflight) {
565
+ this.inflight = !0;
566
+ try {
567
+ const t = await this.requestOnce();
568
+ if (!this.running) return;
569
+ this.deliver(t);
570
+ } catch (t) {
571
+ if (!this.running) return;
572
+ const c = t instanceof Error ? t.message : String(t), a = /unavailable|not (yet )?running|failed|timeout/i.test(c);
573
+ this.currentInterval = a ? _r : Math.min(this.currentInterval * 2, this.maxBackoffMs), this.setStatus(a ? "unavailable" : "error", c);
574
+ } finally {
575
+ this.inflight = !1, this.scheduleNext();
576
+ }
577
+ }
578
+ }
579
+ deliver(t) {
580
+ const c = this.lastSnapshot;
581
+ if (Nr(c, t)) {
582
+ this.currentInterval = Math.min(this.currentInterval * 2, this.maxBackoffMs), this.lastSnapshot = t, t.errors?.includes(Xt) || this.setStatus("ready");
583
+ return;
584
+ }
585
+ this.lastSnapshot = t, this.currentInterval = this.baseIntervalMs, t.errors?.includes(Xt) ? (this.currentInterval = _r, this.setStatus("unavailable", Xt)) : this.setStatus("ready"), this.onSnapshot(t);
586
+ }
587
+ scheduleNext() {
588
+ if (!this.running) return;
589
+ this.timer !== void 0 && window.clearTimeout(this.timer);
590
+ const t = Date.now() < this.boostUntilMs ? Math.min(kn, this.currentInterval) : this.currentInterval;
591
+ this.timer = window.setTimeout(() => {
592
+ this.timer = void 0, this.runOnce();
593
+ }, t);
594
+ }
595
+ settleResolve(t, c) {
596
+ const a = this.pending.get(t);
597
+ a && (window.clearTimeout(a.timer), this.pending.delete(t), a.resolve(c));
598
+ }
599
+ settleReject(t, c) {
600
+ const a = this.pending.get(t);
601
+ a && (window.clearTimeout(a.timer), this.pending.delete(t), a.reject(c));
602
+ }
603
+ failAllPending(t) {
604
+ for (const [c, a] of this.pending.entries())
605
+ window.clearTimeout(a.timer), a.reject(new Error(t)), this.pending.delete(c);
606
+ }
607
+ }
608
+ class Un {
609
+ generation = 0;
610
+ tail = Promise.resolve();
611
+ get currentGeneration() {
612
+ return this.generation;
613
+ }
614
+ enqueue(t) {
615
+ const c = ++this.generation;
616
+ return this.append(c, t);
617
+ }
618
+ /**
619
+ * Queues related work without superseding an already queued request.
620
+ *
621
+ * The operation retains the generation current at enqueue time and becomes
622
+ * stale if a later camera request increments it before this work starts.
623
+ */
624
+ enqueueCurrent(t) {
625
+ return this.append(this.generation, t);
626
+ }
627
+ append(t, c) {
628
+ const a = {
629
+ generation: t,
630
+ isCurrent: () => t === this.generation
631
+ }, m = this.tail.then(() => c(a));
632
+ return this.tail = m.catch(() => {
633
+ }), m;
634
+ }
635
+ invalidate() {
636
+ ++this.generation;
637
+ }
638
+ }
639
+ function xn(n) {
640
+ if (!n || typeof n != "object") return null;
641
+ const t = n;
642
+ if (t.type !== "cameraRequest" || typeof t.active != "boolean") return null;
643
+ const c = { active: t.active };
644
+ return (t.facingMode === "user" || t.facingMode === "environment") && (c.facingMode = t.facingMode), c;
645
+ }
646
+ function Fn(n) {
647
+ const t = {
648
+ frameRate: { ideal: 30, max: 30 }
649
+ };
650
+ return n?.facingMode && (t.facingMode = { ideal: n.facingMode }), t;
651
+ }
652
+ function Wn(n, t) {
653
+ return !n || n.facingMode !== t.facingMode;
654
+ }
655
+ function Hn(n) {
656
+ const t = n.getSettings();
657
+ return {
658
+ width: t.width,
659
+ height: t.height,
660
+ frameRate: t.frameRate,
661
+ deviceId: t.deviceId,
662
+ label: n.label || void 0,
663
+ facingMode: t.facingMode
664
+ };
665
+ }
666
+ function $n(n) {
667
+ return {
668
+ type: "cameraResult",
669
+ granted: !0,
670
+ camera: Hn(n)
671
+ };
672
+ }
673
+ const Xn = async (n) => {
674
+ if (!n) return !1;
675
+ try {
676
+ if (typeof navigator < "u" && navigator.clipboard?.writeText)
677
+ return await navigator.clipboard.writeText(n), !0;
678
+ } catch {
679
+ }
680
+ try {
681
+ const t = document.createElement("textarea");
682
+ t.value = n, t.style.position = "fixed", t.style.opacity = "0", document.body.appendChild(t), t.select();
683
+ const c = document.execCommand("copy");
684
+ return document.body.removeChild(t), c;
685
+ } catch {
686
+ return !1;
687
+ }
688
+ }, Bn = qt(
689
+ function({ element: t, screen: c, highlighted: a, selected: m, selectable: E, onClick: g }) {
690
+ const y = Rn(t.frame, c);
691
+ if (!y) return null;
692
+ const Y = Yr(t);
693
+ return /* @__PURE__ */ W(
694
+ "button",
695
+ {
696
+ type: "button",
697
+ className: Re("rc-inspect-box", !t.enabled && "rc-inspect-box-disabled"),
698
+ "data-ax-id": t.id,
699
+ "data-ax-path": t.path,
700
+ "data-ax-label": t.label || void 0,
701
+ "data-ax-role": t.role || void 0,
702
+ "data-highlighted": a ? "true" : "false",
703
+ "data-selected": m ? "true" : "false",
704
+ "aria-label": Y,
705
+ onClick: (D) => {
706
+ E && (D.preventDefault(), D.stopPropagation(), g(t, { x: D.clientX, y: D.clientY }));
707
+ },
708
+ style: {
709
+ left: `${y.x / c.width * 100}%`,
710
+ top: `${y.y / c.height * 100}%`,
711
+ width: `${y.width / c.width * 100}%`,
712
+ height: `${y.height / c.height * 100}%`
713
+ }
714
+ }
715
+ );
716
+ },
717
+ (n, t) => n.highlighted === t.highlighted && n.selected === t.selected && n.selectable === t.selectable && n.screen.width === t.screen.width && n.screen.height === t.screen.height && n.onClick === t.onClick && br(n.element, t.element)
718
+ ), qn = 260, Vn = 220, Gn = 6, Jn = 8, zn = qt(function({
719
+ element: t,
720
+ platform: c,
721
+ anchor: a,
722
+ cursorAnchored: m,
723
+ showActions: E,
724
+ onTap: g
725
+ }) {
726
+ const [y, Y] = z(null);
727
+ ae(() => {
728
+ if (!y) return;
729
+ const X = window.setTimeout(() => Y(null), 1100);
730
+ return () => window.clearTimeout(X);
731
+ }, [y]);
732
+ const D = Me(() => {
733
+ const X = qn, oe = Vn, j = Gn, $ = Jn, Ee = typeof window < "u" ? window.innerWidth : 1024, be = typeof window < "u" ? window.innerHeight : 768, x = a.x + j + X <= Ee - $, pe = a.y - j - oe >= $;
734
+ let Ge = x ? a.x + j : a.x - j, ge = pe ? a.y - j : a.y + j;
735
+ const bt = `translate(${x ? "0" : "-100%"}, ${pe ? "-100%" : "0"})`;
736
+ return Ge = Math.max($ + (x ? 0 : X), Math.min(Ee - $ - (x ? X : 0), Ge)), ge = Math.max($ + (pe ? oe : 0), Math.min(be - $ - (pe ? 0 : oe), ge)), { left: `${Ge}px`, top: `${ge}px`, transform: bt };
737
+ }, [a.x, a.y]), R = Me(() => bn(t, c), [t, c]), b = c === "ios" ? t.selectors.AXUniqueId : t.selectors.resourceId, ie = c === "ios" ? "AXUniqueId" : "resourceId", de = mn(async (X, oe) => {
738
+ if (!X) return;
739
+ await Xn(X) && Y(oe);
740
+ }, []), me = Ir(t), lt = t.label || t.value || me, Se = Yr(t);
741
+ return gn(
742
+ /* @__PURE__ */ te(
743
+ "div",
744
+ {
745
+ className: "rc-inspect-card",
746
+ "data-cursor-anchored": m ? "true" : "false",
747
+ style: D,
748
+ onClick: (X) => X.stopPropagation(),
749
+ onMouseDown: (X) => X.stopPropagation(),
750
+ onMouseMove: (X) => X.stopPropagation(),
751
+ children: [
752
+ /* @__PURE__ */ te("div", { className: "rc-inspect-card-header", children: [
753
+ /* @__PURE__ */ W("span", { className: "rc-inspect-card-role", children: me }),
754
+ !t.enabled && /* @__PURE__ */ W("span", { className: "rc-inspect-card-tag", children: "disabled" }),
755
+ t.focused && /* @__PURE__ */ W("span", { className: "rc-inspect-card-tag rc-inspect-card-tag-blue", children: "focused" })
756
+ ] }),
757
+ /* @__PURE__ */ W("p", { className: "rc-inspect-card-title", title: Se, children: lt }),
758
+ b && /* @__PURE__ */ te("div", { className: "rc-inspect-card-row", children: [
759
+ /* @__PURE__ */ te("span", { className: "rc-inspect-card-row-label", children: [
760
+ ie,
761
+ ":"
762
+ ] }),
763
+ /* @__PURE__ */ W("span", { className: "rc-inspect-card-row-value", children: b })
764
+ ] }),
765
+ t.value && t.value !== t.label && /* @__PURE__ */ te("div", { className: "rc-inspect-card-row", children: [
766
+ /* @__PURE__ */ W("span", { className: "rc-inspect-card-row-label", children: "value:" }),
767
+ /* @__PURE__ */ W("span", { className: "rc-inspect-card-row-value", children: t.value })
768
+ ] }),
769
+ /* @__PURE__ */ te("div", { className: "rc-inspect-card-row", children: [
770
+ /* @__PURE__ */ W("span", { className: "rc-inspect-card-row-label", children: "frame:" }),
771
+ /* @__PURE__ */ te("span", { className: "rc-inspect-card-row-value", children: [
772
+ Math.round(t.frame.width),
773
+ "×",
774
+ Math.round(t.frame.height),
775
+ " @ ",
776
+ Math.round(t.frame.x),
777
+ ",",
778
+ Math.round(t.frame.y)
779
+ ] })
780
+ ] }),
781
+ E && /* @__PURE__ */ te("div", { className: "rc-inspect-card-actions", children: [
782
+ /* @__PURE__ */ W(
783
+ "button",
784
+ {
785
+ type: "button",
786
+ className: "rc-inspect-card-btn rc-inspect-card-btn-primary",
787
+ onClick: () => g(t, a),
788
+ children: "Tap"
789
+ }
790
+ ),
791
+ /* @__PURE__ */ W(
792
+ "button",
793
+ {
794
+ type: "button",
795
+ className: Re("rc-inspect-card-btn", y === "selector" && "rc-inspect-card-btn-copied"),
796
+ disabled: !R,
797
+ title: R ?? "No usable selector for this element",
798
+ onClick: () => de(R ?? void 0, "selector"),
799
+ children: y === "selector" ? "Copied!" : "Copy selector"
800
+ }
801
+ ),
802
+ /* @__PURE__ */ W(
803
+ "button",
804
+ {
805
+ type: "button",
806
+ className: Re("rc-inspect-card-btn", y === "id" && "rc-inspect-card-btn-copied"),
807
+ disabled: !b,
808
+ title: b ?? `No ${ie}`,
809
+ onClick: () => de(b, "id"),
810
+ children: y === "id" ? "Copied!" : `Copy ${ie}`
811
+ }
812
+ )
813
+ ] })
814
+ ]
815
+ }
816
+ ),
817
+ document.body
818
+ );
819
+ }), jn = qt(function({
820
+ snapshot: t,
821
+ geometry: c,
822
+ highlightedId: a,
823
+ selectedId: m,
824
+ mode: E,
825
+ cursorPosition: g,
826
+ frozenCursorPosition: y,
827
+ onSelectChange: Y,
828
+ onTapElement: D
829
+ }) {
830
+ const R = E === "select", b = R ? a !== null && a !== m : a !== null, ie = R ? a ?? m : a, de = Me(() => {
831
+ const $ = /* @__PURE__ */ new Map();
832
+ if (!t) return $;
833
+ for (const Ee of t.elements) $.set(Ee.id, Ee);
834
+ return $;
835
+ }, [t]), me = Me(() => ie ? de.get(ie) ?? null : null, [ie, de]);
836
+ if (!(!!t && !!c && t.screen.width > 0 && t.screen.height > 0 && t.elements.length > 0)) return null;
837
+ const Se = b ? g : y ?? g, X = b, oe = R && !b && m !== null, j = ($) => {
838
+ R && $.target === $.currentTarget && Y(null, null);
839
+ };
840
+ return /* @__PURE__ */ te(Ar, { children: [
841
+ /* @__PURE__ */ W(
842
+ "div",
843
+ {
844
+ className: Re("rc-inspect-overlay", R && "rc-inspect-overlay-select"),
845
+ style: {
846
+ left: `${c.left}px`,
847
+ top: `${c.top}px`,
848
+ width: `${c.width}px`,
849
+ height: `${c.height}px`
850
+ },
851
+ onClick: j,
852
+ children: t.elements.map(($) => /* @__PURE__ */ W(
853
+ Bn,
854
+ {
855
+ element: $,
856
+ screen: t.screen,
857
+ highlighted: $.id === a,
858
+ selected: $.id === m,
859
+ selectable: R,
860
+ onClick: Y
861
+ },
862
+ $.id
863
+ ))
864
+ }
865
+ ),
866
+ me && Se && /* @__PURE__ */ W(
867
+ zn,
868
+ {
869
+ element: me,
870
+ platform: t.platform,
871
+ anchor: Se,
872
+ cursorAnchored: X,
873
+ showActions: oe,
874
+ onTap: D
875
+ }
876
+ )
877
+ ] });
878
+ }), F = (...n) => {
879
+ window.debugRemoteControl && console.log(...n);
880
+ }, w = (...n) => {
881
+ window.debugRemoteControl && console.warn(...n);
882
+ }, U = (n, t, ...c) => {
883
+ if (t)
884
+ try {
885
+ t(...c);
886
+ } catch (a) {
887
+ console.error(`[RemoteControl] customer callback "${n}" threw:`, a);
888
+ }
889
+ }, Mt = (n) => Object.entries(L).find(
890
+ ([c, a]) => c.startsWith("ACTION_") && a === n
891
+ )?.[0] ?? String(n), Qn = (n) => n.includes("/android_") ? "android" : "ios", Dr = (n, t) => {
892
+ const c = new URL(n);
893
+ return c.searchParams.set("token", t), c.toString();
894
+ }, Tr = 1920, wr = 1200, Bt = 3, Zn = 1e3, ei = 15e3, ti = 3e3, ri = 4e3, ni = (n, t) => n === Tr && t === wr || n === wr && t === Tr, ii = {
895
+ ios: {
896
+ videoBorderRadiusMultiplier: 0.15,
897
+ loadingLogoSize: "20%",
898
+ // Video position as percentage of frame dimensions
899
+ videoPosition: {
900
+ portrait: { heightMultiplier: 0.9678 },
901
+ landscape: { widthMultiplier: 0.9678 }
902
+ }
903
+ },
904
+ android: {
905
+ videoBorderRadiusMultiplier: 0.13,
906
+ loadingLogoSize: "40%",
907
+ // Video position as percentage of frame dimensions
908
+ videoPosition: {
909
+ portrait: { heightMultiplier: 0.967 },
910
+ landscape: { widthMultiplier: 0.962 }
911
+ }
912
+ }
913
+ };
914
+ function oi(n) {
915
+ const t = n.code, c = Rr[t];
916
+ if (!c)
917
+ return w(`Unknown event.code: ${t}, key: ${n.key}`), null;
918
+ let a = s.META_NONE;
919
+ const m = t >= "KeyA" && t <= "KeyZ", E = n.getModifierState("CapsLock"), g = n.shiftKey;
920
+ let y = g;
921
+ return m && (y = g !== E), y && (a |= s.META_SHIFT_ON), n.ctrlKey && (a |= s.META_CTRL_ON), n.altKey && (a |= s.META_ALT_ON), n.metaKey && (a |= s.META_META_ON), { keycode: c, metaState: a };
922
+ }
923
+ const di = En(
924
+ ({
925
+ className: n,
926
+ url: t,
927
+ token: c,
928
+ sessionId: a,
929
+ openUrl: m,
930
+ showFrame: E = !0,
931
+ autoReconnect: g = !1,
932
+ onTerminated: y,
933
+ assets: Y,
934
+ onConnectionStateChange: D,
935
+ inspectMode: R,
936
+ onAxSnapshotChange: b,
937
+ onInspectSelectionChange: ie,
938
+ onAxStatusChange: de,
939
+ axPollIntervalMs: me,
940
+ axMaxBackoffMs: lt,
941
+ androidElementTreeOptions: Se,
942
+ onCameraDemandChange: X,
943
+ onCameraStats: oe,
944
+ microphoneEnabled: j = !1,
945
+ onMicrophoneStateChange: $
946
+ }, Ee) => {
947
+ const be = v(null), x = v(null), pe = v(null), [Ge, ge] = z(!1), [Vt, Je] = z(!1), [bt, Gt] = z(!1), Ne = v(!1), Nt = v(!1), [Jt, Kr] = z(!1), [kr, Pr] = z(!1), [Lr, zt] = z({}), T = v(null), H = v(null), P = v(null), Ie = v(void 0), ze = v(void 0), je = v(void 0), dt = v(void 0), Ye = v(void 0), Ce = v(0), ft = v(0), Ke = v(!1), It = v(g);
948
+ It.current = g;
949
+ const ye = v(null), Q = v(null), Oe = v(void 0), Yt = Me(() => new Un(), []), ue = v(X);
950
+ ue.current = X;
951
+ const ht = v(oe);
952
+ ht.current = oe;
953
+ const Qe = v(null), mt = v(null), Kt = v(j);
954
+ Kt.current = j;
955
+ const kt = v(!1), Ze = v($);
956
+ Ze.current = $;
957
+ const et = v(null), ce = v(null), Et = v(0), jt = v(Promise.resolve()), ke = v(null), tt = v(!1), fe = v(/* @__PURE__ */ new Map()), le = v(/* @__PURE__ */ new Map()), ve = v(/* @__PURE__ */ new Map()), _e = v(/* @__PURE__ */ new Map()), V = v(/* @__PURE__ */ new Map()), De = v(!1), [Ur, xr] = z(!1), B = v(null), Pe = v(null), rt = v({
958
+ handle: () => {
959
+ },
960
+ end: () => {
961
+ }
962
+ }), [Te, pt] = z(null), G = v(null), [Qt, Zt] = z(null), [Pt, nt] = z(null), [Lt, gt] = z(null), [Fr, er] = z(null), [Wr, tr] = z(null), Ct = v(null), ee = v(void 0), rr = (e) => {
963
+ Ct.current = e, ee.current === void 0 && (ee.current = window.requestAnimationFrame(() => {
964
+ ee.current = void 0, tr(Ct.current);
965
+ }));
966
+ }, [Hr, Le] = z(null), Ue = v(R);
967
+ Ue.current = R;
968
+ const xe = v(null);
969
+ xe.current = Qt;
970
+ const Ut = v(b);
971
+ Ut.current = b;
972
+ const Fe = v(ie);
973
+ Fe.current = ie;
974
+ const nr = v(de);
975
+ nr.current = de;
976
+ const ir = v(y);
977
+ ir.current = y;
978
+ const or = v(D);
979
+ or.current = D;
980
+ const xt = v(null), We = (e) => {
981
+ xt.current !== e && (xt.current = e, U("onConnectionStateChange", or.current, e));
982
+ }, it = R === !0 || R === "hover-only", $r = R === "hover-only" ? "hover-only" : "select", re = Me(
983
+ () => a || Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15),
984
+ [a]
985
+ ), se = Me(() => Qn(t), [t]), He = ii[se], ot = Y?.[se], cr = se === "android" && kr ? Jt ? ot?.tabletFrameLandscape : ot?.tabletFrame : Jt ? ot?.frameLandscape : ot?.frame, sr = ot?.loadingLogo, yt = E && !!cr, K = (e) => {
986
+ F(e);
987
+ }, ne = (e) => {
988
+ !P.current || P.current.readyState !== "open" || (P.current.send(e), G.current?.bumpActivity());
989
+ }, ar = -10, ur = (e, o) => {
990
+ const r = ct();
991
+ if (!r) return;
992
+ const i = Xe(r, e, o);
993
+ if (!i) return;
994
+ const { videoX: h, videoY: l, videoWidth: f, videoHeight: u } = i, p = At(
995
+ L.ACTION_DOWN,
996
+ ar,
997
+ f,
998
+ u,
999
+ h,
1000
+ l,
1001
+ 1,
1002
+ L.BUTTON_PRIMARY,
1003
+ L.BUTTON_PRIMARY
1004
+ );
1005
+ p && ne(p), window.setTimeout(() => {
1006
+ const O = At(
1007
+ L.ACTION_UP,
1008
+ ar,
1009
+ f,
1010
+ u,
1011
+ h,
1012
+ l,
1013
+ 0,
1014
+ L.BUTTON_PRIMARY,
1015
+ L.BUTTON_PRIMARY
1016
+ );
1017
+ O && ne(O);
1018
+ }, 60);
1019
+ }, Xr = (e, o) => {
1020
+ const r = ct();
1021
+ if (!r || o.screen.width <= 0 || o.screen.height <= 0) return;
1022
+ const i = e.frame.x + e.frame.width / 2, h = e.frame.y + e.frame.height / 2, l = i / o.screen.width * r.actualWidth, f = h / o.screen.height * r.actualHeight, u = r.videoRect.left + r.offsetX + l, p = r.videoRect.top + r.offsetY + f;
1023
+ ur(u, p);
1024
+ }, Ot = -1, vt = -2, we = -3, $e = (e, o, r, i, h, l) => {
1025
+ const f = At(
1026
+ e,
1027
+ o,
1028
+ r,
1029
+ i,
1030
+ h,
1031
+ l,
1032
+ 1,
1033
+ // pressure
1034
+ L.BUTTON_PRIMARY,
1035
+ L.BUTTON_PRIMARY
1036
+ );
1037
+ f && (F("[rc-touch] sendSingleTouch", {
1038
+ action: e,
1039
+ actionName: Mt(e),
1040
+ pointerId: o,
1041
+ x: h,
1042
+ y: l,
1043
+ video: { width: r, height: i }
1044
+ }), ne(f));
1045
+ }, Ae = (e, o, r) => {
1046
+ if (!r) return;
1047
+ const { videoX: i, videoY: h, videoWidth: l, videoHeight: f } = r;
1048
+ let u = null, p = null, O = 1;
1049
+ const S = L.BUTTON_PRIMARY;
1050
+ switch (o) {
1051
+ case "down":
1052
+ e !== we && rt.current.end(), u = V.current.size === 0 ? L.ACTION_DOWN : L.ACTION_POINTER_DOWN, p = { x: i, y: h }, V.current.set(e, p), e === -1 && x.current?.focus();
1053
+ break;
1054
+ case "move":
1055
+ V.current.has(e) && (u = L.ACTION_MOVE, p = { x: i, y: h }, V.current.set(e, p));
1056
+ break;
1057
+ case "up":
1058
+ case "cancel":
1059
+ V.current.has(e) && (p = V.current.get(e), V.current.delete(e), o === "cancel" ? u = L.ACTION_CANCEL : u = V.current.size === 0 ? L.ACTION_UP : L.ACTION_POINTER_UP);
1060
+ break;
1061
+ }
1062
+ if (u !== null && p !== null) {
1063
+ F("[rc-touch][mouse->touch] sending", {
1064
+ pointerId: e,
1065
+ eventType: o,
1066
+ action: u,
1067
+ actionName: Mt(u),
1068
+ positionToSend: p,
1069
+ video: { width: l, height: f },
1070
+ altHeld: De.current,
1071
+ activePointersAfter: Array.from(V.current.entries()).map(([A, C]) => ({
1072
+ id: A,
1073
+ x: C.x,
1074
+ y: C.y
1075
+ }))
1076
+ });
1077
+ const _ = At(
1078
+ u,
1079
+ e,
1080
+ l,
1081
+ f,
1082
+ p.x,
1083
+ p.y,
1084
+ O,
1085
+ S,
1086
+ S
1087
+ );
1088
+ _ && (F("[rc-touch][mouse->touch] buffer", {
1089
+ pointerId: e,
1090
+ actionName: Mt(u),
1091
+ byteLength: _.byteLength
1092
+ }), ne(_));
1093
+ } else (o === "up" || o === "cancel") && V.current.delete(e);
1094
+ }, Ft = (e) => {
1095
+ if (De.current !== e && (De.current = e, xr(e), e || pt(null), F("[rc-touch][alt] updateAltHeld", {
1096
+ nextHeld: e,
1097
+ activePointerIds: Array.from(V.current.keys())
1098
+ }), se === "ios" && P.current && P.current.readyState === "open")) {
1099
+ const o = e ? s.ACTION_DOWN : s.ACTION_UP, r = ut(
1100
+ o,
1101
+ s.KEYCODE_ALT_LEFT,
1102
+ 0,
1103
+ s.META_NONE
1104
+ );
1105
+ F("[rc-touch][alt] sending Indigo modifier keycode", {
1106
+ action: o,
1107
+ keycode: s.KEYCODE_ALT_LEFT
1108
+ }), r && ne(r);
1109
+ }
1110
+ }, ct = () => {
1111
+ const e = x.current, o = be.current;
1112
+ if (!e || !o) return null;
1113
+ const r = e.videoWidth, i = e.videoHeight;
1114
+ if (!r || !i) return null;
1115
+ const h = e.getBoundingClientRect(), l = o.getBoundingClientRect(), f = h.width, u = h.height, p = r / i, O = f / u;
1116
+ let S = f, _ = u;
1117
+ p > O ? _ = f / p : S = u * p;
1118
+ const A = (f - S) / 2, C = (u - _) / 2;
1119
+ return {
1120
+ videoWidth: r,
1121
+ videoHeight: i,
1122
+ videoRect: h,
1123
+ containerRect: l,
1124
+ actualWidth: S,
1125
+ actualHeight: _,
1126
+ offsetX: A,
1127
+ offsetY: C
1128
+ };
1129
+ }, Xe = (e, o, r) => {
1130
+ const i = o - e.videoRect.left - e.offsetX, h = r - e.videoRect.top - e.offsetY, l = Math.max(0, Math.min(e.actualWidth, i)), f = Math.max(0, Math.min(e.actualHeight, h)), u = Math.max(
1131
+ 0,
1132
+ Math.min(e.videoWidth, l / e.actualWidth * e.videoWidth)
1133
+ ), p = Math.max(
1134
+ 0,
1135
+ Math.min(e.videoHeight, f / e.actualHeight * e.videoHeight)
1136
+ );
1137
+ return {
1138
+ videoX: u,
1139
+ videoY: p,
1140
+ videoWidth: e.videoWidth,
1141
+ videoHeight: e.videoHeight
1142
+ };
1143
+ }, Br = (e, o, r) => {
1144
+ const i = o - e.videoRect.left - e.offsetX, h = r - e.videoRect.top - e.offsetY, l = Math.max(0, Math.min(e.actualWidth, i)), f = Math.max(0, Math.min(e.actualHeight, h)), u = Math.max(
1145
+ 0,
1146
+ Math.min(e.videoWidth, l / e.actualWidth * e.videoWidth)
1147
+ ), p = Math.max(
1148
+ 0,
1149
+ Math.min(e.videoHeight, f / e.actualHeight * e.videoHeight)
1150
+ ), O = e.videoWidth - u, S = e.videoHeight - p, _ = e.videoRect.left + e.offsetX, A = e.videoRect.top + e.offsetY, C = _ - e.containerRect.left + l, d = A - e.containerRect.top + f, N = _ - e.containerRect.left + (e.actualWidth - l), k = A - e.containerRect.top + (e.actualHeight - f);
1151
+ return {
1152
+ containerX: C,
1153
+ containerY: d,
1154
+ mirrorContainerX: N,
1155
+ mirrorContainerY: k,
1156
+ videoX: u,
1157
+ videoY: p,
1158
+ mirrorVideoX: O,
1159
+ mirrorVideoY: S,
1160
+ videoWidth: e.videoWidth,
1161
+ videoHeight: e.videoHeight
1162
+ };
1163
+ }, qr = (e, o, r, i, h, l, f) => {
1164
+ const u = Cn(e, o, r, i, h, l, f);
1165
+ F("[rc-touch2] sendTwoFingerMessage (iOS)", {
1166
+ actionName: Mt(e),
1167
+ video: { width: o, height: r },
1168
+ p0: { x: i, y: h },
1169
+ p1: { x: l, y: f },
1170
+ byteLength: u.byteLength
1171
+ }), ne(u);
1172
+ }, Be = (e, o, r, i, h, l, f, u, p) => {
1173
+ if (F("[rc-touch2] applyTwoFingerEvent", {
1174
+ platform: se,
1175
+ eventType: e,
1176
+ video: { width: o, height: r },
1177
+ p0: { x: i, y: h, id: u },
1178
+ p1: { x: l, y: f, id: p }
1179
+ }), e === "down" && rt.current.end(), se === "ios") {
1180
+ const O = e === "down" ? L.ACTION_DOWN : e === "move" ? L.ACTION_MOVE : L.ACTION_UP;
1181
+ qr(O, o, r, i, h, l, f);
1182
+ } else
1183
+ e === "down" ? ($e(L.ACTION_DOWN, u, o, r, i, h), $e(L.ACTION_POINTER_DOWN, p, o, r, l, f)) : e === "move" ? ($e(L.ACTION_MOVE, u, o, r, i, h), $e(L.ACTION_MOVE, p, o, r, l, f)) : ($e(L.ACTION_POINTER_UP, p, o, r, l, f), $e(L.ACTION_UP, u, o, r, i, h));
1184
+ }, Vr = (e, o, r) => {
1185
+ if (!De.current) {
1186
+ Te !== null && pt(null);
1187
+ return;
1188
+ }
1189
+ const i = Br(e, o, r);
1190
+ pt(i);
1191
+ }, Gr = (e, o, r) => {
1192
+ const i = xe.current;
1193
+ if (!i || i.screen.width <= 0 || i.screen.height <= 0) return null;
1194
+ const h = o - e.videoRect.left - e.offsetX, l = r - e.videoRect.top - e.offsetY;
1195
+ if (h < 0 || l < 0 || h > e.actualWidth || l > e.actualHeight) return null;
1196
+ const f = h / e.actualWidth * i.screen.width, u = l / e.actualHeight * i.screen.height;
1197
+ return Sn(i, f, u);
1198
+ }, he = (e) => {
1199
+ e.preventDefault(), e.stopPropagation();
1200
+ const o = ct();
1201
+ if ((Ue.current === !0 || Ue.current === "hover-only") && !("touches" in e))
1202
+ if (e.type === "mousemove") {
1203
+ if (rr({ x: e.clientX, y: e.clientY }), o) {
1204
+ const i = Gr(o, e.clientX, e.clientY);
1205
+ nt(i?.id ?? null);
1206
+ }
1207
+ } else e.type === "mouseleave" && (rr(null), nt(null));
1208
+ if (Ue.current !== !0 && (!("touches" in e) && o && (e.type === "mousemove" ? Vr(o, e.clientX, e.clientY) : e.type === "mouseleave" && pt(null)), !(!P.current || P.current.readyState !== "open" || !x.current || !o)))
1209
+ if ("touches" in e) {
1210
+ const i = e.touches, h = e.changedTouches;
1211
+ let l;
1212
+ switch (e.type) {
1213
+ case "touchstart":
1214
+ l = "down";
1215
+ break;
1216
+ case "touchmove":
1217
+ l = "move";
1218
+ break;
1219
+ case "touchend":
1220
+ l = "up";
1221
+ break;
1222
+ case "touchcancel":
1223
+ l = "cancel";
1224
+ break;
1225
+ default:
1226
+ return;
1227
+ }
1228
+ if (i.length === 2) {
1229
+ const f = i[0], u = i[1], p = Xe(o, f.clientX, f.clientY), O = Xe(o, u.clientX, u.clientY);
1230
+ if (!p || !O) return;
1231
+ B.current ? B.current.source === "real-touch" && (B.current.finger0 = { x: p.videoX, y: p.videoY }, B.current.finger1 = { x: O.videoX, y: O.videoY }, Be(
1232
+ "move",
1233
+ p.videoWidth,
1234
+ p.videoHeight,
1235
+ p.videoX,
1236
+ p.videoY,
1237
+ O.videoX,
1238
+ O.videoY,
1239
+ B.current.pointerId0,
1240
+ B.current.pointerId1
1241
+ )) : (B.current = {
1242
+ finger0: { x: p.videoX, y: p.videoY },
1243
+ finger1: { x: O.videoX, y: O.videoY },
1244
+ videoSize: { width: p.videoWidth, height: p.videoHeight },
1245
+ source: "real-touch",
1246
+ pointerId0: f.identifier,
1247
+ pointerId1: u.identifier
1248
+ }, Be(
1249
+ "down",
1250
+ p.videoWidth,
1251
+ p.videoHeight,
1252
+ p.videoX,
1253
+ p.videoY,
1254
+ O.videoX,
1255
+ O.videoY,
1256
+ f.identifier,
1257
+ u.identifier
1258
+ ));
1259
+ } else if (i.length < 2 && B.current?.source === "real-touch") {
1260
+ const f = B.current;
1261
+ Be(
1262
+ "up",
1263
+ f.videoSize.width,
1264
+ f.videoSize.height,
1265
+ f.finger0.x,
1266
+ f.finger0.y,
1267
+ f.finger1.x,
1268
+ f.finger1.y,
1269
+ f.pointerId0,
1270
+ f.pointerId1
1271
+ ), B.current = null;
1272
+ return;
1273
+ } else {
1274
+ if (i.length > 2)
1275
+ return;
1276
+ {
1277
+ const f = h[0];
1278
+ if (f) {
1279
+ const u = Xe(o, f.clientX, f.clientY);
1280
+ Ae(f.identifier, l, u);
1281
+ }
1282
+ }
1283
+ }
1284
+ } else {
1285
+ let h = null;
1286
+ const l = B.current?.source === "alt-mouse";
1287
+ switch (e.type) {
1288
+ case "mousedown":
1289
+ e.button === 0 && (h = "down");
1290
+ break;
1291
+ case "mousemove":
1292
+ (l || V.current.has(-1)) && (h = "move");
1293
+ break;
1294
+ case "mouseup":
1295
+ e.button === 0 && (h = "up");
1296
+ break;
1297
+ case "mouseleave":
1298
+ (l || V.current.has(-1)) && (h = "up");
1299
+ break;
1300
+ }
1301
+ if (h) {
1302
+ const f = Xe(o, e.clientX, e.clientY);
1303
+ if (!f)
1304
+ return;
1305
+ F("[rc-touch][mouse] event", {
1306
+ domType: e.type,
1307
+ eventType: h,
1308
+ button: e.button,
1309
+ buttons: e.buttons,
1310
+ client: { x: e.clientX, y: e.clientY },
1311
+ altHeldRef: De.current,
1312
+ inTwoFingerMode: l,
1313
+ geometry: {
1314
+ videoX: f.videoX,
1315
+ videoY: f.videoY,
1316
+ videoWidth: f.videoWidth,
1317
+ videoHeight: f.videoHeight
1318
+ },
1319
+ activePointerIds: Array.from(V.current.keys())
1320
+ }), De.current || l ? Jr(h, f) : Ae(-1, h, f);
1321
+ }
1322
+ }
1323
+ }, Jr = (e, o) => {
1324
+ const { videoX: r, videoY: i, videoWidth: h, videoHeight: l } = o, f = h - r, u = l - i;
1325
+ if (e === "down") {
1326
+ B.current = {
1327
+ finger0: { x: r, y: i },
1328
+ finger1: { x: f, y: u },
1329
+ videoSize: { width: h, height: l },
1330
+ source: "alt-mouse",
1331
+ pointerId0: Ot,
1332
+ pointerId1: vt
1333
+ }, x.current?.focus(), Be(
1334
+ "down",
1335
+ h,
1336
+ l,
1337
+ r,
1338
+ i,
1339
+ f,
1340
+ u,
1341
+ Ot,
1342
+ vt
1343
+ );
1344
+ return;
1345
+ }
1346
+ if (e === "move") {
1347
+ B.current?.source === "alt-mouse" && (B.current.finger0 = { x: r, y: i }, B.current.finger1 = { x: f, y: u }, Be(
1348
+ "move",
1349
+ h,
1350
+ l,
1351
+ r,
1352
+ i,
1353
+ f,
1354
+ u,
1355
+ Ot,
1356
+ vt
1357
+ ));
1358
+ return;
1359
+ }
1360
+ if (e === "up" || e === "cancel") {
1361
+ const p = B.current;
1362
+ if (p?.source === "alt-mouse") {
1363
+ const { finger0: O, finger1: S, videoSize: _ } = p;
1364
+ Be(
1365
+ "up",
1366
+ _.width,
1367
+ _.height,
1368
+ O.x,
1369
+ O.y,
1370
+ S.x,
1371
+ S.y,
1372
+ Ot,
1373
+ vt
1374
+ ), B.current = null;
1375
+ }
1376
+ return;
1377
+ }
1378
+ }, zr = 150, lr = () => {
1379
+ const e = Pe.current;
1380
+ e && (window.clearTimeout(e.endTimer), Ae(we, "up", e.pos), Pe.current = null);
1381
+ }, jr = (e) => {
1382
+ if (e.ctrlKey || De.current || B.current) return;
1383
+ const o = V.current.size;
1384
+ if (o > 1 || o === 1 && !V.current.has(we)) return;
1385
+ const r = ct();
1386
+ if (!r) return;
1387
+ const i = e.clientX - r.videoRect.left - r.offsetX, h = e.clientY - r.videoRect.top - r.offsetY;
1388
+ if (i < 0 || i > r.actualWidth || h < 0 || h > r.actualHeight)
1389
+ return;
1390
+ const l = Xe(r, e.clientX, e.clientY);
1391
+ if (!l) return;
1392
+ e.preventDefault();
1393
+ const f = (e.deltaMode === 1 ? 16 : e.deltaMode === 2 ? r.actualWidth : 1) * (r.videoWidth / r.actualWidth), u = (e.deltaMode === 1 ? 16 : e.deltaMode === 2 ? r.actualHeight : 1) * (r.videoHeight / r.actualHeight), p = -e.deltaX * f, O = -e.deltaY * u, S = (k) => {
1394
+ window.clearTimeout(k.endTimer), k.endTimer = window.setTimeout(lr, zr);
1395
+ };
1396
+ if (p === 0 && O === 0) {
1397
+ Pe.current && S(Pe.current);
1398
+ return;
1399
+ }
1400
+ const _ = () => ({
1401
+ videoWidth: l.videoWidth,
1402
+ videoHeight: l.videoHeight,
1403
+ videoX: Math.abs(p) > Math.abs(O) ? Math.min(Math.max(l.videoX, l.videoWidth * 0.2), l.videoWidth * 0.8) : l.videoX,
1404
+ videoY: Math.abs(O) >= Math.abs(p) ? Math.min(Math.max(l.videoY, l.videoHeight * 0.2), l.videoHeight * 0.8) : l.videoY
1405
+ }), A = (k) => ({
1406
+ ...k,
1407
+ videoX: Math.min(Math.max(k.videoX + p, 0), k.videoWidth),
1408
+ videoY: Math.min(Math.max(k.videoY + O, 0), k.videoHeight)
1409
+ });
1410
+ let C = Pe.current;
1411
+ if (C)
1412
+ window.clearTimeout(C.endTimer);
1413
+ else {
1414
+ const k = _();
1415
+ Ae(we, "down", k), C = { pos: k, endTimer: 0 }, Pe.current = C;
1416
+ }
1417
+ let d = C.pos, N = A(d);
1418
+ N.videoX === d.videoX && N.videoY === d.videoY && (Ae(we, "up", d), d = _(), Ae(we, "down", d), N = A(d)), Ae(we, "move", N), C.pos = N, S(C);
1419
+ };
1420
+ ae(() => {
1421
+ rt.current = { handle: jr, end: lr };
1422
+ }), ae(() => {
1423
+ const e = be.current;
1424
+ if (!e) return;
1425
+ const o = (r) => rt.current.handle(r);
1426
+ return e.addEventListener("wheel", o, { passive: !1 }), () => {
1427
+ rt.current.end(), e.removeEventListener("wheel", o);
1428
+ };
1429
+ }, []), ae(() => {
1430
+ const e = (i) => {
1431
+ i.key === "Alt" && Ft(!0);
1432
+ }, o = (i) => {
1433
+ i.key === "Alt" && Ft(!1);
1434
+ }, r = () => {
1435
+ Ft(!1);
1436
+ };
1437
+ return window.addEventListener("keydown", e, !0), window.addEventListener("keyup", o, !0), window.addEventListener("blur", r), () => {
1438
+ window.removeEventListener("keydown", e, !0), window.removeEventListener("keyup", o, !0), window.removeEventListener("blur", r);
1439
+ };
1440
+ }, []);
1441
+ const dr = (e) => {
1442
+ if (e.preventDefault(), e.stopPropagation(), F("Keyboard event:", {
1443
+ type: e.type,
1444
+ key: e.key,
1445
+ keyCode: e.keyCode,
1446
+ code: e.code,
1447
+ target: e.target.tagName,
1448
+ focused: document.activeElement === x.current
1449
+ }), document.activeElement !== x.current) {
1450
+ w("Video element not focused, skipping keyboard event");
1451
+ return;
1452
+ }
1453
+ if (!P.current || P.current.readyState !== "open") {
1454
+ w("Data channel not ready for keyboard event:", P.current?.readyState);
1455
+ return;
1456
+ }
1457
+ if (e.type === "keydown") {
1458
+ if (e.key.toLowerCase() === "v" && (e.metaKey || e.ctrlKey)) {
1459
+ F("Paste shortcut detected"), navigator.clipboard.readText().then((r) => {
1460
+ if (r) {
1461
+ F(
1462
+ "Pasting text via SET_CLIPBOARD:",
1463
+ r.substring(0, 20) + (r.length > 20 ? "..." : "")
1464
+ );
1465
+ const i = yn(r, !0);
1466
+ ne(i);
1467
+ }
1468
+ }).catch((r) => {
1469
+ console.error("Failed to read clipboard contents: ", r);
1470
+ });
1471
+ return;
1472
+ }
1473
+ if (e.key.toLowerCase() === "m" && (e.metaKey || e.ctrlKey)) {
1474
+ F("Menu shortcut detected");
1475
+ const r = ut(
1476
+ s.ACTION_DOWN,
1477
+ s.MENU,
1478
+ 0,
1479
+ s.META_NONE
1480
+ // Modifiers are handled by the shortcut check, not passed down
1481
+ );
1482
+ ne(r);
1483
+ const i = ut(
1484
+ s.ACTION_UP,
1485
+ s.MENU,
1486
+ 0,
1487
+ s.META_NONE
1488
+ );
1489
+ ne(i);
1490
+ return;
1491
+ }
1492
+ }
1493
+ const o = oi(e);
1494
+ if (o) {
1495
+ const { keycode: r, metaState: i } = o, h = e.type === "keydown" ? s.ACTION_DOWN : s.ACTION_UP;
1496
+ F(`Sending Keycode: key=${e.key}, code=${r}, action=${h}, meta=${i}`);
1497
+ const l = ut(
1498
+ h,
1499
+ r,
1500
+ 0,
1501
+ // repeat count, typically 0 for single presses
1502
+ i
1503
+ );
1504
+ ne(l);
1505
+ } else
1506
+ F(`Ignoring unhandled key event: type=${e.type}, key=${e.key}`);
1507
+ }, Qr = () => {
1508
+ T.current && T.current.readyState === WebSocket.OPEN && T.current.send(
1509
+ JSON.stringify({
1510
+ type: "keepAlive",
1511
+ sessionId: re
1512
+ })
1513
+ );
1514
+ }, fr = () => {
1515
+ Ie.current && window.clearInterval(Ie.current), Ie.current = window.setInterval(Qr, 1e4);
1516
+ }, hr = () => {
1517
+ Ie.current && (window.clearInterval(Ie.current), Ie.current = void 0);
1518
+ }, _t = () => {
1519
+ ze.current && (window.clearTimeout(ze.current), ze.current = void 0);
1520
+ }, Dt = () => {
1521
+ je.current && (window.clearTimeout(je.current), je.current = void 0);
1522
+ }, st = () => {
1523
+ dt.current && (window.clearInterval(dt.current), dt.current = void 0);
1524
+ }, at = () => {
1525
+ Ye.current !== void 0 && (window.clearTimeout(Ye.current), Ye.current = void 0);
1526
+ }, Zr = () => {
1527
+ tt.current || (tt.current = !0, st(), ge(!0), We("connected"));
1528
+ }, J = (e) => {
1529
+ for (const o of e.getTracks())
1530
+ try {
1531
+ o.stop();
1532
+ } catch (r) {
1533
+ w("track.stop() failed:", r);
1534
+ }
1535
+ }, en = () => {
1536
+ const e = Q.current;
1537
+ e && (Q.current = null, J(e));
1538
+ }, mr = (e) => {
1539
+ const o = jt.current.then(e).catch((r) => {
1540
+ w("microphone operation failed:", r);
1541
+ });
1542
+ return jt.current = o, o;
1543
+ }, Wt = () => Kt.current || kt.current, Er = (e) => {
1544
+ const o = `ui-mic-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
1545
+ ke.current = o, e.send(JSON.stringify({ type: "microphoneStart", id: o }));
1546
+ }, Ht = () => mr(() => tn()), tn = async () => {
1547
+ const e = Et.current, o = () => e === Et.current && Wt(), r = (u) => {
1548
+ U("onMicrophoneStateChange", Ze.current, {
1549
+ active: !1,
1550
+ error: u
1551
+ });
1552
+ };
1553
+ if (!o()) return;
1554
+ const i = T.current, h = et.current;
1555
+ if (!i || i.readyState !== WebSocket.OPEN || !h || ce.current) return;
1556
+ if (!navigator.mediaDevices || typeof navigator.mediaDevices.getUserMedia != "function") {
1557
+ console.warn(
1558
+ "[RemoteControl] navigator.mediaDevices.getUserMedia unavailable. getUserMedia requires a secure context (https or http://localhost)."
1559
+ ), r("Microphone capture requires a secure context (https)");
1560
+ return;
1561
+ }
1562
+ let l = null;
1563
+ try {
1564
+ l = await navigator.mediaDevices.getUserMedia({ audio: !0, video: !1 });
1565
+ } catch (u) {
1566
+ console.warn("[RemoteControl] microphone getUserMedia denied/failed:", u);
1567
+ }
1568
+ if (!o()) {
1569
+ l && J(l);
1570
+ return;
1571
+ }
1572
+ if (!l) {
1573
+ r("Microphone permission denied or no device available");
1574
+ return;
1575
+ }
1576
+ const f = l.getAudioTracks()[0] ?? null;
1577
+ if (!f) {
1578
+ J(l), r("Captured stream has no audio track");
1579
+ return;
1580
+ }
1581
+ try {
1582
+ await h.replaceTrack(f);
1583
+ } catch (u) {
1584
+ w("replaceTrack(audioTrack) failed:", u), J(l), r("Failed to attach the microphone track to the connection");
1585
+ return;
1586
+ }
1587
+ if (!o()) {
1588
+ try {
1589
+ await h.replaceTrack(null);
1590
+ } catch (u) {
1591
+ w("replaceTrack(null) on stale mic attach failed:", u);
1592
+ }
1593
+ J(l);
1594
+ return;
1595
+ }
1596
+ ce.current = l, f.onended = () => {
1597
+ ce.current === l && Tt("microphone capture ended by the browser");
1598
+ }, Er(i), U("onMicrophoneStateChange", Ze.current, {
1599
+ active: !0,
1600
+ label: f.label || void 0
1601
+ });
1602
+ }, Tt = (e) => (++Et.current, ke.current = null, mr(async () => {
1603
+ const o = et.current, r = ce.current;
1604
+ if (ce.current = null, o && r)
1605
+ try {
1606
+ await o.replaceTrack(null);
1607
+ } catch (h) {
1608
+ w("replaceTrack(null) on mic detach failed:", h);
1609
+ }
1610
+ r && J(r);
1611
+ const i = T.current;
1612
+ if (r && i && i.readyState === WebSocket.OPEN) {
1613
+ const h = `ui-mic-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
1614
+ i.send(JSON.stringify({ type: "microphoneStop", id: h }));
1615
+ }
1616
+ (r || e) && U("onMicrophoneStateChange", Ze.current, {
1617
+ active: !1,
1618
+ ...e !== void 0 && { error: e }
1619
+ });
1620
+ })), pr = (e, o) => {
1621
+ let r;
1622
+ try {
1623
+ r = $n(o), console.info(
1624
+ `[RemoteControl] camera capture: ${r.camera?.width}x${r.camera?.height} @ ${r.camera?.frameRate ?? "?"}fps` + (r.camera?.label ? ` — ${r.camera.label}` : "")
1625
+ );
1626
+ } catch (i) {
1627
+ w("getSettings() on outbound camera track failed:", i), r = {
1628
+ type: "cameraResult",
1629
+ granted: !0,
1630
+ camera: {
1631
+ label: o.label || void 0
1632
+ }
1633
+ };
1634
+ }
1635
+ e.send(JSON.stringify(r)), U("onCameraDemandChange", ue.current, !0, !0, r.camera);
1636
+ }, rn = (e) => {
1637
+ if (!e) return;
1638
+ const o = e.indexOf("/"), i = (o >= 0 ? e.slice(o + 1) : e).toUpperCase();
1639
+ return i === "HEVC" ? "H265" : i;
1640
+ }, nn = async () => {
1641
+ const e = ye.current, o = ht.current;
1642
+ if (!e || !o) return;
1643
+ let r;
1644
+ try {
1645
+ r = await e.getStats();
1646
+ } catch {
1647
+ return;
1648
+ }
1649
+ let i, h, l;
1650
+ if (r.forEach((A) => {
1651
+ A.type === "outbound-rtp" && A.kind === "video" ? i = A : A.type === "remote-inbound-rtp" && A.kind === "video" && (l = A);
1652
+ }), i?.codecId) {
1653
+ const A = r.get(i.codecId);
1654
+ A && (h = A.mimeType);
1655
+ }
1656
+ if (!i) return;
1657
+ const f = i.timestamp ?? Date.now(), u = mt.current;
1658
+ let p, O, S;
1659
+ if (u && f > u.timestamp) {
1660
+ const A = (f - u.timestamp) / 1e3;
1661
+ if (typeof i.framesEncoded == "number" && typeof u.framesEncoded == "number" && (p = Math.max(0, (i.framesEncoded - u.framesEncoded) / A)), typeof i.bytesSent == "number" && typeof u.bytesSent == "number" && (O = Math.max(0, (i.bytesSent - u.bytesSent) * 8 / A)), typeof i.packetsSent == "number" && typeof u.packetsSent == "number" && l && typeof l.packetsLost == "number" && typeof u.packetsLost == "number") {
1662
+ const C = i.packetsSent - u.packetsSent, d = l.packetsLost - u.packetsLost;
1663
+ C > 0 && (S = Math.max(0, Math.min(100, d / C * 100)));
1664
+ }
1665
+ }
1666
+ mt.current = {
1667
+ timestamp: f,
1668
+ framesEncoded: i.framesEncoded,
1669
+ bytesSent: i.bytesSent,
1670
+ packetsSent: i.packetsSent,
1671
+ packetsLost: l?.packetsLost
1672
+ };
1673
+ const _ = {
1674
+ codec: rn(h),
1675
+ encoderImplementation: i.encoderImplementation,
1676
+ hardwareAccelerated: typeof i.powerEfficientEncoder == "boolean" ? i.powerEfficientEncoder : void 0,
1677
+ framesPerSecond: p,
1678
+ framesEncoded: i.framesEncoded,
1679
+ bitrateBps: O,
1680
+ width: i.frameWidth,
1681
+ height: i.frameHeight,
1682
+ qualityLimitationReason: i.qualityLimitationReason,
1683
+ rttMs: typeof l?.roundTripTime == "number" ? l.roundTripTime * 1e3 : void 0,
1684
+ packetsLostPct: S
1685
+ };
1686
+ U("onCameraStats", ht.current, _);
1687
+ }, gr = () => {
1688
+ Qe.current === null && (mt.current = null, Qe.current = setInterval(() => {
1689
+ nn();
1690
+ }, 1e3));
1691
+ }, wt = () => {
1692
+ Qe.current !== null && (clearInterval(Qe.current), Qe.current = null), mt.current = null, U("onCameraStats", ht.current, null);
1693
+ }, on = (e, o, r, i) => Yt.enqueue(async ({ isCurrent: h }) => {
1694
+ const l = () => h() && i() && T.current === o && ye.current === r;
1695
+ if (!l()) return;
1696
+ if (!e.active) {
1697
+ const _ = Q.current;
1698
+ try {
1699
+ await r.replaceTrack(null);
1700
+ } catch (A) {
1701
+ w("replaceTrack(null) on camera detach failed:", A);
1702
+ }
1703
+ if (Q.current === _ && (Q.current = null, Oe.current = void 0, _ && J(_)), wt(), !l()) return;
1704
+ U("onCameraDemandChange", ue.current, !1);
1705
+ return;
1706
+ }
1707
+ U("onCameraDemandChange", ue.current, !0);
1708
+ const f = Q.current, u = f?.getVideoTracks()[0], p = Oe.current;
1709
+ if (u?.readyState === "live" && p && !Wn(p, e)) {
1710
+ Oe.current = e, pr(o, u), gr();
1711
+ return;
1712
+ }
1713
+ if (f) {
1714
+ try {
1715
+ await r.replaceTrack(null);
1716
+ } catch (_) {
1717
+ w("replaceTrack(null) before camera switch failed:", _);
1718
+ }
1719
+ if (Q.current === f && (Q.current = null, Oe.current = void 0, J(f)), wt(), !l()) return;
1720
+ }
1721
+ if (!navigator.mediaDevices || typeof navigator.mediaDevices.getUserMedia != "function") {
1722
+ if (console.warn(
1723
+ "[RemoteControl] navigator.mediaDevices.getUserMedia unavailable. getUserMedia requires a secure context (https or http://localhost). Replying cameraResult granted=false so limulator falls back to black frames."
1724
+ ), !l()) return;
1725
+ o.send(JSON.stringify({ type: "cameraResult", granted: !1 })), U("onCameraDemandChange", ue.current, !0, !1);
1726
+ return;
1727
+ }
1728
+ let O = null;
1729
+ try {
1730
+ O = await navigator.mediaDevices.getUserMedia({
1731
+ video: Fn(e),
1732
+ audio: !1
1733
+ });
1734
+ } catch (_) {
1735
+ console.warn("[RemoteControl] getUserMedia denied/failed:", _);
1736
+ }
1737
+ if (!l()) {
1738
+ O && J(O);
1739
+ return;
1740
+ }
1741
+ if (!O) {
1742
+ o.send(JSON.stringify({ type: "cameraResult", granted: !1 })), U("onCameraDemandChange", ue.current, !0, !1);
1743
+ return;
1744
+ }
1745
+ const S = O.getVideoTracks()[0] ?? null;
1746
+ if (!S) {
1747
+ if (J(O), !l()) return;
1748
+ o.send(JSON.stringify({ type: "cameraResult", granted: !1 })), U("onCameraDemandChange", ue.current, !0, !1);
1749
+ return;
1750
+ }
1751
+ try {
1752
+ S.contentHint = "motion";
1753
+ } catch {
1754
+ }
1755
+ try {
1756
+ await r.replaceTrack(S);
1757
+ } catch (_) {
1758
+ if (w("replaceTrack(videoTrack) failed:", _), J(O), !l()) return;
1759
+ o.send(JSON.stringify({ type: "cameraResult", granted: !1 })), U("onCameraDemandChange", ue.current, !0, !1);
1760
+ return;
1761
+ }
1762
+ if (!l()) {
1763
+ try {
1764
+ await r.replaceTrack(null);
1765
+ } catch (_) {
1766
+ w("replaceTrack(null) for stale camera attach failed:", _);
1767
+ }
1768
+ J(O);
1769
+ return;
1770
+ }
1771
+ try {
1772
+ const _ = r.getParameters();
1773
+ (!_.encodings || _.encodings.length === 0) && (_.encodings = [{}]), _.encodings[0].maxBitrate = 8e6, _.encodings[0].maxFramerate = 30, _.degradationPreference = "maintain-framerate", await r.setParameters(_);
1774
+ } catch (_) {
1775
+ w("setParameters on outbound camera failed:", _);
1776
+ }
1777
+ if (!l()) {
1778
+ try {
1779
+ await r.replaceTrack(null);
1780
+ } catch (_) {
1781
+ w("replaceTrack(null) for stale camera finalize failed:", _);
1782
+ }
1783
+ J(O);
1784
+ return;
1785
+ }
1786
+ Q.current = O, Oe.current = e, S.onended = () => {
1787
+ Q.current === O && Yt.enqueueCurrent(async ({ isCurrent: _ }) => {
1788
+ if (!(!_() || Q.current !== O || !i() || T.current !== o || ye.current !== r)) {
1789
+ try {
1790
+ await r.replaceTrack(null);
1791
+ } catch (A) {
1792
+ w("replaceTrack(null) after camera ended failed:", A);
1793
+ }
1794
+ !_() || Q.current !== O || !i() || T.current !== o || ye.current !== r || (Q.current = null, Oe.current = void 0, J(O), wt(), o.send(JSON.stringify({ type: "cameraResult", granted: !1 })), U("onCameraDemandChange", ue.current, !0, !1));
1795
+ }
1796
+ }).catch((_) => w("camera ended cleanup failed:", _));
1797
+ }, l() && (pr(o, S), gr());
1798
+ }), qe = () => {
1799
+ Dt(), at(), st(), G.current && (G.current.stop(), G.current = null), Yt.invalidate(), wt(), en(), Oe.current = void 0, ye.current = null, ++Et.current, kt.current = !1, ke.current = null, ce.current && (J(ce.current), ce.current = null, U("onMicrophoneStateChange", Ze.current, {
1800
+ active: !1
1801
+ })), et.current = null, ee.current !== void 0 && (window.cancelAnimationFrame(ee.current), ee.current = void 0), T.current && (T.current.onopen = null, T.current.onmessage = null, T.current.onerror = null, T.current.onclose = null, T.current.close(), T.current = null), H.current && (H.current.onconnectionstatechange = null, H.current.oniceconnectionstatechange = null, H.current.ontrack = null, H.current.onicecandidate = null, H.current.close(), H.current = null), x.current && (x.current.srcObject = null), P.current && (P.current.onopen = null, P.current.onclose = null, P.current.onerror = null, P.current.close(), P.current = null);
1802
+ }, Cr = () => {
1803
+ document.hidden ? hr() : fr();
1804
+ }, cn = async () => {
1805
+ if (typeof navigator < "u" && navigator.onLine === !1)
1806
+ return !1;
1807
+ let e;
1808
+ try {
1809
+ const i = new URL(t);
1810
+ i.protocol = i.protocol === "wss:" ? "https:" : i.protocol === "ws:" ? "http:" : i.protocol, e = Dr(i.toString(), c);
1811
+ } catch {
1812
+ return !1;
1813
+ }
1814
+ const o = new AbortController(), r = window.setTimeout(() => o.abort(), ri);
1815
+ try {
1816
+ return (await fetch(e, { method: "GET", cache: "no-store", signal: o.signal })).status === 404;
1817
+ } catch {
1818
+ return !1;
1819
+ } finally {
1820
+ window.clearTimeout(r);
1821
+ }
1822
+ }, sn = () => {
1823
+ Ne.current || (Ne.current = !0, Gt(!0), Je(!1), Ce.current += 1, _t(), Dt(), at(), qe(), K("Instance terminated"), We("terminated"), U("onTerminated", ir.current));
1824
+ }, an = () => {
1825
+ Ne.current || Nt.current || (Nt.current = !0, cn().then((e) => {
1826
+ Nt.current = !1, e && sn();
1827
+ }));
1828
+ }, Ve = (e, o) => {
1829
+ if (Ne.current || o !== Ce.current)
1830
+ return;
1831
+ if (an(), Ke.current) {
1832
+ if (!It.current) {
1833
+ K(`Connection failed after it was established: ${e}`), Je(!0), We("failed"), qe();
1834
+ return;
1835
+ }
1836
+ K(`Reconnecting after established session dropped: ${e}`), Ke.current = !1, ft.current = -1;
1837
+ }
1838
+ _t();
1839
+ const r = ft.current + 1;
1840
+ if (r >= Bt) {
1841
+ K(`Connection failed after ${Bt} attempts: ${e}`), Je(!0), We("failed"), qe();
1842
+ return;
1843
+ }
1844
+ K(`Retrying connection (${r + 1}/${Bt})`), We("reconnecting"), qe(), ze.current = window.setTimeout(() => {
1845
+ ze.current = void 0, o === Ce.current && yr(r);
1846
+ }, Zn);
1847
+ }, yr = async (e = 0) => {
1848
+ if (Ne.current) return;
1849
+ const o = Ce.current + 1;
1850
+ Ce.current = o, ft.current = e, Ke.current = !1, Je(!1), e === 0 && xt.current !== "reconnecting" && We("connecting"), _t(), Dt(), st(), tt.current = !1, ge(!1), qe();
1851
+ const r = () => o === Ce.current;
1852
+ je.current = window.setTimeout(() => {
1853
+ je.current = void 0, !(!r() || Ke.current) && Ve("Connection did not succeed within 15 seconds", o);
1854
+ }, ei);
1855
+ try {
1856
+ const i = new WebSocket(Dr(t, c));
1857
+ if (T.current = i, await new Promise((C, d) => {
1858
+ let N = !1;
1859
+ const k = window.setTimeout(() => d(new Error("WebSocket connection timeout")), 3e4), M = (I) => {
1860
+ N || (N = !0, window.clearTimeout(k), I());
1861
+ };
1862
+ i.onopen = () => {
1863
+ !r() || T.current !== i || M(C);
1864
+ }, i.onerror = (I) => {
1865
+ !r() || T.current !== i || (K("WebSocket error: " + I), M(() => d(new Error("WebSocket connection failed"))));
1866
+ }, i.onclose = () => {
1867
+ !r() || T.current !== i || (K("WebSocket closed"), M(() => d(new Error("WebSocket closed before connection was established"))));
1868
+ };
1869
+ }), !r() || T.current !== i)
1870
+ return;
1871
+ i.onerror = (C) => {
1872
+ !r() || T.current !== i || K("WebSocket error: " + C);
1873
+ }, i.onclose = () => {
1874
+ !r() || T.current !== i || K("WebSocket closed");
1875
+ };
1876
+ const h = new Promise((C, d) => {
1877
+ const N = (I) => {
1878
+ window.clearTimeout(k), i.removeEventListener("message", M), I();
1879
+ }, k = window.setTimeout(
1880
+ () => N(() => d(new Error("RTCConfiguration timeout"))),
1881
+ 3e4
1882
+ ), M = (I) => {
1883
+ if (!(!r() || T.current !== i))
1884
+ try {
1885
+ const q = JSON.parse(I.data);
1886
+ if (q.type === "signalingError" && q.requestType === "requestRtcConfiguration" && q.sessionId === re) {
1887
+ const Z = typeof q.error == "string" ? q.error : "Unable to load streaming configuration";
1888
+ N(() => d(new Error(Z)));
1889
+ } else q.type === "rtcConfiguration" && N(
1890
+ () => C({
1891
+ rtcConfiguration: q.rtcConfiguration,
1892
+ cameraSupported: q.cameraSupported === !0
1893
+ })
1894
+ );
1895
+ } catch (q) {
1896
+ console.error("Error handling RTC configuration:", q), N(() => d(q));
1897
+ }
1898
+ };
1899
+ i.addEventListener("message", M), i.send(
1900
+ JSON.stringify({
1901
+ type: "requestRtcConfiguration",
1902
+ sessionId: re
1903
+ })
1904
+ );
1905
+ }), { rtcConfiguration: l, cameraSupported: f } = await h;
1906
+ if (!r() || T.current !== i)
1907
+ return;
1908
+ const u = new RTCPeerConnection(l);
1909
+ H.current = u, u.addTransceiver("audio", { direction: "recvonly" });
1910
+ const p = u.addTransceiver("video", { direction: "recvonly" }), O = se === "ios" || f, S = O ? u.addTransceiver("video", {
1911
+ direction: "sendonly"
1912
+ }) : null;
1913
+ ye.current = S?.sender ?? null;
1914
+ const _ = O ? u.addTransceiver("audio", {
1915
+ direction: "sendonly"
1916
+ }) : null;
1917
+ if (et.current = _?.sender ?? null, RTCRtpReceiver.getCapabilities) {
1918
+ const C = RTCRtpReceiver.getCapabilities("video");
1919
+ if (C && C.codecs) {
1920
+ const N = C.codecs.sort((k, M) => {
1921
+ const I = (q) => {
1922
+ const Z = q.mimeType.toLowerCase();
1923
+ return Z.includes("vp9") ? 1 : Z.includes("h265") || Z.includes("hevc") ? 2 : Z.includes("h264") || Z.includes("avc") ? 3 : 4;
1924
+ };
1925
+ return I(k) - I(M);
1926
+ });
1927
+ p.setCodecPreferences(N), F("Set codec preferences:", N.map((k) => k.mimeType).join(", "));
1928
+ }
1929
+ }
1930
+ if (S && RTCRtpSender.getCapabilities) {
1931
+ const C = RTCRtpSender.getCapabilities("video");
1932
+ if (C && C.codecs) {
1933
+ const d = /* @__PURE__ */ new Set(["42e01f", "42e028", "640c1f"]), N = (M) => {
1934
+ const I = M.mimeType.toLowerCase(), Z = (M.sdpFmtpLine || "").toLowerCase().match(/profile-level-id=([0-9a-f]{6})/), hn = Z ? Z[1] : "";
1935
+ return I === "video/h265" || I === "video/hevc" ? 1 : I === "video/h264" && d.has(hn) ? 2 : I === "video/h264" ? 3 : I === "video/vp9" ? 4 : I === "video/vp8" ? 5 : I === "video/rtx" || I === "video/red" || I === "video/ulpfec" ? 0 : 6;
1936
+ }, k = [...C.codecs].sort((M, I) => N(M) - N(I));
1937
+ try {
1938
+ S.setCodecPreferences(k), F(
1939
+ "Outbound camera codec preferences:",
1940
+ k.map((M) => `${M.mimeType}${M.sdpFmtpLine ? `[${M.sdpFmtpLine}]` : ""}`).join(", ")
1941
+ );
1942
+ } catch (M) {
1943
+ w("Failed to set outbound camera codec preferences:", M);
1944
+ }
1945
+ }
1946
+ }
1947
+ const A = u.createDataChannel("control", {
1948
+ ordered: !0,
1949
+ negotiated: !0,
1950
+ id: 1
1951
+ });
1952
+ if (P.current = A, A.onopen = () => {
1953
+ if (!r() || P.current !== A || T.current !== i)
1954
+ return;
1955
+ Ke.current = !0, Dt(), K("Control channel opened"), G.current || (G.current = new Ln({
1956
+ platform: se,
1957
+ baseIntervalMs: me,
1958
+ maxBackoffMs: lt,
1959
+ androidElementTreeOptions: Se,
1960
+ send: (d) => {
1961
+ if (!T.current || T.current.readyState !== WebSocket.OPEN) return !1;
1962
+ try {
1963
+ return T.current.send(JSON.stringify(d)), !0;
1964
+ } catch {
1965
+ return !1;
1966
+ }
1967
+ },
1968
+ onSnapshot: (d) => {
1969
+ Zt((N) => Nr(N, d) ? N : d), queueMicrotask(() => {
1970
+ U("onAxSnapshotChange", Ut.current, d);
1971
+ });
1972
+ },
1973
+ onStatusChange: (d, N) => {
1974
+ U("onAxStatusChange", nr.current, d, N);
1975
+ }
1976
+ }), (Ue.current === !0 || Ue.current === "hover-only") && G.current.start());
1977
+ const C = () => {
1978
+ !r() || tt.current || P.current !== A || T.current !== i || i.readyState !== WebSocket.OPEN || i.send(JSON.stringify({ type: "requestFrame", sessionId: re }));
1979
+ };
1980
+ if (C(), st(), dt.current = window.setInterval(() => {
1981
+ if (!r() || tt.current || P.current !== A || T.current !== i || i.readyState !== WebSocket.OPEN) {
1982
+ st();
1983
+ return;
1984
+ }
1985
+ C();
1986
+ }, 250), m) {
1987
+ try {
1988
+ const d = decodeURIComponent(m);
1989
+ K("Opening URL"), i.send(
1990
+ JSON.stringify({
1991
+ type: "openUrl",
1992
+ url: d,
1993
+ sessionId: re
1994
+ })
1995
+ );
1996
+ } catch (d) {
1997
+ console.error({ error: d }, "Error decoding URL, falling back to the original URL"), i.send(
1998
+ JSON.stringify({
1999
+ type: "openUrl",
2000
+ url: m,
2001
+ sessionId: re
2002
+ })
2003
+ );
2004
+ }
2005
+ G.current?.bumpActivity();
2006
+ }
2007
+ }, A.onclose = () => {
2008
+ !r() || P.current !== A || K("Control channel closed");
2009
+ }, A.onerror = (C) => {
2010
+ !r() || P.current !== A || (console.error("Control channel error:", C), K("Control channel error: " + C));
2011
+ }, u.onconnectionstatechange = () => {
2012
+ !r() || H.current !== u || (K("Connection state: " + u.connectionState), u.connectionState === "failed" && Ve("WebRTC connection entered failed state", o));
2013
+ }, u.oniceconnectionstatechange = () => {
2014
+ if (!r() || H.current !== u)
2015
+ return;
2016
+ const C = u.iceConnectionState;
2017
+ if (K("ICE state: " + C), C === "connected" || C === "completed") {
2018
+ at(), Wt() && !ce.current && Ht();
2019
+ return;
2020
+ }
2021
+ if (C === "failed") {
2022
+ at(), Ve("ICE connection entered failed state", o);
2023
+ return;
2024
+ }
2025
+ C === "disconnected" && It.current && Ye.current === void 0 && (Ye.current = window.setTimeout(() => {
2026
+ Ye.current = void 0, !(!r() || H.current !== u) && u.iceConnectionState === "disconnected" && Ve("ICE stayed disconnected past grace period", o);
2027
+ }, ti));
2028
+ }, u.ontrack = (C) => {
2029
+ !r() || H.current !== u || (K("Received remote track: " + C.track.kind), C.track.kind === "video" && x.current && (F(`[${(/* @__PURE__ */ new Date()).toISOString()}] Video track received:`, C.track), x.current.srcObject = C.streams[0]));
2030
+ }, u.onicecandidate = (C) => {
2031
+ if (!(!r() || H.current !== u || T.current !== i))
2032
+ if (C.candidate && i.readyState === WebSocket.OPEN) {
2033
+ const d = {
2034
+ type: "candidate",
2035
+ candidate: C.candidate.candidate,
2036
+ sdpMid: C.candidate.sdpMid,
2037
+ sdpMLineIndex: C.candidate.sdpMLineIndex,
2038
+ sessionId: re
2039
+ };
2040
+ i.send(JSON.stringify(d)), K("Sent ICE candidate");
2041
+ } else
2042
+ K("ICE candidate gathering completed");
2043
+ }, i.onmessage = async (C) => {
2044
+ if (!r() || T.current !== i)
2045
+ return;
2046
+ let d;
2047
+ try {
2048
+ d = JSON.parse(C.data);
2049
+ } catch (N) {
2050
+ w("Error parsing message:", N);
2051
+ return;
2052
+ }
2053
+ if (!G.current?.handleMessage(d))
2054
+ switch (K("Received: " + d.type), d.type) {
2055
+ case "signalingError": {
2056
+ if (d.requestType !== "offer" || d.sessionId !== re)
2057
+ break;
2058
+ const M = typeof d.error == "string" ? d.error : "Unable to establish the streaming connection";
2059
+ K("Error: " + M), Ve(M, o);
2060
+ break;
2061
+ }
2062
+ case "answer":
2063
+ if (!H.current || H.current !== u) {
2064
+ K("No peer connection, skipping answer");
2065
+ break;
2066
+ }
2067
+ if (await u.setRemoteDescription(
2068
+ new RTCSessionDescription({
2069
+ type: "answer",
2070
+ sdp: d.sdp
2071
+ })
2072
+ ), !r() || H.current !== u)
2073
+ return;
2074
+ K("Set remote description");
2075
+ break;
2076
+ case "candidate":
2077
+ if (!H.current || H.current !== u) {
2078
+ K("No peer connection, skipping candidate");
2079
+ break;
2080
+ }
2081
+ if (await u.addIceCandidate(
2082
+ new RTCIceCandidate({
2083
+ candidate: d.candidate,
2084
+ sdpMid: d.sdpMid,
2085
+ sdpMLineIndex: d.sdpMLineIndex
2086
+ })
2087
+ ), !r() || H.current !== u)
2088
+ return;
2089
+ K("Added ICE candidate");
2090
+ break;
2091
+ case "screenshot":
2092
+ case "screenshotResult": {
2093
+ if (typeof d.id != "string") {
2094
+ w("Received invalid screenshot success message:", d);
2095
+ break;
2096
+ }
2097
+ const M = ci(d);
2098
+ if (M) {
2099
+ const Z = le.current.get(d.id);
2100
+ if (!Z) {
2101
+ w(`Received screenshot error for unknown or handled id: ${d.id}`);
2102
+ break;
2103
+ }
2104
+ w(`Received screenshot error for id ${d.id}: ${M}`), Z(new Error(M)), fe.current.delete(d.id), le.current.delete(d.id);
2105
+ break;
2106
+ }
2107
+ const I = si(d);
2108
+ if (!I) {
2109
+ w("Received screenshot message without image data:", d);
2110
+ break;
2111
+ }
2112
+ const q = fe.current.get(d.id);
2113
+ if (!q) {
2114
+ w(`Received screenshot data for unknown or handled id: ${d.id}`);
2115
+ break;
2116
+ }
2117
+ F(`Received screenshot data for id ${d.id}`), q(I), fe.current.delete(d.id), le.current.delete(d.id);
2118
+ break;
2119
+ }
2120
+ case "screenshotError":
2121
+ if (typeof d.id != "string" || typeof d.message != "string") {
2122
+ w("Received invalid screenshot error message:", d);
2123
+ break;
2124
+ }
2125
+ const N = le.current.get(d.id);
2126
+ if (!N) {
2127
+ w(`Received screenshot error for unknown or handled id: ${d.id}`);
2128
+ break;
2129
+ }
2130
+ w(`Received screenshot error for id ${d.id}: ${d.message}`), N(new Error(d.message)), fe.current.delete(d.id), le.current.delete(d.id);
2131
+ break;
2132
+ case "cameraRequest": {
2133
+ const M = ye.current;
2134
+ if (!M)
2135
+ break;
2136
+ const I = xn(d);
2137
+ if (!I) {
2138
+ w("Received invalid cameraRequest:", d);
2139
+ break;
2140
+ }
2141
+ console.info("[RemoteControl] cameraRequest received:", I.active, I.facingMode), await on(I, i, M, r);
2142
+ break;
2143
+ }
2144
+ case "microphoneRequest": {
2145
+ if (!et.current)
2146
+ break;
2147
+ const M = d.active === !0;
2148
+ if (kt.current = M, console.info("[RemoteControl] microphoneRequest received, active=", M), !M) {
2149
+ Kt.current || await Tt();
2150
+ break;
2151
+ }
2152
+ if (ce.current) {
2153
+ Er(i);
2154
+ break;
2155
+ }
2156
+ await Ht();
2157
+ break;
2158
+ }
2159
+ case "microphoneStartResult": {
2160
+ if (ke.current === null || d.id !== ke.current)
2161
+ break;
2162
+ ke.current = null, typeof d.error == "string" && (console.warn("[RemoteControl] microphoneStart rejected by host:", d.error), Tt(d.error));
2163
+ break;
2164
+ }
2165
+ case "terminateAppResult":
2166
+ if (typeof d.id != "string") {
2167
+ w("Received invalid terminateApp result message:", d);
2168
+ break;
2169
+ }
2170
+ if (typeof d.error == "string") {
2171
+ const M = _e.current.get(d.id);
2172
+ if (!M) {
2173
+ w(`Received terminateApp error for unknown or handled id: ${d.id}`);
2174
+ break;
2175
+ }
2176
+ w(`Received terminateApp error for id ${d.id}: ${d.error}`), M(new Error(d.error)), ve.current.delete(d.id), _e.current.delete(d.id);
2177
+ break;
2178
+ }
2179
+ const k = ve.current.get(d.id);
2180
+ if (!k) {
2181
+ w(`Received terminateApp result for unknown or handled id: ${d.id}`);
2182
+ break;
2183
+ }
2184
+ F(`Received terminateApp success for id ${d.id}`), k(), ve.current.delete(d.id), _e.current.delete(d.id);
2185
+ break;
2186
+ default:
2187
+ w(`Received unhandled message type: ${d.type}`, d);
2188
+ break;
2189
+ }
2190
+ }, H.current === u) {
2191
+ const C = await u.createOffer({
2192
+ offerToReceiveVideo: !0,
2193
+ offerToReceiveAudio: !1
2194
+ });
2195
+ if (!r() || H.current !== u || (await u.setLocalDescription(C), !r() || H.current !== u))
2196
+ return;
2197
+ r() && T.current === i && i.readyState === WebSocket.OPEN && i.send(
2198
+ JSON.stringify({
2199
+ type: "offer",
2200
+ sdp: C.sdp,
2201
+ sessionId: re
2202
+ })
2203
+ ), K("Sent offer");
2204
+ }
2205
+ } catch (i) {
2206
+ if (!r())
2207
+ return;
2208
+ const h = i instanceof Error ? i.message : String(i);
2209
+ K("Error: " + h), Ve(h, o);
2210
+ }
2211
+ }, $t = () => {
2212
+ Ne.current = !1, Gt(!1), yr(0);
2213
+ }, un = () => {
2214
+ Ce.current += 1, ft.current = 0, Ke.current = !1, _t(), at(), qe(), K("Stopped");
2215
+ }, ln = (e) => {
2216
+ e.stopPropagation(), $t();
2217
+ };
2218
+ ae(() => {
2219
+ Wt() ? Ht() : Tt();
2220
+ }, [j]), ae(() => (ge(!1), $t(), document.hidden || fr(), document.addEventListener("visibilitychange", Cr), () => {
2221
+ hr(), un(), document.removeEventListener("visibilitychange", Cr);
2222
+ }), [t, c, a]);
2223
+ const Or = () => {
2224
+ const e = ct();
2225
+ if (!e) {
2226
+ er(null);
2227
+ return;
2228
+ }
2229
+ const o = {
2230
+ left: e.videoRect.left - e.containerRect.left + e.offsetX,
2231
+ top: e.videoRect.top - e.containerRect.top + e.offsetY,
2232
+ width: e.actualWidth,
2233
+ height: e.actualHeight
2234
+ };
2235
+ er(
2236
+ (r) => r && r.left === o.left && r.top === o.top && r.width === o.width && r.height === o.height ? r : o
2237
+ );
2238
+ };
2239
+ ae(() => {
2240
+ const e = x.current, o = pe.current, r = be.current;
2241
+ if (!e) return;
2242
+ const i = () => {
2243
+ if (!yt || !o) {
2244
+ zt({}), Or();
2245
+ return;
2246
+ }
2247
+ const f = o.clientWidth, u = o.clientHeight;
2248
+ if (f === 0 || u === 0) return;
2249
+ const p = e.videoWidth > e.videoHeight;
2250
+ Kr(p), Pr(
2251
+ se === "android" && ni(e.videoWidth, e.videoHeight)
2252
+ );
2253
+ const O = p ? He.videoPosition.landscape : He.videoPosition.portrait;
2254
+ let S = {};
2255
+ O.heightMultiplier ? (S.height = `${u * O.heightMultiplier}px`, S.width = "auto") : O.widthMultiplier && (S.width = `${f * O.widthMultiplier}px`, S.height = "auto"), S.borderRadius = `${p ? u * He.videoBorderRadiusMultiplier : f * He.videoBorderRadiusMultiplier}px`, zt(S), Or();
2256
+ }, h = new ResizeObserver(() => {
2257
+ i();
2258
+ });
2259
+ o && h.observe(o), h.observe(e), r && h.observe(r), o && o.addEventListener("load", i), e.addEventListener("loadedmetadata", i), e.addEventListener("resize", i);
2260
+ const l = () => G.current?.bumpActivity();
2261
+ return e.addEventListener("resize", l), i(), () => {
2262
+ h.disconnect(), e.removeEventListener("loadedmetadata", i), e.removeEventListener("resize", i), e.removeEventListener("resize", l), o && o.removeEventListener("load", i);
2263
+ };
2264
+ }, [He, yt]), ae(() => {
2265
+ const e = G.current;
2266
+ it ? e?.start() : (e?.stop(), Zt(null), nt(null), gt(null), tr(null), Le(null), Ct.current = null, ee.current !== void 0 && (window.cancelAnimationFrame(ee.current), ee.current = void 0), U("onAxSnapshotChange", Ut.current, null));
2267
+ }, [it]), ae(() => () => {
2268
+ ee.current !== void 0 && (window.cancelAnimationFrame(ee.current), ee.current = void 0);
2269
+ }, []), ae(() => {
2270
+ if (!it) return;
2271
+ const e = (o) => {
2272
+ o.key === "Escape" && (Lt || Pt) && (gt(null), nt(null), Le(null), U("onInspectSelectionChange", Fe.current, null));
2273
+ };
2274
+ return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
2275
+ }, [it, Lt, Pt]);
2276
+ const dn = () => {
2277
+ x.current && x.current.focus();
2278
+ };
2279
+ pn(Ee, () => ({
2280
+ openUrl: (e) => {
2281
+ if (!T.current || T.current.readyState !== WebSocket.OPEN) {
2282
+ w("WebSocket not open, cannot send open_url command via ref.");
2283
+ return;
2284
+ }
2285
+ try {
2286
+ const o = decodeURIComponent(e);
2287
+ K("Opening URL"), T.current.send(
2288
+ JSON.stringify({
2289
+ type: "openUrl",
2290
+ url: o,
2291
+ sessionId: re
2292
+ })
2293
+ );
2294
+ } catch (o) {
2295
+ w("Error decoding or sending URL via ref:", { error: o, url: e }), T.current.send(
2296
+ JSON.stringify({
2297
+ type: "openUrl",
2298
+ url: e,
2299
+ sessionId: re
2300
+ })
2301
+ );
2302
+ }
2303
+ G.current?.bumpActivity();
2304
+ },
2305
+ sendKeyEvent: (e) => {
2306
+ if (!P.current || P.current.readyState !== "open") {
2307
+ w("Data channel not ready for imperative key command:", P.current?.readyState);
2308
+ return;
2309
+ }
2310
+ const o = Rr[e.code];
2311
+ if (!o) {
2312
+ w(`Unknown event.code for imperative command: ${e.code}`);
2313
+ return;
2314
+ }
2315
+ let r = s.META_NONE;
2316
+ e.shiftKey && (r |= s.META_SHIFT_ON), e.altKey && (r |= s.META_ALT_ON), e.ctrlKey && (r |= s.META_CTRL_ON), e.metaKey && (r |= s.META_META_ON);
2317
+ const i = e.type === "keydown" ? s.ACTION_DOWN : s.ACTION_UP;
2318
+ F(
2319
+ `Sending Imperative Key Command: code=${e.code}, keycode=${o}, action=${i}, meta=${r}`
2320
+ );
2321
+ const h = ut(
2322
+ i,
2323
+ o,
2324
+ 0,
2325
+ // repeat count, typically 0 for single presses
2326
+ r
2327
+ );
2328
+ h && ne(h);
2329
+ },
2330
+ screenshot: () => new Promise((e, o) => {
2331
+ if (!T.current || T.current.readyState !== WebSocket.OPEN)
2332
+ return w("WebSocket not open, cannot send screenshot command."), o(new Error("WebSocket is not connected or connection is not open."));
2333
+ const r = `ui-ss-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`, i = {
2334
+ type: "screenshot",
2335
+ // Matches the type expected by instance API
2336
+ id: r
2337
+ };
2338
+ fe.current.set(r, e), le.current.set(r, o), F("Sending screenshot request:", i);
2339
+ try {
2340
+ T.current.send(JSON.stringify(i));
2341
+ } catch (h) {
2342
+ w("Failed to send screenshot request immediately:", h), fe.current.delete(r), le.current.delete(r), o(h);
2343
+ return;
2344
+ }
2345
+ setTimeout(() => {
2346
+ fe.current.has(r) && (w(`Screenshot request timed out for id ${r}`), le.current.get(r)?.(new Error("Screenshot request timed out")), fe.current.delete(r), le.current.delete(r));
2347
+ }, 3e4);
2348
+ }),
2349
+ terminateApp: (e) => new Promise((o, r) => {
2350
+ if (!T.current || T.current.readyState !== WebSocket.OPEN)
2351
+ return w("WebSocket not open, cannot send terminateApp command."), r(new Error("WebSocket is not connected or connection is not open."));
2352
+ const i = `ui-term-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`, h = {
2353
+ type: "terminateApp",
2354
+ id: i,
2355
+ bundleId: e
2356
+ };
2357
+ ve.current.set(i, o), _e.current.set(i, r), F("Sending terminateApp request:", h);
2358
+ try {
2359
+ T.current.send(JSON.stringify(h));
2360
+ } catch (l) {
2361
+ w("Failed to send terminateApp request immediately:", l), ve.current.delete(i), _e.current.delete(i), r(l);
2362
+ return;
2363
+ }
2364
+ G.current?.bumpActivity(), setTimeout(() => {
2365
+ ve.current.has(i) && (w(`terminateApp request timed out for id ${i}`), _e.current.get(i)?.(new Error("terminateApp request timed out")), ve.current.delete(i), _e.current.delete(i));
2366
+ }, 3e4);
2367
+ }),
2368
+ reconnect: () => $t(),
2369
+ refreshAxTree: async () => {
2370
+ const e = G.current;
2371
+ if (!e)
2372
+ throw new Error("Inspect mode is not active");
2373
+ return e.refresh();
2374
+ },
2375
+ getAxSnapshot: () => xe.current,
2376
+ setInspectHighlight: (e) => {
2377
+ nt(e?.id ?? null);
2378
+ },
2379
+ setInspectSelection: (e) => {
2380
+ gt(e?.id ?? null), Le(e ? Ct.current : null);
2381
+ const o = xe.current;
2382
+ e && o ? U("onInspectSelectionChange", Fe.current, { element: e, snapshot: o }) : U("onInspectSelectionChange", Fe.current, null);
2383
+ },
2384
+ getAxStatus: () => G.current?.getStatus() ?? "idle"
2385
+ }));
2386
+ const fn = Ur && Te !== null;
2387
+ return /* @__PURE__ */ te(
2388
+ "div",
2389
+ {
2390
+ ref: be,
2391
+ className: Re("rc-container", n),
2392
+ style: { touchAction: "none" },
2393
+ onMouseDown: he,
2394
+ onMouseMove: he,
2395
+ onMouseUp: he,
2396
+ onMouseLeave: he,
2397
+ onTouchStart: he,
2398
+ onTouchMove: he,
2399
+ onTouchEnd: he,
2400
+ onTouchCancel: he,
2401
+ children: [
2402
+ fn && Te && /* @__PURE__ */ te(Ar, { children: [
2403
+ /* @__PURE__ */ W(
2404
+ "div",
2405
+ {
2406
+ className: "rc-touch-indicator",
2407
+ style: {
2408
+ left: `${Te.containerX}px`,
2409
+ top: `${Te.containerY}px`
2410
+ }
2411
+ }
2412
+ ),
2413
+ /* @__PURE__ */ W(
2414
+ "div",
2415
+ {
2416
+ className: "rc-touch-indicator",
2417
+ style: {
2418
+ left: `${Te.mirrorContainerX}px`,
2419
+ top: `${Te.mirrorContainerY}px`
2420
+ }
2421
+ }
2422
+ )
2423
+ ] }),
2424
+ yt && /* @__PURE__ */ W(
2425
+ "img",
2426
+ {
2427
+ ref: pe,
2428
+ src: cr,
2429
+ alt: "",
2430
+ className: se === "ios" ? Re("rc-phone-frame", "rc-phone-frame-ios") : "rc-phone-frame",
2431
+ draggable: !1
2432
+ }
2433
+ ),
2434
+ /* @__PURE__ */ W(
2435
+ "video",
2436
+ {
2437
+ ref: x,
2438
+ className: Re(
2439
+ "rc-video",
2440
+ !yt && "rc-video-frameless",
2441
+ !Ge && "rc-video-loading"
2442
+ ),
2443
+ style: {
2444
+ ...Lr,
2445
+ ...sr ? {
2446
+ backgroundImage: `url("${sr}")`,
2447
+ backgroundRepeat: "no-repeat",
2448
+ backgroundPosition: "center",
2449
+ backgroundSize: He.loadingLogoSize
2450
+ } : {}
2451
+ },
2452
+ autoPlay: !0,
2453
+ playsInline: !0,
2454
+ muted: !0,
2455
+ tabIndex: 0,
2456
+ onKeyDown: dr,
2457
+ onKeyUp: dr,
2458
+ onClick: dn,
2459
+ onLoadedData: Zr,
2460
+ onFocus: () => {
2461
+ x.current && (x.current.style.outline = "none");
2462
+ },
2463
+ onBlur: () => {
2464
+ x.current && (x.current.style.outline = "none");
2465
+ }
2466
+ }
2467
+ ),
2468
+ it && /* @__PURE__ */ W(
2469
+ jn,
2470
+ {
2471
+ snapshot: Qt,
2472
+ geometry: Fr,
2473
+ highlightedId: Pt,
2474
+ selectedId: Lt,
2475
+ mode: $r,
2476
+ cursorPosition: Wr,
2477
+ frozenCursorPosition: Hr,
2478
+ onSelectChange: (e, o) => {
2479
+ gt(e?.id ?? null), e && o ? Le(o) : e || Le(null);
2480
+ const r = xe.current;
2481
+ e && r ? U("onInspectSelectionChange", Fe.current, {
2482
+ element: e,
2483
+ snapshot: r
2484
+ }) : U("onInspectSelectionChange", Fe.current, null);
2485
+ },
2486
+ onTapElement: (e, o) => {
2487
+ if (o) {
2488
+ ur(o.x, o.y);
2489
+ return;
2490
+ }
2491
+ const r = xe.current;
2492
+ r && Xr(e, r);
2493
+ }
2494
+ }
2495
+ ),
2496
+ bt ? /* @__PURE__ */ te("div", { className: "rc-terminated", role: "status", children: [
2497
+ /* @__PURE__ */ W("div", { className: "rc-terminated-title", children: "Instance terminated" }),
2498
+ /* @__PURE__ */ W("div", { className: "rc-terminated-message", children: "This instance no longer exists and can't be reconnected." })
2499
+ ] }) : Vt && /* @__PURE__ */ W("button", { type: "button", className: "rc-retry-button", onClick: ln, children: "Retry" })
2500
+ ]
2501
+ }
2502
+ );
2503
+ }
2504
+ ), ci = (n) => typeof n.message == "string" ? n.message : typeof n.error == "string" ? n.error : null, si = (n) => typeof n.dataUri == "string" ? { dataUri: n.dataUri } : typeof n.base64 == "string" ? n.base64.startsWith("data:") ? { dataUri: n.base64 } : { dataUri: `data:${n.base64.startsWith("/9j/") ? "image/jpeg" : "image/png"};base64,${n.base64}` } : null;
2505
+ export {
2506
+ Xt as A,
2507
+ di as R,
2508
+ Sn as a,
2509
+ bn as b,
2510
+ Yr as c,
2511
+ br as d,
2512
+ Nr as e,
2513
+ Rn as f,
2514
+ Tn as g,
2515
+ Mn as n
2516
+ };