@whenessel/seql-js 1.1.1 → 1.2.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.
package/dist/seql-js.js CHANGED
@@ -1,9 +1,9 @@
1
- const ee = "1.0", se = 10, L = {
1
+ const se = "1.0", re = 10, _ = {
2
2
  ANCHOR: 0.4,
3
3
  PATH: 0.3,
4
4
  TARGET: 0.2,
5
5
  UNIQUENESS: 0.1
6
- }, I = {
6
+ }, N = {
7
7
  SEMANTIC_TAG: 0.5,
8
8
  ROLE: 0.3,
9
9
  ARIA_LABEL: 0.1,
@@ -12,7 +12,7 @@ const ee = "1.0", se = 10, L = {
12
12
  DEPTH_PENALTY_THRESHOLD: 5,
13
13
  DEPTH_PENALTY_FACTOR: 0.05,
14
14
  DEGRADED_SCORE: 0.3
15
- }, ct = {
15
+ }, lt = {
16
16
  MIN_CONFIDENCE_FOR_SKIP: 0.7
17
17
  }, X = [
18
18
  "form",
@@ -31,7 +31,7 @@ const ee = "1.0", se = 10, L = {
31
31
  "complementary",
32
32
  "banner",
33
33
  "search"
34
- ], lt = [
34
+ ], ht = [
35
35
  // HTML5 Semantic
36
36
  "article",
37
37
  "aside",
@@ -108,7 +108,7 @@ const ee = "1.0", se = 10, L = {
108
108
  "g",
109
109
  "text",
110
110
  "use"
111
- ], ht = [
111
+ ], ut = [
112
112
  "rect",
113
113
  "path",
114
114
  "circle",
@@ -122,7 +122,7 @@ const ee = "1.0", se = 10, L = {
122
122
  "defs",
123
123
  "clipPath",
124
124
  "mask"
125
- ], re = [
125
+ ], ne = [
126
126
  "aria-label",
127
127
  "aria-labelledby",
128
128
  "aria-describedby",
@@ -135,7 +135,7 @@ const ee = "1.0", se = 10, L = {
135
135
  "title",
136
136
  "placeholder",
137
137
  "alt"
138
- ], w = {
138
+ ], E = {
139
139
  // Test attributes (highest priority)
140
140
  "data-testid": 100,
141
141
  "data-qa": 99,
@@ -174,14 +174,14 @@ const ee = "1.0", se = 10, L = {
174
174
  "tabindex",
175
175
  // can change
176
176
  "contenteditable"
177
- ]), ut = {
177
+ ]), dt = {
178
178
  maxPathDepth: 10,
179
179
  enableSvgFingerprint: !0,
180
180
  confidenceThreshold: 0.1,
181
181
  fallbackToBody: !0,
182
182
  includeUtilityClasses: !1,
183
183
  source: "dom-dsl"
184
- }, dt = {
184
+ }, ft = {
185
185
  strictMode: !1,
186
186
  enableFallback: !0,
187
187
  maxCandidates: 20
@@ -206,7 +206,7 @@ const G = /* @__PURE__ */ new Set([
206
206
  function V(n) {
207
207
  return n.trim().split(/\s+/).some((e) => D(e));
208
208
  }
209
- class ft {
209
+ class gt {
210
210
  constructor(t, e) {
211
211
  this.maxDepth = t.maxPathDepth ?? 10, this.cache = e;
212
212
  }
@@ -214,33 +214,72 @@ class ft {
214
214
  * Finds the best anchor element for the target
215
215
  * @param target - Target element to find anchor for
216
216
  * @returns Anchor result or null if not found
217
+ * @remarks
218
+ * Special handling for root elements (html, head, body):
219
+ * - For html: returns html itself as anchor
220
+ * - For head or elements inside head: returns html as anchor
221
+ * - For body: returns html as anchor
217
222
  */
218
223
  findAnchor(t) {
219
224
  if (this.cache) {
220
- const i = this.cache.getAnchor(t);
221
- if (i !== void 0)
222
- return i;
225
+ const c = this.cache.getAnchor(t);
226
+ if (c !== void 0)
227
+ return c;
228
+ }
229
+ const e = t.tagName.toLowerCase(), s = t.ownerDocument;
230
+ if (e === "html") {
231
+ const c = {
232
+ element: t,
233
+ score: 1,
234
+ tier: "A",
235
+ depth: 0
236
+ };
237
+ return this.cacheResult(t, c), c;
238
+ }
239
+ if (e === "head" || this.isInsideHead(t)) {
240
+ const c = s?.documentElement;
241
+ if (c) {
242
+ const u = {
243
+ element: c,
244
+ score: 1,
245
+ tier: "A",
246
+ depth: 0
247
+ };
248
+ return this.cacheResult(t, u), u;
249
+ }
223
250
  }
224
- let e = t.parentElement, s = 0, r = null;
225
- for (; e && s < this.maxDepth; ) {
226
- if (e.tagName.toLowerCase() === "body")
227
- return r || {
228
- element: e,
229
- score: I.DEGRADED_SCORE,
251
+ if (e === "body") {
252
+ const c = s?.documentElement;
253
+ if (c) {
254
+ const u = {
255
+ element: c,
256
+ score: 1,
257
+ tier: "A",
258
+ depth: 0
259
+ };
260
+ return this.cacheResult(t, u), u;
261
+ }
262
+ }
263
+ let r = t.parentElement, a = 0, i = null;
264
+ for (; r && a < this.maxDepth; ) {
265
+ if (r.tagName.toLowerCase() === "body")
266
+ return i || {
267
+ element: r,
268
+ score: N.DEGRADED_SCORE,
230
269
  tier: "C",
231
- depth: s
270
+ depth: a
232
271
  };
233
- const i = this.scoreAnchor(e);
234
- if (i > 0) {
235
- const o = this.applyDepthPenalty(i, s), l = this.getTier(e), u = { element: e, score: o, tier: l, depth: s };
236
- if (l === "A")
237
- return u;
238
- (!r || o > r.score) && (r = u);
272
+ const c = this.scoreAnchor(r);
273
+ if (c > 0) {
274
+ const u = this.applyDepthPenalty(c, a), d = this.getTier(r), l = { element: r, score: u, tier: d, depth: a };
275
+ if (d === "A")
276
+ return l;
277
+ (!i || u > i.score) && (i = l);
239
278
  }
240
- e = e.parentElement, s++;
279
+ r = r.parentElement, a++;
241
280
  }
242
- const a = r;
243
- return this.cache && this.cache.setAnchor(t, a), a;
281
+ const o = i;
282
+ return this.cache && this.cache.setAnchor(t, o), o;
244
283
  }
245
284
  /**
246
285
  * Scores an element as anchor candidate (without depth penalty)
@@ -250,20 +289,20 @@ class ft {
250
289
  scoreAnchor(t) {
251
290
  let e = 0;
252
291
  const s = t.tagName.toLowerCase();
253
- X.includes(s) && (e += I.SEMANTIC_TAG);
292
+ X.includes(s) && (e += N.SEMANTIC_TAG);
254
293
  const r = t.getAttribute("role");
255
- r && K.includes(r) && (e += I.ROLE), (t.hasAttribute("aria-label") || t.hasAttribute("aria-labelledby")) && (e += I.ARIA_LABEL);
294
+ r && K.includes(r) && (e += N.ROLE), (t.hasAttribute("aria-label") || t.hasAttribute("aria-labelledby")) && (e += N.ARIA_LABEL);
256
295
  const a = t.id;
257
- return a && !D(a) && (e += I.STABLE_ID), (t.hasAttribute("data-testid") || t.hasAttribute("data-qa") || t.hasAttribute("data-test")) && (e += I.TEST_MARKER), Math.min(e, 1);
296
+ return a && !D(a) && (e += N.STABLE_ID), (t.hasAttribute("data-testid") || t.hasAttribute("data-qa") || t.hasAttribute("data-test")) && (e += N.TEST_MARKER), Math.min(e, 1);
258
297
  }
259
298
  /**
260
299
  * Applies depth penalty to score
261
300
  * Following SPECIFICATION.md §7: depthPenalty = (depth - threshold) * factor
262
301
  */
263
302
  applyDepthPenalty(t, e) {
264
- if (e <= I.DEPTH_PENALTY_THRESHOLD)
303
+ if (e <= N.DEPTH_PENALTY_THRESHOLD)
265
304
  return t;
266
- const s = (e - I.DEPTH_PENALTY_THRESHOLD) * I.DEPTH_PENALTY_FACTOR;
305
+ const s = (e - N.DEPTH_PENALTY_THRESHOLD) * N.DEPTH_PENALTY_FACTOR;
267
306
  return Math.max(0, t - s);
268
307
  }
269
308
  /**
@@ -276,8 +315,38 @@ class ft {
276
315
  const s = t.getAttribute("role");
277
316
  return s && K.includes(s) ? "B" : "C";
278
317
  }
318
+ /**
319
+ * Checks if element is inside <head> section.
320
+ * Stops at <body> to avoid false positives.
321
+ * @param element - Element to check
322
+ * @returns True if element is inside head, false otherwise
323
+ * @remarks
324
+ * Traverses up the DOM tree until finding head or body.
325
+ * Returns false if body is encountered first.
326
+ * @example
327
+ * const meta = document.querySelector('meta');
328
+ * if (isInsideHead(meta)) { ... }
329
+ */
330
+ isInsideHead(t) {
331
+ let e = t.parentElement;
332
+ for (; e; ) {
333
+ const s = e.tagName.toLowerCase();
334
+ if (s === "head") return !0;
335
+ if (s === "body") return !1;
336
+ e = e.parentElement;
337
+ }
338
+ return !1;
339
+ }
340
+ /**
341
+ * Caches the anchor result for the target element
342
+ * @param target - Target element
343
+ * @param result - Anchor result to cache
344
+ */
345
+ cacheResult(t, e) {
346
+ this.cache && this.cache.setAnchor(t, e);
347
+ }
279
348
  }
280
- const gt = [
349
+ const mt = [
281
350
  // CSS-in-JS
282
351
  /^css-[a-z0-9]+$/i,
283
352
  /^sc-[a-z0-9]+-\d+$/i,
@@ -403,7 +472,7 @@ const gt = [
403
472
  /^clearfix$/,
404
473
  /^pull-(left|right)$/,
405
474
  /^float-(left|right|none)$/
406
- ], mt = [
475
+ ], bt = [
407
476
  // === Navigation ===
408
477
  /^(nav|menu|header|footer|sidebar|topbar|navbar|breadcrumb)/,
409
478
  /(navigation|dropdown|megamenu)$/,
@@ -430,41 +499,41 @@ const gt = [
430
499
  // === Status ===
431
500
  /^(loading|pending|complete|failed|draft|published)/
432
501
  ];
433
- function _(n) {
434
- return gt.some((t) => t.test(n));
502
+ function L(n) {
503
+ return mt.some((t) => t.test(n));
435
504
  }
436
- function q(n) {
505
+ function k(n) {
437
506
  return n.length <= 2 || /^\d/.test(n) ? !0 : pt.some((t) => t.test(n));
438
507
  }
439
- function bt(n) {
440
- return _(n) || q(n) ? !1 : mt.some((t) => t.test(n));
441
- }
442
508
  function St(n) {
443
- return !_(n) && !q(n);
444
- }
445
- function N(n) {
446
- return n.filter((t) => St(t));
509
+ return L(n) || k(n) ? !1 : bt.some((t) => t.test(n));
447
510
  }
448
511
  function yt(n) {
449
- if (_(n) || q(n))
512
+ return !L(n) && !k(n);
513
+ }
514
+ function M(n) {
515
+ return n.filter((t) => yt(t));
516
+ }
517
+ function At(n) {
518
+ if (L(n) || k(n))
450
519
  return 0;
451
520
  let t = 0.5;
452
- return bt(n) && (t = 0.8), n.length < 3 ? t *= 0.3 : n.length < 5 && (t *= 0.6), /\d/.test(n) && (t *= 0.7), Math.min(t, 1);
521
+ return St(n) && (t = 0.8), n.length < 3 ? t *= 0.3 : n.length < 5 && (t *= 0.6), /\d/.test(n) && (t *= 0.7), Math.min(t, 1);
453
522
  }
454
- function At(n) {
523
+ function xt(n) {
455
524
  const t = [], e = [];
456
525
  for (const s of n)
457
- q(s) || _(s) ? e.push(s) : t.push(s);
526
+ k(s) || L(s) ? e.push(s) : t.push(s);
458
527
  return { semantic: t, utility: e };
459
528
  }
460
529
  function J(n) {
461
- return q(n) || _(n);
530
+ return k(n) || L(n);
462
531
  }
463
- function ne(n) {
464
- return yt(n);
532
+ function ae(n) {
533
+ return At(n);
465
534
  }
466
535
  const tt = (n) => n.replace(/([#:.[\]@])/g, "\\$1");
467
- class xt {
536
+ class Ct {
468
537
  constructor(t, e) {
469
538
  this.maxDepth = t.maxPathDepth ?? 10, this.cache = e;
470
539
  }
@@ -474,31 +543,49 @@ class xt {
474
543
  * @param target - Target element (end)
475
544
  * @param extractor - Semantic extractor instance
476
545
  * @returns Path build result with nodes and degradation info
546
+ * @remarks
547
+ * Special handling for root elements:
548
+ * - If anchor is html and target is head/body: returns empty path
549
+ * - If anchor is html and target is inside head: builds path through head
477
550
  */
478
551
  buildPath(t, e, s) {
479
- const r = [];
480
- let a = e.parentElement;
481
- for (; a && a !== t && r.length < this.maxDepth; )
482
- r.unshift(a), a = a.parentElement;
483
- const i = r.length >= this.maxDepth && a !== t;
484
- let o = this.filterNoise(r);
485
- return o = this.ensureUniqueness(r, o, t, e, s), {
486
- path: o.map((u) => {
487
- const d = u.parentElement;
488
- let c;
489
- if (d) {
490
- const g = Array.from(d.children).indexOf(u);
491
- g !== -1 && (c = g + 1);
552
+ const r = t.tagName.toLowerCase(), a = e.tagName.toLowerCase();
553
+ if (r === "html" && (a === "head" || a === "body"))
554
+ return {
555
+ path: [],
556
+ degraded: !1
557
+ };
558
+ if (r === "html" && this.isInsideHead(e))
559
+ return this.buildHeadPath(t, e, s);
560
+ const i = [];
561
+ let o = e.parentElement;
562
+ for (; o && o !== t && i.length < this.maxDepth; )
563
+ i.unshift(o), o = o.parentElement;
564
+ const c = i.length >= this.maxDepth && o !== t;
565
+ if (!c && o !== t)
566
+ return console.warn("[PathBuilder] Target is not a descendant of anchor"), {
567
+ path: [],
568
+ degraded: !0,
569
+ degradationReason: "target-not-descendant-of-anchor"
570
+ };
571
+ let u = this.filterNoise(i);
572
+ return u = this.ensureUniqueness(i, u, t, e, s), {
573
+ path: u.map((l) => {
574
+ const h = l.parentElement;
575
+ let g;
576
+ if (h) {
577
+ const m = Array.from(h.children).indexOf(l);
578
+ m !== -1 && (g = m + 1);
492
579
  }
493
580
  return {
494
- tag: u.tagName.toLowerCase(),
495
- semantics: s.extract(u),
496
- score: s.scoreElement(u),
497
- nthChild: c
581
+ tag: l.tagName.toLowerCase(),
582
+ semantics: s.extract(l),
583
+ score: s.scoreElement(l),
584
+ nthChild: g
498
585
  };
499
586
  }),
500
- degraded: i,
501
- degradationReason: i ? "path-depth-overflow" : void 0
587
+ degraded: c,
588
+ degradationReason: c ? "path-depth-overflow" : void 0
502
589
  };
503
590
  }
504
591
  /**
@@ -516,29 +603,29 @@ class xt {
516
603
  try {
517
604
  const o = r.ownerDocument;
518
605
  if (!o) return e;
519
- let l;
606
+ let c;
520
607
  if (this.cache) {
521
608
  const d = this.cache.getSelectorResults(i);
522
- d !== void 0 ? l = d : (l = Array.from(o.querySelectorAll(i)), this.cache.setSelectorResults(i, l));
609
+ d !== void 0 ? c = d : (c = Array.from(o.querySelectorAll(i)), this.cache.setSelectorResults(i, c));
523
610
  } else
524
- l = o.querySelectorAll(i);
525
- if (l.length <= 1)
611
+ c = o.querySelectorAll(i);
612
+ if (c.length <= 1)
526
613
  return e;
527
614
  const u = t.filter((d) => !e.includes(d));
528
615
  for (const d of u) {
529
- if (a.scoreElement(d) < ct.MIN_CONFIDENCE_FOR_SKIP)
616
+ if (a.scoreElement(d) < lt.MIN_CONFIDENCE_FOR_SKIP)
530
617
  continue;
531
618
  const h = this.insertNodeInOrder(e, d, t), g = this.buildTestSelector(s, h, r);
532
619
  try {
533
620
  let f;
534
621
  if (this.cache) {
535
- const p = this.cache.getSelectorResults(g);
536
- p !== void 0 ? f = p : (f = Array.from(o.querySelectorAll(g)), this.cache.setSelectorResults(g, f));
622
+ const m = this.cache.getSelectorResults(g);
623
+ m !== void 0 ? f = m : (f = Array.from(o.querySelectorAll(g)), this.cache.setSelectorResults(g, f));
537
624
  } else
538
625
  f = o.querySelectorAll(g);
539
626
  if (f.length === 1)
540
627
  return h;
541
- f.length < l.length && (e = h);
628
+ f.length < c.length && (e = h);
542
629
  } catch {
543
630
  }
544
631
  }
@@ -588,7 +675,7 @@ class xt {
588
675
  */
589
676
  shouldInclude(t) {
590
677
  const e = t.tagName.toLowerCase();
591
- return lt.includes(e) ? !0 : e === "div" || e === "span" ? this.hasSemanticFeatures(t) : !1;
678
+ return ht.includes(e) ? !0 : e === "div" || e === "span" ? this.hasSemanticFeatures(t) : !1;
592
679
  }
593
680
  /**
594
681
  * Checks if element has meaningful semantic features
@@ -606,15 +693,76 @@ class xt {
606
693
  const e = t.id;
607
694
  return !!(e && !D(e));
608
695
  }
696
+ /**
697
+ * Checks if element is inside <head> section.
698
+ * Stops at <body> to avoid false positives.
699
+ * @param element - Element to check
700
+ * @returns True if element is inside head, false otherwise
701
+ * @remarks
702
+ * Traverses up the DOM tree until finding head or body.
703
+ * Returns false if body is encountered first.
704
+ */
705
+ isInsideHead(t) {
706
+ let e = t.parentElement;
707
+ for (; e; ) {
708
+ const s = e.tagName.toLowerCase();
709
+ if (s === "head") return !0;
710
+ if (s === "body") return !1;
711
+ e = e.parentElement;
712
+ }
713
+ return !1;
714
+ }
715
+ /**
716
+ * Builds path from html to target through head element.
717
+ * Always includes head in the path for correct CSS selector generation.
718
+ * @param htmlElement - The html element (anchor)
719
+ * @param target - Target element inside head
720
+ * @param extractor - Semantic extractor instance
721
+ * @returns Path build result with head and intermediate nodes
722
+ * @example
723
+ * For <html><head><meta name="description"></head></html>
724
+ * Returns path: [head]
725
+ */
726
+ buildHeadPath(t, e, s) {
727
+ const r = [];
728
+ let a = e.parentElement;
729
+ for (; a && a !== t; )
730
+ r.unshift(a), a = a.parentElement;
731
+ return a !== t ? {
732
+ path: [],
733
+ degraded: !0,
734
+ degradationReason: "target-not-descendant-of-html"
735
+ } : r.findIndex((c) => c.tagName.toLowerCase() === "head") === -1 ? {
736
+ path: [],
737
+ degraded: !0,
738
+ degradationReason: "head-not-found-in-path"
739
+ } : {
740
+ path: r.map((c) => {
741
+ const u = c.parentElement;
742
+ let d;
743
+ if (u) {
744
+ const h = Array.from(u.children).indexOf(c);
745
+ h !== -1 && (d = h + 1);
746
+ }
747
+ return {
748
+ tag: c.tagName.toLowerCase(),
749
+ semantics: s.extract(c),
750
+ score: s.scoreElement(c),
751
+ nthChild: d
752
+ };
753
+ }),
754
+ degraded: !1
755
+ };
756
+ }
609
757
  }
610
758
  function Q(n) {
611
759
  return n ? n.trim().replace(/[\n\t\r]/g, " ").replace(/\s+/g, " ") : "";
612
760
  }
613
- const Ct = {
761
+ const Tt = {
614
762
  preserveQueryForAbsolute: !0,
615
763
  removeDynamicHashes: !0
616
764
  };
617
- function Tt(n) {
765
+ function Et(n) {
618
766
  return n ? [
619
767
  /\d{5,}/,
620
768
  // 5+ digits
@@ -628,18 +776,18 @@ function Tt(n) {
628
776
  // UUID-like
629
777
  ].some((e) => e.test(n)) : !1;
630
778
  }
631
- function Et(n, t) {
779
+ function wt(n, t) {
632
780
  if (!n) return n;
633
781
  const e = n.startsWith("http://") || n.startsWith("https://"), [s, r] = n.split("#"), [a, i] = s.split("?");
634
782
  let o = a;
635
- return e && t.preserveQueryForAbsolute && i && (o += `?${i}`), r && (t.removeDynamicHashes && Tt(r) || (o += `#${r}`)), o;
783
+ return e && t.preserveQueryForAbsolute && i && (o += `?${i}`), r && (t.removeDynamicHashes && Et(r) || (o += `#${r}`)), o;
636
784
  }
637
- function k(n, t, e = {}) {
785
+ function q(n, t, e = {}) {
638
786
  if (!t) return t;
639
- const s = { ...Ct, ...e };
640
- return n === "href" || n === "src" ? Et(t, s) : t;
787
+ const s = { ...Tt, ...e };
788
+ return n === "href" || n === "src" ? wt(t, s) : t;
641
789
  }
642
- const wt = [
790
+ const vt = [
643
791
  "role",
644
792
  "aria-label",
645
793
  "aria-labelledby",
@@ -650,7 +798,7 @@ const wt = [
650
798
  "aria-posinset",
651
799
  "aria-setsize",
652
800
  "aria-haspopup"
653
- ], vt = [
801
+ ], $t = [
654
802
  "aria-selected",
655
803
  "aria-checked",
656
804
  "aria-pressed",
@@ -663,7 +811,7 @@ const wt = [
663
811
  "aria-grabbed",
664
812
  "aria-live",
665
813
  "aria-atomic"
666
- ], $t = [
814
+ ], It = [
667
815
  "data-state",
668
816
  "data-active",
669
817
  "data-inactive",
@@ -682,7 +830,7 @@ const wt = [
682
830
  "data-hover",
683
831
  "data-orientation",
684
832
  "data-theme"
685
- ], Mt = [
833
+ ], Nt = [
686
834
  "data-radix-",
687
835
  "data-headlessui-",
688
836
  "data-reach-",
@@ -690,7 +838,7 @@ const wt = [
690
838
  "data-chakra-",
691
839
  "data-mantine-",
692
840
  "data-tw-"
693
- ], It = [
841
+ ], Rt = [
694
842
  "data-testid",
695
843
  "data-test-id",
696
844
  "data-test",
@@ -702,7 +850,7 @@ const wt = [
702
850
  "data-entity-id",
703
851
  "data-product-id",
704
852
  "data-user-id"
705
- ], Rt = [
853
+ ], Mt = [
706
854
  "id",
707
855
  "name",
708
856
  "type",
@@ -711,7 +859,7 @@ const wt = [
711
859
  "for",
712
860
  "alt",
713
861
  "href"
714
- ], Nt = [
862
+ ], Dt = [
715
863
  "disabled",
716
864
  "checked",
717
865
  "selected",
@@ -719,17 +867,17 @@ const wt = [
719
867
  "readonly",
720
868
  "required",
721
869
  "value"
722
- ], Dt = [
870
+ ], Ht = [
723
871
  /^radix-/,
724
872
  /^headlessui-/,
725
873
  /^mui-/,
726
874
  /:\w+:/
727
875
  // matches :ru:, :r1:, etc.
728
876
  ];
729
- function Ht(n, t) {
730
- return wt.includes(n) ? !0 : vt.includes(n) || $t.includes(n) || Mt.some((e) => n.startsWith(e)) ? !1 : It.includes(n) || n.startsWith("data-") && n.endsWith("-id") ? !0 : n === "id" ? !Dt.some((e) => e.test(t)) : Rt.includes(n) ? !0 : Nt.includes(n) ? !1 : !!n.startsWith("data-");
877
+ function Pt(n, t) {
878
+ return vt.includes(n) ? !0 : $t.includes(n) || It.includes(n) || Nt.some((e) => n.startsWith(e)) ? !1 : Rt.includes(n) || n.startsWith("data-") && n.endsWith("-id") ? !0 : n === "id" ? !Ht.some((e) => e.test(t)) : Mt.includes(n) ? !0 : Dt.includes(n) ? !1 : !!n.startsWith("data-");
731
879
  }
732
- class Pt {
880
+ class et {
733
881
  constructor(t, e) {
734
882
  this.includeUtilityClasses = t.includeUtilityClasses ?? !1, this.cache = e;
735
883
  }
@@ -750,7 +898,7 @@ class Pt {
750
898
  if (this.includeUtilityClasses)
751
899
  e.classes = i;
752
900
  else {
753
- const { semantic: o } = At(i);
901
+ const { semantic: o } = xt(i);
754
902
  o.length > 0 && (e.classes = o);
755
903
  }
756
904
  }
@@ -787,7 +935,7 @@ class Pt {
787
935
  * @returns Priority number (higher = more priority)
788
936
  */
789
937
  getAttributePriority(t) {
790
- return w[t] !== void 0 ? w[t] : t.startsWith("data-") ? w["data-*"] : t.startsWith("aria-") ? w["aria-*"] : 0;
938
+ return E[t] !== void 0 ? E[t] : t.startsWith("data-") ? E["data-*"] : t.startsWith("aria-") ? E["aria-*"] : 0;
791
939
  }
792
940
  /**
793
941
  * Checks if attribute value is dynamic (should be ignored)
@@ -814,8 +962,8 @@ class Pt {
814
962
  const e = {};
815
963
  for (const s of Array.from(t.attributes)) {
816
964
  const r = s.name;
817
- if (this.shouldIgnoreAttribute(r) || !Ht(r, s.value) || G.has(r) && V(s.value) || this.getAttributePriority(r) === 0) continue;
818
- const i = r === "href" || r === "src" ? k(r, s.value) : s.value;
965
+ if (this.shouldIgnoreAttribute(r) || !Pt(r, s.value) || G.has(r) && V(s.value) || this.getAttributePriority(r) === 0) continue;
966
+ const i = r === "href" || r === "src" ? q(r, s.value) : s.value;
819
967
  !i || i.trim() === "" || this.isDynamicValue(i) || (e[r] = i);
820
968
  }
821
969
  return e;
@@ -874,7 +1022,7 @@ class Pt {
874
1022
  ].includes(e);
875
1023
  }
876
1024
  }
877
- class kt {
1025
+ class qt {
878
1026
  /**
879
1027
  * Generates fingerprint for SVG element
880
1028
  * @param element - SVG element to fingerprint
@@ -950,8 +1098,8 @@ class kt {
950
1098
  break;
951
1099
  case "line":
952
1100
  {
953
- const r = parseFloat(t.getAttribute("x1") ?? "0"), a = parseFloat(t.getAttribute("y1") ?? "0"), i = parseFloat(t.getAttribute("x2") ?? "0"), o = parseFloat(t.getAttribute("y2") ?? "0"), l = Math.atan2(o - a, i - r);
954
- s.push(`angle=${l.toFixed(2)}`);
1101
+ const r = parseFloat(t.getAttribute("x1") ?? "0"), a = parseFloat(t.getAttribute("y1") ?? "0"), i = parseFloat(t.getAttribute("x2") ?? "0"), o = parseFloat(t.getAttribute("y2") ?? "0"), c = Math.atan2(o - a, i - r);
1102
+ s.push(`angle=${c.toFixed(2)}`);
955
1103
  }
956
1104
  break;
957
1105
  }
@@ -985,15 +1133,15 @@ class kt {
985
1133
  return Math.abs(e).toString(16).padStart(8, "0");
986
1134
  }
987
1135
  }
988
- function _t(n, t = 0) {
989
- const e = n.anchor.score, s = n.path.length > 0 ? n.path.reduce((o, l) => o + l.score, 0) / n.path.length : 0.5, r = n.target.score, a = e * L.ANCHOR + s * L.PATH + r * L.TARGET + t * L.UNIQUENESS, i = n.anchor.degraded ? 0.2 : 0;
1136
+ function Lt(n, t = 0) {
1137
+ const e = n.anchor.score, s = n.path.length > 0 ? n.path.reduce((o, c) => o + c.score, 0) / n.path.length : 0.5, r = n.target.score, a = e * _.ANCHOR + s * _.PATH + r * _.TARGET + t * _.UNIQUENESS, i = n.anchor.degraded ? 0.2 : 0;
990
1138
  return Math.max(0, Math.min(1, a - i));
991
1139
  }
992
- function ae(n, t, e) {
1140
+ function ie(n, t, e) {
993
1141
  let s = 0.5;
994
1142
  return t && (s += 0.2), e && (s += 0.15), s += Math.min(n * 0.05, 0.15), Math.min(s, 1);
995
1143
  }
996
- class qt {
1144
+ class kt {
997
1145
  constructor(t) {
998
1146
  this.cache = /* @__PURE__ */ new Map(), this.maxSize = t;
999
1147
  }
@@ -1024,9 +1172,9 @@ class qt {
1024
1172
  return this.cache.size;
1025
1173
  }
1026
1174
  }
1027
- class Lt {
1175
+ class _t {
1028
1176
  constructor(t = {}) {
1029
- this.eidCache = /* @__PURE__ */ new WeakMap(), this.selectorResultCache = new qt(
1177
+ this.eidCache = /* @__PURE__ */ new WeakMap(), this.selectorResultCache = new kt(
1030
1178
  t.maxSelectorCacheSize ?? 1e3
1031
1179
  ), this.anchorCache = /* @__PURE__ */ new WeakMap(), this.semanticsCache = /* @__PURE__ */ new WeakMap(), this.stats = {
1032
1180
  eidHits: 0,
@@ -1176,78 +1324,82 @@ class Lt {
1176
1324
  }
1177
1325
  }
1178
1326
  function Ot(n) {
1179
- return new Lt(n);
1327
+ return new _t(n);
1180
1328
  }
1181
1329
  let O = null;
1182
1330
  function Z() {
1183
1331
  return O || (O = Ot()), O;
1184
1332
  }
1185
- function ie() {
1333
+ function oe() {
1186
1334
  O = null;
1187
1335
  }
1188
1336
  function Y(n, t = {}) {
1189
1337
  if (!n || !n.ownerDocument || !n.isConnected)
1190
1338
  return null;
1191
- const e = { ...ut, ...t }, s = e.cache ?? Z(), r = s.getEID(n);
1339
+ const e = { ...dt, ...t }, s = e.cache ?? Z(), r = s.getEID(n);
1192
1340
  if (r !== void 0)
1193
1341
  return r;
1194
- const a = new ft(e, s), i = new xt(e, s), o = new Pt(e, s), l = new kt(), u = a.findAnchor(n);
1195
- if (!u && !e.fallbackToBody)
1342
+ if (n.tagName.toLowerCase() === "html") {
1343
+ const v = new et(e, s), A = Ft(n, e, v);
1344
+ return s.setEID(n, A), A;
1345
+ }
1346
+ const i = new gt(e, s), o = new Ct(e, s), c = new et(e, s), u = new qt(), d = i.findAnchor(n);
1347
+ if (!d && !e.fallbackToBody)
1196
1348
  return null;
1197
- const d = u?.element ?? n.ownerDocument?.body ?? null;
1198
- if (!d) return null;
1199
- const c = !u || u.tier === "C", h = d.tagName.toLowerCase(), g = d.parentElement;
1200
- let f;
1201
- if (g && h !== "body" && h !== "html") {
1202
- const T = Array.from(g.children).indexOf(d);
1203
- T !== -1 && (f = T + 1);
1204
- }
1205
- const p = o.extract(d), m = {
1206
- tag: d.tagName.toLowerCase(),
1349
+ const l = d?.element ?? n.ownerDocument?.body ?? null;
1350
+ if (!l) return null;
1351
+ const h = !d || d.tier === "C", g = l.tagName.toLowerCase(), f = l.parentElement;
1352
+ let m;
1353
+ if (f && g !== "body" && g !== "html") {
1354
+ const A = Array.from(f.children).indexOf(l);
1355
+ A !== -1 && (m = A + 1);
1356
+ }
1357
+ const p = c.extract(l), S = {
1358
+ tag: l.tagName.toLowerCase(),
1207
1359
  semantics: p,
1208
- score: u?.score ?? I.DEGRADED_SCORE,
1209
- degraded: c,
1210
- nthChild: f
1211
- }, b = i.buildPath(d, n, o), y = o.extract(n);
1212
- e.enableSvgFingerprint && zt(n) && (y.svg = l.fingerprint(n));
1213
- const v = n.parentElement;
1214
- let A;
1215
- if (v) {
1216
- const T = Array.from(v.children).indexOf(n);
1217
- T !== -1 && (A = T + 1);
1218
- }
1219
- const S = {
1360
+ score: d?.score ?? N.DEGRADED_SCORE,
1361
+ degraded: h,
1362
+ nthChild: m
1363
+ }, y = o.buildPath(l, n, c), w = c.extract(n);
1364
+ e.enableSvgFingerprint && Ut(n) && (w.svg = u.fingerprint(n));
1365
+ const x = n.parentElement;
1366
+ let b;
1367
+ if (x) {
1368
+ const A = Array.from(x.children).indexOf(n);
1369
+ A !== -1 && (b = A + 1);
1370
+ }
1371
+ const $ = {
1220
1372
  tag: n.tagName.toLowerCase(),
1221
- semantics: y,
1222
- score: o.scoreElement(n),
1223
- nthChild: A
1224
- }, $ = [], M = {
1373
+ semantics: w,
1374
+ score: c.scoreElement(n),
1375
+ nthChild: b
1376
+ }, I = [], H = {
1225
1377
  onMultiple: "best-score",
1226
1378
  onMissing: "anchor-only",
1227
1379
  maxDepth: 3
1228
- }, H = m.degraded || b.degraded, E = Ut(m.degraded, b), x = {
1380
+ }, T = S.degraded || y.degraded, R = zt(S.degraded, y), C = {
1229
1381
  version: "1.0",
1230
- anchor: m,
1231
- path: b.path,
1232
- target: S,
1233
- constraints: $,
1234
- fallback: M,
1382
+ anchor: S,
1383
+ path: y.path,
1384
+ target: $,
1385
+ constraints: I,
1386
+ fallback: H,
1235
1387
  meta: {
1236
1388
  confidence: 0,
1237
1389
  // Calculated below
1238
1390
  generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
1239
1391
  generator: "dom-eid@1.0",
1240
1392
  source: e.source,
1241
- degraded: H,
1242
- degradationReason: E
1393
+ degraded: T,
1394
+ degradationReason: R
1243
1395
  }
1244
1396
  };
1245
- return x.meta.confidence = _t(x), x.meta.confidence < e.confidenceThreshold ? null : (s.setEID(n, x), x);
1397
+ return C.meta.confidence = Lt(C), C.meta.confidence < e.confidenceThreshold ? null : (s.setEID(n, C), C);
1246
1398
  }
1247
- function zt(n) {
1399
+ function Ut(n) {
1248
1400
  return n.namespaceURI === "http://www.w3.org/2000/svg" || n.tagName.toLowerCase() === "svg" || n instanceof SVGElement;
1249
1401
  }
1250
- function Ut(n, t) {
1402
+ function zt(n, t) {
1251
1403
  if (n && t.degraded)
1252
1404
  return "anchor-and-path-degraded";
1253
1405
  if (n)
@@ -1255,22 +1407,71 @@ function Ut(n, t) {
1255
1407
  if (t.degraded)
1256
1408
  return t.degradationReason;
1257
1409
  }
1258
- class st {
1410
+ function Ft(n, t, e, s) {
1411
+ const a = {
1412
+ tag: "html",
1413
+ semantics: e.extract(n),
1414
+ score: 1,
1415
+ degraded: !1,
1416
+ nthChild: void 0
1417
+ };
1418
+ return {
1419
+ version: "1.0",
1420
+ anchor: a,
1421
+ path: [],
1422
+ target: a,
1423
+ constraints: [],
1424
+ fallback: {
1425
+ onMultiple: "best-score",
1426
+ onMissing: "anchor-only",
1427
+ maxDepth: 3
1428
+ },
1429
+ meta: {
1430
+ confidence: 1,
1431
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
1432
+ generator: "dom-eid@1.0",
1433
+ source: t.source,
1434
+ degraded: !1,
1435
+ degradationReason: void 0
1436
+ }
1437
+ };
1438
+ }
1439
+ class rt {
1259
1440
  buildSelector(t, e) {
1441
+ if (t.target.tag === "html") {
1442
+ const l = "html";
1443
+ return e?.ensureUnique ? {
1444
+ selector: l,
1445
+ isUnique: !0,
1446
+ usedNthOfType: !1,
1447
+ extraClassesAdded: 0
1448
+ } : l;
1449
+ }
1450
+ if (t.anchor.tag === "html" && t.path.length === 0) {
1451
+ const h = `html > ${this.buildNodeSelector(t.target.tag, t.target.semantics)}`;
1452
+ return e?.ensureUnique ? {
1453
+ selector: h,
1454
+ isUnique: this.isUnique(h, e.root ?? document),
1455
+ usedNthOfType: !1,
1456
+ extraClassesAdded: 0
1457
+ } : h;
1458
+ }
1459
+ if (t.anchor.tag === "html" && t.path.length > 0 && t.path[0].tag === "head")
1460
+ return this.buildHeadSelector(t, e);
1260
1461
  if (t.path.length === 0 && t.anchor.tag === t.target.tag && JSON.stringify(t.anchor.semantics) === JSON.stringify(t.target.semantics)) {
1261
- const c = this.buildNodeSelector(
1462
+ const l = this.buildNodeSelector(
1262
1463
  t.target.tag,
1263
1464
  t.target.semantics,
1264
1465
  { excludeClasses: !1 }
1265
1466
  // Include classes for same-element case
1266
1467
  );
1267
- return e?.ensureUnique ? this.ensureUniqueSelector(c, t, e) : c;
1468
+ return e?.ensureUnique ? this.ensureUniqueSelector(l, t, e) : l;
1268
1469
  }
1269
1470
  const r = [], a = e?.ensureUnique ? this.ensureUniqueAnchor(t, e.root ?? document) : this.buildNodeSelector(t.anchor.tag, t.anchor.semantics);
1270
1471
  r.push(a);
1271
- for (const c of t.path) {
1272
- let h = this.buildNodeSelector(c.tag, c.semantics);
1273
- c.nthChild !== void 0 && (["tr", "td", "th", "thead", "tbody", "tfoot"].includes(c.tag) ? h += `:nth-child(${c.nthChild})` : h += `:nth-child(${c.nthChild})`), r.push(h);
1472
+ for (const l of t.path) {
1473
+ let h = this.buildNodeSelector(l.tag, l.semantics);
1474
+ l.nthChild !== void 0 && (["tr", "td", "th", "thead", "tbody", "tfoot"].includes(l.tag) ? h += `:nth-child(${l.nthChild})` : h += `:nth-child(${l.nthChild})`), r.push(h);
1274
1475
  }
1275
1476
  let i = this.buildNodeSelector(
1276
1477
  t.target.tag,
@@ -1279,13 +1480,13 @@ class st {
1279
1480
  // Exclude classes initially if we need unique
1280
1481
  );
1281
1482
  t.target.nthChild !== void 0 && (["tr", "td", "th", "thead", "tbody", "tfoot"].includes(t.target.tag) ? i += `:nth-child(${t.target.nthChild})` : i += `:nth-child(${t.target.nthChild})`), r.push(i);
1282
- const o = this.isSvgChildElement(t.target.tag), l = t.path.some((c) => c.tag === "svg");
1483
+ const o = this.isSvgChildElement(t.target.tag), c = t.path.some((l) => l.tag === "svg");
1283
1484
  let u;
1284
- if (o && l) {
1285
- const c = t.path.findIndex((h) => h.tag === "svg");
1286
- if (c !== -1) {
1287
- const h = c + 1, g = r.slice(0, h + 1), f = r.slice(h + 1, -1), p = r[r.length - 1];
1288
- f.length > 0 ? u = g.join(" ") + " > " + f.join(" > ") + " > " + p : u = g.join(" ") + " > " + p;
1485
+ if (o && c) {
1486
+ const l = t.path.findIndex((h) => h.tag === "svg");
1487
+ if (l !== -1) {
1488
+ const h = l + 1, g = r.slice(0, h + 1), f = r.slice(h + 1, -1), m = r[r.length - 1];
1489
+ f.length > 0 ? u = g.join(" ") + " > " + f.join(" > ") + " > " + m : u = g.join(" ") + " > " + m;
1289
1490
  } else
1290
1491
  u = r.join(" ");
1291
1492
  } else
@@ -1301,16 +1502,16 @@ class st {
1301
1502
  extraClassesAdded: 0
1302
1503
  };
1303
1504
  if (d.length === 0 || d.length > 1) {
1304
- const c = this.buildFullDomPathSelector(
1505
+ const l = this.buildFullDomPathSelector(
1305
1506
  t,
1306
1507
  t.target.semantics,
1307
1508
  e.root ?? document
1308
1509
  );
1309
- if (c && this.isUnique(c, e.root ?? document))
1510
+ if (l && this.isUnique(l, e.root ?? document))
1310
1511
  return {
1311
- selector: c,
1512
+ selector: l,
1312
1513
  isUnique: !0,
1313
- usedNthOfType: c.includes(":nth-"),
1514
+ usedNthOfType: l.includes(":nth-"),
1314
1515
  extraClassesAdded: 0
1315
1516
  };
1316
1517
  }
@@ -1329,36 +1530,36 @@ class st {
1329
1530
  */
1330
1531
  ensureUniqueSelector(t, e, s) {
1331
1532
  const r = s.root ?? document, a = s.maxClasses ?? 4, i = e.target.tag, o = e.target.semantics;
1332
- let l = t, u = 0, d = !1;
1333
- if (this.querySelectorSafe(l, r).length === 0) {
1533
+ let c = t, u = 0, d = !1;
1534
+ if (this.querySelectorSafe(c, r).length === 0) {
1334
1535
  const f = this.buildFullDomPathSelector(e, o, r);
1335
- if (f && (l = f, this.isUnique(l, r)))
1536
+ if (f && (c = f, this.isUnique(c, r)))
1336
1537
  return {
1337
- selector: l,
1538
+ selector: c,
1338
1539
  isUnique: !0,
1339
1540
  usedNthOfType: !1,
1340
1541
  extraClassesAdded: 0
1341
1542
  };
1342
1543
  }
1343
- if (this.isUnique(l, r))
1544
+ if (this.isUnique(c, r))
1344
1545
  return {
1345
- selector: l,
1546
+ selector: c,
1346
1547
  isUnique: !0,
1347
1548
  usedNthOfType: !1,
1348
1549
  extraClassesAdded: 0
1349
1550
  };
1350
- const h = N(o.classes ?? []);
1551
+ const h = M(o.classes ?? []);
1351
1552
  for (let f = 0; f < Math.min(h.length, a); f++) {
1352
- const p = h[f];
1353
- if (l += `.${this.escapeCSS(p)}`, u++, this.isUnique(l, r))
1553
+ const m = h[f];
1554
+ if (c += `.${this.escapeCSS(m)}`, u++, this.isUnique(c, r))
1354
1555
  return {
1355
- selector: l,
1556
+ selector: c,
1356
1557
  isUnique: !0,
1357
1558
  usedNthOfType: !1,
1358
1559
  extraClassesAdded: u
1359
1560
  };
1360
1561
  }
1361
- if (!this.isUnique(l, r)) {
1562
+ if (!this.isUnique(c, r)) {
1362
1563
  const f = this.buildFullDomPathSelector(e, o, r);
1363
1564
  if (f && this.isUnique(f, r))
1364
1565
  return {
@@ -1368,10 +1569,10 @@ class st {
1368
1569
  extraClassesAdded: u
1369
1570
  };
1370
1571
  }
1371
- const g = this.findNthElementByText(l, o, r);
1372
- return g && (l += this.getNthSelector(g, i), d = !0), {
1373
- selector: l,
1374
- isUnique: this.isUnique(l, r),
1572
+ const g = this.findNthElementByText(c, o, r);
1573
+ return g && (c += this.getNthSelector(g, i), d = !0), {
1574
+ selector: c,
1575
+ isUnique: this.isUnique(c, r),
1375
1576
  usedNthOfType: d,
1376
1577
  extraClassesAdded: u
1377
1578
  };
@@ -1386,12 +1587,12 @@ class st {
1386
1587
  for (const i of a) {
1387
1588
  const o = this.findTargetWithinAnchor(i, t.target.tag, e);
1388
1589
  if (o.length === 0) continue;
1389
- const l = o.map((u) => {
1590
+ const c = o.map((u) => {
1390
1591
  const d = this.scorePathMatch(u, i, t.path);
1391
1592
  return { element: u, score: d };
1392
1593
  });
1393
- l.sort((u, d) => d.score - u.score);
1394
- for (const { element: u } of l) {
1594
+ c.sort((u, d) => d.score - u.score);
1595
+ for (const { element: u } of c) {
1395
1596
  const d = this.buildPathFromAnchorToTarget(i, u, t, s);
1396
1597
  if (d && this.isUnique(d, s))
1397
1598
  return d;
@@ -1415,29 +1616,29 @@ class st {
1415
1616
  let i = 0;
1416
1617
  const o = Math.min(r.length, s.length);
1417
1618
  for (let u = 0; u < o; u++) {
1418
- const d = r[u], c = s[u];
1419
- if (d.tagName.toLowerCase() === c.tag) {
1420
- if (i += 10, c.nthChild !== void 0) {
1619
+ const d = r[u], l = s[u];
1620
+ if (d.tagName.toLowerCase() === l.tag) {
1621
+ if (i += 10, l.nthChild !== void 0) {
1421
1622
  const h = d.parentElement;
1422
- h && (Array.from(h.children).indexOf(d) + 1 === c.nthChild ? i += 20 : i -= 10);
1623
+ h && (Array.from(h.children).indexOf(d) + 1 === l.nthChild ? i += 20 : i -= 10);
1423
1624
  }
1424
1625
  } else
1425
1626
  i -= 5;
1426
- if (c.semantics.classes && c.semantics.classes.length > 0) {
1427
- const h = c.semantics.classes.filter(
1627
+ if (l.semantics.classes && l.semantics.classes.length > 0) {
1628
+ const h = l.semantics.classes.filter(
1428
1629
  (g) => d.classList.contains(g)
1429
1630
  );
1430
1631
  i += h.length * 2;
1431
1632
  }
1432
- if (c.semantics.attributes) {
1433
- const h = Object.entries(c.semantics.attributes).filter(
1633
+ if (l.semantics.attributes) {
1634
+ const h = Object.entries(l.semantics.attributes).filter(
1434
1635
  ([g, f]) => d.getAttribute(g) === f
1435
1636
  );
1436
1637
  i += h.length * 3;
1437
1638
  }
1438
1639
  }
1439
- const l = Math.abs(r.length - s.length);
1440
- return i -= l * 2, i;
1640
+ const c = Math.abs(r.length - s.length);
1641
+ return i -= c * 2, i;
1441
1642
  }
1442
1643
  /**
1443
1644
  * Finds target elements within an anchor by matching semantics
@@ -1449,9 +1650,9 @@ class st {
1449
1650
  if (!i.includes(o) && !o.includes(i))
1450
1651
  return !1;
1451
1652
  }
1452
- return !!(s.classes && s.classes.length > 0 && s.classes.every((o) => a.classList.contains(o)) || s.attributes && Object.entries(s.attributes).every(([o, l]) => {
1653
+ return !!(s.classes && s.classes.length > 0 && s.classes.every((o) => a.classList.contains(o)) || s.attributes && Object.entries(s.attributes).every(([o, c]) => {
1453
1654
  const u = a.getAttribute(o);
1454
- return o === "href" || o === "src" ? k(o, u || "") === k(o, l) : u === l;
1655
+ return o === "href" || o === "src" ? q(o, u || "") === q(o, c) : u === c;
1455
1656
  }) || s.text);
1456
1657
  });
1457
1658
  }
@@ -1469,20 +1670,20 @@ class st {
1469
1670
  if (s?.semantics?.attributes) {
1470
1671
  const o = this.buildNodeSelector(e, s.semantics, {
1471
1672
  excludeClasses: !0
1472
- }), l = [...r, e].join(" > "), u = this.querySelectorSafe(l, a), d = [...r, o].join(" > "), c = this.querySelectorSafe(d, a);
1473
- if (c.length > 0 && c.length < u.length)
1673
+ }), c = [...r, e].join(" > "), u = this.querySelectorSafe(c, a), d = [...r, o].join(" > "), l = this.querySelectorSafe(d, a);
1674
+ if (l.length > 0 && l.length < u.length)
1474
1675
  return o;
1475
1676
  }
1476
1677
  if (s?.semantics?.classes) {
1477
- const o = N(s.semantics.classes);
1678
+ const o = M(s.semantics.classes);
1478
1679
  if (o.length > 0) {
1479
- const l = `${e}.${this.escapeCSS(o[0])}`, u = [...r, e].join(" > "), d = this.querySelectorSafe(u, a), c = [...r, l].join(" > "), h = this.querySelectorSafe(c, a);
1680
+ const c = `${e}.${this.escapeCSS(o[0])}`, u = [...r, e].join(" > "), d = this.querySelectorSafe(u, a), l = [...r, c].join(" > "), h = this.querySelectorSafe(l, a);
1480
1681
  if (h.length > 0 && h.length < d.length)
1481
- return l;
1682
+ return c;
1482
1683
  }
1483
1684
  }
1484
1685
  const i = t.parentElement;
1485
- return i && Array.from(i.children).filter((l) => l.tagName.toLowerCase() === e).length > 1 ? `${e}${this.getNthSelector(t, e)}` : e;
1686
+ return i && Array.from(i.children).filter((c) => c.tagName.toLowerCase() === e).length > 1 ? `${e}${this.getNthSelector(t, e)}` : e;
1486
1687
  }
1487
1688
  /**
1488
1689
  * Builds CSS selector path from anchor to target by traversing actual DOM
@@ -1500,21 +1701,21 @@ class st {
1500
1701
  // Most flexible - no classes on target, only semantic attributes
1501
1702
  // ============================================================
1502
1703
  () => {
1503
- const l = this.buildNodeSelector(s.anchor.tag, s.anchor.semantics), u = s.target.tag, d = s.target.semantics, c = [];
1504
- for (const m of s.path)
1505
- c.push(m.tag);
1506
- const g = [l, ...c, u].filter(Boolean).join(" ");
1704
+ const c = this.buildNodeSelector(s.anchor.tag, s.anchor.semantics), u = s.target.tag, d = s.target.semantics, l = [];
1705
+ for (const p of s.path)
1706
+ l.push(p.tag);
1707
+ const g = [c, ...l, u].filter(Boolean).join(" ");
1507
1708
  if (this.isUnique(g, r))
1508
1709
  return g;
1509
1710
  const f = this.buildNodeSelector(u, d, {
1510
1711
  excludeClasses: !0
1511
1712
  // KEY: no classes on target in Strategy 0
1512
- }), p = [
1513
- l,
1514
- ...c.slice(0, -1),
1713
+ }), m = [
1714
+ c,
1715
+ ...l.slice(0, -1),
1515
1716
  f
1516
1717
  ].join(" ");
1517
- return this.isUnique(p, r) ? p : null;
1718
+ return this.isUnique(m, r) ? m : null;
1518
1719
  },
1519
1720
  // ============================================================
1520
1721
  // Strategy 1: anchor > parent[attrs|class|nth] > target[attrs_only]
@@ -1523,7 +1724,7 @@ class st {
1523
1724
  // Target: ONLY attributes, NO classes
1524
1725
  // ============================================================
1525
1726
  () => {
1526
- const l = [this.buildNodeSelector(s.anchor.tag, s.anchor.semantics)], u = /* @__PURE__ */ new Map();
1727
+ const c = [this.buildNodeSelector(s.anchor.tag, s.anchor.semantics)], u = /* @__PURE__ */ new Map();
1527
1728
  let d = 0;
1528
1729
  for (let h = 0; h < a.length - 1; h++) {
1529
1730
  const g = a[h], f = g.tagName.toLowerCase();
@@ -1532,22 +1733,22 @@ class st {
1532
1733
  for (let h = 0; h < a.length; h++) {
1533
1734
  const g = a[h], f = g.tagName.toLowerCase();
1534
1735
  if (h < a.length - 1) {
1535
- const b = u.get(g) || null, y = this.disambiguateParent(g, f, b, l, r);
1536
- l.push(y);
1736
+ const S = u.get(g) || null, y = this.disambiguateParent(g, f, S, c, r);
1737
+ c.push(y);
1537
1738
  continue;
1538
1739
  }
1539
- const p = this.buildNodeSelector(
1740
+ const m = this.buildNodeSelector(
1540
1741
  s.target.tag,
1541
1742
  s.target.semantics,
1542
1743
  { excludeClasses: !0 }
1543
1744
  // KEY: no classes on target
1544
- ), m = g.parentElement;
1545
- m && ["td", "th", "tr", "thead", "tbody", "tfoot"].includes(f) && Array.from(m.children).filter(
1745
+ ), p = g.parentElement;
1746
+ p && ["td", "th", "tr", "thead", "tbody", "tfoot"].includes(f) && Array.from(p.children).filter(
1546
1747
  (y) => y.tagName.toLowerCase() === f
1547
- ).length > 1 ? l.push(`${p}${this.getNthSelector(g, f)}`) : l.push(p);
1748
+ ).length > 1 ? c.push(`${m}${this.getNthSelector(g, f)}`) : c.push(m);
1548
1749
  }
1549
- const c = l.join(" > ");
1550
- return this.isUnique(c, r) ? c : null;
1750
+ const l = c.join(" > ");
1751
+ return this.isUnique(l, r) ? l : null;
1551
1752
  },
1552
1753
  // ============================================================
1553
1754
  // Strategy 2: anchor parent[attrs|class|nth] target[attrs_only]
@@ -1558,30 +1759,30 @@ class st {
1558
1759
  () => {
1559
1760
  const u = [this.buildNodeSelector(s.anchor.tag, s.anchor.semantics)];
1560
1761
  for (let h = 0; h < a.length - 1; h++) {
1561
- const f = a[h].tagName.toLowerCase(), p = s.path[h] || null, m = u.join(" ") + " " + f;
1562
- if (this.querySelectorSafe(m, r).length > 1) {
1563
- if (p?.semantics?.attributes) {
1564
- const A = this.buildNodeSelector(f, p.semantics, {
1762
+ const f = a[h].tagName.toLowerCase(), m = s.path[h] || null, p = u.join(" ") + " " + f;
1763
+ if (this.querySelectorSafe(p, r).length > 1) {
1764
+ if (m?.semantics?.attributes) {
1765
+ const x = this.buildNodeSelector(f, m.semantics, {
1565
1766
  excludeClasses: !0
1566
- }), S = u.join(" ") + " " + A;
1567
- if (this.querySelectorSafe(S, r).length === 1 || this.querySelectorSafe(S + " " + s.target.tag, r).length === 1) {
1568
- u.push(A);
1767
+ }), b = u.join(" ") + " " + x;
1768
+ if (this.querySelectorSafe(b, r).length === 1 || this.querySelectorSafe(b + " " + s.target.tag, r).length === 1) {
1769
+ u.push(x);
1569
1770
  continue;
1570
1771
  }
1571
1772
  }
1572
- if (p?.semantics?.classes) {
1573
- const A = N(p.semantics.classes);
1574
- if (A.length > 0) {
1575
- const S = `${f}.${this.escapeCSS(A[0])}`, $ = u.join(" ") + " " + S;
1773
+ if (m?.semantics?.classes) {
1774
+ const x = M(m.semantics.classes);
1775
+ if (x.length > 0) {
1776
+ const b = `${f}.${this.escapeCSS(x[0])}`, $ = u.join(" ") + " " + b;
1576
1777
  if (this.querySelectorSafe($, r).length === 1 || this.querySelectorSafe($ + " " + s.target.tag, r).length === 1) {
1577
- u.push(S);
1778
+ u.push(b);
1578
1779
  continue;
1579
1780
  }
1580
1781
  }
1581
1782
  }
1582
- const y = a[h], v = y.parentElement;
1583
- if (v && Array.from(v.children).filter(
1584
- (S) => S.tagName.toLowerCase() === f
1783
+ const y = a[h], w = y.parentElement;
1784
+ if (w && Array.from(w.children).filter(
1785
+ (b) => b.tagName.toLowerCase() === f
1585
1786
  ).length > 1) {
1586
1787
  u.push(`${f}${this.getNthSelector(y, f)}`);
1587
1788
  continue;
@@ -1596,8 +1797,8 @@ class st {
1596
1797
  // KEY: no classes on target
1597
1798
  );
1598
1799
  u.push(d);
1599
- const c = u.join(" ");
1600
- return this.isUnique(c, r) ? c : null;
1800
+ const l = u.join(" ");
1801
+ return this.isUnique(l, r) ? l : null;
1601
1802
  },
1602
1803
  // ============================================================
1603
1804
  // Strategy 3: anchor path target[attrs + 1_stable_class]
@@ -1605,17 +1806,17 @@ class st {
1605
1806
  // Only use this if attrs alone are not sufficient
1606
1807
  // ============================================================
1607
1808
  () => {
1608
- const l = this.buildNodeSelector(s.anchor.tag, s.anchor.semantics), u = [];
1809
+ const c = this.buildNodeSelector(s.anchor.tag, s.anchor.semantics), u = [];
1609
1810
  for (const g of s.path)
1610
1811
  u.push(g.tag);
1611
- if (N(s.target.semantics.classes ?? []).length === 0)
1812
+ if (M(s.target.semantics.classes ?? []).length === 0)
1612
1813
  return null;
1613
- const c = this.buildNodeSelector(
1814
+ const l = this.buildNodeSelector(
1614
1815
  s.target.tag,
1615
1816
  s.target.semantics,
1616
1817
  { maxClasses: 1 }
1617
1818
  // KEY: ONE stable class only
1618
- ), h = [l, ...u.slice(0, -1), c].join(" ");
1819
+ ), h = [c, ...u.slice(0, -1), l].join(" ");
1619
1820
  return this.isUnique(h, r) ? h : null;
1620
1821
  },
1621
1822
  // ============================================================
@@ -1624,24 +1825,24 @@ class st {
1624
1825
  // Only use when all other strategies fail
1625
1826
  // ============================================================
1626
1827
  () => {
1627
- const l = this.buildNodeSelector(s.anchor.tag, s.anchor.semantics), u = [];
1628
- for (const p of s.path)
1629
- u.push(p.tag);
1630
- const d = a[a.length - 1], c = d.parentElement;
1631
- if (!c || Array.from(c.children).filter(
1632
- (p) => p.tagName.toLowerCase() === s.target.tag
1828
+ const c = this.buildNodeSelector(s.anchor.tag, s.anchor.semantics), u = [];
1829
+ for (const m of s.path)
1830
+ u.push(m.tag);
1831
+ const d = a[a.length - 1], l = d.parentElement;
1832
+ if (!l || Array.from(l.children).filter(
1833
+ (m) => m.tagName.toLowerCase() === s.target.tag
1633
1834
  ).length <= 1) return null;
1634
1835
  const g = this.buildNodeSelector(
1635
1836
  s.target.tag,
1636
1837
  s.target.semantics,
1637
1838
  { excludeClasses: !0 }
1638
1839
  // No classes, just attrs + nth
1639
- ) + this.getNthSelector(d, s.target.tag), f = [l, ...u.slice(0, -1), g].join(" ");
1840
+ ) + this.getNthSelector(d, s.target.tag), f = [c, ...u.slice(0, -1), g].join(" ");
1640
1841
  return this.isUnique(f, r) ? f : null;
1641
1842
  }
1642
1843
  ];
1643
- for (const l of o) {
1644
- const u = l();
1844
+ for (const c of o) {
1845
+ const u = c();
1645
1846
  if (u) return u;
1646
1847
  }
1647
1848
  return null;
@@ -1656,7 +1857,7 @@ class st {
1656
1857
  let s = e;
1657
1858
  if (t.id && !D(t.id))
1658
1859
  return `${e}#${this.escapeCSS(t.id)}`;
1659
- const r = Array.from(t.classList), a = N(r);
1860
+ const r = Array.from(t.classList), a = M(r);
1660
1861
  a.length > 0 && (s += a.slice(0, 2).map((o) => `.${this.escapeCSS(o)}`).join(""));
1661
1862
  const i = t.getAttribute("role");
1662
1863
  return i && (s += `[role="${this.escapeAttr(i)}"]`), s;
@@ -1719,7 +1920,7 @@ class st {
1719
1920
  if (this.isUnique(s, e))
1720
1921
  return s;
1721
1922
  if (r.classes && r.classes.length > 0) {
1722
- const i = N(r.classes);
1923
+ const i = M(r.classes);
1723
1924
  if (i.length > 0) {
1724
1925
  const o = `${s}.${this.escapeCSS(i[0])}`;
1725
1926
  if (this.isUnique(o, e))
@@ -1728,8 +1929,8 @@ class st {
1728
1929
  }
1729
1930
  if (r.attributes) {
1730
1931
  const i = this.getSortedAttributes(r.attributes);
1731
- for (const { name: o, value: l } of i) {
1732
- const u = o === "href" || o === "src" ? k(o, l) : l;
1932
+ for (const { name: o, value: c } of i) {
1933
+ const u = o === "href" || o === "src" ? q(o, c) : c;
1733
1934
  if (u) {
1734
1935
  const d = `${s}[${o}="${this.escapeAttr(u)}"]`;
1735
1936
  if (this.isUnique(d, e))
@@ -1785,7 +1986,7 @@ class st {
1785
1986
  const s = t.parentElement;
1786
1987
  if (!s) return "";
1787
1988
  const r = Array.from(s.children), a = r.indexOf(t) + 1;
1788
- return ["tr", "td", "th", "thead", "tbody", "tfoot"].includes(e) ? `:nth-child(${a})` : `:nth-of-type(${r.filter((l) => l.tagName.toLowerCase() === e).indexOf(t) + 1})`;
1989
+ return ["tr", "td", "th", "thead", "tbody", "tfoot"].includes(e) ? `:nth-child(${a})` : `:nth-of-type(${r.filter((c) => c.tagName.toLowerCase() === e).indexOf(t) + 1})`;
1789
1990
  }
1790
1991
  /**
1791
1992
  * Gets attribute priority for sorting
@@ -1793,7 +1994,7 @@ class st {
1793
1994
  * @returns Priority number (higher = more priority)
1794
1995
  */
1795
1996
  getAttributePriority(t) {
1796
- return w[t] !== void 0 ? w[t] : t.startsWith("data-") ? w["data-*"] : t.startsWith("aria-") ? w["aria-*"] : 0;
1997
+ return E[t] !== void 0 ? E[t] : t.startsWith("data-") ? E["data-*"] : t.startsWith("aria-") ? E["aria-*"] : 0;
1797
1998
  }
1798
1999
  /**
1799
2000
  * Checks if attribute should be ignored
@@ -1828,12 +2029,12 @@ class st {
1828
2029
  if (e.attributes) {
1829
2030
  const a = this.getSortedAttributes(e.attributes);
1830
2031
  for (const { name: i, value: o } of a) {
1831
- const l = i === "href" || i === "src" ? k(i, o) : o;
1832
- l && (r += `[${i}="${this.escapeAttr(l)}"]`);
2032
+ const c = i === "href" || i === "src" ? q(i, o) : o;
2033
+ c && (r += `[${i}="${this.escapeAttr(c)}"]`);
1833
2034
  }
1834
2035
  }
1835
2036
  if (e.role && !e.attributes?.role && (r += `[role="${this.escapeAttr(e.role)}"]`), !s?.excludeClasses && e.classes && e.classes.length > 0) {
1836
- const a = N(e.classes), i = s?.maxClasses !== void 0 ? a.slice(0, s.maxClasses) : a;
2037
+ const a = M(e.classes), i = s?.maxClasses !== void 0 ? a.slice(0, s.maxClasses) : a;
1837
2038
  r += i.map((o) => `.${this.escapeCSS(o)}`).join("");
1838
2039
  }
1839
2040
  return r;
@@ -1857,10 +2058,42 @@ class st {
1857
2058
  * @returns True if element is an SVG child
1858
2059
  */
1859
2060
  isSvgChildElement(t) {
1860
- return ht.includes(t);
2061
+ return ut.includes(t);
2062
+ }
2063
+ /**
2064
+ * Builds CSS selector for elements inside <head>.
2065
+ * Uses child combinator (>) for strict structure: html > head > ... > target
2066
+ * @param eid - Element Identity with anchor=html and path[0]=head
2067
+ * @param options - Optional uniqueness control settings
2068
+ * @returns CSS selector string or BuildSelectorResult
2069
+ * @remarks
2070
+ * This method handles the special case where elements are inside <head>.
2071
+ * The selector always uses child combinators for strict parent-child relationships.
2072
+ * @example
2073
+ * For <html><head><meta name="description"></head></html>
2074
+ * Returns: "html > head > meta[name='description']"
2075
+ */
2076
+ buildHeadSelector(t, e) {
2077
+ const s = ["html"];
2078
+ for (const o of t.path) {
2079
+ let c = this.buildNodeSelector(o.tag, o.semantics);
2080
+ o.nthChild !== void 0 && (c += `:nth-child(${o.nthChild})`), s.push(c);
2081
+ }
2082
+ let r = this.buildNodeSelector(t.target.tag, t.target.semantics);
2083
+ t.target.nthChild !== void 0 && (r += `:nth-child(${t.target.nthChild})`), s.push(r);
2084
+ const a = s.join(" > ");
2085
+ if (!e?.ensureUnique)
2086
+ return a;
2087
+ const i = this.isUnique(a, e.root ?? document);
2088
+ return {
2089
+ selector: a,
2090
+ isUnique: i,
2091
+ usedNthOfType: a.includes(":nth-"),
2092
+ extraClassesAdded: 0
2093
+ };
1861
2094
  }
1862
2095
  }
1863
- class Ft {
2096
+ class jt {
1864
2097
  /**
1865
2098
  * Filters elements that match the semantics
1866
2099
  * @param elements - Candidate elements
@@ -1937,8 +2170,8 @@ class Ft {
1937
2170
  break;
1938
2171
  }
1939
2172
  case "line": {
1940
- const r = parseFloat(t.getAttribute("x1") ?? "0"), a = parseFloat(t.getAttribute("y1") ?? "0"), i = parseFloat(t.getAttribute("x2") ?? "0"), o = parseFloat(t.getAttribute("y2") ?? "0"), l = Math.atan2(o - a, i - r);
1941
- s.push(`angle=${l.toFixed(2)}`);
2173
+ const r = parseFloat(t.getAttribute("x1") ?? "0"), a = parseFloat(t.getAttribute("y1") ?? "0"), i = parseFloat(t.getAttribute("x2") ?? "0"), o = parseFloat(t.getAttribute("y2") ?? "0"), c = Math.atan2(o - a, i - r);
2174
+ s.push(`angle=${c.toFixed(2)}`);
1942
2175
  break;
1943
2176
  }
1944
2177
  }
@@ -1956,7 +2189,7 @@ class Ft {
1956
2189
  return Math.abs(e).toString(16).padStart(8, "0");
1957
2190
  }
1958
2191
  }
1959
- class jt {
2192
+ class Wt {
1960
2193
  /**
1961
2194
  * Applies a single constraint to candidates
1962
2195
  * @param candidates - Current candidate elements
@@ -2046,9 +2279,9 @@ class jt {
2046
2279
  return s[e.length];
2047
2280
  }
2048
2281
  }
2049
- class Wt {
2282
+ class Bt {
2050
2283
  constructor() {
2051
- this.cssGenerator = new st();
2284
+ this.cssGenerator = new rt();
2052
2285
  }
2053
2286
  /**
2054
2287
  * Handles fallback when resolution fails
@@ -2178,8 +2411,8 @@ class Wt {
2178
2411
  if (a.length > 0) {
2179
2412
  r += 0.2;
2180
2413
  let i = 0;
2181
- for (const [o, l] of a)
2182
- t.getAttribute(o) === l && i++;
2414
+ for (const [o, c] of a)
2415
+ t.getAttribute(o) === c && i++;
2183
2416
  s += i / a.length * 0.2;
2184
2417
  }
2185
2418
  }
@@ -2191,44 +2424,44 @@ class Wt {
2191
2424
  return r > 0 ? s / r : 0;
2192
2425
  }
2193
2426
  }
2194
- function Bt(n, t, e = {}) {
2195
- const s = { ...dt, ...e }, r = new st(), a = new Ft(), i = new jt(), o = new Wt(), l = t instanceof Document ? t : t.ownerDocument ?? t, u = r.buildSelector(n, {
2427
+ function Gt(n, t, e = {}) {
2428
+ const s = { ...ft, ...e }, r = new rt(), a = new jt(), i = new Wt(), o = new Bt(), c = t instanceof Document ? t : t.ownerDocument ?? t, u = r.buildSelector(n, {
2196
2429
  ensureUnique: !1,
2197
- root: l
2430
+ root: c
2198
2431
  });
2199
2432
  let d;
2200
2433
  try {
2201
- d = Array.from(l.querySelectorAll(u));
2434
+ d = Array.from(c.querySelectorAll(u));
2202
2435
  } catch (f) {
2203
- const p = f instanceof Error ? f.message : "Unknown selector error";
2436
+ const m = f instanceof Error ? f.message : "Unknown selector error";
2204
2437
  return {
2205
2438
  status: "error",
2206
2439
  elements: [],
2207
- warnings: [`Invalid CSS selector: ${u}`, `Error: ${p}`],
2440
+ warnings: [`Invalid CSS selector: ${u}`, `Error: ${m}`],
2208
2441
  confidence: 0,
2209
2442
  meta: { degraded: !0, degradationReason: "invalid-selector" }
2210
2443
  };
2211
2444
  }
2212
2445
  d.length > s.maxCandidates && (d = d.slice(0, s.maxCandidates));
2213
- const c = a.match(d, n.target.semantics);
2214
- if (c.length === 1)
2446
+ const l = a.match(d, n.target.semantics);
2447
+ if (l.length === 1)
2215
2448
  return {
2216
2449
  status: "success",
2217
- elements: c,
2450
+ elements: l,
2218
2451
  warnings: [],
2219
2452
  confidence: n.meta.confidence,
2220
2453
  meta: { degraded: !1 }
2221
2454
  };
2222
- if (c.length === 0)
2223
- return s.enableFallback ? o.handleFallback(n, l) : {
2455
+ if (l.length === 0)
2456
+ return s.enableFallback ? o.handleFallback(n, c) : {
2224
2457
  status: "error",
2225
2458
  elements: [],
2226
2459
  warnings: ["No matching elements found"],
2227
2460
  confidence: 0,
2228
2461
  meta: { degraded: !0, degradationReason: "not-found" }
2229
2462
  };
2230
- let h = c;
2231
- const g = Gt(n.constraints);
2463
+ let h = l;
2464
+ const g = Vt(n.constraints);
2232
2465
  for (const f of g) {
2233
2466
  if (h = i.applyConstraint(h, f), h.length === 1)
2234
2467
  return {
@@ -2239,7 +2472,7 @@ function Bt(n, t, e = {}) {
2239
2472
  meta: { degraded: !1 }
2240
2473
  };
2241
2474
  if (h.length === 0)
2242
- return s.enableFallback ? o.handleFallback(n, l) : {
2475
+ return s.enableFallback ? o.handleFallback(n, c) : {
2243
2476
  status: "error",
2244
2477
  elements: [],
2245
2478
  warnings: ["Constraints eliminated all candidates"],
@@ -2255,10 +2488,10 @@ function Bt(n, t, e = {}) {
2255
2488
  meta: { degraded: !0, degradationReason: "ambiguous" }
2256
2489
  } : o.handleAmbiguous(h, n);
2257
2490
  }
2258
- function Gt(n) {
2491
+ function Vt(n) {
2259
2492
  return [...n].sort((t, e) => e.priority - t.priority);
2260
2493
  }
2261
- function oe(n) {
2494
+ function ce(n) {
2262
2495
  const t = [], e = [];
2263
2496
  if (n.version ? n.version !== "1.0" && e.push(`Unknown version: ${n.version}`) : t.push("Missing version field"), n.anchor ? (n.anchor.tag || t.push("Anchor missing tag"), typeof n.anchor.score != "number" && t.push("Anchor missing score"), n.anchor.semantics || t.push("Anchor missing semantics")) : t.push("Missing anchor field"), n.target ? (n.target.tag || t.push("Target missing tag"), typeof n.target.score != "number" && t.push("Target missing score"), n.target.semantics || t.push("Target missing semantics")) : t.push("Missing target field"), !Array.isArray(n.path))
2264
2497
  t.push("Path must be an array");
@@ -2273,12 +2506,12 @@ function oe(n) {
2273
2506
  warnings: e
2274
2507
  };
2275
2508
  }
2276
- function ce(n) {
2509
+ function le(n) {
2277
2510
  if (!n || typeof n != "object") return !1;
2278
2511
  const t = n;
2279
2512
  return typeof t.version == "string" && typeof t.anchor == "object" && Array.isArray(t.path) && typeof t.target == "object";
2280
2513
  }
2281
- const rt = {
2514
+ const nt = {
2282
2515
  maxClasses: 2,
2283
2516
  maxAttributes: 5,
2284
2517
  includeText: !0,
@@ -2286,20 +2519,20 @@ const rt = {
2286
2519
  simplifyTarget: !0,
2287
2520
  includeConstraints: !0
2288
2521
  };
2289
- function et(n) {
2290
- return n === "id" ? 101 : w[n] !== void 0 ? w[n] : n.startsWith("data-") ? w["data-*"] : n.startsWith("aria-") ? w["aria-*"] : 0;
2522
+ function st(n) {
2523
+ return n === "id" ? 101 : E[n] !== void 0 ? E[n] : n.startsWith("data-") ? E["data-*"] : n.startsWith("aria-") ? E["aria-*"] : 0;
2291
2524
  }
2292
- function Vt(n) {
2525
+ function Qt(n) {
2293
2526
  return ["id", "data-testid", "data-qa", "data-cy", "href", "text", "role"].includes(n);
2294
2527
  }
2295
- function Qt(n) {
2528
+ function Zt(n) {
2296
2529
  return !!(/@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/.test(n) || /(\+?\d{1,3}[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}/.test(n) || /\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}/.test(n));
2297
2530
  }
2298
- function Zt(n, t) {
2299
- const e = { ...rt, ...t }, s = `v${n.version}`, r = U(n.anchor, !1, e), a = n.path.length > 0 ? n.path.map((l) => U(l, !1, e)).join(" > ") + " > " : "", i = U(n.target, !0, e), o = e.includeConstraints ? Xt(n) : "";
2531
+ function Yt(n, t) {
2532
+ const e = { ...nt, ...t }, s = `v${n.version}`, r = z(n.anchor, !1, e), a = n.path.length > 0 ? n.path.map((c) => z(c, !1, e)).join(" > ") + " > " : "", i = z(n.target, !0, e), o = e.includeConstraints ? Kt(n) : "";
2300
2533
  return `${s}: ${r} :: ${a}${i}${o}`;
2301
2534
  }
2302
- function Yt(n) {
2535
+ function Xt(n) {
2303
2536
  n = n.trim();
2304
2537
  const t = n.match(/^v(\d+(?:\.\d+)?)\s*:\s*/);
2305
2538
  if (!t)
@@ -2316,13 +2549,13 @@ function Yt(n) {
2316
2549
  const i = s.match(/\s*\{([^}]+)\}\s*$/);
2317
2550
  let o = "";
2318
2551
  i && (o = i[1], s = s.slice(0, i.index));
2319
- const l = s.split(/\s*>\s*/).map((m) => m.trim()).filter((m) => m);
2320
- if (l.length === 0)
2552
+ const c = s.split(/\s*>\s*/).map((p) => p.trim()).filter((p) => p);
2553
+ if (c.length === 0)
2321
2554
  throw new Error("Invalid SEQL Selector: missing target node");
2322
- const u = l[l.length - 1], d = l.slice(0, -1), c = F(a, !0), h = d.map((m) => F(m, !1)), g = F(u, !1), f = Kt(o);
2555
+ const u = c[c.length - 1], d = c.slice(0, -1), l = F(a, !0), h = d.map((p) => F(p, !1)), g = F(u, !1), f = Jt(o);
2323
2556
  return {
2324
2557
  version: "1.0",
2325
- anchor: c,
2558
+ anchor: l,
2326
2559
  path: h,
2327
2560
  target: g,
2328
2561
  constraints: f,
@@ -2340,44 +2573,44 @@ function Yt(n) {
2340
2573
  }
2341
2574
  };
2342
2575
  }
2343
- function U(n, t = !1, e = rt) {
2576
+ function z(n, t = !1, e = nt) {
2344
2577
  const { tag: s, semantics: r } = n;
2345
2578
  let a = s;
2346
2579
  const i = [], o = { ...r.attributes };
2347
2580
  r.id && (o.id = r.id), r.role && !o.role && (o.role = r.role);
2348
- const l = Object.entries(o).map(([c, h]) => {
2349
- const g = et(c), f = c === "href" || c === "src" ? k(c, h) : h;
2350
- return { name: c, value: f, priority: g };
2351
- }).filter((c) => c.name !== "id" && c.name !== "class" && B.has(c.name) || G.has(c.name) && V(c.value) ? !1 : c.priority > 0 || c.name === "role" || c.name === "id");
2352
- l.sort((c, h) => h.priority - c.priority);
2353
- const u = l.slice(0, e.maxAttributes);
2354
- u.sort((c, h) => c.name.localeCompare(h.name));
2355
- for (const { name: c, value: h } of u)
2356
- i.push(`${c}="${j(h)}"`);
2357
- if (e.includeText && r.text && !Qt(r.text.normalized)) {
2358
- const c = r.text.normalized;
2359
- c.length > 0 && c.length <= e.maxTextLength && i.push(`text="${j(c)}"`);
2581
+ const c = Object.entries(o).map(([l, h]) => {
2582
+ const g = st(l), f = l === "href" || l === "src" ? q(l, h) : h;
2583
+ return { name: l, value: f, priority: g };
2584
+ }).filter((l) => l.name !== "id" && l.name !== "class" && B.has(l.name) || G.has(l.name) && V(l.value) ? !1 : l.priority > 0 || l.name === "role" || l.name === "id");
2585
+ c.sort((l, h) => h.priority - l.priority);
2586
+ const u = c.slice(0, e.maxAttributes);
2587
+ u.sort((l, h) => l.name.localeCompare(h.name));
2588
+ for (const { name: l, value: h } of u)
2589
+ i.push(`${l}="${j(h)}"`);
2590
+ if (e.includeText && r.text && !Zt(r.text.normalized)) {
2591
+ const l = r.text.normalized;
2592
+ l.length > 0 && l.length <= e.maxTextLength && i.push(`text="${j(l)}"`);
2360
2593
  }
2361
2594
  let d = i;
2362
- if (i.length > 0 && (t && e.simplifyTarget && r.id && (d = i.filter((c) => {
2363
- const h = c.split("=")[0];
2364
- return et(h) >= 60 || h === "text" || h === "id" || h === "role";
2365
- })), d.length > 0 && d.sort((c, h) => c.localeCompare(h))), r.classes && r.classes.length > 0) {
2366
- const c = N(r.classes), h = !!r.id || i.some(
2595
+ if (i.length > 0 && (t && e.simplifyTarget && r.id && (d = i.filter((l) => {
2596
+ const h = l.split("=")[0];
2597
+ return st(h) >= 60 || h === "text" || h === "id" || h === "role";
2598
+ })), d.length > 0 && d.sort((l, h) => l.localeCompare(h))), r.classes && r.classes.length > 0) {
2599
+ const l = M(r.classes), h = !!r.id || i.some(
2367
2600
  (f) => f.startsWith("href=") || f.startsWith("data-testid=") || f.startsWith("text=") || f.startsWith("role=")
2368
2601
  );
2369
- if (!(t && e.simplifyTarget && h) && c.length > 0) {
2370
- const f = c.sort().slice(0, e.maxClasses);
2371
- a += f.map((p) => `.${p}`).join("");
2602
+ if (!(t && e.simplifyTarget && h) && l.length > 0) {
2603
+ const f = l.sort().slice(0, e.maxClasses);
2604
+ a += f.map((m) => `.${m}`).join("");
2372
2605
  }
2373
2606
  }
2374
2607
  if (d.length > 0 && (a += `[${d.join(",")}]`), "nthChild" in n && n.nthChild) {
2375
- const c = !!r.id || r.attributes && Object.keys(r.attributes).some(Vt);
2376
- t && e.simplifyTarget && c || (a += `#${n.nthChild}`);
2608
+ const l = !!r.id || r.attributes && Object.keys(r.attributes).some(Qt);
2609
+ t && e.simplifyTarget && l || (a += `#${n.nthChild}`);
2377
2610
  }
2378
2611
  return a;
2379
2612
  }
2380
- function Xt(n) {
2613
+ function Kt(n) {
2381
2614
  if (!n.constraints || n.constraints.length === 0)
2382
2615
  return "";
2383
2616
  const t = [];
@@ -2410,20 +2643,20 @@ function F(n, t) {
2410
2643
  for (; o = e.match(/^\.([a-zA-Z][a-zA-Z0-9-_]*)/); )
2411
2644
  i.push(o[1]), e = e.slice(o[0].length);
2412
2645
  i.length > 0 && (s.classes = i);
2413
- const l = e.match(/^\[([^\]]+)\]/);
2414
- if (l) {
2415
- const c = l[1], h = {}, g = Jt(c);
2646
+ const c = e.match(/^\[([^\]]+)\]/);
2647
+ if (c) {
2648
+ const l = c[1], h = {}, g = te(l);
2416
2649
  for (const f of g) {
2417
- const p = f.match(/^([a-z][a-z0-9-]*)(?:=|~=)"((?:[^"\\]|\\.)*)"/);
2418
- if (p) {
2419
- const [, m, b] = p;
2420
- h[m] = nt(b);
2650
+ const m = f.match(/^([a-z][a-z0-9-]*)(?:=|~=)"((?:[^"\\]|\\.)*)"/);
2651
+ if (m) {
2652
+ const [, p, S] = m;
2653
+ h[p] = at(S);
2421
2654
  }
2422
2655
  }
2423
2656
  Object.keys(h).length > 0 && (h.text && (s.text = {
2424
2657
  raw: h.text,
2425
2658
  normalized: h.text
2426
- }, delete h.text), h.id && (s.id = h.id, delete h.id), h.role && (s.role = h.role, delete h.role), Object.keys(h).length > 0 && (s.attributes = h)), e = e.slice(l[0].length);
2659
+ }, delete h.text), h.id && (s.id = h.id, delete h.id), h.role && (s.role = h.role, delete h.role), Object.keys(h).length > 0 && (s.attributes = h)), e = e.slice(c[0].length);
2427
2660
  }
2428
2661
  let u;
2429
2662
  const d = e.match(/^#(\d+)/);
@@ -2441,7 +2674,7 @@ function F(n, t) {
2441
2674
  nthChild: u
2442
2675
  };
2443
2676
  }
2444
- function Kt(n) {
2677
+ function Jt(n) {
2445
2678
  if (!n.trim())
2446
2679
  return [];
2447
2680
  const t = [], e = n.split(",").map((s) => s.trim());
@@ -2471,7 +2704,7 @@ function Kt(n) {
2471
2704
  t.push({
2472
2705
  type: "text-proximity",
2473
2706
  params: {
2474
- reference: nt(i),
2707
+ reference: at(i),
2475
2708
  maxDistance: 5
2476
2709
  },
2477
2710
  priority: 60
@@ -2482,7 +2715,7 @@ function Kt(n) {
2482
2715
  }
2483
2716
  return t;
2484
2717
  }
2485
- function Jt(n) {
2718
+ function te(n) {
2486
2719
  const t = [];
2487
2720
  let e = "", s = !1;
2488
2721
  for (let r = 0; r < n.length; r++) {
@@ -2494,28 +2727,28 @@ function Jt(n) {
2494
2727
  function j(n) {
2495
2728
  return n.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/>/g, "\\>").replace(/:/g, "\\:");
2496
2729
  }
2497
- function nt(n) {
2730
+ function at(n) {
2498
2731
  return n.replace(/\\\\/g, "\0").replace(/\\"/g, '"').replace(/\\>/g, ">").replace(/\\:/g, ":").replace(/\x00/g, "\\");
2499
2732
  }
2500
- function le(n, t, e) {
2733
+ function he(n, t, e) {
2501
2734
  const s = Y(n, t);
2502
- return s ? Zt(s, e) : null;
2735
+ return s ? Yt(s, e) : null;
2503
2736
  }
2504
- function he(n, t, e) {
2737
+ function ue(n, t, e) {
2505
2738
  try {
2506
- const s = Yt(n);
2507
- return Bt(s, t, e).elements || [];
2739
+ const s = Xt(n);
2740
+ return Gt(s, t, e).elements || [];
2508
2741
  } catch (s) {
2509
2742
  return console.error("Failed to resolve SEQL Selector:", s), [];
2510
2743
  }
2511
2744
  }
2512
- const te = /* @__PURE__ */ new Set(["script", "style", "noscript", "meta", "link", "head", "title"]);
2745
+ const ee = /* @__PURE__ */ new Set(["script", "style", "noscript", "meta", "link", "head", "title"]);
2513
2746
  function W(n) {
2514
2747
  return n.id && !D(n.id) ? 3 : n.hasAttribute("role") || n.hasAttribute("aria-label") || n.hasAttribute("aria-labelledby") || n.hasAttribute("data-testid") || n.hasAttribute("data-qa") || n.hasAttribute("data-test") ? 2 : 1;
2515
2748
  }
2516
- function at(n, t) {
2749
+ function it(n, t) {
2517
2750
  const e = n.tagName.toLowerCase();
2518
- return !!(te.has(e) || t && W(n) === 1 && ![
2751
+ return !!(ee.has(e) || t && W(n) === 1 && ![
2519
2752
  "form",
2520
2753
  "main",
2521
2754
  "nav",
@@ -2531,13 +2764,13 @@ function at(n, t) {
2531
2764
  "textarea"
2532
2765
  ].includes(e));
2533
2766
  }
2534
- function it(n) {
2767
+ function ot(n) {
2535
2768
  return [...n].sort((t, e) => {
2536
2769
  const s = W(t);
2537
2770
  return W(e) - s;
2538
2771
  });
2539
2772
  }
2540
- function ue(n = {}) {
2773
+ function de(n = {}) {
2541
2774
  const t = performance.now(), {
2542
2775
  root: e = typeof document < "u" ? document.body : void 0,
2543
2776
  filter: s = "*",
@@ -2545,13 +2778,13 @@ function ue(n = {}) {
2545
2778
  onProgress: a,
2546
2779
  progressInterval: i = 100,
2547
2780
  skipNonSemantic: o = !0,
2548
- generatorOptions: l = {},
2781
+ generatorOptions: c = {},
2549
2782
  cache: u,
2550
2783
  signal: d
2551
2784
  } = n;
2552
2785
  if (!e)
2553
2786
  throw new Error("Root element or document is required");
2554
- const c = u ?? Z(), h = { ...l, cache: c };
2787
+ const l = u ?? Z(), h = { ...c, cache: l };
2555
2788
  let g;
2556
2789
  try {
2557
2790
  e instanceof Document, g = Array.from(e.querySelectorAll(s));
@@ -2570,144 +2803,144 @@ function ue(n = {}) {
2570
2803
  }
2571
2804
  };
2572
2805
  }
2573
- const f = g.filter((C) => !at(C, o)), m = it(f).slice(0, r), b = [], y = [];
2574
- let v = 0;
2575
- const A = m.length;
2576
- let S = 0;
2577
- for (let C = 0; C < m.length && !d?.aborted; C++) {
2578
- const T = m[C], R = c.getEID(T);
2579
- if (R)
2580
- b.push({
2581
- element: T,
2582
- eid: R,
2806
+ const f = g.filter((C) => !it(C, o)), p = ot(f).slice(0, r), S = [], y = [];
2807
+ let w = 0;
2808
+ const x = p.length;
2809
+ let b = 0;
2810
+ for (let C = 0; C < p.length && !d?.aborted; C++) {
2811
+ const v = p[C], A = l.getEID(v);
2812
+ if (A)
2813
+ S.push({
2814
+ element: v,
2815
+ eid: A,
2583
2816
  generationTimeMs: 0
2584
2817
  // Cached, no generation time
2585
2818
  });
2586
2819
  else {
2587
- const z = performance.now();
2820
+ const U = performance.now();
2588
2821
  try {
2589
- const P = Y(T, h), ot = performance.now() - z;
2590
- P ? b.push({
2591
- element: T,
2822
+ const P = Y(v, h), ct = performance.now() - U;
2823
+ P ? S.push({
2824
+ element: v,
2592
2825
  eid: P,
2593
- generationTimeMs: ot
2594
- }) : v++;
2826
+ generationTimeMs: ct
2827
+ }) : w++;
2595
2828
  } catch (P) {
2596
2829
  y.push({
2597
- element: T,
2830
+ element: v,
2598
2831
  error: P instanceof Error ? P.message : String(P)
2599
2832
  });
2600
2833
  }
2601
2834
  }
2602
- a && C - S >= i && (a(C + 1, A), S = C);
2835
+ a && C - b >= i && (a(C + 1, x), b = C);
2603
2836
  }
2604
- a && a(A, A);
2605
- const $ = performance.now() - t, M = c.getStats(), H = M.eidHits + M.eidMisses + M.selectorHits + M.selectorMisses, E = M.eidHits + M.selectorHits, x = H > 0 ? E / H : 0;
2837
+ a && a(x, x);
2838
+ const $ = performance.now() - t, I = l.getStats(), H = I.eidHits + I.eidMisses + I.selectorHits + I.selectorMisses, T = I.eidHits + I.selectorHits, R = H > 0 ? T / H : 0;
2606
2839
  return {
2607
- results: b,
2840
+ results: S,
2608
2841
  failed: y,
2609
2842
  stats: {
2610
- totalElements: A,
2611
- successful: b.length,
2843
+ totalElements: x,
2844
+ successful: S.length,
2612
2845
  failed: y.length,
2613
- skipped: v,
2846
+ skipped: w,
2614
2847
  totalTimeMs: $,
2615
- avgTimePerElementMs: b.length > 0 ? $ / b.length : 0,
2616
- cacheHitRate: x
2848
+ avgTimePerElementMs: S.length > 0 ? $ / S.length : 0,
2849
+ cacheHitRate: R
2617
2850
  }
2618
2851
  };
2619
2852
  }
2620
- function de(n, t = {}) {
2853
+ function fe(n, t = {}) {
2621
2854
  const e = performance.now(), {
2622
2855
  limit: s = 1 / 0,
2623
2856
  onProgress: r,
2624
2857
  progressInterval: a = 100,
2625
2858
  skipNonSemantic: i = !0,
2626
2859
  generatorOptions: o = {},
2627
- cache: l,
2860
+ cache: c,
2628
2861
  signal: u
2629
- } = t, d = l ?? Z(), c = { ...o, cache: d }, h = n.filter((E) => !at(E, i)), f = it(h).slice(0, s), p = [], m = [];
2630
- let b = 0;
2862
+ } = t, d = c ?? Z(), l = { ...o, cache: d }, h = n.filter((T) => !it(T, i)), f = ot(h).slice(0, s), m = [], p = [];
2863
+ let S = 0;
2631
2864
  const y = f.length;
2632
- let v = 0;
2633
- for (let E = 0; E < f.length && !u?.aborted; E++) {
2634
- const x = f[E], C = d.getEID(x);
2865
+ let w = 0;
2866
+ for (let T = 0; T < f.length && !u?.aborted; T++) {
2867
+ const R = f[T], C = d.getEID(R);
2635
2868
  if (C)
2636
- p.push({
2637
- element: x,
2869
+ m.push({
2870
+ element: R,
2638
2871
  eid: C,
2639
2872
  generationTimeMs: 0
2640
2873
  });
2641
2874
  else {
2642
- const T = performance.now();
2875
+ const v = performance.now();
2643
2876
  try {
2644
- const R = Y(x, c), z = performance.now() - T;
2645
- R ? p.push({
2646
- element: x,
2647
- eid: R,
2648
- generationTimeMs: z
2649
- }) : b++;
2650
- } catch (R) {
2651
- m.push({
2652
- element: x,
2653
- error: R instanceof Error ? R.message : String(R)
2877
+ const A = Y(R, l), U = performance.now() - v;
2878
+ A ? m.push({
2879
+ element: R,
2880
+ eid: A,
2881
+ generationTimeMs: U
2882
+ }) : S++;
2883
+ } catch (A) {
2884
+ p.push({
2885
+ element: R,
2886
+ error: A instanceof Error ? A.message : String(A)
2654
2887
  });
2655
2888
  }
2656
2889
  }
2657
- r && E - v >= a && (r(E + 1, y), v = E);
2890
+ r && T - w >= a && (r(T + 1, y), w = T);
2658
2891
  }
2659
2892
  r && r(y, y);
2660
- const A = performance.now() - e, S = d.getStats(), $ = S.eidHits + S.eidMisses + S.selectorHits + S.selectorMisses, M = S.eidHits + S.selectorHits, H = $ > 0 ? M / $ : 0;
2893
+ const x = performance.now() - e, b = d.getStats(), $ = b.eidHits + b.eidMisses + b.selectorHits + b.selectorMisses, I = b.eidHits + b.selectorHits, H = $ > 0 ? I / $ : 0;
2661
2894
  return {
2662
- results: p,
2663
- failed: m,
2895
+ results: m,
2896
+ failed: p,
2664
2897
  stats: {
2665
2898
  totalElements: y,
2666
- successful: p.length,
2667
- failed: m.length,
2668
- skipped: b,
2669
- totalTimeMs: A,
2670
- avgTimePerElementMs: p.length > 0 ? A / p.length : 0,
2899
+ successful: m.length,
2900
+ failed: p.length,
2901
+ skipped: S,
2902
+ totalTimeMs: x,
2903
+ avgTimePerElementMs: m.length > 0 ? x / m.length : 0,
2671
2904
  cacheHitRate: H
2672
2905
  }
2673
2906
  };
2674
2907
  }
2675
2908
  export {
2676
- ft as AnchorFinder,
2677
- jt as ConstraintsEvaluator,
2678
- st as CssGenerator,
2679
- ut as DEFAULT_GENERATOR_OPTIONS,
2680
- dt as DEFAULT_RESOLVER_OPTIONS,
2681
- Lt as EIDCache,
2682
- ee as EID_VERSION,
2683
- Wt as FallbackHandler,
2684
- se as MAX_PATH_DEPTH,
2685
- xt as PathBuilder,
2909
+ gt as AnchorFinder,
2910
+ Wt as ConstraintsEvaluator,
2911
+ rt as CssGenerator,
2912
+ dt as DEFAULT_GENERATOR_OPTIONS,
2913
+ ft as DEFAULT_RESOLVER_OPTIONS,
2914
+ _t as EIDCache,
2915
+ se as EID_VERSION,
2916
+ Bt as FallbackHandler,
2917
+ re as MAX_PATH_DEPTH,
2918
+ Ct as PathBuilder,
2686
2919
  K as ROLE_ANCHOR_VALUES,
2687
2920
  X as SEMANTIC_ANCHOR_TAGS,
2688
- re as SEMANTIC_ATTRIBUTES,
2689
- lt as SEMANTIC_TAGS,
2690
- Pt as SemanticExtractor,
2691
- Ft as SemanticsMatcher,
2692
- kt as SvgFingerprinter,
2693
- _t as calculateConfidence,
2694
- ae as calculateElementScore,
2921
+ ne as SEMANTIC_ATTRIBUTES,
2922
+ ht as SEMANTIC_TAGS,
2923
+ et as SemanticExtractor,
2924
+ jt as SemanticsMatcher,
2925
+ qt as SvgFingerprinter,
2926
+ Lt as calculateConfidence,
2927
+ ie as calculateElementScore,
2695
2928
  Ot as createEIDCache,
2696
- At as filterClasses,
2929
+ xt as filterClasses,
2697
2930
  Y as generateEID,
2698
- ue as generateEIDBatch,
2699
- de as generateEIDForElements,
2700
- le as generateSEQL,
2701
- ne as getClassScore,
2931
+ de as generateEIDBatch,
2932
+ fe as generateEIDForElements,
2933
+ he as generateSEQL,
2934
+ ae as getClassScore,
2702
2935
  Z as getGlobalCache,
2703
- ce as isEID,
2936
+ le as isEID,
2704
2937
  J as isUtilityClass,
2705
2938
  Q as normalizeText,
2706
- Yt as parseSEQL,
2707
- ie as resetGlobalCache,
2708
- Bt as resolve,
2709
- he as resolveSEQL,
2710
- Zt as stringifySEQL,
2711
- oe as validateEID
2939
+ Xt as parseSEQL,
2940
+ oe as resetGlobalCache,
2941
+ Gt as resolve,
2942
+ ue as resolveSEQL,
2943
+ Yt as stringifySEQL,
2944
+ ce as validateEID
2712
2945
  };
2713
2946
  //# sourceMappingURL=seql-js.js.map