@accesslint/core 0.3.9 → 0.3.11

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/index.js CHANGED
@@ -1,8 +1,8 @@
1
- let O = /* @__PURE__ */ new WeakMap();
2
- function ve() {
3
- O = /* @__PURE__ */ new WeakMap();
1
+ let B = /* @__PURE__ */ new WeakMap();
2
+ function we() {
3
+ B = /* @__PURE__ */ new WeakMap();
4
4
  }
5
- function ue(t) {
5
+ function de(t) {
6
6
  var i;
7
7
  const a = t.tagName.toLowerCase(), e = (i = t.getAttribute("type")) == null ? void 0 : i.toLowerCase();
8
8
  switch (a) {
@@ -117,30 +117,30 @@ function ue(t) {
117
117
  return null;
118
118
  }
119
119
  }
120
- function L(t) {
120
+ function q(t) {
121
121
  var n;
122
- const a = O.get(t);
122
+ const a = B.get(t);
123
123
  if (a !== void 0) return a;
124
- const i = ((n = t.getAttribute("role")) == null ? void 0 : n.trim().toLowerCase()) || null || ue(t);
125
- return O.set(t, i), i;
124
+ const i = ((n = t.getAttribute("role")) == null ? void 0 : n.trim().toLowerCase()) || null || de(t);
125
+ return B.set(t, i), i;
126
126
  }
127
127
  let F = /* @__PURE__ */ new WeakMap();
128
- function ye() {
128
+ function Ae() {
129
129
  F = /* @__PURE__ */ new WeakMap();
130
130
  }
131
131
  function v(t) {
132
132
  const a = F.get(t);
133
133
  if (a !== void 0) return a;
134
- const e = we(t);
134
+ const e = xe(t);
135
135
  return F.set(t, e), e;
136
136
  }
137
- function we(t) {
137
+ function xe(t) {
138
138
  var r, o, s, l, h;
139
139
  const a = t.getAttribute("aria-labelledby");
140
140
  if (a) {
141
- const c = a.split(/\s+/).map((d) => {
142
- const g = t.ownerDocument.getElementById(d);
143
- return g ? w(g).trim() : "";
141
+ const c = a.split(/\s+/).map((u) => {
142
+ const p = t.ownerDocument.getElementById(u);
143
+ return p ? A(p).trim() : "";
144
144
  }).filter(Boolean);
145
145
  if (c.length) return c.join(" ");
146
146
  }
@@ -148,11 +148,11 @@ function we(t) {
148
148
  if (e) return e;
149
149
  if (t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement || t instanceof HTMLSelectElement) {
150
150
  if (t.id) {
151
- const g = t.ownerDocument.querySelector(`label[for="${CSS.escape(t.id)}"]`), b = g ? w(g).trim() : "";
151
+ const p = t.ownerDocument.querySelector(`label[for="${CSS.escape(t.id)}"]`), b = p ? A(p).trim() : "";
152
152
  if (b) return b;
153
153
  }
154
- const c = t.closest("label"), d = c ? w(c).trim() : "";
155
- if (d) return d;
154
+ const c = t.closest("label"), u = c ? A(c).trim() : "";
155
+ if (u) return u;
156
156
  }
157
157
  const i = (o = t.getAttribute("title")) == null ? void 0 : o.trim();
158
158
  if (i) return i;
@@ -164,24 +164,24 @@ function we(t) {
164
164
  if (n === "fieldset") {
165
165
  const c = t.querySelector(":scope > legend");
166
166
  if (c) {
167
- const d = w(c).trim();
168
- if (d) return d;
167
+ const u = A(c).trim();
168
+ if (u) return u;
169
169
  }
170
170
  }
171
171
  if (n === "table") {
172
172
  const c = t.querySelector(":scope > caption");
173
173
  if (c) {
174
- const d = w(c).trim();
175
- if (d) return d;
174
+ const u = A(c).trim();
175
+ if (u) return u;
176
176
  }
177
177
  }
178
178
  if (!(t instanceof HTMLInputElement)) {
179
- const c = w(t).trim();
179
+ const c = A(t).trim();
180
180
  if (c) return c;
181
181
  }
182
182
  return t instanceof HTMLImageElement || t instanceof HTMLAreaElement ? ((l = t.alt) == null ? void 0 : l.trim()) ?? "" : t instanceof HTMLInputElement && t.type === "image" ? ((h = t.alt) == null ? void 0 : h.trim()) ?? "" : "";
183
183
  }
184
- const Ae = /* @__PURE__ */ new Set([
184
+ const Se = /* @__PURE__ */ new Set([
185
185
  "alert",
186
186
  "alertdialog",
187
187
  "application",
@@ -265,24 +265,36 @@ const Ae = /* @__PURE__ */ new Set([
265
265
  "treegrid",
266
266
  "treeitem"
267
267
  ]);
268
- function xe(t) {
268
+ function ke(t) {
269
269
  const a = t.trim().toLowerCase().replace(/[\u201C\u201D\u2018\u2019\u00AB\u00BB]/g, "");
270
- return Ae.has(a);
270
+ return Se.has(a);
271
271
  }
272
- let B = /* @__PURE__ */ new WeakMap();
273
- function Se() {
274
- B = /* @__PURE__ */ new WeakMap();
272
+ function T(t) {
273
+ let a = t;
274
+ for (; a; ) {
275
+ if (a.getAttribute("aria-hidden") === "true" || a instanceof HTMLElement && a.hidden) return !0;
276
+ if (typeof getComputedStyle == "function") {
277
+ const e = getComputedStyle(a);
278
+ if (e.display === "none" || e.visibility === "hidden") return !0;
279
+ } else if (a instanceof HTMLElement && a.style.display === "none") return !0;
280
+ a = a.parentElement;
281
+ }
282
+ return !1;
275
283
  }
276
- function p(t) {
277
- const a = B.get(t);
284
+ let W = /* @__PURE__ */ new WeakMap();
285
+ function Ie() {
286
+ W = /* @__PURE__ */ new WeakMap();
287
+ }
288
+ function g(t) {
289
+ const a = W.get(t);
278
290
  if (a !== void 0) return a;
279
291
  let e;
280
- return t.getAttribute("aria-hidden") === "true" || t instanceof HTMLElement && (t.hidden || t.style.display === "none") ? e = !0 : t.parentElement ? e = p(t.parentElement) : e = !1, B.set(t, e), e;
292
+ return t.getAttribute("aria-hidden") === "true" || t instanceof HTMLElement && (t.hidden || t.style.display === "none") ? e = !0 : t.parentElement ? e = g(t.parentElement) : e = !1, W.set(t, e), e;
281
293
  }
282
- function ke(t) {
294
+ function Te(t) {
283
295
  return !!(t.getAttribute("aria-hidden") === "true" || t instanceof HTMLElement && (t.hidden || t.style.display === "none"));
284
296
  }
285
- function w(t) {
297
+ function A(t) {
286
298
  var e, i, n, r, o;
287
299
  let a = "";
288
300
  for (const s of t.childNodes)
@@ -290,17 +302,17 @@ function w(t) {
290
302
  a += s.textContent ?? "";
291
303
  else if (s.nodeType === 1) {
292
304
  const l = s;
293
- if (!ke(l)) {
305
+ if (!Te(l)) {
294
306
  const h = (e = l.tagName) == null ? void 0 : e.toLowerCase();
295
307
  if (h === "img" || h === "area") {
296
308
  const c = l.getAttribute("aria-labelledby");
297
309
  if (c) {
298
- const d = c.split(/\s+/).map((g) => {
310
+ const u = c.split(/\s+/).map((p) => {
299
311
  var b, f;
300
- return ((f = (b = l.ownerDocument.getElementById(g)) == null ? void 0 : b.textContent) == null ? void 0 : f.trim()) ?? "";
312
+ return ((f = (b = l.ownerDocument.getElementById(p)) == null ? void 0 : b.textContent) == null ? void 0 : f.trim()) ?? "";
301
313
  }).filter(Boolean);
302
- if (d.length) {
303
- a += d.join(" ");
314
+ if (u.length) {
315
+ a += u.join(" ");
304
316
  continue;
305
317
  }
306
318
  }
@@ -310,22 +322,22 @@ function w(t) {
310
322
  if (c)
311
323
  a += c;
312
324
  else {
313
- const d = l.querySelector("title");
314
- d && (a += d.textContent ?? "");
325
+ const u = l.querySelector("title");
326
+ u && (a += u.textContent ?? "");
315
327
  }
316
- } else (o = l.getAttribute("aria-label")) != null && o.trim() ? a += l.getAttribute("aria-label").trim() : a += w(l);
328
+ } else (o = l.getAttribute("aria-label")) != null && o.trim() ? a += l.getAttribute("aria-label").trim() : a += A(l);
317
329
  }
318
330
  }
319
331
  return a;
320
332
  }
321
- let W = /* @__PURE__ */ new WeakMap();
322
- function Ie() {
323
- W = /* @__PURE__ */ new WeakMap();
333
+ let _ = /* @__PURE__ */ new WeakMap();
334
+ function Ee() {
335
+ _ = /* @__PURE__ */ new WeakMap();
324
336
  }
325
- function Te(t) {
337
+ function Ce(t) {
326
338
  return t.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
327
339
  }
328
- const Ee = [
340
+ const Le = [
329
341
  "data-testid",
330
342
  "data-test-id",
331
343
  "data-cy",
@@ -335,12 +347,12 @@ const Ee = [
335
347
  "for",
336
348
  "aria-label"
337
349
  ];
338
- function Ce(t) {
350
+ function qe(t) {
339
351
  const a = t.tagName.toLowerCase();
340
- for (const i of Ee) {
352
+ for (const i of Le) {
341
353
  const n = t.getAttribute(i);
342
354
  if (n != null && n.length > 0 && n.length < 100)
343
- return `${a}[${i}="${Te(n)}"]`;
355
+ return `${a}[${i}="${Ce(n)}"]`;
344
356
  }
345
357
  const e = t.parentElement;
346
358
  if (e) {
@@ -352,7 +364,7 @@ function Ce(t) {
352
364
  }
353
365
  return a;
354
366
  }
355
- function M(t) {
367
+ function H(t) {
356
368
  if (t.id) return `#${CSS.escape(t.id)}`;
357
369
  const a = t.getRootNode(), e = a instanceof ShadowRoot ? null : a.documentElement, i = [];
358
370
  let n = t;
@@ -361,7 +373,7 @@ function M(t) {
361
373
  i.unshift(`#${CSS.escape(n.id)}`);
362
374
  break;
363
375
  }
364
- if (i.unshift(Ce(n)), i.length >= 2) {
376
+ if (i.unshift(qe(n)), i.length >= 2) {
365
377
  const r = i.join(" > ");
366
378
  try {
367
379
  const o = a.querySelectorAll(r);
@@ -375,28 +387,28 @@ function M(t) {
375
387
  }
376
388
  function m(t) {
377
389
  var r;
378
- const a = W.get(t);
390
+ const a = _.get(t);
379
391
  if (a !== void 0) return a;
380
392
  const e = [];
381
393
  let i = t;
382
394
  for (; i; ) {
383
395
  const o = i.getRootNode();
384
396
  if (o instanceof ShadowRoot)
385
- e.unshift({ selector: M(i), delimiter: " >>> " }), i = o.host;
397
+ e.unshift({ selector: H(i), delimiter: " >>> " }), i = o.host;
386
398
  else {
387
399
  const s = (r = o.defaultView) == null ? void 0 : r.frameElement;
388
400
  if (s)
389
- e.unshift({ selector: M(i), delimiter: " >>>iframe> " }), i = s;
401
+ e.unshift({ selector: H(i), delimiter: " >>>iframe> " }), i = s;
390
402
  else {
391
- e.unshift({ selector: M(i), delimiter: "" });
403
+ e.unshift({ selector: H(i), delimiter: "" });
392
404
  break;
393
405
  }
394
406
  }
395
407
  }
396
408
  const n = e.map((o, s) => (s === 0 ? "" : o.delimiter) + o.selector).join("");
397
- return W.set(t, n), n;
409
+ return _.set(t, n), n;
398
410
  }
399
- function wi(t) {
411
+ function Ti(t) {
400
412
  const a = [], e = [];
401
413
  let i = t;
402
414
  for (; i; ) {
@@ -429,11 +441,11 @@ function wi(t) {
429
441
  }
430
442
  return null;
431
443
  }
432
- function u(t) {
444
+ function d(t) {
433
445
  const a = t.outerHTML;
434
446
  return a.length > 200 ? a.slice(0, 200) + "..." : a;
435
447
  }
436
- const Le = /* @__PURE__ */ new Set([
448
+ const Re = /* @__PURE__ */ new Set([
437
449
  "aria-activedescendant",
438
450
  "aria-atomic",
439
451
  "aria-autocomplete",
@@ -487,7 +499,7 @@ const Le = /* @__PURE__ */ new Set([
487
499
  "aria-valuemin",
488
500
  "aria-valuenow",
489
501
  "aria-valuetext"
490
- ]), G = /* @__PURE__ */ new Set([
502
+ ]), Y = /* @__PURE__ */ new Set([
491
503
  "aria-atomic",
492
504
  "aria-busy",
493
505
  "aria-disabled",
@@ -498,7 +510,7 @@ const Le = /* @__PURE__ */ new Set([
498
510
  "aria-multiselectable",
499
511
  "aria-readonly",
500
512
  "aria-required"
501
- ]), X = /* @__PURE__ */ new Set(["aria-checked", "aria-pressed"]), qe = /* @__PURE__ */ new Set([
513
+ ]), X = /* @__PURE__ */ new Set(["aria-checked", "aria-pressed"]), Ne = /* @__PURE__ */ new Set([
502
514
  "aria-colcount",
503
515
  "aria-colindex",
504
516
  "aria-colspan",
@@ -508,11 +520,11 @@ const Le = /* @__PURE__ */ new Set([
508
520
  "aria-rowindex",
509
521
  "aria-rowspan",
510
522
  "aria-setsize"
511
- ]), Re = /* @__PURE__ */ new Set([
523
+ ]), $e = /* @__PURE__ */ new Set([
512
524
  "aria-valuemax",
513
525
  "aria-valuemin",
514
526
  "aria-valuenow"
515
- ]), Y = {
527
+ ]), K = {
516
528
  "aria-autocomplete": /* @__PURE__ */ new Set(["inline", "list", "both", "none"]),
517
529
  "aria-expanded": /* @__PURE__ */ new Set(["true", "false", "undefined"]),
518
530
  "aria-current": /* @__PURE__ */ new Set(["page", "step", "location", "date", "time", "true", "false"]),
@@ -523,7 +535,7 @@ const Le = /* @__PURE__ */ new Set([
523
535
  "aria-orientation": /* @__PURE__ */ new Set(["horizontal", "vertical", "undefined"]),
524
536
  "aria-relevant": /* @__PURE__ */ new Set(["additions", "all", "removals", "text"]),
525
537
  "aria-sort": /* @__PURE__ */ new Set(["ascending", "descending", "none", "other"])
526
- }, K = /* @__PURE__ */ new Set([
538
+ }, J = /* @__PURE__ */ new Set([
527
539
  "caption",
528
540
  "code",
529
541
  "deletion",
@@ -540,7 +552,7 @@ const Le = /* @__PURE__ */ new Set([
540
552
  "suggestion",
541
553
  "term",
542
554
  "time"
543
- ]), Ne = {
555
+ ]), Me = {
544
556
  abbr: !0,
545
557
  bdi: !0,
546
558
  bdo: !0,
@@ -568,7 +580,7 @@ const Le = /* @__PURE__ */ new Set([
568
580
  u: !0,
569
581
  var: !0,
570
582
  wbr: !0
571
- }, $e = {
583
+ }, He = {
572
584
  alert: /* @__PURE__ */ new Set(["aria-disabled", "aria-errormessage", "aria-haspopup", "aria-invalid"]),
573
585
  article: /* @__PURE__ */ new Set(["aria-disabled", "aria-errormessage", "aria-haspopup", "aria-invalid"]),
574
586
  banner: /* @__PURE__ */ new Set(["aria-disabled", "aria-errormessage", "aria-haspopup", "aria-invalid"]),
@@ -601,13 +613,13 @@ const Le = /* @__PURE__ */ new Set([
601
613
  time: /* @__PURE__ */ new Set(["aria-disabled", "aria-errormessage", "aria-haspopup", "aria-invalid"]),
602
614
  tooltip: /* @__PURE__ */ new Set(["aria-disabled", "aria-errormessage", "aria-haspopup", "aria-invalid"])
603
615
  };
604
- let E = null, C = null;
605
- function Me() {
606
- E = null, C = null;
616
+ let C = null, L = null;
617
+ function De() {
618
+ C = null, L = null;
607
619
  }
608
- function z(t) {
620
+ function U(t) {
609
621
  var n;
610
- if (C && (E == null ? void 0 : E.deref()) === t) return C;
622
+ if (L && (C == null ? void 0 : C.deref()) === t) return L;
611
623
  const a = [], e = [], i = [];
612
624
  for (const r of t.querySelectorAll("*")) {
613
625
  let o = !1;
@@ -618,14 +630,14 @@ function z(t) {
618
630
  }
619
631
  if (!o) continue;
620
632
  let s, l;
621
- const h = () => (s === void 0 && (s = m(r), l = u(r)), { selector: s, html: l });
633
+ const h = () => (s === void 0 && (s = m(r), l = d(r)), { selector: s, html: l });
622
634
  for (const c of r.attributes)
623
- if (c.name.startsWith("aria-") && !Le.has(c.name)) {
624
- const d = h();
635
+ if (c.name.startsWith("aria-") && !Re.has(c.name)) {
636
+ const u = h();
625
637
  a.push({
626
638
  ruleId: "aria-valid-attr",
627
- selector: d.selector,
628
- html: d.html,
639
+ selector: u.selector,
640
+ html: u.html,
629
641
  impact: "critical",
630
642
  message: `Invalid ARIA attribute "${c.name}".`
631
643
  });
@@ -633,85 +645,85 @@ function z(t) {
633
645
  }
634
646
  for (const c of r.attributes) {
635
647
  if (!c.name.startsWith("aria-")) continue;
636
- const d = c.value.trim();
637
- if (!(d === "" && !G.has(c.name) && !X.has(c.name))) {
638
- if (G.has(c.name)) {
639
- if (d !== "true" && d !== "false") {
640
- const g = h();
648
+ const u = c.value.trim();
649
+ if (!(u === "" && !Y.has(c.name) && !X.has(c.name))) {
650
+ if (Y.has(c.name)) {
651
+ if (u !== "true" && u !== "false") {
652
+ const p = h();
641
653
  e.push({
642
654
  ruleId: "aria-valid-attr-value",
643
- selector: g.selector,
644
- html: g.html,
655
+ selector: p.selector,
656
+ html: p.html,
645
657
  impact: "critical",
646
- message: `${c.name} must be "true" or "false", got "${d}".`
658
+ message: `${c.name} must be "true" or "false", got "${u}".`
647
659
  });
648
660
  }
649
661
  } else if (X.has(c.name)) {
650
- if (d !== "true" && d !== "false" && d !== "mixed") {
651
- const g = h();
662
+ if (u !== "true" && u !== "false" && u !== "mixed") {
663
+ const p = h();
652
664
  e.push({
653
665
  ruleId: "aria-valid-attr-value",
654
- selector: g.selector,
655
- html: g.html,
666
+ selector: p.selector,
667
+ html: p.html,
656
668
  impact: "critical",
657
- message: `${c.name} must be "true", "false", or "mixed", got "${d}".`
669
+ message: `${c.name} must be "true", "false", or "mixed", got "${u}".`
658
670
  });
659
671
  }
660
- } else if (qe.has(c.name)) {
661
- if (d === "" || !/^-?\d+$/.test(d)) {
662
- const g = h();
672
+ } else if (Ne.has(c.name)) {
673
+ if (u === "" || !/^-?\d+$/.test(u)) {
674
+ const p = h();
663
675
  e.push({
664
676
  ruleId: "aria-valid-attr-value",
665
- selector: g.selector,
666
- html: g.html,
677
+ selector: p.selector,
678
+ html: p.html,
667
679
  impact: "critical",
668
- message: `${c.name} must be an integer, got "${d}".`
680
+ message: `${c.name} must be an integer, got "${u}".`
669
681
  });
670
682
  }
671
- } else if (Re.has(c.name)) {
672
- if (d === "" || isNaN(Number(d))) {
673
- const g = h();
683
+ } else if ($e.has(c.name)) {
684
+ if (u === "" || isNaN(Number(u))) {
685
+ const p = h();
674
686
  e.push({
675
687
  ruleId: "aria-valid-attr-value",
676
- selector: g.selector,
677
- html: g.html,
688
+ selector: p.selector,
689
+ html: p.html,
678
690
  impact: "critical",
679
- message: `${c.name} must be a number, got "${d}".`
691
+ message: `${c.name} must be a number, got "${u}".`
680
692
  });
681
693
  }
682
- } else if (Y[c.name]) {
683
- const g = d.split(/\s+/);
684
- for (const b of g)
685
- if (!Y[c.name].has(b)) {
694
+ } else if (K[c.name]) {
695
+ const p = u.split(/\s+/);
696
+ for (const b of p)
697
+ if (!K[c.name].has(b)) {
686
698
  const f = h();
687
699
  e.push({
688
700
  ruleId: "aria-valid-attr-value",
689
701
  selector: f.selector,
690
702
  html: f.html,
691
703
  impact: "critical",
692
- message: `Invalid value "${d}" for ${c.name}.`
704
+ message: `Invalid value "${u}" for ${c.name}.`
693
705
  });
694
706
  break;
695
707
  }
696
708
  }
697
709
  }
698
710
  }
699
- if (!p(r)) {
700
- const c = (n = r.getAttribute("role")) == null ? void 0 : n.trim().toLowerCase(), d = r.tagName.toLowerCase();
701
- if (!c && Ne[d]) {
702
- const g = r.hasAttribute("aria-label"), b = r.hasAttribute("aria-labelledby");
703
- if (g || b) {
711
+ if (!g(r)) {
712
+ const c = (n = r.getAttribute("role")) == null ? void 0 : n.trim().toLowerCase(), u = r.tagName.toLowerCase();
713
+ if (!c && Me[u]) {
714
+ const p = r.hasAttribute("aria-label"), b = r.hasAttribute("aria-labelledby");
715
+ if (p || b) {
704
716
  const f = h();
705
717
  i.push({
706
718
  ruleId: "aria-prohibited-attr",
707
719
  selector: f.selector,
708
720
  html: f.html,
709
721
  impact: "serious",
710
- message: `aria-label and aria-labelledby are prohibited on <${d}> elements.`
722
+ message: `aria-label and aria-labelledby are prohibited on <${u}> elements.`
711
723
  });
712
724
  }
713
725
  } else if (c) {
714
- if (K.has(c)) {
726
+ if (J.has(c)) {
715
727
  const b = r.hasAttribute("aria-label"), f = r.hasAttribute("aria-labelledby");
716
728
  if (b || f) {
717
729
  const y = h();
@@ -724,11 +736,11 @@ function z(t) {
724
736
  });
725
737
  }
726
738
  }
727
- const g = $e[c];
728
- if (g) {
739
+ const p = He[c];
740
+ if (p) {
729
741
  for (const b of r.attributes)
730
- if (b.name.startsWith("aria-") && g.has(b.name)) {
731
- if ((b.name === "aria-label" || b.name === "aria-labelledby") && K.has(c))
742
+ if (b.name.startsWith("aria-") && p.has(b.name)) {
743
+ if ((b.name === "aria-label" || b.name === "aria-labelledby") && J.has(c))
732
744
  continue;
733
745
  const f = h();
734
746
  i.push({
@@ -743,28 +755,28 @@ function z(t) {
743
755
  }
744
756
  }
745
757
  }
746
- return E = new WeakRef(t), C = { validAttr: a, validAttrValue: e, prohibitedAttr: i }, C;
758
+ return C = new WeakRef(t), L = { validAttr: a, validAttrValue: e, prohibitedAttr: i }, L;
747
759
  }
748
- let _ = /* @__PURE__ */ new WeakMap(), P = /* @__PURE__ */ new WeakMap(), j = /* @__PURE__ */ new WeakMap();
749
- function He() {
750
- _ = /* @__PURE__ */ new WeakMap(), P = /* @__PURE__ */ new WeakMap(), j = /* @__PURE__ */ new WeakMap();
760
+ let P = /* @__PURE__ */ new WeakMap(), j = /* @__PURE__ */ new WeakMap(), V = /* @__PURE__ */ new WeakMap();
761
+ function Oe() {
762
+ P = /* @__PURE__ */ new WeakMap(), j = /* @__PURE__ */ new WeakMap(), V = /* @__PURE__ */ new WeakMap();
751
763
  }
752
- function A(t) {
753
- let a = _.get(t);
754
- return a || (a = getComputedStyle(t), _.set(t, a), a);
764
+ function w(t) {
765
+ let a = P.get(t);
766
+ return a || (a = getComputedStyle(t), P.set(t, a), a);
755
767
  }
756
- function q(t, a, e) {
768
+ function R(t, a, e) {
757
769
  const [i, n, r] = [t, a, e].map((o) => {
758
770
  const s = o / 255;
759
771
  return s <= 0.04045 ? s / 12.92 : Math.pow((s + 0.055) / 1.055, 2.4);
760
772
  });
761
773
  return 0.2126 * i + 0.7152 * n + 0.0722 * r;
762
774
  }
763
- function de(t, a) {
775
+ function me(t, a) {
764
776
  const e = Math.max(t, a), i = Math.min(t, a);
765
777
  return (e + 0.05) / (i + 0.05);
766
778
  }
767
- const J = {
779
+ const Q = {
768
780
  black: [0, 0, 0],
769
781
  white: [255, 255, 255],
770
782
  red: [255, 0, 0],
@@ -784,9 +796,9 @@ const J = {
784
796
  lime: [0, 255, 0],
785
797
  olive: [128, 128, 0]
786
798
  };
787
- function R(t) {
799
+ function N(t) {
788
800
  const a = t.trim().toLowerCase();
789
- if (J[a]) return J[a];
801
+ if (Q[a]) return Q[a];
790
802
  const e = a.match(/^#([0-9a-f])([0-9a-f])([0-9a-f])$/);
791
803
  if (e)
792
804
  return [parseInt(e[1] + e[1], 16), parseInt(e[2] + e[2], 16), parseInt(e[3] + e[3], 16)];
@@ -803,16 +815,16 @@ function R(t) {
803
815
  );
804
816
  return r ? [parseInt(r[1]), parseInt(r[2]), parseInt(r[3])] : null;
805
817
  }
806
- function De(t) {
807
- const a = P.get(t);
818
+ function Be(t) {
819
+ const a = j.get(t);
808
820
  if (a !== void 0) return a;
809
- const e = Oe(t);
810
- return P.set(t, e), e;
821
+ const e = Fe(t);
822
+ return j.set(t, e), e;
811
823
  }
812
- function Oe(t) {
824
+ function Fe(t) {
813
825
  let a = t;
814
826
  for (; a; ) {
815
- const e = A(a), i = e.backgroundImage;
827
+ const e = w(a), i = e.backgroundImage;
816
828
  if (i && i !== "none" && i !== "initial") return null;
817
829
  const n = e.backgroundColor;
818
830
  if (n === "transparent" || n === "rgba(0, 0, 0, 0)" || n === "rgba(0 0 0 / 0)") {
@@ -824,26 +836,26 @@ function Oe(t) {
824
836
  a = a.parentElement;
825
837
  continue;
826
838
  }
827
- return R(n);
839
+ return N(n);
828
840
  }
829
841
  return [255, 255, 255];
830
842
  }
831
- const Fe = /* @__PURE__ */ new Set(["IMG", "PICTURE", "VIDEO", "SVG"]);
832
- function Be(t) {
833
- const a = j.get(t);
843
+ const We = /* @__PURE__ */ new Set(["IMG", "PICTURE", "VIDEO", "SVG"]);
844
+ function _e(t) {
845
+ const a = V.get(t);
834
846
  if (a !== void 0) return a;
835
- const e = We(t);
836
- return j.set(t, e), e;
847
+ const e = Pe(t);
848
+ return V.set(t, e), e;
837
849
  }
838
- function We(t) {
850
+ function Pe(t) {
839
851
  let a = t, e = !1;
840
852
  for (; a; ) {
841
- const i = A(a).position;
853
+ const i = w(a).position;
842
854
  if ((i === "absolute" || i === "fixed") && (e = !0), a !== t && i !== "static") {
843
855
  for (const n of a.children)
844
- if (!(n === t || n.contains(t)) && Fe.has(n.tagName)) {
856
+ if (!(n === t || n.contains(t)) && We.has(n.tagName)) {
845
857
  if (e) return !0;
846
- const r = A(n).position;
858
+ const r = w(n).position;
847
859
  if (r === "absolute" || r === "fixed") return !0;
848
860
  }
849
861
  if (e) break;
@@ -852,15 +864,15 @@ function We(t) {
852
864
  }
853
865
  return !1;
854
866
  }
855
- function _e(t) {
867
+ function je(t) {
856
868
  const a = parseFloat(t);
857
869
  return t.endsWith("pt") ? a * (4 / 3) : a;
858
870
  }
859
- function Pe(t) {
860
- const a = A(t), e = _e(a.fontSize), i = parseInt(a.fontWeight) || (a.fontWeight === "bold" ? 700 : 400);
871
+ function Ve(t) {
872
+ const a = w(t), e = je(a.fontSize), i = parseInt(a.fontWeight) || (a.fontWeight === "bold" ? 700 : 400);
861
873
  return e >= 23.5 || e >= 18.5 && i >= 700;
862
874
  }
863
- function H(t) {
875
+ function D(t) {
864
876
  var r, o;
865
877
  const a = [], e = t.closest("a");
866
878
  if (e) {
@@ -880,7 +892,7 @@ function H(t) {
880
892
  return a.length > 0 ? a.join(`
881
893
  `) : void 0;
882
894
  }
883
- function Q(t) {
895
+ function Z(t) {
884
896
  let a = t;
885
897
  for (; a; ) {
886
898
  if (a instanceof HTMLElement && a.style.visibility === "hidden") return !0;
@@ -888,7 +900,7 @@ function Q(t) {
888
900
  }
889
901
  return !1;
890
902
  }
891
- const je = {
903
+ const ze = {
892
904
  id: "img-alt",
893
905
  wcag: ["1.1.1"],
894
906
  level: "A",
@@ -898,7 +910,7 @@ const je = {
898
910
  run(t) {
899
911
  const a = [];
900
912
  for (const e of t.querySelectorAll("img")) {
901
- if (p(e) || Q(e)) continue;
913
+ if (g(e) || Z(e)) continue;
902
914
  const i = e.getAttribute("role");
903
915
  if (i === "presentation" || i === "none") {
904
916
  const r = e.getAttribute("tabindex");
@@ -909,41 +921,41 @@ const je = {
909
921
  a.push({
910
922
  ruleId: "img-alt",
911
923
  selector: m(e),
912
- html: u(e),
924
+ html: d(e),
913
925
  impact: "critical",
914
926
  message: 'Image has whitespace-only alt text. Use alt="" for decorative images or provide descriptive text.',
915
- context: H(e)
927
+ context: D(e)
916
928
  });
917
929
  continue;
918
930
  }
919
931
  !e.hasAttribute("alt") && !v(e) && a.push({
920
932
  ruleId: "img-alt",
921
933
  selector: m(e),
922
- html: u(e),
934
+ html: d(e),
923
935
  impact: "critical",
924
936
  message: "Image element missing alt attribute.",
925
- context: H(e)
937
+ context: D(e)
926
938
  });
927
939
  }
928
940
  for (const e of t.querySelectorAll('[role="img"]:not(img):not(svg)'))
929
- p(e) || Q(e) || v(e) || a.push({
941
+ g(e) || Z(e) || v(e) || a.push({
930
942
  ruleId: "img-alt",
931
943
  selector: m(e),
932
- html: u(e),
944
+ html: d(e),
933
945
  impact: "critical",
934
946
  message: 'Element with role="img" has no accessible name. Add aria-label or aria-labelledby.',
935
- context: H(e)
947
+ context: D(e)
936
948
  });
937
949
  return a;
938
950
  }
939
951
  };
940
- function Ve(t) {
952
+ function Ue(t) {
941
953
  var r, o, s;
942
954
  const a = t.getAttribute("aria-labelledby");
943
955
  if (a) {
944
956
  const l = a.split(/\s+/).map((h) => {
945
- var c, d;
946
- return ((d = (c = t.ownerDocument.getElementById(h)) == null ? void 0 : c.textContent) == null ? void 0 : d.trim()) ?? "";
957
+ var c, u;
958
+ return ((u = (c = t.ownerDocument.getElementById(h)) == null ? void 0 : c.textContent) == null ? void 0 : u.trim()) ?? "";
947
959
  }).filter(Boolean);
948
960
  if (l.length) return l.join(" ");
949
961
  }
@@ -954,7 +966,7 @@ function Ve(t) {
954
966
  const n = (s = t.getAttribute("title")) == null ? void 0 : s.trim();
955
967
  return n || "";
956
968
  }
957
- const ze = {
969
+ const Ge = {
958
970
  id: "svg-img-alt",
959
971
  wcag: ["1.1.1"],
960
972
  level: "A",
@@ -964,13 +976,13 @@ const ze = {
964
976
  run(t) {
965
977
  const a = [], e = 'svg[role="img"], [role="graphics-document"], [role="graphics-symbol"]';
966
978
  for (const i of t.querySelectorAll(e)) {
967
- if (p(i)) continue;
968
- if (!Ve(i)) {
979
+ if (g(i)) continue;
980
+ if (!Ue(i)) {
969
981
  const r = i.getAttribute("role");
970
982
  a.push({
971
983
  ruleId: "svg-img-alt",
972
984
  selector: m(i),
973
- html: u(i),
985
+ html: d(i),
974
986
  impact: "serious",
975
987
  message: `${i.tagName.toLowerCase()} with role='${r}' has no accessible name.`
976
988
  });
@@ -978,7 +990,7 @@ const ze = {
978
990
  }
979
991
  return a;
980
992
  }
981
- }, Ue = {
993
+ }, Ye = {
982
994
  id: "input-image-alt",
983
995
  wcag: ["1.1.1", "4.1.2"],
984
996
  level: "A",
@@ -988,16 +1000,16 @@ const ze = {
988
1000
  run(t) {
989
1001
  const a = [];
990
1002
  for (const e of t.querySelectorAll('input[type="image"]'))
991
- p(e) || v(e) || a.push({
1003
+ g(e) || v(e) || a.push({
992
1004
  ruleId: "input-image-alt",
993
1005
  selector: m(e),
994
- html: u(e),
1006
+ html: d(e),
995
1007
  impact: "critical",
996
1008
  message: "Image input missing alt text."
997
1009
  });
998
1010
  return a;
999
1011
  }
1000
- }, Ge = {
1012
+ }, Xe = {
1001
1013
  id: "image-redundant-alt",
1002
1014
  wcag: [],
1003
1015
  level: "A",
@@ -1019,7 +1031,7 @@ const ze = {
1019
1031
  a.push({
1020
1032
  ruleId: "image-redundant-alt",
1021
1033
  selector: m(i),
1022
- html: u(i),
1034
+ html: d(i),
1023
1035
  impact: "minor",
1024
1036
  message: `Alt text "${i.getAttribute("alt")}" duplicates surrounding ${s} text.`,
1025
1037
  context: `Duplicated text: "${i.getAttribute("alt")}", parent element: <${s}>${l ? ` href="${l}"` : ""}`
@@ -1029,7 +1041,7 @@ const ze = {
1029
1041
  }
1030
1042
  return a;
1031
1043
  }
1032
- }, Xe = ["image", "picture", "photo", "graphic", "icon", "img"], Ye = {
1044
+ }, Ke = ["image", "picture", "photo", "graphic", "icon", "img"], Je = {
1033
1045
  id: "image-alt-redundant-words",
1034
1046
  wcag: [],
1035
1047
  level: "A",
@@ -1042,11 +1054,11 @@ const ze = {
1042
1054
  for (const e of t.querySelectorAll("img[alt]")) {
1043
1055
  const i = e.getAttribute("alt").toLowerCase();
1044
1056
  if (!i) continue;
1045
- const n = Xe.filter((r) => i.split(/\s+/).includes(r));
1057
+ const n = Ke.filter((r) => i.split(/\s+/).includes(r));
1046
1058
  n.length > 0 && a.push({
1047
1059
  ruleId: "image-alt-redundant-words",
1048
1060
  selector: m(e),
1049
- html: u(e),
1061
+ html: d(e),
1050
1062
  impact: "minor",
1051
1063
  message: `Alt text "${e.getAttribute("alt")}" contains redundant word(s): ${n.join(", ")}.`,
1052
1064
  context: `Current alt: "${e.getAttribute("alt")}", redundant word(s): ${n.join(", ")}`
@@ -1054,7 +1066,7 @@ const ze = {
1054
1066
  }
1055
1067
  return a;
1056
1068
  }
1057
- }, Ke = {
1069
+ }, Qe = {
1058
1070
  id: "area-alt",
1059
1071
  wcag: ["1.1.1", "4.1.2"],
1060
1072
  level: "A",
@@ -1064,11 +1076,11 @@ const ze = {
1064
1076
  run(t) {
1065
1077
  const a = [];
1066
1078
  for (const e of t.querySelectorAll("area[href]")) {
1067
- if (p(e)) continue;
1079
+ if (g(e)) continue;
1068
1080
  v(e) || a.push({
1069
1081
  ruleId: "area-alt",
1070
1082
  selector: m(e),
1071
- html: u(e),
1083
+ html: d(e),
1072
1084
  impact: "critical",
1073
1085
  message: "Image map <area> element is missing alternative text."
1074
1086
  });
@@ -1076,7 +1088,7 @@ const ze = {
1076
1088
  return a;
1077
1089
  }
1078
1090
  };
1079
- function Je(t) {
1091
+ function Ze(t) {
1080
1092
  var n, r;
1081
1093
  const a = t.getAttribute("aria-labelledby");
1082
1094
  if (a) {
@@ -1091,7 +1103,7 @@ function Je(t) {
1091
1103
  const i = (r = t.getAttribute("title")) == null ? void 0 : r.trim();
1092
1104
  return i || "";
1093
1105
  }
1094
- const Qe = {
1106
+ const et = {
1095
1107
  id: "object-alt",
1096
1108
  wcag: ["1.1.1"],
1097
1109
  level: "A",
@@ -1102,7 +1114,7 @@ const Qe = {
1102
1114
  var e;
1103
1115
  const a = [];
1104
1116
  for (const i of t.querySelectorAll("object")) {
1105
- if (p(i) || i instanceof HTMLElement && i.style.visibility === "hidden") continue;
1117
+ if (g(i) || i instanceof HTMLElement && i.style.visibility === "hidden") continue;
1106
1118
  let n = i.parentElement, r = !1;
1107
1119
  for (; n; ) {
1108
1120
  if (n instanceof HTMLElement && n.style.visibility === "hidden") {
@@ -1111,7 +1123,7 @@ const Qe = {
1111
1123
  }
1112
1124
  n = n.parentElement;
1113
1125
  }
1114
- if (r || i.getAttribute("role") === "presentation" || i.getAttribute("role") === "none" || Je(i)) continue;
1126
+ if (r || i.getAttribute("role") === "presentation" || i.getAttribute("role") === "none" || Ze(i)) continue;
1115
1127
  const o = i.getAttribute("data") || "";
1116
1128
  if (!((i.getAttribute("type") || "").startsWith("image/") || /\.(png|jpg|jpeg|gif|svg|webp|bmp|ico)$/i.test(o))) {
1117
1129
  const h = i.querySelector("img[alt]");
@@ -1120,14 +1132,14 @@ const Qe = {
1120
1132
  a.push({
1121
1133
  ruleId: "object-alt",
1122
1134
  selector: m(i),
1123
- html: u(i),
1135
+ html: d(i),
1124
1136
  impact: "serious",
1125
1137
  message: "<object> element is missing alternative text. Add aria-label, aria-labelledby, or a title attribute."
1126
1138
  });
1127
1139
  }
1128
1140
  return a;
1129
1141
  }
1130
- }, Ze = {
1142
+ }, tt = {
1131
1143
  id: "role-img-alt",
1132
1144
  wcag: ["1.1.1"],
1133
1145
  level: "A",
@@ -1137,11 +1149,11 @@ const Qe = {
1137
1149
  run(t) {
1138
1150
  const a = [];
1139
1151
  for (const e of t.querySelectorAll('[role="img"]')) {
1140
- if (p(e) || e.tagName.toLowerCase() === "svg" || e.tagName.toLowerCase() === "img") continue;
1152
+ if (g(e) || e.tagName.toLowerCase() === "svg" || e.tagName.toLowerCase() === "img") continue;
1141
1153
  v(e) || a.push({
1142
1154
  ruleId: "role-img-alt",
1143
1155
  selector: m(e),
1144
- html: u(e),
1156
+ html: d(e),
1145
1157
  impact: "serious",
1146
1158
  message: "Element with role='img' has no accessible name. Add aria-label or aria-labelledby."
1147
1159
  });
@@ -1149,7 +1161,7 @@ const Qe = {
1149
1161
  return a;
1150
1162
  }
1151
1163
  };
1152
- function Ai(t) {
1164
+ function Ei(t) {
1153
1165
  if (typeof t != "object" || t === null)
1154
1166
  return "Rule spec must be an object";
1155
1167
  const a = t;
@@ -1179,10 +1191,10 @@ function Ai(t) {
1179
1191
  return "Rule must have a wcag array";
1180
1192
  if (typeof a.level != "string" || !["A", "AA"].includes(a.level))
1181
1193
  return "Rule must have level A or AA";
1182
- const n = et(e);
1194
+ const n = at(e);
1183
1195
  return n || null;
1184
1196
  }
1185
- function et(t) {
1197
+ function at(t) {
1186
1198
  switch (t.type) {
1187
1199
  case "selector-exists":
1188
1200
  return null;
@@ -1219,112 +1231,118 @@ function k(t) {
1219
1231
  guidance: t.guidance,
1220
1232
  prompt: t.prompt,
1221
1233
  run(e) {
1234
+ var n, r;
1222
1235
  const i = [];
1223
1236
  switch (t.check.type) {
1224
1237
  case "selector-exists": {
1225
- for (const n of e.querySelectorAll(t.selector))
1226
- a && p(n) || i.push({
1238
+ for (const o of e.querySelectorAll(t.selector))
1239
+ a && g(o) || i.push({
1227
1240
  ruleId: t.id,
1228
- selector: m(n),
1229
- html: u(n),
1241
+ selector: m(o),
1242
+ html: d(o),
1230
1243
  impact: t.impact,
1231
- message: S(t.message, n, t.check),
1232
- element: n
1244
+ message: S(t.message, o, t.check),
1245
+ element: o
1233
1246
  });
1234
1247
  break;
1235
1248
  }
1236
1249
  case "attribute-value": {
1237
- const { attribute: n, operator: r, value: o } = t.check;
1238
- for (const s of e.querySelectorAll(t.selector)) {
1239
- if (a && p(s)) continue;
1240
- const l = s.getAttribute(n);
1241
- l !== null && tt(l, r, o) && i.push({
1250
+ const { attribute: o, operator: s, value: l } = t.check;
1251
+ for (const h of e.querySelectorAll(t.selector)) {
1252
+ if (a && g(h)) continue;
1253
+ const c = h.getAttribute(o);
1254
+ c !== null && it(c, s, l) && i.push({
1242
1255
  ruleId: t.id,
1243
- selector: m(s),
1244
- html: u(s),
1256
+ selector: m(h),
1257
+ html: d(h),
1245
1258
  impact: t.impact,
1246
- message: S(t.message, s, t.check),
1247
- element: s
1259
+ message: S(t.message, h, t.check),
1260
+ element: h
1248
1261
  });
1249
1262
  }
1250
1263
  break;
1251
1264
  }
1252
1265
  case "attribute-missing": {
1253
- const { attribute: n } = t.check;
1254
- for (const r of e.querySelectorAll(t.selector))
1255
- a && p(r) || r.hasAttribute(n) || i.push({
1266
+ const { attribute: o } = t.check;
1267
+ for (const s of e.querySelectorAll(t.selector))
1268
+ a && g(s) || s.hasAttribute(o) || i.push({
1256
1269
  ruleId: t.id,
1257
- selector: m(r),
1258
- html: u(r),
1270
+ selector: m(s),
1271
+ html: d(s),
1259
1272
  impact: t.impact,
1260
- message: S(t.message, r, t.check),
1261
- element: r
1273
+ message: S(t.message, s, t.check),
1274
+ element: s
1262
1275
  });
1263
1276
  break;
1264
1277
  }
1265
1278
  case "attribute-regex": {
1266
- const { attribute: n, pattern: r, flags: o, shouldMatch: s } = t.check;
1267
- let l;
1279
+ const { attribute: o, pattern: s, flags: l, shouldMatch: h } = t.check;
1280
+ let c;
1268
1281
  try {
1269
- l = new RegExp(r, o);
1282
+ c = new RegExp(s, l);
1270
1283
  } catch {
1271
1284
  break;
1272
1285
  }
1273
- for (const h of e.querySelectorAll(t.selector)) {
1274
- if (a && p(h)) continue;
1275
- const c = h.getAttribute(n);
1276
- if (c === null) continue;
1277
- const d = l.test(c);
1278
- s && !d ? i.push({
1286
+ for (const u of e.querySelectorAll(t.selector)) {
1287
+ if (a && g(u)) continue;
1288
+ const p = u.getAttribute(o);
1289
+ if (p === null) continue;
1290
+ const b = c.test(p);
1291
+ h && !b ? i.push({
1279
1292
  ruleId: t.id,
1280
- selector: m(h),
1281
- html: u(h),
1293
+ selector: m(u),
1294
+ html: d(u),
1282
1295
  impact: t.impact,
1283
- message: S(t.message, h, t.check),
1284
- element: h
1285
- }) : !s && d && i.push({
1296
+ message: S(t.message, u, t.check),
1297
+ element: u
1298
+ }) : !h && b && i.push({
1286
1299
  ruleId: t.id,
1287
- selector: m(h),
1288
- html: u(h),
1300
+ selector: m(u),
1301
+ html: d(u),
1289
1302
  impact: t.impact,
1290
- message: S(t.message, h, t.check),
1291
- element: h
1303
+ message: S(t.message, u, t.check),
1304
+ element: u
1292
1305
  });
1293
1306
  }
1294
1307
  break;
1295
1308
  }
1296
1309
  case "child-required": {
1297
- const { childSelector: n } = t.check;
1298
- for (const r of e.querySelectorAll(t.selector))
1299
- a && p(r) || r.querySelector(n) || i.push({
1310
+ const { childSelector: o } = t.check;
1311
+ for (const s of e.querySelectorAll(t.selector))
1312
+ a && g(s) || s.querySelector(o) || i.push({
1300
1313
  ruleId: t.id,
1301
- selector: m(r),
1302
- html: u(r),
1314
+ selector: m(s),
1315
+ html: d(s),
1303
1316
  impact: t.impact,
1304
- message: S(t.message, r, t.check),
1305
- element: r
1317
+ message: S(t.message, s, t.check),
1318
+ element: s
1306
1319
  });
1307
1320
  break;
1308
1321
  }
1309
1322
  case "child-invalid": {
1310
- const n = new Set(
1311
- t.check.allowedChildren.map((r) => r.toLowerCase())
1312
- );
1313
- for (const r of e.querySelectorAll(t.selector))
1314
- if (!(a && p(r))) {
1315
- for (const o of r.children)
1316
- if (!n.has(o.tagName.toLowerCase())) {
1323
+ const o = new Set(
1324
+ t.check.allowedChildren.map((l) => l.toLowerCase())
1325
+ ), s = t.check.allowedChildRoles ? new Set(t.check.allowedChildRoles.map((l) => l.toLowerCase())) : null;
1326
+ for (const l of e.querySelectorAll(t.selector)) {
1327
+ if (a && g(l)) continue;
1328
+ const h = (n = l.getAttribute("role")) == null ? void 0 : n.trim().toLowerCase();
1329
+ if (!(h === "presentation" || h === "none"))
1330
+ for (const c of l.children) {
1331
+ if (o.has(c.tagName.toLowerCase())) continue;
1332
+ const u = (r = c.getAttribute("role")) == null ? void 0 : r.trim().toLowerCase();
1333
+ if (!(u && (s != null && s.has(u))) && !(u === "presentation" || u === "none")) {
1317
1334
  i.push({
1318
1335
  ruleId: t.id,
1319
- selector: m(o),
1320
- html: u(o),
1336
+ selector: m(c),
1337
+ html: d(c),
1321
1338
  impact: t.impact,
1322
- message: S(t.message, o, t.check),
1323
- element: o
1339
+ message: S(t.message, c, t.check),
1340
+ element: c
1324
1341
  });
1325
1342
  break;
1326
1343
  }
1327
- }
1344
+ }
1345
+ }
1328
1346
  break;
1329
1347
  }
1330
1348
  }
@@ -1332,7 +1350,7 @@ function k(t) {
1332
1350
  }
1333
1351
  };
1334
1352
  }
1335
- function tt(t, a, e) {
1353
+ function it(t, a, e) {
1336
1354
  switch (a) {
1337
1355
  case ">":
1338
1356
  return parseFloat(t) > e;
@@ -1350,7 +1368,7 @@ function tt(t, a, e) {
1350
1368
  return !1;
1351
1369
  }
1352
1370
  }
1353
- const at = {
1371
+ const nt = {
1354
1372
  id: "server-side-image-map",
1355
1373
  selector: "img[ismap], input[type='image'][ismap]",
1356
1374
  check: { type: "selector-exists" },
@@ -1361,7 +1379,7 @@ const at = {
1361
1379
  level: "A",
1362
1380
  guidance: "Server-side image maps (using ismap attribute) send click coordinates to the server, which is inaccessible to keyboard users and screen readers who can't precisely click specific regions. Replace with client-side image maps (<map> with <area> elements) that provide keyboard access and accessible names, or use linked images/buttons instead.",
1363
1381
  prompt: "Explain that the ismap attribute should be removed and the functionality replaced with a client-side <map> element with <area> children, or separate linked images/buttons."
1364
- }, it = k(at), nt = [
1382
+ }, rt = k(nt), ot = [
1365
1383
  '[role="checkbox"]',
1366
1384
  '[role="combobox"]',
1367
1385
  '[role="listbox"]',
@@ -1373,13 +1391,13 @@ const at = {
1373
1391
  '[role="spinbutton"]',
1374
1392
  '[role="switch"]',
1375
1393
  '[role="textbox"]'
1376
- ].join(", "), rt = /* @__PURE__ */ new Set([
1394
+ ].join(", "), st = /* @__PURE__ */ new Set([
1377
1395
  "checkbox",
1378
1396
  "menuitemcheckbox",
1379
1397
  "menuitemradio",
1380
1398
  "radio",
1381
1399
  "switch"
1382
- ]), ot = /* @__PURE__ */ new Set([
1400
+ ]), lt = /* @__PURE__ */ new Set([
1383
1401
  "combobox",
1384
1402
  "listbox",
1385
1403
  "searchbox",
@@ -1387,16 +1405,16 @@ const at = {
1387
1405
  "spinbutton",
1388
1406
  "textbox"
1389
1407
  ]);
1390
- function st(t) {
1408
+ function ct(t) {
1391
1409
  var o, s, l, h;
1392
1410
  const a = (o = t.getAttribute("role")) == null ? void 0 : o.trim().toLowerCase();
1393
- if (a && rt.has(a) || (t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement) && !(a && ot.has(a)))
1411
+ if (a && st.has(a) || (t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement) && !(a && lt.has(a)))
1394
1412
  return v(t);
1395
1413
  const i = t.getAttribute("aria-labelledby");
1396
1414
  if (i) {
1397
- const c = i.split(/\s+/).map((d) => {
1398
- const g = t.ownerDocument.getElementById(d);
1399
- return g ? w(g).trim() : "";
1415
+ const c = i.split(/\s+/).map((u) => {
1416
+ const p = t.ownerDocument.getElementById(u);
1417
+ return p ? A(p).trim() : "";
1400
1418
  }).filter(Boolean);
1401
1419
  if (c.length) return c.join(" ");
1402
1420
  }
@@ -1404,16 +1422,16 @@ function st(t) {
1404
1422
  if (n) return n;
1405
1423
  if (t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement || t instanceof HTMLSelectElement) {
1406
1424
  if (t.id) {
1407
- const d = t.ownerDocument.querySelector(`label[for="${CSS.escape(t.id)}"]`);
1408
- if (d) {
1409
- const g = w(d).trim();
1410
- if (g) return g;
1425
+ const u = t.ownerDocument.querySelector(`label[for="${CSS.escape(t.id)}"]`);
1426
+ if (u) {
1427
+ const p = A(u).trim();
1428
+ if (p) return p;
1411
1429
  }
1412
1430
  }
1413
1431
  const c = t.closest("label");
1414
1432
  if (c) {
1415
- const d = w(c).trim();
1416
- if (d) return d;
1433
+ const u = A(c).trim();
1434
+ if (u) return u;
1417
1435
  }
1418
1436
  }
1419
1437
  const r = (l = t.getAttribute("title")) == null ? void 0 : l.trim();
@@ -1424,7 +1442,7 @@ function st(t) {
1424
1442
  }
1425
1443
  return "";
1426
1444
  }
1427
- const lt = {
1445
+ const ut = {
1428
1446
  id: "label",
1429
1447
  wcag: ["4.1.2"],
1430
1448
  level: "A",
@@ -1433,23 +1451,23 @@ const lt = {
1433
1451
  prompt: `This form field has no accessible label. Based on the context (input type, name attribute, placeholder, or surrounding elements), suggest adding a <label for="id"> element with descriptive text, or an aria-label attribute. The label should describe what information the user should enter, not the field type. For example: 'Email address', 'Search', 'Phone number'.`,
1434
1452
  run(t) {
1435
1453
  var n;
1436
- const a = [], i = t.querySelectorAll(`input:not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="image"]), textarea, select, ${nt}`);
1454
+ const a = [], i = t.querySelectorAll(`input:not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="image"]), textarea, select, ${ot}`);
1437
1455
  for (const r of i) {
1438
- if (p(r) || r instanceof HTMLElement && (r.hidden || r.style.display === "none")) continue;
1456
+ if (g(r) || T(r) || (r instanceof HTMLInputElement || r instanceof HTMLTextAreaElement || r instanceof HTMLSelectElement || r instanceof HTMLButtonElement) && r.disabled || r.closest("fieldset[disabled]") || r.getAttribute("aria-disabled") === "true") continue;
1439
1457
  const o = (n = r.getAttribute("role")) == null ? void 0 : n.trim().toLowerCase();
1440
1458
  if (o === "presentation" || o === "none") continue;
1441
- if (!st(r)) {
1459
+ if (!ct(r)) {
1442
1460
  const l = [], h = r.tagName.toLowerCase(), c = r.getAttribute("type");
1443
1461
  c && h === "input" && l.push(`type: ${c}`);
1444
- const d = r.getAttribute("name");
1445
- d && l.push(`name: "${d}"`);
1446
- const g = r.getAttribute("placeholder");
1447
- g && l.push(`placeholder: "${g}"`), o && l.push(`role: ${o}`);
1462
+ const u = r.getAttribute("name");
1463
+ u && l.push(`name: "${u}"`);
1464
+ const p = r.getAttribute("placeholder");
1465
+ p && l.push(`placeholder: "${p}"`), o && l.push(`role: ${o}`);
1448
1466
  const b = r.getAttribute("id");
1449
1467
  b && l.push(`id: "${b}"`), a.push({
1450
1468
  ruleId: "label",
1451
1469
  selector: m(r),
1452
- html: u(r),
1470
+ html: d(r),
1453
1471
  impact: "critical",
1454
1472
  message: "Form element has no accessible label.",
1455
1473
  context: l.length > 0 ? l.join(", ") : void 0
@@ -1458,7 +1476,7 @@ const lt = {
1458
1476
  }
1459
1477
  return a;
1460
1478
  }
1461
- }, ct = {
1479
+ }, dt = {
1462
1480
  id: "form-field-multiple-labels",
1463
1481
  wcag: [],
1464
1482
  level: "A",
@@ -1469,7 +1487,7 @@ const lt = {
1469
1487
  run(t) {
1470
1488
  const a = [], e = t.querySelectorAll('input:not([type="hidden"]), textarea, select');
1471
1489
  for (const i of e) {
1472
- if (p(i) || !i.id) continue;
1490
+ if (g(i) || !i.id) continue;
1473
1491
  const n = t.querySelectorAll(`label[for="${CSS.escape(i.id)}"]`);
1474
1492
  let r = 0, o = i.parentElement;
1475
1493
  for (; o; ) {
@@ -1483,14 +1501,14 @@ const lt = {
1483
1501
  s > 1 && a.push({
1484
1502
  ruleId: "form-field-multiple-labels",
1485
1503
  selector: m(i),
1486
- html: u(i),
1504
+ html: d(i),
1487
1505
  impact: "moderate",
1488
1506
  message: `Form field has ${s} labels. Use a single label element.`
1489
1507
  });
1490
1508
  }
1491
1509
  return a;
1492
1510
  }
1493
- }, ut = {
1511
+ }, mt = {
1494
1512
  id: "select-name",
1495
1513
  wcag: ["4.1.2"],
1496
1514
  level: "A",
@@ -1500,16 +1518,16 @@ const lt = {
1500
1518
  run(t) {
1501
1519
  const a = [];
1502
1520
  for (const e of t.querySelectorAll("select"))
1503
- p(e) || v(e) || a.push({
1521
+ g(e) || v(e) || a.push({
1504
1522
  ruleId: "select-name",
1505
1523
  selector: m(e),
1506
- html: u(e),
1524
+ html: d(e),
1507
1525
  impact: "critical",
1508
1526
  message: "Select element has no accessible name."
1509
1527
  });
1510
1528
  return a;
1511
1529
  }
1512
- }, dt = {
1530
+ }, ht = {
1513
1531
  id: "input-button-name",
1514
1532
  wcag: ["4.1.2"],
1515
1533
  level: "A",
@@ -1522,19 +1540,19 @@ const lt = {
1522
1540
  for (const n of t.querySelectorAll(
1523
1541
  'input[type="submit"], input[type="button"], input[type="reset"]'
1524
1542
  )) {
1525
- if (p(n)) continue;
1543
+ if (g(n)) continue;
1526
1544
  const r = (e = n.getAttribute("value")) == null ? void 0 : e.trim(), o = (i = n.getAttribute("type")) == null ? void 0 : i.toLowerCase(), s = (o === "submit" || o === "reset") && !n.hasAttribute("value");
1527
1545
  !r && !s && !v(n) && a.push({
1528
1546
  ruleId: "input-button-name",
1529
1547
  selector: m(n),
1530
- html: u(n),
1548
+ html: d(n),
1531
1549
  impact: "critical",
1532
1550
  message: "Input button has no discernible text."
1533
1551
  });
1534
1552
  }
1535
1553
  return a;
1536
1554
  }
1537
- }, mt = /* @__PURE__ */ new Set([
1555
+ }, pt = /* @__PURE__ */ new Set([
1538
1556
  "off",
1539
1557
  "on",
1540
1558
  "name",
@@ -1589,7 +1607,7 @@ const lt = {
1589
1607
  "impp",
1590
1608
  "url",
1591
1609
  "photo"
1592
- ]), ht = /* @__PURE__ */ new Set([
1610
+ ]), gt = /* @__PURE__ */ new Set([
1593
1611
  "tel",
1594
1612
  "tel-country-code",
1595
1613
  "tel-national",
@@ -1598,18 +1616,18 @@ const lt = {
1598
1616
  "tel-extension",
1599
1617
  "email",
1600
1618
  "impp"
1601
- ]), pt = /* @__PURE__ */ new Set(["home", "work", "mobile", "fax", "pager"]), gt = /* @__PURE__ */ new Set(["shipping", "billing"]), bt = /* @__PURE__ */ new Set(["webauthn"]);
1602
- function ft(t) {
1619
+ ]), bt = /* @__PURE__ */ new Set(["home", "work", "mobile", "fax", "pager"]), ft = /* @__PURE__ */ new Set(["shipping", "billing"]), vt = /* @__PURE__ */ new Set(["webauthn"]);
1620
+ function yt(t) {
1603
1621
  const a = t.toLowerCase().split(/\s+/).filter(Boolean);
1604
1622
  if (a.length === 0) return !0;
1605
1623
  let e = 0;
1606
- a[e].startsWith("section-") && e++, e < a.length && gt.has(a[e]) && e++;
1624
+ a[e].startsWith("section-") && e++, e < a.length && ft.has(a[e]) && e++;
1607
1625
  let i = !1;
1608
- if (e < a.length && pt.has(a[e]) && (i = !0, e++), e >= a.length) return !1;
1626
+ if (e < a.length && bt.has(a[e]) && (i = !0, e++), e >= a.length) return !1;
1609
1627
  const n = a[e];
1610
- return !mt.has(n) || i && !ht.has(n) ? !1 : (e++, e < a.length && bt.has(a[e]) && e++, e === a.length);
1628
+ return !pt.has(n) || i && !gt.has(n) ? !1 : (e++, e < a.length && vt.has(a[e]) && e++, e === a.length);
1611
1629
  }
1612
- const vt = {
1630
+ const wt = {
1613
1631
  id: "autocomplete-valid",
1614
1632
  wcag: ["1.3.5"],
1615
1633
  level: "AA",
@@ -1619,12 +1637,12 @@ const vt = {
1619
1637
  run(t) {
1620
1638
  const a = [];
1621
1639
  for (const e of t.querySelectorAll("[autocomplete]")) {
1622
- if (p(e) || e instanceof HTMLElement && e.style.display === "none" || e.disabled || e.getAttribute("aria-disabled") === "true") continue;
1640
+ if (g(e) || e instanceof HTMLElement && e.style.display === "none" || e.disabled || e.getAttribute("aria-disabled") === "true") continue;
1623
1641
  const i = e.getAttribute("autocomplete").trim();
1624
- i && (ft(i) || a.push({
1642
+ i && (yt(i) || a.push({
1625
1643
  ruleId: "autocomplete-valid",
1626
1644
  selector: m(e),
1627
- html: u(e),
1645
+ html: d(e),
1628
1646
  impact: "serious",
1629
1647
  message: `Invalid autocomplete value "${i}".`
1630
1648
  }));
@@ -1632,16 +1650,16 @@ const vt = {
1632
1650
  return a;
1633
1651
  }
1634
1652
  };
1635
- function Z(t) {
1653
+ function ee(t) {
1636
1654
  return t.toLowerCase().replace(/\s+/g, " ").trim();
1637
1655
  }
1638
- function ee(t, a) {
1639
- const e = Z(t), i = Z(a);
1656
+ function te(t, a) {
1657
+ const e = ee(t), i = ee(a);
1640
1658
  if (!e || !i || e.includes(i) || i.includes(e)) return !0;
1641
1659
  const n = i.split(/\s+/).map((r) => r.replace(/[.,;:!?\u2026]+$/g, "")).filter((r) => r.length > 2);
1642
1660
  return n.length >= 2 && n.filter((o) => e.includes(o)).length / n.length > 0.5;
1643
1661
  }
1644
- function V(t) {
1662
+ function z(t) {
1645
1663
  let a = "";
1646
1664
  for (const e of t.childNodes)
1647
1665
  if (e.nodeType === 3)
@@ -1651,57 +1669,58 @@ function V(t) {
1651
1669
  if (n === "style" || n === "script" || n === "svg" || i.getAttribute("aria-hidden") === "true" || i instanceof HTMLElement && i.style.display === "none") continue;
1652
1670
  const r = i.getAttribute("role");
1653
1671
  if (r === "img" || r === "presentation" || r === "none") continue;
1654
- a += V(i);
1672
+ a += z(i);
1655
1673
  }
1656
1674
  return a;
1657
1675
  }
1658
- const yt = {
1676
+ const At = {
1659
1677
  id: "label-content-name-mismatch",
1660
- wcag: ["2.5.3"],
1678
+ wcag: [],
1661
1679
  level: "A",
1680
+ tags: ["best-practice"],
1662
1681
  description: "Interactive elements with visible text must have accessible names that contain that text.",
1663
1682
  guidance: "For voice control users who activate controls by speaking their visible label, the accessible name must include the visible text. If aria-label is 'Submit form' but the button shows 'Send', voice users saying 'click Send' won't activate it. Ensure aria-label/aria-labelledby contains or matches the visible text.",
1664
1683
  prompt: "Show the mismatch between the visible text and accessible name, and suggest updating aria-label to include the visible text.",
1665
1684
  run(t) {
1666
1685
  const a = [];
1667
1686
  for (const e of t.querySelectorAll('button, [role="button"], a[href], input[type="submit"], input[type="button"]')) {
1668
- if (p(e)) continue;
1687
+ if (g(e)) continue;
1669
1688
  const i = v(e);
1670
1689
  if (!i) continue;
1671
1690
  let n = "";
1672
- e instanceof HTMLInputElement ? n = e.value || "" : n = V(e);
1691
+ e instanceof HTMLInputElement ? n = e.value || "" : n = z(e);
1673
1692
  const r = n.trim();
1674
1693
  if (!r || r.length <= 2) continue;
1675
1694
  const o = e.hasAttribute("aria-label"), s = e.hasAttribute("aria-labelledby");
1676
- !o && !s || ee(i, n) || a.push({
1695
+ !o && !s || te(i, n) || a.push({
1677
1696
  ruleId: "label-content-name-mismatch",
1678
1697
  selector: m(e),
1679
- html: u(e),
1698
+ html: d(e),
1680
1699
  impact: "serious",
1681
1700
  message: `Accessible name "${i}" does not contain visible text "${n.trim()}".`
1682
1701
  });
1683
1702
  }
1684
1703
  for (const e of t.querySelectorAll("input, select, textarea")) {
1685
- if (p(e) || e instanceof HTMLInputElement && ["hidden", "submit", "button", "image"].includes(e.type)) continue;
1704
+ if (g(e) || e instanceof HTMLInputElement && ["hidden", "submit", "button", "image"].includes(e.type)) continue;
1686
1705
  const i = v(e);
1687
1706
  if (!i || !e.hasAttribute("aria-label")) continue;
1688
1707
  const r = e.id;
1689
1708
  let o = "";
1690
1709
  if (r) {
1691
1710
  const s = t.querySelector(`label[for="${CSS.escape(r)}"]`);
1692
- s && (o = V(s));
1711
+ s && (o = z(s));
1693
1712
  }
1694
- o.trim() && (ee(i, o) || a.push({
1713
+ o.trim() && (te(i, o) || a.push({
1695
1714
  ruleId: "label-content-name-mismatch",
1696
1715
  selector: m(e),
1697
- html: u(e),
1716
+ html: d(e),
1698
1717
  impact: "serious",
1699
1718
  message: `Accessible name "${i}" does not contain visible label "${o.trim()}".`
1700
1719
  }));
1701
1720
  }
1702
1721
  return a;
1703
1722
  }
1704
- }, wt = {
1723
+ }, xt = {
1705
1724
  id: "label-title-only",
1706
1725
  wcag: [],
1707
1726
  level: "A",
@@ -1715,26 +1734,26 @@ const yt = {
1715
1734
  'input:not([type="hidden"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="image"]), textarea, select'
1716
1735
  );
1717
1736
  for (const s of e) {
1718
- if (p(s)) continue;
1737
+ if (g(s)) continue;
1719
1738
  const l = s.hasAttribute("title") && ((i = s.getAttribute("title")) == null ? void 0 : i.trim()), h = s.hasAttribute("aria-label") && ((n = s.getAttribute("aria-label")) == null ? void 0 : n.trim()), c = s.hasAttribute("aria-labelledby");
1720
- let d = !1;
1721
- const g = s.id;
1722
- if (g) {
1723
- const f = s.ownerDocument.querySelector(`label[for="${CSS.escape(g)}"]`);
1724
- (r = f == null ? void 0 : f.textContent) != null && r.trim() && (d = !0);
1739
+ let u = !1;
1740
+ const p = s.id;
1741
+ if (p) {
1742
+ const f = s.ownerDocument.querySelector(`label[for="${CSS.escape(p)}"]`);
1743
+ (r = f == null ? void 0 : f.textContent) != null && r.trim() && (u = !0);
1725
1744
  }
1726
1745
  const b = s.closest("label");
1727
- (o = b == null ? void 0 : b.textContent) != null && o.trim() && (d = !0), l && !h && !c && !d && a.push({
1746
+ (o = b == null ? void 0 : b.textContent) != null && o.trim() && (u = !0), l && !h && !c && !u && a.push({
1728
1747
  ruleId: "label-title-only",
1729
1748
  selector: m(s),
1730
- html: u(s),
1749
+ html: d(s),
1731
1750
  impact: "serious",
1732
1751
  message: "Form element uses title attribute as only label. Use <label>, aria-label, or aria-labelledby instead."
1733
1752
  });
1734
1753
  }
1735
1754
  return a;
1736
1755
  }
1737
- }, At = {
1756
+ }, St = {
1738
1757
  id: "tabindex",
1739
1758
  selector: "[tabindex]",
1740
1759
  check: { type: "attribute-value", attribute: "tabindex", operator: ">", value: 0 },
@@ -1746,7 +1765,7 @@ const yt = {
1746
1765
  tags: ["best-practice"],
1747
1766
  guidance: "Positive tabindex values force elements to the front of the tab order regardless of DOM position, creating unpredictable navigation for keyboard users. Use tabindex='0' to add elements to the natural tab order, or tabindex='-1' to make elements programmatically focusable but not in tab order. Rely on DOM order for tab sequence.",
1748
1767
  prompt: "Change the positive tabindex value to tabindex='0' and rely on DOM order for tab sequence instead."
1749
- }, xt = k(At), St = /* @__PURE__ */ new Set([
1768
+ }, kt = k(St), It = /* @__PURE__ */ new Set([
1750
1769
  "div",
1751
1770
  "span",
1752
1771
  "p",
@@ -1773,7 +1792,7 @@ const yt = {
1773
1792
  "tr",
1774
1793
  "td",
1775
1794
  "th"
1776
- ]), kt = {
1795
+ ]), Tt = {
1777
1796
  id: "focus-order-semantics",
1778
1797
  wcag: [],
1779
1798
  tags: ["best-practice"],
@@ -1785,18 +1804,18 @@ const yt = {
1785
1804
  const a = [];
1786
1805
  for (const e of t.querySelectorAll('[tabindex="0"]')) {
1787
1806
  const i = e.tagName.toLowerCase();
1788
- if (!St.has(i)) continue;
1807
+ if (!It.has(i)) continue;
1789
1808
  e.getAttribute("role") || a.push({
1790
1809
  ruleId: "focus-order-semantics",
1791
1810
  selector: m(e),
1792
- html: u(e),
1811
+ html: d(e),
1793
1812
  impact: "moderate",
1794
1813
  message: `Non-interactive <${i}> with tabindex="0" has no interactive role.`
1795
1814
  });
1796
1815
  }
1797
1816
  return a;
1798
1817
  }
1799
- }, It = /* @__PURE__ */ new Set([
1818
+ }, Et = /* @__PURE__ */ new Set([
1800
1819
  "a",
1801
1820
  "audio",
1802
1821
  "button",
@@ -1805,7 +1824,7 @@ const yt = {
1805
1824
  "select",
1806
1825
  "textarea",
1807
1826
  "video"
1808
- ]), Tt = /* @__PURE__ */ new Set([
1827
+ ]), Ct = /* @__PURE__ */ new Set([
1809
1828
  "button",
1810
1829
  "checkbox",
1811
1830
  "combobox",
@@ -1829,7 +1848,7 @@ const yt = {
1829
1848
  "tabpanel",
1830
1849
  "textbox",
1831
1850
  "treeitem"
1832
- ]), Et = {
1851
+ ]), Lt = {
1833
1852
  grid: /* @__PURE__ */ new Set(["gridcell", "row", "columnheader", "rowheader"]),
1834
1853
  listbox: /* @__PURE__ */ new Set(["option"]),
1835
1854
  menu: /* @__PURE__ */ new Set(["menuitem", "menuitemcheckbox", "menuitemradio"]),
@@ -1839,26 +1858,26 @@ const yt = {
1839
1858
  tree: /* @__PURE__ */ new Set(["treeitem"]),
1840
1859
  treegrid: /* @__PURE__ */ new Set(["gridcell", "row", "columnheader", "rowheader", "treeitem"])
1841
1860
  };
1842
- function Ct(t, a) {
1861
+ function qt(t, a) {
1843
1862
  var n, r, o;
1844
1863
  const e = (n = t.getAttribute("role")) == null ? void 0 : n.toLowerCase(), i = (r = a.getAttribute("role")) == null ? void 0 : r.toLowerCase();
1845
- return !e || !i ? !1 : ((o = Et[e]) == null ? void 0 : o.has(i)) ?? !1;
1864
+ return !e || !i ? !1 : ((o = Lt[e]) == null ? void 0 : o.has(i)) ?? !1;
1846
1865
  }
1847
- function Lt(t) {
1866
+ function Rt(t) {
1848
1867
  var n;
1849
1868
  const a = t.tagName.toLowerCase();
1850
- if (It.has(a))
1869
+ if (Et.has(a))
1851
1870
  return a === "a" && !t.hasAttribute("href") ? !1 : a === "audio" || a === "video" ? t.hasAttribute("controls") : !(a === "img" && !t.hasAttribute("usemap") || a === "input" && t.type === "hidden" || t.disabled);
1852
1871
  const e = (n = t.getAttribute("role")) == null ? void 0 : n.toLowerCase();
1853
- if (e && Tt.has(e)) return !0;
1872
+ if (e && Ct.has(e)) return !0;
1854
1873
  const i = t.getAttribute("tabindex");
1855
1874
  return i !== null && i !== "-1" || t.getAttribute("contenteditable") === "true";
1856
1875
  }
1857
- function qt(t) {
1876
+ function Nt(t) {
1858
1877
  const a = t.tagName.toLowerCase();
1859
1878
  return !!(a === "a" && t.hasAttribute("href") || a === "button" && !t.disabled);
1860
1879
  }
1861
- const Rt = {
1880
+ const $t = {
1862
1881
  id: "nested-interactive",
1863
1882
  wcag: ["4.1.2"],
1864
1883
  level: "A",
@@ -1873,24 +1892,24 @@ const Rt = {
1873
1892
  for (; o; ) {
1874
1893
  for (; r.length > 0 && !r[r.length - 1].contains(o); )
1875
1894
  r.pop();
1876
- if (!p(o) && Lt(o)) {
1895
+ if (!g(o) && Rt(o)) {
1877
1896
  if (r.length > 0) {
1878
1897
  const s = r[r.length - 1];
1879
- Ct(s, o) || a.push({
1898
+ qt(s, o) || a.push({
1880
1899
  ruleId: "nested-interactive",
1881
1900
  selector: m(o),
1882
- html: u(o),
1901
+ html: d(o),
1883
1902
  impact: "serious",
1884
1903
  message: `Interactive element <${o.tagName.toLowerCase()}> is nested inside <${s.tagName.toLowerCase()}>.`
1885
1904
  });
1886
1905
  }
1887
- qt(o) && r.push(o);
1906
+ Nt(o) && r.push(o);
1888
1907
  }
1889
1908
  o = n.nextNode();
1890
1909
  }
1891
1910
  return a;
1892
1911
  }
1893
- }, Nt = {
1912
+ }, Mt = {
1894
1913
  id: "scrollable-region-focusable",
1895
1914
  wcag: ["2.1.1"],
1896
1915
  level: "A",
@@ -1898,31 +1917,37 @@ const Rt = {
1898
1917
  guidance: "Content that scrolls must be accessible to keyboard users. If a region has overflow:scroll or overflow:auto and contains scrollable content, it needs either tabindex='0' to be focusable, or it must contain focusable elements. Without this, keyboard users cannot scroll the content.",
1899
1918
  prompt: "Explain how to make this scrollable region keyboard accessible.",
1900
1919
  run(t) {
1920
+ var e;
1901
1921
  const a = [];
1902
- for (const e of t.querySelectorAll("*")) {
1903
- if (p(e) || !(e instanceof HTMLElement)) continue;
1904
- const i = A(e), n = i.overflowX, r = i.overflowY;
1905
- if (!(n === "scroll" || n === "auto" || r === "scroll" || r === "auto")) continue;
1906
- if (e.scrollHeight > 0 || e.clientHeight > 0) {
1907
- if (e.scrollHeight <= e.clientHeight && e.scrollWidth <= e.clientWidth) continue;
1922
+ for (const i of t.querySelectorAll("*")) {
1923
+ if (g(i) || !(i instanceof HTMLElement)) continue;
1924
+ const n = i.tagName.toLowerCase();
1925
+ if (n === "body" || n === "html") continue;
1926
+ const r = i.getAttribute("role");
1927
+ if (r === "presentation" || r === "none") continue;
1928
+ const o = w(i), s = o.overflowX, l = o.overflowY;
1929
+ if (!(s === "scroll" || s === "auto" || l === "scroll" || l === "auto")) continue;
1930
+ if (i.scrollHeight > 0 || i.clientHeight > 0) {
1931
+ const b = i.scrollHeight - i.clientHeight, f = i.scrollWidth - i.clientWidth;
1932
+ if (b <= 0 && f <= 0 || b < 36 && f < 36 || i.clientWidth < 64 && i.clientHeight < 64) continue;
1908
1933
  } else {
1909
- const c = i.height !== "" || i.maxHeight !== "", d = e.textContent != null && e.textContent.trim().length > 0;
1910
- if (!c || !d) continue;
1934
+ const b = o.height !== "" || o.maxHeight !== "", f = ((e = i.textContent) == null ? void 0 : e.trim().length) ?? 0;
1935
+ if (!b || f <= 50) continue;
1911
1936
  }
1912
- const l = e.getAttribute("tabindex");
1913
- l !== null && l !== "-1" || e.querySelector(
1937
+ const u = i.getAttribute("tabindex");
1938
+ u !== null && u !== "-1" || i.querySelector(
1914
1939
  'a[href], button:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
1915
1940
  ) || a.push({
1916
1941
  ruleId: "scrollable-region-focusable",
1917
- selector: m(e),
1918
- html: u(e),
1942
+ selector: m(i),
1943
+ html: d(i),
1919
1944
  impact: "serious",
1920
1945
  message: "Scrollable region is not keyboard accessible. Add tabindex='0' or include focusable elements."
1921
1946
  });
1922
1947
  }
1923
1948
  return a;
1924
1949
  }
1925
- }, $t = {
1950
+ }, Ht = {
1926
1951
  id: "accesskeys",
1927
1952
  wcag: [],
1928
1953
  level: "A",
@@ -1934,7 +1959,7 @@ const Rt = {
1934
1959
  var i;
1935
1960
  const a = [], e = /* @__PURE__ */ new Map();
1936
1961
  for (const n of t.querySelectorAll("[accesskey]")) {
1937
- if (p(n)) continue;
1962
+ if (g(n)) continue;
1938
1963
  const r = (i = n.getAttribute("accesskey")) == null ? void 0 : i.trim().toLowerCase();
1939
1964
  if (!r) continue;
1940
1965
  const o = e.get(r) || [];
@@ -1946,13 +1971,13 @@ const Rt = {
1946
1971
  a.push({
1947
1972
  ruleId: "accesskeys",
1948
1973
  selector: m(o),
1949
- html: u(o),
1974
+ html: d(o),
1950
1975
  impact: "serious",
1951
1976
  message: `Duplicate accesskey "${n}". Each accesskey must be unique.`
1952
1977
  });
1953
1978
  return a;
1954
1979
  }
1955
- }, Mt = {
1980
+ }, Dt = {
1956
1981
  id: "heading-order",
1957
1982
  wcag: [],
1958
1983
  level: "A",
@@ -1964,20 +1989,20 @@ const Rt = {
1964
1989
  const a = [], e = t.querySelectorAll("h1, h2, h3, h4, h5, h6, [role='heading']");
1965
1990
  let i = 0, n = null;
1966
1991
  for (const r of e) {
1967
- if (p(r)) continue;
1992
+ if (g(r)) continue;
1968
1993
  let o;
1969
1994
  r.hasAttribute("aria-level") ? o = parseInt(r.getAttribute("aria-level"), 10) : o = parseInt(r.tagName[1], 10), i > 0 && o > i + 1 && a.push({
1970
1995
  ruleId: "heading-order",
1971
1996
  selector: m(r),
1972
- html: u(r),
1997
+ html: d(r),
1973
1998
  impact: "moderate",
1974
1999
  message: `Heading level ${o} skipped from level ${i}.`,
1975
- context: n ? `Previous heading: ${u(n)}` : void 0
2000
+ context: n ? `Previous heading: ${d(n)}` : void 0
1976
2001
  }), i = o, n = r;
1977
2002
  }
1978
2003
  return a;
1979
2004
  }
1980
- }, N = 'article, aside, main, nav, section, [role="article"], [role="complementary"], [role="main"], [role="navigation"], [role="region"]', te = 'main, [role="main"], header, [role="banner"], footer, [role="contentinfo"], nav, [role="navigation"], aside, [role="complementary"], section[aria-label], section[aria-labelledby], [role="region"][aria-label], [role="region"][aria-labelledby], form[aria-label], form[aria-labelledby], [role="form"][aria-label], [role="form"][aria-labelledby], [role="search"]', Ht = {
2005
+ }, $ = 'article, aside, main, nav, section, [role="article"], [role="complementary"], [role="main"], [role="navigation"], [role="region"]', ae = 'main, [role="main"], header, [role="banner"], footer, [role="contentinfo"], nav, [role="navigation"], aside, [role="complementary"], section[aria-label], section[aria-labelledby], [role="region"][aria-label], [role="region"][aria-labelledby], form[aria-label], form[aria-labelledby], [role="form"][aria-label], [role="form"][aria-labelledby], [role="search"]', Ot = {
1981
2006
  id: "landmark-one-main",
1982
2007
  wcag: [],
1983
2008
  level: "A",
@@ -1996,12 +2021,12 @@ const Rt = {
1996
2021
  }] : a.length > 1 ? Array.from(a).slice(1).map((e) => ({
1997
2022
  ruleId: "landmark-one-main",
1998
2023
  selector: m(e),
1999
- html: u(e),
2024
+ html: d(e),
2000
2025
  impact: "moderate",
2001
2026
  message: "Page has multiple main landmarks."
2002
2027
  })) : [];
2003
2028
  }
2004
- }, Dt = {
2029
+ }, Bt = {
2005
2030
  id: "landmark-no-duplicate-banner",
2006
2031
  wcag: [],
2007
2032
  level: "A",
@@ -2010,18 +2035,18 @@ const Rt = {
2010
2035
  guidance: "The banner landmark (typically <header>) identifies site-oriented content like logos and search. Only one top-level banner is allowed per page. If you need multiple headers, nest them inside sectioning elements (article, section, aside) where they become scoped headers rather than page-level banners.",
2011
2036
  prompt: "Explain whether to remove this duplicate banner or nest it inside a sectioning element.",
2012
2037
  run(t) {
2013
- const a = [], e = t.querySelectorAll('header, [role="banner"]'), i = Array.from(e).filter((n) => !n.closest(N));
2038
+ const a = [], e = t.querySelectorAll('header, [role="banner"]'), i = Array.from(e).filter((n) => !n.closest($));
2014
2039
  return i.length > 1 && i.slice(1).forEach(
2015
2040
  (n) => a.push({
2016
2041
  ruleId: "landmark-no-duplicate-banner",
2017
2042
  selector: m(n),
2018
- html: u(n),
2043
+ html: d(n),
2019
2044
  impact: "moderate",
2020
2045
  message: "Page has multiple banner landmarks."
2021
2046
  })
2022
2047
  ), a;
2023
2048
  }
2024
- }, Ot = {
2049
+ }, Ft = {
2025
2050
  id: "landmark-no-duplicate-contentinfo",
2026
2051
  wcag: [],
2027
2052
  level: "A",
@@ -2030,18 +2055,18 @@ const Rt = {
2030
2055
  guidance: "The contentinfo landmark (typically <footer>) contains information about the page like copyright and contact info. Only one top-level contentinfo is allowed per page. Nest additional footers inside sectioning elements to scope them.",
2031
2056
  prompt: "Explain whether to remove this duplicate footer or nest it inside a sectioning element.",
2032
2057
  run(t) {
2033
- const a = [], e = t.querySelectorAll('footer, [role="contentinfo"]'), i = Array.from(e).filter((n) => !n.closest(N));
2058
+ const a = [], e = t.querySelectorAll('footer, [role="contentinfo"]'), i = Array.from(e).filter((n) => !n.closest($));
2034
2059
  return i.length > 1 && i.slice(1).forEach(
2035
2060
  (n) => a.push({
2036
2061
  ruleId: "landmark-no-duplicate-contentinfo",
2037
2062
  selector: m(n),
2038
- html: u(n),
2063
+ html: d(n),
2039
2064
  impact: "moderate",
2040
2065
  message: "Page has multiple contentinfo landmarks."
2041
2066
  })
2042
2067
  ), a;
2043
2068
  }
2044
- }, Ft = {
2069
+ }, Wt = {
2045
2070
  id: "landmark-no-duplicate-main",
2046
2071
  wcag: [],
2047
2072
  level: "A",
@@ -2055,13 +2080,13 @@ const Rt = {
2055
2080
  (i) => a.push({
2056
2081
  ruleId: "landmark-no-duplicate-main",
2057
2082
  selector: m(i),
2058
- html: u(i),
2083
+ html: d(i),
2059
2084
  impact: "moderate",
2060
2085
  message: "Page has multiple main landmarks."
2061
2086
  })
2062
2087
  ), a;
2063
2088
  }
2064
- }, Bt = {
2089
+ }, _t = {
2065
2090
  id: "landmark-banner-is-top-level",
2066
2091
  wcag: [],
2067
2092
  level: "A",
@@ -2072,16 +2097,16 @@ const Rt = {
2072
2097
  run(t) {
2073
2098
  const a = [], e = t.querySelectorAll('[role="banner"]');
2074
2099
  for (const i of e)
2075
- i.closest(N) && a.push({
2100
+ i.closest($) && a.push({
2076
2101
  ruleId: "landmark-banner-is-top-level",
2077
2102
  selector: m(i),
2078
- html: u(i),
2103
+ html: d(i),
2079
2104
  impact: "moderate",
2080
2105
  message: "Banner landmark is nested within another landmark."
2081
2106
  });
2082
2107
  return a;
2083
2108
  }
2084
- }, Wt = {
2109
+ }, Pt = {
2085
2110
  id: "landmark-contentinfo-is-top-level",
2086
2111
  wcag: [],
2087
2112
  level: "A",
@@ -2092,16 +2117,16 @@ const Rt = {
2092
2117
  run(t) {
2093
2118
  const a = [], e = t.querySelectorAll('[role="contentinfo"]');
2094
2119
  for (const i of e)
2095
- i.closest(N) && a.push({
2120
+ i.closest($) && a.push({
2096
2121
  ruleId: "landmark-contentinfo-is-top-level",
2097
2122
  selector: m(i),
2098
- html: u(i),
2123
+ html: d(i),
2099
2124
  impact: "moderate",
2100
2125
  message: "Contentinfo landmark is nested within another landmark."
2101
2126
  });
2102
2127
  return a;
2103
2128
  }
2104
- }, _t = {
2129
+ }, jt = {
2105
2130
  id: "landmark-main-is-top-level",
2106
2131
  wcag: [],
2107
2132
  level: "A",
@@ -2116,14 +2141,14 @@ const Rt = {
2116
2141
  n != null && n.closest('article, aside, nav, section, [role="article"], [role="complementary"], [role="navigation"], [role="region"]') && a.push({
2117
2142
  ruleId: "landmark-main-is-top-level",
2118
2143
  selector: m(i),
2119
- html: u(i),
2144
+ html: d(i),
2120
2145
  impact: "moderate",
2121
2146
  message: "Main landmark is nested within another landmark."
2122
2147
  });
2123
2148
  }
2124
2149
  return a;
2125
2150
  }
2126
- }, Pt = {
2151
+ }, Vt = {
2127
2152
  id: "landmark-complementary-is-top-level",
2128
2153
  wcag: [],
2129
2154
  level: "A",
@@ -2138,14 +2163,14 @@ const Rt = {
2138
2163
  n && !n.matches('body, main, [role="main"]') && i.closest('article, nav, section, [role="article"], [role="navigation"], [role="region"]') && a.push({
2139
2164
  ruleId: "landmark-complementary-is-top-level",
2140
2165
  selector: m(i),
2141
- html: u(i),
2166
+ html: d(i),
2142
2167
  impact: "moderate",
2143
2168
  message: "Complementary landmark should be top-level."
2144
2169
  });
2145
2170
  }
2146
2171
  return a;
2147
2172
  }
2148
- }, jt = {
2173
+ }, zt = {
2149
2174
  id: "landmark-unique",
2150
2175
  wcag: [],
2151
2176
  level: "A",
@@ -2161,7 +2186,7 @@ const Rt = {
2161
2186
  { selector: 'form[aria-label], form[aria-labelledby], [role="form"], [role="search"]', type: "form" }
2162
2187
  ];
2163
2188
  for (const { selector: i, type: n } of e) {
2164
- const r = Array.from(t.querySelectorAll(i)).filter((s) => !p(s));
2189
+ const r = Array.from(t.querySelectorAll(i)).filter((s) => !g(s));
2165
2190
  if (r.length <= 1) continue;
2166
2191
  const o = /* @__PURE__ */ new Map();
2167
2192
  for (const s of r) {
@@ -2174,14 +2199,14 @@ const Rt = {
2174
2199
  a.push({
2175
2200
  ruleId: "landmark-unique",
2176
2201
  selector: m(h),
2177
- html: u(h),
2202
+ html: d(h),
2178
2203
  impact: "moderate",
2179
2204
  message: s ? `Multiple ${n} landmarks have the same label "${s}".` : `Multiple ${n} landmarks have no label. Add unique aria-label attributes.`
2180
2205
  });
2181
2206
  }
2182
2207
  return a;
2183
2208
  }
2184
- }, Vt = {
2209
+ }, Ut = {
2185
2210
  id: "region",
2186
2211
  wcag: [],
2187
2212
  level: "A",
@@ -2194,22 +2219,22 @@ const Rt = {
2194
2219
  const a = [], e = t.body;
2195
2220
  if (!e) return [];
2196
2221
  for (const n of e.children) {
2197
- if (p(n) || n instanceof HTMLScriptElement || n instanceof HTMLStyleElement || n.tagName === "NOSCRIPT" || n instanceof HTMLElement && n.hidden || n.matches('a[href^="#"]')) continue;
2198
- const r = n.matches(te), o = (i = n.textContent) == null ? void 0 : i.trim();
2199
- !r && o && (n.querySelector(te) || a.push({
2222
+ if (g(n) || n instanceof HTMLScriptElement || n instanceof HTMLStyleElement || n.tagName === "NOSCRIPT" || n instanceof HTMLElement && n.hidden || n.matches('a[href^="#"]')) continue;
2223
+ const r = n.matches(ae), o = (i = n.textContent) == null ? void 0 : i.trim();
2224
+ !r && o && (n.querySelector(ae) || a.push({
2200
2225
  ruleId: "region",
2201
2226
  selector: m(n),
2202
- html: u(n),
2227
+ html: d(n),
2203
2228
  impact: "moderate",
2204
2229
  message: "Content is not contained within a landmark region."
2205
2230
  }));
2206
2231
  }
2207
2232
  return a;
2208
2233
  }
2209
- }, zt = {
2234
+ }, Gt = {
2210
2235
  id: "list",
2211
2236
  selector: "ul, ol",
2212
- check: { type: "child-invalid", allowedChildren: ["li", "script", "template"] },
2237
+ check: { type: "child-invalid", allowedChildren: ["li", "script", "template"], allowedChildRoles: ["listitem"] },
2213
2238
  impact: "serious",
2214
2239
  message: "List contains non-<li> child <{{tag}}>.",
2215
2240
  description: "<ul> and <ol> must only contain <li>, <script>, or <template> as direct children.",
@@ -2217,7 +2242,7 @@ const Rt = {
2217
2242
  level: "A",
2218
2243
  guidance: "Screen readers announce list structure ('list with 5 items') based on proper markup. Placing non-<li> elements directly inside <ul> or <ol> breaks this structure. Wrap content in <li> elements, or if you need wrapper divs for styling, restructure your CSS to style the <li> elements directly.",
2219
2244
  prompt: "Explain how to restructure this element within the list properly."
2220
- }, Ut = k(zt), Gt = {
2245
+ }, Yt = k(Gt), Xt = {
2221
2246
  id: "dlitem",
2222
2247
  wcag: ["1.3.1"],
2223
2248
  level: "A",
@@ -2230,13 +2255,13 @@ const Rt = {
2230
2255
  (!e.parentElement || e.parentElement.tagName.toLowerCase() !== "dl") && a.push({
2231
2256
  ruleId: "dlitem",
2232
2257
  selector: m(e),
2233
- html: u(e),
2258
+ html: d(e),
2234
2259
  impact: "serious",
2235
2260
  message: `<${e.tagName.toLowerCase()}> is not contained in a <dl>.`
2236
2261
  });
2237
2262
  return a;
2238
2263
  }
2239
- }, Xt = {
2264
+ }, Kt = {
2240
2265
  id: "definition-list",
2241
2266
  selector: "dl",
2242
2267
  check: { type: "child-invalid", allowedChildren: ["dt", "dd", "div", "script", "template"] },
@@ -2247,7 +2272,32 @@ const Rt = {
2247
2272
  level: "A",
2248
2273
  guidance: "Definition lists have strict content requirements. Only <dt> (terms), <dd> (definitions), and <div> (for grouping dt/dd pairs) are valid children. Other elements break the list structure for screen readers. Move invalid elements outside the <dl>, or restructure using proper definition list markup.",
2249
2274
  prompt: "Explain whether to move this element outside the <dl> or convert it to dt/dd."
2250
- }, Yt = k(Xt), Kt = {
2275
+ }, Jt = k(Kt), Qt = {
2276
+ id: "listitem",
2277
+ wcag: ["1.3.1"],
2278
+ level: "A",
2279
+ description: "<li> elements must be contained in a <ul>, <ol>, or <menu>.",
2280
+ guidance: "List items (<li>) only have semantic meaning inside a list container (<ul>, <ol>, or <menu>). Outside of these containers, assistive technologies cannot convey the list relationship. Wrap <li> elements in the appropriate list container.",
2281
+ prompt: "Explain that this <li> must be placed inside a <ul>, <ol>, or <menu> element.",
2282
+ run(t) {
2283
+ var e;
2284
+ const a = [];
2285
+ for (const i of t.querySelectorAll("li")) {
2286
+ if (g(i)) continue;
2287
+ const n = i.parentElement;
2288
+ if (!n) continue;
2289
+ const r = n.tagName.toLowerCase();
2290
+ r === "ul" || r === "ol" || r === "menu" || ((e = n.getAttribute("role")) == null ? void 0 : e.trim().toLowerCase()) === "list" || a.push({
2291
+ ruleId: "listitem",
2292
+ selector: m(i),
2293
+ html: d(i),
2294
+ impact: "serious",
2295
+ message: "<li> is not contained in a <ul>, <ol>, or <menu>."
2296
+ });
2297
+ }
2298
+ return a;
2299
+ }
2300
+ }, Zt = {
2251
2301
  id: "document-title",
2252
2302
  wcag: ["2.4.2"],
2253
2303
  level: "A",
@@ -2277,10 +2327,11 @@ const Rt = {
2277
2327
  }
2278
2328
  return [];
2279
2329
  }
2280
- }, Jt = {
2330
+ }, ea = {
2281
2331
  id: "bypass",
2282
- wcag: ["2.4.1"],
2332
+ wcag: [],
2283
2333
  level: "A",
2334
+ tags: ["best-practice"],
2284
2335
  description: "Page must have a mechanism to bypass repeated blocks of content.",
2285
2336
  guidance: 'Keyboard users must be able to skip repetitive content like navigation. Provide a skip link at the top of the page that links to the main content (e.g., <a href="#main">Skip to main content</a>), or use a <main> landmark. Screen readers can jump directly to landmarks, so a properly marked-up <main> element satisfies this requirement.',
2286
2337
  prompt: 'The page has no mechanism for keyboard users to skip repeated content. The simplest fix is to wrap the primary content area in a <main> element — screen readers can jump directly to it. Alternatively, add a skip link as the first element in <body>: <a href="#main" class="skip-link">Skip to main content</a>, with a matching id on the target element. Use the context to understand what the page is missing.',
@@ -2307,7 +2358,7 @@ const Rt = {
2307
2358
  context: `Missing: ${n.join(", ")}`
2308
2359
  }];
2309
2360
  }
2310
- }, Qt = {
2361
+ }, ta = {
2311
2362
  id: "page-has-heading-one",
2312
2363
  wcag: [],
2313
2364
  level: "A",
@@ -2339,13 +2390,13 @@ const Rt = {
2339
2390
  }];
2340
2391
  }
2341
2392
  };
2342
- function me(t) {
2393
+ function he(t) {
2343
2394
  if (!(t instanceof HTMLElement)) return !1;
2344
2395
  if (t.style.display === "none" || t.style.visibility === "hidden") return !0;
2345
2396
  const a = t.getAttribute("width"), e = t.getAttribute("height");
2346
2397
  return (a === "0" || a === "1") && (e === "0" || e === "1");
2347
2398
  }
2348
- const Zt = {
2399
+ const aa = {
2349
2400
  id: "frame-title",
2350
2401
  wcag: ["4.1.2"],
2351
2402
  level: "A",
@@ -2355,13 +2406,13 @@ const Zt = {
2355
2406
  run(t) {
2356
2407
  const a = [];
2357
2408
  for (const e of t.querySelectorAll("iframe, frame")) {
2358
- if (p(e) || me(e)) continue;
2409
+ if (g(e) || he(e)) continue;
2359
2410
  if (!v(e)) {
2360
2411
  const n = e.getAttribute("src");
2361
2412
  a.push({
2362
2413
  ruleId: "frame-title",
2363
2414
  selector: m(e),
2364
- html: u(e),
2415
+ html: d(e),
2365
2416
  impact: "serious",
2366
2417
  message: "Frame is missing an accessible name. Add a title attribute.",
2367
2418
  context: n ? `src: "${n}"` : void 0
@@ -2370,7 +2421,7 @@ const Zt = {
2370
2421
  }
2371
2422
  return a;
2372
2423
  }
2373
- }, ea = {
2424
+ }, ia = {
2374
2425
  id: "frame-title-unique",
2375
2426
  wcag: ["4.1.2"],
2376
2427
  level: "A",
@@ -2382,7 +2433,7 @@ const Zt = {
2382
2433
  var n;
2383
2434
  const a = [], e = Array.from(t.querySelectorAll("iframe[title], frame[title]")), i = /* @__PURE__ */ new Map();
2384
2435
  for (const r of e) {
2385
- if (p(r) || me(r)) continue;
2436
+ if (g(r) || he(r)) continue;
2386
2437
  const o = (n = r.getAttribute("title")) == null ? void 0 : n.trim().toLowerCase();
2387
2438
  if (o) {
2388
2439
  const s = i.get(o) || [];
@@ -2395,13 +2446,13 @@ const Zt = {
2395
2446
  a.push({
2396
2447
  ruleId: "frame-title-unique",
2397
2448
  selector: m(o),
2398
- html: u(o),
2449
+ html: d(o),
2399
2450
  impact: "moderate",
2400
2451
  message: "Frame title is not unique. Use a distinct title for each frame."
2401
2452
  });
2402
2453
  return a;
2403
2454
  }
2404
- }, ta = {
2455
+ }, na = {
2405
2456
  id: "empty-heading",
2406
2457
  wcag: [],
2407
2458
  level: "A",
@@ -2413,7 +2464,7 @@ const Zt = {
2413
2464
  var i;
2414
2465
  const a = [], e = t.querySelectorAll('h1, h2, h3, h4, h5, h6, [role="heading"]');
2415
2466
  for (const n of e)
2416
- if (!p(n) && !v(n)) {
2467
+ if (!g(n) && !v(n)) {
2417
2468
  let r;
2418
2469
  const o = n.nextElementSibling;
2419
2470
  if (o) {
@@ -2423,7 +2474,7 @@ const Zt = {
2423
2474
  a.push({
2424
2475
  ruleId: "empty-heading",
2425
2476
  selector: m(n),
2426
- html: u(n),
2477
+ html: d(n),
2427
2478
  impact: "minor",
2428
2479
  message: "Heading is empty. Add text content or remove the heading element.",
2429
2480
  context: r ? `Following content: "${r}"` : void 0
@@ -2431,7 +2482,7 @@ const Zt = {
2431
2482
  }
2432
2483
  return a;
2433
2484
  }
2434
- }, aa = {
2485
+ }, ra = {
2435
2486
  id: "meta-viewport",
2436
2487
  wcag: ["1.4.4"],
2437
2488
  level: "AA",
@@ -2445,7 +2496,7 @@ const Zt = {
2445
2496
  (/user-scalable\s*=\s*no/i.test(n) || /user-scalable\s*=\s*0/i.test(n)) && a.push({
2446
2497
  ruleId: "meta-viewport",
2447
2498
  selector: m(e),
2448
- html: u(e),
2499
+ html: d(e),
2449
2500
  impact: "critical",
2450
2501
  message: "Viewport disables user scaling. Remove user-scalable=no.",
2451
2502
  context: `content: "${i}"`
@@ -2456,7 +2507,7 @@ const Zt = {
2456
2507
  s < 2 && a.push({
2457
2508
  ruleId: "meta-viewport",
2458
2509
  selector: m(e),
2459
- html: u(e),
2510
+ html: d(e),
2460
2511
  impact: "critical",
2461
2512
  message: `Viewport maximum-scale=${s} restricts zooming. Set to at least 2 or remove.`,
2462
2513
  context: `content: "${i}"`
@@ -2464,7 +2515,7 @@ const Zt = {
2464
2515
  }
2465
2516
  return a;
2466
2517
  }
2467
- }, ia = {
2518
+ }, oa = {
2468
2519
  id: "meta-refresh",
2469
2520
  wcag: ["2.2.1", "2.2.4", "3.2.5"],
2470
2521
  level: "A",
@@ -2480,7 +2531,7 @@ const Zt = {
2480
2531
  return n > 0 && n <= 72e3 ? [{
2481
2532
  ruleId: "meta-refresh",
2482
2533
  selector: m(a),
2483
- html: u(a),
2534
+ html: d(a),
2484
2535
  impact: "critical",
2485
2536
  message: `Page redirects after ${n} seconds without warning. Use server-side redirect.`
2486
2537
  }] : [];
@@ -2488,14 +2539,14 @@ const Zt = {
2488
2539
  return [{
2489
2540
  ruleId: "meta-refresh",
2490
2541
  selector: m(a),
2491
- html: u(a),
2542
+ html: d(a),
2492
2543
  impact: "critical",
2493
2544
  message: `Page auto-refreshes after ${n} seconds. Provide user control over refresh.`
2494
2545
  }];
2495
2546
  }
2496
2547
  return [];
2497
2548
  }
2498
- }, na = {
2549
+ }, sa = {
2499
2550
  id: "blink",
2500
2551
  selector: "blink",
2501
2552
  check: { type: "selector-exists" },
@@ -2506,7 +2557,7 @@ const Zt = {
2506
2557
  level: "A",
2507
2558
  guidance: "Blinking content can cause seizures in users with photosensitive epilepsy and is distracting for users with attention disorders. The <blink> element is deprecated and should never be used. If you need to draw attention to content, use less intrusive methods like color, borders, or icons.",
2508
2559
  prompt: "Suggest static alternatives to the blinking effect."
2509
- }, ra = k(na), oa = {
2560
+ }, la = k(sa), ca = {
2510
2561
  id: "marquee",
2511
2562
  selector: "marquee",
2512
2563
  check: { type: "selector-exists" },
@@ -2517,7 +2568,7 @@ const Zt = {
2517
2568
  level: "A",
2518
2569
  guidance: "Scrolling or moving content is difficult for many users to read, especially those with cognitive or visual disabilities. The <marquee> element is deprecated. Replace scrolling text with static content. If content must scroll, provide pause/stop controls and ensure it stops after 5 seconds.",
2519
2570
  prompt: "Suggest static alternatives or accessible carousel patterns."
2520
- }, sa = k(oa), la = {
2571
+ }, ua = k(ca), da = {
2521
2572
  id: "p-as-heading",
2522
2573
  wcag: [],
2523
2574
  level: "A",
@@ -2529,14 +2580,14 @@ const Zt = {
2529
2580
  var e, i;
2530
2581
  const a = [];
2531
2582
  for (const n of t.querySelectorAll("p")) {
2532
- if (p(n)) continue;
2533
- const r = n.getAttribute("style") || "", o = /font-weight\s*:\s*(bold|[6-9]00)/i.test(r), s = /font-size\s*:\s*(\d+)\s*(px|em|rem)/i.test(r), l = ((e = n.className) == null ? void 0 : e.toLowerCase()) || "", h = /\bh[1-6]\b|\bheading\b/.test(l), c = ((i = n.textContent) == null ? void 0 : i.trim()) || "", d = c.length > 0 && c.length < 50, g = !c.match(/[.!?,;:]$/);
2534
- if ((o && s || o && h) && d && g) {
2583
+ if (g(n)) continue;
2584
+ const r = n.getAttribute("style") || "", o = /font-weight\s*:\s*(bold|[6-9]00)/i.test(r), s = /font-size\s*:\s*(\d+)\s*(px|em|rem)/i.test(r), l = ((e = n.className) == null ? void 0 : e.toLowerCase()) || "", h = /\bh[1-6]\b|\bheading\b/.test(l), c = ((i = n.textContent) == null ? void 0 : i.trim()) || "", u = c.length > 0 && c.length < 50, p = !c.match(/[.!?,;:]$/);
2585
+ if ((o && s || o && h) && u && p) {
2535
2586
  const y = n.nextElementSibling;
2536
2587
  y && (y.tagName === "P" || y.tagName === "DIV" || y.tagName === "UL") && a.push({
2537
2588
  ruleId: "p-as-heading",
2538
2589
  selector: m(n),
2539
- html: u(n),
2590
+ html: d(n),
2540
2591
  impact: "serious",
2541
2592
  message: "Paragraph appears to be styled as a heading. Use an h1-h6 element instead."
2542
2593
  });
@@ -2544,7 +2595,7 @@ const Zt = {
2544
2595
  }
2545
2596
  return a;
2546
2597
  }
2547
- }, ca = {
2598
+ }, ma = {
2548
2599
  id: "aria-roles",
2549
2600
  wcag: ["4.1.2"],
2550
2601
  level: "A",
@@ -2555,17 +2606,17 @@ const Zt = {
2555
2606
  const a = [];
2556
2607
  for (const e of t.querySelectorAll("[role]")) {
2557
2608
  const r = e.getAttribute("role").replace(/[\u201C\u201D\u2018\u2019\u00AB\u00BB]/g, "").split(/\s+/).filter(Boolean);
2558
- !r.some((s) => xe(s)) && r.length > 0 && a.push({
2609
+ !r.some((s) => ke(s)) && r.length > 0 && a.push({
2559
2610
  ruleId: "aria-roles",
2560
2611
  selector: m(e),
2561
- html: u(e),
2612
+ html: d(e),
2562
2613
  impact: "critical",
2563
2614
  message: `Invalid ARIA role "${r[0]}".`
2564
2615
  });
2565
2616
  }
2566
2617
  return a;
2567
2618
  }
2568
- }, ua = {
2619
+ }, ha = {
2569
2620
  id: "aria-valid-attr",
2570
2621
  wcag: ["4.1.2"],
2571
2622
  level: "A",
@@ -2573,9 +2624,9 @@ const Zt = {
2573
2624
  guidance: "Misspelled ARIA attributes are ignored by assistive technologies. Check the spelling against the WAI-ARIA specification. Common mistakes: aria-labeledby (should be aria-labelledby), aria-role (should be role), aria-description (valid in ARIA 1.3+).",
2574
2625
  prompt: "Identify the misspelled attribute and provide the correct spelling.",
2575
2626
  run(t) {
2576
- return z(t).validAttr;
2627
+ return U(t).validAttr;
2577
2628
  }
2578
- }, da = {
2629
+ }, pa = {
2579
2630
  id: "aria-valid-attr-value",
2580
2631
  wcag: ["4.1.2"],
2581
2632
  level: "A",
@@ -2583,9 +2634,9 @@ const Zt = {
2583
2634
  guidance: "Each ARIA attribute accepts specific value types. Boolean attributes (aria-hidden, aria-disabled) accept only 'true' or 'false'. Tristate attributes (aria-checked, aria-pressed) also accept 'mixed'. Token attributes (aria-live, aria-autocomplete) accept predefined values. ID reference attributes (aria-labelledby, aria-describedby) must reference existing element IDs.",
2584
2635
  prompt: "Show the invalid value and list the valid values for this specific attribute.",
2585
2636
  run(t) {
2586
- return z(t).validAttrValue;
2637
+ return U(t).validAttrValue;
2587
2638
  }
2588
- }, ma = {
2639
+ }, ga = {
2589
2640
  checkbox: ["aria-checked"],
2590
2641
  combobox: ["aria-expanded"],
2591
2642
  heading: ["aria-level"],
@@ -2599,7 +2650,7 @@ const Zt = {
2599
2650
  slider: ["aria-valuenow"],
2600
2651
  spinbutton: ["aria-valuenow"],
2601
2652
  switch: ["aria-checked"]
2602
- }, ha = {
2653
+ }, ba = {
2603
2654
  id: "aria-required-attr",
2604
2655
  wcag: ["4.1.2"],
2605
2656
  level: "A",
@@ -2609,8 +2660,8 @@ const Zt = {
2609
2660
  run(t) {
2610
2661
  const a = [];
2611
2662
  for (const e of t.querySelectorAll("[role]")) {
2612
- if (p(e) || e instanceof HTMLElement && e.style.display === "none") continue;
2613
- const i = e.getAttribute("role").trim().toLowerCase(), n = ma[i];
2663
+ if (g(e) || e instanceof HTMLElement && e.style.display === "none") continue;
2664
+ const i = e.getAttribute("role").trim().toLowerCase(), n = ga[i];
2614
2665
  if (n && !(i === "checkbox" && e instanceof HTMLInputElement && e.type === "checkbox") && !(i === "radio" && e instanceof HTMLInputElement && e.type === "radio") && !(i === "option" && e instanceof HTMLOptionElement) && !(i === "heading" && /^h[1-6]$/i.test(e.tagName))) {
2615
2666
  if (i === "separator") {
2616
2667
  const r = e.getAttribute("tabindex");
@@ -2622,7 +2673,7 @@ const Zt = {
2622
2673
  a.push({
2623
2674
  ruleId: "aria-required-attr",
2624
2675
  selector: m(e),
2625
- html: u(e),
2676
+ html: d(e),
2626
2677
  impact: "critical",
2627
2678
  message: `Role "${i}" requires attribute "${r}".`
2628
2679
  });
@@ -2634,7 +2685,7 @@ const Zt = {
2634
2685
  return a;
2635
2686
  }
2636
2687
  };
2637
- function pa(t) {
2688
+ function fa(t) {
2638
2689
  var r, o, s;
2639
2690
  const a = [], e = t.className;
2640
2691
  e && typeof e == "string" && e.trim() && a.push(`Classes: ${e.trim().slice(0, 100)}`);
@@ -2651,7 +2702,7 @@ function pa(t) {
2651
2702
  return a.length > 0 ? a.join(`
2652
2703
  `) : void 0;
2653
2704
  }
2654
- const ga = {
2705
+ const va = {
2655
2706
  id: "button-name",
2656
2707
  wcag: ["4.1.2"],
2657
2708
  level: "A",
@@ -2661,21 +2712,21 @@ const ga = {
2661
2712
  run(t) {
2662
2713
  const a = [];
2663
2714
  for (const e of t.querySelectorAll('button, [role="button"]')) {
2664
- if (p(e)) continue;
2715
+ if (g(e) || T(e)) continue;
2665
2716
  const i = e.getAttribute("role");
2666
2717
  if ((i === "none" || i === "presentation") && !(e.matches('button:not([disabled]), [tabindex]:not([tabindex="-1"])') || e.tagName.toLowerCase() === "button" && !e.disabled) || e.getRootNode() instanceof ShadowRoot) continue;
2667
2718
  v(e) || a.push({
2668
2719
  ruleId: "button-name",
2669
2720
  selector: m(e),
2670
- html: u(e),
2721
+ html: d(e),
2671
2722
  impact: "critical",
2672
2723
  message: "Button has no discernible text.",
2673
- context: pa(e)
2724
+ context: fa(e)
2674
2725
  });
2675
2726
  }
2676
2727
  return a;
2677
2728
  }
2678
- }, ba = {
2729
+ }, ya = {
2679
2730
  alert: /* @__PURE__ */ new Set(["aria-atomic", "aria-busy", "aria-live", "aria-relevant"]),
2680
2731
  alertdialog: /* @__PURE__ */ new Set(["aria-describedby", "aria-modal"]),
2681
2732
  application: /* @__PURE__ */ new Set(["aria-activedescendant", "aria-disabled", "aria-errormessage", "aria-expanded", "aria-haspopup", "aria-invalid"]),
@@ -2747,7 +2798,7 @@ const ga = {
2747
2798
  tree: /* @__PURE__ */ new Set(["aria-activedescendant", "aria-disabled", "aria-errormessage", "aria-invalid", "aria-multiselectable", "aria-orientation", "aria-required"]),
2748
2799
  treegrid: /* @__PURE__ */ new Set(["aria-activedescendant", "aria-colcount", "aria-disabled", "aria-errormessage", "aria-invalid", "aria-multiselectable", "aria-orientation", "aria-readonly", "aria-required", "aria-rowcount"]),
2749
2800
  treeitem: /* @__PURE__ */ new Set(["aria-checked", "aria-disabled", "aria-expanded", "aria-haspopup", "aria-level", "aria-posinset", "aria-selected", "aria-setsize"])
2750
- }, fa = /* @__PURE__ */ new Set([
2801
+ }, wa = /* @__PURE__ */ new Set([
2751
2802
  "aria-atomic",
2752
2803
  "aria-busy",
2753
2804
  "aria-controls",
@@ -2771,7 +2822,7 @@ const ga = {
2771
2822
  "aria-roledescription",
2772
2823
  "aria-braillelabel",
2773
2824
  "aria-brailleroledescription"
2774
- ]), va = {
2825
+ ]), Aa = {
2775
2826
  id: "aria-allowed-attr",
2776
2827
  wcag: ["4.1.2"],
2777
2828
  level: "A",
@@ -2781,18 +2832,18 @@ const ga = {
2781
2832
  run(t) {
2782
2833
  const a = [];
2783
2834
  for (const e of t.querySelectorAll("[role], [aria-*]")) {
2784
- if (p(e)) continue;
2785
- const i = L(e);
2835
+ if (g(e)) continue;
2836
+ const i = q(e);
2786
2837
  if (!i) continue;
2787
- const n = ba[i];
2838
+ const n = ya[i];
2788
2839
  if (n)
2789
2840
  for (const r of e.attributes) {
2790
- if (!r.name.startsWith("aria-") || fa.has(r.name) || n.has(r.name)) continue;
2841
+ if (!r.name.startsWith("aria-") || wa.has(r.name) || n.has(r.name)) continue;
2791
2842
  const o = n.size > 0 ? [...n].join(", ") : "none (only global ARIA attributes)";
2792
2843
  a.push({
2793
2844
  ruleId: "aria-allowed-attr",
2794
2845
  selector: m(e),
2795
- html: u(e),
2846
+ html: d(e),
2796
2847
  impact: "critical",
2797
2848
  message: `ARIA attribute "${r.name}" is not allowed on role "${i}".`,
2798
2849
  context: `Attribute: ${r.name}="${r.value}", role: ${i}, allowed role-specific attributes: ${o}`
@@ -2801,7 +2852,7 @@ const ga = {
2801
2852
  }
2802
2853
  return a;
2803
2854
  }
2804
- }, ya = /* @__PURE__ */ new Set([
2855
+ }, xa = /* @__PURE__ */ new Set([
2805
2856
  "base",
2806
2857
  "col",
2807
2858
  "colgroup",
@@ -2816,7 +2867,7 @@ const ga = {
2816
2867
  "template",
2817
2868
  "title",
2818
2869
  "track"
2819
- ]), T = {
2870
+ ]), E = {
2820
2871
  a: /* @__PURE__ */ new Set(["button", "checkbox", "menuitem", "menuitemcheckbox", "menuitemradio", "option", "radio", "switch", "tab", "treeitem", "link"]),
2821
2872
  "a[href]": /* @__PURE__ */ new Set(["button", "checkbox", "menuitem", "menuitemcheckbox", "menuitemradio", "option", "radio", "switch", "tab", "treeitem"]),
2822
2873
  abbr: "any",
@@ -2923,22 +2974,22 @@ const ga = {
2923
2974
  video: /* @__PURE__ */ new Set(["application"]),
2924
2975
  wbr: /* @__PURE__ */ new Set(["none", "presentation"])
2925
2976
  };
2926
- function wa(t) {
2977
+ function Sa(t) {
2927
2978
  var e;
2928
2979
  const a = t.tagName.toLowerCase();
2929
- if (ya.has(a))
2980
+ if (xa.has(a))
2930
2981
  return "none";
2931
2982
  if (a === "a" && t.hasAttribute("href"))
2932
- return T["a[href]"];
2983
+ return E["a[href]"];
2933
2984
  if (a === "img" && t.getAttribute("alt") === "")
2934
- return T["img[alt='']"];
2985
+ return E["img[alt='']"];
2935
2986
  if (a === "input") {
2936
2987
  const n = `input[type=${((e = t.getAttribute("type")) == null ? void 0 : e.toLowerCase()) || "text"}]`;
2937
- return n in T ? T[n] : "none";
2988
+ return n in E ? E[n] : "none";
2938
2989
  }
2939
- return T[a] || "any";
2990
+ return E[a] || "any";
2940
2991
  }
2941
- const Aa = {
2992
+ const ka = {
2942
2993
  id: "aria-allowed-role",
2943
2994
  wcag: ["4.1.2"],
2944
2995
  level: "A",
@@ -2949,29 +3000,29 @@ const Aa = {
2949
3000
  var e;
2950
3001
  const a = [];
2951
3002
  for (const i of t.querySelectorAll("[role]")) {
2952
- if (p(i)) continue;
3003
+ if (g(i)) continue;
2953
3004
  const n = (e = i.getAttribute("role")) == null ? void 0 : e.trim().toLowerCase();
2954
3005
  if (!n) continue;
2955
- const r = ue(i);
3006
+ const r = de(i);
2956
3007
  if (r && n === r) continue;
2957
- const o = wa(i);
3008
+ const o = Sa(i);
2958
3009
  o === "none" ? a.push({
2959
3010
  ruleId: "aria-allowed-role",
2960
3011
  selector: m(i),
2961
- html: u(i),
3012
+ html: d(i),
2962
3013
  impact: "minor",
2963
3014
  message: `Element <${i.tagName.toLowerCase()}> should not have an explicit role.`
2964
3015
  }) : o !== "any" && !o.has(n) && a.push({
2965
3016
  ruleId: "aria-allowed-role",
2966
3017
  selector: m(i),
2967
- html: u(i),
3018
+ html: d(i),
2968
3019
  impact: "minor",
2969
3020
  message: `Role "${n}" is not allowed on element <${i.tagName.toLowerCase()}>.`
2970
3021
  });
2971
3022
  }
2972
3023
  return a;
2973
3024
  }
2974
- }, ae = {
3025
+ }, ie = {
2975
3026
  // Each array is an OR group - at least one of each inner array must be present
2976
3027
  combobox: [["listbox", "tree", "grid", "dialog", "textbox"]],
2977
3028
  // Must own/contain one of these
@@ -2988,7 +3039,7 @@ const Aa = {
2988
3039
  tablist: [["tab"]],
2989
3040
  tree: [["treeitem", "group"]],
2990
3041
  treegrid: [["row", "rowgroup"]]
2991
- }, ie = {
3042
+ }, ne = {
2992
3043
  caption: ["figure", "table", "grid", "treegrid"],
2993
3044
  // cell/gridcell/columnheader/rowheader must be in a row
2994
3045
  // but we skip checking native td/th since they're handled by HTML semantics
@@ -3002,27 +3053,27 @@ const Aa = {
3002
3053
  tab: ["tablist"],
3003
3054
  treeitem: ["tree", "group"]
3004
3055
  };
3005
- function xa(t, a) {
3056
+ function Ia(t, a) {
3006
3057
  var r;
3007
3058
  const e = ((r = t.getAttribute("aria-owns")) == null ? void 0 : r.split(/\s+/)) || [], i = t.ownerDocument, n = /* @__PURE__ */ new Set();
3008
3059
  for (const o of t.querySelectorAll("*")) {
3009
- const s = L(o);
3010
- s && !p(o) && n.add(s);
3060
+ const s = q(o);
3061
+ s && !g(o) && n.add(s);
3011
3062
  }
3012
3063
  for (const o of e) {
3013
3064
  const s = i.getElementById(o);
3014
3065
  if (s) {
3015
- const l = L(s);
3016
- l && !p(s) && n.add(l);
3066
+ const l = q(s);
3067
+ l && !g(s) && n.add(l);
3017
3068
  }
3018
3069
  }
3019
3070
  for (const o of a)
3020
3071
  if (!o.some((l) => n.has(l))) return !1;
3021
3072
  return !0;
3022
3073
  }
3023
- const Sa = {
3074
+ const Ta = {
3024
3075
  id: "aria-required-children",
3025
- wcag: ["4.1.2"],
3076
+ wcag: ["1.3.1"],
3026
3077
  level: "A",
3027
3078
  description: "Certain ARIA roles require specific child roles to be present.",
3028
3079
  guidance: "Some ARIA roles represent containers that must contain specific child roles for proper semantics. For example, a list must contain listitems, a menu must contain menuitems. Add the required child elements with appropriate roles, or use native HTML elements that provide these semantics implicitly (e.g., <ul> with <li>).",
@@ -3031,16 +3082,16 @@ const Sa = {
3031
3082
  var e;
3032
3083
  const a = [];
3033
3084
  for (const i of t.querySelectorAll("[role]")) {
3034
- if (p(i)) continue;
3085
+ if (g(i)) continue;
3035
3086
  const n = (e = i.getAttribute("role")) == null ? void 0 : e.trim().toLowerCase();
3036
- if (!n || !(n in ae)) continue;
3037
- const r = ae[n];
3038
- if (!xa(i, r)) {
3087
+ if (!n || !(n in ie)) continue;
3088
+ const r = ie[n];
3089
+ if (!Ia(i, r)) {
3039
3090
  const o = r.map((s) => s.join(" or ")).join(", ");
3040
3091
  a.push({
3041
3092
  ruleId: "aria-required-children",
3042
3093
  selector: m(i),
3043
- html: u(i),
3094
+ html: d(i),
3044
3095
  impact: "critical",
3045
3096
  message: `Role "${n}" requires children with role: ${o}.`
3046
3097
  });
@@ -3048,9 +3099,9 @@ const Sa = {
3048
3099
  }
3049
3100
  return a;
3050
3101
  }
3051
- }, ka = {
3102
+ }, Ea = {
3052
3103
  id: "aria-required-parent",
3053
- wcag: ["4.1.2"],
3104
+ wcag: ["1.3.1"],
3054
3105
  level: "A",
3055
3106
  description: "Certain ARIA roles must be contained within specific parent roles.",
3056
3107
  guidance: "Some ARIA roles represent items that must exist within specific container roles. For example, a listitem must be within a list, a tab must be within a tablist. Wrap the element in the appropriate parent, or use native HTML elements that provide this structure (e.g., <li> inside <ul>).",
@@ -3059,13 +3110,13 @@ const Sa = {
3059
3110
  var e;
3060
3111
  const a = [];
3061
3112
  for (const i of t.querySelectorAll("[role]")) {
3062
- if (p(i)) continue;
3113
+ if (g(i)) continue;
3063
3114
  const n = (e = i.getAttribute("role")) == null ? void 0 : e.trim().toLowerCase();
3064
- if (!n || !(n in ie)) continue;
3065
- const r = ie[n];
3115
+ if (!n || !(n in ne)) continue;
3116
+ const r = ne[n];
3066
3117
  let o = i.parentElement, s = !1;
3067
3118
  for (; o && o !== t.documentElement; ) {
3068
- const l = L(o);
3119
+ const l = q(o);
3069
3120
  if (l && r.includes(l)) {
3070
3121
  s = !0;
3071
3122
  break;
@@ -3075,14 +3126,14 @@ const Sa = {
3075
3126
  s || a.push({
3076
3127
  ruleId: "aria-required-parent",
3077
3128
  selector: m(i),
3078
- html: u(i),
3129
+ html: d(i),
3079
3130
  impact: "critical",
3080
3131
  message: `Role "${n}" must be contained within: ${r.join(", ")}.`
3081
3132
  });
3082
3133
  }
3083
3134
  return a;
3084
3135
  }
3085
- }, ne = [
3136
+ }, re = [
3086
3137
  "a[href]",
3087
3138
  "button:not([disabled])",
3088
3139
  'input:not([disabled]):not([type="hidden"])',
@@ -3098,7 +3149,7 @@ const Sa = {
3098
3149
  "embed",
3099
3150
  "area[href]"
3100
3151
  ].join(", ");
3101
- function Ia(t) {
3152
+ function Ca(t) {
3102
3153
  let a = t;
3103
3154
  const e = t.ownerDocument, i = e.defaultView;
3104
3155
  for (; a && a !== e.body; ) {
@@ -3111,7 +3162,7 @@ function Ia(t) {
3111
3162
  }
3112
3163
  return !0;
3113
3164
  }
3114
- const Ta = {
3165
+ const La = {
3115
3166
  id: "aria-hidden-body",
3116
3167
  selector: 'body[aria-hidden="true"]',
3117
3168
  check: { type: "selector-exists" },
@@ -3123,7 +3174,7 @@ const Ta = {
3123
3174
  guidance: "Setting aria-hidden='true' on the body element hides all page content from assistive technologies, making the page completely inaccessible to screen reader users. Remove aria-hidden from the body element. If you need to hide content temporarily (e.g., behind a modal), use aria-hidden on specific sections instead.",
3124
3175
  prompt: "Instruct to remove aria-hidden='true' from the body element.",
3125
3176
  skipAriaHidden: !1
3126
- }, Ea = k(Ta), Ca = {
3177
+ }, qa = k(La), Ra = {
3127
3178
  id: "aria-hidden-focus",
3128
3179
  wcag: ["4.1.2"],
3129
3180
  level: "A",
@@ -3134,12 +3185,12 @@ const Ta = {
3134
3185
  const a = [];
3135
3186
  for (const e of t.querySelectorAll('[aria-hidden="true"]')) {
3136
3187
  if (e === t.body) continue;
3137
- const i = [...e.querySelectorAll(ne)];
3138
- e.matches(ne) && i.push(e);
3188
+ const i = [...e.querySelectorAll(re)];
3189
+ e.matches(re) && i.push(e);
3139
3190
  for (const n of i)
3140
3191
  if (n instanceof HTMLElement) {
3141
3192
  const r = n.getAttribute("tabindex");
3142
- if (r === "-1" || n.disabled || n instanceof HTMLInputElement && n.type === "hidden" || !Ia(n)) continue;
3193
+ if (r === "-1" || n.disabled || n instanceof HTMLInputElement && n.type === "hidden" || !Ca(n)) continue;
3143
3194
  const o = n.tagName.toLowerCase();
3144
3195
  let s;
3145
3196
  r !== null ? s = `has tabindex="${r}"` : o === "a" && n.hasAttribute("href") ? s = "is a link with href" : o === "button" ? s = "is a <button>" : o === "input" ? s = `is an <input type="${n.type}">` : o === "select" ? s = "is a <select>" : o === "textarea" ? s = "is a <textarea>" : o === "iframe" ? s = "is an <iframe>" : s = `is a natively focusable <${o}>`;
@@ -3147,16 +3198,16 @@ const Ta = {
3147
3198
  a.push({
3148
3199
  ruleId: "aria-hidden-focus",
3149
3200
  selector: m(n),
3150
- html: u(n),
3201
+ html: d(n),
3151
3202
  impact: "serious",
3152
3203
  message: "Focusable element is inside an aria-hidden region.",
3153
- context: `Focusable because: ${s}. aria-hidden ancestor: ${l ? u(l) : "unknown"}`
3204
+ context: `Focusable because: ${s}. aria-hidden ancestor: ${l ? d(l) : "unknown"}`
3154
3205
  });
3155
3206
  }
3156
3207
  }
3157
3208
  return a;
3158
3209
  }
3159
- }, La = {
3210
+ }, Na = {
3160
3211
  id: "aria-command-name",
3161
3212
  wcag: ["4.1.2"],
3162
3213
  level: "A",
@@ -3167,14 +3218,14 @@ const Ta = {
3167
3218
  var e;
3168
3219
  const a = [];
3169
3220
  for (const i of t.querySelectorAll('[role="button"], [role="link"], [role="menuitem"]')) {
3170
- if (p(i) || i.tagName.toLowerCase() === "button" || i.tagName.toLowerCase() === "a") continue;
3221
+ if (g(i) || T(i) || i.getRootNode() instanceof ShadowRoot || i.tagName.toLowerCase() === "button" || i.tagName.toLowerCase() === "a") continue;
3171
3222
  if (!v(i)) {
3172
3223
  const r = i.querySelector("img[alt]");
3173
3224
  if ((e = r == null ? void 0 : r.getAttribute("alt")) != null && e.trim()) continue;
3174
3225
  a.push({
3175
3226
  ruleId: "aria-command-name",
3176
3227
  selector: m(i),
3177
- html: u(i),
3228
+ html: d(i),
3178
3229
  impact: "serious",
3179
3230
  message: "ARIA command has no accessible name."
3180
3231
  });
@@ -3182,7 +3233,7 @@ const Ta = {
3182
3233
  }
3183
3234
  return a;
3184
3235
  }
3185
- }, qa = {
3236
+ }, $a = {
3186
3237
  id: "aria-input-field-name",
3187
3238
  wcag: ["4.1.2"],
3188
3239
  level: "A",
@@ -3192,18 +3243,18 @@ const Ta = {
3192
3243
  run(t) {
3193
3244
  const a = [], e = '[role="combobox"], [role="listbox"], [role="searchbox"], [role="slider"], [role="spinbutton"], [role="textbox"]';
3194
3245
  for (const i of t.querySelectorAll(e)) {
3195
- if (p(i) || i.matches("input, select, textarea")) continue;
3246
+ if (g(i) || T(i) || i.getRootNode() instanceof ShadowRoot || i.matches("input, select, textarea")) continue;
3196
3247
  v(i) || a.push({
3197
3248
  ruleId: "aria-input-field-name",
3198
3249
  selector: m(i),
3199
- html: u(i),
3250
+ html: d(i),
3200
3251
  impact: "serious",
3201
3252
  message: "ARIA input field has no accessible name."
3202
3253
  });
3203
3254
  }
3204
3255
  return a;
3205
3256
  }
3206
- }, Ra = {
3257
+ }, Ma = {
3207
3258
  id: "aria-toggle-field-name",
3208
3259
  wcag: ["4.1.2"],
3209
3260
  level: "A",
@@ -3213,18 +3264,18 @@ const Ta = {
3213
3264
  run(t) {
3214
3265
  const a = [], e = '[role="checkbox"], [role="switch"], [role="radio"], [role="menuitemcheckbox"], [role="menuitemradio"]';
3215
3266
  for (const i of t.querySelectorAll(e)) {
3216
- if (p(i) || i.matches('input[type="checkbox"], input[type="radio"]')) continue;
3267
+ if (g(i) || T(i) || i.getRootNode() instanceof ShadowRoot || i.matches('input[type="checkbox"], input[type="radio"]')) continue;
3217
3268
  v(i) || a.push({
3218
3269
  ruleId: "aria-toggle-field-name",
3219
3270
  selector: m(i),
3220
- html: u(i),
3271
+ html: d(i),
3221
3272
  impact: "serious",
3222
3273
  message: "ARIA toggle field has no accessible name."
3223
3274
  });
3224
3275
  }
3225
3276
  return a;
3226
3277
  }
3227
- }, Na = {
3278
+ }, Ha = {
3228
3279
  id: "aria-meter-name",
3229
3280
  wcag: ["4.1.2"],
3230
3281
  level: "A",
@@ -3234,18 +3285,18 @@ const Ta = {
3234
3285
  run(t) {
3235
3286
  const a = [];
3236
3287
  for (const e of t.querySelectorAll('[role="meter"], meter')) {
3237
- if (p(e)) continue;
3288
+ if (g(e)) continue;
3238
3289
  v(e) || a.push({
3239
3290
  ruleId: "aria-meter-name",
3240
3291
  selector: m(e),
3241
- html: u(e),
3292
+ html: d(e),
3242
3293
  impact: "serious",
3243
3294
  message: "Meter has no accessible name."
3244
3295
  });
3245
3296
  }
3246
3297
  return a;
3247
3298
  }
3248
- }, $a = {
3299
+ }, Da = {
3249
3300
  id: "aria-progressbar-name",
3250
3301
  wcag: ["4.1.2"],
3251
3302
  level: "A",
@@ -3255,18 +3306,18 @@ const Ta = {
3255
3306
  run(t) {
3256
3307
  const a = [];
3257
3308
  for (const e of t.querySelectorAll('[role="progressbar"], progress')) {
3258
- if (p(e)) continue;
3309
+ if (g(e)) continue;
3259
3310
  v(e) || a.push({
3260
3311
  ruleId: "aria-progressbar-name",
3261
3312
  selector: m(e),
3262
- html: u(e),
3313
+ html: d(e),
3263
3314
  impact: "serious",
3264
3315
  message: "Progressbar has no accessible name."
3265
3316
  });
3266
3317
  }
3267
3318
  return a;
3268
3319
  }
3269
- }, Ma = {
3320
+ }, Oa = {
3270
3321
  id: "aria-dialog-name",
3271
3322
  wcag: ["4.1.2"],
3272
3323
  level: "A",
@@ -3276,18 +3327,18 @@ const Ta = {
3276
3327
  run(t) {
3277
3328
  const a = [];
3278
3329
  for (const e of t.querySelectorAll('[role="dialog"], [role="alertdialog"], dialog')) {
3279
- if (p(e)) continue;
3330
+ if (g(e)) continue;
3280
3331
  v(e) || a.push({
3281
3332
  ruleId: "aria-dialog-name",
3282
3333
  selector: m(e),
3283
- html: u(e),
3334
+ html: d(e),
3284
3335
  impact: "serious",
3285
3336
  message: "Dialog has no accessible name."
3286
3337
  });
3287
3338
  }
3288
3339
  return a;
3289
3340
  }
3290
- }, Ha = {
3341
+ }, Ba = {
3291
3342
  id: "aria-tooltip-name",
3292
3343
  wcag: ["4.1.2"],
3293
3344
  level: "A",
@@ -3297,18 +3348,18 @@ const Ta = {
3297
3348
  run(t) {
3298
3349
  const a = [];
3299
3350
  for (const e of t.querySelectorAll('[role="tooltip"]')) {
3300
- if (p(e)) continue;
3351
+ if (g(e)) continue;
3301
3352
  v(e) || a.push({
3302
3353
  ruleId: "aria-tooltip-name",
3303
3354
  selector: m(e),
3304
- html: u(e),
3355
+ html: d(e),
3305
3356
  impact: "serious",
3306
3357
  message: "Tooltip has no accessible name."
3307
3358
  });
3308
3359
  }
3309
3360
  return a;
3310
3361
  }
3311
- }, Da = {
3362
+ }, Fa = {
3312
3363
  id: "aria-treeitem-name",
3313
3364
  wcag: ["4.1.2"],
3314
3365
  level: "A",
@@ -3318,18 +3369,18 @@ const Ta = {
3318
3369
  run(t) {
3319
3370
  const a = [];
3320
3371
  for (const e of t.querySelectorAll('[role="treeitem"]')) {
3321
- if (p(e)) continue;
3372
+ if (g(e)) continue;
3322
3373
  v(e) || a.push({
3323
3374
  ruleId: "aria-treeitem-name",
3324
3375
  selector: m(e),
3325
- html: u(e),
3376
+ html: d(e),
3326
3377
  impact: "serious",
3327
3378
  message: "Treeitem has no accessible name."
3328
3379
  });
3329
3380
  }
3330
3381
  return a;
3331
3382
  }
3332
- }, Oa = {
3383
+ }, Wa = {
3333
3384
  id: "aria-prohibited-attr",
3334
3385
  wcag: ["4.1.2"],
3335
3386
  level: "A",
@@ -3337,16 +3388,16 @@ const Ta = {
3337
3388
  guidance: "Some ARIA roles prohibit certain attributes. For example, roles like 'none', 'presentation', 'generic', and text-level roles (code, emphasis, strong) prohibit aria-label and aria-labelledby because naming is not supported for these roles. Remove the prohibited attributes or change the role.",
3338
3389
  prompt: "Identify the prohibited attribute and recommend removing it from this element.",
3339
3390
  run(t) {
3340
- return z(t).prohibitedAttr;
3391
+ return U(t).prohibitedAttr;
3341
3392
  }
3342
- }, Fa = [
3393
+ }, _a = [
3343
3394
  "a[href]",
3344
3395
  "button:not([disabled])",
3345
3396
  'input:not([disabled]):not([type="hidden"])',
3346
3397
  "select:not([disabled])",
3347
3398
  "textarea:not([disabled])",
3348
3399
  '[tabindex]:not([tabindex="-1"])'
3349
- ].join(", "), Ba = [
3400
+ ].join(", "), Pa = [
3350
3401
  "aria-atomic",
3351
3402
  "aria-busy",
3352
3403
  "aria-controls",
@@ -3361,17 +3412,17 @@ const Ta = {
3361
3412
  "aria-owns",
3362
3413
  "aria-relevant"
3363
3414
  ];
3364
- function re(t) {
3415
+ function oe(t) {
3365
3416
  const a = [];
3366
- t.matches(Fa) && a.push("element is focusable");
3367
- for (const e of Ba)
3417
+ t.matches(_a) && a.push("element is focusable");
3418
+ for (const e of Pa)
3368
3419
  if (t.hasAttribute(e)) {
3369
3420
  a.push(`has ${e}`);
3370
3421
  break;
3371
3422
  }
3372
3423
  return (t.hasAttribute("aria-label") || t.hasAttribute("aria-labelledby")) && a.push("has accessible name"), a;
3373
3424
  }
3374
- const Wa = {
3425
+ const ja = {
3375
3426
  id: "presentation-role-conflict",
3376
3427
  wcag: ["4.1.2"],
3377
3428
  level: "A",
@@ -3381,30 +3432,30 @@ const Wa = {
3381
3432
  run(t) {
3382
3433
  const a = [];
3383
3434
  for (const e of t.querySelectorAll('[role="presentation"], [role="none"]')) {
3384
- if (p(e)) continue;
3385
- const i = re(e);
3435
+ if (g(e)) continue;
3436
+ const i = oe(e);
3386
3437
  i.length > 0 && a.push({
3387
3438
  ruleId: "presentation-role-conflict",
3388
3439
  selector: m(e),
3389
- html: u(e),
3440
+ html: d(e),
3390
3441
  impact: "serious",
3391
3442
  message: `Presentation role conflicts with: ${i.join(", ")}. The role will be ignored.`
3392
3443
  });
3393
3444
  }
3394
3445
  for (const e of t.querySelectorAll('img[alt=""]')) {
3395
- if (p(e) || e.hasAttribute("role")) continue;
3396
- const i = re(e);
3446
+ if (g(e) || e.hasAttribute("role")) continue;
3447
+ const i = oe(e);
3397
3448
  i.length > 0 && a.push({
3398
3449
  ruleId: "presentation-role-conflict",
3399
3450
  selector: m(e),
3400
- html: u(e),
3451
+ html: d(e),
3401
3452
  impact: "serious",
3402
3453
  message: `Element with implicit presentation role (alt="") conflicts with: ${i.join(", ")}. The decorative role will be ignored.`
3403
3454
  });
3404
3455
  }
3405
3456
  return a;
3406
3457
  }
3407
- }, _a = {
3458
+ }, Va = {
3408
3459
  id: "summary-name",
3409
3460
  wcag: ["4.1.2"],
3410
3461
  level: "A",
@@ -3414,11 +3465,11 @@ const Wa = {
3414
3465
  run(t) {
3415
3466
  const a = [];
3416
3467
  for (const e of t.querySelectorAll("details > summary:first-of-type")) {
3417
- if (p(e)) continue;
3468
+ if (g(e)) continue;
3418
3469
  v(e) || a.push({
3419
3470
  ruleId: "summary-name",
3420
3471
  selector: m(e),
3421
- html: u(e),
3472
+ html: d(e),
3422
3473
  impact: "serious",
3423
3474
  message: "<summary> element has no accessible name. Add descriptive text."
3424
3475
  });
@@ -3426,7 +3477,7 @@ const Wa = {
3426
3477
  return a;
3427
3478
  }
3428
3479
  };
3429
- function Pa(t) {
3480
+ function za(t) {
3430
3481
  var n, r;
3431
3482
  const a = [], e = t.getAttribute("href");
3432
3483
  e && a.push(`href: ${e}`);
@@ -3443,7 +3494,7 @@ function Pa(t) {
3443
3494
  return a.length > 0 ? a.join(`
3444
3495
  `) : void 0;
3445
3496
  }
3446
- const ja = {
3497
+ const Ua = {
3447
3498
  id: "link-name",
3448
3499
  wcag: ["2.4.4", "4.1.2"],
3449
3500
  level: "A",
@@ -3453,19 +3504,19 @@ const ja = {
3453
3504
  run(t) {
3454
3505
  const a = [];
3455
3506
  for (const e of t.querySelectorAll('a[href], area[href], [role="link"]')) {
3456
- if (p(e)) continue;
3507
+ if (g(e) || T(e) || e.getRootNode() instanceof ShadowRoot) continue;
3457
3508
  v(e) || a.push({
3458
3509
  ruleId: "link-name",
3459
3510
  selector: m(e),
3460
- html: u(e),
3511
+ html: d(e),
3461
3512
  impact: "serious",
3462
3513
  message: "Link has no discernible text.",
3463
- context: Pa(e)
3514
+ context: za(e)
3464
3515
  });
3465
3516
  }
3466
3517
  return a;
3467
3518
  }
3468
- }, Va = {
3519
+ }, Ga = {
3469
3520
  id: "skip-link",
3470
3521
  wcag: ["2.4.1"],
3471
3522
  level: "A",
@@ -3478,20 +3529,20 @@ const ja = {
3478
3529
  for (const i of e) {
3479
3530
  const n = i.getAttribute("href");
3480
3531
  if (!n || n === "#") continue;
3481
- const r = w(i).toLowerCase();
3532
+ const r = A(i).toLowerCase();
3482
3533
  if (!(r.includes("skip") || r.includes("jump") || r.includes("main content") || r.includes("navigation"))) continue;
3483
3534
  const s = n.slice(1);
3484
3535
  t.getElementById(s) || a.push({
3485
3536
  ruleId: "skip-link",
3486
3537
  selector: m(i),
3487
- html: u(i),
3538
+ html: d(i),
3488
3539
  impact: "moderate",
3489
3540
  message: `Skip link points to "#${s}" which does not exist on the page.`
3490
3541
  });
3491
3542
  }
3492
3543
  return a;
3493
3544
  }
3494
- }, za = /* @__PURE__ */ new Set([
3545
+ }, Ya = /* @__PURE__ */ new Set([
3495
3546
  "block",
3496
3547
  "flex",
3497
3548
  "grid",
@@ -3499,23 +3550,23 @@ const ja = {
3499
3550
  "table-cell",
3500
3551
  "list-item",
3501
3552
  "flow-root"
3502
- ]), Ua = /* @__PURE__ */ new Set([
3553
+ ]), Xa = /* @__PURE__ */ new Set([
3503
3554
  "inline",
3504
3555
  "inline-block",
3505
3556
  "inline-flex",
3506
3557
  "inline-grid"
3507
3558
  ]);
3508
- function Ga(t) {
3559
+ function Ka(t) {
3509
3560
  let a = t.parentElement;
3510
3561
  for (; a; ) {
3511
- const e = A(a).display;
3512
- if (za.has(e))
3513
- return Xa(a) ? a : null;
3562
+ const e = w(a).display;
3563
+ if (Ya.has(e))
3564
+ return Ja(a) ? a : null;
3514
3565
  a = a.parentElement;
3515
3566
  }
3516
3567
  return null;
3517
3568
  }
3518
- function Xa(t) {
3569
+ function Ja(t) {
3519
3570
  const a = t.ownerDocument.createTreeWalker(
3520
3571
  t,
3521
3572
  NodeFilter.SHOW_TEXT
@@ -3535,7 +3586,7 @@ function Xa(t) {
3535
3586
  }
3536
3587
  return /[a-zA-Z\u00C0-\u024F]{2,}/.test(e);
3537
3588
  }
3538
- function Ya(t, a) {
3589
+ function Qa(t, a) {
3539
3590
  const e = t.ownerDocument.createTreeWalker(
3540
3591
  t,
3541
3592
  NodeFilter.SHOW_TEXT
@@ -3552,11 +3603,11 @@ function Ya(t, a) {
3552
3603
  o = o.parentElement;
3553
3604
  }
3554
3605
  if (!r && n)
3555
- return R(A(n).color);
3606
+ return N(w(n).color);
3556
3607
  }
3557
3608
  return null;
3558
3609
  }
3559
- function Ka(t, a) {
3610
+ function Za(t, a) {
3560
3611
  const e = t.textDecorationLine || t.textDecoration || "", i = a.textDecorationLine || a.textDecoration || "";
3561
3612
  if ((e.includes("underline") || e.includes("line-through")) && e !== i)
3562
3613
  return !0;
@@ -3569,19 +3620,19 @@ function Ka(t, a) {
3569
3620
  const l = t.backgroundImage || "";
3570
3621
  if (l && l !== "none" && l !== "initial")
3571
3622
  return !0;
3572
- const h = oe(t.fontWeight), c = oe(a.fontWeight);
3623
+ const h = se(t.fontWeight), c = se(a.fontWeight);
3573
3624
  if (Math.abs(h - c) >= 300 || t.fontStyle !== a.fontStyle)
3574
3625
  return !0;
3575
- const d = parseFloat(t.fontSize) || 16, g = parseFloat(a.fontSize) || 16;
3576
- return g > 0 && d / g >= 1.2;
3626
+ const u = parseFloat(t.fontSize) || 16, p = parseFloat(a.fontSize) || 16;
3627
+ return p > 0 && u / p >= 1.2;
3577
3628
  }
3578
- function oe(t) {
3629
+ function se(t) {
3579
3630
  return t === "bold" ? 700 : t === "normal" ? 400 : parseInt(t) || 400;
3580
3631
  }
3581
- function se(t, a, e) {
3632
+ function le(t, a, e) {
3582
3633
  return "#" + [t, a, e].map((i) => i.toString(16).padStart(2, "0")).join("");
3583
3634
  }
3584
- const Ja = {
3635
+ const ei = {
3585
3636
  id: "link-in-text-block",
3586
3637
  wcag: ["1.4.1"],
3587
3638
  level: "A",
@@ -3591,22 +3642,22 @@ const Ja = {
3591
3642
  run(t) {
3592
3643
  const a = [];
3593
3644
  for (const e of t.querySelectorAll("a[href]")) {
3594
- if (p(e) || !w(e).trim() || e.closest('nav, header, footer, [role="navigation"], [role="banner"], [role="contentinfo"]')) continue;
3595
- const i = A(e), n = i.display || "inline";
3596
- if (!Ua.has(n)) continue;
3597
- const r = Ga(e);
3645
+ if (g(e) || !A(e).trim() || e.closest('nav, header, footer, [role="navigation"], [role="banner"], [role="contentinfo"]')) continue;
3646
+ const i = w(e), n = i.display || "inline";
3647
+ if (!Xa.has(n)) continue;
3648
+ const r = Ka(e);
3598
3649
  if (!r) continue;
3599
- const o = A(r);
3600
- if (Ka(i, o)) continue;
3601
- const s = R(i.color), l = Ya(r);
3650
+ const o = w(r);
3651
+ if (Za(i, o)) continue;
3652
+ const s = N(i.color), l = Qa(r);
3602
3653
  if (!s || !l) continue;
3603
- const h = q(...s), c = q(...l), d = de(h, c);
3604
- if (d >= 3) continue;
3605
- const g = se(...s), b = se(...l), f = `link color: ${g} rgb(${s.join(", ")}), surrounding text: ${b} rgb(${l.join(", ")}), ratio: ${d.toFixed(2)}:1`;
3654
+ const h = R(...s), c = R(...l), u = me(h, c);
3655
+ if (u >= 3) continue;
3656
+ const p = le(...s), b = le(...l), f = `link color: ${p} rgb(${s.join(", ")}), surrounding text: ${b} rgb(${l.join(", ")}), ratio: ${u.toFixed(2)}:1`;
3606
3657
  a.push({
3607
3658
  ruleId: "link-in-text-block",
3608
3659
  selector: m(e),
3609
- html: u(e),
3660
+ html: d(e),
3610
3661
  impact: "serious",
3611
3662
  message: "Link in text block is not visually distinguishable from surrounding text. Add an underline, border, or ensure 3:1 color contrast with surrounding text.",
3612
3663
  context: f
@@ -3614,7 +3665,7 @@ const Ja = {
3614
3665
  }
3615
3666
  return a;
3616
3667
  }
3617
- }, Qa = {
3668
+ }, ti = {
3618
3669
  id: "html-has-lang",
3619
3670
  wcag: ["3.1.1"],
3620
3671
  level: "A",
@@ -3640,7 +3691,7 @@ const Ja = {
3640
3691
  return [{
3641
3692
  ruleId: "html-has-lang",
3642
3693
  selector: m(a),
3643
- html: u(a),
3694
+ html: d(a),
3644
3695
  impact: "serious",
3645
3696
  message: "<html> element missing lang attribute.",
3646
3697
  context: n ? `Page text sample: "${n}"` : void 0
@@ -3648,17 +3699,17 @@ const Ja = {
3648
3699
  }
3649
3700
  return [];
3650
3701
  }
3651
- }, Za = new Set(
3702
+ }, ai = new Set(
3652
3703
  "aa ab ae af ak am an ar as av ay az ba be bg bh bi bm bn bo br bs ca ce ch co cr cs cu cv cy da de dv dz ee el en eo es et eu fa ff fi fj fo fr fy ga gd gl gn gu gv ha he hi ho hr ht hu hy hz ia id ie ig ii ik io is it iu ja jv ka kg ki kj kk kl km kn ko kr ks ku kv kw ky la lb lg li ln lo lt lu lv mg mh mi mk ml mn mr ms mt my na nb nd ne ng nl nn no nr nv ny oc oj om or os pa pi pl ps pt qu rm rn ro ru rw sa sc sd se sg si sk sl sm sn so sq sr ss st su sv sw ta te tg th ti tk tl tn to tr ts tt tw ty ug uk ur uz ve vi vo wa wo xh yi yo za zh zu".split(" ")
3653
- ), ei = new Set(
3704
+ ), ii = new Set(
3654
3705
  "aar abk afr aka amh ara arg asm ava ave aym aze bak bam bel ben bih bis bod bos bre bul cat ces cha che chu chv cor cos cre cym dan deu div dzo ell eng epo est eus ewe fao fas fij fin fra fry ful gla gle glg glv grn guj hat hau hbs heb her hin hmo hrv hun hye ibo iii iku ile ina ind ipk isl ita jav jpn kal kan kas kat kau kaz khm kik kin kir kom kon kor kua kur lao lat lav lim lin lit ltz lub lug mah mal mar mkd mlg mlt mon mri msa mya nau nav nbl nde ndo nep nld nno nob nor nya oci oji ori orm oss pan pli pol por pus que roh ron run rus sag san sin slk slv sme smo sna snd som sot spa sqi srd srp ssw sun swa swe tah tam tat tel tgk tgl tha tir ton tsn tso tuk tur twi uig ukr urd uzb ven vie vol wln wol xho yid yor zha zho zul".split(" ")
3655
- ), ti = /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i;
3656
- function he(t) {
3657
- if (!ti.test(t)) return !1;
3706
+ ), ni = /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i;
3707
+ function pe(t) {
3708
+ if (!ni.test(t)) return !1;
3658
3709
  const a = t.split("-")[0].toLowerCase();
3659
- return a.length === 2 ? Za.has(a) : a.length === 3 ? !ei.has(a) : !1;
3710
+ return a.length === 2 ? ai.has(a) : a.length === 3 ? !ii.has(a) : !1;
3660
3711
  }
3661
- const ai = {
3712
+ const ri = {
3662
3713
  id: "html-lang-valid",
3663
3714
  wcag: ["3.1.1"],
3664
3715
  level: "A",
@@ -3668,16 +3719,16 @@ const ai = {
3668
3719
  run(t) {
3669
3720
  var e;
3670
3721
  const a = (e = t.documentElement.getAttribute("lang")) == null ? void 0 : e.trim();
3671
- return a && !he(a) ? [{
3722
+ return a && !pe(a) ? [{
3672
3723
  ruleId: "html-lang-valid",
3673
3724
  selector: "html",
3674
- html: u(t.documentElement),
3725
+ html: d(t.documentElement),
3675
3726
  impact: "serious",
3676
3727
  message: `Invalid lang attribute value "${a}".`
3677
3728
  }] : [];
3678
3729
  }
3679
3730
  };
3680
- function le(t) {
3731
+ function ce(t) {
3681
3732
  var i;
3682
3733
  const a = t.ownerDocument.createTreeWalker(t, NodeFilter.SHOW_TEXT);
3683
3734
  let e;
@@ -3709,7 +3760,7 @@ function le(t) {
3709
3760
  }
3710
3761
  return !1;
3711
3762
  }
3712
- const ii = {
3763
+ const oi = {
3713
3764
  id: "valid-lang",
3714
3765
  wcag: ["3.1.2"],
3715
3766
  level: "AA",
@@ -3719,29 +3770,29 @@ const ii = {
3719
3770
  run(t) {
3720
3771
  const a = [];
3721
3772
  for (const e of t.querySelectorAll("[lang]")) {
3722
- if (p(e) || e === t.documentElement) continue;
3773
+ if (g(e) || e === t.documentElement) continue;
3723
3774
  const i = e.getAttribute("lang"), n = i == null ? void 0 : i.trim();
3724
3775
  if (i && !n) {
3725
- le(e) && a.push({
3776
+ ce(e) && a.push({
3726
3777
  ruleId: "valid-lang",
3727
3778
  selector: m(e),
3728
- html: u(e),
3779
+ html: d(e),
3729
3780
  impact: "serious",
3730
3781
  message: "Empty lang attribute value."
3731
3782
  });
3732
3783
  continue;
3733
3784
  }
3734
- n && le(e) && (he(n) || a.push({
3785
+ n && ce(e) && (pe(n) || a.push({
3735
3786
  ruleId: "valid-lang",
3736
3787
  selector: m(e),
3737
- html: u(e),
3788
+ html: d(e),
3738
3789
  impact: "serious",
3739
3790
  message: `Invalid lang attribute value "${n}".`
3740
3791
  }));
3741
3792
  }
3742
3793
  return a;
3743
3794
  }
3744
- }, ni = {
3795
+ }, si = {
3745
3796
  id: "html-xml-lang-mismatch",
3746
3797
  wcag: ["3.1.1"],
3747
3798
  level: "A",
@@ -3757,14 +3808,14 @@ const ii = {
3757
3808
  return [{
3758
3809
  ruleId: "html-xml-lang-mismatch",
3759
3810
  selector: "html",
3760
- html: u(a),
3811
+ html: d(a),
3761
3812
  impact: "moderate",
3762
3813
  message: `lang="${e}" and xml:lang="${i}" do not match.`
3763
3814
  }];
3764
3815
  }
3765
3816
  return [];
3766
3817
  }
3767
- }, ri = {
3818
+ }, li = {
3768
3819
  id: "td-headers-attr",
3769
3820
  wcag: ["1.3.1"],
3770
3821
  level: "A",
@@ -3774,7 +3825,7 @@ const ii = {
3774
3825
  run(t) {
3775
3826
  const a = [];
3776
3827
  for (const e of t.querySelectorAll("td[headers]")) {
3777
- if (p(e)) continue;
3828
+ if (g(e)) continue;
3778
3829
  const i = e.closest("table");
3779
3830
  if (!i) continue;
3780
3831
  const n = e.getAttribute("id"), r = e.getAttribute("headers").split(/\s+/);
@@ -3783,7 +3834,7 @@ const ii = {
3783
3834
  a.push({
3784
3835
  ruleId: "td-headers-attr",
3785
3836
  selector: m(e),
3786
- html: u(e),
3837
+ html: d(e),
3787
3838
  impact: "serious",
3788
3839
  message: `Headers attribute references the cell itself ("${o}").`
3789
3840
  });
@@ -3793,7 +3844,7 @@ const ii = {
3793
3844
  a.push({
3794
3845
  ruleId: "td-headers-attr",
3795
3846
  selector: m(e),
3796
- html: u(e),
3847
+ html: d(e),
3797
3848
  impact: "serious",
3798
3849
  message: `Headers attribute references non-existent ID "${o}".`
3799
3850
  });
@@ -3803,7 +3854,7 @@ const ii = {
3803
3854
  }
3804
3855
  return a;
3805
3856
  }
3806
- }, oi = {
3857
+ }, ci = {
3807
3858
  id: "th-has-data-cells",
3808
3859
  wcag: ["1.3.1"],
3809
3860
  level: "A",
@@ -3813,19 +3864,19 @@ const ii = {
3813
3864
  run(t) {
3814
3865
  const a = [];
3815
3866
  for (const e of t.querySelectorAll("table")) {
3816
- if (p(e) || e.getAttribute("role") === "presentation" || e.getAttribute("role") === "none") continue;
3867
+ if (g(e) || e.getAttribute("role") === "presentation" || e.getAttribute("role") === "none") continue;
3817
3868
  const i = e.querySelectorAll("th"), n = e.querySelectorAll("td");
3818
3869
  i.length > 0 && n.length === 0 && a.push({
3819
3870
  ruleId: "th-has-data-cells",
3820
3871
  selector: m(e),
3821
- html: u(e),
3872
+ html: d(e),
3822
3873
  impact: "serious",
3823
3874
  message: "Table has header cells but no data cells."
3824
3875
  });
3825
3876
  }
3826
3877
  return a;
3827
3878
  }
3828
- }, si = {
3879
+ }, ui = {
3829
3880
  id: "td-has-header",
3830
3881
  wcag: ["1.3.1"],
3831
3882
  level: "A",
@@ -3836,24 +3887,24 @@ const ii = {
3836
3887
  var e, i;
3837
3888
  const a = [];
3838
3889
  for (const n of t.querySelectorAll("table")) {
3839
- if (p(n) || n.getAttribute("role") === "presentation" || n.getAttribute("role") === "none") continue;
3890
+ if (g(n) || n.getAttribute("role") === "presentation" || n.getAttribute("role") === "none") continue;
3840
3891
  const r = n.querySelectorAll("tr"), o = r.length;
3841
3892
  let s = 0;
3842
- for (const d of r) {
3843
- const g = d.querySelectorAll("td, th");
3893
+ for (const u of r) {
3894
+ const p = u.querySelectorAll("td, th");
3844
3895
  let b = 0;
3845
- for (const f of g)
3896
+ for (const f of p)
3846
3897
  b += parseInt(f.getAttribute("colspan") || "1", 10);
3847
3898
  s = Math.max(s, b);
3848
3899
  }
3849
3900
  if (o <= 3 && s <= 3) continue;
3850
3901
  const l = n.querySelector("th") !== null, h = n.querySelector("th[scope]") !== null, c = n.querySelector("td[headers]") !== null;
3851
3902
  if (l)
3852
- for (const d of n.querySelectorAll("td")) {
3853
- if (p(d) || d.hasAttribute("headers")) continue;
3854
- const g = d.closest("tr");
3855
- if (!g) continue;
3856
- const b = g.querySelector("th") !== null, f = Array.from(g.children).indexOf(d);
3903
+ for (const u of n.querySelectorAll("td")) {
3904
+ if (g(u) || u.hasAttribute("headers")) continue;
3905
+ const p = u.closest("tr");
3906
+ if (!p) continue;
3907
+ const b = p.querySelector("th") !== null, f = Array.from(p.children).indexOf(u);
3857
3908
  let y = !1;
3858
3909
  const I = n.querySelector("thead");
3859
3910
  if (I) {
@@ -3867,8 +3918,8 @@ const ii = {
3867
3918
  if (!b && !y && !h && !c) {
3868
3919
  a.push({
3869
3920
  ruleId: "td-has-header",
3870
- selector: m(d),
3871
- html: u(d),
3921
+ selector: m(u),
3922
+ html: d(u),
3872
3923
  impact: "serious",
3873
3924
  message: "Data cell has no associated header. Add th elements with scope, or headers attribute."
3874
3925
  });
@@ -3878,7 +3929,7 @@ const ii = {
3878
3929
  }
3879
3930
  return a;
3880
3931
  }
3881
- }, li = {
3932
+ }, di = {
3882
3933
  id: "scope-attr-valid",
3883
3934
  wcag: ["1.3.1"],
3884
3935
  level: "A",
@@ -3889,19 +3940,19 @@ const ii = {
3889
3940
  var i;
3890
3941
  const a = [], e = /* @__PURE__ */ new Set(["row", "col", "rowgroup", "colgroup"]);
3891
3942
  for (const n of t.querySelectorAll("th[scope]")) {
3892
- if (p(n)) continue;
3943
+ if (g(n)) continue;
3893
3944
  const r = (i = n.getAttribute("scope")) == null ? void 0 : i.toLowerCase();
3894
3945
  r && !e.has(r) && a.push({
3895
3946
  ruleId: "scope-attr-valid",
3896
3947
  selector: m(n),
3897
- html: u(n),
3948
+ html: d(n),
3898
3949
  impact: "moderate",
3899
3950
  message: `Invalid scope value "${r}". Use row, col, rowgroup, or colgroup.`
3900
3951
  });
3901
3952
  }
3902
3953
  return a;
3903
3954
  }
3904
- }, ci = {
3955
+ }, mi = {
3905
3956
  id: "empty-table-header",
3906
3957
  wcag: [],
3907
3958
  level: "A",
@@ -3912,19 +3963,19 @@ const ii = {
3912
3963
  run(t) {
3913
3964
  const a = [];
3914
3965
  for (const e of t.querySelectorAll("th")) {
3915
- if (p(e)) continue;
3966
+ if (g(e)) continue;
3916
3967
  const i = e.closest("table");
3917
3968
  (i == null ? void 0 : i.getAttribute("role")) === "presentation" || (i == null ? void 0 : i.getAttribute("role")) === "none" || v(e) || a.push({
3918
3969
  ruleId: "empty-table-header",
3919
3970
  selector: m(e),
3920
- html: u(e),
3971
+ html: d(e),
3921
3972
  impact: "minor",
3922
3973
  message: "Table header cell is empty. Add text or use aria-label."
3923
3974
  });
3924
3975
  }
3925
3976
  return a;
3926
3977
  }
3927
- }, D = ["aria-labelledby", "aria-describedby", "aria-controls", "aria-owns", "aria-flowto"], ui = {
3978
+ }, O = ["aria-labelledby", "aria-describedby", "aria-controls", "aria-owns", "aria-flowto"], hi = {
3928
3979
  id: "duplicate-id-aria",
3929
3980
  wcag: ["4.1.2"],
3930
3981
  level: "A",
@@ -3934,7 +3985,7 @@ const ii = {
3934
3985
  run(t) {
3935
3986
  const a = [], e = /* @__PURE__ */ new Set();
3936
3987
  for (const n of t.querySelectorAll("[aria-labelledby], [aria-describedby], [aria-controls], [aria-owns], [aria-flowto]"))
3937
- for (const r of D) {
3988
+ for (const r of O) {
3938
3989
  const o = n.getAttribute(r);
3939
3990
  o && o.split(/\s+/).forEach((s) => e.add(s));
3940
3991
  }
@@ -3948,14 +3999,14 @@ const ii = {
3948
3999
  for (const [n, r] of i) {
3949
4000
  if (r <= 1) continue;
3950
4001
  const o = t.querySelectorAll(`#${CSS.escape(n)}`), s = t.querySelector(
3951
- D.map((c) => `[${c}~="${CSS.escape(n)}"]`).join(", ")
4002
+ O.map((c) => `[${c}~="${CSS.escape(n)}"]`).join(", ")
3952
4003
  ), l = t.querySelector(`label[for="${CSS.escape(n)}"]`);
3953
4004
  let h;
3954
4005
  if (s) {
3955
- const c = D.find(
3956
- (d) => {
3957
- var g;
3958
- return (g = s.getAttribute(d)) == null ? void 0 : g.split(/\s+/).includes(n);
4006
+ const c = O.find(
4007
+ (u) => {
4008
+ var p;
4009
+ return (p = s.getAttribute(u)) == null ? void 0 : p.split(/\s+/).includes(n);
3959
4010
  }
3960
4011
  );
3961
4012
  c && (h = c);
@@ -3963,16 +4014,16 @@ const ii = {
3963
4014
  a.push({
3964
4015
  ruleId: "duplicate-id-aria",
3965
4016
  selector: m(o[1]),
3966
- html: u(o[1]),
4017
+ html: d(o[1]),
3967
4018
  impact: "critical",
3968
4019
  message: `Duplicate ID "${n}" referenced by ${h ?? "an accessibility attribute"}.`,
3969
- context: `First element: ${u(o[0])}${h ? `
4020
+ context: `First element: ${d(o[0])}${h ? `
3970
4021
  Referenced by: ${h}` : ""}`
3971
4022
  });
3972
4023
  }
3973
4024
  return a;
3974
4025
  }
3975
- }, di = {
4026
+ }, pi = {
3976
4027
  id: "video-caption",
3977
4028
  wcag: ["1.2.2"],
3978
4029
  level: "A",
@@ -3982,18 +4033,18 @@ Referenced by: ${h}` : ""}`
3982
4033
  run(t) {
3983
4034
  const a = [];
3984
4035
  for (const e of t.querySelectorAll("video")) {
3985
- if (p(e) || e.hasAttribute("muted") || e.hasAttribute("autoplay")) continue;
4036
+ if (g(e) || e.hasAttribute("muted") || e.hasAttribute("autoplay")) continue;
3986
4037
  e.querySelector('track[kind="captions"], track[kind="subtitles"]') || a.push({
3987
4038
  ruleId: "video-caption",
3988
4039
  selector: m(e),
3989
- html: u(e),
4040
+ html: d(e),
3990
4041
  impact: "critical",
3991
4042
  message: "Video element has no captions track."
3992
4043
  });
3993
4044
  }
3994
4045
  return a;
3995
4046
  }
3996
- }, mi = {
4047
+ }, gi = {
3997
4048
  id: "audio-caption",
3998
4049
  wcag: ["1.2.1"],
3999
4050
  level: "A",
@@ -4003,19 +4054,19 @@ Referenced by: ${h}` : ""}`
4003
4054
  run(t) {
4004
4055
  const a = [];
4005
4056
  for (const e of t.querySelectorAll("audio")) {
4006
- if (p(e) || e.querySelector('track[kind="captions"], track[kind="descriptions"]') || e.hasAttribute("aria-describedby")) continue;
4057
+ if (g(e) || e.querySelector('track[kind="captions"], track[kind="descriptions"]') || e.hasAttribute("aria-describedby")) continue;
4007
4058
  const n = e.parentElement;
4008
4059
  n && n.querySelector('a[href*="transcript"], a[href*="text"]') || a.push({
4009
4060
  ruleId: "audio-caption",
4010
4061
  selector: m(e),
4011
- html: u(e),
4062
+ html: d(e),
4012
4063
  impact: "critical",
4013
4064
  message: "Audio element has no transcript or text alternative. Add a transcript or track element."
4014
4065
  });
4015
4066
  }
4016
4067
  return a;
4017
4068
  }
4018
- }, hi = /* @__PURE__ */ new Set([
4069
+ }, bi = /* @__PURE__ */ new Set([
4019
4070
  "SCRIPT",
4020
4071
  "STYLE",
4021
4072
  "NOSCRIPT",
@@ -4031,13 +4082,13 @@ Referenced by: ${h}` : ""}`
4031
4082
  "BR",
4032
4083
  "HR"
4033
4084
  ]);
4034
- function ce([t, a, e]) {
4085
+ function ue([t, a, e]) {
4035
4086
  return "#" + [t, a, e].map((i) => i.toString(16).padStart(2, "0")).join("");
4036
4087
  }
4037
- function pi(t) {
4088
+ function fi(t) {
4038
4089
  return t instanceof HTMLInputElement || t instanceof HTMLTextAreaElement || t instanceof HTMLSelectElement || t instanceof HTMLButtonElement ? t.disabled : !!(t.closest("fieldset[disabled]") || t.getAttribute("aria-disabled") === "true");
4039
4090
  }
4040
- function gi(t, a) {
4091
+ function vi(t, a) {
4041
4092
  if (t.tagName !== "LABEL") return !1;
4042
4093
  const e = t, i = e.htmlFor;
4043
4094
  if (i) {
@@ -4049,7 +4100,7 @@ function gi(t, a) {
4049
4100
  const r = e.id;
4050
4101
  return !!(r && a.querySelector(`[aria-labelledby~="${r}"][aria-disabled="true"]`));
4051
4102
  }
4052
- function bi(t) {
4103
+ function yi(t) {
4053
4104
  const a = t.clip;
4054
4105
  if (a && a.startsWith("rect(")) {
4055
4106
  const i = a.match(/[\d.]+/g);
@@ -4063,17 +4114,41 @@ function bi(t) {
4063
4114
  }
4064
4115
  return !1;
4065
4116
  }
4066
- function fi(t) {
4067
- if (p(t)) return !0;
4117
+ function wi(t) {
4118
+ if (g(t)) return !0;
4119
+ let a = t;
4120
+ for (; a; ) {
4121
+ const e = w(a);
4122
+ if (e.display === "none" || e.visibility === "hidden" || yi(e)) return !0;
4123
+ a = a.parentElement;
4124
+ }
4125
+ return !1;
4126
+ }
4127
+ function Ai(t) {
4128
+ let a = 1, e = t;
4129
+ for (; e; ) {
4130
+ const i = w(e), n = parseFloat(i.opacity);
4131
+ isNaN(n) || (a *= n), e = e.parentElement;
4132
+ }
4133
+ return a;
4134
+ }
4135
+ function xi(t) {
4068
4136
  let a = t;
4069
4137
  for (; a; ) {
4070
- const e = A(a);
4071
- if (e.display === "none" || e.visibility === "hidden" || bi(e)) return !0;
4138
+ const e = w(a), i = e.filter;
4139
+ if (i && i !== "none" && i !== "initial") return !0;
4140
+ const n = e.mixBlendMode;
4141
+ if (n && n !== "normal" && n !== "initial") return !0;
4142
+ const r = e.backdropFilter;
4143
+ if (r && r !== "none" && r !== "initial") return !0;
4072
4144
  a = a.parentElement;
4073
4145
  }
4074
4146
  return !1;
4075
4147
  }
4076
- const vi = {
4148
+ function Si(t) {
4149
+ return t.closest("select") !== null;
4150
+ }
4151
+ const ki = {
4077
4152
  id: "color-contrast",
4078
4153
  wcag: ["1.4.3"],
4079
4154
  level: "AA",
@@ -4088,96 +4163,96 @@ const vi = {
4088
4163
  for (; r = i.nextNode(); ) {
4089
4164
  if (!r.textContent || !r.textContent.trim()) continue;
4090
4165
  const o = r.parentElement;
4091
- if (!o || n.has(o) || (n.add(o), hi.has(o.tagName)) || pi(o) || gi(o, t) || fi(o)) continue;
4092
- const s = A(o);
4093
- if (parseFloat(s.opacity) === 0) continue;
4094
- const l = s.textShadow;
4095
- if (l && l !== "none" && l !== "initial") continue;
4096
- const h = R(s.color);
4097
- if (!h) continue;
4098
- const c = s.color.match(/rgba\(.+?,\s*([\d.]+)\s*\)/) || s.color.match(/rgba?\(.+?\/\s*([\d.]+%?)\s*\)/);
4099
- if (c && (c[1].endsWith("%") ? parseFloat(c[1]) / 100 : parseFloat(c[1])) === 0 || Be(o)) continue;
4100
- const d = De(o);
4101
- if (!d) continue;
4102
- const g = q(h[0], h[1], h[2]), b = q(d[0], d[1], d[2]), f = de(g, b), y = Pe(o) ? 3 : 4.5;
4103
- if (f < y) {
4104
- const I = Math.round(f * 100) / 100, x = ce(h), $ = ce(d);
4166
+ if (!o || n.has(o) || (n.add(o), bi.has(o.tagName))) continue;
4167
+ const s = o.tagName;
4168
+ if (s === "BODY" || s === "HTML" || Si(o) || fi(o) || vi(o, t) || wi(o)) continue;
4169
+ const l = w(o);
4170
+ if (parseFloat(l.opacity) === 0 || Ai(o) < 0.1) continue;
4171
+ const h = l.textShadow;
4172
+ if (h && h !== "none" && h !== "initial" || xi(o)) continue;
4173
+ const c = N(l.color);
4174
+ if (!c) continue;
4175
+ const u = l.color.match(/rgba\(.+?,\s*([\d.]+)\s*\)/) || l.color.match(/rgba?\(.+?\/\s*([\d.]+%?)\s*\)/);
4176
+ if (u && (u[1].endsWith("%") ? parseFloat(u[1]) / 100 : parseFloat(u[1])) === 0 || _e(o)) continue;
4177
+ const p = Be(o);
4178
+ if (!p) continue;
4179
+ const b = R(c[0], c[1], c[2]), f = R(p[0], p[1], p[2]), y = me(b, f), I = Ve(o) ? 3 : 4.5;
4180
+ if (y < I) {
4181
+ const x = Math.round(y * 100) / 100, M = ue(c), ye = ue(p);
4105
4182
  a.push({
4106
4183
  ruleId: "color-contrast",
4107
4184
  selector: m(o),
4108
- html: u(o),
4185
+ html: d(o),
4109
4186
  impact: "serious",
4110
- message: `Insufficient color contrast ratio of ${I}:1 (required ${y}:1).`,
4111
- context: `foreground: ${x} rgb(${h.join(", ")}), background: ${$} rgb(${d.join(", ")}), ratio: ${I}:1, required: ${y}:1`
4187
+ message: `Insufficient color contrast ratio of ${x}:1 (required ${I}:1).`,
4188
+ context: `foreground: ${M} rgb(${c.join(", ")}), background: ${ye} rgb(${p.join(", ")}), ratio: ${x}:1, required: ${I}:1`
4112
4189
  });
4113
4190
  }
4114
4191
  }
4115
4192
  return a;
4116
4193
  }
4117
- }, pe = [
4194
+ }, ge = [
4118
4195
  // Document Structure
4119
- Kt,
4120
- Jt,
4121
- Qt,
4122
4196
  Zt,
4123
4197
  ea,
4198
+ ta,
4124
4199
  aa,
4125
4200
  ia,
4126
4201
  ra,
4127
- sa,
4202
+ oa,
4203
+ la,
4204
+ ua,
4128
4205
  // Images
4129
- je,
4130
4206
  ze,
4131
- Ue,
4132
4207
  Ge,
4133
4208
  Ye,
4134
- Ke,
4209
+ Xe,
4210
+ Je,
4135
4211
  Qe,
4136
- Ze,
4137
- it,
4212
+ et,
4213
+ tt,
4214
+ rt,
4138
4215
  // Forms
4139
- lt,
4140
- ct,
4141
4216
  ut,
4142
4217
  dt,
4143
- vt,
4144
- yt,
4218
+ mt,
4219
+ ht,
4145
4220
  wt,
4146
- // Keyboard
4221
+ At,
4147
4222
  xt,
4223
+ // Keyboard
4148
4224
  kt,
4149
- Rt,
4150
- Nt,
4225
+ Tt,
4151
4226
  $t,
4152
- // Structure
4153
4227
  Mt,
4154
- ta,
4155
- la,
4156
4228
  Ht,
4229
+ // Structure
4157
4230
  Dt,
4231
+ na,
4232
+ da,
4158
4233
  Ot,
4159
- Ft,
4160
4234
  Bt,
4235
+ Ft,
4161
4236
  Wt,
4162
4237
  _t,
4163
4238
  Pt,
4164
4239
  jt,
4165
4240
  Vt,
4241
+ zt,
4166
4242
  Ut,
4167
- Gt,
4168
4243
  Yt,
4244
+ Qt,
4245
+ Xt,
4246
+ Jt,
4169
4247
  // ARIA
4170
- ca,
4171
- ua,
4172
- da,
4248
+ ma,
4173
4249
  ha,
4174
- va,
4250
+ pa,
4251
+ ba,
4175
4252
  Aa,
4176
- Sa,
4177
4253
  ka,
4254
+ Ta,
4178
4255
  Ea,
4179
- Ca,
4180
- La,
4181
4256
  qa,
4182
4257
  Ra,
4183
4258
  Na,
@@ -4186,42 +4261,45 @@ const vi = {
4186
4261
  Ha,
4187
4262
  Da,
4188
4263
  Oa,
4264
+ Ba,
4265
+ Fa,
4189
4266
  Wa,
4190
- ga,
4191
- _a,
4192
- // Links
4193
4267
  ja,
4268
+ va,
4194
4269
  Va,
4195
- Ja,
4270
+ // Links
4271
+ Ua,
4272
+ Ga,
4273
+ ei,
4196
4274
  // Language
4197
- Qa,
4198
- ai,
4199
- ii,
4200
- ni,
4201
- // Tables
4275
+ ti,
4202
4276
  ri,
4203
4277
  oi,
4204
4278
  si,
4279
+ // Tables
4205
4280
  li,
4206
4281
  ci,
4207
- // Parsing
4208
4282
  ui,
4209
- // Media
4210
4283
  di,
4211
4284
  mi,
4285
+ // Parsing
4286
+ hi,
4287
+ // Media
4288
+ pi,
4289
+ gi,
4212
4290
  // Color
4213
- vi
4291
+ ki
4214
4292
  ];
4215
- let U = [], ge = /* @__PURE__ */ new Set();
4216
- function xi(t) {
4217
- t.additionalRules && (U = t.additionalRules), t.disabledRules && (ge = new Set(t.disabledRules));
4293
+ let G = [], be = /* @__PURE__ */ new Set();
4294
+ function Ci(t) {
4295
+ t.additionalRules && (G = t.additionalRules), t.disabledRules && (be = new Set(t.disabledRules));
4218
4296
  }
4219
- function be() {
4220
- return pe.filter((a) => !ge.has(a.id)).concat(U);
4297
+ function fe() {
4298
+ return ge.filter((a) => !be.has(a.id)).concat(G);
4221
4299
  }
4222
- function Si(t) {
4223
- fe();
4224
- const a = be(), e = [];
4300
+ function Li(t) {
4301
+ ve();
4302
+ const a = fe(), e = [];
4225
4303
  let i = 0;
4226
4304
  return {
4227
4305
  processChunk(n) {
@@ -4240,13 +4318,13 @@ function Si(t) {
4240
4318
  }
4241
4319
  };
4242
4320
  }
4243
- function fe() {
4244
- Se(), ve(), ye(), He(), Me(), Ie();
4321
+ function ve() {
4322
+ Ie(), we(), Ae(), Oe(), De(), Ee();
4245
4323
  }
4246
- function ki(t) {
4324
+ function qi(t) {
4247
4325
  var i;
4248
- fe();
4249
- const a = be(), e = [];
4326
+ ve();
4327
+ const a = fe(), e = [];
4250
4328
  for (const n of a)
4251
4329
  try {
4252
4330
  e.push(...n.run(t));
@@ -4259,32 +4337,32 @@ function ki(t) {
4259
4337
  ruleCount: a.length
4260
4338
  };
4261
4339
  }
4262
- const yi = new Map(pe.map((t) => [t.id, t]));
4263
- function Ii(t) {
4264
- const a = yi.get(t);
4265
- return a || U.find((e) => e.id === t);
4340
+ const Ii = new Map(ge.map((t) => [t.id, t]));
4341
+ function Ri(t) {
4342
+ const a = Ii.get(t);
4343
+ return a || G.find((e) => e.id === t);
4266
4344
  }
4267
4345
  export {
4268
- fe as clearAllCaches,
4269
- Me as clearAriaAttrAuditCache,
4270
- Se as clearAriaHiddenCache,
4271
- He as clearColorCaches,
4272
- ve as clearComputedRoleCache,
4346
+ ve as clearAllCaches,
4347
+ De as clearAriaAttrAuditCache,
4348
+ Ie as clearAriaHiddenCache,
4349
+ Oe as clearColorCaches,
4350
+ we as clearComputedRoleCache,
4273
4351
  k as compileDeclarativeRule,
4274
- xi as configureRules,
4275
- Si as createChunkedAudit,
4352
+ Ci as configureRules,
4353
+ Li as createChunkedAudit,
4276
4354
  v as getAccessibleName,
4277
- w as getAccessibleTextContent,
4278
- be as getActiveRules,
4279
- L as getComputedRole,
4280
- u as getHtmlSnippet,
4281
- ue as getImplicitRole,
4282
- Ii as getRuleById,
4355
+ A as getAccessibleTextContent,
4356
+ fe as getActiveRules,
4357
+ q as getComputedRole,
4358
+ d as getHtmlSnippet,
4359
+ de as getImplicitRole,
4360
+ Ri as getRuleById,
4283
4361
  m as getSelector,
4284
- p as isAriaHidden,
4285
- xe as isValidRole,
4286
- wi as querySelectorShadowAware,
4287
- pe as rules,
4288
- ki as runAudit,
4289
- Ai as validateDeclarativeRule
4362
+ g as isAriaHidden,
4363
+ ke as isValidRole,
4364
+ Ti as querySelectorShadowAware,
4365
+ ge as rules,
4366
+ qi as runAudit,
4367
+ Ei as validateDeclarativeRule
4290
4368
  };