@usecrow/client 0.1.33 → 0.1.34

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,1385 @@
1
+ async function waitFor(e) {
2
+ await new Promise((n) => setTimeout(n, e * 1e3));
3
+ }
4
+ async function movePointerToElement(e) {
5
+ const n = e.getBoundingClientRect(), s = n.left + n.width / 2, o = n.top + n.height / 2;
6
+ window.dispatchEvent(new CustomEvent("PageAgent::MovePointerTo", { detail: { x: s, y: o } })), await waitFor(0.3);
7
+ }
8
+ function getElementByIndex(e, n) {
9
+ const s = e.get(n);
10
+ if (!s)
11
+ throw new Error(`No interactive element found at index ${n}`);
12
+ const o = s.ref;
13
+ if (!o)
14
+ throw new Error(`Element at index ${n} does not have a reference`);
15
+ if (!(o instanceof HTMLElement))
16
+ throw new Error(`Element at index ${n} is not an HTMLElement`);
17
+ return o;
18
+ }
19
+ let lastClickedElement = null;
20
+ function blurLastClickedElement() {
21
+ lastClickedElement && (lastClickedElement.blur(), lastClickedElement.dispatchEvent(
22
+ new MouseEvent("mouseout", { bubbles: !0, cancelable: !0 })
23
+ ), lastClickedElement = null);
24
+ }
25
+ async function clickElement(e) {
26
+ blurLastClickedElement(), lastClickedElement = e, await scrollIntoViewIfNeeded(e), await movePointerToElement(e), window.dispatchEvent(new CustomEvent("PageAgent::ClickPointer")), await waitFor(0.1), e.dispatchEvent(new MouseEvent("mouseenter", { bubbles: !0, cancelable: !0 })), e.dispatchEvent(new MouseEvent("mouseover", { bubbles: !0, cancelable: !0 })), e.dispatchEvent(new MouseEvent("mousedown", { bubbles: !0, cancelable: !0 })), e.focus(), e.dispatchEvent(new MouseEvent("mouseup", { bubbles: !0, cancelable: !0 })), e.dispatchEvent(new MouseEvent("click", { bubbles: !0, cancelable: !0 })), await waitFor(0.1);
27
+ }
28
+ let _nativeInputValueSetter, _nativeTextAreaValueSetter;
29
+ function getNativeInputValueSetter() {
30
+ return _nativeInputValueSetter || (_nativeInputValueSetter = Object.getOwnPropertyDescriptor(
31
+ window.HTMLInputElement.prototype,
32
+ "value"
33
+ ).set), _nativeInputValueSetter;
34
+ }
35
+ function getNativeTextAreaValueSetter() {
36
+ return _nativeTextAreaValueSetter || (_nativeTextAreaValueSetter = Object.getOwnPropertyDescriptor(
37
+ window.HTMLTextAreaElement.prototype,
38
+ "value"
39
+ ).set), _nativeTextAreaValueSetter;
40
+ }
41
+ async function inputTextElement(e, n) {
42
+ if (!(e instanceof HTMLInputElement || e instanceof HTMLTextAreaElement))
43
+ throw new Error("Element is not an input or textarea");
44
+ await clickElement(e), e instanceof HTMLTextAreaElement ? getNativeTextAreaValueSetter().call(e, n) : getNativeInputValueSetter().call(e, n);
45
+ const s = new Event("input", { bubbles: !0 });
46
+ e.dispatchEvent(s), await waitFor(0.1), blurLastClickedElement();
47
+ }
48
+ async function selectOptionElement(e, n) {
49
+ if (!(e instanceof HTMLSelectElement))
50
+ throw new Error("Element is not a select element");
51
+ const o = Array.from(e.options).find((w) => {
52
+ var d;
53
+ return ((d = w.textContent) == null ? void 0 : d.trim()) === n.trim();
54
+ });
55
+ if (!o)
56
+ throw new Error(`Option with text "${n}" not found in select element`);
57
+ e.value = o.value, e.dispatchEvent(new Event("change", { bubbles: !0 })), await waitFor(0.1);
58
+ }
59
+ async function scrollIntoViewIfNeeded(e) {
60
+ const n = e;
61
+ n.scrollIntoViewIfNeeded ? n.scrollIntoViewIfNeeded() : n.scrollIntoView({ behavior: "auto", block: "center", inline: "nearest" });
62
+ }
63
+ async function scrollVertically(e, n, s) {
64
+ if (s) {
65
+ const l = s;
66
+ console.log(
67
+ "[SCROLL DEBUG] Starting direct container scroll for element:",
68
+ l.tagName
69
+ );
70
+ let h = l, T = !1, b = null, u = 0, f = 0;
71
+ const N = n;
72
+ for (; h && f < 10; ) {
73
+ const D = window.getComputedStyle(h), z = /(auto|scroll|overlay)/.test(D.overflowY), _ = h.scrollHeight > h.clientHeight;
74
+ if (console.log(
75
+ "[SCROLL DEBUG] Checking element:",
76
+ h.tagName,
77
+ "hasScrollableY:",
78
+ z,
79
+ "canScrollVertically:",
80
+ _,
81
+ "scrollHeight:",
82
+ h.scrollHeight,
83
+ "clientHeight:",
84
+ h.clientHeight
85
+ ), z && _) {
86
+ const R = h.scrollTop, U = h.scrollHeight - h.clientHeight;
87
+ let H = N / 3;
88
+ H > 0 ? H = Math.min(H, U - R) : H = Math.max(H, -R), h.scrollTop = R + H;
89
+ const V = h.scrollTop, O = V - R;
90
+ if (console.log(
91
+ "[SCROLL DEBUG] Scroll attempt:",
92
+ h.tagName,
93
+ "before:",
94
+ R,
95
+ "after:",
96
+ V,
97
+ "delta:",
98
+ O
99
+ ), Math.abs(O) > 0.5) {
100
+ T = !0, b = h, u = O, console.log(
101
+ "[SCROLL DEBUG] Successfully scrolled container:",
102
+ h.tagName,
103
+ "delta:",
104
+ O
105
+ );
106
+ break;
107
+ }
108
+ }
109
+ if (h === document.body || h === document.documentElement)
110
+ break;
111
+ h = h.parentElement, f++;
112
+ }
113
+ return T ? `Scrolled container (${b == null ? void 0 : b.tagName}) by ${u}px` : `No scrollable container found for element (${l.tagName})`;
114
+ }
115
+ const o = n, w = (l) => l.clientHeight >= window.innerHeight * 0.5, d = (l) => l && /(auto|scroll|overlay)/.test(getComputedStyle(l).overflowY) && l.scrollHeight > l.clientHeight && w(l);
116
+ let r = document.activeElement;
117
+ for (; r && !d(r) && r !== document.body; ) r = r.parentElement;
118
+ if (r = d(r) ? r : Array.from(document.querySelectorAll("*")).find(d) || document.scrollingElement || document.documentElement, r === document.scrollingElement || r === document.documentElement || r === document.body) {
119
+ const l = window.scrollY, h = document.documentElement.scrollHeight - window.innerHeight;
120
+ window.scrollBy(0, o);
121
+ const T = window.scrollY, b = T - l;
122
+ if (Math.abs(b) < 1)
123
+ return o > 0 ? "⚠️ Already at the bottom of the page, cannot scroll down further." : "⚠️ Already at the top of the page, cannot scroll up further.";
124
+ const u = o > 0 && T >= h - 1, f = o < 0 && T <= 1;
125
+ return u ? `✅ Scrolled page by ${b}px. Reached the bottom of the page.` : f ? `✅ Scrolled page by ${b}px. Reached the top of the page.` : `✅ Scrolled page by ${b}px.`;
126
+ } else {
127
+ const l = r.scrollTop, h = r.scrollHeight - r.clientHeight;
128
+ r.scrollBy({ top: o, behavior: "smooth" }), await waitFor(0.1);
129
+ const T = r.scrollTop, b = T - l;
130
+ if (Math.abs(b) < 1)
131
+ return o > 0 ? `⚠️ Already at the bottom of container (${r.tagName}), cannot scroll down further.` : `⚠️ Already at the top of container (${r.tagName}), cannot scroll up further.`;
132
+ const u = o > 0 && T >= h - 1, f = o < 0 && T <= 1;
133
+ return u ? `✅ Scrolled container (${r.tagName}) by ${b}px. Reached the bottom.` : f ? `✅ Scrolled container (${r.tagName}) by ${b}px. Reached the top.` : `✅ Scrolled container (${r.tagName}) by ${b}px.`;
134
+ }
135
+ }
136
+ async function scrollHorizontally(e, n, s) {
137
+ if (s) {
138
+ const l = s;
139
+ console.log(
140
+ "[SCROLL DEBUG] Starting direct container scroll for element:",
141
+ l.tagName
142
+ );
143
+ let h = l, T = !1, b = null, u = 0, f = 0;
144
+ const N = e ? n : -n;
145
+ for (; h && f < 10; ) {
146
+ const D = window.getComputedStyle(h), z = /(auto|scroll|overlay)/.test(D.overflowX), _ = h.scrollWidth > h.clientWidth;
147
+ if (console.log(
148
+ "[SCROLL DEBUG] Checking element:",
149
+ h.tagName,
150
+ "hasScrollableX:",
151
+ z,
152
+ "canScrollHorizontally:",
153
+ _,
154
+ "scrollWidth:",
155
+ h.scrollWidth,
156
+ "clientWidth:",
157
+ h.clientWidth
158
+ ), z && _) {
159
+ const R = h.scrollLeft, U = h.scrollWidth - h.clientWidth;
160
+ let H = N / 3;
161
+ H > 0 ? H = Math.min(H, U - R) : H = Math.max(H, -R), h.scrollLeft = R + H;
162
+ const V = h.scrollLeft, O = V - R;
163
+ if (console.log(
164
+ "[SCROLL DEBUG] Scroll attempt:",
165
+ h.tagName,
166
+ "before:",
167
+ R,
168
+ "after:",
169
+ V,
170
+ "delta:",
171
+ O
172
+ ), Math.abs(O) > 0.5) {
173
+ T = !0, b = h, u = O, console.log(
174
+ "[SCROLL DEBUG] Successfully scrolled container:",
175
+ h.tagName,
176
+ "delta:",
177
+ O
178
+ );
179
+ break;
180
+ }
181
+ }
182
+ if (h === document.body || h === document.documentElement)
183
+ break;
184
+ h = h.parentElement, f++;
185
+ }
186
+ return T ? `Scrolled container (${b == null ? void 0 : b.tagName}) horizontally by ${u}px` : `No horizontally scrollable container found for element (${l.tagName})`;
187
+ }
188
+ const o = e ? n : -n, w = (l) => l.clientWidth >= window.innerWidth * 0.5, d = (l) => l && /(auto|scroll|overlay)/.test(getComputedStyle(l).overflowX) && l.scrollWidth > l.clientWidth && w(l);
189
+ let r = document.activeElement;
190
+ for (; r && !d(r) && r !== document.body; ) r = r.parentElement;
191
+ if (r = d(r) ? r : Array.from(document.querySelectorAll("*")).find(d) || document.scrollingElement || document.documentElement, r === document.scrollingElement || r === document.documentElement || r === document.body) {
192
+ const l = window.scrollX, h = document.documentElement.scrollWidth - window.innerWidth;
193
+ window.scrollBy(o, 0);
194
+ const T = window.scrollX, b = T - l;
195
+ if (Math.abs(b) < 1)
196
+ return o > 0 ? "⚠️ Already at the right edge of the page, cannot scroll right further." : "⚠️ Already at the left edge of the page, cannot scroll left further.";
197
+ const u = o > 0 && T >= h - 1, f = o < 0 && T <= 1;
198
+ return u ? `✅ Scrolled page by ${b}px. Reached the right edge of the page.` : f ? `✅ Scrolled page by ${b}px. Reached the left edge of the page.` : `✅ Scrolled page horizontally by ${b}px.`;
199
+ } else {
200
+ const l = r.scrollLeft, h = r.scrollWidth - r.clientWidth;
201
+ r.scrollBy({ left: o, behavior: "smooth" }), await waitFor(0.1);
202
+ const T = r.scrollLeft, b = T - l;
203
+ if (Math.abs(b) < 1)
204
+ return o > 0 ? `⚠️ Already at the right edge of container (${r.tagName}), cannot scroll right further.` : `⚠️ Already at the left edge of container (${r.tagName}), cannot scroll left further.`;
205
+ const u = o > 0 && T >= h - 1, f = o < 0 && T <= 1;
206
+ return u ? `✅ Scrolled container (${r.tagName}) by ${b}px. Reached the right edge.` : f ? `✅ Scrolled container (${r.tagName}) by ${b}px. Reached the left edge.` : `✅ Scrolled container (${r.tagName}) horizontally by ${b}px.`;
207
+ }
208
+ }
209
+ const VIEWPORT_EXPANSION = -1, domTree = (e = {
210
+ doHighlightElements: !0,
211
+ focusHighlightIndex: -1,
212
+ viewportExpansion: 0,
213
+ debugMode: !1,
214
+ /**
215
+ * @edit
216
+ */
217
+ /** @type {Element[]} */
218
+ interactiveBlacklist: [],
219
+ /** @type {Element[]} */
220
+ interactiveWhitelist: [],
221
+ highlightOpacity: 0.1,
222
+ highlightLabelOpacity: 0.5
223
+ }) => {
224
+ const { interactiveBlacklist: n, interactiveWhitelist: s, highlightOpacity: o, highlightLabelOpacity: w } = e, { doHighlightElements: d, focusHighlightIndex: r, viewportExpansion: l, debugMode: h } = e;
225
+ let T = 0;
226
+ const b = /* @__PURE__ */ new WeakMap();
227
+ function u(t, i) {
228
+ !t || t.nodeType !== Node.ELEMENT_NODE || b.set(t, { ...b.get(t), ...i });
229
+ }
230
+ const f = {
231
+ boundingRects: /* @__PURE__ */ new WeakMap(),
232
+ clientRects: /* @__PURE__ */ new WeakMap(),
233
+ computedStyles: /* @__PURE__ */ new WeakMap(),
234
+ clearCache: () => {
235
+ f.boundingRects = /* @__PURE__ */ new WeakMap(), f.clientRects = /* @__PURE__ */ new WeakMap(), f.computedStyles = /* @__PURE__ */ new WeakMap();
236
+ }
237
+ };
238
+ function N(t) {
239
+ if (!t) return null;
240
+ if (f.boundingRects.has(t))
241
+ return f.boundingRects.get(t);
242
+ const i = t.getBoundingClientRect();
243
+ return i && f.boundingRects.set(t, i), i;
244
+ }
245
+ function D(t) {
246
+ if (!t) return null;
247
+ if (f.computedStyles.has(t))
248
+ return f.computedStyles.get(t);
249
+ const i = window.getComputedStyle(t);
250
+ return i && f.computedStyles.set(t, i), i;
251
+ }
252
+ function z(t) {
253
+ if (!t) return null;
254
+ if (f.clientRects.has(t))
255
+ return f.clientRects.get(t);
256
+ const i = t.getClientRects();
257
+ return i && f.clientRects.set(t, i), i;
258
+ }
259
+ const _ = {}, R = { current: 0 }, U = "playwright-highlight-container";
260
+ function H(t, i, p = null) {
261
+ if (!t) return i;
262
+ const c = [];
263
+ let a = null, x = 20, E = 16, I = null;
264
+ try {
265
+ let m = document.getElementById(U);
266
+ m || (m = document.createElement("div"), m.id = U, m.style.position = "fixed", m.style.pointerEvents = "none", m.style.top = "0", m.style.left = "0", m.style.width = "100%", m.style.height = "100%", m.style.zIndex = "2147483640", m.style.backgroundColor = "transparent", document.body.appendChild(m));
267
+ const A = t.getClientRects();
268
+ if (!A || A.length === 0) return i;
269
+ const $ = [
270
+ "#FF0000",
271
+ "#00FF00",
272
+ "#0000FF",
273
+ "#FFA500",
274
+ "#800080",
275
+ "#008080",
276
+ "#FF69B4",
277
+ "#4B0082",
278
+ "#FF4500",
279
+ "#2E8B57",
280
+ "#DC143C",
281
+ "#4682B4"
282
+ ], g = i % $.length;
283
+ let y = $[g];
284
+ const C = y + Math.floor(o * 255).toString(16).padStart(2, "0");
285
+ y = y + Math.floor(w * 255).toString(16).padStart(2, "0");
286
+ let M = { x: 0, y: 0 };
287
+ if (p) {
288
+ const S = p.getBoundingClientRect();
289
+ M.x = S.left, M.y = S.top;
290
+ }
291
+ const B = document.createDocumentFragment();
292
+ for (const S of A) {
293
+ if (S.width === 0 || S.height === 0) continue;
294
+ const k = document.createElement("div");
295
+ k.style.position = "fixed", k.style.border = `2px solid ${y}`, k.style.backgroundColor = C, k.style.pointerEvents = "none", k.style.boxSizing = "border-box";
296
+ const v = S.top + M.y, W = S.left + M.x;
297
+ k.style.top = `${v}px`, k.style.left = `${W}px`, k.style.width = `${S.width}px`, k.style.height = `${S.height}px`, B.appendChild(k), c.push({ element: k, initialRect: S });
298
+ }
299
+ const G = A[0];
300
+ if (w > 0) {
301
+ a = document.createElement("div"), a.className = "playwright-highlight-label", a.style.position = "fixed", a.style.background = y, a.style.color = "white", a.style.padding = "1px 4px", a.style.borderRadius = "4px", a.style.fontSize = `${Math.min(12, Math.max(8, G.height / 2))}px`, a.textContent = i.toString(), x = a.offsetWidth > 0 ? a.offsetWidth : x, E = a.offsetHeight > 0 ? a.offsetHeight : E;
302
+ const S = G.top + M.y, k = G.left + M.x;
303
+ let v = S + 2, W = k + G.width - x - 2;
304
+ (G.width < x + 4 || G.height < E + 4) && (v = S - E - 2, W = k + G.width - x, W < M.x && (W = k)), v = Math.max(0, Math.min(v, window.innerHeight - E)), W = Math.max(0, Math.min(W, window.innerWidth - x)), a.style.top = `${v}px`, a.style.left = `${W}px`, B.appendChild(a);
305
+ }
306
+ const j = ((S, k) => {
307
+ let v = 0;
308
+ return (...W) => {
309
+ const P = performance.now();
310
+ if (!(P - v < k))
311
+ return v = P, S(...W);
312
+ };
313
+ })(() => {
314
+ const S = t.getClientRects();
315
+ let k = { x: 0, y: 0 };
316
+ if (p) {
317
+ const v = p.getBoundingClientRect();
318
+ k.x = v.left, k.y = v.top;
319
+ }
320
+ if (c.forEach((v, W) => {
321
+ if (W < S.length) {
322
+ const P = S[W], Z = P.top + k.y, J = P.left + k.x;
323
+ v.element.style.top = `${Z}px`, v.element.style.left = `${J}px`, v.element.style.width = `${P.width}px`, v.element.style.height = `${P.height}px`, v.element.style.display = P.width === 0 || P.height === 0 ? "none" : "block";
324
+ } else
325
+ v.element.style.display = "none";
326
+ }), S.length < c.length)
327
+ for (let v = S.length; v < c.length; v++)
328
+ c[v].element.style.display = "none";
329
+ if (a && S.length > 0) {
330
+ const v = S[0], W = v.top + k.y, P = v.left + k.x;
331
+ let Z = W + 2, J = P + v.width - x - 2;
332
+ (v.width < x + 4 || v.height < E + 4) && (Z = W - E - 2, J = P + v.width - x, J < k.x && (J = P)), Z = Math.max(0, Math.min(Z, window.innerHeight - E)), J = Math.max(0, Math.min(J, window.innerWidth - x)), a.style.top = `${Z}px`, a.style.left = `${J}px`, a.style.display = "block";
333
+ } else a && (a.style.display = "none");
334
+ }, 16);
335
+ return window.addEventListener("scroll", j, !0), window.addEventListener("resize", j), I = () => {
336
+ window.removeEventListener("scroll", j, !0), window.removeEventListener("resize", j), c.forEach((S) => S.element.remove()), a && a.remove();
337
+ }, m.appendChild(B), i + 1;
338
+ } finally {
339
+ I && (window._highlightCleanupFunctions = window._highlightCleanupFunctions || []).push(
340
+ I
341
+ );
342
+ }
343
+ }
344
+ function V(t) {
345
+ if (!t || t.nodeType !== Node.ELEMENT_NODE)
346
+ return null;
347
+ const i = D(t);
348
+ if (!i) return null;
349
+ const p = i.display;
350
+ if (p === "inline" || p === "inline-block")
351
+ return null;
352
+ const c = i.overflowX, a = i.overflowY, x = c === "auto" || c === "scroll", E = a === "auto" || a === "scroll";
353
+ if (!x && !E)
354
+ return null;
355
+ const I = t.scrollWidth - t.clientWidth, m = t.scrollHeight - t.clientHeight, A = 4;
356
+ if (I < A && m < A || !E && I < A || !x && m < A)
357
+ return null;
358
+ const $ = t.scrollTop, g = t.scrollLeft, y = t.scrollWidth - t.clientWidth - t.scrollLeft, C = t.scrollHeight - t.clientHeight - t.scrollTop, M = {
359
+ top: $,
360
+ right: y,
361
+ bottom: C,
362
+ left: g
363
+ };
364
+ return u(t, {
365
+ scrollable: !0,
366
+ scrollData: M
367
+ }), M;
368
+ }
369
+ function O(t) {
370
+ try {
371
+ if (l === -1) {
372
+ const E = t.parentElement;
373
+ if (!E) return !1;
374
+ try {
375
+ return E.checkVisibility({
376
+ checkOpacity: !0,
377
+ checkVisibilityCSS: !0
378
+ });
379
+ } catch {
380
+ const m = window.getComputedStyle(E);
381
+ return m.display !== "none" && m.visibility !== "hidden" && m.opacity !== "0";
382
+ }
383
+ }
384
+ const i = document.createRange();
385
+ i.selectNodeContents(t);
386
+ const p = i.getClientRects();
387
+ if (!p || p.length === 0)
388
+ return !1;
389
+ let c = !1, a = !1;
390
+ for (const E of p)
391
+ if (E.width > 0 && E.height > 0 && (c = !0, !(E.bottom < -l || E.top > window.innerHeight + l || E.right < -l || E.left > window.innerWidth + l))) {
392
+ a = !0;
393
+ break;
394
+ }
395
+ if (!c || !a)
396
+ return !1;
397
+ const x = t.parentElement;
398
+ if (!x) return !1;
399
+ try {
400
+ return x.checkVisibility({
401
+ checkOpacity: !0,
402
+ checkVisibilityCSS: !0
403
+ });
404
+ } catch {
405
+ const I = window.getComputedStyle(x);
406
+ return I.display !== "none" && I.visibility !== "hidden" && I.opacity !== "0";
407
+ }
408
+ } catch (i) {
409
+ return console.warn("Error checking text node visibility:", i), !1;
410
+ }
411
+ }
412
+ function it(t) {
413
+ if (!t || !t.tagName) return !1;
414
+ const i = /* @__PURE__ */ new Set([
415
+ "body",
416
+ "div",
417
+ "main",
418
+ "article",
419
+ "section",
420
+ "nav",
421
+ "header",
422
+ "footer"
423
+ ]), p = t.tagName.toLowerCase();
424
+ return i.has(p) ? !0 : !(/* @__PURE__ */ new Set([
425
+ "svg",
426
+ "script",
427
+ "style",
428
+ "link",
429
+ "meta",
430
+ "noscript",
431
+ "template"
432
+ ])).has(p);
433
+ }
434
+ function X(t) {
435
+ const i = D(t);
436
+ return t.offsetWidth > 0 && t.offsetHeight > 0 && (i == null ? void 0 : i.visibility) !== "hidden" && (i == null ? void 0 : i.display) !== "none";
437
+ }
438
+ function L(t) {
439
+ var C, M;
440
+ if (!t || t.nodeType !== Node.ELEMENT_NODE || n.includes(t))
441
+ return !1;
442
+ if (s.includes(t))
443
+ return !0;
444
+ const i = t.tagName.toLowerCase(), p = D(t), c = /* @__PURE__ */ new Set([
445
+ "pointer",
446
+ // Link/clickable elements
447
+ "move",
448
+ // Movable elements
449
+ "text",
450
+ // Text selection
451
+ "grab",
452
+ // Grabbable elements
453
+ "grabbing",
454
+ // Currently grabbing
455
+ "cell",
456
+ // Table cell selection
457
+ "copy",
458
+ // Copy operation
459
+ "alias",
460
+ // Alias creation
461
+ "all-scroll",
462
+ // Scrollable content
463
+ "col-resize",
464
+ // Column resize
465
+ "context-menu",
466
+ // Context menu available
467
+ "crosshair",
468
+ // Precise selection
469
+ "e-resize",
470
+ // East resize
471
+ "ew-resize",
472
+ // East-west resize
473
+ "help",
474
+ // Help available
475
+ "n-resize",
476
+ // North resize
477
+ "ne-resize",
478
+ // Northeast resize
479
+ "nesw-resize",
480
+ // Northeast-southwest resize
481
+ "ns-resize",
482
+ // North-south resize
483
+ "nw-resize",
484
+ // Northwest resize
485
+ "nwse-resize",
486
+ // Northwest-southeast resize
487
+ "row-resize",
488
+ // Row resize
489
+ "s-resize",
490
+ // South resize
491
+ "se-resize",
492
+ // Southeast resize
493
+ "sw-resize",
494
+ // Southwest resize
495
+ "vertical-text",
496
+ // Vertical text selection
497
+ "w-resize",
498
+ // West resize
499
+ "zoom-in",
500
+ // Zoom in
501
+ "zoom-out"
502
+ // Zoom out
503
+ ]), a = /* @__PURE__ */ new Set([
504
+ "not-allowed",
505
+ // Action not allowed
506
+ "no-drop",
507
+ // Drop not allowed
508
+ "wait",
509
+ // Processing
510
+ "progress",
511
+ // In progress
512
+ "initial",
513
+ // Initial value
514
+ "inherit"
515
+ // Inherited value
516
+ //? Let's just include all potentially clickable elements that are not specifically blocked
517
+ // 'none', // No cursor
518
+ // 'default', // Default cursor
519
+ // 'auto', // Browser default
520
+ ]);
521
+ function x(B) {
522
+ return B.tagName.toLowerCase() === "html" ? !1 : !!(p != null && p.cursor && c.has(p.cursor));
523
+ }
524
+ if (x(t))
525
+ return !0;
526
+ const I = /* @__PURE__ */ new Set([
527
+ "a",
528
+ // Links
529
+ "button",
530
+ // Buttons
531
+ "input",
532
+ // All input types (text, checkbox, radio, etc.)
533
+ "select",
534
+ // Dropdown menus
535
+ "textarea",
536
+ // Text areas
537
+ "details",
538
+ // Expandable details
539
+ "summary",
540
+ // Summary element (clickable part of details)
541
+ "label",
542
+ // Form labels (often clickable)
543
+ "option",
544
+ // Select options
545
+ "optgroup",
546
+ // Option groups
547
+ "fieldset",
548
+ // Form fieldsets (can be interactive with legend)
549
+ "legend"
550
+ // Fieldset legends
551
+ ]), m = /* @__PURE__ */ new Set([
552
+ "disabled",
553
+ // Standard disabled attribute
554
+ // 'aria-disabled', // ARIA disabled state
555
+ "readonly"
556
+ // Read-only state
557
+ // 'aria-readonly', // ARIA read-only state
558
+ // 'aria-hidden', // Hidden from accessibility
559
+ // 'hidden', // Hidden attribute
560
+ // 'inert', // Inert attribute
561
+ // 'aria-inert', // ARIA inert state
562
+ // 'tabindex="-1"', // Removed from tab order
563
+ // 'aria-hidden="true"' // Hidden from screen readers
564
+ ]);
565
+ if (I.has(i)) {
566
+ if (p != null && p.cursor && a.has(p.cursor))
567
+ return !1;
568
+ for (const B of m)
569
+ if (t.hasAttribute(B) || t.getAttribute(B) === "true" || t.getAttribute(B) === "")
570
+ return !1;
571
+ return !(t.disabled || t.readOnly || t.inert);
572
+ }
573
+ const A = t.getAttribute("role"), $ = t.getAttribute("aria-role");
574
+ if (t.getAttribute("contenteditable") === "true" || t.isContentEditable || t.classList && (t.classList.contains("button") || t.classList.contains("dropdown-toggle") || t.getAttribute("data-index") || t.getAttribute("data-toggle") === "dropdown" || t.getAttribute("aria-haspopup") === "true"))
575
+ return !0;
576
+ const g = /* @__PURE__ */ new Set([
577
+ "button",
578
+ // Directly clickable element
579
+ // 'link', // Clickable link
580
+ "menu",
581
+ // Menu container (ARIA menus)
582
+ "menubar",
583
+ // Menu bar container
584
+ "menuitem",
585
+ // Clickable menu item
586
+ "menuitemradio",
587
+ // Radio-style menu item (selectable)
588
+ "menuitemcheckbox",
589
+ // Checkbox-style menu item (toggleable)
590
+ "radio",
591
+ // Radio button (selectable)
592
+ "checkbox",
593
+ // Checkbox (toggleable)
594
+ "tab",
595
+ // Tab (clickable to switch content)
596
+ "switch",
597
+ // Toggle switch (clickable to change state)
598
+ "slider",
599
+ // Slider control (draggable)
600
+ "spinbutton",
601
+ // Number input with up/down controls
602
+ "combobox",
603
+ // Dropdown with text input
604
+ "searchbox",
605
+ // Search input field
606
+ "textbox",
607
+ // Text input field
608
+ "listbox",
609
+ // Selectable list
610
+ "option",
611
+ // Selectable option in a list
612
+ "scrollbar"
613
+ // Scrollable control
614
+ ]);
615
+ if (I.has(i) || A && g.has(A) || $ && g.has($)) return !0;
616
+ try {
617
+ if (typeof getEventListeners == "function") {
618
+ const q = getEventListeners(t), nt = ["click", "mousedown", "mouseup", "dblclick"];
619
+ for (const j of nt)
620
+ if (q[j] && q[j].length > 0)
621
+ return !0;
622
+ }
623
+ const B = ((M = (C = t == null ? void 0 : t.ownerDocument) == null ? void 0 : C.defaultView) == null ? void 0 : M.getEventListenersForNode) || window.getEventListenersForNode;
624
+ if (typeof B == "function") {
625
+ const q = B(t), nt = [
626
+ "click",
627
+ "mousedown",
628
+ "mouseup",
629
+ "keydown",
630
+ "keyup",
631
+ "submit",
632
+ "change",
633
+ "input",
634
+ "focus",
635
+ "blur"
636
+ ];
637
+ for (const j of nt)
638
+ for (const S of q)
639
+ if (S.type === j)
640
+ return !0;
641
+ }
642
+ const G = ["onclick", "onmousedown", "onmouseup", "ondblclick"];
643
+ for (const q of G)
644
+ if (t.hasAttribute(q) || typeof t[q] == "function")
645
+ return !0;
646
+ } catch {
647
+ }
648
+ return !!V(t);
649
+ }
650
+ function et(t) {
651
+ if (l === -1)
652
+ return !0;
653
+ const i = z(t);
654
+ if (!i || i.length === 0)
655
+ return !1;
656
+ let p = !1;
657
+ for (const m of i)
658
+ if (m.width > 0 && m.height > 0 && !// Only check non-empty rects
659
+ (m.bottom < -l || m.top > window.innerHeight + l || m.right < -l || m.left > window.innerWidth + l)) {
660
+ p = !0;
661
+ break;
662
+ }
663
+ if (!p)
664
+ return !1;
665
+ if (t.ownerDocument !== window.document)
666
+ return !0;
667
+ let a = Array.from(i).find((m) => m.width > 0 && m.height > 0);
668
+ if (!a)
669
+ return !1;
670
+ const x = t.getRootNode();
671
+ if (x instanceof ShadowRoot) {
672
+ const m = a.left + a.width / 2, A = a.top + a.height / 2;
673
+ try {
674
+ const $ = x.elementFromPoint(m, A);
675
+ if (!$) return !1;
676
+ let g = $;
677
+ for (; g && g !== x; ) {
678
+ if (g === t) return !0;
679
+ g = g.parentElement;
680
+ }
681
+ return !1;
682
+ } catch {
683
+ return !0;
684
+ }
685
+ }
686
+ const E = 5;
687
+ return [
688
+ // Initially only this was used, but it was not enough
689
+ { x: a.left + a.width / 2, y: a.top + a.height / 2 },
690
+ { x: a.left + E, y: a.top + E },
691
+ // top left
692
+ // { x: rect.right - margin, y: rect.top + margin }, // top right
693
+ // { x: rect.left + margin, y: rect.bottom - margin }, // bottom left
694
+ { x: a.right - E, y: a.bottom - E }
695
+ // bottom right
696
+ ].some(({ x: m, y: A }) => {
697
+ try {
698
+ const $ = document.elementFromPoint(m, A);
699
+ if (!$) return !1;
700
+ let g = $;
701
+ for (; g && g !== document.documentElement; ) {
702
+ if (g === t) return !0;
703
+ g = g.parentElement;
704
+ }
705
+ return !1;
706
+ } catch {
707
+ return !0;
708
+ }
709
+ });
710
+ }
711
+ function ot(t, i) {
712
+ if (i === -1)
713
+ return !0;
714
+ const p = t.getClientRects();
715
+ if (!p || p.length === 0) {
716
+ const c = N(t);
717
+ return !c || c.width === 0 || c.height === 0 ? !1 : !(c.bottom < -i || c.top > window.innerHeight + i || c.right < -i || c.left > window.innerWidth + i);
718
+ }
719
+ for (const c of p)
720
+ if (!(c.width === 0 || c.height === 0) && !(c.bottom < -i || c.top > window.innerHeight + i || c.right < -i || c.left > window.innerWidth + i))
721
+ return !0;
722
+ return !1;
723
+ }
724
+ function F(t) {
725
+ if (!t || t.nodeType !== Node.ELEMENT_NODE) return !1;
726
+ const i = t.tagName.toLowerCase();
727
+ return (/* @__PURE__ */ new Set([
728
+ "a",
729
+ "button",
730
+ "input",
731
+ "select",
732
+ "textarea",
733
+ "details",
734
+ "summary",
735
+ "label"
736
+ ])).has(i) ? !0 : t.hasAttribute("onclick") || t.hasAttribute("role") || t.hasAttribute("tabindex") || t.hasAttribute("aria-") || t.hasAttribute("data-action") || t.getAttribute("contenteditable") === "true";
737
+ }
738
+ const Y = /* @__PURE__ */ new Set([
739
+ "a",
740
+ "button",
741
+ "input",
742
+ "select",
743
+ "textarea",
744
+ "summary",
745
+ "details",
746
+ "label",
747
+ "option"
748
+ ]), K = /* @__PURE__ */ new Set([
749
+ "button",
750
+ "link",
751
+ "menuitem",
752
+ "menuitemradio",
753
+ "menuitemcheckbox",
754
+ "radio",
755
+ "checkbox",
756
+ "tab",
757
+ "switch",
758
+ "slider",
759
+ "spinbutton",
760
+ "combobox",
761
+ "searchbox",
762
+ "textbox",
763
+ "listbox",
764
+ "option",
765
+ "scrollbar"
766
+ ]);
767
+ function tt(t) {
768
+ if (!t || t.nodeType !== Node.ELEMENT_NODE || !X(t)) return !1;
769
+ const i = t.hasAttribute("role") || t.hasAttribute("tabindex") || t.hasAttribute("onclick") || typeof t.onclick == "function", p = /\b(btn|clickable|menu|item|entry|link)\b/i.test(
770
+ t.className || ""
771
+ ), c = !!t.closest('button,a,[role="button"],.menu,.dropdown,.list,.toolbar'), a = [...t.children].some(X), x = t.parentElement && t.parentElement.isSameNode(document.body);
772
+ return (L(t) || i || p) && a && c && !x;
773
+ }
774
+ function rt(t) {
775
+ var c, a;
776
+ if (!t || t.nodeType !== Node.ELEMENT_NODE)
777
+ return !1;
778
+ const i = t.tagName.toLowerCase(), p = t.getAttribute("role");
779
+ if (i === "iframe" || Y.has(i) || p && K.has(p) || t.isContentEditable || t.getAttribute("contenteditable") === "true" || t.hasAttribute("data-testid") || t.hasAttribute("data-cy") || t.hasAttribute("data-test") || t.hasAttribute("onclick") || typeof t.onclick == "function")
780
+ return !0;
781
+ try {
782
+ const x = ((a = (c = t == null ? void 0 : t.ownerDocument) == null ? void 0 : c.defaultView) == null ? void 0 : a.getEventListenersForNode) || window.getEventListenersForNode;
783
+ if (typeof x == "function") {
784
+ const I = x(t), m = [
785
+ "click",
786
+ "mousedown",
787
+ "mouseup",
788
+ "keydown",
789
+ "keyup",
790
+ "submit",
791
+ "change",
792
+ "input",
793
+ "focus",
794
+ "blur"
795
+ ];
796
+ for (const A of m)
797
+ for (const $ of I)
798
+ if ($.type === A)
799
+ return !0;
800
+ }
801
+ if ([
802
+ "onmousedown",
803
+ "onmouseup",
804
+ "onkeydown",
805
+ "onkeyup",
806
+ "onsubmit",
807
+ "onchange",
808
+ "oninput",
809
+ "onfocus",
810
+ "onblur"
811
+ ].some((I) => t.hasAttribute(I)))
812
+ return !0;
813
+ } catch {
814
+ }
815
+ return !!tt(t);
816
+ }
817
+ function st(t, i, p, c) {
818
+ if (!t.isInteractive) return !1;
819
+ let a = !1;
820
+ return c ? rt(i) ? a = !0 : a = !1 : a = !0, a && (t.isInViewport = ot(i, l), (t.isInViewport || l === -1) && (t.highlightIndex = T++, d)) ? (r >= 0 ? r === t.highlightIndex && H(i, t.highlightIndex, p) : H(i, t.highlightIndex, p), !0) : !1;
821
+ }
822
+ function Q(t, i = null, p = !1) {
823
+ var E, I, m, A, $;
824
+ if (!t || t.id === U || t.nodeType !== Node.ELEMENT_NODE && t.nodeType !== Node.TEXT_NODE || !t || t.id === U || ((E = t.dataset) == null ? void 0 : E.browserUseIgnore) === "true" || t.getAttribute && t.getAttribute("aria-hidden") === "true")
825
+ return null;
826
+ if (t === document.body) {
827
+ const g = {
828
+ tagName: "body",
829
+ attributes: {},
830
+ xpath: "/body",
831
+ children: []
832
+ };
833
+ for (const C of t.childNodes) {
834
+ const M = Q(C, i, !1);
835
+ M && g.children.push(M);
836
+ }
837
+ const y = `${R.current++}`;
838
+ return _[y] = g, y;
839
+ }
840
+ if (t.nodeType !== Node.ELEMENT_NODE && t.nodeType !== Node.TEXT_NODE)
841
+ return null;
842
+ if (t.nodeType === Node.TEXT_NODE) {
843
+ const g = (I = t.textContent) == null ? void 0 : I.trim();
844
+ if (!g)
845
+ return null;
846
+ const y = t.parentElement;
847
+ if (!y || y.tagName.toLowerCase() === "script")
848
+ return null;
849
+ const C = `${R.current++}`;
850
+ return _[C] = {
851
+ type: "TEXT_NODE",
852
+ text: g,
853
+ isVisible: O(t)
854
+ }, C;
855
+ }
856
+ if (t.nodeType === Node.ELEMENT_NODE && !it(t))
857
+ return null;
858
+ if (l !== -1 && !t.shadowRoot) {
859
+ const g = N(t), y = D(t), C = y && (y.position === "fixed" || y.position === "sticky"), M = t.offsetWidth > 0 || t.offsetHeight > 0;
860
+ if (!g || !C && !M && (g.bottom < -l || g.top > window.innerHeight + l || g.right < -l || g.left > window.innerWidth + l))
861
+ return null;
862
+ }
863
+ const c = {
864
+ tagName: t.tagName.toLowerCase(),
865
+ attributes: {},
866
+ /**
867
+ * @edit no need for xpath
868
+ */
869
+ // xpath: getXPathTree(node, true),
870
+ children: []
871
+ };
872
+ if (F(t) || t.tagName.toLowerCase() === "iframe" || t.tagName.toLowerCase() === "body") {
873
+ const g = ((m = t.getAttributeNames) == null ? void 0 : m.call(t)) || [];
874
+ for (const y of g) {
875
+ const C = t.getAttribute(y);
876
+ c.attributes[y] = C;
877
+ }
878
+ t.tagName.toLowerCase() === "input" && (t.type === "checkbox" || t.type === "radio") && (c.attributes.checked = t.checked ? "true" : "false");
879
+ }
880
+ let a = !1;
881
+ if (t.nodeType === Node.ELEMENT_NODE && (c.isVisible = X(t), c.isVisible)) {
882
+ c.isTopElement = et(t);
883
+ const g = t.getAttribute("role"), y = g === "menu" || g === "menubar" || g === "listbox";
884
+ (c.isTopElement || y) && (c.isInteractive = L(t), a = st(c, t, i, p), c.ref = t);
885
+ }
886
+ if (t.tagName) {
887
+ const g = t.tagName.toLowerCase();
888
+ if (g === "iframe")
889
+ try {
890
+ const y = t.contentDocument || ((A = t.contentWindow) == null ? void 0 : A.document);
891
+ if (y)
892
+ for (const C of y.childNodes) {
893
+ const M = Q(C, t, !1);
894
+ M && c.children.push(M);
895
+ }
896
+ } catch (y) {
897
+ console.warn("Unable to access iframe:", y);
898
+ }
899
+ else if (t.isContentEditable || t.getAttribute("contenteditable") === "true" || t.id === "tinymce" || t.classList.contains("mce-content-body") || g === "body" && (($ = t.getAttribute("data-id")) != null && $.startsWith("mce_")))
900
+ for (const y of t.childNodes) {
901
+ const C = Q(y, i, a);
902
+ C && c.children.push(C);
903
+ }
904
+ else {
905
+ if (t.shadowRoot) {
906
+ c.shadowRoot = !0;
907
+ for (const y of t.shadowRoot.childNodes) {
908
+ const C = Q(y, i, a);
909
+ C && c.children.push(C);
910
+ }
911
+ }
912
+ for (const y of t.childNodes) {
913
+ const M = Q(y, i, a || p);
914
+ M && c.children.push(M);
915
+ }
916
+ }
917
+ }
918
+ if (c.tagName === "a" && c.children.length === 0 && !c.attributes.href) {
919
+ const g = N(t);
920
+ if (!(g && g.width > 0 && g.height > 0 || t.offsetWidth > 0 || t.offsetHeight > 0))
921
+ return null;
922
+ }
923
+ c.extra = b.get(t) || null;
924
+ const x = `${R.current++}`;
925
+ return _[x] = c, x;
926
+ }
927
+ const lt = Q(document.body);
928
+ return f.clearCache(), { rootId: lt, map: _ };
929
+ }, newElementsCache = /* @__PURE__ */ new WeakMap();
930
+ function getFlatTree(e) {
931
+ const n = [];
932
+ for (const d of e.interactiveBlacklist || [])
933
+ typeof d == "function" ? n.push(d()) : n.push(d);
934
+ const s = [];
935
+ for (const d of e.interactiveWhitelist || [])
936
+ typeof d == "function" ? s.push(d()) : s.push(d);
937
+ const o = domTree({
938
+ doHighlightElements: !0,
939
+ debugMode: !0,
940
+ focusHighlightIndex: -1,
941
+ viewportExpansion: VIEWPORT_EXPANSION,
942
+ interactiveBlacklist: n,
943
+ interactiveWhitelist: s,
944
+ highlightOpacity: e.highlightOpacity ?? 0,
945
+ highlightLabelOpacity: e.highlightLabelOpacity ?? 0.1
946
+ }), w = window.location.href;
947
+ for (const d in o.map) {
948
+ const r = o.map[d];
949
+ if (r.isInteractive && r.ref) {
950
+ const l = r.ref;
951
+ newElementsCache.has(l) || (newElementsCache.set(l, w), r.isNew = !0);
952
+ }
953
+ }
954
+ return o;
955
+ }
956
+ function flatTreeToString(e, n) {
957
+ const s = [
958
+ "title",
959
+ "type",
960
+ "checked",
961
+ "name",
962
+ "role",
963
+ "value",
964
+ "placeholder",
965
+ "data-date-format",
966
+ "alt",
967
+ "aria-label",
968
+ "aria-expanded",
969
+ "data-state",
970
+ "aria-checked",
971
+ // @edit added for better form handling
972
+ "id",
973
+ "for",
974
+ // for jump check
975
+ "target",
976
+ // absolute 定位的下拉菜单
977
+ "aria-haspopup",
978
+ "aria-controls",
979
+ "aria-owns"
980
+ ], o = [...n || [], ...s], w = (u, f) => u.length > f ? u.substring(0, f) + "..." : u, d = (u) => {
981
+ const f = e.map[u];
982
+ if (!f) return null;
983
+ if (f.type === "TEXT_NODE") {
984
+ const N = f;
985
+ return {
986
+ type: "text",
987
+ text: N.text,
988
+ isVisible: N.isVisible,
989
+ parent: null,
990
+ children: []
991
+ };
992
+ } else {
993
+ const N = f, D = [];
994
+ if (N.children)
995
+ for (const z of N.children) {
996
+ const _ = d(z);
997
+ _ && (_.parent = null, D.push(_));
998
+ }
999
+ return {
1000
+ type: "element",
1001
+ tagName: N.tagName,
1002
+ attributes: N.attributes ?? {},
1003
+ isVisible: N.isVisible ?? !1,
1004
+ isInteractive: N.isInteractive ?? !1,
1005
+ isTopElement: N.isTopElement ?? !1,
1006
+ isNew: N.isNew ?? !1,
1007
+ highlightIndex: N.highlightIndex,
1008
+ parent: null,
1009
+ children: D,
1010
+ extra: N.extra ?? {}
1011
+ };
1012
+ }
1013
+ }, r = (u, f = null) => {
1014
+ u.parent = f;
1015
+ for (const N of u.children)
1016
+ r(N, u);
1017
+ }, l = d(e.rootId);
1018
+ if (!l) return "";
1019
+ r(l);
1020
+ const h = (u) => {
1021
+ let f = u.parent;
1022
+ for (; f; ) {
1023
+ if (f.type === "element" && f.highlightIndex !== void 0)
1024
+ return !0;
1025
+ f = f.parent;
1026
+ }
1027
+ return !1;
1028
+ }, T = (u, f, N) => {
1029
+ var _, R, U, H;
1030
+ let D = f;
1031
+ const z = " ".repeat(f);
1032
+ if (u.type === "element") {
1033
+ if (u.highlightIndex !== void 0) {
1034
+ D += 1;
1035
+ const V = getAllTextTillNextClickableElement(u);
1036
+ let O = "";
1037
+ if (o.length > 0 && u.attributes) {
1038
+ const L = {};
1039
+ for (const F of o) {
1040
+ const Y = u.attributes[F];
1041
+ Y && Y.trim() !== "" && (L[F] = Y.trim());
1042
+ }
1043
+ const et = o.filter((F) => F in L);
1044
+ if (et.length > 1) {
1045
+ const F = /* @__PURE__ */ new Set(), Y = {};
1046
+ for (const K of et) {
1047
+ const tt = L[K];
1048
+ tt.length > 5 && (tt in Y ? F.add(K) : Y[tt] = K);
1049
+ }
1050
+ for (const K of F)
1051
+ delete L[K];
1052
+ }
1053
+ L.role === u.tagName && delete L.role;
1054
+ const ot = ["aria-label", "placeholder", "title"];
1055
+ for (const F of ot)
1056
+ L[F] && L[F].toLowerCase().trim() === V.toLowerCase().trim() && delete L[F];
1057
+ Object.keys(L).length > 0 && (O = Object.entries(L).map(([F, Y]) => `${F}=${w(Y, 20)}`).join(" "));
1058
+ }
1059
+ const it = u.isNew ? `*[${u.highlightIndex}]` : `[${u.highlightIndex}]`;
1060
+ let X = `${z}${it}<${u.tagName ?? ""}`;
1061
+ if (O && (X += ` ${O}`), u.extra && u.extra.scrollable) {
1062
+ let L = "";
1063
+ (_ = u.extra.scrollData) != null && _.left && (L += `left=${u.extra.scrollData.left}, `), (R = u.extra.scrollData) != null && R.top && (L += `top=${u.extra.scrollData.top}, `), (U = u.extra.scrollData) != null && U.right && (L += `right=${u.extra.scrollData.right}, `), (H = u.extra.scrollData) != null && H.bottom && (L += `bottom=${u.extra.scrollData.bottom}`), X += ` data-scrollable="${L}"`;
1064
+ }
1065
+ if (V) {
1066
+ const L = V.trim();
1067
+ O || (X += " "), X += `>${L}`;
1068
+ } else O || (X += " ");
1069
+ X += " />", N.push(X);
1070
+ }
1071
+ for (const V of u.children)
1072
+ T(V, D, N);
1073
+ } else if (u.type === "text") {
1074
+ if (h(u))
1075
+ return;
1076
+ u.parent && u.parent.type === "element" && u.parent.isVisible && u.parent.isTopElement && N.push(`${z}${u.text ?? ""}`);
1077
+ }
1078
+ }, b = [];
1079
+ return T(l, 0, b), b.join(`
1080
+ `);
1081
+ }
1082
+ const getAllTextTillNextClickableElement = (e, n = -1) => {
1083
+ const s = [], o = (w, d) => {
1084
+ if (!(n !== -1 && d > n) && !(w.type === "element" && w !== e && w.highlightIndex !== void 0)) {
1085
+ if (w.type === "text" && w.text)
1086
+ s.push(w.text);
1087
+ else if (w.type === "element")
1088
+ for (const r of w.children)
1089
+ o(r, d + 1);
1090
+ }
1091
+ };
1092
+ return o(e, 0), s.join(`
1093
+ `).trim();
1094
+ };
1095
+ function getSelectorMap(e) {
1096
+ const n = /* @__PURE__ */ new Map(), s = Object.keys(e.map);
1097
+ for (const o of s) {
1098
+ const w = e.map[o];
1099
+ w.isInteractive && typeof w.highlightIndex == "number" && n.set(w.highlightIndex, w);
1100
+ }
1101
+ return n;
1102
+ }
1103
+ function getElementTextMap(e) {
1104
+ const n = e.split(`
1105
+ `).map((o) => o.trim()).filter((o) => o.length > 0), s = /* @__PURE__ */ new Map();
1106
+ for (const o of n) {
1107
+ const d = /^\[(\d+)\]<[^>]+>([^<]*)/.exec(o);
1108
+ if (d) {
1109
+ const r = parseInt(d[1], 10);
1110
+ s.set(r, o);
1111
+ }
1112
+ }
1113
+ return s;
1114
+ }
1115
+ function cleanUpHighlights() {
1116
+ const e = window._highlightCleanupFunctions || [];
1117
+ for (const n of e)
1118
+ typeof n == "function" && n();
1119
+ window._highlightCleanupFunctions = [];
1120
+ }
1121
+ window.addEventListener("popstate", () => {
1122
+ cleanUpHighlights();
1123
+ });
1124
+ window.addEventListener("hashchange", () => {
1125
+ cleanUpHighlights();
1126
+ });
1127
+ window.addEventListener("beforeunload", () => {
1128
+ cleanUpHighlights();
1129
+ });
1130
+ const navigation = window.navigation;
1131
+ if (navigation && typeof navigation.addEventListener == "function")
1132
+ navigation.addEventListener("navigate", () => {
1133
+ cleanUpHighlights();
1134
+ });
1135
+ else {
1136
+ let e = window.location.href;
1137
+ setInterval(() => {
1138
+ window.location.href !== e && (e = window.location.href, cleanUpHighlights());
1139
+ }, 500);
1140
+ }
1141
+ function getPageInfo() {
1142
+ const e = window.innerWidth, n = window.innerHeight, s = Math.max(document.documentElement.scrollWidth, document.body.scrollWidth || 0), o = Math.max(
1143
+ document.documentElement.scrollHeight,
1144
+ document.body.scrollHeight || 0
1145
+ ), w = window.scrollX || window.pageXOffset || document.documentElement.scrollLeft || 0, d = window.scrollY || window.pageYOffset || document.documentElement.scrollTop || 0, r = Math.max(0, o - (window.innerHeight + d)), l = Math.max(0, s - (window.innerWidth + w));
1146
+ return {
1147
+ // Current viewport dimensions
1148
+ viewport_width: e,
1149
+ viewport_height: n,
1150
+ // Total page dimensions
1151
+ page_width: s,
1152
+ page_height: o,
1153
+ // Current scroll position
1154
+ scroll_x: w,
1155
+ scroll_y: d,
1156
+ pixels_above: d,
1157
+ pixels_below: r,
1158
+ pages_above: n > 0 ? d / n : 0,
1159
+ pages_below: n > 0 ? r / n : 0,
1160
+ total_pages: n > 0 ? o / n : 0,
1161
+ current_page_position: d / Math.max(1, o - n),
1162
+ pixels_left: w,
1163
+ pixels_right: l
1164
+ };
1165
+ }
1166
+ function patchReact(e) {
1167
+ const n = document.querySelectorAll(
1168
+ '[data-reactroot], [data-reactid], [data-react-checksum], #root, #app, [id^="root-"], [id^="app-"], #adex-wrapper, #adex-root'
1169
+ );
1170
+ for (const s of n)
1171
+ s.setAttribute("data-page-agent-not-interactive", "true");
1172
+ }
1173
+ class PageController extends EventTarget {
1174
+ constructor(e = {}) {
1175
+ super(), this.flatTree = null, this.selectorMap = /* @__PURE__ */ new Map(), this.elementTextMap = /* @__PURE__ */ new Map(), this.simplifiedHTML = "<EMPTY>", this.lastTimeUpdate = 0, this.isIndexed = !1, this.mask = null, this.maskReady = null, this.config = e, patchReact(), e.enableMask && this.initMask();
1176
+ }
1177
+ /**
1178
+ * Initialize mask asynchronously (dynamic import to avoid CSS loading in Node)
1179
+ */
1180
+ initMask() {
1181
+ this.maskReady === null && (this.maskReady = (async () => {
1182
+ const { SimulatorMask: e } = await import("./SimulatorMask-74sRLkJv.js");
1183
+ this.mask = new e();
1184
+ })());
1185
+ }
1186
+ // ======= State Queries =======
1187
+ /**
1188
+ * Get current page URL
1189
+ */
1190
+ async getCurrentUrl() {
1191
+ return window.location.href;
1192
+ }
1193
+ /**
1194
+ * Get last tree update timestamp
1195
+ */
1196
+ async getLastUpdateTime() {
1197
+ return this.lastTimeUpdate;
1198
+ }
1199
+ /**
1200
+ * Get structured browser state for LLM consumption.
1201
+ * Automatically calls updateTree() to refresh the DOM state.
1202
+ */
1203
+ async getBrowserState() {
1204
+ const e = window.location.href, n = document.title, s = getPageInfo(), o = this.config.viewportExpansion ?? VIEWPORT_EXPANSION;
1205
+ await this.updateTree();
1206
+ const w = this.simplifiedHTML, d = `Current Page: [${n}](${e})`, r = `Page info: ${s.viewport_width}x${s.viewport_height}px viewport, ${s.page_width}x${s.page_height}px total page size, ${s.pages_above.toFixed(1)} pages above, ${s.pages_below.toFixed(1)} pages below, ${s.total_pages.toFixed(1)} total pages, at ${(s.current_page_position * 100).toFixed(0)}% of page`, l = o === -1 ? "Interactive elements from top layer of the current page (full page):" : "Interactive elements from top layer of the current page inside the viewport:", T = s.pixels_above > 4 && o !== -1 ? `... ${s.pixels_above} pixels above (${s.pages_above.toFixed(1)} pages) - scroll to see more ...` : "[Start of page]", b = `${d}
1207
+ ${r}
1208
+
1209
+ ${l}
1210
+
1211
+ ${T}`, f = s.pixels_below > 4 && o !== -1 ? `... ${s.pixels_below} pixels below (${s.pages_below.toFixed(1)} pages) - scroll to see more ...` : "[End of page]";
1212
+ return { url: e, title: n, header: b, content: w, footer: f };
1213
+ }
1214
+ // ======= DOM Tree Operations =======
1215
+ /**
1216
+ * Update DOM tree, returns simplified HTML for LLM.
1217
+ * This is the main method to refresh the page state.
1218
+ * Automatically bypasses mask during DOM extraction if enabled.
1219
+ */
1220
+ async updateTree() {
1221
+ this.dispatchEvent(new Event("beforeUpdate")), this.lastTimeUpdate = Date.now(), this.mask && (this.mask.wrapper.style.pointerEvents = "none"), cleanUpHighlights();
1222
+ const e = [
1223
+ ...this.config.interactiveBlacklist || [],
1224
+ ...document.querySelectorAll("[data-page-agent-not-interactive]").values()
1225
+ ];
1226
+ return this.flatTree = getFlatTree({
1227
+ ...this.config,
1228
+ interactiveBlacklist: e
1229
+ }), this.simplifiedHTML = flatTreeToString(this.flatTree, this.config.include_attributes), this.selectorMap.clear(), this.selectorMap = getSelectorMap(this.flatTree), this.elementTextMap.clear(), this.elementTextMap = getElementTextMap(this.simplifiedHTML), this.isIndexed = !0, this.mask && (this.mask.wrapper.style.pointerEvents = "auto"), this.dispatchEvent(new Event("afterUpdate")), this.simplifiedHTML;
1230
+ }
1231
+ /**
1232
+ * Clean up all element highlights
1233
+ */
1234
+ async cleanUpHighlights() {
1235
+ cleanUpHighlights();
1236
+ }
1237
+ // ======= Element Actions =======
1238
+ /**
1239
+ * Ensure the tree has been indexed before any index-based operation.
1240
+ * Throws if updateTree() hasn't been called yet.
1241
+ */
1242
+ assertIndexed() {
1243
+ if (!this.isIndexed)
1244
+ throw new Error("DOM tree not indexed yet. Can not perform actions on elements.");
1245
+ }
1246
+ /**
1247
+ * Click element by index
1248
+ */
1249
+ async clickElement(e) {
1250
+ try {
1251
+ this.assertIndexed();
1252
+ const n = getElementByIndex(this.selectorMap, e), s = this.elementTextMap.get(e);
1253
+ return await clickElement(n), n instanceof HTMLAnchorElement && n.target === "_blank" ? {
1254
+ success: !0,
1255
+ message: `✅ Clicked element (${s ?? e}). ⚠️ Link opens in a new tab. You are not capable of reading new tabs.`
1256
+ } : {
1257
+ success: !0,
1258
+ message: `✅ Clicked element (${s ?? e}).`
1259
+ };
1260
+ } catch (n) {
1261
+ return {
1262
+ success: !1,
1263
+ message: `❌ Failed to click element: ${n}`
1264
+ };
1265
+ }
1266
+ }
1267
+ /**
1268
+ * Input text into element by index
1269
+ */
1270
+ async inputText(e, n) {
1271
+ try {
1272
+ this.assertIndexed();
1273
+ const s = getElementByIndex(this.selectorMap, e), o = this.elementTextMap.get(e);
1274
+ return await inputTextElement(s, n), {
1275
+ success: !0,
1276
+ message: `✅ Input text (${n}) into element (${o ?? e}).`
1277
+ };
1278
+ } catch (s) {
1279
+ return {
1280
+ success: !1,
1281
+ message: `❌ Failed to input text: ${s}`
1282
+ };
1283
+ }
1284
+ }
1285
+ /**
1286
+ * Select dropdown option by index and option text
1287
+ */
1288
+ async selectOption(e, n) {
1289
+ try {
1290
+ this.assertIndexed();
1291
+ const s = getElementByIndex(this.selectorMap, e), o = this.elementTextMap.get(e);
1292
+ return await selectOptionElement(s, n), {
1293
+ success: !0,
1294
+ message: `✅ Selected option (${n}) in element (${o ?? e}).`
1295
+ };
1296
+ } catch (s) {
1297
+ return {
1298
+ success: !1,
1299
+ message: `❌ Failed to select option: ${s}`
1300
+ };
1301
+ }
1302
+ }
1303
+ /**
1304
+ * Scroll vertically
1305
+ */
1306
+ async scroll(e) {
1307
+ try {
1308
+ const { down: n, numPages: s, pixels: o, index: w } = e;
1309
+ this.assertIndexed();
1310
+ const d = o ?? s * (n ? 1 : -1) * window.innerHeight, r = w !== void 0 ? getElementByIndex(this.selectorMap, w) : null;
1311
+ return {
1312
+ success: !0,
1313
+ message: await scrollVertically(n, d, r)
1314
+ };
1315
+ } catch (n) {
1316
+ return {
1317
+ success: !1,
1318
+ message: `❌ Failed to scroll: ${n}`
1319
+ };
1320
+ }
1321
+ }
1322
+ /**
1323
+ * Scroll horizontally
1324
+ */
1325
+ async scrollHorizontally(e) {
1326
+ try {
1327
+ const { right: n, pixels: s, index: o } = e;
1328
+ this.assertIndexed();
1329
+ const w = s * (n ? 1 : -1), d = o !== void 0 ? getElementByIndex(this.selectorMap, o) : null;
1330
+ return {
1331
+ success: !0,
1332
+ message: await scrollHorizontally(n, w, d)
1333
+ };
1334
+ } catch (n) {
1335
+ return {
1336
+ success: !1,
1337
+ message: `❌ Failed to scroll horizontally: ${n}`
1338
+ };
1339
+ }
1340
+ }
1341
+ /**
1342
+ * Execute arbitrary JavaScript on the page
1343
+ */
1344
+ async executeJavascript(script) {
1345
+ try {
1346
+ const asyncFunction = eval(`(async () => { ${script} })`), result = await asyncFunction();
1347
+ return {
1348
+ success: !0,
1349
+ message: `✅ Executed JavaScript. Result: ${result}`
1350
+ };
1351
+ } catch (e) {
1352
+ return {
1353
+ success: !1,
1354
+ message: `❌ Error executing JavaScript: ${e}`
1355
+ };
1356
+ }
1357
+ }
1358
+ // ======= Mask Operations =======
1359
+ /**
1360
+ * Show the visual mask overlay.
1361
+ * Only works after mask is setup.
1362
+ */
1363
+ async showMask() {
1364
+ var e;
1365
+ await this.maskReady, (e = this.mask) == null || e.show();
1366
+ }
1367
+ /**
1368
+ * Hide the visual mask overlay.
1369
+ * Only works after mask is setup.
1370
+ */
1371
+ async hideMask() {
1372
+ var e;
1373
+ await this.maskReady, (e = this.mask) == null || e.hide();
1374
+ }
1375
+ /**
1376
+ * Dispose and clean up resources
1377
+ */
1378
+ dispose() {
1379
+ var e;
1380
+ cleanUpHighlights(), this.flatTree = null, this.selectorMap.clear(), this.elementTextMap.clear(), this.simplifiedHTML = "<EMPTY>", this.isIndexed = !1, (e = this.mask) == null || e.dispose(), this.mask = null;
1381
+ }
1382
+ }
1383
+ export {
1384
+ PageController
1385
+ };