-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathengine.iife.js
More file actions
10 lines (10 loc) · 241 KB
/
Copy pathengine.iife.js
File metadata and controls
10 lines (10 loc) · 241 KB
1
2
3
4
5
6
7
8
9
10
/*! pour engine 1.43.0 | MIT | github.com/pourdev/pour-engine */
var PourEngine=(()=>{var Tt=Object.defineProperty;var $s=Object.getOwnPropertyDescriptor;var Is=Object.getOwnPropertyNames;var Es=Object.prototype.hasOwnProperty;var Ms=(e,t)=>{for(var o in t)Tt(e,o,{get:t[o],enumerable:!0})},Ws=(e,t,o,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Is(t))!Es.call(e,n)&&n!==o&&Tt(e,n,{get:()=>t[n],enumerable:!(a=$s(t,n))||a.enumerable});return e};var Ls=e=>Ws(Tt({},"__esModule",{value:!0}),e);var Tl={};Ms(Tl,{name:()=>Rs,run:()=>Sl,version:()=>Ns});var Rt={slug:"pour",productName:"pour",shortName:"pour",toolsName:"pour tools",description:"One-click accessibility checker: WCAG 2.2 audits, contrast checks, exact fixes, and vision, sensory and motor filters.",author:"David Yarham",homepage:"https://pour.dev",supportEmail:"info@pour.dev",version:"1.2.129",engine:{name:"pour engine",version:"1.43.0"},extension:{nameSuffix:" - Accessibility Checker & WCAG Audit",chromeWebStoreUrl:"https://chromewebstore.google.com/detail/cmebappepecpgihmahkfmaahmajglgch",firefoxAmoUrl:"https://addons.mozilla.org/firefox/addon/pour-devtools/",vscodeMarketplaceUrl:"https://marketplace.visualstudio.com/items?itemName=pourdev.pour-html",geckoId:"devtools@pour.dev",geckoStrictMinVersion:"140.0",targets:["chromium","firefox"]},site:{outDir:"site"},benchmark:{published:"2026-09-12-1701"}};var rt=new Set(["SCRIPT","TEMPLATE","STYLE","LINK","META"]);function xe(e){let t=e.shadowRoot?[e,e.shadowRoot]:[e];for(let o=0;o<t.length;o++)if(t[o].querySelectorAll)for(let a of t[o].querySelectorAll("*"))a.shadowRoot&&t.push(a.shadowRoot);return t}function ge(e){return e.assignedSlot??e.parentElement??e.getRootNode()?.host??null}function ko(e){let t=[],o=new Set,a=n=>{for(let s of n.querySelectorAll("*"))if(!o.has(s)&&(o.add(s),t.push(s),s.shadowRoot&&a(s.shadowRoot),s.tagName==="SLOT"))for(let i of s.assignedElements({flatten:!0}))o.has(i)||(o.add(i),t.push(i)),a(i)};return e.shadowRoot&&a(e.shadowRoot),a(e),t}function lt(e,t=null){let o=a=>a.hasAttribute("tabindex")&&a.tabIndex<0;if(o(e))return!0;for(let a=ge(e);a&&a!==t;a=ge(a))if(a.shadowRoot&&o(a))return!0;return!1}function ct(e){if(typeof e.checkVisibility=="function")return e.checkVisibility({visibilityProperty:!0});let t=getComputedStyle(e);return t.display!=="none"&&t.visibility!=="hidden"}function It(e){for(let o=e;o;o=ge(o))if(o.getAttribute?.("aria-hidden")==="true"||o.hasAttribute?.("inert"))return!1;if(ct(e))return!0;let t=getComputedStyle(e);if(t.display!=="contents"||t.visibility==="hidden"||t.visibility==="collapse")return!1;for(let o=ge(e);o;o=ge(o))if(getComputedStyle(o).display==="none")return!1;return!0}var Nt=new WeakMap,$t=new Set;function Et(){for(let e of $t)e.disconnect();$t.clear(),Nt=new WeakMap}var Co=Et;function Os(e){let t=Nt.get(e);if(!t){let o=typeof MutationObserver=="function"?new MutationObserver(()=>{t.ids=null,t.parents=new WeakMap}):null;t={ids:null,parents:new WeakMap,observer:o},o&&(o.observe(e,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["id"]}),$t.add(o)),Nt.set(e,t)}if(t.observer?.takeRecords().length&&(t.ids=null,t.parents=new WeakMap),!t.ids){t.ids=new Map;for(let o of e.querySelectorAll("[id]"))t.ids.set(o.id,(t.ids.get(o.id)??0)+1)}return t}function Us(e,t){let o=e.parentElement,a=t.parents.get(o);if(!a){let n=new Map;a=new WeakMap;for(let s of o.children){let i=(n.get(s.tagName)??0)+1;n.set(s.tagName,i),a.set(s,{position:i,repeated:!1})}for(let s of o.children)a.get(s).repeated=n.get(s.tagName)>1;t.parents.set(o,a)}return a.get(e)}function vo(e){let t=e.getRootNode(),o=Os(t),a=i=>i.id&&o.ids.get(i.id)===1;if(a(e))return`#${CSS.escape(e.id)}`;let n=[],s=e;for(;s&&s.nodeType===Node.ELEMENT_NODE&&s!==document.documentElement;){let i=s.tagName.toLowerCase();if(s.parentElement){let{position:r,repeated:l}=Us(s,o);l&&(i+=`:nth-of-type(${r})`)}if(n.unshift(i),s.parentElement&&a(s.parentElement)){n.unshift(`#${CSS.escape(s.parentElement.id)}`);break}s=s.parentElement}return n.join(" > ")||e.tagName.toLowerCase()}function Mt(e){let t=vo(e),o=e.getRootNode();for(;o&&o.host;)t=`${vo(o.host)} >>> ${t}`,o=o.host.getRootNode();return t}var Ao=typeof Element<"u"?Object.getOwnPropertyDescriptor(Element.prototype,"attributes")?.get:null;function $e(e){let t=e.attributes;return t&&typeof t.length=="number"&&typeof t.item=="function"?t:Ao?Ao.call(e):[]}function Wt(e,t=300){let o=`<${e.tagName.toLowerCase()}`;for(let{name:n,value:s}of $e(e)){if(o.length>=t)break;o+=` ${n}="${s}"`}o+=">";let a=Lt(e);return a&&o.length<t&&(o+=a.slice(0,t-o.length)),o.length>t?`${o.slice(0,t)}\u2026`:o}function Oe(e){let t=e?.defaultView;return!!(t&&t.top&&t!==t.top)}function ce(e){for(let t=e;t;t=ge(t))if(t.nodeType===1&&t.hasAttribute("inert"))return!0;return!1}function Lt(e){return[...e.childNodes].filter(t=>t.nodeType===Node.TEXT_NODE).map(t=>t.textContent).join("").trim()}var Ds=new Set(["untitled document","untitled page","untitled-1","untitled 1","no title","insert title here","title here","page title","document title","web page","webpage"]),Fs=new Set(["untitled","document","page","title","default","index","new document","new page","new tab","react app","create react app","vite app","vite + react","vite + vue","vite + svelte","next app","create next app","vue app","nuxt app","svelte app","angular app","my app","my site","my website","site title","your site title","example domain","hello world"]),So={id:"document-title",name:"Page title",impact:"serious",tags:["wcag2a","wcag242"],help:"The page must have a title that describes its topic or purpose",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/page-titled.html",selector:"html",visibleOnly:!1,evaluate(e){if(Oe(e.ownerDocument))return{status:"pass"};let t=e.ownerDocument.title.trim();if(!t)return{status:"fail",message:"The page has no title, so users of screen readers and browser tabs cannot tell what it is.",fix:"Add <title>Page name \u2014 Site name</title> inside <head>."};let o=t.replace(/\s+/g," ").toLowerCase();return Ds.has(o)||/^(?:untitled|new (?:document|page|tab))[\s-]*\d+$/.test(o)?{status:"incomplete",message:`\u201C${t}\u201D resembles a template title. Check whether it describes this page's actual topic or purpose; the same words can also be a legitimate subject or name.`,fix:"Put this page's own subject in the title first, then the site name."}:Fs.has(o)?{status:"incomplete",message:`\u201C${t}\u201D is a generic title, and usually a default nobody replaced. Unless the page really is about that, it describes neither topic nor purpose and 2.4.2 is not met. Check whether it was meant to be filled in.`}:{status:"pass"}}};var Ps=/^([a-zA-Z]{2,3}(-[a-zA-Z0-9]{1,8})*|[xXiI](-[a-zA-Z0-9]{1,8})+)$/,To={id:"html-lang",name:"Page language",impact:"serious",tags:["wcag2a","wcag311"],help:"The <html> element must declare a valid language",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/language-of-page.html",selector:"html",visibleOnly:!1,evaluate(e){let t=e.getAttribute("lang")?.trim();return e.hasAttribute("lang")?t?Ps.test(t)?{status:"pass"}:{status:"fail",message:`lang="${t}" is not a valid language tag.`,fix:'Use a BCP 47 tag such as lang="en" or lang="en-GB".'}:{status:"fail",message:"The lang attribute is present but empty, so the page declares no language: screen readers will guess it and may mispronounce everything.",fix:'Give lang a BCP 47 value, e.g. <html lang="en">.'}:{status:"fail",message:"No lang attribute: screen readers will guess the language and may mispronounce everything.",fix:'Add lang to the html element, e.g. <html lang="en">.'}}};var Bs=/^([a-zA-Z]{2,3}(-[a-zA-Z0-9]{1,8})*|[xXiI](-[a-zA-Z0-9]{1,8})+)$/,Ro={id:"valid-lang-parts",name:"Part language tags",impact:"serious",tags:["wcag2aa","wcag312"],help:"lang attributes on page parts must be valid",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/language-of-parts.html",selector:"[lang]:not(html)",evaluate(e){let t=e.getAttribute("lang").trim();return t===""||Bs.test(t)?{status:"pass"}:{status:"fail",message:`lang="${t}" is not a valid language tag, so screen readers may switch to the wrong pronunciation.`,fix:'Use a BCP 47 tag such as lang="fr" or lang="de-AT".'}}};var ut=new Set(["activedescendant","atomic","autocomplete","braillelabel","brailleroledescription","busy","checked","colcount","colindex","colindextext","colspan","controls","current","describedby","description","details","disabled","dropeffect","errormessage","expanded","flowto","grabbed","haspopup","hidden","invalid","keyshortcuts","label","labelledby","level","live","modal","multiline","multiselectable","orientation","owns","placeholder","posinset","pressed","readonly","relevant","required","roledescription","rowcount","rowindex","rowindextext","rowspan","selected","setsize","sort","valuemax","valuemin","valuenow","valuetext"]),Ye=new Set(["atomic","busy","controls","current","describedby","description","details","dropeffect","flowto","grabbed","hidden","keyshortcuts","label","labelledby","live","owns","relevant","roledescription","braillelabel","brailleroledescription"]),Ue=new Set(["banner","complementary","contentinfo","form","main","navigation","region","search"]),ve={link:["disabled","errormessage","expanded","haspopup","invalid"],button:["disabled","errormessage","expanded","haspopup","invalid","pressed"],checkbox:["checked","disabled","errormessage","expanded","haspopup","invalid","readonly","required"],switch:["checked","disabled","errormessage","expanded","haspopup","invalid","readonly","required"],radio:["checked","disabled","errormessage","haspopup","invalid","posinset","setsize"],option:["checked","disabled","errormessage","haspopup","invalid","posinset","selected","setsize"],tab:["disabled","errormessage","expanded","haspopup","invalid","posinset","selected","setsize"],menuitem:["disabled","errormessage","expanded","haspopup","invalid","posinset","setsize"],menuitemcheckbox:["checked","disabled","errormessage","expanded","haspopup","invalid","posinset","setsize"],menuitemradio:["checked","disabled","errormessage","expanded","haspopup","invalid","posinset","setsize"],textbox:["activedescendant","autocomplete","disabled","errormessage","haspopup","invalid","multiline","placeholder","readonly","required"],searchbox:["activedescendant","autocomplete","disabled","errormessage","haspopup","invalid","multiline","placeholder","readonly","required"],combobox:["activedescendant","autocomplete","disabled","errormessage","expanded","haspopup","invalid","readonly","required"],listbox:["activedescendant","disabled","errormessage","expanded","haspopup","invalid","multiselectable","orientation","readonly","required"],slider:["disabled","errormessage","haspopup","invalid","orientation","readonly","valuemax","valuemin","valuenow","valuetext"],spinbutton:["activedescendant","disabled","errormessage","haspopup","invalid","readonly","required","valuemax","valuemin","valuenow","valuetext"],progressbar:["disabled","errormessage","haspopup","invalid","valuemax","valuemin","valuenow","valuetext"],meter:["disabled","errormessage","haspopup","invalid","valuemax","valuemin","valuenow","valuetext"],scrollbar:["disabled","errormessage","haspopup","invalid","orientation","valuemax","valuemin","valuenow","valuetext"],heading:["disabled","errormessage","haspopup","invalid","level"],list:["disabled","errormessage","haspopup","invalid"],listitem:["disabled","errormessage","haspopup","invalid","level","posinset","setsize"],row:["activedescendant","colindex","colindextext","disabled","errormessage","expanded","haspopup","invalid","level","posinset","rowindex","rowindextext","selected","setsize"],rowgroup:["disabled","errormessage","haspopup","invalid"],cell:["colindex","colindextext","colspan","disabled","errormessage","haspopup","invalid","rowindex","rowindextext","rowspan"],gridcell:["colindex","colindextext","colspan","disabled","errormessage","expanded","haspopup","invalid","readonly","required","rowindex","rowindextext","rowspan","selected"],columnheader:["colindex","colindextext","colspan","disabled","errormessage","expanded","haspopup","invalid","readonly","required","rowindex","rowindextext","rowspan","selected","sort"],rowheader:["colindex","colindextext","colspan","disabled","errormessage","expanded","haspopup","invalid","readonly","required","rowindex","rowindextext","rowspan","selected","sort"],table:["colcount","disabled","errormessage","haspopup","invalid","rowcount"],grid:["activedescendant","colcount","disabled","errormessage","haspopup","invalid","multiselectable","readonly","rowcount"],treegrid:["activedescendant","colcount","disabled","errormessage","haspopup","invalid","multiselectable","orientation","readonly","required","rowcount"],tablist:["activedescendant","disabled","errormessage","haspopup","invalid","multiselectable","orientation"],menu:["activedescendant","disabled","errormessage","haspopup","invalid","orientation"],menubar:["activedescendant","disabled","errormessage","haspopup","invalid","orientation"],tree:["activedescendant","disabled","errormessage","haspopup","invalid","multiselectable","orientation","required"],treeitem:["checked","disabled","errormessage","expanded","haspopup","invalid","level","posinset","selected","setsize"],radiogroup:["activedescendant","disabled","errormessage","haspopup","invalid","orientation","readonly","required"],group:["activedescendant","disabled","errormessage","haspopup","invalid"],separator:["disabled","errormessage","haspopup","invalid","orientation","valuemax","valuemin","valuenow","valuetext"],toolbar:["activedescendant","disabled","errormessage","haspopup","invalid","orientation"],dialog:["disabled","errormessage","haspopup","invalid","modal"],alertdialog:["disabled","errormessage","haspopup","invalid","modal"],application:["activedescendant","disabled","errormessage","expanded","haspopup","invalid"],article:["disabled","errormessage","haspopup","invalid","posinset","setsize"],img:["disabled","errormessage","haspopup","invalid"],figure:["disabled","errormessage","haspopup","invalid"],document:["disabled","errormessage","haspopup","invalid"],feed:["disabled","errormessage","haspopup","invalid"],math:["disabled","errormessage","haspopup","invalid"],note:["disabled","errormessage","haspopup","invalid"],presentation:["disabled","errormessage","haspopup","invalid"],none:["disabled","errormessage","haspopup","invalid"],banner:["disabled","errormessage","haspopup","invalid"],complementary:["disabled","errormessage","haspopup","invalid"],contentinfo:["disabled","errormessage","haspopup","invalid"],form:["disabled","errormessage","haspopup","invalid"],main:["disabled","errormessage","haspopup","invalid"],navigation:["disabled","errormessage","haspopup","invalid"],region:["disabled","errormessage","haspopup","invalid"],search:["disabled","errormessage","haspopup","invalid"],alert:["disabled","errormessage","haspopup","invalid"],log:["disabled","errormessage","haspopup","invalid"],marquee:["disabled","errormessage","haspopup","invalid"],status:["disabled","errormessage","haspopup","invalid"],timer:["disabled","errormessage","haspopup","invalid"],tabpanel:["disabled","errormessage","haspopup","invalid"],tooltip:["disabled","errormessage","haspopup","invalid"],definition:["disabled","errormessage","haspopup","invalid"],term:["disabled","errormessage","haspopup","invalid"],paragraph:["disabled","errormessage","haspopup","invalid"],generic:["disabled","errormessage","haspopup","invalid"],blockquote:["disabled","errormessage","haspopup","invalid"],caption:["disabled","errormessage","haspopup","invalid"],code:["disabled","errormessage","haspopup","invalid"],emphasis:["disabled","errormessage","haspopup","invalid"],strong:["disabled","errormessage","haspopup","invalid"],time:["disabled","errormessage","haspopup","invalid"],deletion:["disabled","errormessage","haspopup","invalid"],insertion:["disabled","errormessage","haspopup","invalid"],subscript:["disabled","errormessage","haspopup","invalid"],superscript:["disabled","errormessage","haspopup","invalid"]},Gs={checkbox:"checkbox",radio:"radio",range:"slider",number:"spinbutton",search:"searchbox",email:"textbox",tel:"textbox",text:"textbox",url:"textbox",button:"button",submit:"button",reset:"button",image:"button"},qs=new Set(["text","search","tel","url","email"]),zs={button:"button",textarea:"textbox",img:"img",article:"article",aside:"complementary",nav:"navigation",main:"main",search:"search",h1:"heading",h2:"heading",h3:"heading",h4:"heading",h5:"heading",h6:"heading",ul:"list",ol:"list",menu:"list",li:"listitem",table:"table",thead:"rowgroup",tbody:"rowgroup",tfoot:"rowgroup",tr:"row",td:"cell",th:"columnheader",form:"form",fieldset:"group",details:"group",dialog:"dialog",hr:"separator",progress:"progressbar",meter:"meter",output:"status",option:"option",datalist:"listbox",dt:"term",dd:"definition",p:"paragraph",div:"generic",span:"generic",blockquote:"blockquote",figure:"figure",time:"time",code:"code",em:"emphasis",strong:"strong"};function ae(e){let t=e.tagName.toLowerCase();if(t==="a"||t==="area")return e.hasAttribute("href")?"link":"generic";if(t==="input")return qs.has(e.type)&&e.hasAttribute("list")?"combobox":Gs[e.type]??null;if(t==="td"||t==="th"){if(t==="th"&&e.getAttribute("scope")?.toLowerCase()==="row")return"rowheader";if(t==="th")return"columnheader";let o=e.closest("table"),a=o&&P(o);return a==="grid"||a==="treegrid"?"gridcell":"cell"}if(t==="select")return e.multiple||e.size>1?"listbox":"combobox";if(t==="img")return e.getAttribute("alt")===""?"presentation":"img";if(t==="header")return e.closest("article, aside, main, nav, section")?"generic":"banner";if(t==="footer")return e.closest("article, aside, main, nav, section")?"generic":"contentinfo";if(t==="aside"){let o=e.parentElement?.closest("article, aside, nav, section"),a=e.hasAttribute("aria-label")||e.hasAttribute("aria-labelledby");return o&&!a?"generic":"complementary"}return t==="section"?e.hasAttribute("aria-label")||e.hasAttribute("aria-labelledby")?"region":"generic":zs[t]??null}function Vs(e){return[...Ye].some(t=>e.hasAttribute(`aria-${t}`))?!0:e.matches(":disabled")||ce(e)?!1:e.tabIndex>=0?!0:e.matches('a[href], button, input, select, textarea, summary, [contenteditable="true"]')}function P(e){let t=e.getAttribute("role")?.trim().split(/\s+/)??[];for(let o of t){let a=o.toLowerCase();if(a==="image")return"img";if(ve[a])return(a==="presentation"||a==="none")&&Vs(e)?ae(e):a}return ae(e)}var _s=/\.(png|jpe?g|gif|webp|svg|avif|bmp|ico)([?#].*)?$/i,Hs=/^(image|img|photo|photograph|picture|graphic|icon|untitled|placeholder|spacer|\d+)$/i,No={id:"image-alt",name:"Image alt text",impact:"critical",tags:["wcag2a","wcag111"],help:"Every <img> needs a text alternative",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/non-text-content.html",selector:"img",evaluate(e,{accessibleName:t}){let o=P(e);if(o==="presentation"||o==="none")return{status:"pass"};if(e.hasAttribute("alt")){let a=e.getAttribute("alt");if(a==="")return{status:"pass"};if(!a.trim())return{status:"incomplete",message:`alt="${a}" is only whitespace \u2014 not a description, and not the decorative marker either (that is alt="" with nothing between the quotes). Screen readers skip it today, so check the image is really decorative; if it carries meaning, describe it, and either way use alt="".`};let n=a.trim();return _s.test(n)||Hs.test(n)?{status:"incomplete",message:`alt="${n}" looks like a file name or placeholder, not a description \u2014 screen-reader users learn nothing from it. If the image carries meaning, describe it; if not, use alt="".`}:{status:"pass"}}return t(e)?{status:"pass"}:{status:"fail",message:"This image has no alt attribute, so screen readers announce its file name or nothing at all.",fix:`Describe the image: <img alt="\u2026" src="${e.getAttribute("src")??""}">, or mark it decorative with alt="".`}}};var js=new Set(["text","search","url","tel","email","password","number","date","datetime-local","month","time","week",""]),Ys=new Set(["input","select","textarea","button","meter","output","progress"]);function Ot(e){return e.replace(/[\uE000-\uF8FF\u{F0000}-\u{FFFFD}\u{100000}-\u{10FFFD}\u200B-\u200D\u2060\uFEFF]/gu,"").trim()?e:""}function dt(e){return Ot(Ke(e,!1,!1,new Set))}function ue(e){return Ot(Eo(e,new Set)??"")}function Io(e,t){return Ot(Ke(t,!1,Ut(t),new Set([e])))}function Ut(e){for(let o=e;o;o=ge(o))if(o.getAttribute?.("aria-hidden")==="true"||getComputedStyle(o).display==="none")return!0;let t=getComputedStyle(e).visibility;return t==="hidden"||t==="collapse"}function Eo(e,t){let o=e.getAttribute?.("aria-labelledby");if(!o)return null;let a=e.getRootNode(),n=o.split(/\s+/).filter(Boolean).map(s=>a.getElementById?.(s)).filter(Boolean);return n.length?n.map(s=>{let i=new Set(t);return s===e&&i.delete(e),Ke(s,!0,Ut(s),i)}).join(" ").replace(/\s+/g," ").trim():null}function Ke(e,t,o,a){if(a.has(e))return"";if(a.add(e),!t){let r=Eo(e,a);if(r)return r}let n=e.getAttribute("aria-label")?.trim();if(n)return n;let s=e.tagName.toLowerCase();if(s==="img"||s==="area"){let r=e.getAttribute("alt")?.trim();if(r)return r}if(Ys.has(s)&&e.labels?.length){let r=[...e.labels].map(l=>Ke(l,t,Ut(l),a)).join(" ").trim();if(r)return r}if(s==="input"||s==="select"||s==="textarea"){if(e.type==="submit"||e.type==="reset"||e.type==="button"){let r=(e.value??e.getAttribute("value")??"").trim();if(r)return r}if(e.type==="image"){let r=e.getAttribute("alt")?.trim();if(r)return r}if(t&&(s==="textarea"||js.has(e.type))){let r=(e.value??"").trim();if(r)return r}if(e.type==="submit")return"Submit";if(e.type==="reset")return"Reset"}let i=Ks(e,o,t,a).replace(/\s+/g," ").trim();return i||(e.getAttribute("title")??e.getAttribute("placeholder")??"").trim()}function Ks(e,t,o,a){let n=e.shadowRoot?e.shadowRoot.childNodes:e.childNodes;return $o(e,"::before",t)+Mo(n,t,o,a)+$o(e,"::after",t)}function $o(e,t,o){if(e.namespaceURI==="http://www.w3.org/2000/svg")return"";let a=getComputedStyle(e,t);if(!o&&(a.display==="none"||a.visibility==="hidden"||a.visibility==="collapse"))return"";let n=a.content;if(!n||n==="none"||n==="normal")return"";let s=n.match(/\/\s*"((?:[^"\\]|\\.)*)"\s*$/);if(s)return s[1].replace(/\\(.)/g,"$1");let i=n.match(/^"((?:[^"\\]|\\.)*)"$/);return i?i[1].replace(/\\(.)/g,"$1"):""}function Mo(e,t,o,a){let n="";for(let s of e){if(s.nodeType===3){n+=s.textContent;continue}if(s.nodeType!==1)continue;let i=s.tagName.toLowerCase();if(i==="script"||i==="style"||i==="noscript"||i==="template")continue;if(!t){if(s.getAttribute("aria-hidden")==="true")continue;let l=getComputedStyle(s);if(l.display==="none"||l.visibility==="hidden"||l.visibility==="collapse")continue}if(i==="slot"){let l=s.assignedNodes?.()??[];n+=Mo(l.length?l:s.childNodes,t,o,a);continue}if((i==="img"||i==="area")&&s.getAttribute("alt")===""&&!s.getAttribute("aria-label")?.trim()&&!s.getAttribute("aria-labelledby"))continue;let r=Ke(s,o,t,a);n+=i==="img"||i==="area"||s.hasAttribute("aria-label")||s.hasAttribute("aria-labelledby")?` ${r} `:r}return n}var Wo={id:"svg-img-alt",name:"SVG accessible name",impact:"serious",tags:["wcag2a","wcag111"],help:'Inline SVG and role="img" graphics need an accessible name',helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/non-text-content.html",selector:"svg, [role]",evaluate(e,{accessibleName:t}){if(e.tagName==="IMG")return{status:"pass"};let o=e.tagName.toLowerCase()==="svg",a=P(e)==="img"||["graphics-document","graphics-symbol"].includes(e.getAttribute("role")?.trim());if(!o&&!a)return{status:"pass"};if(o&&e.hasAttribute("role")&&!a)return{status:"pass"};let n=o&&[...e.children].find(i=>i.tagName.toLowerCase()==="title");if(ue(e)||e.getAttribute("aria-label")?.trim()||n&&t(n)||e.getAttribute("title")?.trim())return{status:"pass"};if(!e.getAttribute("role")&&e.tagName.toLowerCase()==="svg"){if(e.parentNode instanceof SVGElement)return{status:"pass"};let i=e.closest('a[href], button, [role="button"], [role="link"]');return i&&t(i)?{status:"pass"}:{status:"incomplete",message:"This SVG has no accessible name and is not marked decorative \u2014 some screen readers announce it as an unlabeled graphic.",fix:'Add aria-hidden="true" if decorative; if meaningful, add role="img" and aria-label="\u2026" (or a <title> as the first child).'}}return{status:"fail",message:"This element is marked as an image but has no accessible name.",fix:'Add aria-label="\u2026" (for SVG, a <title> as the first child also works).'}}};var Lo={id:"button-name",name:"Button names",impact:"critical",tags:["wcag2a","wcag412"],help:"Buttons must have an accessible name",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html",selector:'button, [role], input[type="button"], input[type="submit"], input[type="reset"]',evaluate(e,{accessibleName:t}){return(P(e)??ae(e))!=="button"?{status:"pass"}:t(e)?{status:"pass"}:{status:"fail",message:'This button has no accessible name \u2014 a screen reader announces just "button".',fix:'Add visible text inside the button, or aria-label="What it does" for icon-only buttons.'}}};var Oo={id:"link-name",name:"Link names",impact:"serious",tags:["wcag2a","wcag244","wcag412"],help:"Links must have an accessible name",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/link-purpose-in-context.html",selector:'a[href], [role="link"]',evaluate(e,{accessibleName:t}){return(P(e)??ae(e))!=="link"?{status:"pass"}:t(e)?{status:"pass"}:{status:"fail",message:"This link has no accessible name \u2014 screen readers can only announce its URL.",fix:"Add text content to the link, alt text to the image inside it, or an aria-label."}}};var Uo=new Set(["read more","read more about this","more","much more","learn more","click here","click","click this","tap here","press here","here","this","this link","link","this page","go","go here","more info","more information","further information","see more","view more","show more","find out more","discover more","continue","continue reading","keep reading","full story","full article","details","see details","view details","more details","en savoir plus","savoir plus","lire la suite","lire plus","plus","cliquez ici","cliquer ici","clique ici","ici","ce lien","lien","cette page","voir plus","en voir plus","afficher plus","afficher","voir","voir le d\xE9tail","voir les d\xE9tails","plus de d\xE9tails","plus d informations","plus d infos","en savoir davantage","d\xE9couvrir","d\xE9couvrez","continuer","suite"]);function Xs(e){return e.toLowerCase().replace(/[^\p{L}\p{N}]+/gu," ").replace(/\s+/g," ").trim()}function Zs(e){let t=e.trim();if(/^[<\[({"'«‹「『].*[>\])}"'»›」』]$/su.test(t))return!1;let o=t.toLowerCase().replace(/[’']/gu," ").replace(/^[^\p{L}\p{N}\s]+\s*/u,"").replace(/[^\p{L}\p{N}\s]+\s*$/u,"").replace(/\s+/g," ").trim();return Uo.has(o)}function Dt({id:e,impact:t,tags:o,help:a,helpUrl:n,verdict:s}){return{id:e,impact:t,tags:o,help:a,helpUrl:n,selector:'a[href], [role="link"]',evaluate(i,{accessibleName:r}){if((P(i)??ae(i))!=="link")return{status:"pass"};let l=r(i);if(!l)return{status:"pass"};let d=Xs(l);if(!Uo.has(d))return{status:"pass"};let u=(i.closest("[lang]")?.getAttribute("lang")??i.ownerDocument.documentElement.getAttribute("lang")??"").trim();return s(l,{provable:Zs(l),normalized:d,lang:u})}}}var Do=Dt({id:"link-text-generic",name:"Generic link text",impact:"moderate",tags:["wcag2a","wcag244"],help:"Link text should describe where the link goes",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/link-purpose-in-context.html",verdict:e=>({status:"incomplete",message:`\u201C${e}\u201D does not say where this link goes. 2.4.4 lets the surrounding text supply that, so this passes only if the context a screen reader reaches \u2014 the same sentence, list item, table cell, or the heading of the card it sits in \u2014 makes the destination obvious. Check it does, and remember that anyone navigating by a list of the page's links sees this name on its own.`,fix:'Put the destination in the link text itself, e.g. "Read more about the 2026 budget", or extend the name with aria-label while keeping the visible words at the start of it.'})});var Js=new Set(["plus","suite"]),Qs=/^fr(-|$)/i;function ei(e,t){return e==="go"?!0:Js.has(e)&&!Qs.test(t)}var Fo=Dt({id:"link-text-generic-only",name:"Self-sufficient link text",impact:"moderate",tags:["wcag2aaa","wcag249"],help:"Link text alone must identify where the link goes (AAA)",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/link-purpose-link-only.html",verdict:(e,{provable:t,normalized:o,lang:a})=>!t||ei(o,a)?{status:"incomplete",message:`\u201C${e}\u201D matches a generic link phrase, but may identify its destination anyway: a code term keeps its meaning through the punctuation this comparison drops, and a brand or product name (a logo link named \u201CGo\u201D, a plan named \u201CPlus\u201D) is the destination. Check whether this name, read alone in a list of the page's links, says where it goes.`,fix:'If the name really is generic here, put the destination in the link text, e.g. "Read more about the 2026 budget".'}:{status:"incomplete",message:`\u201C${e}\u201D appears generic when read alone. Check whether it identifies the destination in this context or whether a mechanism makes the link text descriptive. 2.4.9 permits such a mechanism; the initial link name alone cannot establish a failure.`,fix:'Name the destination in the link text, e.g. "Read more about the 2026 budget".'}});var Po={id:"form-label",name:"Form field labels",impact:"critical",tags:["wcag2a","wcag131","wcag332","wcag412"],help:"Every form field needs a label",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships.html",selector:'input:not([type="hidden"]):not([type="button"]):not([type="submit"]):not([type="reset"]):not([type="image"]), select, textarea',evaluate(e){let t=P(e);if(t==="presentation"||t==="none")return{status:"pass"};let o=[...e.labels??[]].filter(r=>{if(r.closest('[aria-hidden="true"]'))return!1;let l=getComputedStyle(r);return l.display!=="none"&&l.visibility!=="hidden"}),a=o.map(r=>Io(e,r)).join(" ").trim(),n=e.getAttribute("aria-label")?.trim(),s=ue(e);if(a||n||s)return{status:"pass"};let i=e.id?` (it already has id="${e.id}")`:" (give it an id first)";if(e.getAttribute("title")?.trim())return{status:"incomplete",message:"This field is named only by its title attribute (technique H65) \u2014 conformant, but the label is invisible until hover and some tools skip it. Check a visible label isn\u2019t needed here."};if(e.getAttribute("placeholder"))return{status:"fail",message:"This field relies on its placeholder as the only label \u2014 the name vanishes as soon as the user types.",fix:`Add <label for="\u2026">Field name</label> pointing at this field${i}; keep the placeholder as an example value only.`};if(e.labels?.length&&!o.length)return[...e.labels].some(l=>{let d=getComputedStyle(l);return d.display!=="none"&&d.visibility!=="hidden"})?{status:"fail",message:`This field's only <label> is inside aria-hidden="true": sighted users still see it, but it is removed from the accessibility tree, so the field has no accessible name.`,fix:"Remove aria-hidden from the label (or from the ancestor that hides it). If the label must stay hidden from assistive technology, name the field another way with aria-label or aria-labelledby."}:{status:"fail",message:"This field's only <label> is hidden (display:none or visibility:hidden), so no one can see or rely on it.",fix:"Make the label visible, or use a visually-hidden-but-rendered technique (clip/sr-only) if it must not show."};if(e.labels?.length){let r=o.some(d=>d.textContent.trim()),l=o.some(d=>[...d.querySelectorAll('[aria-hidden="true"]')].some(u=>u.textContent.trim()));return r&&!l?{status:"fail",message:"This field's <label> holds text, but all of it is inside unrendered content (display:none or visibility:hidden), so the accessible name computes to nothing and nobody sees a label.",fix:"Render the text inside the label, move it out of the hidden element, or add aria-label to the field."}:{status:"fail",message:r?"This field's <label> shows text, but all of it is inside aria-hidden content \u2014 the accessible name computes to nothing.":"This field has a <label>, but the label is empty \u2014 it announces nothing.",fix:r?"Move the visible text out of the aria-hidden wrapper, or add aria-label to the field.":"Put visible text inside the label."}}if(e.id){let r=e.getRootNode(),l=r.querySelector?.(`label[for="${CSS.escape(e.id)}"]`),d=r.getElementById?.(e.id);if(l&&d&&d!==e)return{status:"fail",message:`A <label for="${e.id}"> exists, but an earlier element on the page has the same id, so the label belongs to that one and this field has no label at all.`,fix:"Give this field a unique id and point its label at that; ids must not repeat on a page."}}return{status:"fail",message:"This form field has no label \u2014 users cannot tell what to enter.",fix:`Add <label for="\u2026">Field name</label> pointing at this field${i}.`}}};var Ft=new Set(["additional-name","address-level1","address-level2","address-level3","address-level4","address-line1","address-line2","address-line3","bday","bday-day","bday-month","bday-year","cc-additional-name","cc-csc","cc-exp","cc-exp-month","cc-exp-year","cc-family-name","cc-given-name","cc-name","cc-number","cc-type","country","country-name","current-password","email","family-name","given-name","honorific-prefix","honorific-suffix","impp","language","name","new-password","nickname","one-time-code","organization","organization-title","photo","postal-code","sex","street-address","tel","tel-area-code","tel-country-code","tel-extension","tel-local","tel-local-prefix","tel-local-suffix","tel-national","transaction-amount","transaction-currency","url","username"]),Pt=new Set(["home","work","mobile","fax","pager"]),ti=new Set(["tel","tel-country-code","tel-national","tel-area-code","tel-local","tel-local-prefix","tel-local-suffix","tel-extension","email","impp"]),oi=new Set(["shipping","billing","webauthn","on","off"]),ht=e=>e.startsWith("section-"),ai=e=>Ft.has(e)||Pt.has(e)||oi.has(e)||ht(e);function ni(e){if(e.length===1&&(e[0]==="on"||e[0]==="off"))return null;if(e.includes("on")||e.includes("off"))return'"on" and "off" must stand alone, with no other tokens';let t=0;if(ht(e[t])&&(t+=1),(e[t]==="shipping"||e[t]==="billing")&&(t+=1),Pt.has(e[t])){if(!ti.has(e[t+1]))return`"${e[t]}" must come directly before a tel, tel-*, email or impp field name`;t+=2}else if(Ft.has(e[t]))t+=1;else{let o=e[t];return o&&ht(o)?`"${o}" must be the first token`:o==="webauthn"?'"webauthn" must come last, after a field name':o==="shipping"||o==="billing"?`"${o}" may appear once, directly before the field name`:"the value names no field (exactly one field name such as email, tel or given-name is required)"}if(e[t]==="webauthn"&&(t+=1),t<e.length){let o=e[t];return ht(o)?`"${o}" must be the first token`:o==="shipping"||o==="billing"?`"${o}" must come before the field name`:o==="webauthn"?'"webauthn" must be the last token':Ft.has(o)||Pt.has(o)?`only one field name is allowed, but "${e[t-1]}" is followed by "${o}"`:`"${o}" cannot follow the field name`}return null}var Bo={id:"autocomplete-valid",name:"Autocomplete tokens",impact:"serious",tags:["wcag21aa","wcag135"],help:"autocomplete attributes must use valid tokens",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/identify-input-purpose.html",selector:'input[autocomplete]:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="submit"]):not([type="image"]):not([type="reset"]):not([type="button"]):not(:disabled), select[autocomplete]:not(:disabled), textarea[autocomplete]:not(:disabled)',evaluate(e){if(e.getAttribute("aria-disabled")==="true")return{status:"pass"};let t=e.getAttribute("autocomplete").trim().toLowerCase().split(/\s+/).filter(Boolean),o=t.filter(i=>!ai(i)),a=o.length?null:t.length?ni(t):null;if(!o.length&&!a)return{status:"pass"};let n=o.length?`autocomplete contains unknown token(s): ${o.join(", ")}, so browsers and assistive tools cannot identify this field's purpose from it`:`autocomplete="${e.getAttribute("autocomplete").trim()}" is not a valid autofill value: ${a}. Browsers discard the whole value, so no purpose is exposed`,s=o.length?'Use tokens from the HTML input-purposes list, e.g. autocomplete="email" or autocomplete="given-name".':'Use one field name from the HTML autofill list, optionally preceded by section-*, then shipping or billing, and (for tel, email and impp only) a contact type, e.g. autocomplete="shipping tel" or autocomplete="home email".';return e.type==="search"?{status:"incomplete",message:`${n}. 1.3.5 covers fields that collect information about the user, which a search box usually does not; if this one does, correct the value.`,fix:s}:{status:"fail",message:`${n}. 1.3.5 covers fields that collect information about the user, which is what an autocomplete attribute is for; if this field collects nothing about the user, the criterion does not apply and this finding can be dismissed.`,fix:s}}};var si=/^(html|body|:root)((?::[a-z-]+(?:\([^()]*\))?)*)$/i,Go=/rotate(?:3d\([^)]*,\s*)?\(?\s*(?:-?(?:90|270)deg|0\.25turn|-0\.25turn|100grad|-100grad)/i;function ii(e,t){let o=new Set;for(let a of(e??"").split(",")){let n=si.exec(a.trim());if(!n)continue;let s=/^body$/i.test(n[1])?t.body:t.documentElement;try{s?.matches(a.trim())&&o.add(s)}catch{}}return[...o]}function ri(e,t){let o=0;if(e.transform&&e.transform!=="none")try{let a=new t.DOMMatrixReadOnly(e.transform);if(!a.is2D)return null;o+=Math.atan2(a.b,a.a)*180/Math.PI}catch{return null}if(e.rotate&&e.rotate!=="none"){let a=/^(?:(?:z|0\s+0\s+1)\s+)?(-?[\d.]+)(deg|rad|grad|turn)$/.exec(e.rotate);if(!a)return null;let n={deg:1,rad:180/Math.PI,grad:.9,turn:360}[a[2]];o+=Number(a[1])*n}return Math.abs((o%180+180)%180-90)<.01}function pt(e,t,o,a,n,s){let i=n.defaultView;for(let r of e??[]){if(r.type===i.CSSRule.SUPPORTS_RULE){s.supports(r.conditionText)&&pt(r.cssRules,t,o,a,n,s);continue}if(r.type===i.CSSRule.MEDIA_RULE){let l=r.conditionText??r.media.mediaText,d=/orientation\s*:\s*(portrait|landscape)/i.exec(l)?.[1],u=d?{condition:l,orientation:d}:t;pt(r.cssRules,u,o&&s.media(l),a,n,s);continue}if(t&&r.style){let{display:l,visibility:d,transform:u,rotate:c}=r.style,h={display:l?l==="none"?"hidden":null:void 0,visibility:d?d==="hidden"?"hidden":null:void 0,transform:u?Go.test(u)?"rotated":null:void 0,rotate:c?Go.test(`rotate(${c})`)?"rotated":null:void 0};if(Object.values(h).some(f=>f!==void 0))for(let f of ii(r.selectorText,n)){let m=`${t.orientation.toLowerCase()}|${f===n.body?"body":"html"}`;a.has(m)||a.set(m,{});let y=a.get(m);for(let[g,w]of Object.entries(h))w!==void 0&&(y[g]=w?{kind:w,active:o,selector:r.selectorText,...t}:null)}}r.cssRules&&pt(r.cssRules,t,o&&r.conditionText===void 0,a,n,s)}}var qo={id:"orientation-lock",name:"Orientation lock",impact:"serious",tags:["wcag21aa","wcag134"],help:"Content must work in both portrait and landscape",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/orientation.html",selector:"html",visibleOnly:!1,evaluate(e){let t=e.ownerDocument,o=t.defaultView,a=new Map,n=new Map,s=new Map,i={media:u=>(n.has(u)||n.set(u,o.matchMedia(u).matches),n.get(u)),supports:u=>(s.has(u)||s.set(u,o.CSS.supports(u)),s.get(u))};for(let u of t.styleSheets){if(u.disabled)continue;let c=u.media?.mediaText;if(c&&!i.media(c))continue;let h;try{h=u.cssRules}catch{continue}pt(h,null,!0,a,t,i)}let r=[];for(let[u,c]of a){let h=u.endsWith("|body")?t.body:t.documentElement;for(let f of Object.values(c))if(f){if(f.active){let m=o.getComputedStyle(h);if((f.kind==="hidden"?m.display==="none"||m.visibility==="hidden":ri(m,o))===!1)continue}r.push(f)}}if(!r.length)return{status:"pass"};let l=r.find(u=>u.active)??r[0],d=l.kind==="hidden"?"hides the page":"rotates the page to force the other orientation";return{status:"fail",message:`A stylesheet rule (${l.selector} under @media ${l.condition}) ${d} when the device is in ${l.orientation}${l.active?", and it is in effect now":""}: the content is locked to a single display orientation. 1.3.4 allows that only where one orientation is essential, which a stylesheet cannot show; this finding assumes it is not.`,fix:"Let the layout adapt to both orientations instead of hiding or rotating the page. If a single orientation is genuinely essential (rare), document why and dismiss this finding."}}};var zo={id:"meta-viewport",name:"Viewport zoom lock",impact:"critical",tags:["wcag2aa","wcag144"],help:"The viewport must let users zoom to at least 200%",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/resize-text.html",selector:'meta[name="viewport"]',visibleOnly:!1,evaluate(e){if(Oe(e.ownerDocument))return{status:"pass"};let t=e.getAttribute("content")??"",o=/user-scalable\s*=\s*(no|0)/i.test(t),a=t.match(/maximum-scale\s*=\s*([\d.]+)/i),n=a&&parseFloat(a[1])<2;return!o&&!n?{status:"pass"}:{status:"fail",message:"This viewport meta tag stops users zooming the page, so text cannot be enlarged with the browser. 1.4.4 is met only if the page provides its own control that enlarges all text to 200% (technique G178); this finding assumes it does not, since the tag cannot show it.",fix:"Remove user-scalable=no and any maximum-scale below 2 from the viewport meta tag. If the page has its own text-size control that reaches 200%, record that and dismiss this finding."}}};var li=/^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*(?:,\s*([\d.]+%?)\s*)?\)$/,ci=/^rgba?\(\s*([\d.]+%?)\s+([\d.]+%?)\s+([\d.]+%?)\s*(?:\/\s*([\d.]+%?)\s*)?\)$/,ui=/^color\(\s*srgb\s+(-?[\d.]+%?)\s+(-?[\d.]+%?)\s+(-?[\d.]+%?)\s*(?:\/\s*([\d.]+%?)\s*)?\)$/,di=e=>Math.min(255,Math.max(0,e)),De=(e,t)=>di(e.endsWith("%")?parseFloat(e)/100*255:parseFloat(e)*t),Vo=e=>{if(e===void 0)return 1;let t=parseFloat(e);return Math.min(1,Math.max(0,e.endsWith("%")?t/100:t))};function hi(e){let t=li.exec(e)??ci.exec(e);if(t)return{r:De(t[1],1),g:De(t[2],1),b:De(t[3],1),a:Vo(t[4])};let o=ui.exec(e);return o?{r:De(o[1],255),g:De(o[2],255),b:De(o[3],255),a:Vo(o[4])}:null}var be,Bt=!1;function pi(e){if(Bt)return null;try{if(be??=document.createElement("canvas").getContext("2d",{willReadFrequently:!0}),!be)return Bt=!0,null;be.fillStyle="#000000",be.fillStyle=e;let t=be.fillStyle;if(be.fillStyle="#ffffff",be.fillStyle=e,t==="#000000"&&be.fillStyle==="#ffffff")return null;be.clearRect(0,0,1,1),be.fillRect(0,0,1,1);let[o,a,n,s]=be.getImageData(0,0,1,1).data;return{r:o,g:a,b:n,a:s/255}}catch{return Bt=!0,null}}var ft=new Map;function L(e){if(e==null)return null;if(ft.has(e))return ft.get(e);let t=hi(e)??pi(e);return ft.size<1e4&&ft.set(e,t),t}function Gt(e){let t=e/255;return t<=.04045?t/12.92:((t+.055)/1.055)**2.4}function ke({r:e,g:t,b:o}){return .2126*Gt(e)+.7152*Gt(t)+.0722*Gt(o)}function H(e,t){let[o,a]=[ke(e),ke(t)].sort((n,s)=>s-n);return(o+.05)/(a+.05)}var qt=e=>String(Math.round(e*100)/100),he=e=>`rgb(${qt(e.r)}, ${qt(e.g)}, ${qt(e.b)})`;function K(e){return(e>=10?(Math.floor(e*10)/10).toFixed(1):(Math.floor(e*100)/100).toFixed(2)).replace(/\.0+$/,"")}function G(e,t){let o=e.a+t.a*(1-e.a),a=(n,s)=>(n*e.a+s*t.a*(1-e.a))/(o||1);return{r:a(e.r,t.r),g:a(e.g,t.g),b:a(e.b,t.b),a:o}}var Ze=new WeakMap,Vt=new WeakMap,Fe=null,Xe=null,Ae=null,_t=new WeakMap,Ht=new WeakMap,jt=new WeakMap,gt=new WeakMap,bt=new WeakMap,wt=new WeakMap,_o=Symbol("background-image in chain");function Ko(){Ze=new WeakMap,Vt=new WeakMap,Fe=null,Xe=null,Ae=null,_t=new WeakMap,Ht=new WeakMap,jt=new WeakMap,gt=new WeakMap,bt=new WeakMap,wt=new WeakMap}var Xo=e=>e.assignedSlot??e.parentElement??e.getRootNode()?.host??null;function fi(e){if(!e||e==="none")return!1;let t=0,o="";for(let a of e)if(a==="("){if(t===0&&o&&o!=="drop-shadow")return!0;t+=1,o=""}else a===")"?t-=1:t===0&&(o=/[a-z-]/i.test(a)?o+a.toLowerCase():"");return!1}function Zo(e){if(!e||e.nodeType!==1)return!1;if(gt.has(e))return gt.get(e);let t=getComputedStyle(e),a=!!(fi(t.filter)||t.mixBlendMode&&t.mixBlendMode!=="normal"||Zo(Xo(e)));return gt.set(e,a),a}function Jo(e){if(!e||e.nodeType!==1)return!1;if(bt.has(e))return bt.get(e);let t=getComputedStyle(e),o;return(L(t.backgroundColor)?.a??0)>=1?o=!1:t.backdropFilter&&t.backdropFilter!=="none"||t.filter&&t.filter!=="none"?o=!0:o=Jo(Xo(e)),bt.set(e,o),o}function Pe(e){return!e||e.nodeType!==1?!1:Zo(e)||Jo(e)}function Yt(e){if(!e||e.nodeType!==1)return!1;if(wt.has(e))return wt.get(e);let t=getComputedStyle(e),o=L(t.backgroundColor),a=!1;return(!o||o.a<1)&&(a=t.isolation==="isolate"||["fixed","sticky"].includes(t.position)||t.zIndex!=="auto"||["transform","perspective","filter","backdropFilter","clipPath","maskImage","webkitMaskImage"].some(s=>t[s]&&t[s]!=="none")||/(?:paint|layout|strict|content)/.test(t.contain)||t.willChange&&t.willChange!=="auto"||parseFloat(t.opacity)<1||Yt(e.assignedSlot??e.parentElement??e.getRootNode()?.host)),wt.set(e,a),a}function Kt(e){for(let t=e;t;t=t.parentElement){let o=Ht.get(t);if(o===void 0){let a=getComputedStyle(t);if(o=!1,a.clip!=="auto"&&a.position!=="static"){let n=/rect\(([^)]+)\)/.exec(a.clip);if(n){let s=n[1].split(",").map(i=>i.trim());if(!s.includes("auto")&&s.length===4){let[i,r,l,d]=s.map(parseFloat);(r-d<=0||l-i<=0)&&(o=!0)}}}if(!o&&a.clipPath&&a.clipPath!=="none"){let n=/inset\(([^)]+)\)/.exec(a.clipPath);if(n&&!n[1].includes("px")){let s=n[1].trim().split(/\s+/).map(parseFloat),[i,r=i,l=i,d=r]=s;(i+l>=100||d+r>=100)&&(o=!0)}}Ht.set(t,o)}if(o)return!0}return!1}function Qo(e){for(let t=e;t&&t.nodeType===1;t=t.assignedSlot??t.parentElement??t.getRootNode()?.host){let o=getComputedStyle(t);if(o.backgroundImage!=="none"&&!Ce(o.backgroundImage))return null;let a=L(o.backgroundColor);if(!(!a||a.a===0))return a.a>=1?o.backgroundColor:null}return null}var ea=new Set;function Ce(e){if(e.includes("gradient("))return!1;let t=[...e.matchAll(/url\(["']?(.*?)["']?\)/g)].map(o=>o[1]);return t.length>0&&t.every(o=>ea.has(o))}function Xt(e){let t=getComputedStyle(e.documentElement).colorScheme??"",o=typeof matchMedia=="function"&&matchMedia("(prefers-color-scheme: dark)").matches;return/dark/.test(t)&&(!/light/.test(t)||o)?{r:18,g:18,b:18,a:1}:{r:255,g:255,b:255,a:1}}function ta(e,t){if(!e||e.nodeType!==1)return Xt(t);if(Ze.has(e)){let n=Ze.get(e);return n===_o?null:n}let o,a=getComputedStyle(e);if(a.backgroundImage!=="none"&&!Ce(a.backgroundImage))o=null;else{let n=L(a.backgroundColor);if(n&&n.a>=1)o=n;else{let s=ta(e.assignedSlot??e.parentElement??e.getRootNode()?.host,t);o=s===null?null:n&&n.a>0?G(n,s):s}}return Ze.set(e,o===null?_o:o),o}function ne(e){return ta(e,e.ownerDocument)}function Zt(e){if(!Fe){Fe=new WeakMap;for(let t of typeof e.getAnimations=="function"?e.getAnimations():[]){if(t.playState!=="running")continue;let o=t.effect?.target;if(!o)continue;let a=t.effect.getKeyframes?.()??[];if(!a.some(r=>r.opacity!==void 0))continue;let n=null,s=t.effect.getComputedTiming?.()??{};if(Number.isFinite(s.endTime)&&(s.fill==="forwards"||s.fill==="both")){let r=[...a].reverse().find(d=>d.opacity!==void 0),l=parseFloat(r?.opacity);Number.isFinite(l)&&(n=l)}let i=Fe.get(o);(i===void 0||n!==null&&(i===null||n<i))&&Fe.set(o,n)}}return Fe}function yt(e){let t=Zt(e.ownerDocument);for(let o=e;o&&o.nodeType===1;o=o.parentElement??o.getRootNode()?.host)if(t.has(o))return!0;return!1}function xt(e){let t=Zt(e.ownerDocument),o=1;for(let a=e;a&&a.nodeType===1;a=a.parentElement??a.getRootNode()?.host)if(t.has(a)){let n=t.get(a);o*=n===null?1:n}else o*=parseFloat(getComputedStyle(a).opacity)||0;return o}function Ee(e){if(!e||e.nodeType!==1)return 1;let t=Vt.get(e);if(t===void 0){let o=e.parentElement??e.getRootNode()?.host??null;t=(parseFloat(getComputedStyle(e).opacity)||0)*Ee(o),Vt.set(e,t)}return t}function Ho(e){let t=Zt(e.ownerDocument);if(t.has(e)){let a=t.get(e);return a===null?1:a}let o=parseFloat(getComputedStyle(e).opacity);return Number.isFinite(o)?o:1}function vt(e,t){let o=u=>u.parentElement??u.getRootNode()?.host??null,a=null,n=1;for(let u=e;u&&u.nodeType===1;u=o(u)){let c=Ho(u);c<1&&(a=u,n*=c)}if(!a)return null;let s={...t},i={r:0,g:0,b:0,a:0},r=!1;for(let u=e;u&&u.nodeType===1;u=o(u)){let c=getComputedStyle(u);if(c.backgroundImage!=="none"&&!Ce(c.backgroundImage)||c.mixBlendMode&&c.mixBlendMode!=="normal"||c.filter&&c.filter!=="none"||c.backdropFilter&&c.backdropFilter!=="none")return null;let h=L(c.backgroundColor);h&&h.a>0&&(s=G(s,h),i=G(i,h),r=!0);let f=Ho(u);if(f<1&&(s={...s,a:s.a*f},i={...i,a:i.a*f}),u===a)break}if(!r)return null;let l=o(a),d=l?ne(l):Xt(e.ownerDocument);return d?{foreground:G(s,d),background:G(i,d),opacity:n,text:s,paint:i}:{unresolved:!0,opacity:n}}function oa(e){let t=e.ownerDocument;if(typeof t.elementsFromPoint!="function")return null;let o=L(getComputedStyle(e).backgroundColor);if(o&&o.a>=1)return null;let a=e.getBoundingClientRect();if(!a.width||!a.height)return null;let n=t.defaultView,s=Math.min(Math.max(a.left+a.width/2,0),n.innerWidth-1),i=Math.min(Math.max(a.top+a.height/2,0),n.innerHeight-1),r=t.elementsFromPoint(s,i),l=r.indexOf(e);if(l===-1)return"unverifiable";for(let d of r.slice(l+1)){if(d.contains(e)){let u=getComputedStyle(d);if(u.backgroundImage!=="none")return d;let c=L(u.backgroundColor);if(c&&c.a>=1)return null;continue}return d}return null}function Je(e){for(let o of e.childNodes){if(o.nodeType!==3||!o.textContent.trim())continue;let a=e.ownerDocument.createRange();a.selectNodeContents(o);let n=a.getClientRects()[0];if(n&&n.width&&n.height)return{x:n.left+n.width/2,y:n.top+n.height/2}}let t=e.getBoundingClientRect();return t.width&&t.height?{x:t.left+t.width/2,y:t.top+t.height/2}:null}var se=e=>typeof e=="string"&&e.endsWith("px")?parseFloat(e):NaN;function mi(e){for(let t=e;t&&t.nodeType===1;t=t.parentElement){let o=getComputedStyle(t);if(o.position!=="static"||o.transform!=="none"||o.filter!=="none"||/paint|layout|strict|content/.test(o.contain??""))return t}return null}function gi(e,t){let o=mi(e);if(!o)return null;let a=getComputedStyle(o),n=o.getBoundingClientRect(),s=se(a.borderLeftWidth)||0,i=se(a.borderTopWidth)||0,r=n.left+s,l=n.top+i,d=n.width-s-(se(a.borderRightWidth)||0),u=n.height-i-(se(a.borderBottomWidth)||0),c=(se(t.paddingLeft)||0)+(se(t.paddingRight)||0)+(se(t.borderLeftWidth)||0)+(se(t.borderRightWidth)||0),h=(se(t.paddingTop)||0)+(se(t.paddingBottom)||0)+(se(t.borderTopWidth)||0)+(se(t.borderBottomWidth)||0),f=(I,O,F,E,q,B)=>{let k=se(I),U=se(O),N=se(F);if(Number.isFinite(k)&&Number.isFinite(U))return[E+k,E+q-U];if(Number.isFinite(k)&&Number.isFinite(N))return[E+k,E+k+N+B];if(Number.isFinite(U)&&Number.isFinite(N)){let V=E+q-U;return[V-N-B,V]}return null},m=f(t.left,t.right,t.width,r,d,c),y=f(t.top,t.bottom,t.height,l,u,h);if(!m||!y)return null;let[g,w]=m,[b,x]=y;if(t.transform&&t.transform!=="none"){let I=/^matrix\(([^)]+)\)$/.exec(t.transform);if(!I)return null;let[O,F,E,q,B,k]=I[1].split(",").map(Number);if(O!==1||F!==0||E!==0||q!==1)return null;g+=B,w+=B,b+=k,x+=k}return{left:g,top:b,right:w,bottom:x,empty:!(w>g)||!(x>b)}}function bi(e){let t=_t.get(e);if(t!==void 0)return t;t=[];for(let o of["::before","::after"]){let a=getComputedStyle(e,o);if(a.content==="none"||a.display==="none"||a.visibility==="hidden")continue;let n=L(a.backgroundColor);if(!(a.backgroundImage!=="none"||(n?.a??0)>0)||a.position!=="absolute"&&a.position!=="fixed")continue;let i=parseFloat(a.opacity),r=Number.isFinite(i)?i:1,l=a.position==="absolute"?gi(e,a):null;if(!l){let h=Math.min(1,r*(a.backgroundImage!=="none"?1:n.a));h>0&&t.push({film:h,fixed:a.position==="fixed"});continue}if(l.empty)continue;let d=n;d&&r<1&&(d={...d,a:d.a*r});let u=a.backgroundImage!=="none"?a.backgroundImage:null,c=u?{repeat:a.backgroundRepeat,size:a.backgroundSize,position:a.backgroundPosition}:null;t.push({rect:l,color:d,imageCss:u,imageMeta:c})}return _t.set(e,t),t}function At(e){let t=Je(e);if(!t)return null;let o=null,a=null,n=!1,s=0,i=!1,r=!1;for(let l=e;l&&l.nodeType===1;l=l.parentElement??l.getRootNode()?.host){for(let d of bi(l)){if(d.film){if(!d.fixed&&i)continue;s=1-(1-s)*(1-d.film);continue}if(n)continue;let{rect:u,color:c,imageCss:h}=d;if(!(t.x<u.left||t.x>u.right||t.y<u.top||t.y>u.bottom)){if(h){a={css:h,element:l,box:u,meta:d.imageMeta},n=!0,r=r||i;continue}!c||c.a===0||(o=o?G(o,c):c,r=r||i,o.a>=1&&(n=!0))}}if(!i){let d=getComputedStyle(l);(d.backgroundImage!=="none"&&!Ce(d.backgroundImage)||(L(d.backgroundColor)?.a??0)>=1)&&(i=!0)}}return a?{image:a,...s>0&&{film:s},...r&&{beyondPaint:r}}:o?{color:o,...s>0&&{film:s},...r&&{beyondPaint:r}}:s>0?{film:s}:null}function aa(e,t,o){let a=[H(e,t)],n=ke(e),s=[];for(let i of[0,255]){let r={r:i,g:i,b:i,a:o},l=G(r,t);a.push(H(e,l)),a.push(H(G(r,e),l)),s.push(Math.sign(n-ke(l)))}return{min:Math.min(...a),max:Math.max(...a),crossed:s[0]!==s[1]}}function wi(e,t,o){let a=t.getBoundingClientRect(),n=[];for(let s of e){if(s.contains(t)||t.contains(s))continue;let i=getComputedStyle(s),r=L(i.backgroundColor),l=(r?r.a:0)*(parseFloat(i.opacity)||1);if(!(i.backdropFilter&&i.backdropFilter!=="none")&&(l<.15||l>=1))continue;let u=s.getBoundingClientRect(),c=(Math.min(u.right,o.innerWidth)-Math.max(u.left,0))*(Math.min(u.bottom,o.innerHeight)-Math.max(u.top,0))>=.6*o.innerWidth*o.innerHeight,h=u.left<=a.left+1&&u.top<=a.top+1&&u.right>=a.right-1&&u.bottom>=a.bottom-1;c&&h&&n.push(s)}return n.length?n:null}function Jt(e){let t=[];for(let o of e){let a=getComputedStyle(o);if(a.backdropFilter&&a.backdropFilter!=="none"||a.filter&&a.filter!=="none"||a.mixBlendMode&&a.mixBlendMode!=="normal"||a.backgroundImage!=="none")return null;let n=L(a.backgroundColor);if(!n)return null;let s=n.a*(parseFloat(a.opacity)||1);s<=0||t.push({...n,a:s})}return t.length?t:null}function Qt(e){let t=e.ownerDocument,o=t.defaultView;if(typeof t.elementsFromPoint!="function")return"unresolved";let a=Je(e);if(!a)return"unresolved";if(a.x<0||a.y<0||a.x>=o.innerWidth||a.y>=o.innerHeight)return"offscreen";let n=t.elementsFromPoint(a.x,a.y),s=n.indexOf(e),i=s>0?wi(n.slice(0,s),e,o):null,r=null,l=[],d=L(getComputedStyle(e).backgroundColor);if(d&&d.a>0){if(d.a>=1)return{color:d,scrim:i};r=d,l.push(d)}if(s===-1)return"unresolved";let u=[],c=new Set(n);for(let m=e.parentElement??e.getRootNode()?.host;m&&m.nodeType===1;m=m.parentElement??m.getRootNode()?.host){if(c.has(m))continue;let y=m.getBoundingClientRect();if(a.x<y.left||a.x>=y.right||a.y<y.top||a.y>=y.bottom)continue;let g=getComputedStyle(m),w=L(g.backgroundColor);(w&&w.a>0||g.backgroundImage!=="none"&&!Ce(g.backgroundImage))&&u.push(m)}let h=[];for(let m of n.slice(s+1)){for(;u.length&&!u[0].contains(m);)h.push(u.shift());h.push(m)}h.push(...u);for(let m of h){if(/^(img|video|canvas|svg|picture|object|embed|iframe)$/i.test(m.tagName))return{image:m,scrim:i,overlays:l};let y=getComputedStyle(m);if(m.shadowRoot||y.mixBlendMode&&y.mixBlendMode!=="normal"||y.filter&&y.filter!=="none"||y.backdropFilter&&y.backdropFilter!=="none")return"unresolved";if(y.backgroundImage!=="none"){let b=vi(m),x=I=>!I||a.x>=I.left&&a.x<I.right&&a.y>=I.top&&a.y<I.bottom;if(!b.length||b.some(x))return{image:m,scrim:i,overlays:l}}let g=L(y.backgroundColor);if(!g)return"unresolved";let w=parseFloat(y.opacity);if(w<1&&(g={...g,a:g.a*w}),g.a!==0){if(r=r?G(r,g):g,r.a>=1)return{color:r,scrim:i};l.push(g)}}let f=Xt(t);return{color:r?G(r,f):f,scrim:i}}function kt(e){if(!Ae){Ae={panels:[],veil:null};let t=e.defaultView,o=e.querySelectorAll("body *");if(o.length<=3e4)for(let a of o){let n=getComputedStyle(a);if(n.position==="static"&&n.cssFloat==="none")continue;let s=L(n.backgroundColor),i=a.getBoundingClientRect();if(s&&s.a>=1&&i.width>=24&&i.height>=12&&Ae.panels.push({element:a,rect:i,color:s,hitTestBlind:n.pointerEvents==="none"}),!Ae.veil&&(n.position==="fixed"||n.position==="sticky")&&n.visibility!=="hidden"){let r=(s?s.a:0)*(parseFloat(n.opacity)||1),l=n.backdropFilter&&n.backdropFilter!=="none";i.width>=.9*t.innerWidth&&i.height>=.9*t.innerHeight&&(l||r>=.15&&r<1)&&(Ae.veil=a)}}}return Ae.panels}function eo(e){return kt(e),Ae.veil}function na(e){if(!e||e==="none")return[];let t=[];for(let o of e.split(/,(?![^(]*\))/)){let a=/rgba?\([^)]*\)|#[0-9a-fA-F]{3,8}\b/.exec(o),n=[...o.replace(a?.[0]??"","").matchAll(/(-?\d*\.?\d+)px/g)].map(s=>parseFloat(s[1]));n.length<2||t.push({x:n[0],y:n[1],blur:n[2]??0,color:L(a?.[0]??"")})}return t}function sa(e,t){let o=Math.max(2,t*.25),a=new Map;for(let n of na(e)){if(!n.color||n.color.a<.95||n.blur>o||Math.abs(n.x)>o||Math.abs(n.y)>o)continue;let s=`${Math.round(n.color.r)},${Math.round(n.color.g)},${Math.round(n.color.b)}`,i=a.get(s)??{color:n.color,up:!1,down:!1,left:!1,right:!1};n.blur>=Math.max(Math.abs(n.x),Math.abs(n.y),.5)?i.up=i.down=i.left=i.right=!0:(n.x>0&&(i.right=!0),n.x<0&&(i.left=!0),n.y>0&&(i.down=!0),n.y<0&&(i.up=!0)),a.set(s,i)}for(let n of a.values())if(n.up&&n.down&&n.left&&n.right)return n.color;return null}function ia(e,t){return na(e).every(o=>!o.color||o.color.a<.15||o.blur>t*.5)}function yi(e,t){let{left:o,top:a,right:n,bottom:s}=t,i=getComputedStyle(e).position;for(let r=e.parentElement;r&&i!=="fixed";r=r.parentElement){let l=getComputedStyle(r),d=l.position!=="static"||l.transform!=="none"||l.filter&&l.filter!=="none";if(i==="absolute"&&!d)continue;let u=c=>c==="hidden"||c==="clip";if(u(l.overflowX)||u(l.overflowY)){let c=r.getBoundingClientRect();if(u(l.overflowX)&&(o=Math.max(o,c.left),n=Math.min(n,c.right)),u(l.overflowY)&&(a=Math.max(a,c.top),s=Math.min(s,c.bottom)),n<=o||s<=a)return null}i=l.position}return{left:o,top:a,right:n,bottom:s,width:n-o,height:s-a,x:o,y:a}}function to(e){if(!Xe){Xe=[];for(let t of e.querySelectorAll("img, video, canvas, svg")){let o=yi(t,t.getBoundingClientRect());o&&o.width>=8&&o.height>=8&&Xe.push({element:t,rect:o,hitTestBlind:getComputedStyle(t).pointerEvents==="none"})}}return Xe}function Be(e){let t=[];for(let o=e;o;o=o.parentElement){let a=getComputedStyle(o);if(a.backgroundImage!=="none")return{css:a.backgroundImage,element:o,overlays:t};let n=L(a.backgroundColor);if(n&&n.a>=1)return null;n&&n.a>0&&t.push(n)}return null}function Se(e,t){let o=e;for(let a=t.length-1;a>=0;a--)o=G(t[a],o);return o}var jo=e=>e.map(t=>`${t.r},${t.g},${t.b},${t.a}`).join(";"),zt=new Map,xi=1024;function ra(e){if(!e||!(e.width>0)||!(e.height>0))return null;let t=n=>Math.min(xi,Math.max(32,Math.ceil(n/4))),o=t(e.width),a=t(e.height);return{width:o,height:a,reduced:e.width/o>4.5||e.height/a>4.5}}function Qe(e,t=[],o=null,a=null){let n=o?.width??32,s=o?.height??32,i=n===32&&s===32?"":`|${n}x${s}`,r=a?.a>=1?a:null,l=`${e}${t.length?`|${jo(t)}`:""}${i}${r?`|under:${jo([r])}`:""}`;if(zt.has(l))return zt.get(l);let d=new Promise(u=>{let c=new Image;c.crossOrigin="anonymous";let h=setTimeout(()=>u(null),1500);c.onload=()=>{clearTimeout(h);try{let f=document.createElement("canvas");f.width=n,f.height=s;let m=f.getContext("2d",{willReadFrequently:!0});m.drawImage(c,0,0,n,s);let y=m.getImageData(0,0,n,s).data,g=1/0,w=-1/0,b=null,x=null,I=0,O=!1;for(let E=0;E<y.length;E+=4){if(y[E+3]<255&&!r&&(O=!0),y[E+3]>0&&(I+=1),y[E+3]===0&&!r)continue;let q={r:y[E],g:y[E+1],b:y[E+2],a:y[E+3]/255},B=r?G(q,r):{...q,a:1},k=t.length?Se(B,t):B,U=ke(k);U<g&&(g=U,b=k),U>w&&(w=U,x=k)}if(!I){ea.add(e),Ze=new WeakMap,u({transparent:!0,width:c.naturalWidth,height:c.naturalHeight});return}let F=!!o?.reduced&&(c.naturalWidth>n||c.naturalHeight>s);u(g<=w?{min:g,max:w,minColor:b,maxColor:x,hasAlpha:O,width:c.naturalWidth,height:c.naturalHeight,reduced:F}:null)}catch{u(null)}},c.onerror=()=>{clearTimeout(h),u(null)},c.src=e});return zt.set(l,d),d}function vi(e){let t=getComputedStyle(e),o=Ie(t.backgroundImage);if(!o.length)return[];let a=e.getBoundingClientRect(),n=Ie(t.backgroundSize),s=Ie(t.backgroundPosition),i=Ie(t.backgroundRepeat),r=(l,d)=>l.length?l[d%l.length]:void 0;return o.map((l,d)=>{if(l==="none")return{left:0,top:0,right:0,bottom:0};if((r(i,d)??"repeat")!=="no-repeat")return null;let c=r(n,d)??"auto";if(c==="cover"||c==="contain")return null;let h=Yo(c),f=(F,E)=>F?.endsWith("px")?parseFloat(F):F?.endsWith("%")?parseFloat(F)/100*E:null,m=f(h[0],a.width),y=f(h[1]??h[0],a.height);if(m===null||y===null||Number.isNaN(m)||Number.isNaN(y))return null;let g=Yo(r(s,d)??"0% 0%"),w=(F,E,q)=>F?.endsWith("%")?parseFloat(F)/100*(E-q):F?.endsWith("px")?parseFloat(F):null,b=w(g[0],a.width,m),x=w(g[1]??"50%",a.height,y);if(b===null||x===null||Number.isNaN(b)||Number.isNaN(x))return null;let I=a.left+b,O=a.top+x;return{left:I,top:O,right:I+m,bottom:O+y}})}function Yo(e){let t=[],o=0,a="";for(let n of e){if(n==="("&&(o+=1),n===")"&&(o-=1),/\s/.test(n)&&o===0){a&&t.push(a),a="";continue}a+=n}return a&&t.push(a),t}function Ie(e){if(!e||e==="none")return e==="none"?["none"]:[];let t=[],o=0,a="";for(let n of e){if(n==="("&&(o+=1),n===")"&&(o-=1),n===","&&o===0){t.push(a.trim()),a="";continue}a+=n}return a.trim()&&t.push(a.trim()),t}function la(e,t){let o=getComputedStyle(e);if(Ie(o.backgroundImage).filter(n=>n!=="none").length!==1)return null;let a=e.getBoundingClientRect();return oo({left:a.left,top:a.top,right:a.right,bottom:a.bottom},{repeat:o.backgroundRepeat,size:o.backgroundSize,position:o.backgroundPosition},t)}function oo(e,t,o){if(!e||!t||t.repeat!=="no-repeat"||t.size==="cover"||t.size==="contain")return null;let a=e.right-e.left,n=e.bottom-e.top,s=(y,g,w)=>y?.endsWith("px")?parseFloat(y):y?.endsWith("%")?parseFloat(y)/100*g:w,i=t.size.split(" "),r=s(i[0],a,o?.width),l=s(i[1]??i[0],n,o?.height);if(!Number.isFinite(r)||!Number.isFinite(l))return null;let d=(y,g,w)=>y?.endsWith("%")?parseFloat(y)/100*(g-w):y?.endsWith("px")?parseFloat(y):null,u=t.position.split(" "),c=d(u[0],a,r),h=d(u[1]??"50%",n,l);if(c===null||h===null||Number.isNaN(c)||Number.isNaN(h))return null;let f=e.left+c,m=e.top+h;return{left:f,top:m,right:f+r,bottom:m+l}}function ca(e,t,o=[]){if(!e||!e.hasAlpha)return e;if(!t||t.a<1)return null;let a=o.length?Se(t,o):t,n=ke(a);return{...e,min:Math.min(e.min,n),max:Math.max(e.max,n),minColor:n<e.min?a:e.minColor,maxColor:n>e.max?a:e.maxColor}}function Ge(e){return Ie(e)}function ao(e){let t=/^url\(([\s\S]*)\)$/.exec((e??"").trim());if(!t)return null;let o=t[1].trim(),a=o[0];return(a==='"'||a==="'")&&o.endsWith(a)&&(o=o.slice(1,-1).replace(new RegExp(`\\\\${a}`,"g"),a)),o}var Ai=/^(?:(?:to|at|from|in|circle|ellipse|closest-side|closest-corner|farthest-side|farthest-corner)\b|calc\(|-?\d|\.\d)/i;function no(e){let t={colors:[],unparsed:0,translucent:!1,space:null},o=e.indexOf("("),a=e.lastIndexOf(")");if(o===-1||a<=o)return t;for(let n of Ie(e.slice(o+1,a))){let s=/(?:^|\s)in\s+([a-z0-9-]+)/i.exec(n);s&&s[1].toLowerCase()!=="srgb"&&(t.space=s[1].toLowerCase());let i=null,r=/([a-z][a-z0-9-]*)\(/i.exec(n);if(r){let d=0;for(let u=r.index;u<n.length;u++)if(n[u]==="("&&(d+=1),n[u]===")"&&(d-=1,d===0)){i=n.slice(r.index,u+1);break}}else i=n.trim().split(/\s+/)[0]??"";if(!i||Ai.test(i))continue;let l=/^currentcolor$/i.test(i)?null:L(i);if(!l){t.unparsed+=1;continue}l.a<1&&(t.translucent=!0),t.colors.push(l)}return t}function et(e,t=[],o=16){let{colors:a,unparsed:n,translucent:s,space:i}=no(e);if(!a.length||n||s||i)return null;let r=[];a.length===1&&r.push(a[0]);for(let f=0;f+1<a.length;f++){let m=a[f],y=a[f+1];for(let g=0;g<=o;g++){let w=g/o;r.push({r:m.r+(y.r-m.r)*w,g:m.g+(y.g-m.g)*w,b:m.b+(y.b-m.b)*w,a:1})}}let l=r.map(f=>t.length?Se(f,t):f),d=1/0,u=-1/0,c=null,h=null;for(let f of l){let m=ke(f);m<d&&(d=m,c=f),m>u&&(u=m,h=f)}return{min:d,max:u,minColor:c,maxColor:h,sampled:!0}}function mt(e,t){let[o,a]=e>t?[e,t]:[t,e];return(o+.05)/(a+.05)}function ua(e,t,o){let a=ke(e),s=a>=t.min&&a<=t.max?1:Math.min(mt(a,t.min),mt(a,t.max)),i=Math.max(mt(a,t.min),mt(a,t.max));return s>=o?{verdict:"pass",worst:s,best:i}:i<o?{verdict:"fail",worst:s,best:i}:{verdict:"mixed",worst:s,best:i}}function ki(e){let t=jt.get(e);if(t!==void 0)return t;t=!1;let o=n=>{for(let s of n){if(s.selectorText&&/::?first-(?:line|letter)\b/.test(s.selectorText))return!0;let i=s.cssRules??s.styleSheet?.cssRules;if(i&&o(i))return!0}return!1},a=[...e.styleSheets??[],...e.adoptedStyleSheets??[]];for(let n of a)try{if(o(n.cssRules)){t=!0;break}}catch{t=!0;break}return jt.set(e,t),t}function da(e,t){if(t.display==="inline"||t.display==="contents")return[];if(!ki(e.getRootNode()))return[];let o=s=>s.webkitTextFillColor&&s.webkitTextFillColor!==s.color?s.webkitTextFillColor:s.color,a=o(t),n=[];for(let s of["::first-line","::first-letter"]){let i=getComputedStyle(e,s),r=o(i);if(!r||r===a)continue;let l=L(r);l&&n.push({pseudo:s,color:l,style:i})}return n}var so=600;function qe(e){let t=parseFloat(e.fontSize),o=parseInt(e.fontWeight,10)||400;return t>=24||t>=56/3&&o>=so}var ha=e=>Ge(e??"").map(ao).find(Boolean)??null,Ct=e=>e?{width:e.right-e.left,height:e.bottom-e.top}:null,Ci=/^([|¦·•∙‧/⁄\\‐‑‒–—―⁃«»‹›-])\1*$/,ze=(e,t)=>({status:"incomplete",message:"This text sits behind a translucent full-page overlay (a modal or loading veil), which changes its presented contrast"+(e&&t?`: ${K(e)}:1 at rest, ${K(t)}:1 as presented through the overlay, which straddles the threshold`:"")+" \u2014 judge the page with the overlay dismissed, or the dimmed state by eye if the overlay is permanent."}),Si='button, a[href], input, select, textarea, fieldset, optgroup, option, [role="button"], [role="link"], [role="checkbox"], [role="radio"], [role="switch"], [role="tab"], [role="menuitem"], [role="menuitemcheckbox"], [role="menuitemradio"], [role="option"], [role="slider"], [role="spinbutton"], [role="textbox"], [role="searchbox"], [role="combobox"], [role="gridcell"], [role="treeitem"], [role="scrollbar"], [role="separator"], [role="application"], [role="group"], [role="listbox"], [role="menu"], [role="menubar"], [role="radiogroup"], [role="tablist"], [role="tree"], [role="treegrid"], [role="grid"], [role="toolbar"]';function Ti(e){for(let o=e;o;o=o.parentElement){let a=o.closest(":disabled");if(!a)break;if(a.tagName!=="FIELDSET")return!0;let n=e.closest("legend");if(!n||n.parentElement!==a||a.querySelector(":scope > legend")!==n)return!0;o=a}let t=e.closest('[aria-disabled="true"]');return!!(t&&t.matches(Si))}function Ri(e){return e.matches(':disabled, [aria-disabled="true"], [tabindex="-1"]')||e.closest("[inert]")?!0:!e.matches("button, a[href], input, select")&&!e.hasAttribute("tabindex")&&!e.isContentEditable}function Ni(e){let t=e.ownerDocument;if(typeof t.elementsFromPoint!="function")return!1;let o=e.textContent.trim();if(!o)return!1;let a=e.getBoundingClientRect(),n=t.defaultView,s=a.left+a.width/2,i=a.top+a.height/2;if(s<0||i<0||s>=n.innerWidth||i>=n.innerHeight)return!1;let r=t.elementsFromPoint(s,i),l=r.indexOf(e);return l<=0?!1:r.slice(0,l).some(d=>!d.contains(e)&&!e.contains(d)&&d.textContent.trim()===o)}function Me(e,t){let o=e.getBoundingClientRect();if(Math.min(o.right,t.right)-Math.max(o.left,t.left)<3||Math.min(o.bottom,t.bottom)-Math.max(o.top,t.top)<3)return!1;let a=e.ownerDocument.createRange();for(let n of e.childNodes)if(!(n.nodeType!==Node.TEXT_NODE||!n.textContent.trim())){a.selectNodeContents(n);for(let s of a.getClientRects()){let i=Math.min(s.right,t.right)-Math.max(s.left,t.left),r=Math.min(s.bottom,t.bottom)-Math.max(s.top,t.top);if(i>=3&&r>=3)return!0}}return!1}async function $i(e,t,o){let a=ha(e.css),n=null;if(a)try{n=await Qe(new URL(a,o.baseURI).href)}catch{}let s=!n||!n.width||n.width===300&&n.height===150,i=!a&&e.css.includes("gradient("),r=!1;if(i){let u=[...(getComputedStyle(e.element).backgroundSize??"").matchAll(/(\d+(?:\.\d+)?)px/g)].map(c=>parseFloat(c[1]));r=u.length>0&&u.every(c=>c<=40)}let l=la(e.element,s?null:n);return l?{relation:Me(t,l)?"under":"clear",intrinsic:n,dimensionless:s,isGradient:i,sizedSmall:r,paint:l}:{relation:"unknown",intrinsic:n,dimensionless:s,isGradient:i,sizedSmall:r,paint:null}}function Ii(e,t,o){if(o?.a===0||parseFloat(t.fontSize)===0||parseFloat(t.opacity)===0)return!0;let a=parseFloat(t.textIndent)||0,n=/hidden|clip/.test(`${t.overflow} ${t.overflowX} ${t.overflowY}`)||t.clipPath!=="none"||t.clip!=="auto"&&t.position==="absolute";if(!n&&Math.abs(a)<=1e3)return Kt(e);let s=e.getBoundingClientRect();return(s.width<=1||s.height<=1)&&n||Math.abs(a)>s.width&&(n||Math.abs(a)>1e3)?!0:Kt(e)}function pa(e,t,o,a,n=!1){if(!e)return null;let{verdict:s,worst:i,best:r}=ua(t,e,o);return s==="pass"?n?{status:"incomplete",message:`The ${a} behind this text is too large to sample at glyph scale, so detail narrower than the sampling grid could sit under the text unseen. Every sampled pixel passes (worst ${K(i)}:1), so confirm by eye.`}:{status:"pass"}:s==="fail"?{status:"fail",message:`Contrast against the ${a} behind this text is at best ${K(r)}:1 \u2014 below the ${o}:1 minimum against every part of it.`,fix:"Change the text colour, or place a solid overlay between the text and the image."}:{status:"incomplete",message:`The ${a} behind this text has both light and dark areas (contrast ranges ${K(i)}\u2013${K(r)}:1 for this text) \u2014 whether it passes depends on the exact overlap, check by eye.`}}function Ei(e,t){if(At(e)?.color?.a>0)return!0;let a=e.ownerDocument;if(typeof a.elementsFromPoint!="function")return!1;let n=e.getBoundingClientRect(),s=a.defaultView,i=n.left+n.width/2,r=n.top+n.height/2;if(i<0||r<0||i>=s.innerWidth||r>=s.innerHeight)return!1;let l=a.elementsFromPoint(i,r),d=l.indexOf(e);return d===-1?!1:l.slice(d+1).some(u=>{if(u.contains(e)||u===t)return!1;let c=L(getComputedStyle(u).backgroundColor);return c&&c.a>0})}function Mi(e,t){let o=e.ownerDocument,a=o.defaultView;if(typeof o.elementsFromPoint!="function")return;let n=Je(e);if(!n||n.x<0||n.y<0||n.x>=a.innerWidth||n.y>=a.innerHeight)return;let s=o.elementsFromPoint(n.x,n.y),i=s.indexOf(e);if(i===-1)return;let r=[];for(let l of s.slice(i+1)){if(l===t)return null;if(l.contains(e)){let c=L(getComputedStyle(l).backgroundColor);c&&c.a>0&&c.a<1&&r.push(c);continue}if(l.shadowRoot)return;if(/^(img|video|canvas|picture)$/i.test(l.tagName))return{covered:l};let d=getComputedStyle(l);if(d.backgroundImage!=="none"&&!Ce(d.backgroundImage))return{image:l,css:d.backgroundImage,overlays:r};let u=L(d.backgroundColor);if(u&&u.a>=1)return{covered:l}}return null}function Wi(e,t){let o=Je(t);if(!o)return!1;for(let a of e.querySelectorAll("*")){if(a.contains(t)||t.contains(a))continue;let n=getComputedStyle(a);if(n.position!=="absolute"&&n.position!=="fixed"||!(n.backgroundImage!=="none"&&!Ce(n.backgroundImage)||(L(n.backgroundColor)?.a??0)>=1)||a.checkVisibility?.({checkOpacity:!0,checkVisibilityCSS:!0})===!1)continue;let i=a.getBoundingClientRect();if(o.x>=i.left&&o.x<i.right&&o.y>=i.top&&o.y<i.bottom)return!0}return!1}var tt=Symbol("fully transparent image layer");function Li(e){let t=L(getComputedStyle(e).backgroundColor);if(t&&t.a>=1)return t;let o=e.parentElement??e.getRootNode()?.host??null,a=o?ne(o):null;return a?t&&t.a>0?G(t,a):a:null}async function St(e,t,o,a,n=[],s=null,i=null){if(!e)return null;let r=null,l="image",d=ra(i);if(e.tagName==="IMG")r=await Qe(e.currentSrc||e.src,n,d,s);else{let u=e.css??getComputedStyle(e).backgroundImage;if(!u||u==="none")return null;let c=Ge(u).filter(m=>m!=="none");if(c.length>1)return null;let h=c[0]??"",f=ao(h);if(f){let m;try{m=new URL(f,a.baseURI).href}catch{return null}r=await Qe(m,n,d,s)}else if(h.includes("gradient(")){l="gradient";let m=no(h);if(!m.colors.length||m.unparsed)return{status:"incomplete",message:"The gradient behind this text has colour stops this engine could not parse, so its range of colours could not be sampled. Check the contrast by eye."};if(m.space)return{status:"incomplete",message:`The gradient behind this text interpolates in ${m.space}, not sRGB, so the colours between its stops cannot be computed here. Check the contrast by eye.`};if(m.translucent)return{status:"incomplete",message:"The gradient behind this text has translucent colour stops, so what shows behind the glyphs is a blend with whatever is painted beneath the gradient. Check the contrast by eye."};r=et(h,n)}else return null}if(r?.transparent)return tt;if(r?.hasAlpha&&(r=ca(r,s,n),!r))return{status:"incomplete",message:`The ${l} behind this text has transparent regions, so parts of the text sit on whatever is painted beneath it, and that layer could not be resolved \u2014 check the contrast by eye.`};if(t.a<1){let u=[r?.minColor,r?.maxColor].filter(Boolean);if(u.length===2){let c=u.map(h=>H(G(t,h),h));if(c.every(h=>h<o)){let h=Math.max(...c);return{status:"fail",message:`This text is translucent, so it blends with what is behind it: against every part of that backdrop the blend reaches at best ${K(h)}:1, below the ${o}:1 minimum.`,fix:"Raise the text opacity, change its colour, or put a solid layer between the text and the backdrop.",data:{ratio:Number(K(h)),required:o}}}}return{status:"incomplete",message:"This text is translucent over an image or gradient, so its presented colour depends on the pixels beneath \u2014 contrast must be checked by eye."}}return!r&&l==="image"?{status:"incomplete",message:"The image painted behind this text can\u2019t be read: it is cross-origin, or it failed to load, so a script can\u2019t sample its colours. Check the contrast by eye."}:pa(r,t,o,l,!!r?.reduced)}function io({id:e,tags:t,help:o,helpUrl:a,thresholds:n}){let s=(l,d,u)=>{if(d!==n.normal||u<n.large)return"";let c=parseFloat(l.fontSize)||0,f=(parseInt(l.fontWeight,10)||400)>=so,m=f?56/3:24,y=f?"18.67px":"24px",g=Math.abs(c-m)<.05,w=g?`${c.toFixed(2)}px`:`${Math.round(c*10)/10}px`;return g&&parseFloat(w)>=parseFloat(y)&&(w=`just under ${y}`),f&&c<18.666666666666668?` This text is bold at ${w}; bold text counts as large scale from 18.67px (14pt), where the ${n.large}:1 minimum would apply and these colours would pass.`:!f&&c>=18.666666666666668&&c<24?` At ${w} regular weight this is not large scale; from 24px (18pt), or bold at this size, the ${n.large}:1 minimum would apply and these colours would pass.`:""},i={id:e,impact:"serious",tags:t,help:o,helpUrl:a,selector:"*:not(script):not(style):not(noscript):not(title):not(option):not(optgroup):not(input):not(textarea):not(select):not(svg):not(svg *):not(math):not(math *)",visibility:"visual",async evaluate(l,{ownText:d}){if(!d(l))return{status:"pass"};if(Ti(l))return{status:"pass"};let u=l;if(l.shadowRoot){let v=[...l.childNodes].find($=>$.nodeType===3&&$.textContent.trim())?.assignedSlot??null;if(!v)return{status:"pass"};u=v}let c=getComputedStyle(u),h=c.display.startsWith("inline")||/flex|grid/.test(l.parentElement?getComputedStyle(l.parentElement).display:"");if(Ci.test(d(l))&&h&&!l.closest('code, pre, samp, kbd, var, a[href], button, [role="button"], [role="link"], [role="menuitem"], [role="tab"], [role="option"]')){let C=(v,$)=>{for(let W=v;W;W=W[$])if(W.nodeType===3&&W.textContent.trim()||W.nodeType===1&&(W.textContent.trim()||W.matches("img, svg, video, canvas, input, select, button")))return!0;return!1};if(C(l.previousSibling,"previousSibling")&&C(l.nextSibling,"nextSibling"))return{status:"pass"}}let f=l.closest('button, a[href], input, select, [role="button"], [role="link"], [role="option"], [role="tab"]');if(f&&getComputedStyle(f).pointerEvents==="none"&&Ri(f))return(f.textContent||"").trim().length<=80?{status:"pass"}:{status:"incomplete",message:"This text sits inside a non-interactive (pointer-events: none) control with substantial content \u2014 a disabled control's dimmed text is exempt from contrast, but an inactive content slide is not. Judge which this is by eye."};let m=L(c.webkitTextFillColor);if(/\btext\b/.test(c.webkitBackgroundClip??"")||/\btext\b/.test(c.backgroundClip??"")){if(Pe(u))return{status:"incomplete",message:"A filter or blend mode changes the colours presented by this text and its background. Check the resulting contrast by eye."};let C=ne(l.parentElement??l),v=c.backgroundImage!=="none"?et(Ge(c.backgroundImage)[0]??""):null;if(v&&C){let $=qe(c)?n.large:n.normal;return pa(v,C,$,"gradient painting this text")??{status:"incomplete",message:"This text is painted with its background layer (background-clip: text) \u2014 contrast must be checked by eye."}}return{status:"incomplete",message:"This text is painted with its background layer (background-clip: text) \u2014 contrast must be checked by eye."}}let g=m&&c.webkitTextFillColor!==c.color?m:L(c.color);if(Ii(l,c,g))return{status:"pass"};let w=c.mixBlendMode==="multiply"&&u===l&&!l.children.length&&!l.shadowRoot&&L(c.backgroundColor)?.a===0&&c.backgroundImage==="none"&&c.filter==="none"&&(!c.backdropFilter||c.backdropFilter==="none")&&(!c.textShadow||c.textShadow==="none")&&!Pe(l.assignedSlot??l.parentElement??l.getRootNode()?.host)&&!Yt(l.assignedSlot??l.parentElement??l.getRootNode()?.host)&&!["::before","::after"].some(C=>{let v=getComputedStyle(l,C),$=v.content;return($==='"\u2060"'||$==="'\u2060'")&&v.display==="inline"&&v.position==="static"&&v.cssFloat==="none"&&L(v.backgroundColor)?.a===0&&["backgroundImage","boxShadow","textShadow","transform","filter","backdropFilter","maskImage","webkitMaskImage"].every(Y=>!v[Y]||v[Y]==="none")&&["Top","Right","Bottom","Left"].every(Y=>parseFloat(v[`padding${Y}`])===0&&parseFloat(v[`border${Y}Width`])===0)&&v.outlineStyle==="none"&&(!v.mixBlendMode||v.mixBlendMode==="normal")?!1:$&&$!=="none"&&$!=="normal"&&$!=='""'});if(Pe(u)&&!w)return{status:"incomplete",message:"A filter or blend mode changes the colours presented by this text and its background. Check the resulting contrast by eye."};if(!g)return{status:"incomplete",message:"The text colour could not be parsed \u2014 check contrast by eye."};let b=qe(c)?n.large:n.normal,x=l.ownerDocument,I=null,O=g,F=b,E=da(l,c).map(({pseudo:C,color:v,style:$})=>({origin:C,color:v,required:qe($)?n.large:n.normal})),q=!0;if(!l.childElementCount&&E.some(C=>C.origin==="::first-line")){let C=x.createRange();C.selectNodeContents(l);let v=[...C.getClientRects()].filter($=>$.width>0&&$.height>0);if(v.length&&v.every($=>Math.abs($.top-v[0].top)<1)){if(["::before","::after"].some(W=>{let Y=getComputedStyle(l,W);return Y.display!=="none"&&!["none","normal"].includes(Y.content)}))return{status:"incomplete",message:"Generated content may occupy this element\u2019s first line, so the colours that actually paint its text cannot be identified from text ranges alone. Check contrast by eye."};q=!1}}let B=(C,v)=>C.reduce(($,W)=>{let Y=W.color.a<1?G(W.color,v):W.color,me=H(Y,v)/W.required;return!$||me<$.margin?{...W,margin:me}:$},null);if(E.length){let C=ne(u)??{r:255,g:255,b:255,a:1},v=B([...q?[{origin:null,color:g,required:b}]:[],...E],C);g=v.color,b=v.required,I=v.origin}let k=yt(l)?xt(l):Ee(l);if(k<.05)return{status:"pass"};if(w&&(k<1||E.length))return{status:"incomplete",message:"This text blends as a group or uses additional text paint. Check its presented contrast by eye."};if(k<1){let v=(!c.textShadow||c.textShadow==="none")&&!(At(l)?.film>0)?vt(l,g):null;if(v?.unresolved)return{status:"incomplete",message:`This text and its own background render together at ${Math.round(v.opacity*100)}% opacity over an image or gradient, so the presented colours are a blend a script cannot resolve. Check the contrast by eye.`};if(v){let $=H(v.foreground,v.background),W=l.getBoundingClientRect(),Y=Z=>Math.min(W.right,Z.right)-Math.max(W.left,Z.left)>=3&&Math.min(W.bottom,Z.bottom)-Math.max(W.top,Z.top)>=3;if(to(x).some(({element:Z,rect:pe})=>Y(pe)&&!Z.contains(l)&&!l.contains(Z)&&Me(l,pe)))return{status:"incomplete",message:"This text overlaps an image or video, so its real background can\u2019t be computed \u2014 contrast must be checked by eye."};if(kt(x).some(({element:Z,rect:pe,color:Ne})=>Y(pe)&&!Z.contains(l)&&!l.contains(Z)&&Me(l,pe)&&H(G(v.text,Ne),G(v.paint,Ne))>=b!=$>=b))return{status:"incomplete",message:"This text overlaps a coloured block that isn\u2019t its DOM ancestor, so its real background is ambiguous \u2014 check contrast by eye."};let ee=Qt(l),Q=ee?.scrim??null;if(!Q&&ee==="offscreen"){let Z=eo(x);Z&&!Z.contains(l)&&(Q=[Z])}if(Q){let Z=Jt(Q);if(!Z)return ze();let pe=H(Se(v.foreground,Z),Se(v.background,Z));if(pe>=b!=$>=b)return ze($,pe)}if($>=b)return{status:"pass"};if(!W.width||!W.height)return{status:"pass"};let X=he(v.foreground),le=he(v.background);return{status:"fail",message:`Contrast is ${K($)}:1, below the ${b}:1 WCAG minimum for this text size.${s(c,b,$)}`,fix:`Darken the text or lighten the background until the ratio reaches ${b}:1 (currently ${X} on ${le}).`+(c.color!==X?` Your CSS writes the text as ${c.color}, so searching it for the sRGB values above won't find them.`:"")+` The gap is opacity: this element or an ancestor renders at ${Math.round(v.opacity*100)}% opacity, so the text and its own background are both blended toward what lies behind them, into the sRGB values above.`,data:{foreground:X,background:le,ratio:Number(K($)),required:b}}}g={...g,a:g.a*k}}let U=Be(l);if(U&&U.element!==l){let C=Mi(l,U.element);if(C?.image)U={css:C.css,element:C.image,overlays:C.overlays};else if(C)U=null;else if(C===void 0&&Wi(U.element,l))return{status:"incomplete",message:"This text sits in a section with a background image or gradient, and a positioned element inside that section paints its own background where the text is. Which of the two is behind the glyphs depends on paint order, and the text is off screen where the browser cannot be asked, so check the contrast by eye."}}if(U){if(w)return{status:"incomplete",message:"This text multiplies against an image or gradient. Its contrast depends on the pixels behind each glyph; check it by eye."};let{relation:C,intrinsic:v,dimensionless:$,isGradient:W,sizedSmall:Y,paint:me}=await $i(U,l,x);if(C!=="clear"){let Le=U.element.getBoundingClientRect(),ee=me?Ct(me):{width:Math.max(Le.width,$?0:v.width),height:Math.max(Le.height,$?0:v.height)},Q=await St(U,g,b,x,U.overlays,Li(U.element),ee);if(Q!==tt){Q&&Ei(l,U.element)&&(Q={status:"incomplete",message:"This text sits over a background image with a translucent overlay painted on top of it (a pseudo-element or positioned scrim), so the colour behind the glyphs is the blend of the two \u2014 check the contrast by eye."});let X=W?Y||Le.height<=40:$||v.width<=32&&v.height<=32||Le.height<=40;return Q?.status==="fail"&&X?{status:"incomplete",message:"A small background icon is painted on this element \u2014 if it sits beside the text rather than under it, judge the contrast against the plain background by eye."}:Q??{status:"incomplete",message:"The background here is several stacked image or gradient layers, which a script can\u2019t sample. Contrast must be checked by eye."}}}}let N=ne(u),V=Qt(l);if(w&&V?.image)return{status:"incomplete",message:"This text multiplies against image paint. Check its presented contrast by eye."};let _=null,ie=V?.scrim??null;if(!ie&&V==="offscreen"){let C=eo(x);C&&!C.contains(l)&&(ie=[C])}if(ie&&(_=Jt(ie),!_))return ze();let re=At(l);if(w&&re)return{status:"incomplete",message:"Pseudo-element paint affects the backdrop of this blended text. Check its presented contrast by eye."};let de=re?.film??0,z=re?.color||re?.image?re:null,_e=!1;if(z?.image?.meta&&z.image.box){let C=ha(z.image.css);if(C&&z.image.meta.repeat==="no-repeat"){let v=null;try{v=await Qe(new URL(C,x.baseURI).href)}catch{}let $=!v||!v.width||v.width===300&&v.height===150,W=oo(z.image.box,z.image.meta,$?null:v);W&&!W.empty&&!Me(l,W)?z=null:_e=$||v.width<=32&&v.height<=32}}let we={status:"incomplete",message:"A pseudo-element with its own background paints in this element's chain, but its position can't be computed \u2014 so whether it sits behind this text is unknown. Check the contrast by eye."};if(de>0&&(z?.image||V?.image||V==="unresolved"||_||c.textShadow&&c.textShadow!=="none"))return we;if(_&&(z?.image||V?.image))return ze();if(z?.image&&z.beyondPaint)return{status:"incomplete",message:"An ancestor's pseudo-element paints an image or gradient where this text is, but other backgrounds sit between them \u2014 which one is behind the glyphs depends on paint order, so check the contrast by eye."};if(z?.image){let C=await St(z.image,g,b,x,[],ne(z.image.element),Ct(z.image.box));if(C!==tt)return C?.status==="fail"&&_e?{status:"incomplete",message:"A small icon is painted by a pseudo-element on this element \u2014 if it sits beside the text rather than under it, judge the contrast against the plain background by eye."}:C??{status:"incomplete",message:"A pseudo-element paints an image or gradient behind this text, so its real background isn\u2019t the computed colour \u2014 contrast must be checked by eye."}}if(V?.image&&!z){let C=await St(V.image,g,b,x,V.overlays??[],null,Ct(V.image.getBoundingClientRect()));if(C!==tt)return C??{status:"incomplete",message:"An image or overlapping element is painted behind this text, so its real background isn\u2019t the computed colour \u2014 contrast must be checked by eye."}}let ye=!1;if(V?.color)N=V.color,ye=!0;else if(V==="unresolved"){let C=oa(l);if(C&&C!=="unverifiable"){let v=await St(C,g,b,x,[],null,Ct(C.getBoundingClientRect()));if(v!==tt)return v??{status:"incomplete",message:"An image or overlapping element is painted behind this text, so its real background isn\u2019t the computed colour \u2014 contrast must be checked by eye."}}}if(z?.color&&z.beyondPaint){let C=z.color.a>=1||!N?z.color:G(z.color,N);if(!N)return{status:"incomplete",message:"The background could not be determined \u2014 check contrast by eye."};let v=g.a<1?G(g,N):g,$=g.a<1?G(g,C):g;if(H(v,N)>=b!=H($,C)>=b)return{status:"incomplete",message:"An ancestor's pseudo-element paints where this text is, but other backgrounds sit between them \u2014 which colour is behind the glyphs depends on paint order, and the two candidates disagree on the verdict. Check the contrast by eye."}}else z?.color&&(N=z.color.a>=1||!N?z.color:G(z.color,N),ye=!0);if(!N)return{status:"incomplete",message:"The background could not be determined \u2014 check contrast by eye."};if(E.length){let C=W=>k<1?{...W,a:W.a*k}:W,v={origin:null,color:C(O),required:F},$=B([...q?[v]:[],...E.map(W=>({...W,color:C(W.color)}))],N);g=$.color,b=$.required,I=$.origin}w&&(g={...g,r:g.r*N.r/255,g:g.g*N.g/255,b:g.b*N.b/255}),g.a<1&&(g=G(g,N));let it=(C,v)=>{let $=L(c.backgroundColor);if($&&$.a>=1)return null;let W=l.getBoundingClientRect(),Y=ee=>Math.min(W.right,ee.right)-Math.max(W.left,ee.left)>=3&&Math.min(W.bottom,ee.bottom)-Math.max(W.top,ee.top)>=3;if(to(x).some(({element:ee,rect:Q,hitTestBlind:X})=>(!v||X)&&Y(Q)&&!ee.contains(l)&&!l.contains(ee)&&Me(l,Q)))return{status:"incomplete",message:"This text overlaps an image or video, so its real background can\u2019t be computed \u2014 contrast must be checked by eye."};if(kt(x).some(({element:ee,rect:Q,color:X,hitTestBlind:le})=>(!v||le)&&Y(Q)&&!ee.contains(l)&&!l.contains(ee)&&Me(l,Q)&&(w||H(g,X)>=b!=(C==="pass"))))return{status:"incomplete",message:"This text overlaps a coloured block that isn\u2019t its DOM ancestor, so its real background is ambiguous \u2014 check contrast by eye."};if(!v){let ee=!1,Q=null;for(let X=l;X&&X.nodeType===1&&X!==x.body;X=X.parentElement??X.getRootNode()?.host){let le=getComputedStyle(X).position;if(X!==l&&le!=="static"){Q=X;break}(le==="absolute"||le==="fixed")&&(ee=!0)}if(ee&&Q){let X=Q.querySelectorAll("*");if(X.length<=2e3)for(let le of X){if(le===l||le.contains(l)||l.contains(le))continue;let Z=getComputedStyle(le);if(Z.position!=="static"||Z.visibility==="hidden")continue;let pe=L(Z.backgroundColor);if(!pe||pe.a<1)continue;let Ne=le.getBoundingClientRect();if(!(Ne.width<24||Ne.height<12||!Y(Ne)||!Me(l,Ne))&&(w||H(g,pe)>=b!=(C==="pass")))return{status:"incomplete",message:"This text is positioned over a coloured box that isn\u2019t its DOM ancestor, so its real background is ambiguous \u2014 check contrast by eye."}}}}return null},fe=H(g,N);if(de>0){let C=aa(g,N,de);if(!(C.min>=b==C.max>=b&&!(C.crossed&&C.min>=b)))return we}let He=(C,v)=>H(Se(C,_),Se(v,_));if(_){let C=He(g,N);if(C>=b!=fe>=b)return ze(fe,C)}if(fe>=b)return it("pass",ye)??{status:"pass"};let Te=l.getBoundingClientRect();if(!Te.width||!Te.height)return{status:"pass"};{let C=x.defaultView;if(C&&getComputedStyle(x.documentElement).direction!=="rtl"&&(Te.right+C.scrollX<=0||Te.bottom+C.scrollY<=0))return{status:"pass"}}if(c.textShadow&&c.textShadow!=="none"){let C=parseFloat(c.fontSize)||16,v=sa(c.textShadow,C);if(v){let $=H(g,v);if(_){let W=He(g,v);if(W>=b!=$>=b)return ze($,W)}return $>=b?{status:"pass"}:{status:"fail",message:`Contrast is ${K($)}:1 against this text's own outline and ${K(fe)}:1 against the background \u2014 below the ${b}:1 WCAG minimum for this text size.`,fix:`Increase the difference between the text colour and its text-shadow outline (or the background) until the ratio reaches ${b}:1.`,data:{foreground:he(g),background:he(v),ratio:Number(K($)),required:b}}}if(!ia(c.textShadow,C))return{status:"incomplete",message:`Contrast against the background is ${K(fe)}:1, but this text has a text-shadow \u2014 if the shadow forms a solid halo, contrast may be measured against it instead. Check by eye.`}}if(Math.round(g.r)===Math.round(N.r)&&Math.round(g.g)===Math.round(N.g)&&Math.round(g.b)===Math.round(N.b))return{status:"incomplete",message:"This text is exactly the same colour as its background \u2014 invisible. If that's a hiding technique for screen-reader-only labels, use the clip pattern instead; if the text is meant to be seen, this is a serious defect."};if(Ni(l))return{status:"pass"};{let C=it("fail",ye);if(C)return C}let Re=he(g),We=he(N),je=(C,v)=>{let $=L(C);return $!=null&&$.a>=1&&he($)===v},p=!I&&c.color!==Re?c.color:null,A=I?` The judged text colour comes from a ${I} rule on this element, which paints that part of the text in place of its color.`:"",T=Qo(l),R=T&&T!==We?T:null,M=p&&je(p,Re)?p:null,D=R&&je(R,We)?R:null,J=[p&&`the text as ${p}`,R&&`the background as ${R}`].filter(Boolean).join(" and "),te=p&&!M?L(p):null,j=te?k<1?` The gap is opacity: this element or an ancestor renders at ${Math.round(k*100)}% opacity, dimming the text to the sRGB value above.`:te.a<1?" The text colour is translucent, so it composites with the background into the sRGB value above.":"":"",oe=s(c,b,fe);return{status:"fail",message:`Contrast is ${K(fe)}:1 \u2014 below the ${b}:1 WCAG minimum for this text size.${oe}`,fix:`Darken the text or lighten the background until the ratio reaches ${b}:1 (currently ${Re} on ${We}).`+(J?` Your CSS writes ${J}, so searching it for the sRGB values above won't find them.`:"")+j+A,data:{foreground:Re,background:We,...M?{foregroundCss:M}:{},...D?{backgroundCss:D}:{},ratio:Number(K(fe)),required:b}}}},r=i.evaluate.bind(i);return i.evaluate=async(l,d)=>{let u=await r(l,d);return u.status==="fail"&&l.closest('[aria-hidden="true"]')&&(u.message+=" aria-hidden hides this from screen readers, not from sighted users; contrast is judged for the people who see it."),u},i}var fa=io({id:"color-contrast",name:"Text contrast",tags:["wcag2aa","wcag143"],help:"Text must have sufficient contrast against its background",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html",thresholds:{normal:4.5,large:3}});var ma={id:"frame-title",name:"Frame titles",impact:"serious",tags:["wcag2a","wcag412"],help:"Frames must have a title describing their content",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html",selector:"iframe, frame",evaluate(e,{accessibleName:t}){return e.getAttribute("title")?.trim()||t(e)?{status:"pass"}:{status:"fail",message:"This frame has no title \u2014 screen-reader users cannot tell what it contains before entering it.",fix:`Add title="\u2026" describing the embedded content, e.g. <iframe title="Newsletter signup" src="${e.getAttribute("src")??""}">.`}}};var ga=["aria-labelledby","aria-describedby","aria-controls","aria-activedescendant","aria-owns","aria-errormessage","aria-details"],Oi=new Set(["button","checkbox","gridcell","link","menuitem","menuitemcheckbox","menuitemradio","option","progressbar","radio","scrollbar","searchbox","separator","slider","spinbutton","switch","tab","tabpanel","textbox","treeitem","combobox","grid","listbox","menu","menubar","radiogroup","tablist","tree","treegrid","dialog","alertdialog"]),Ui='a[href], button, input:not([type="hidden"]), select, textarea, summary, audio[controls], video[controls], [contenteditable="true"]';function Di(e){let t=e.tagName.toLowerCase();if(t==="img"||t==="area")return e.getAttribute("alt")?.trim()??"";let o={svg:"title",table:"caption",fieldset:"legend",figure:"figcaption"}[t];return o?[...e.children].find(a=>a.tagName.toLowerCase()===o)?.textContent.trim()??"":""}function Fi(e){return e.matches(Ui)||Oi.has(P(e))?!0:e.tabIndex>=0}function Pi(e){let t=e.getRootNode(),o=e.getAttribute("aria-expanded")==="false",a=[],n=[];for(let s of ga)if(!(s==="aria-errormessage"&&(!e.hasAttribute("aria-invalid")||["false",""].includes(e.getAttribute("aria-invalid").trim().toLowerCase()))))for(let i of(e.getAttribute(s)??"").split(/\s+/).filter(Boolean)){if(!t.getElementById?.(i)){if(s==="aria-controls"&&o)continue;a.push({attr:s,id:i});continue}let r=t.querySelectorAll(`[id="${CSS.escape(i)}"]`).length;r>1&&n.push(`${s}="${i}" \u2014 ${r} elements share this id; the reference binds to the FIRST one in the DOM`)}return{missing:a,ambiguous:n}}function Bi({missing:e,ambiguous:t},o,a){if(e.length){let n=Fi(o),s=n?(a?.(o)??"").trim():(ue(o)||o.getAttribute("aria-label")||Di(o)||o.getAttribute("title")||"").trim(),i=e.filter(({attr:u})=>!(u==="aria-labelledby"&&s));if(!i.length)return{status:"pass"};let r=({attr:u,id:c})=>u==="aria-labelledby"?`aria-labelledby="${c}" points to nothing and leaves this element without an accessible name`:`${u}="${c}" points to nothing \u2014 assistive technology silently ignores it`;if(i.filter(({attr:u})=>n&&(u==="aria-labelledby"||u==="aria-activedescendant")).length)return{status:"fail",message:`Broken ARIA references: ${i.map(r).join("; ")}.`,fix:"Correct or remove the reference, or give the target element that id."};let d=i.filter(({attr:u})=>u==="aria-labelledby");if(d.length){let u=o.tagName.toLowerCase();return{status:"incomplete",message:`${d.map(({id:c})=>`aria-labelledby="${c}" points to nothing`).join("; ")}, so this <${u}> has no accessible name. It is not a user interface component, so 4.1.2 does not require one, but the reference was meant to label it: correct it, or remove it if the label was never needed.`,fix:"Correct or remove the reference, or give the target element that id."}}return{status:"incomplete",message:`${i.map(r).join("; ")} at rest. The element keeps its name and role, so this is not a proven 4.1.2 failure: if the description is created when the element is hovered or focused (a tooltip library), this works; otherwise correct the reference.`,fix:"Correct or remove the reference, or give the target element that id."}}return t.length?{status:"incomplete",message:`Ambiguous ARIA references: ${t.join("; ")}. If the first copy in the DOM is the intended target, this works today \u2014 but it's fragile.`}:{status:"pass"}}var ba={id:"aria-valid-refs",name:"ARIA id references",impact:"moderate",tags:["wcag2a","wcag412"],help:"ARIA id references must point to elements that exist",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html",selector:ga.map(e=>`[${e}]`).join(", "),evaluate(e,{accessibleName:t}={}){return Bi(Pi(e),e,t)}};var wa=new Set(["alert","alertdialog","application","article","banner","blockquote","button","caption","cell","checkbox","code","columnheader","combobox","complementary","contentinfo","definition","deletion","dialog","directory","document","emphasis","feed","figure","form","generic","grid","gridcell","group","heading","img","insertion","link","list","listbox","listitem","log","main","marquee","math","menu","menubar","menuitem","menuitemcheckbox","menuitemradio","meter","navigation","none","note","option","paragraph","presentation","progressbar","radio","radiogroup","region","row","rowgroup","rowheader","scrollbar","search","searchbox","separator","slider","spinbutton","status","strong","subscript","superscript","switch","tab","table","tablist","tabpanel","term","textbox","time","timer","toolbar","tooltip","tree","treegrid","treeitem","image","comment","mark","suggestion"]);function Gi(e,t){let o=Array.from({length:e.length+1},(a,n)=>[n]);for(let a=1;a<=t.length;a++)o[0][a]=a;for(let a=1;a<=e.length;a++)for(let n=1;n<=t.length;n++)o[a][n]=Math.min(o[a-1][n]+1,o[a][n-1]+1,o[a-1][n-1]+(e[a-1]===t[n-1]?0:1));return o[e.length][t.length]}function qi(e){let t=null,o=3;for(let a of e){let n=a.toLowerCase();for(let s of wa){if(Math.abs(s.length-n.length)>2)continue;let i=Gi(n,s);i>0&&i<o&&(t=s,o=i)}}return t}var ya={id:"valid-role",name:"Valid roles",impact:"critical",tags:["wcag2a","wcag412"],help:"role attributes must use valid ARIA roles",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html",selector:"[role]",evaluate(e){let t=e.getAttribute("role").trim().split(/\s+/).filter(Boolean),o=c=>{let h=c.toLowerCase();return wa.has(h)||h.startsWith("doc-")||h.startsWith("graphics-")};if(t.some(o))return{status:"pass"};let a=e.tagName.toLowerCase(),n=qi(t),s=n?` (did you mean role="${n}"?)`:"",i=n?`Correct the spelling to role="${n}", or remove the attribute to keep the element\u2019s native role.`:"Use a valid role from the ARIA specification, or remove the attribute to keep the element\u2019s native role.",r=a==="div"||a==="span"||a==="svg",l=e.tabIndex>=0||e.matches("a[href], button, input, select, textarea, summary"),d=[...$e(e)].some(c=>c.name.startsWith("aria-")&&c.name!=="aria-hidden");if(r&&!l&&!d)return{status:"pass"};let u=ae(e);return!l&&!d||u&&u!=="generic"?{status:"incomplete",message:`role="${e.getAttribute("role")}" is not a valid ARIA role${s}, so assistive technology ignores it and exposes the element's native <${a}> semantics. Nothing is announced wrongly, but the author reached for a role that does not exist. Is the native <${a}> role the right one here? If a different role was intended, that role is missing.`,fix:i}:{status:"fail",message:`role="${e.getAttribute("role")}" is not a valid ARIA role${s}, so assistive technology ignores it${r?"":` and falls back to the element\u2019s native <${a}> semantics`}.`,fix:i}}};var xa='a[href], area[href], button, input, select, textarea, summary, iframe, audio[controls], video[controls], [contenteditable]:not([contenteditable="false"]), [tabindex]',va={id:"aria-hidden-focus",name:"Focusable hidden content",impact:"serious",tags:["wcag2a","wcag412"],help:'Nothing focusable may sit inside aria-hidden="true"',helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html",selector:'[aria-hidden="true"]',visibleOnly:!1,evaluate(e,{isRendered:t}){let o=[e,...e.querySelectorAll(xa)].filter(s=>s.matches?.(xa)&&!(s.hasAttribute("tabindex")&&s.tabIndex<0)&&!s.matches(":disabled")&&!s.closest("[inert]")&&t(s)&&Ee(s)>0);if(!o.length)return{status:"pass"};let a=e.ownerDocument,n=null;try{n=a.querySelector("dialog:modal")}catch{}return n??=[...a.querySelectorAll('[aria-modal="true"]')].find(t)??null,n&&!e.contains(n)&&!n.contains(e)?{status:"incomplete",message:`This aria-hidden element contains ${o.length} focusable element(s) while a modal dialog is open \u2014 fine if the modal traps keyboard focus, a failure if Tab can reach them. Check the trap by keyboard.`}:{status:"fail",message:`This aria-hidden element contains ${o.length} focusable element(s) \u2014 keyboard users can Tab into content that screen readers cannot see.`,fix:'Add tabindex="-1" (or disabled) to focusable elements inside aria-hidden regions, or remove aria-hidden.'}}};var Aa=["listitem","presentation","none"],ka={id:"list-structure",name:"List structure",impact:"serious",tags:["wcag2a","wcag131"],help:"Lists must only contain list items",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships.html",selector:"ul, ol",evaluate(e,{isRendered:t}){if(P(e)!=="list")return{status:"pass"};let o=i=>[...i.children].flatMap(r=>r.tagName==="SLOT"?r.assignedElements?.().length?r.assignedElements():[...r.children]:[r]),a=i=>{if(rt.has(i.tagName)||t&&!t(i))return!0;let r=P(i);return i.tagName==="LI"?!r||Aa.includes(r):Aa.includes(r)?!0:!i.hasAttribute("role")&&(i.tagName==="DIV"||i.tagName==="SPAN")?![...i.childNodes].some(u=>u.nodeType===Node.TEXT_NODE&&u.textContent.trim())&&o(i).every(a):!1},n=o(e).filter(i=>!a(i));if(!n.length){let i=o(e).filter(l=>l.tagName==="LI"&&(!t||t(l))),r=i.filter(l=>["presentation","none"].includes(P(l)));return i.length&&r.length===i.length?{status:"fail",message:`Every item in this list carries role="${r[0].getAttribute("role")}", so the list announces itself with zero items while ${i.length} are visible \u2014 screen readers lose the count and the positions.`,fix:'Remove the role from the <li> elements, or neutralise the whole structure by putting role="presentation" (or the intended widget role) on the list element itself.'}:{status:"pass"}}let s=[...new Set(n.map(i=>{let r=i.getAttribute("role");return`<${i.tagName.toLowerCase()}${r?` role="${r}"`:""}>`}))].join(", ");return{status:"fail",message:`This list has ${n.length} direct child(ren) without listitem semantics (${s}) \u2014 screen readers misreport the list's size and structure.`,fix:'Use plain <li> children (an explicit role like role="group" replaces the listitem role), or move non-item elements outside the list.'}}};var Ca='a[href], button, input, select, textarea, summary, audio[controls], video[controls], [role="button"], [role="link"], [role="checkbox"], [role="radio"], [role="switch"], [role="menuitem"], [role="tab"], [role="option"]',Sa={id:"nested-interactive",name:"Nested controls",impact:"serious",tags:["wcag2a","wcag412"],help:"A control must not contain another control",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html",selector:Ca,evaluate(e,{isRendered:t}){let o="a[href], button, input, select, textarea, summary, audio[controls], video[controls]",a=ko(e).filter(s=>s.matches?.(Ca)&&!s.matches(":disabled")&&!ce(s)&&!(s.tagName==="INPUT"&&s.type==="hidden")&&t(s)&&!(s.closest('[aria-hidden="true"]')&&!lt(s,e))&&(s.matches(o)||s.hasAttribute("tabindex"))),n=a.find(s=>!lt(s,e))??a[0];if(!n)return{status:"pass"};if(lt(n,e)&&!e.matches("a[href], button")){let s=null;for(let r=ge(n);r&&r!==e;r=ge(r))if(r.shadowRoot&&r.hasAttribute("tabindex")&&r.tabIndex<0){s=r;break}let i=`<${n.tagName.toLowerCase()}>`;return{status:"incomplete",message:s?`This control contains a custom element (<${s.tagName.toLowerCase()}>) whose shadow tree holds another control (${i}). The host's negative tabindex keeps it out of the tab order, but a click or a script can still focus it. Check that both controls expose the intended name and role, and that focusing and activating the child works correctly.`:n.closest('[aria-hidden="true"]')?`This control contains an element (${i}) that is hidden from assistive technology but can still receive focus from a click or a script. Focus landing there lands on content a screen reader cannot see. Check whether it can take focus, and if it can, remove it from focus or from aria-hidden.`:`This control contains an element (${i}) with a negative tabindex. It can still receive focus. Check that both controls expose the intended name and role, and that focusing and activating the child works correctly.`}}return e.tagName==="SUMMARY"?{status:"incomplete",message:`This summary contains another interactive element (<${n.tagName.toLowerCase()}>). HTML allows it and both controls keep their name and role, but the disclosure and the control inside it are separate keyboard stops in one label. Check that activating each does what a user expects.`}:{status:"fail",message:`This ${e.tagName.toLowerCase()} contains another interactive element (<${n.tagName.toLowerCase()}>) \u2014 focus order and announcements become unpredictable.`,fix:"Restructure so interactive elements are siblings, not ancestors of each other."}}};var zi=new Set(["form","region"]),Vi="main, header, footer, nav, aside, section, form, [role]",_i=e=>!!(e.getAttribute("aria-label")?.trim()||e.getAttribute("aria-labelledby")?.trim()||e.getAttribute("title")?.trim()),Hi=e=>{let t=P(e);return Ue.has(t)&&(!zi.has(t)||_i(e))},Ta={id:"bypass-blocks",name:"Skip to content",impact:"serious",tags:["wcag2a","wcag241"],help:"The page must offer a way to skip repeated blocks",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/bypass-blocks.html",selector:"html",visibleOnly:!1,evaluate(e,{isRendered:t}){if(Oe(e.ownerDocument))return{status:"pass"};let o=e.ownerDocument,a=xe(o),n=r=>a.some(l=>l.querySelector?.(r));if(a.some(r=>[...r.querySelectorAll?.(Vi)??[]].some(Hi)))return{status:"pass"};if(n('h1, h2, h3, h4, h5, h6, [role="heading"]'))return{status:"pass"};for(let r of a)for(let l of r.querySelectorAll?.('a[href^="#"]')??[]){let d=l.getAttribute("href").slice(1);if(d&&!(t&&!t(l))&&a.some(u=>u.getElementById?.(d)||u.querySelector?.(`[id="${CSS.escape(d)}"]`)))return{status:"pass"}}let s=[...o.querySelectorAll("iframe, frame")??[]];if(s.length&&s.every(r=>r.getAttribute("title")?.trim()))return{status:"pass"};let i=a.reduce((r,l)=>r+(l.querySelectorAll?.("a[href], button").length??0),0);return i<4?{status:"pass"}:{status:"incomplete",message:`This page has ${i} links and buttons but no detected landmark, heading, skip link or titled frame. Check whether it contains blocks repeated on other pages and, if so, whether a mechanism lets users bypass them. A single page cannot establish repetition.`,fix:'Add a skip link like <a href="#content">Skip to content</a>, wrap primary content in <main>, or structure the page with headings.'}}};var Ia='a[href], button, input, select, [role="button"], [role="link"]';function Ra(e,t){if(e.contains(t))return!0;if(e.getRootNode()===t.getRootNode()&&!t.assignedSlot)return!1;for(let o=t;o;o=o.assignedSlot??o.parentElement??o.getRootNode()?.host)if(o===e)return!0;return!1}function Na(e,t){for(let o=e.parentElement;o;o=o.parentElement){let a=getComputedStyle(o);if(a.display==="contents")continue;let n=/^(hidden|clip)$/.test(a.overflowX),s=/^(hidden|clip)$/.test(a.overflowY);if(!n&&!s)continue;let i=o.getBoundingClientRect();if(n&&(i.width===0||t.right<=i.left||t.left>=i.right)||s&&(i.height===0||t.bottom<=i.top||t.top>=i.bottom))return!0}return!1}function ji(e,t){if(t.width<=1||t.height<=1||t.right<=0||t.bottom<=0)return!0;let o=e.ownerDocument.defaultView,a=e.ownerDocument.scrollingElement??e.ownerDocument.documentElement;if(o&&a&&(t.left+o.scrollX>=a.scrollWidth-1||t.top+o.scrollY>=a.scrollHeight-1))return!0;let n=getComputedStyle(e);return(parseFloat(n.opacity)||0)===0||n.clipPath!=="none"||n.clip!=="auto"&&n.position==="absolute"}function Yi(e,t){let o=e.ownerDocument,a=o.defaultView;if(!a||typeof o.elementsFromPoint!="function")return[t];let n=[...e.getClientRects()].filter(l=>l.width>0&&l.height>0),s=n.length?n:[t],i=[],r=!1;for(let l of s){let d=l.left+l.width/2,u=l.top+l.height/2;if(d<0||u<0||d>=a.innerWidth||u>=a.innerHeight)continue;let c=o.elementsFromPoint(d,u),h=c.indexOf(e);if(h<0){e.getRootNode()===o&&(r=!0);continue}r=!0,c.slice(0,h).every(f=>f.contains(e)||e.contains(f))&&i.push(l)}return r?i:s}function Ea(e){for(let t of e.childNodes)if(t.nodeType===Node.TEXT_NODE&&t.textContent.trim()||t.nodeType===Node.ELEMENT_NODE&&!t.matches(Ia)&&Ea(t))return!0;return!1}function $a(e){let t=e;for(;t&&getComputedStyle(t).display.startsWith("inline");){for(let o of t.parentNode?.childNodes??[])if(o!==t&&(o.nodeType===Node.TEXT_NODE&&o.textContent.trim()||o.nodeType===Node.ELEMENT_NODE&&!o.matches(Ia)&&Ea(o)&&getComputedStyle(o).display.startsWith("inline")))return!0;t=t.parentElement}return!1}var Ki=/^(button|input|select|textarea)$/i,Xi=/^(width|height|(min|max)-(width|height|inline-size|block-size)|inline-size|block-size|padding(-.+)?|border(-.+)?|font(-.+)?|line-height|box-sizing|transform|scale|zoom|appearance|all)$/;function Ma(e){for(let t=0;t<e.length;t++)if(Xi.test(e[t]))return!0;return!1}function Zi(e,t){let o=[...e.styleSheets??[],...e.adoptedStyleSheets??[]],a=o.map(d=>{try{return d.cssRules.length}catch{return"x"}}).join(","),n=t.get(e);if(n?.key===a)return n;let s=(e.ownerDocument??e).defaultView,i=(e.ownerDocument??e).createElement("div"),r={key:a,selectors:[],open:!1},l=(d,u)=>{for(let c of d){if(c.media&&s?.matchMedia&&!s.matchMedia(c.media.mediaText).matches)continue;let h=c.selectorText??u;if(u&&c.selectorText&&(h=/&/.test(h)?h.replace(/&/g,`:is(${u})`):`:is(${u}) ${h}`),h&&c.style&&Ma(c.style))try{i.matches(h),r.selectors.push(h)}catch{r.open=!0}c.cssRules?.length&&l(c.cssRules,c.selectorText?h:u)}};for(let d of o)try{l(d.cssRules,null)}catch{r.open=!0}return r.combined=r.selectors.join(", "),t.set(e,r),r}function Ji(e,t){if(!Ki.test(e.tagName)||e.type==="image"||Ma(e.style))return"no";let o=Zi(e.getRootNode(),t);return o.combined&&e.matches(o.combined)?"no":o.open?"open":"yes"}function Qi(e,t){let o=Math.max(t.left-e.x,0,e.x-t.right),a=Math.max(t.top-e.y,0,e.y-t.bottom);return Math.hypot(o,a)}function ro({id:e,tags:t,help:o,helpUrl:a,min:n,spacingException:s}){let i=r=>{if(!(Math.round(r)>=n&&r<n))return String(Math.round(r));for(let l of[1,2]){let d=r.toFixed(l);if(Number(d)<n)return d}return`just under ${n}`};return{id:e,impact:"serious",tags:t,help:o,helpUrl:a,selector:'button, a[href], input:not([type="hidden"]), select, [role="button"], [role="link"]',visibility:"visual",async evaluateAll(r,l={}){let d=new WeakMap,u=l.yieldToMain??(()=>Promise.resolve()),c=p=>{let A=p.getBoundingClientRect(),T=p.labels?.[0];if(!T)return A;let R=T.getBoundingClientRect();if(!R.width||!R.height)return A;let M=Math.min(A.left,R.left),D=Math.min(A.top,R.top),J=Math.max(A.right,R.right),te=Math.max(A.bottom,R.bottom);return{left:M,top:D,right:J,bottom:te,width:J-M,height:te-D}},h=p=>p.tagName==="INPUT"&&(p.type==="checkbox"||p.type==="radio")&&getComputedStyle(p).appearance!=="none",f=[];for(let p=0;p<r.length;p++)p%64===0&&await u(),f.push(c(r[p]));let m=f.map(p=>({x:p.left+p.width/2,y:p.top+p.height/2})),y=p=>{try{return typeof p.checkVisibility=="function"&&p.checkVisibility({visibilityProperty:!0})&&!p.checkVisibility({contentVisibilityAuto:!0,visibilityProperty:!0})}catch{return!1}},g=[];for(let p=0;p<r.length;p++){p%64===0&&await u();let A=f[p],T=r[p];g.push(A.width>0&&A.height>0&&!T.matches(":disabled")&&!ce(T)&&!ji(T,A)&&!y(T))}let w=f.map((p,A)=>g[A]&&(p.width<n||p.height<n)),b=(p,A)=>p.left<=A.left&&p.right>=A.right&&p.top<=A.top&&p.bottom>=A.bottom,x=(p,A,T)=>{if(!b(A,T))return!1;let R=[...p.getClientRects()].filter(M=>M.width>0&&M.height>0);return R.length<=1||R.some(M=>b(M,T))},I=new Map,O=p=>{if(I.has(p))return I.get(p);let A=null;for(let T=p;T&&T!==p.ownerDocument.documentElement;T=T.parentElement){let R=getComputedStyle(T).position;if(R==="fixed"||R==="sticky"){A=T;break}}return I.set(p,A),A},F=(p,A)=>{let T=Math.max(p.left,A.left),R=Math.max(p.top,A.top),M=Math.min(p.right,A.right),D=Math.min(p.bottom,A.bottom);return M-T>2&&D-R>2?{left:T,top:R,right:M,bottom:D,width:M-T,height:D-R}:null},E=(p,A,T)=>{let R=r[A].ownerDocument,M=R.defaultView,D=T.left+T.width/2,J=T.top+T.height/2;if(!M||typeof R.elementsFromPoint!="function"||D<0||J<0||D>=M.innerWidth||J>=M.innerHeight)return!1;for(let te of R.elementsFromPoint(D,J)){let j=r[p]===te||r[p].contains(te),oe=r[A]===te||r[A].contains(te);if(j&&!oe)return!0;if(oe&&!j)return!1}return!1},q=(p,A)=>[{left:p.left,top:p.top,right:A.left,bottom:p.bottom},{left:A.right,top:p.top,right:p.right,bottom:p.bottom},{left:p.left,top:p.top,right:p.right,bottom:A.top},{left:p.left,top:A.bottom,right:p.right,bottom:p.bottom}].map(R=>({...R,width:R.right-R.left,height:R.bottom-R.top})).filter(R=>R.width>=1&&R.height>=1),B=256,k=new Map,U=[],N=p=>{let A=[];if((Math.floor(p.right/B)-Math.floor(p.left/B)+1)*(Math.floor(p.bottom/B)-Math.floor(p.top/B)+1)>2048)return null;for(let T=Math.floor(p.left/B);T<=Math.floor(p.right/B);T++)for(let R=Math.floor(p.top/B);R<=Math.floor(p.bottom/B);R++)A.push(`${T}:${R}`);return A};for(let p=0;p<f.length;p++){if(p%64===0&&await u(),!g[p])continue;let A=N(f[p]);if(!A){U.push(p);continue}for(let T of A)k.has(T)||k.set(T,[]),k.get(T).push(p)}let V=(p,A=f[p])=>{let T=N(A);if(!T)return r.map((M,D)=>D).filter(M=>M!==p&&g[M]);let R=new Set(U.filter(M=>M!==p));for(let M of T)for(let D of k.get(M)??[])D!==p&&R.add(D);return R},_=new Map,ie=p=>{let A=null;for(let T of V(p)){if(r[T].contains(r[p])||r[p].contains(r[T])||b(f[T],f[p])||b(f[p],f[T])||typeof r[p].href=="string"&&r[p].href===r[T].href)continue;let R=F(f[p],f[T]);if(!R||O(r[T])!==O(r[p])||!E(T,p,R))continue;let M=(A??[f[p]]).flatMap(D=>{let J=F(D,f[T]);return J?q(D,J):[D]});if(A=M.filter((D,J)=>!M.some((te,j)=>j!==J&&b(te,D)&&(j<J||!b(D,te)))),A.length>128)return{uncertain:!0}}return A===null?null:A.find(T=>T.width>=n&&T.height>=n)??A.reduce((T,R)=>R.width*R.height>T.width*T.height?R:T,{width:0,height:0})},re=p=>(_.has(p)||_.set(p,ie(p)),_.get(p)),de=p=>{if(typeof p.href!="string"||!p.href)return null;let A=(p.getAttribute("href")??"").trim();return!A||A==="#"||/^javascript:/i.test(A)?null:p.href},z=null,_e=p=>{let A=de(r[p]);if(!A)return!1;z||(z=new Map,r.forEach((R,M)=>{if(!g[M]||w[M]||R.ownerDocument!==r[p].ownerDocument)return;let D=de(R);D&&(z.has(D)||z.set(D,[]),z.get(D).push(M))}));let T=!1;for(let R of z.get(A)??[]){if(R===p)continue;let M=re(R);if(M?.uncertain){T=!0;continue}if(!M||M.width>=n&&M.height>=n)return"pass"}return T?"incomplete":null},we=null,ye=new Map,it=p=>(ye.has(p)||ye.set(p,l.accessibleName?.(p)?.trim()??""),ye.get(p)),fe=p=>{let A=[],T=it(p);T&&A.push(`name:${T}`);let R=p.getAttribute("onclick")?.trim();R&&A.push(`handler:${R}`);let M=p.getAttribute("aria-controls")?.trim().split(/\s+/).sort().join(" ");return M&&A.push(`controls:${M}`),A},He=p=>{if(de(r[p]))return!1;let A=fe(r[p]);return A.length?(we||(we=new Map,r.forEach((T,R)=>{if(!g[R]||w[R]||de(T))return;let M=re(R);if(!(M&&!M.uncertain&&(M.width<n||M.height<n)))for(let D of fe(T))we.has(D)||we.set(D,[]),we.get(D).push(R)})),A.some(T=>we.get(T)?.some(R=>R!==p))):!1},Te=()=>({status:"incomplete",message:`This control's measured pointer area is below ${n}\xD7${n}px, but a larger control has a matching name, handler or declared target. Check whether it provides the same function and meets the target-size requirement; if so, the Equivalent exception applies.`,fix:"Verify the larger alternative, or enlarge or separate this target."}),Re=()=>({status:"incomplete",message:`Another link reaches the same destination, but its unobscured pointer area could not be established. Check whether that alternative meets ${n}\xD7${n}px before applying the Equivalent exception.`}),We=(p,A)=>{if(!g[A])return{status:"pass"};if(!w[A]){let D=re(A);if(D?.uncertain)return{status:"incomplete",message:"Several targets overlap this control. The remaining pointer area could not be resolved within the geometry budget; check whether it contains the required target size."};if(!D||D.width>=n&&D.height>=n)return{status:"pass"};if($a(p))return{status:"pass"};if(!(()=>{let oe=p.ownerDocument,C=oe.defaultView;if(!C||typeof oe.elementsFromPoint!="function")return!0;let v=[...p.getClientRects()].filter(W=>W.width>0&&W.height>0),$=!1;for(let W of v.length?v:[f[A]]){let Y=W.left+W.width/2,me=W.top+W.height/2;if(!(Y<0||me<0||Y>=C.innerWidth||me>=C.innerHeight)&&($=!0,oe.elementsFromPoint(Y,me).includes(p)))return!0}return!$})())return{status:"pass"};let te=_e(A);if(te==="pass")return{status:"pass"};if(te==="incomplete")return Re();if(He(A))return Te();let j=f[A];return{status:"fail",message:`This target's box is ${Math.round(j.width)}\xD7${Math.round(j.height)}px, but another target overlaps it and clicks in the overlap go there \u2014 the part that still accepts the pointer is ${i(D.width)}\xD7${i(D.height)}px, below the ${n}\xD7${n}px minimum.`,fix:"Space the targets so they no longer overlap, or enlarge this one until the uncovered part reaches the minimum.",data:{box:{width:Math.round(j.width),height:Math.round(j.height)},effective:{width:Math.round(D.width),height:Math.round(D.height)}}}}if(h(p))return{status:"pass"};let T=Ji(p,d);if(T==="yes")return{status:"pass"};if($a(p))return{status:"pass"};if(s){let D=(j,oe)=>{if(oe===A||!g[oe]||Ra(j,p)||Ra(p,j))return!1;if(x(j,f[oe],f[A])||x(p,f[A],f[oe])){let v=de(p);if(v&&v===de(j)||Na(p,f[A])||Na(j,f[oe]))return!1}if(O(j)!==O(p))return!1;let C=v=>{if(w[oe]){let $={x:v.left+v.width/2,y:v.top+v.height/2};if(Math.hypot($.x-m[A].x,$.y-m[A].y)<n)return!0}return Qi(m[A],v)<n/2};return C(f[oe])?Yi(j,f[oe]).some(C):!1},J=m[A];if(![...V(A,{left:J.x-n,right:J.x+n,top:J.y-n,bottom:J.y+n})].some(j=>D(r[j],j)))return{status:"pass"}}let R=_e(A);if(R==="pass")return{status:"pass"};if(R==="incomplete")return Re();if(He(A))return Te();let M=f[A];return T==="open"?{status:"incomplete",message:`This native control is ${i(M.width)}\xD7${i(M.height)}px, under the ${n}\xD7${n}px minimum${s?", and another target crowds it":""}. The browser sizes an unstyled control (the User Agent Control exception), but a stylesheet this audit cannot read might set its size. Check whether author CSS sizes this control; if nothing does, it passes.`}:{status:"fail",message:s?`This target is ${i(M.width)}\xD7${i(M.height)}px AND another target crowds it (within ${n}px) \u2014 small targets are only acceptable with clear space around them; crowded ones are hard to hit for users with motor impairments.`:`This target is ${i(M.width)}\xD7${i(M.height)}px \u2014 below the ${n}\xD7${n}px minimum, hard to hit for users with motor impairments.`,fix:`Increase the element\u2019s size or padding to at least ${n}\xD7${n}px${s?", or add spacing between the targets":""}.`}},je=[];for(let p=0;p<r.length;p++)p%64===0&&await u(),je.push(We(r[p],p));return je}}}var Wa=ro({id:"target-size",name:"Target size",tags:["wcag22aa","wcag258"],help:"Interactive targets must be at least 24\xD724 pixels",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/target-size-minimum.html",min:24,spacingException:!0});var La={id:"audio-control",name:"Auto-playing audio control",impact:"critical",tags:["wcag2a","wcag142"],help:"Auto-playing audio must be stoppable or muted",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/audio-control.html",selector:"audio[autoplay], video[autoplay]",visibleOnly:!1,evaluate(e){if(e.muted||e.volume===0)return{status:"pass"};if(e.hasAttribute("muted")||e.hasAttribute("controls"))return{status:"pass"};if(!e.loop){if(Number.isFinite(e.duration)&&e.duration<=3)return{status:"pass"};if(!Number.isFinite(e.duration))return{status:"incomplete",message:"This media auto-plays without controls or muting; its duration isn\u2019t loaded yet, and only audio playing longer than 3 seconds fails 1.4.2 \u2014 check whether it has sound and how long it plays."}}let t=e.loop?"on a loop":"for more than three seconds",o="Add controls (or muted), or do not autoplay. Otherwise put a pause, stop or volume control near the start of the page, before the media.";if(e.tagName==="VIDEO"){let a=e.webkitAudioDecodedByteCount;return!e.paused&&!e.ended&&e.currentTime>=1&&a===0?{status:"pass"}:a>0?{status:"incomplete",message:`This video auto-plays with sound ${t}, with no controls and no muting, so its audio talks over a screen reader unless the page offers a way to stop it. Check for a pause, stop or volume control near the top of the page; if there is none, 1.4.2 is not met.`,fix:o}:{status:"incomplete",message:`This video auto-plays ${t} with no controls and no muting. If this video has a soundtrack, its audio talks over a screen reader unless the page offers a way to stop it. Check whether it has sound and, if so, that a pause, stop or volume control sits near the top of the page.`,fix:o}}return{status:"incomplete",message:`This audio auto-plays ${t} with no controls and no muting, so it talks over a screen reader unless the page offers a way to stop it. Check for a pause, stop or volume control near the top of the page; if there is none, 1.4.2 is not met.`,fix:o}}};var er=new Set(["transform","translate","rotate","scale","offsetDistance","offsetPath","offsetRotate","left","right","top","bottom","marginLeft","marginRight","marginTop","marginBottom","backgroundPosition","backgroundPositionX","backgroundPositionY","objectPosition"]);function lo(e){return e.some(t=>Object.keys(t).some(o=>er.has(o)))}function tr(e){if(e.some(o=>o.visibility==="hidden"))return!0;let t=e.map(o=>parseFloat(o.opacity)).filter(o=>!Number.isNaN(o));return t.some(o=>o<=.25)&&t.some(o=>o>=.75)}function or(e){if(!e||e==="none"||e==="normal")return!1;let t=e.replace(/url\([^)]*\)/g,"");return(t.match(/"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'/g)??[]).some(a=>a.slice(1,-1).trim())?!0:/\b(?:attr|counters?)\(|(?:open|close)-quote/.test(t)}function ar(e){let t=new Map;if(typeof e.getAnimations!="function")return t;let o;try{o=e.getAnimations()}catch{return t}for(let a of o){if(a.playState!=="running"||!a.playbackRate||a.timeline&&a.timeline!==e.timeline)continue;let n=a.effect,s=n?.target;if(!s||s.nodeType!==1)continue;let i=n.getComputedTiming?.()??{};if(i.iterations!==1/0||!(i.duration>0))continue;let r;try{r=n.getKeyframes()}catch{continue}let l=lo(r);if(!l&&!tr(r))continue;let d=!1;if(n.pseudoElement){let u="";try{u=s.ownerDocument.defaultView.getComputedStyle(s,n.pseudoElement).content}catch{}if(!or(u))continue;d=!0}t.has(s)||t.set(s,{name:a.animationName,verb:l?"moves":"blinks",pseudoText:d})}return t}var Oa={id:"pause-stop-hide",name:"Pausable moving content",impact:"serious",tags:["wcag2a","wcag222"],help:"Moving content must be pausable",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/pause-stop-hide.html",selector:"*",visibility:"visual",evaluateAll(e){if(!e.length)return[];let t=ar(e[0].ownerDocument);return e.map(o=>{if(o.tagName==="MARQUEE")return o.tagName==="MARQUEE"&&o.getAttribute("scrollamount")==="0"?{status:"pass"}:{status:"incomplete",message:"This marquee can scroll content. Check whether it actually starts automatically, continues for more than five seconds alongside other content, and has a working pause, stop or hide mechanism. The element alone does not establish those conditions.",fix:"Replace it with static content, or a CSS animation with a pause control that honours prefers-reduced-motion."};let a=t.get(o);if(!a||!(a.pseudoText||o.textContent.trim()))return{status:"pass"};let n=a.name?` (the \u201C${a.name}\u201D animation)`:"";return{status:"incomplete",message:`This content ${a.verb} continuously${n}: the animation repeats for ever, so it runs well past the five seconds at which WCAG 2.2.2 requires a way to pause, stop or hide it. Check the page offers one, and that it reaches this content.`}})}};var Ua={id:"media-captions",name:"Video captions",impact:"critical",tags:["wcag2a","wcag122"],help:"Video content must have captions",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/captions-prerecorded.html",selector:"video",visibleOnly:!1,evaluate(e){return e.querySelector('track[kind="captions" i]')?{status:"pass"}:e.querySelector('track[kind="subtitles" i], track:not([kind])')?{status:"incomplete",message:'This video has a subtitles track but no captions track. Subtitles carry dialogue for people who can hear the audio; captions also carry sound effects and other audio information deaf and hard-of-hearing users need. Check the track covers those, or mark it kind="captions" if it does.',fix:'Use <track kind="captions" src="\u2026" srclang="\u2026" label="\u2026"> for a track that includes non-speech audio information.'}:!e.currentSrc&&!e.getAttribute("src")&&!e.querySelector("source")?{status:"pass"}:e.muted&&!e.controls?{status:"pass"}:{status:"incomplete",message:"No caption track found on this video. If captions aren\u2019t burned in or provided by the player, deaf and hard-of-hearing users are excluded \u2014 please verify.",fix:'Add <track kind="captions" src="\u2026" srclang="\u2026" label="\u2026"> with a WebVTT file.'}}};var ot={"aria-atomic":["true","false"],"aria-busy":["true","false"],"aria-disabled":["true","false"],"aria-expanded":["true","false","undefined"],"aria-hidden":["true","false","undefined"],"aria-modal":["true","false"],"aria-multiline":["true","false"],"aria-multiselectable":["true","false"],"aria-readonly":["true","false"],"aria-required":["true","false"],"aria-selected":["true","false","undefined"],"aria-checked":["true","false","mixed","undefined"],"aria-pressed":["true","false","mixed","undefined"],"aria-live":["off","polite","assertive"],"aria-orientation":["horizontal","vertical","undefined"],"aria-sort":["none","ascending","descending","other"],"aria-autocomplete":["none","inline","list","both"],"aria-invalid":["true","false","grammar","spelling"],"aria-haspopup":["true","false","menu","listbox","tree","grid","dialog"],"aria-current":["true","false","page","step","location","date","time"]},Da={id:"aria-attr-valid",name:"Valid ARIA values",impact:"critical",tags:["wcag2a","wcag412"],help:"aria attributes must exist and have valid values",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html",selector:"*",visibleOnly:!1,evaluate(e){let t=[],o=[],a=[],n;for(let{name:s,value:i}of $e(e)){if(!s.startsWith("aria-"))continue;let r=s.slice(5);if(!(s==="aria-current"||s==="aria-invalid")){if(!ut.has(r))t.push(s);else if(ot[s]&&i.trim()==="")s!=="aria-current"&&a.push(s);else if(ot[s]&&!ot[s].includes(i.trim().toLowerCase())){if(!Ye.has(r)&&(n??=P(e),n&&ve[n]&&!ve[n].includes(r)))continue;o.push(`${s}="${i}" \u2014 allowed values: ${ot[s].join(", ")}`)}}}return o.length?{status:"fail",message:`Invalid ARIA: ${o.join("; ")}. Assistive technology ignores attributes it doesn't recognise.`,fix:"Correct the attribute name/value against the ARIA specification, or remove it."}:a.length?{status:"incomplete",message:`${a.join(", ")} is empty, so the browser ignores it and no state is exposed. Was a value intended here? If a real state was meant (${a.map(s=>ot[s].slice(0,3).join(", ")).join("; ")}, ...), it is missing and this is a 4.1.2 failure; if the attribute is a template leftover, no one is affected.`,fix:"Give the attribute one of its allowed values, or remove it."}:t.length?{status:"incomplete",message:`${t.join(", ")} is not an ARIA attribute, so the browser ignores it and assistive technology never sees it. Nothing is announced wrongly, but nothing is announced at all. Was a real ARIA state or name intended here? If it was, that state or name is missing and this is a 4.1.2 failure. If not, the attribute is stray and no one is affected. Invalid markup is not by itself a WCAG failure: the criterion that policed validity, 4.1.1 Parsing, was removed in WCAG 2.2.`,fix:"Correct the attribute name against the ARIA specification, or remove it."}:{status:"pass"}}};var nr=new Set(["label","labelledby"]),Ve={readonly:"readonly",required:"required",disabled:"disabled",checked:"checked"};function co(e){let t=[];for(let{name:s}of $e(e)){if(!s.startsWith("aria-"))continue;let i=s.slice(5);!nr.has(i)&&ut.has(i)&&t.push(i)}if(!t.length)return null;let o=P(e),a=o&&ve[o];if(!a)return null;let n=t.filter(s=>!Ye.has(s)&&!a.includes(s));return n.length?{role:o,names:n}:null}var Fa={id:"aria-allowed-attr",name:"Allowed ARIA attributes",impact:"minor",tags:["wcag2a","wcag412"],help:"ARIA attributes must be supported by the element\u2019s role",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html",selector:"*",visibleOnly:!1,evaluate(e){let t=co(e);if(!t)return{status:"pass"};let o=t.names.filter(s=>!(Ve[s]&&e.hasAttribute(Ve[s])));if(!o.length)return{status:"pass"};let a=t.role,n=o.map(s=>`aria-${s}`);return{status:"fail",message:`${n.join(", ")} is not supported on role "${a}" (ARIA 1.2 \xA78.6), so user agents drop it and assistive technology never sees it. Nothing is announced wrongly, but nothing is announced at all. If the element really has that state, it is invisible to a screen reader; if it does not, the attribute is stray and no one is affected, but ARIA 1.2 still says authors MUST NOT write it.`,fix:`Move ${n.join("/")} to the element whose role supports it, usually the control that toggles this one, or remove it if the element has no such state. Adding a role to this element to make the attribute legal is rarely right: the host language restricts which roles each element may take.`}}};var Pa={id:"aria-state-unreachable",name:"ARIA state the element really has cannot be reached",impact:"moderate",tags:["wcag2a","wcag412"],help:"A state the element has must be exposed through a role that supports it",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html",selector:"[aria-readonly], [aria-required], [aria-disabled], [aria-checked]",visibleOnly:!1,evaluate(e){let t=co(e);if(!t)return{status:"pass"};let o=t.names.filter(s=>Ve[s]&&e.hasAttribute(Ve[s]));if(!o.length)return{status:"pass"};let a=o.map(s=>`aria-${s}`),n=o.map(s=>Ve[s]);return{status:"fail",message:`This element really is ${n.join(" and ")}: its native ${n.join(" and ")} attribute says so. But ${a.join(" and ")} is not supported on role "${t.role}" (ARIA 1.2 \xA78.6), so user agents drop it and assistive technology cannot learn the state. The control works, and nobody using a screen reader is told how.`,fix:`Give the element a role that supports ${a.join(" and ")}, which for a form control is usually its own native role with no role attribute at all, or move the state to the element that carries the control's role. Do not add a role the host language forbids on this element to make the attribute legal.`}}};var Ba=["textbox","searchbox","combobox","listbox","spinbutton","slider","progressbar","meter"],Ga=["checkbox","radio","switch"];function sr(e){return ue(e)||e.getAttribute("aria-label")?.trim()||e.getAttribute("title")?.trim()||""}var qa={id:"aria-field-name",name:"ARIA field names",impact:"serious",tags:["wcag2a","wcag412"],help:"ARIA fields and value widgets must have an accessible name",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html",selector:"[role]:not(input):not(select):not(textarea)",evaluate(e,{accessibleName:t}){let o=P(e);if(![...Ba,...Ga].includes(o))return{status:"pass"};if(Ga.includes(o)||e.labels?.length?t(e):sr(e))return{status:"pass"};if(o==="combobox"&&e.tabIndex<0){let n=e.querySelector('input, [role="textbox"], [role="searchbox"]');if(n&&(n.labels?.length||n.getAttribute("aria-label")||n.getAttribute("aria-labelledby")))return{status:"pass"}}return{status:"fail",message:`This role="${o}" control has no accessible name \u2014 screen readers announce the role and value with no idea what it's for.${Ba.includes(o)?" (Content inside it does not count as a name for this role.)":""}`,fix:'Add aria-label="\u2026" or aria-labelledby pointing at its visible label.'}}};var ir='a[href], button, summary, h1, h2, h3, h4, h5, h6, th, td, [role="button"], [role="link"], [role="menuitem"], [role="menuitemcheckbox"], [role="menuitemradio"], [role="option"], [role="tab"], [role="treeitem"], [role="checkbox"], [role="radio"], [role="switch"], [role="heading"], [role="cell"], [role="gridcell"], [role="columnheader"], [role="rowheader"], [role="tooltip"]',rr=["caption","code","deletion","emphasis","generic","insertion","paragraph","strong","subscript","superscript"],lr=["div","span","p","strong","em","code","del","s","ins","sub","sup"],cr=["aria-label","aria-labelledby"].flatMap(e=>[...lr.map(t=>`${t}[${e}]:not([role]):not([tabindex])`),...rr.map(t=>`[role="${t}"][${e}]:not([tabindex])`)]).join(", "),za={id:"aria-label-misuse",name:"aria-label placement",impact:"moderate",tags:["wcag2a","wcag412"],help:"aria-label or aria-labelledby on a plain container is prohibited by ARIA, so its announcement is not guaranteed",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html",selector:cr,evaluate(e){if(e.closest(ir))return{status:"pass"};let t=e.getAttribute("aria-label");return{status:"incomplete",message:`${t!==null?`aria-label="${t}"`:(()=>{let a=(e.getAttribute("aria-labelledby")??"").trim().split(/\s+/).map(n=>e.ownerDocument.getElementById(n)?.textContent?.trim()).filter(Boolean).join(" ");return a?`aria-labelledby (naming it "${a.slice(0,80)}")`:"aria-labelledby (whose references resolve to no text)"})()} on ${e.hasAttribute("role")?`role="${e.getAttribute("role").trim()}"`:`a plain <${e.tagName.toLowerCase()}>`} is prohibited by ARIA: this element's role does not support naming, so although many browser and screen reader pairings announce the label today, that support is not guaranteed anywhere and can differ between assistive technologies. Where it is announced it replaces the element's visible text; where it is not, users get the visible text alone. Check both presentations read correctly, and that nothing here relies on the label being heard. Prohibited markup is not by itself a WCAG failure: the criterion that policed validity, 4.1.1 Parsing, was removed in WCAG 2.2 (w3.org/WAI/WCAG22/Understanding/parsing.html), so what decides this is what users actually hear.`,fix:"If this element must reliably announce something of its own, give it the role it is playing (a landmark, group, or widget role) so the name is legal and exposure is guaranteed \u2014 or move the spoken text into visible or visually-hidden real text. If the label is stray, remove it. Do not add a role solely to legalise the label."}}};var Va={checkbox:["aria-checked"],switch:["aria-checked"],radio:["aria-checked"],menuitemcheckbox:["aria-checked"],menuitemradio:["aria-checked"],slider:["aria-valuenow"],meter:["aria-valuenow"],scrollbar:["aria-valuenow","aria-controls"],separator:["aria-valuenow"],heading:["aria-level"],combobox:["aria-expanded","aria-controls"],option:["aria-selected"]},ur=new Set(["aria-controls","aria-selected"]),uo={"aria-checked":"screen readers can't announce whether it is on or off","aria-valuenow":"screen readers can't announce its value or position","aria-level":"browsers assume level 2 for a heading with no level, so the outline a screen reader user navigates by is a guess","aria-expanded":"screen readers can't announce whether its list is open","aria-controls":"assistive technology has no link from the control to what it operates","aria-selected":"a screen reader may not announce which option is selected"};function dr(e,t){let o=e.tagName,a=o==="INPUT"?e.type:null;switch(t){case"aria-checked":return a==="checkbox"||a==="radio";case"aria-valuenow":return a==="range"||o==="METER"||o==="PROGRESS";case"aria-level":return/^H[1-6]$/.test(o);case"aria-selected":return o==="OPTION";case"aria-expanded":return o==="SELECT";default:return!1}}var _a={id:"role-required-aria",name:"Required role states",impact:"serious",tags:["wcag2a","wcag412"],help:"Some roles require a state attribute to work",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html",selector:Object.keys(Va).map(e=>`[role="${e}"]`).join(", "),evaluate(e){let t=e.getAttribute("role");if(t==="separator"&&!(e.tabIndex>=0))return{status:"pass"};let o=Va[t].filter(s=>!e.hasAttribute(s)&&!dr(e,s));if(!o.length)return{status:"pass"};let a=o.filter(s=>!ur.has(s));if(a.length){let s=a.join(" and "),i=t==="separator"?`this separator takes focus, so it is a resizing widget, but without aria-valuenow ${uo["aria-valuenow"]}`:a.map(r=>uo[r]).join("; ");return{status:"fail",message:`role="${t}" without ${s} \u2014 ${i}.`,fix:`Add ${s} and keep it updated from your script, or use the native HTML element instead.`}}if(t==="combobox"&&e.getAttribute("aria-expanded")!=="true")return{status:"pass"};let n=o.join(" and ");return{status:"incomplete",message:`role="${t}" without ${n}, which ARIA lists as required for the role \u2014 ${o.map(s=>uo[s]).join("; ")}. Check the control is usable with a screen reader; adding ${n} settles it.`}}};var hr='input:not([type="hidden"]), select, textarea, button, meter, output, progress',Ha={id:"label-for-valid",name:"Label target references",impact:"serious",tags:["wcag2a","wcag412"],help:"label[for] must reference a form control that exists",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html",selector:"label[for]",evaluate(e,{accessibleName:t}){let o=e.getAttribute("for");if(e.control)return{status:"pass"};let a=e.getRootNode().getElementById?.(o);if(a&&a.tagName==="INPUT"&&a.type==="hidden")return{status:"pass"};let n=e.querySelector(hr);return n&&!t(n)?{status:"fail",message:`This label wraps a <${n.tagName.toLowerCase()}> but its for="${o}" ${a?`points at a <${a.tagName.toLowerCase()}>, which is not labelable`:"points at nothing"}. The for attribute overrides the wrapping, so the wrapped control is not labelled by this text.`,fix:"Point the for attribute at the wrapped control's id, or remove the for attribute so the wrapping labels it."}:{status:"incomplete",message:a?`for="${o}" points at a <${a.tagName.toLowerCase()}>, which is not a labelable element, so the browser ignores the association. Was a form control meant to be here? If so it has no label from this text (form-label reports the control itself); if this text captions something that is not a control, nothing is affected.`:`for="${o}" points at nothing, so this label is not associated with any control. Was a form control meant to be here? If so it has lost its label (form-label reports the control itself); if this is leftover markup, no one is affected.`,fix:"Point the for attribute at the id of the control it labels, or remove the attribute."}}};var ja={id:"listitem-parent",name:"List item placement",impact:"serious",tags:["wcag2a","wcag131"],help:"<li> must be inside a list",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships.html",selector:"li:not([role])",evaluate(e){let t=i=>i.assignedSlot?.parentElement??i.parentElement??i.getRootNode()?.host,o=t(e);for(;o?.tagName==="SLOT";)o=o.assignedSlot?.parentElement??o.parentElement;let a=i=>{let l=(i.getAttribute("role")??"").trim().toLowerCase().split(/\s+/).filter(Boolean).find(d=>ve[d])??null;return i.matches("ul, ol, menu")?!l||["list","presentation","none"].includes(l):l==="list"},n=i=>["presentation","none"].includes(i.getAttribute("role")??"")||!i.hasAttribute("role")&&(i.tagName==="DIV"||i.tagName==="SPAN");for(;o&&!a(o)&&n(o);)o=t(o);if(o&&a(o))return{status:"pass"};let s=o?`<${o.tagName.toLowerCase()}${o.getAttribute("role")?` role="${o.getAttribute("role")}"`:""}>`:"nothing";if(o?.getAttribute("role")==="group"){let i=t(o);for(;i&&!a(i)&&(n(i)||i.getAttribute("role")==="group");)i=t(i);if(i&&a(i))return{status:"fail",message:`This <li> sits inside ${s} within its list. A list may only own list items directly, and role="group" is not permitted between a list and its items, so screen readers lose the item's list context.`,fix:'Remove role="group" from the wrapper (a plain <div> keeps the items owned by the list), or move the group label onto the list element with aria-label.'}}return{status:"fail",message:`This <li> sits inside ${s} \u2014 ${o?.matches("ul, ol, menu")&&o.getAttribute("role")?"the explicit role replaces the list semantics, so":"outside a list,"} screen readers lose the item's list context entirely.`,fix:o?.matches("ul, ol, menu")&&o.getAttribute("role")?"Remove the role from the list (use a wrapping element for the landmark), or give the items roles the container expects.":"Wrap it in a <ul> or <ol>, or change it to a <div>/<p> if it isn\u2019t really a list item."}}};var pr=new Set(["DT","DD","DIV"]),Ya={id:"definition-list",name:"Definition list structure",impact:"serious",tags:["wcag2a","wcag131"],help:"<dl> must be structured as term/description pairs",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships.html",selector:"dl:not([role])",evaluate(e,{isRendered:t}){let o=r=>!rt.has(r.tagName)&&!r.closest('[aria-hidden="true"]')&&!ce(r)&&(!t||t(r)||getComputedStyle(r).display==="contents"),a=[...e.children].filter(r=>!pr.has(r.tagName)&&o(r));if(a.length)return{status:"fail",message:`This <dl> contains ${[...new Set(a.map(l=>`<${l.tagName.toLowerCase()}>`))].join(", ")} directly \u2014 only <dt>, <dd> (optionally grouped in <div>) are allowed, otherwise the term/description pairing breaks.`,fix:"Restructure the list into <dt>/<dd> pairs, or use a different element."};let n=[...e.children].filter(r=>r.tagName==="DIV"&&o(r)&&![...r.children].some(l=>l.tagName==="DT"||l.tagName==="DD"));if(n.length)return{status:"fail",message:`${n.length} <div> wrapper(s) in this <dl> hold no <dt>/<dd> directly \u2014 the term/description pairing breaks when the pairs sit deeper than the wrapper.`,fix:"Make each <div> child of the <dl> contain its <dt>/<dd> pair directly, or flatten the pairs into the <dl> itself."};let s=[...e.children].filter(o),i=[[...e.children].filter(r=>r.tagName!=="DIV"),...s.filter(r=>r.tagName==="DIV").map(r=>[...r.children])];for(let r of i){let l=r.filter(o),d=r.some(h=>(h.tagName==="DT"||h.tagName==="DD")&&!o(h)),u={status:"incomplete",message:"A term or description in this group is hidden from assistive technology. Check that any disclosure control exposes the associated content when opened, and that the term and description relationship remains available."},c=null;for(let h of l)if(!(h.tagName!=="DT"&&h.tagName!=="DD")){if(h.tagName==="DD"&&c===null)return d?u:{status:"fail",message:"This description list has a description without a preceding term in its group.",fix:"Add a <dt> before the <dd>, or use a paragraph when the content is not a term and description."};c=h.tagName}if(c==="DT")return d?u:{status:"fail",message:"This description list ends a group with a term that has no description.",fix:"Follow the <dt> element or elements with at least one <dd> in the same group."}}return{status:"pass"}}};var Ka={id:"dlitem-parent",name:"Definition item placement",impact:"serious",tags:["wcag2a","wcag131"],help:"<dt> and <dd> must be inside a <dl>",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships.html",selector:"dt:not([role]), dd:not([role])",evaluate(e){let t=o=>o.assignedSlot?.parentElement??o.parentElement??o.getRootNode()?.host??null;for(let o=t(e);o;o=t(o))if(o.tagName==="DL")return{status:"pass"};return{status:"fail",message:`<${e.tagName.toLowerCase()}> outside a <dl> has no term/description semantics.`,fix:"Wrap the terms and descriptions in a <dl>, or use different elements."}}};var Xa={id:"area-alt",name:"Image map alt text",impact:"critical",tags:["wcag2a","wcag111","wcag244"],help:"Image map areas must have alternative text",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/non-text-content.html",selector:"map area[href]",visibleOnly:!1,evaluate(e,{accessibleName:t,isVisible:o}){let a=e.closest("map"),n=[...e.getRootNode().querySelectorAll("img[usemap], object[usemap]")];return a?.name&&n.some(i=>i.getAttribute("usemap")===`#${a.name}`&&o(i))?t(e)?{status:"pass"}:{status:"fail",message:"This clickable map area has no alt text \u2014 screen readers announce nothing for it.",fix:'Add alt="Where this area links to".'}:{status:"pass"}}};var Za={id:"object-alt",name:"Object alt text",impact:"serious",tags:["wcag2a","wcag111"],help:"<object> embeds must have a text alternative",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/non-text-content.html",selector:"object",evaluate(e,{accessibleName:t}){if(t(e)||e.textContent.trim())return{status:"pass"};let o=(e.getAttribute("type")??"").trim().toLowerCase(),a=(e.getAttribute("data")??"").split(/[?#]/)[0].toLowerCase();return o.startsWith("text/")||o==="application/pdf"||o==="application/xhtml+xml"||!o&&/\.(html?|xhtml|pdf|txt)$/.test(a)?{status:"incomplete",message:"This embedded object renders a text document but has no accessible name, so assistive technology users get no indication of what the embedded document is. Check it is identified in the surrounding context.",fix:'Add aria-label="\u2026" naming the embedded document, or fallback content inside the <object> element.'}:{status:"fail",message:"This embedded object has no text alternative \u2014 users who can\u2019t see it get nothing.",fix:'Add aria-label="\u2026", or fallback content inside the <object> element.'}}};var Ja={id:"input-image-alt",name:"Image button alt text",impact:"critical",tags:["wcag2a","wcag111","wcag412"],help:"Image inputs need alt text describing their action",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/non-text-content.html",selector:'input[type="image"]',evaluate(e,{accessibleName:t}){return t(e)?{status:"pass"}:{status:"fail",message:'This image button has no alt text, so browsers fall back to a generic "Submit" name that does not describe what the button does.',fix:'Add alt="What the button does", e.g. alt="Search".'}}};var Qa={id:"multiple-labels",name:"Multiple labels",impact:"minor",tags:["best-practice"],help:"Form fields should not have multiple labels",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/labels-or-instructions.html",selector:"input, select, textarea",evaluate(e,{isVisible:t}){let o=[...e.labels??[]].filter(t);return o.length<=1?{status:"pass"}:{status:"fail",message:`${o.length} visible labels point at this field \u2014 screen readers differ in which they announce.`,fix:"Keep one label; move extra guidance into aria-describedby text."}}};function ho(e){let t=e.replace(/^\s*[\d.]*\s*(?:[;,]\s*)?/,"");t=t.replace(/^url\s*(?:=\s*)?/i,"");let o=t[0]==='"'||t[0]==="'"?t[0]:"";if(o){t=t.slice(1);let a=t.indexOf(o);a!==-1&&(t=t.slice(0,a))}return t.trim()}function po(e){let t=i=>i===" "||i===" "||i===`
`||i==="\f"||i==="\r",o=i=>i>="0"&&i<="9",a=0;for(;a<e.length&&t(e[a]);)a++;let n="";for(;a<e.length&&o(e[a]);)n+=e[a++];if(!n&&e[a]!==".")return null;let s=n?Number(n):0;for(;a<e.length&&(o(e[a])||e[a]===".");)a++;return a<e.length&&e[a]!==";"&&e[a]!==","&&!t(e[a])?null:s}var en={id:"meta-refresh",name:"Timed page refresh",impact:"critical",tags:["wcag2a","wcag221"],help:"The page must not use a timed refresh",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/timing-adjustable.html",selector:'meta[http-equiv="refresh" i]',visibleOnly:!1,evaluate(e){let t=e.getAttribute("content")??"",o=po(t);if(o===null)return{status:"pass"};let a=ho(t)!=="";return o===0&&!a?{status:"fail",message:"The page reloads itself immediately and has no destination to move on to, so the reload repeats for as long as the page is open. Nobody can read or complete anything on it.",fix:'Remove the timed refresh. If this is meant to be a redirect, give it a url (content="0; url=\u2026"); if the content needs updating, update it in place instead of reloading.'}:o>0?o>72e3?{status:"pass"}:{status:"fail",message:`The page refreshes or redirects itself after ${o}s. Slow readers lose their place, or the whole page, and a meta refresh offers no way to turn that off, adjust it or extend it. 2.2.1 excuses a time limit only where it is part of a real-time event or essential; this finding assumes neither applies, since the tag cannot show it.`,fix:"Remove the timed refresh; let users act in their own time. If the page offers a control that turns the refresh off, or the refresh is essential, record that and dismiss this finding."}:{status:"pass"}}};var at=e=>(e??"").split(/,(?![^(]*\))/).map(t=>t.trim()),fr=["Top","Right","Bottom","Left"],on=(e,t)=>parseFloat(e[`border${t}Width`])>0&&e[`border${t}Style`]!=="none"&&(L(e[`border${t}Color`])?.a??0)>0;function mr(e){return!e||e==="none"?!1:at(e).some(t=>{let o=t.match(/[a-z-]+\([^)]*\)/)?.[0],a=o?L(o):null;if(a&&a.a===0)return!1;let n=t.replace(o??"","").match(/-?[\d.]+(?=px)/g)??[];return!(n.length&&n.every(s=>parseFloat(s)===0))})}function an(e,t){if(!e.backgroundImage||e.backgroundImage==="none")return"no";let o=at(e.backgroundImage),a=at(e.backgroundSize),n=at(e.backgroundRepeat),s=at(e.backgroundPosition),i="no";return o.forEach((r,l)=>{if(r==="none")return;let d=a[l%a.length]||"auto";if(/(^|\s)0(px|%)?(\s|$)/.test(d))return;let u=n[l%n.length]||"repeat",c=s[l%s.length]||"0% 0%";if(u.includes("no-repeat")&&c.split(/\s+/).some((f,m)=>{let y=parseFloat(f);if(Number.isNaN(y))return!1;if(f.endsWith("%"))return y<0||y>100;let g=m===0?t?.width:t?.height;return y<0||Number.isFinite(g)&&y>g})){i==="no"&&(i="unclear");return}i="yes"}),i}function gr(e,t){let o;try{o=getComputedStyle(e,t)}catch{return null}let a=o.content;if(!a||a==="none"||a==="normal"||o.display==="none"||o.visibility!=="visible"||parseFloat(o.opacity)===0)return null;let n=(o.transform??"none").match(/^matrix(3d)?\((.*)\)$/);if(n){let u=n[2].split(",").map(parseFloat),[c,h,f,m]=n[1]?[u[0],u[1],u[4],u[5]]:u;if(c===0&&h===0||f===0&&m===0)return null}let s=parseFloat(o.width),i=parseFloat(o.height),r=/^["'].+["']$/s.test(a)&&parseFloat(o.fontSize)>0||/^(url|counter|counters|attr|image-set)\(/.test(a),l=(L(o.backgroundColor)?.a??0)>0||an(o,Number.isNaN(s)?null:{width:s,height:i})==="yes",d=fr.some(u=>on(o,u));if(l||d){if(Number.isNaN(s)||Number.isNaN(i))return r?"glyph":"unclear";let u=f=>f.reduce((m,y)=>m+(parseFloat(o[y])||0),0),c=s+u(["paddingLeft","paddingRight","borderLeftWidth","borderRightWidth"]),h=i+u(["paddingTop","paddingBottom","borderTopWidth","borderBottomWidth"]);if(c>0&&h>0)return"cue"}return r?!Number.isNaN(s)&&!Number.isNaN(i)&&s<=1&&i<=1?null:"glyph":null}var tn="svg, img, picture, canvas, video, object, embed",nn={id:"link-in-text-block",name:"Link distinction in text",impact:"serious",tags:["wcag2a","wcag141"],help:"Links inside text must be distinguishable by more than colour",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/use-of-color.html",selector:"p a[href], dd a[href], blockquote a[href], td a[href], li a[href], div a[href]",visibility:"visual",evaluate(e,{ownText:t}){let o=e.closest("p, dd, blockquote, td, li, div");if(!e.textContent.trim()||!o)return{status:"pass"};let a=t(o).trim();if(!/[\p{L}\p{N}]/u.test(a))return{status:"pass"};let n=a.replace(/\s+/g,"").length<10,s=getComputedStyle(e),i=getComputedStyle(o),r=k=>parseInt(k.fontWeight,10)||400,l=k=>/italic|oblique/.test(k.fontStyle??""),d=parseFloat(i.fontSize)||16,u=[{s,el:e,text:!0}],c=!1;for(let k of e.querySelectorAll("*")){let U=[...k.getClientRects()].filter(N=>N.width>1&&N.height>1);if(U.length){if(k.matches(tn)){U.some(N=>N.width>=4&&N.height>=4)&&(c=!0);continue}k.closest(tn)||u.push({s:getComputedStyle(k),el:k,text:!!k.textContent.trim()})}}let h=!1;for(let{s:k,el:U,text:N}of u){if(N&&(k.textDecorationLine??k.textDecoration??"").includes("underline"))return{status:"pass"};if(on(k,"Bottom"))return{status:"pass"};if(mr(k.boxShadow))return{status:"pass"};let V=L(k.backgroundColor);if(V&&V.a>0){let ie=ne(o);if(!ie)h=!0;else{let re=G(V,ie);if(["r","g","b"].some(de=>Math.round(re[de])!==Math.round(ie[de])))return{status:"pass"}}}let _=an(k,U.getBoundingClientRect());if(_==="yes")return{status:"pass"};if(_==="unclear"&&(h=!0),!!N){if(Math.abs(r(k)-r(i))>=300)return{status:"pass"};if(l(k)!==l(i))return{status:"pass"}}}let f=u.filter(k=>k.text).map(k=>k.s),m=Math.max(...f.map(k=>Math.abs(r(k)-r(i)))),y=Math.max(...f.map(k=>Math.abs((parseFloat(k.fontSize)||d)-d))),g=y>=2&&y/d>=.1,w=u.filter(({el:k})=>t(k)).map(({s:k})=>k.webkitTextFillColor||k.color),b=[...new Set(w)];if(b.length>1)return{status:"incomplete",message:"This link presents text in several colours without a detected non-colour cue. Check that each part is distinguishable from the surrounding text."};let x=L(b[0]||s.webkitTextFillColor||s.color),I=L(i.webkitTextFillColor||i.color);if(!x||!I)return{status:"pass"};if((x.a??1)<1||(I.a??1)<1){if(Be(e))return{status:"incomplete",message:"This link has no underline and its colour is translucent over a background image or gradient, so its colour difference from the surrounding text depends on the pixels behind it. Check by eye that something other than colour identifies it as a link.",fix:"Underline links inside text (text-decoration: underline), or add a non-colour indicator."};let k=ne(e);if(!k)return{status:"incomplete",message:"This link has no underline and its colour is translucent, but the background it composites over could not be determined. Check by eye that something other than colour identifies it as a link.",fix:"Underline links inside text (text-decoration: underline), or add a non-colour indicator."};let U=N=>(N.a??1)<1?G(N,k):N;x=U(x),I=U(I)}let O=(k,U)=>Math.round(k)===Math.round(U);if(O(x.r,I.r)&&O(x.g,I.g)&&O(x.b,I.b))return{status:"pass"};let F=H(x,I);if(F>=3)return{status:"pass"};for(let k=e.parentElement;k&&k!==o;k=k.parentElement)if((getComputedStyle(k).textDecorationLine??"").includes("underline")){if(k.textContent.replace(/\s+/g,"")===e.textContent.replace(/\s+/g,""))return{status:"pass"};break}for(let k of["::after","::before"]){let U=gr(e,k);if(U==="cue")return{status:"pass"};U==="glyph"&&(c=!0),U==="unclear"&&(h=!0)}let E=[...e.getClientRects()].filter(k=>k.width>0&&k.height>0);if(E.length){let k=E.map(_=>_.top+_.height/2),U=e.ownerDocument.createTreeWalker(o,NodeFilter.SHOW_TEXT),N=e.ownerDocument.createRange(),V=!1;for(let _=U.nextNode();_&&!V;_=U.nextNode())if(!(!_.textContent.trim()||e.contains(_))){N.selectNodeContents(_);for(let ie of N.getClientRects())if(ie.width>0&&k.some(re=>ie.top<=re&&ie.bottom>=re)){V=!0;break}}if(!V)return{status:"pass"}}let q=F.toFixed(2),B="Underline links inside text (text-decoration: underline), or add another clear non-colour indicator.";return c?{status:"incomplete",message:`This link has no underline and only ${q}:1 colour difference from the surrounding text, but it carries an icon or image. Judge by eye whether the graphic reads as part of the link and marks it out from the prose; if it does not, this fails SC 1.4.1.`,fix:B}:h?{status:"incomplete",message:`This link has no underline and only ${q}:1 colour difference from the surrounding text, but a generated box or background image is painted on it whose size at rest could not be measured. Check by eye whether it draws a visible underline or shape; if nothing shows until hover, this fails SC 1.4.1.`,fix:B}:m>=200?{status:"incomplete",message:`This link has no underline and only ${q}:1 colour difference from the surrounding text, but its font weight differs from the prose by ${m}: a visible non-colour cue that falls short of a clear bold step. Judge by eye whether the weight alone identifies it as a link in this face and size; if it does not, this fails SC 1.4.1.`,fix:"Underline links inside text (text-decoration: underline), raise the weight difference to a clear bold step, or add another non-colour indicator."}:g?{status:"incomplete",message:`This link has no underline and only ${q}:1 colour difference from the surrounding text, but its font size differs from the prose by ${y.toFixed(1).replace(/\.0$/,"")}px, one of the cues G182 names. Judge by eye whether the size alone identifies it as a link; if it does not, this fails SC 1.4.1.`,fix:B}:n?{status:"incomplete",message:`This link has no detected non-colour cue and only ${q}:1 colour difference from nearby text. The surrounding text is a short fragment. Check whether it forms a sentence or other prose with the link; if it does, colour alone does not distinguish the link sufficiently.`,fix:B}:{status:"fail",message:F<1.01?"This link has no underline and its colour differs from the surrounding text in hue alone, with no luminance difference: the distinction disappears entirely without colour vision, the exact failure F73 describes.":`This link has no underline and only ${q}:1 colour difference from the surrounding text, below the 3:1 WCAG technique G183 asks for when colour is the only thing marking a link.`,fix:"Underline links inside text (text-decoration: underline), or add a non-colour indicator."}}};var sn={id:"p-as-heading",name:"Styled text as heading",impact:"serious",tags:["wcag2a","wcag131"],help:"Bold paragraphs should not stand in for headings",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships.html",selector:"p",evaluate(e){let t=e.textContent.trim(),o=e.children.length===1&&e.children[0];return t&&t.length<60&&o&&o.matches("b, strong")&&o.textContent.trim()===t&&e.nextElementSibling?.matches("p")?{status:"incomplete",message:`"${t}" is a short bold paragraph followed by text \u2014 if it's acting as a heading, it's invisible to heading navigation. Verify.`,fix:"If it is a heading, use a real heading element (<h2>\u2026</h2>) at the appropriate level."}:{status:"pass"}}};var br={feed:["article"],row:["cell","columnheader","gridcell","rowheader"],list:["listitem"],listbox:["option","group"],menu:["menuitem","menuitemcheckbox","menuitemradio","group"],menubar:["menuitem","menuitemcheckbox","menuitemradio","group"],radiogroup:["radio"],tablist:["tab"],tree:["treeitem","group"],table:["row","rowgroup"],grid:["row","rowgroup"],treegrid:["row","rowgroup"],rowgroup:["row"]},wr=P;function rn(e){let t=[],o=[e],a=new Set,n=s=>{if(!a.has(s)&&(a.add(s),t.push(s),s.shadowRoot&&o.push(s.shadowRoot),s.tagName==="SLOT"))for(let i of s.assignedElements({flatten:!0}))n(i),o.push(i)};for(let s=0;s<o.length;s++){let i=o[s];if(i.shadowRoot&&o.push(i.shadowRoot),i.tagName==="SLOT")for(let r of i.assignedElements({flatten:!0}))n(r),o.push(r);for(let r of i.querySelectorAll("*"))n(r)}return t}function yr(e){let t=rn(e).filter(a=>!a.matches("script, style, template")),o=e.getAttribute("aria-owns");if(o){let a=e.getRootNode();for(let n of o.split(/\s+/).filter(Boolean)){let s=a.getElementById?.(n);s&&t.push(s,...rn(s))}}return t}function xr(e,t){if(t(e))return!0;if(e.tagName!=="OPTION")return!1;let o=e.closest("select");return!!o&&t(o)}var ln={id:"aria-required-children",name:"Required ARIA children",impact:"critical",tags:["wcag2a","wcag131"],help:"Composite ARIA roles must contain their required children",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships.html",selector:"[role]",evaluate(e,{isVisible:t}){if(e.getAttribute("aria-busy")==="true")return{status:"pass"};let o=P(e),a=br[o];return a?![...e.children,...e.shadowRoot?.children??[]].filter(s=>!s.matches("script, style, template")).length&&!e.hasAttribute("aria-owns")?{status:"pass"}:yr(e).some(s=>a.includes(wr(s))&&xr(s,t))?{status:"pass"}:{status:"fail",message:`role="${o}" contains no ${a.join("/")} anywhere inside it, and claims none by aria-owns \u2014 screen readers announce a broken, empty ${o}.`,fix:`Give the item elements role="${a[0]}", or remove role="${o}" from the container.`}:{status:"pass"}}};var vr={caption:["figure","grid","table","treegrid"],columnheader:["row"],rowheader:["row"],listitem:["list"],option:["listbox","group"],menuitem:["menu","menubar","group"],menuitemcheckbox:["menu","menubar","group"],menuitemradio:["menu","menubar","group"],tab:["tablist"],treeitem:["tree","group"],row:["table","grid","treegrid","rowgroup"],rowgroup:["table","grid","treegrid"],cell:["row"],gridcell:["row"]},cn={id:"aria-required-parent",name:"Required ARIA parent",impact:"critical",tags:["wcag2a","wcag131"],help:"ARIA child roles must be inside their required container role",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships.html",selector:"[role]",evaluate(e){let t=P(e),o=vr[t];if(!o)return{status:"pass"};let a=o.filter(s=>s!=="group");if(e.id){let s=e.getRootNode().querySelector?.(`[aria-owns~="${CSS.escape(e.id)}"]`),i=s&&P(s);if(i&&o.includes(i))return{status:"pass"}}let n=s=>s.assignedSlot??s.parentElement??(s.getRootNode()instanceof ShadowRoot?s.getRootNode().host:null);for(let s=n(e);s;s=n(s)){if(s.tagName==="SLOT"&&!s.hasAttribute("role"))continue;let i=P(s);if(o.includes(i))return{status:"pass"};if(i!=="group"&&!(i==="presentation"||i==="none")&&i&&i!=="generic")break}return{status:"fail",message:`role="${t}" is not inside a ${a.join("/")} \u2014 assistive technology loses the structure entirely.`,fix:`Wrap it in an element with role="${a[0]}", or fix the intervening roles.`}}};var fo='a[href], button, input:not([type="hidden"]), select, textarea, summary, [tabindex]';function mo(e){return e.tabIndex<0||e.disabled||ce(e)?!1:typeof e.checkVisibility=="function"?e.checkVisibility({visibilityProperty:!0}):!0}function un(e){for(let t of e.querySelectorAll?.(fo)??[])if(mo(t))return!0;for(let t of e.querySelectorAll?.("slot")??[])for(let o of t.assignedElements?.()??[]){if(o.matches?.(fo)&&mo(o))return!0;for(let a of o.querySelectorAll?.(fo)??[])if(mo(a))return!0}for(let t of e.querySelectorAll?.("*")??[])if(t.shadowRoot&&un(t.shadowRoot))return!0;return!1}var dn={id:"scrollable-region-focusable",name:"Keyboard-reachable scroll areas",impact:"serious",tags:["wcag2a","wcag211","wcag213"],help:"Scrollable regions must be reachable by keyboard",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/keyboard.html",selector:"*",visibleOnly:!1,evaluate(e,{isVisible:t}){let o=e.scrollWidth>e.clientWidth+1,a=e.scrollHeight>e.clientHeight+1;if(!o&&!a)return{status:"pass"};if(e===e.ownerDocument.documentElement||e===e.ownerDocument.body)return{status:"pass"};if(!e.clientWidth||!e.clientHeight)return{status:"pass"};let n=getComputedStyle(e),s=o&&/(auto|scroll)/.test(n.overflowX),i=a&&/(auto|scroll)/.test(n.overflowY);return!s&&!i?{status:"pass"}:t(e)?e.tabIndex>=0?{status:"pass"}:un(e)?{status:"pass"}:e.hasAttribute("tabindex")?{status:"incomplete",message:"This region scrolls, has no detected tabbable content and is removed from sequential focus by a negative tabindex. Check whether keyboard-operable controls elsewhere scroll it or move focus into it; without such a mechanism, the overflowed content may be unreachable.",fix:'Change tabindex="-1" to tabindex="0" (plus role="region" and an aria-label describing it), or make something inside it tabbable.'}:{status:"incomplete",message:'This region scrolls and holds nothing tabbable, so reaching its overflowed content depends on the browser. Chromium gives such containers keyboard focus automatically; not every engine does. Tab to it in the browsers you support, and add tabindex="0" if it cannot be reached.',fix:'If you support browsers that do not focus scroll containers, add tabindex="0" (plus role="region" and an aria-label describing it).'}:{status:"pass"}}};var Ar="h1, h2, h3, h4, h5, h6, p, ul, ol, dl, menu, form, nav, main, header, footer, section, article, aside, blockquote, figure, fieldset, pre, hr, table",hn={id:"table-headers",name:"Table header associations",impact:"serious",tags:["wcag2a","wcag131"],help:"Data tables must have properly associated header cells",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/info-and-relationships.html",selector:"table",evaluate(e){let t=e.getAttribute("role");if(t&&!["table","grid"].includes(t))return{status:"pass"};let o=[...e.rows],a=o.flatMap(c=>[...c.cells]),n=o.length>=2&&Math.max(0,...o.map(c=>c.cells.length))>=2,s=a.filter(c=>c.textContent.trim()).length;if(!n||s<4)return{status:"pass"};let i=c=>c.getAttribute("role")?.trim().split(/\s+/)[0]?.toLowerCase(),r=c=>c.tagName==="TH"||["columnheader","rowheader"].includes(i(c)),l=a.some(r);if(!l&&(e.querySelector("table")||e.parentElement?.closest("table")))return{status:"incomplete",message:'This table has no header cells and is part of a nested-table structure \u2014 a layout-table signature. If it really presents data, mark its header cells with <th>; if it is layout scaffolding, add role="presentation".'};let d=a.filter(c=>{let h=c.getAttribute("headers");return h&&h.trim().split(/\s+/).filter(Boolean).some(f=>{let m=e.getRootNode().getElementById?.(f);return!m||!a.includes(m)||!r(m)})});return d.length?{status:"fail",message:`${d.length} cell(s) have headers="\u2026" referencing ids that are not header cells of this table \u2014 screen readers cannot relate the data to its headers.`,fix:"Make each headers attribute list the id(s) of <th> cells in the same table."}:l||a.some(c=>c.hasAttribute("scope")||c.hasAttribute("headers"))?{status:"pass"}:a.some(m=>m.querySelector(Ar))?{status:"incomplete",message:'This table has no header cells and its cells hold block content (headings, paragraphs, lists or forms), which is a layout-table signature. If it really presents data, mark its header cells with <th>; if it is layout scaffolding, add role="presentation".'}:a.filter(m=>m.textContent.trim()).every(m=>{let y=[...m.querySelectorAll("a, button")];return y.length&&y.map(g=>g.textContent.trim()).join(" ").replace(/\s+/g," ")===m.textContent.trim().replace(/\s+/g," ")})?{status:"incomplete",message:'This table has no header cells and every cell holds only a link or a button, which is the shape of a navigation block laid out as a table. If it presents data, mark its header cells with <th>; if it is layout, add role="presentation".'}:{status:"fail",message:'This looks like a data table but has no header cells, so screen reader users get the data with no way to tell what each row or column means. If it only arranges content, mark it role="presentation" and dismiss this finding.',fix:Math.max(0,...o.map(m=>m.cells.length))===2?'Mark the first cell of each row as <th scope="row">: in a two-column table the first column names what the second holds.':'Mark header cells with <th> (add scope="col" or scope="row" when the table has both).'}}};var pn=io({id:"color-contrast-enhanced",name:"Enhanced text contrast",tags:["wcag2aaa","wcag146"],help:"Text must have enhanced contrast against its background (AAA)",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/contrast-enhanced.html",thresholds:{normal:7,large:4.5}});var fn=ro({id:"target-size-enhanced",name:"Enhanced target size",tags:["wcag21aaa","wcag255"],help:"Interactive targets must be at least 44\xD744 pixels (AAA)",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/target-size-enhanced.html",min:44,spacingException:!1});var mn={id:"dialog-name",name:"Dialog names",impact:"serious",tags:["best-practice"],help:"Dialogs should have an accessible name",helpUrl:"https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/",selector:'dialog, [role="dialog"], [role="alertdialog"]',evaluate(e){return ue(e)?{status:"pass"}:e.getAttribute("aria-label")?.trim()||e.getAttribute("title")?.trim()?{status:"pass"}:{status:"fail",message:'This dialog has no accessible name \u2014 screen readers announce just "dialog" with no hint of what it is or why it appeared.',fix:`Point aria-labelledby at the dialog's heading, or add aria-label="What this dialog is".`}}};var gn={id:"control-contrast",name:"Form control contrast",impact:"serious",tags:["wcag2aa","wcag143"],help:"Text inside form controls must have sufficient contrast",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/contrast-minimum.html",selector:'input:not([type="hidden"]):not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="color"]):not([type="file"]):not([type="image"]), select, textarea',visibility:"visual",evaluate(e){if(e.closest(':disabled, [aria-disabled="true"]'))return{status:"pass"};let t=e.getBoundingClientRect();if(t.width<=1||t.height<=1)return{status:"pass"};let o=getComputedStyle(e);if(parseFloat(o.fontSize)===0)return{status:"pass"};if(/^(submit|button|reset)$/i.test(e.getAttribute("type")??"")&&e.hasAttribute("value")&&e.getAttribute("value")==="")return{status:"pass"};{let h=e.ownerDocument,f=h.defaultView;if(f&&getComputedStyle(h.documentElement).direction!=="rtl"&&(t.right+f.scrollX<=0||t.bottom+f.scrollY<=0))return{status:"pass"}}let a=yt(e)?xt(e):Ee(e);if(a<.05)return{status:"pass"};if(Pe(e))return{status:"incomplete",message:"A filter or blend mode changes the colours presented inside this field. Check the resulting text contrast by eye."};let n=L(o.backgroundColor),s;if(o.backgroundImage!=="none"){let h=Ge(o.backgroundImage),f=h.length===1&&h[0].includes("gradient(")?et(h[0]):null,m=/^(auto|auto auto)$/.test(o.backgroundSize)&&o.backgroundPosition==="0% 0%"&&["repeat","no-repeat"].includes(o.backgroundRepeat);if(!f||f.min!==f.max||a<1||!m)return{status:"incomplete",message:"An image or gradient paints this field background. Check its text against the pixels behind it."};s=f.minColor}else if(n&&n.a>=1)s=n;else{if(Be(e))return{status:"incomplete",message:"This field is see-through and sits over a background image or gradient, so its real text contrast depends on the pixels behind it. Check it by eye."};s=ne(e)}if(!s)return{status:"incomplete",message:"The control\u2019s background could not be determined \u2014 check its text contrast by eye."};let i=qe(o)?3:4.5,r=!1,l=(h,f,m=1)=>{let y=L(h);if(!y||y.a===0)return null;if(a<1){let I=vt(e,{...y,a:y.a*m});if(I?.unresolved)return r=!0,null;if(I){let O=H(I.foreground,I.background);return O>=i?null:{what:f,ratio:O,fg:I.foreground,bg:I.background}}}let g=a*m,w=g<1?{...y,a:y.a*g}:y,b=w.a<1?G(w,s):w,x=H(b,s);return x>=i?null:{what:f,ratio:x,fg:b,bg:s}},d=[],u=l(o.webkitTextFillColor||o.color,"value text");if(u&&d.push(u),e.getAttribute("placeholder")?.trim()&&e.matches(":placeholder-shown")){let h=null,f=1;try{let m=getComputedStyle(e,"::placeholder");h=m.webkitTextFillColor||m.color;let y=parseFloat(m.opacity);Number.isFinite(y)&&(f=Math.min(1,Math.max(0,y)))}catch{}if(h&&(h!==o.color||f<1)){let m=l(h,"placeholder text",f);m&&d.push(m)}}if(r)return{status:"incomplete",message:"The field and its text fade together over an unresolved background. Check the presented text contrast by eye."};if(!d.length)return{status:"pass"};let c=d.sort((h,f)=>h.ratio-f.ratio)[0];return{status:"fail",message:`This field's ${c.what} has ${K(c.ratio)}:1 contrast against the field background \u2014 below the ${i}:1 minimum.`,fix:`Darken the ${c.what.includes("placeholder")?"placeholder colour (::placeholder)":"text colour"} until it reaches ${i}:1 against the field background (currently ${he(c.fg)} on ${he(c.bg)}).`,data:{foreground:he(c.fg),background:he(c.bg),ratio:Number(K(c.ratio)),required:i}}}};var bn={id:"non-text-contrast",name:"Form field boundary contrast",impact:"serious",tags:["wcag21aa","wcag1411"],help:"Form field fills and borders below 3:1 need checking against the field's other identifiers",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/non-text-contrast.html",selector:'input:not([type="hidden"]):not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]):not([type="reset"]):not([type="image"]):not([type="range"]):not([type="file"]), select, textarea',visibility:"visual",evaluate(e){if(e.closest(':disabled, [aria-disabled="true"]'))return{status:"pass"};let t=e.getBoundingClientRect();if(t.width<=1||t.height<=1)return{status:"pass"};let o=getComputedStyle(e);if(o.appearance!=="none"&&e.tagName==="SELECT")return{status:"pass"};let a=ne(e.parentElement??e);if(!a)return{status:"incomplete",message:"The background around this field could not be determined \u2014 check the field has a visible boundary by eye."};let n=[],s=!1,i=L(o.backgroundColor);i&&i.a>0&&(n.push(i.a>=1?i:G(i,a)),i.a<1&&(s=!0));let r=!1;for(let d of["Top","Right","Bottom","Left"]){if(parseFloat(o[`border${d}Width`])<=0||o[`border${d}Style`]==="none")continue;r=!0;let u=L(o[`border${d}Color`]);!u||u.a===0||(n.push(u.a>=1?u:G(u,a)),u.a<1&&(s=!0))}if(parseFloat(o.outlineWidth)>0&&o.outlineStyle!=="none"){let d=L(o.outlineColor);d&&d.a>0&&(r=!0,n.push(d.a>=1?d:G(d,a)),d.a<1&&(s=!0))}let l=Math.max(1,...n.map(d=>H(d,a)));if(l>=3)return{status:"pass"};if(o.boxShadow!=="none"||o.backgroundImage!=="none")return{status:"incomplete",message:"This field\u2019s boundary may come from a box-shadow or background image \u2014 check it reaches 3:1 against the page by eye."};if(s)return{status:"incomplete",message:`This field's boundary uses translucent colours and reaches about ${K(l)}:1 against the page \u2014 near the 3:1 minimum; check by eye.`};for(let d=e.parentElement,u=0;d&&u<4;d=d.parentElement,u++){let c=d.getBoundingClientRect();if(c.height>t.height+24||c.width>t.width+160)break;let h=getComputedStyle(d);if(["Top","Right","Bottom","Left"].some(y=>parseFloat(h[`border${y}Width`])>0&&h[`border${y}Style`]!=="none"&&(L(h[`border${y}Color`])?.a??0)>0)){let y=ne(d.parentElement??d);if(y&&["Top","Right","Bottom","Left"].some(w=>{if(!(parseFloat(h[`border${w}Width`])>0)||h[`border${w}Style`]==="none")return!1;let b=L(h[`border${w}Color`]);return b&&H(G(b,y),y)>=3}))return{status:"pass"}}let m=L(h.backgroundColor);if(m&&m.a>=1){let y=ne(d.parentElement??d);if(y&&H(m,y)>=3)return{status:"pass"};break}}return!r&&(!i||i.a===0)?{status:"incomplete",message:"This field has no border and no distinct fill \u2014 if its label and layout don\u2019t already make it findable, low-vision users can\u2019t locate it. Check by eye (3:1 boundary or clear identification needed)."}:{status:"incomplete",message:`This field's boundary reaches only ${K(l)}:1 against the page \u2014 below the 3:1 minimum. That\u2019s conformant ONLY if the field is identifiable without the boundary (visible label, placeholder position); check by eye.`}}};var kr=e=>`html { overflow-anchor: none !important; min-height: ${e}px !important; }
* {
line-height: 1.5 !important;
letter-spacing: 0.12em !important;
word-spacing: 0.16em !important;
}
p { margin-bottom: 2em !important; }`,wn=e=>e.scrollWidth>e.clientWidth+2||e.scrollHeight>e.clientHeight+2,yn={id:"text-spacing",name:"Text spacing overrides",impact:"serious",tags:["wcag21aa","wcag1412"],help:"Text must survive user spacing overrides without being cut off",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/text-spacing.html",selector:"p, h1, h2, h3, h4, h5, h6, a, button, li, span, div, td, th, label, dt, dd, figcaption",visibility:"visual",evaluateAll(e){let t=e[0]?.ownerDocument??document;if(e.length>2e4)return e.map((u,c)=>c===0?{status:"incomplete",message:`The text-spacing probe was not run because this page has ${e.length} candidate elements, exceeding its 20,000-element budget. Check the page with the WCAG spacing overrides applied.`}:{status:"skipped"});let o=e.map(u=>{let c=getComputedStyle(u);return!/(hidden|clip)/.test(`${c.overflowX} ${c.overflowY}`)||!u.textContent.trim()?null:u.clientWidth>4&&u.clientHeight>4?u:null});if(!o.some(Boolean))return e.map(()=>({status:"pass"}));let a=o.map(u=>u&&wn(u)),n=t.defaultView,s=n?.scrollX??0,i=n?.scrollY??0,r=t.createElement("style");r.dataset.pourAudit="probe",r.textContent=kr(t.documentElement.scrollHeight),t.documentElement.append(r);let l=[r];for(let u of new Set(o.filter(Boolean).map(c=>c.getRootNode()))){if(u===t||!u.host)continue;let c=r.cloneNode(!0);u.append(c),l.push(c)}let d;try{t.documentElement.offsetHeight,d=o.map(u=>u&&wn(u))}finally{for(let u of l)u.remove();t.documentElement.offsetHeight,n&&(n.scrollX!==s||n.scrollY!==i)&&n.scrollTo({left:s,top:i,behavior:"instant"})}return e.map((u,c)=>o[c]?a[c]||!d[c]?{status:"pass"}:{status:"incomplete",message:"With the WCAG text-spacing overrides applied (line height 1.5, letter/word spacing bumps), this container overflows instead of growing \u2014 if that hides text rather than empty trailing spacing, users who need wider spacing lose content. Check with the overrides applied; to be safe, let the container grow (min-height instead of height, avoid overflow:hidden on text)."}:{status:"pass"})}};var xn={id:"reflow",name:"Content reflow",impact:"moderate",tags:["wcag21aa","wcag1410"],help:"Content should reflow to one-dimensional scrolling",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/reflow.html",selector:"html",visibleOnly:!1,evaluate(e){let t=e.ownerDocument,o=t.scrollingElement??t.documentElement,a=o.scrollWidth-o.clientWidth;return a<=1?{status:"pass"}:{status:"incomplete",message:`The page already scrolls horizontally by ${Math.round(a)}px at the current viewport. Verify content reflows at 320 CSS px width (data tables, maps and images are exempt).`}}};var Cr=/:focus(?:-visible)?(?![\w-])/g,Sr=/:focus(?:-visible)?(?![\w-])/;function Tr(e){let t=[],o=c=>c.getPropertyValue("box-shadow")||c.getPropertyValue("border")||c.getPropertyValue("border-color")||c.getPropertyValue("background")||c.getPropertyValue("background-color")||c.getPropertyValue("text-decoration"),a=c=>`${c.getPropertyValue("outline")} ${c.getPropertyValue("outline-style")} ${c.getPropertyValue("outline-width")}`,n=c=>/\bnone\b/.test(c)||/(^|\s)0(px)?(\s|$)/.test(c),s=c=>c.split(",").map(h=>h.replace(Cr,"").replace(/\s+/g," ").trim()),i=null,r=c=>{if(!c.selectorText||!/:focus/.test(c.selectorText)||/:not\(\s*:focus-visible\s*\)/.test(c.selectorText))return;let h=c.style;if(!h)return;let f=[h,...[...c.cssRules??[]].filter(w=>w.style&&!w.selectorText).map(w=>w.style)],m=f.some(o),y=f.map(a).filter(w=>w.trim()),g=y.some(w=>!n(w));Sr.test(c.selectorText)&&(m||g)&&i.providers.push({order:i.order,subjects:s(c.selectorText)}),!(!y.some(n)||m)&&i.suspects.push({order:i.order,selector:c.selectorText,subjects:s(c.selectorText)})},l=(c,h)=>h.subjects.some(f=>f===c||f==="*"||f===""),d=()=>{for(let c of i.suspects)c.subjects.every(f=>i.providers.some(m=>m.order>c.order&&l(f,m)))||t.push(c.selector)},u=c=>{for(let h of c)i.order++,r(h),h.cssRules?.length&&u(h.cssRules)};for(let c of e.styleSheets){i={order:0,suspects:[],providers:[]};try{u(c.cssRules)}catch{}d()}return t}var vn={id:"focus-visible",name:"Visible focus",impact:"serious",tags:["wcag2aa","wcag247"],help:"Keyboard focus must remain visible",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/focus-visible.html",selector:"html",visibleOnly:!1,evaluate(e){let t=Tr(e.ownerDocument);if(!t.length)return{status:"pass"};let o=t.slice(0,3).join(", ");return{status:"incomplete",message:`${t.length} CSS rule(s) remove the focus outline without setting a replacement in the same rule (e.g. ${o}) \u2014 if no other rule provides a visible indicator, keyboard users lose their place. Tab through the page to check.`}}};var Rr='a[href], button, input:not([type="hidden"]), select, textarea, summary, [tabindex]:not([tabindex="-1"])';function Nr(e,t,o){let a=e.scrollingElement??e.documentElement,n=getComputedStyle(a),s=t==="top"?n.scrollPaddingTop:n.scrollPaddingBottom;return(s&&s.endsWith("px")?parseFloat(s):0)>=o-1}function go({id:e,name:t,tags:o,help:a,helpUrl:n,partial:s}){return{id:e,name:t,impact:"serious",tags:o,help:a,helpUrl:n,selector:Rr,visibility:"visual",evaluateAll(i){let r=i[0]?.ownerDocument??document,l=r.defaultView;if([...r.querySelectorAll('dialog[open], [role="dialog"], [role="alertdialog"], [aria-modal="true"]')].some(w=>{let b=w.getBoundingClientRect();return b.width>0&&b.height>0&&getComputedStyle(w).visibility!=="hidden"}))return i.map(()=>({status:"pass"}));let u=new Map,c=w=>{if(u.has(w))return u.get(w);let b=!1,x=getComputedStyle(w);if(x.position==="fixed"||x.position==="sticky"){let I=x.backgroundColor.match(/rgba?\(([^)]+)\)/)?.[1]?.split(","),O=I?.[3]===void 0?1:parseFloat(I[3]),F=w.getBoundingClientRect();b=O>=.9&&F.width>=40&&F.height>=24}return u.set(w,b),b},h=(w,b)=>w.left>=b.left&&w.right<=b.right&&w.top>=b.top&&w.bottom<=b.bottom,f=(w,b)=>Math.min(w.right,b.right)-Math.max(w.left,b.left)>0&&Math.min(w.bottom,b.bottom)-Math.max(w.top,b.top)>0,m=w=>Math.min(Math.max(w,0),l.innerWidth-1),y=w=>Math.min(Math.max(w,0),l.innerHeight-1),g=(w,b,x,I)=>{let O=r.elementsFromPoint(m(x),y(I)),F=O.indexOf(w);return F<=0?null:O.slice(0,F).find(q=>!q.contains(w)&&!w.contains(q)&&c(q)&&(s?f:h)(b,q.getBoundingClientRect()))??null};return i.map(w=>{if(w.matches(":disabled"))return{status:"pass"};if(ce(w))return{status:"pass"};let b=w.getBoundingClientRect();if(!b.width||!b.height)return{status:"pass"};if(b.bottom<0||b.right<0||b.top>l.innerHeight||b.left>l.innerWidth)return{status:"pass"};let x=b.left+b.width/2,I=b.top+b.height/2,O=g(w,b,x,I);if(!O&&s){let B=[b.left+1,x,b.right-1],k=[b.top+1,I,b.bottom-1];for(let U of B){for(let N of k)if(!(U===x&&N===I)&&(O=g(w,b,U,N),O))break;if(O)break}}if(!O)return{status:"pass"};let F=O.getBoundingClientRect(),E=F.top<=1&&F.bottom<l.innerHeight?"top":F.bottom>=l.innerHeight-1?"bottom":null;return E&&Nr(r,E,F.height)?{status:"pass"}:s?{status:"incomplete",message:"Part of this element is currently underneath an opaque fixed panel. 2.4.12 (AAA) allows no part of a focused component to be hidden by author content, and whether that happens depends on where the page sits when focus reaches it \u2014 the browser does not scroll an element that is already in the viewport, merely overlapped, so focus can land half-hidden. Tab through the page and check the whole element, indicator included, stays clear of the panel.",fix:`Reserve room for the panel with scroll-padding-${E??"bottom"} on the scrolling container, or move focus clear of it when the panel is up.`}:{status:"incomplete",message:"This element is currently underneath an opaque fixed panel. Whether that breaks 2.4.11 depends on where the page sits when focus reaches it \u2014 the browser does not scroll an element that is already in the viewport, merely covered, so focus can land invisibly. Tab through the page and check the focus indicator is never entirely hidden.",fix:`Reserve room for the panel with scroll-padding-${E??"bottom"} on the scrolling container, or move focus clear of it when the panel is up.`}})}}}var An=go({id:"focus-not-obscured",name:"Unobscured focus",tags:["wcag22aa","wcag2411"],help:"Focused elements must not be fully hidden behind overlays",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/focus-not-obscured-minimum.html",partial:!1});var kn={id:"auth-field-obstruction",name:"Accessible login fields",impact:"serious",tags:["wcag22aa","wcag338","wcag339"],help:"Login fields must not block paste or password managers",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/accessible-authentication-minimum.html",selector:'input[type="password"]:not([autocomplete~="new-password"]), input[autocomplete~="current-password"], input[autocomplete~="one-time-code"]',evaluate(e){let t=/return\s+false|preventDefault/.test(e.getAttribute("onpaste")??""),o=(e.getAttribute("autocomplete")??"").trim().toLowerCase().split(/\s+/).filter(Boolean),a=o.length===1&&o[0]==="off";if(!t&&!a)return{status:"pass"};let n=e.form??e.closest("form"),s=n?n.querySelectorAll('input[type="password"]').length:e.type==="password"?1:0,i=n?.querySelector('input[autocomplete~="username"], input[autocomplete~="email"], input[type="email"]'),r=o.includes("current-password")||o.includes("one-time-code")||s===1&&!!i,l=s>=2?"This form holds more than one password field, the shape of account sign-up or a password change, which 3.3.8 does not cover unless the field takes an existing credential. Confirm whether this field is part of an authentication step at all.":"Nothing here shows the field takes an existing credential (no current-password purpose, and no username or email field beside it), so confirm it is part of signing in before treating this as a failure.",d=r?"this login":"this step";return t&&a?{status:"incomplete",message:`This field has a paste handler containing cancellation code and sets autocomplete="off". Check whether the handler actually blocks pasting, whether a password manager can fill the field, and whether another authentication method is available. Conditional code may leave pasting enabled, and autocomplete="off" does not establish that password-manager entry is blocked.${r?"":` ${l}`}`,fix:'Remove the paste blocking, and drop autocomplete="off" so a password manager can fill the field.'}:t?{status:"incomplete",message:`This field has a paste handler containing cancellation code. Check whether pasting is actually blocked; the code may run only conditionally. Also check whether a password manager can complete ${d}, or whether the page offers another way in such as a passkey or a federated sign-in.${r?"":` ${l}`}`,fix:"Remove the paste blocking, or make sure another way to sign in is available that does not rely on recalling the credential."}:{status:"incomplete",message:`This field sets autocomplete="off", discouraging password managers. Browsers often fill anyway: verify a password manager can complete ${d} without retyping.${r?"":` ${l}`}`}}};var Cn={id:"embed-alt",name:"Embed accessible name",impact:"serious",tags:["wcag2a","wcag111"],help:"<embed> needs an accessible name",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/non-text-content.html",selector:"embed",evaluate(e,{accessibleName:t}){if(t(e))return{status:"pass"};let o=(e.getAttribute("type")??"").trim().toLowerCase(),a=(e.getAttribute("src")??"").split(/[?#]/)[0].toLowerCase();return o.startsWith("text/")||o==="application/pdf"||o==="application/xhtml+xml"||!o&&/\.(html?|xhtml|pdf|txt)$/.test(a)?{status:"incomplete",message:"This <embed> renders a text document but has no accessible name \u2014 assistive technology users get no indication of what the embedded document is. Check it is identified in the surrounding context.",fix:'Add title="\u2026" naming the embedded document.'}:{status:"fail",message:"This <embed> has no accessible name \u2014 screen readers cannot tell users what the embedded content is.",fix:'Add title="\u2026" (or aria-label) describing what the embed shows.'}}};var Sn={id:"canvas-alt",name:"Canvas accessible name",impact:"moderate",tags:["wcag2a","wcag111"],help:"Meaningful <canvas> graphics need an accessible name or fallback",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/non-text-content.html",selector:"canvas:not([role])",evaluate(e,{accessibleName:t}){if(t(e))return{status:"pass"};if([...e.childNodes].filter(s=>!/^(SCRIPT|STYLE|TEMPLATE)$/.test(s.nodeName)).map(s=>s.textContent).join("").trim())return{status:"pass"};let a=e.closest('a[href], button, [role="button"], [role="link"]');if(a&&t(a))return{status:"pass"};let n=e.getBoundingClientRect();return n.width<32||n.height<32?{status:"pass"}:{status:"incomplete",message:"This canvas has no accessible name, no fallback content, and is not marked decorative \u2014 if it draws a chart or diagram, screen reader users get nothing at all.",fix:'If decorative, add aria-hidden="true". If meaningful, add role="img" with aria-label="\u2026", or put a text alternative inside the <canvas> as fallback content.'}}};function $r(e,t){let o=e.getRootNode();if(!o.querySelectorAll)return null;let a=n=>o.getElementById?o.getElementById(n):o.querySelector(`#${CSS.escape(n)}`);for(let n of o.querySelectorAll('button[aria-controls], [role="button"][aria-controls], input[type="button"][aria-controls]'))if(!(n.disabled||!t(n)))for(let s of n.getAttribute("aria-controls").split(/\s+/)){let i=s&&a(s);if(i&&(i===e||i.contains(e)))return n}return null}var Tn={id:"video-loop-motion",name:"Looping video control",impact:"serious",tags:["wcag2a","wcag222"],help:"Looping autoplay video must be pausable",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/pause-stop-hide.html",selector:"video[autoplay][loop]:not([controls])",visibility:"visual",evaluate(e,{isVisible:t}){let o=e.getBoundingClientRect();return o.width<64&&o.height<64?{status:"pass"}:e.paused&&e.readyState>=2?{status:"pass"}:$r(e,t)?{status:"pass"}:{status:"incomplete",message:"This video auto-plays on a loop with no built-in controls: it starts by itself and never ends, so it runs well past the five seconds at which WCAG 2.2.2 requires a way to pause, stop or hide it. Check the page offers a pause control that reaches this video, or that the video is the only content presented.",fix:"Add controls, wire a visible pause button to it, or drop autoplay \u2014 and honour prefers-reduced-motion."}}};var bo=/^(inline-)?(flex|grid)$/;function wo(e){return!(e.disabled||e.tabIndex<0||ce(e))}function yo(e,t){let o=[];for(let a of[...e].sort((n,s)=>n.rect.top-s.rect.top)){let n=o.find(s=>{let i=s[0].rect;return Math.min(i.bottom,a.rect.bottom)-Math.max(i.top,a.rect.top)>Math.min(i.height,a.rect.height)/2});n?n.push(a):o.push([a])}return o.flatMap(a=>a.sort((n,s)=>t?s.rect.right-n.rect.right:n.rect.left-s.rect.left))}var Rn={id:"visual-order-divergence",name:"Focus order vs visual order",impact:"moderate",tags:["wcag2a","wcag243"],help:"CSS reordering should not make Tab jump against the visual order",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/focus-order.html",selector:'a[href], button, input:not([type="hidden"]), select, textarea, summary, [tabindex]',evaluateAll(e){let t=new Map,o=new Map;for(let a of e){if(!wo(a))continue;let n=a.parentElement;n&&(o.has(n)||o.set(n,[]),o.get(n).push(a))}for(let[a,n]of o){if(n.length<2)continue;let s=getComputedStyle(a);if(!bo.test(s.display))continue;let i=/-reverse$/.test(s.flexDirection),r=n.map(h=>({element:h,style:getComputedStyle(h)})).filter(({style:h})=>h.position!=="absolute"&&h.position!=="fixed").map(h=>({...h,rect:h.element.getBoundingClientRect()})).filter(({rect:h})=>h.width>0&&h.height>0);if(r.length<2)continue;let l=r.some(({style:h})=>h.order!=="0");if(!i&&!l||!yo(r,s.direction==="rtl").some((h,f)=>h!==r[f]))continue;let c=i?`flex-direction: ${s.flexDirection}`:"CSS order";t.set(r[0].element,{status:"incomplete",message:`Keyboard focus moves through these ${r.length} controls in DOM order, but ${c} arranges them differently on screen \u2014 Tab will jump against the visual layout. Check the focus sequence still preserves meaning and operability.`,fix:"Reorder the source to match the visual order instead of reordering with CSS, or confirm the divergence is harmless here."})}return e.map(a=>t.get(a)??{status:"pass"})}};var Nn={id:"audio-transcript",name:"Audio transcript",impact:"serious",tags:["wcag2a","wcag121"],help:"Prerecorded audio-only content needs a transcript",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/audio-only-and-video-only-prerecorded.html",selector:"audio",visibleOnly:!1,evaluate(e){return!e.currentSrc&&!e.getAttribute("src")&&!e.querySelector("source")?{status:"pass"}:(e.muted||e.volume===0)&&!e.hasAttribute("controls")?{status:"pass"}:{status:"incomplete",message:"This audio content needs a transcript nearby \u2014 deaf and hard-of-hearing users get nothing from the recording itself. Check that an equivalent text version exists and is easy to find from the player (1.2.1 covers prerecorded audio; a live stream is 1.2.9 instead).",fix:"Provide a transcript of the recording as text on the page or behind a clearly labelled link next to the player."}}};var $n={id:"reading-order-divergence",name:"Reading order vs visual order",impact:"moderate",tags:["wcag2a","wcag132"],help:"CSS reordering should not make reading order diverge from the visual order",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/meaningful-sequence.html",selector:"*",evaluateAll(e){let t=new Map,o=new Map;for(let a of e){let n=a.parentElement;n&&(o.has(n)||o.set(n,[]),o.get(n).push(a))}for(let[a,n]of o){if(n.length<2)continue;let s=getComputedStyle(a);if(!bo.test(s.display))continue;let i=/-reverse$/.test(s.flexDirection),r=n.map(f=>({element:f,style:getComputedStyle(f)})).filter(({style:f})=>f.position!=="absolute"&&f.position!=="fixed").map(f=>({...f,rect:f.element.getBoundingClientRect()})).filter(({rect:f})=>f.width>0&&f.height>0);if(r.length<2)continue;let l=r.some(({style:f})=>f.order!=="0");if(!i&&!l||r.filter(({element:f})=>(f.textContent||"").trim().length>0).length<2||r.every(({element:f})=>f.matches("a[href], button, input, select, textarea, summary, [tabindex]")&&wo(f))||!yo(r,s.direction==="rtl").some((f,m)=>f!==r[m]))continue;let h=i?`flex-direction: ${s.flexDirection}`:"CSS order";t.set(r[0].element,{status:"incomplete",message:`A screen reader reads these ${r.length} blocks in DOM order, but ${h} arranges them differently on screen \u2014 sighted and screen reader users get two different sequences. Check the source order still tells the same story as the layout.`,fix:"Reorder the source to match the visual order instead of reordering with CSS, or confirm the sequence difference does not change meaning here."})}return e.map(a=>t.get(a)??{status:"pass"})}};var In={id:"drag-alternative",name:"Dragging alternative",impact:"moderate",tags:["wcag22aa","wcag257"],help:"Dragging must have a single-pointer alternative",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/dragging-movements.html",selector:'[draggable="true" i]:not(img):not(a[href])',evaluate(){return{status:"incomplete",message:"This element declares itself draggable, and 2.5.7 requires everything achievable by dragging to also work with single clicks or taps \u2014 tremors, switch access and head pointers can press but not drag. Check an equivalent no-drag path exists (buttons to reorder, a menu to move, a field to set the value), unless dragging itself is essential here.",fix:'Add a single-pointer way to do the same thing, e.g. up/down buttons beside a sortable item or a "move to" action in a menu.'}}};var Ir=new Set(["new-password","current-password","one-time-code","on","off"]),En={id:"redundant-entry",name:"Redundant entry",impact:"moderate",tags:["wcag22a","wcag337"],help:"A form should not ask for the same information twice",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/redundant-entry.html",selector:"form",evaluate(e,{isVisible:t}){let o=new Map;for(let a of e.querySelectorAll("input[autocomplete], select[autocomplete], textarea[autocomplete]")){if(a.disabled||a.readOnly||!t(a)||a instanceof HTMLInputElement&&(a.type==="hidden"||a.type==="password"))continue;let n=(a.getAttribute("autocomplete")||"").trim().toLowerCase().replace(/\s+/g," ");if(!(!n||Ir.has(n))){if(o.has(n))return{status:"incomplete",message:`This form asks for "${n}" twice \u2014 3.3.7 says information the user already entered must be auto-populated or selectable, not typed again. A deliberate confirmation field can be essential (the criterion's own escape); that judgement is yours.`,fix:"Auto-populate the second field from the first, offer the earlier value for selection, or drop the duplicate. Keep it only if re-entry is genuinely essential here.",data:{purpose:n}};o.set(n,a)}}return{status:"pass"}}};var Er=new Set(["toggle-popover","show-popover","hide-popover"]),Mr=new Set(["show-modal","close","request-close"]),Mn={id:"invoker-target",name:"Popover and command targets",impact:"serious",tags:["wcag2a","wcag412"],help:"popovertarget and commandfor must point at an element they can act on",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html",selector:"[popovertarget], [commandfor]",evaluate(e){if(e.matches(":disabled")||!e.matches('button, input[type="button"]'))return{status:"pass"};let t=e.getRootNode(),o=n=>n&&t.getElementById?.(n)||null,a=[];if(e.hasAttribute("popovertarget")){let n=e.getAttribute("popovertarget").trim(),s=o(n);s?s.hasAttribute("popover")||a.push(`popovertarget="${n}" points at a <${s.tagName.toLowerCase()}> with no popover attribute, which the button cannot open`):a.push(`popovertarget="${n}" names no element in this document`)}if(e.tagName==="BUTTON"&&e.hasAttribute("commandfor")){let n=e.getAttribute("commandfor").trim(),s=(e.getAttribute("command")??"").trim().toLowerCase(),i=o(n);i?s?Er.has(s)&&!i.hasAttribute("popover")?a.push(`command="${s}" needs a popover, and "${n}" has no popover attribute`):Mr.has(s)&&i.tagName!=="DIALOG"&&a.push(`command="${s}" needs a <dialog>, and "${n}" is a <${i.tagName.toLowerCase()}>`):a.push("commandfor has no command attribute, so activating the button does nothing"):a.push(`commandfor="${n}" names no element in this document`)}return a.length?{status:"fail",message:`${a.join("; ")}. Activating this button does nothing, and the expanded state and control relationship the browser would expose for it are missing.`,fix:"Point the attribute at the id of the popover or dialog it drives (give that element the popover attribute, or make it a <dialog>), and keep the id unique in this tree."}:{status:"pass"}}};var Wr=["transform","translate","rotate","scale","offset-path","offset-distance","offset-rotate","left","right","top","bottom"],Lr=/:(?:hover|focus-visible|focus-within|focus|active)\b/,Or=/:(?:hover|focus-visible|focus-within|focus|active)\b/g,Ur=/\b(?:all|transform|translate|rotate|scale|offset-path|offset-distance|offset-rotate|left|right|top|bottom|inset)\b/;function Dr(e){let t=e.style;if(["offset-path","offset-distance","offset-rotate","rotate","left","right","top","bottom"].some(i=>t.getPropertyValue(i)))return!0;let o=["transform","translate","scale"].map(i=>t.getPropertyValue(i)).join(" ");if(/rotate|skew|matrix|%|em|rem|vw|vh/.test(o)||[...o.matchAll(/(-?\d*\.?\d+)px/g)].map(i=>Math.abs(parseFloat(i[1]))).some(i=>i>=8))return!0;let n=[...o.matchAll(/scale[XYZ3d]*\(([^)]*)\)/gi)].flatMap(i=>i[1].split(",").map(r=>parseFloat(r))),s=t.getPropertyValue("scale").split(/\s+/).map(i=>parseFloat(i)).filter(i=>!Number.isNaN(i));return[...n,...s].some(i=>!Number.isNaN(i)&&(i<.85||i>1.15))}function Fr(e,t){let o=t.style.getPropertyValue("transition-duration")||t.style.getPropertyValue("animation-name");if(o&&o!=="none"&&o!=="0s")return!0;let a=t.selectorText.replace(Or,"").trim();if(!a||/^[,\s]*$/.test(a))return!1;let n;try{n=e.querySelectorAll(a)}catch{return!1}let s=0;for(let i of n){if(s++>=5)break;let r=e.defaultView.getComputedStyle(i);if(r.transitionDuration.split(",").map(d=>parseFloat(d)||0).some(d=>d>0)&&Ur.test(r.transitionProperty))return!0}return!1}function Pr(e){let t={honours:!1,hoverMotion:0,hoverSelectors:[],unreadable:0},o=n=>{for(let s of n){let i=s.media?.mediaText;i&&/prefers-reduced-motion/i.test(i)&&(t.honours=!0),s.selectorText&&Lr.test(s.selectorText)&&s.style&&Wr.some(l=>s.style.getPropertyValue(l))&&Dr(s)&&Fr(e,s)&&(t.hoverMotion+=1,t.hoverSelectors.length<3&&t.hoverSelectors.push(s.selectorText.slice(0,80)));let r=s.cssRules??s.styleSheet?.cssRules;if(r)try{o(r)}catch{t.unreadable+=1}}},a=[...e.styleSheets??[],...e.adoptedStyleSheets??[]];for(let n of a)try{o(n.cssRules)}catch{t.unreadable+=1}return t}function Br(e){if(typeof e.getAnimations!="function")return 0;let t;try{t=e.getAnimations()}catch{return 0}let o=0;for(let a of t){if(!a.timeline||a.timeline===e.timeline)continue;let n;try{n=a.effect?.getKeyframes?.()??[]}catch{continue}lo(n)&&(o+=1)}return o}var Wn={id:"reduced-motion",name:"Motion honours reduced-motion",impact:"moderate",tags:["wcag21aaa","wcag233"],help:"Motion set off by scrolling, hovering or focusing should be switchable off",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/animation-from-interactions.html",selector:"html",visibleOnly:!1,evaluate(e){let t=e.ownerDocument,o=t.defaultView,a=Pr(t);if(a.honours)return{status:"pass"};let n=[],s=Br(t);if(s&&n.push(`${s} scroll-driven animation${s===1?"":"s"} that move${s===1?"s":""} content`),[t.documentElement,t.body].some(l=>l&&o.getComputedStyle(l).scrollBehavior==="smooth")&&n.push("smooth scrolling on in-page navigation (scroll-behavior: smooth)"),a.hoverMotion){let l=a.hoverMotion>a.hoverSelectors.length?", \u2026":"";n.push(`${a.hoverMotion} style rule${a.hoverMotion===1?"":"s"} animating movement on hover or focus (${a.hoverSelectors.join(", ")}${l})`)}if(!n.length)return{status:"pass"};let r=a.unreadable?` (${a.unreadable} stylesheet${a.unreadable===1?"":"s"} could not be read and might carry one)`:"";return{status:"incomplete",message:`This page moves content when people interact with it (${n.join("; ")}), and none of the stylesheets this audit could read honours prefers-reduced-motion${r}. 2.3.3 asks that such motion can be turned off unless it is essential.`,fix:"Put the motion inside @media (prefers-reduced-motion: no-preference), or remove it under @media (prefers-reduced-motion: reduce), keeping only motion that is essential to the function or the information."}}};var Ln=/\blocation\s*(\+?=(?!=)|\.\s*(href\s*\+?=(?!=)|(assign|replace|reload)\s*\())|\.(submit|requestSubmit)\s*\(|window\.open\s*\(/,On={id:"on-input-navigation",name:"Unexpected context change",impact:"serious",tags:["wcag2a","wcag322","wcag321"],help:"Changing or focusing a control must not unexpectedly change context",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/on-input.html",selector:"select[onchange], input[onchange], textarea[onchange], select[oninput], input[oninput], textarea[oninput], [onfocus]",evaluate(e){let t=e.getAttribute("onfocus");if(t&&Ln.test(t))return{status:"incomplete",message:"Focusing this element appears to navigate or submit (its onfocus handler reaches for location/submit). A change of context on focus alone fails WCAG 3.2.1 \u2014 check what the handler actually does when focus lands.",fix:"Trigger navigation from activation (click/Enter), never from focus."};for(let o of["onchange","oninput"]){let a=e.getAttribute(o);if(a&&Ln.test(a))return{status:"incomplete",message:`Changing this control appears to navigate or submit (its ${o} handler reaches for location/submit). WCAG 3.2.2 allows that only when users are told beforehand: check the page says so before the control.`,fix:"Describe the behaviour before the control, or navigate from an explicit Go button instead of the change event."}}return{status:"pass"}}};var Un={id:"error-message-linkage",name:"Error message linkage",impact:"serious",tags:["wcag2a","wcag331"],help:"Fields marked invalid need their error described in text",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/error-identification.html",selector:'[aria-invalid="true"], [aria-invalid="spelling"], [aria-invalid="grammar"], [aria-errormessage]',evaluate(e,{isVisible:t,accessibleName:o}){let a=e.getRootNode(),n=e.getAttribute("aria-invalid"),s=!!n&&n!=="false"&&n!=="undefined",i=l=>(e.getAttribute(l)??"").trim().split(/\s+/).filter(Boolean).map(d=>a.getElementById?.(d)).filter(Boolean),r=l=>l.some(d=>t(d)&&(d.textContent.trim()||o(d)));if(e.hasAttribute("aria-errormessage")){if(!s)return{status:"pass"};let l=i("aria-errormessage");return r(l)?{status:"pass"}:{status:"incomplete",message:(l.length?"This field is marked invalid, but the element its aria-errormessage points at is empty or hidden \u2014 screen readers follow the reference and find no text.":"This field is marked invalid, but its aria-errormessage points at nothing \u2014 screen readers follow the reference and find no text.")+" The error must be described in text: check a visible message exists, and fix the reference so it reaches assistive technology too.",fix:"Point aria-errormessage at the visible element containing the error text, and keep that element populated while the field is invalid."}}return r(i("aria-describedby"))?{status:"pass"}:{status:"incomplete",message:"This field is marked invalid, but no error text is programmatically linked to it. The error must be described to the user in text \u2014 check a message exists, and associate it with aria-describedby or aria-errormessage so screen readers announce it with the field.",fix:"Add the error text near the field and reference it with aria-describedby (or aria-errormessage)."}}};var Gr=new Set(["tab","menuitem","menuitemcheckbox","menuitemradio","option","treeitem"]),Dn={id:"composite-widget-name",name:"Widget item names",impact:"serious",tags:["wcag2a","wcag412"],help:"Tabs, menu items, options and tree items need an accessible name",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html",selector:"[role]",evaluate(e,{accessibleName:t}){let o=P(e);return Gr.has(o)?t(e)?{status:"pass"}:{status:"fail",message:`This ${o} has no accessible name \u2014 a screen reader announces an unnamed ${o}, and users cannot tell what choosing it does.`,fix:'Put text inside the element, or add aria-label="\u2026" for icon-only items.'}:{status:"pass"}}};var Fn={id:"summary-name",name:"Disclosure names",impact:"serious",tags:["wcag2a","wcag412"],help:"Disclosure controls (<summary>) need an accessible name",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/name-role-value.html",selector:"summary",evaluate(e,{accessibleName:t}){let o=e.parentElement;return o?.tagName==="DETAILS"&&o.querySelector(":scope > summary")===e?t(e)?{status:"pass"}:{status:"fail",message:"This disclosure control has no accessible name \u2014 a screen reader announces an unnamed button, and users cannot tell what it expands.",fix:'Put text inside the <summary>, or add aria-label="\u2026" for icon-only disclosures.'}:{status:"pass"}}};var Pn={id:"meta-refresh-no-exceptions",name:"Timed refresh (AAA)",impact:"serious",tags:["wcag2aaa","wcag224","wcag325"],help:"The page must not refresh or redirect itself on any timer (AAA)",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/interruptions.html",selector:'meta[http-equiv="refresh" i]',visibleOnly:!1,evaluate(e){let t=e.getAttribute("content")??"",o=po(t);if(o===null)return{status:"pass"};let a=ho(t)!=="";return o===0&&a?{status:"pass"}:a?{status:"fail",message:`The page redirects itself after ${o}s (failure F40). The reader cannot postpone or suppress the move, which 2.2.4 requires, and the change of context is not requested, which 3.2.5 forbids; the AAA criteria allow no 20-hour exemption. 2.2.4 excuses only an emergency, which the tag cannot show, so this finding assumes there is none.`,fix:'Redirect instantly (content="0; url=\u2026") or on the server, or give the reader a link and let them choose when to move.'}:{status:"fail",message:`The page reloads itself${o>0?` every ${o}s`:" immediately, over and over"} (failure F41). The reader cannot postpone or suppress the reload, which 2.2.4 requires, and it changes the page without being asked, which 3.2.5 forbids. Neither AAA criterion has 2.2.1's 20-hour allowance.`,fix:"Remove the timed refresh and update the content in place, or let the reader request an update with a control."}}};var Bn=go({id:"focus-not-obscured-enhanced",name:"Fully unobscured focus",tags:["wcag22aaa","wcag2412"],help:"No part of a focused element may be hidden behind overlays (AAA)",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/focus-not-obscured-enhanced.html",partial:!0});var Gn={id:"video-audio-description",name:"Video audio description",impact:"serious",tags:["wcag2a","wcag123","wcag125"],help:"Video content needs audio description or a text alternative",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/audio-description-prerecorded.html",selector:"video",visibleOnly:!1,evaluate(e){return e.querySelector('track[kind="descriptions" i]')?{status:"pass"}:!e.currentSrc&&!e.getAttribute("src")&&!e.querySelector("source")?{status:"pass"}:e.muted&&!e.controls?{status:"pass"}:{status:"incomplete",message:"This video has no audio-description track. If it shows something its soundtrack does not say (text on screen, actions, charts, who is speaking), blind and low-vision users miss it. 1.2.5 asks for audio description; at Level A, 1.2.3 is also met by a full text alternative describing the visuals, linked near the player. A talking-head video whose soundtrack already carries everything needs neither, and a video with no soundtrack at all is 1.2.1's question instead: check which this is, and where the description or alternative lives.",fix:'Provide a described audio track or a described version of the video (a <track kind="descriptions"> file works for text-based description), or publish a full transcript that describes the visuals next to the player.'}}};var qr=new Set(["add your heading text here","add a heading","add heading","your heading here","heading here","your title goes here","your title here","title goes here","title here","insert title here","insert heading here","heading text","heading goes here","section title here","placeholder","placeholder text","placeholder heading","label text","your label here","text here","enter text here","your text here","type here","sample heading","sample text","dummy text","dummy heading","todo","tbd","xxx","xxxx","asdf","this is a heading","this is a title","this is the heading","this is a label","new heading","new label","new section"]),zr=new Set(["heading","title","subtitle","headline","label","untitled","header","text","default","section","section title","section heading","page title","field","input"]),Vr=/^(?:heading|title|label|h)\s*[1-6]$/,qn={id:"heading-label-placeholder",name:"Placeholder headings and labels",impact:"moderate",tags:["wcag2aa","wcag246"],help:"Headings and labels must describe their topic or purpose, not be template text",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/headings-and-labels.html",selector:'h1, h2, h3, h4, h5, h6, [role="heading"], label, legend',evaluate(e){let t=e.getAttribute("role");if(/^h[1-6]$/i.test(e.tagName)&&t&&t!=="heading")return{status:"pass"};let o=(e.textContent??"").replace(/\s+/g," ").trim();if(!o)return{status:"pass"};let a=o.toLowerCase().replace(/[\s.:!…-]+$/,""),n=/^h[1-6]$/i.test(e.tagName)||t==="heading"?"heading":"label";return qr.has(a)||a.startsWith("lorem ipsum")||Vr.test(a)?{status:"fail",message:`\u201C${o}\u201D is template text left in a ${n}. It describes nothing, so a screen-reader user scanning by ${n}s, or anyone reading the form, learns nothing from it.`,fix:n==="heading"?"Replace it with words that name what the section is about.":"Replace it with words that name what the field asks for."}:zr.has(a)?{status:"incomplete",message:`\u201C${o}\u201D is a generic ${n}. Check whether it describes the topic of its section or the purpose of its field; the same word can also be a real subject or name.`,fix:n==="heading"?"Name the section's actual topic in the heading.":"Name what the field asks for in the label."}:{status:"pass"}}};var _r=/^(?:block|list-item|table-cell|flow-root)$/;function Hr(e){let t="";for(let o of e.childNodes)(o.nodeType===3||o.nodeType===1&&getComputedStyle(o).display.startsWith("inline"))&&(t+=o.textContent);return t.replace(/\s+/g," ").trim()}var zn={id:"text-justified",name:"Justified text",impact:"moderate",tags:["wcag2aaa","wcag148"],help:"Blocks of text should not be justified to both margins (AAA)",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/visual-presentation.html",selector:"p, li, dd, dt, td, th, blockquote, figcaption, summary, address, div, section, article, main, aside, header, footer",evaluate(e){let t=getComputedStyle(e);return t.textAlign!=="justify"&&t.textAlign!=="justify-all"?{status:"pass"}:_r.test(t.display)?Hr(e).length<120?{status:"pass"}:{status:"incomplete",message:'This block of text is justified to both margins. The uneven spaces between words form "rivers of white" down the page that some readers with dyslexia or low vision cannot read across (failure F88). 1.4.8 allows justified text only where a mechanism lets the reader switch it off; check that one exists, in the page or the browser.',fix:"Set text-align: start (or left) on running text, or offer a control that turns justification off."}:{status:"pass"}}};var nt='h1, h2, h3, h4, h5, h6, [role="heading"]',jr="img, svg, video, audio, canvas, iframe, input, select, textarea, button",Yr="script, style, template, noscript";function Vn(e,t){let o=n=>t?[...n.childNodes].reverse():[...n.childNodes],a=o(e).reverse();for(;a.length;){let n=a.pop();if(n.nodeType===3){if(n.textContent.trim())return!1;continue}if(n.nodeType===1){if(n.matches(nt))return!0;if(!n.matches(Yr)){if(n.matches(jr))return!1;for(let s of o(n).reverse())a.push(s)}}}return!1}var _n={id:"section-heading",name:"Section headings",impact:"moderate",tags:["wcag2aaa","wcag2410"],help:"Sections of written content should begin with a heading (AAA)",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/section-headings.html",selector:"section",evaluate(e){if(e.hasAttribute("aria-label")||e.hasAttribute("aria-labelledby"))return{status:"pass"};let t=e.getAttribute("role");if(t&&t!=="region")return{status:"pass"};if([...e.querySelectorAll(nt)].some(r=>r.closest("section, article")===e)||Vn(e,!1))return{status:"pass"};let a=e.previousElementSibling;if(a&&(a.matches(nt)||a.matches("header, hgroup")&&a.querySelector(nt)||Vn(a,!0)))return{status:"pass"};let n=e.closest("article");if(n&&n.parentElement&&!n.querySelector(nt)){let r=d=>[...d.children].filter(u=>u.matches("article")||u.querySelector(":scope > article")).length,l=n.parentElement;if(r(l)>=3||l.parentElement&&r(l.parentElement)>=3)return{status:"pass"}}let s=(e.textContent??"").replace(/\s+/g," ").trim(),i=e.querySelectorAll("p").length;return s.length<200&&i<2?{status:"pass"}:{status:"incomplete",message:"This section holds written content but begins with no heading of its own, so readers scanning by headings cannot find or skip it. 2.4.10 asks for a heading at the start of each section of writing; check whether this is a section of content that needs one, or a purely structural wrapper.",fix:"Start the section with a heading that names its topic, at the level below its parent heading, or name it with aria-labelledby pointing at its visible title."}}};var Kr='input[type="password"], input[autocomplete~="current-password"], input[autocomplete~="one-time-code"]',Hn={id:"captcha-alternative",name:"CAPTCHA in a login step",impact:"serious",tags:["wcag22aaa","wcag339"],help:"A picture-puzzle CAPTCHA in an authentication step needs an alternative (AAA)",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/accessible-authentication-enhanced.html",selector:'iframe[src*="recaptcha" i], iframe[src*="hcaptcha" i], iframe[src*="turnstile" i], .g-recaptcha, .h-captcha, .cf-turnstile, [data-sitekey]',visibleOnly:!1,evaluate(e){let t=e.closest("form");return!t||!t.querySelector(Kr)?{status:"pass"}:{status:"incomplete",message:"This login form carries a CAPTCHA widget. If the challenge can escalate to a picture puzzle, that is object recognition, which 3.3.8 allows but 3.3.9 (AAA) does not: a cognitive function test in an authentication step then needs another way in (a passkey, an emailed link, a federated sign-in) or a mechanism that helps the user through it. Check what the widget can show and what the alternatives are.",fix:"Use a risk-based or invisible challenge that never shows a puzzle, or offer another authentication method beside it."}}};var st='main, nav, aside, search, form[aria-label], form[aria-labelledby], header:not(:is(article, aside, main, nav, section) header), footer:not(:is(article, aside, main, nav, section) footer), section[aria-label], section[aria-labelledby], [role="main"], [role="navigation"], [role="banner"], [role="contentinfo"], [role="complementary"], [role="region"][aria-label], [role="region"][aria-labelledby], [role="form"][aria-label], [role="form"][aria-labelledby], [role="search"], [role="dialog"], [role="alertdialog"], dialog[open]',jn={id:"region",name:"Content outside landmarks",impact:"moderate",tags:["best-practice"],help:"All readable content belongs inside a landmark region",helpUrl:"https://www.w3.org/WAI/ARIA/apg/practices/landmark-regions/",selector:"body *:not(script):not(style):not(template):not(noscript)",evaluateAll(e,t){return(e[0]?.ownerDocument??document).querySelector(st)?e.map(a=>this.judge(a,t)):e.map(()=>({status:"pass"}))},judge(e,{ownText:t}){let o=e.matches('img:not([alt=""]):not([role="presentation"]):not([role="none"]), svg[role="img"], video, audio, canvas, iframe, input:not([type="hidden"]), select, textarea, button');if(!t(e)&&!o)return{status:"pass"};if(e.closest(st))return{status:"pass"};let a=e.ownerDocument,n=e.closest('a[href*="#"]');if(n){let s=n.getAttribute("href").split("#")[1]??"";try{s=decodeURIComponent(s)}catch{}let i=s&&(a.getElementById(s)||a.getElementsByName(s)[0]),r=/^skip\b/i.test(n.textContent.trim()),l=a.querySelector(st),d=!l||n.compareDocumentPosition(l)&Node.DOCUMENT_POSITION_FOLLOWING;if((i||r)&&d)return{status:"pass"}}for(let s=e.parentElement;s&&s!==a.body;s=s.parentElement)if(t(s))return{status:"pass"};return{status:"fail",message:"This content sits outside any landmark, so screen-reader users navigating by regions never reach it.",fix:"Move it into <main>, <nav>, <header>, <footer>, <aside>, or a labelled <section>."}}};var Yn={id:"region-purpose",name:"Regions with a purpose",impact:"moderate",tags:["wcag21aaa","wcag136"],help:"The purpose of page regions should be programmatically determinable (AAA)",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/identify-purpose.html",selector:"html",visibleOnly:!1,evaluate(e){return e.ownerDocument.querySelector(st)?{status:"pass"}:{status:"incomplete",message:"This page declares no landmark regions (no main, nav, header, footer, aside, search or labelled region), so the purpose of its regions is not exposed to assistive technology or personalisation tools. 1.3.6 (AAA) lists landmarks as the way to identify regions; the purpose of components and icons still needs a person to check.",fix:"Wrap the page's regions in <main>, <nav>, <header>, <footer>, <aside> and labelled <section> elements (or the matching ARIA roles)."}}};var Kn={id:"financial-form-confirmation",name:"Payment form safeguards",impact:"serious",tags:["wcag2aa","wcag334"],help:"A form that takes a payment must be reversible, checked or confirmed before submission",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/error-prevention-legal-financial-data.html",selector:"form",visibleOnly:!1,evaluate(e){return e.querySelector('input[autocomplete*="cc-" i], input[autocomplete~="transaction-amount" i]')?{status:"incomplete",message:"This form collects card details, so submitting it makes a financial transaction. 3.3.4 requires at least one of: the submission can be reversed, the entries are checked for errors with a chance to correct them, or a review-and-confirm step comes before the final submit. Check which applies to this checkout.",fix:"Add a review page before the final submit, validate the entries and let the user correct them, or state a period in which the order can be amended or cancelled."}:{status:"pass"}}};var Xr=new Set(["auto","manipulation"]);function Zr(e){if(!e||Xr.has(e))return!1;let t=e.split(/\s+/);if(t.includes("none"))return!0;let o=t.some(n=>/^pan-(x|left|right)$/.test(n)),a=t.some(n=>/^pan-(y|up|down)$/.test(n));return!o||!a}var Xn={id:"pointer-gesture-alternative",name:"Pointer gesture alternative",impact:"serious",tags:["wcag21a","wcag251"],help:"Swipe, pan and pinch gestures need a single-pointer alternative",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/pointer-gestures.html",selector:"*",visibleOnly:!1,evaluateAll(e,{isRendered:t}){let o=new Set;for(let s of e){let i=s.tagName;if(i==="HTML"||i==="BODY"||i==="SCRIPT"||i==="STYLE"||i==="LINK"||i==="META"||i==="TEMPLATE"||s.getAttribute("draggable")==="true"||s.getAttribute("role")==="slider"||i==="INPUT"&&s.type==="range")continue;let r=s.getBoundingClientRect();if(r.width<100||r.height<60||!t(s))continue;let l=getComputedStyle(s).touchAction;Zr(l)&&o.add(s)}let a=new Set,n=new Set;for(let s of o){let i=!1;for(let r=s.parentElement;r;r=r.parentElement)if(o.has(r)){i=!0;break}i||n.has(s.parentElement)||(n.add(s.parentElement),a.add(s))}return e.map(s=>{if(!a.has(s))return{status:"pass"};let i=getComputedStyle(s).touchAction,r=i.split(/\s+/),l=r.includes("none")?"every touch gesture":[!r.some(d=>/^pan-(x|left|right)$/.test(d))&&"horizontal swipes",!r.some(d=>/^pan-(y|up|down)$/.test(d))&&"vertical swipes"].filter(Boolean).join(" and ");return{status:"incomplete",message:`touch-action: ${i} tells the browser to hand ${l} on this element to the page's own script, which is how custom swipe, pan and pinch interactions are built. 2.5.1 requires whatever those gestures do to also work with a single tap or click (previous and next buttons, zoom in and out, a choose-a-value control), unless the gesture is essential. Check a single-pointer way exists for everything the gesture does.`,fix:"Add plain buttons for the same actions (previous/next, zoom in/out), or make the element operable by simple clicks as well as gestures."}})}};var xo=e=>e.hasAttribute("aria-level")?parseInt(e.getAttribute("aria-level"),10):parseInt(e.tagName[1],10)||2,Jr=e=>{let t=P(e);return t==="heading"||t===null},Zn={id:"heading-order",name:"Heading order",impact:"moderate",tags:["best-practice"],help:"Headings should step down one level at a time",helpUrl:"https://www.w3.org/WAI/tutorials/page-structure/headings/",selector:'h1, h2, h3, h4, h5, h6, [role="heading"]',evaluateAll(e){let t=0;return e.map(o=>{if(!Jr(o))return{status:"pass"};let a=xo(o),s=t>0&&a>t+1?{status:"fail",message:`Heading level jumps from h${t} to h${a}, which breaks the page outline for screen-reader navigation.`,fix:`Use <h${t+1}> here, or restructure so levels increase one at a time.`}:{status:"pass"};return t=a,s})}};var Jn={id:"empty-heading",name:"Empty headings",impact:"minor",tags:["best-practice"],help:"Headings must contain text",helpUrl:"https://www.w3.org/WAI/tutorials/page-structure/headings/",selector:'h1, h2, h3, h4, h5, h6, [role="heading"]',evaluate(e,{accessibleName:t}){let o=e.getAttribute("role");return o&&o!=="heading"?{status:"pass"}:t(e)?{status:"pass"}:{status:"fail",message:"This heading is empty \u2014 screen-reader users navigating by headings land on nothing.",fix:"Add text to the heading, or remove the element if it is only used for spacing."}}};var Qn={id:"positive-tabindex",name:"Positive tabindex",impact:"serious",tags:["best-practice"],help:"Positive tabindex values disrupt the natural focus order",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/focus-order.html",selector:"[tabindex]",evaluate(e){let t=parseInt(e.getAttribute("tabindex"),10);return t>0?{status:"fail",message:`tabindex="${t}" overrides the natural focus order, which almost always creates a confusing keyboard path.`,fix:'Use tabindex="0" and place the element where it belongs in the document order instead.'}:{status:"pass"}}};var es={id:"landmark-one-main",name:"One main landmark",impact:"moderate",tags:["best-practice"],help:"The page should have exactly one main landmark",helpUrl:"https://www.w3.org/WAI/ARIA/apg/practices/landmark-regions/",selector:"html",visibleOnly:!1,evaluate(e,{isVisible:t}){let o=xe(e.ownerDocument).flatMap(a=>[...a.querySelectorAll('main, [role="main"]')]).filter(t).length;return o===1?{status:"pass"}:{status:"fail",message:o===0?"No <main> landmark \u2014 screen-reader users have no shortcut to the primary content.":`${o} main landmarks \u2014 "skip to main" becomes ambiguous.`,fix:o===0?"Wrap the primary content in a single <main> element.":"Keep one <main>; demote the others to <section> or <div>."}}};var Qr='h1, h2, h3, h4, h5, h6, [role="heading"]',ts={id:"page-heading-one",name:"Leading page heading",impact:"moderate",tags:["best-practice"],help:"Every page should start its outline with an <h1>",helpUrl:"https://www.w3.org/WAI/tutorials/page-structure/headings/",selector:"html",visibleOnly:!1,evaluate(e){return xe(e.ownerDocument).some(o=>[...o.querySelectorAll(Qr)].some(a=>xo(a)===1))?{status:"pass"}:{status:"fail",message:"No <h1> \u2014 the page outline has no starting point for screen-reader navigation.",fix:"Add one <h1> naming what the page is about."}}};var os=new Set(["banner","contentinfo","main"]),el=e=>e.getAttribute("role")?.trim().split(/\s+/)[0]?.toLowerCase()??ae(e),tl=e=>ue(e)||e.getAttribute("aria-label")?.trim()||e.getAttribute("title")?.trim()||"",as={id:"landmark-unique",name:"Distinguishable landmarks",impact:"moderate",tags:["best-practice"],help:"Landmarks of the same type need distinguishing labels",helpUrl:"https://www.w3.org/WAI/ARIA/apg/practices/landmark-regions/",selector:'nav, search, aside, header, footer, section[aria-label], section[aria-labelledby], form[aria-label], form[aria-labelledby], [role="navigation"], [role="complementary"], [role="banner"], [role="contentinfo"], [role="region"][aria-label], [role="region"][aria-labelledby], [role="form"][aria-label], [role="form"][aria-labelledby], [role="search"], [role="main"], main',evaluateAll(e){let t=e.map(el),o=e.map(()=>({status:"pass"})),a=e.map((s,i)=>({element:s,index:i,role:t[i]})).filter(({role:s})=>Ue.has(s));for(let s of os){let i=a.filter(({role:r})=>r===s);if(!(i.length<2))for(let{index:r}of i)o[r]={status:"fail",message:`${i.length} ${s} landmarks on one page \u2014 ${s} must be unique; screen-reader region navigation becomes ambiguous.`,fix:`Keep one ${s}; demote the others (remove the role, or use a non-landmark element).`}}let n={};for(let{element:s,index:i,role:r}of a){if(os.has(r))continue;let l=`${r}::${tl(s).toLowerCase()}`;(n[l]??=[]).push(i)}for(let[s,i]of Object.entries(n)){if(i.length<2)continue;let[r,l]=s.split("::");for(let d of i)o[d]={status:"fail",message:l?`${i.length} ${r} landmarks share the label "${l}" \u2014 screen-reader users can't tell them apart.`:`${i.length} unlabelled ${r} landmarks \u2014 screen-reader users hear "${r}" twice with no way to tell them apart.`,fix:'Give each one a distinct aria-label, e.g. aria-label="Primary" / aria-label="Footer".'}}return o}};var ol=new Set(["ul","ol","li","button","nav","main","aside","form","table","article","img","hr","progress","textarea","dialog","option","h1","h2","h3","h4","h5","h6","tr","thead","tbody","tfoot","td","fieldset","a","input"]),al=new Set(["checkbox","radio","button","submit","reset","text","email","tel","url","range","number","search"]);function nl(e){let t=e.tagName.toLowerCase();if(!ol.has(t)||t==="input"&&!al.has(e.type))return null;let o=ae(e);return o&&o!=="generic"&&o!=="presentation"?o:null}var ns={table:["table","inline-table"],thead:["table-header-group"],tbody:["table-row-group"],tfoot:["table-footer-group"],tr:["table-row"],td:["table-cell"]},sl=new Set(["table","rowgroup","row","cell"]);function il(e,t){let o=t==="table"?e:e.closest("table");if(o&&!ns.table.includes(getComputedStyle(o).display))return!0;let a=ns[t];return!!a&&!a.includes(getComputedStyle(e).display)}function ss(e){if(getComputedStyle(e).listStyleType==="none")return!0;let t=getComputedStyle(e,"::marker").content;return t==="none"||t==='""'||t==="''"}function rl(e){if(getComputedStyle(e).listStyleType==="none")return!0;for(let t of e.children)if(t.tagName==="LI"&&ss(t))return!0;return!1}var is={id:"redundant-role",name:"Redundant roles",impact:"minor",tags:["best-practice"],help:"role attributes should not repeat the element\u2019s built-in role",helpUrl:"https://www.w3.org/TR/using-aria/#firstrule",selector:"[role]",evaluate(e){let t=e.getAttribute("role").trim().split(/\s+/)[0]?.toLowerCase(),o=nl(e);if(!o||t!==o)return{status:"pass"};let a=e.tagName.toLowerCase();if(t==="list"&&rl(e))return{status:"pass"};if(t==="listitem"){if(ss(e))return{status:"pass"};let s=e.closest("ul, ol");if(s&&getComputedStyle(s).listStyleType==="none")return{status:"pass"}}return sl.has(t)&&il(e,a)?{status:"pass"}:t==="img"&&/\.svg([?#]|$)/i.test(e.currentSrc||e.src||"")?{status:"pass"}:{status:"fail",message:`role="${t}" is redundant: <${a}> already has that role built in. Redundant ARIA adds noise and drift risk, not accessibility.${o==="list"?" (Exception: keep it if you set list-style: none \u2014 Safari/VoiceOver drops list semantics without it.)":""}`,fix:`Remove role="${t}" from the <${a}>.`}}};var ll=[{aria:"aria-required",native:"required"},{aria:"aria-disabled",native:"disabled"},{aria:"aria-readonly",native:"readonly"},{aria:"aria-placeholder",native:"placeholder"},{aria:"aria-checked",native:"checked"}],rs={id:"redundant-aria",name:"Redundant ARIA attributes",impact:"minor",tags:["best-practice"],help:"aria attributes should not duplicate native HTML attributes",helpUrl:"https://www.w3.org/TR/using-aria/#rule2",selector:'[aria-required], [aria-disabled], [aria-readonly], [aria-placeholder], [aria-checked], [aria-hidden="false"]',evaluate(e){let t=ll.filter(({aria:o,native:a})=>e.hasAttribute(o)&&e.hasAttribute(a)).map(({aria:o,native:a})=>`${o} duplicates ${a}`);return e.getAttribute("aria-hidden")==="false"&&t.push('aria-hidden="false" does nothing reliable \u2014 elements are visible to AT by default'),t.length?{status:"fail",message:`Redundant ARIA: ${t.join("; ")}. The native attribute already tells assistive technology everything.`,fix:"Remove the aria-* attribute(s) and keep the native HTML attribute."}:{status:"pass"}}};var cl=new Set(["button","link","menuitem","menuitemcheckbox","menuitemradio","option","tab","treeitem","checkbox","radio","switch","heading","cell","gridcell","columnheader","rowheader","tooltip"]),ls=new Set(["none","normal",'""',"''"]);function ul(e){let t=[e,...e.querySelectorAll("*")];for(let o of t){let a=o.tagName.toLowerCase();if(a==="img"||a==="area"||a==="svg"||o!==e&&(o.getAttribute("aria-hidden")==="true"||o.hasAttribute("hidden")))return!0;let n=getComputedStyle(o);if(o!==e&&(n.display==="none"||n.visibility==="hidden")||!ls.has(getComputedStyle(o,"::before").content)||!ls.has(getComputedStyle(o,"::after").content))return!0}return!1}var cs={id:"redundant-aria-label",name:"Redundant aria-label",impact:"minor",tags:["best-practice"],help:"aria-label should not repeat the visible text",helpUrl:"https://www.w3.org/TR/using-aria/#rule2",selector:"[aria-label]",evaluate(e){if(!cl.has(P(e)))return{status:"pass"};let t=e.getAttribute("aria-label").replace(/\s+/g," ").trim().toLowerCase(),o=e.textContent.replace(/\s+/g," ").trim().toLowerCase();return!o||t!==o?{status:"pass"}:ul(e)?{status:"pass"}:{status:"fail",message:`aria-label="${e.getAttribute("aria-label")}" is identical to the element's visible text \u2014 it adds nothing and will drift out of sync when the text changes.`,fix:"Remove the aria-label and let the visible text be the accessible name."}}};var us=/^(?:(?:image|icon)s?(?:\s*[:-]\s*|\s+(?:of|showing|depicting)\b\s*|\s*$)|(?:picture|graphic)s?\s+of\b\s*)/i,ds={id:"redundant-alt-phrase",name:"Redundant alt phrasing",impact:"minor",tags:["best-practice"],help:'alt text should not start with "image of" or similar',helpUrl:"https://www.w3.org/WAI/tutorials/images/tips/",selector:"img[alt]",evaluate(e){let t=e.getAttribute("alt").trim();return!t||!us.test(t)?{status:"pass"}:{status:"fail",message:`alt="${t}" \u2014 screen readers already announce this element as an image, so users hear "image, ${t}".`,fix:`Describe the content directly, e.g. alt="${t.replace(us,"").trim()||"\u2026"}".`}}};var hs={id:"redundant-tabindex",name:"Redundant tabindex",impact:"minor",tags:["best-practice"],help:'tabindex="0" is unnecessary on natively focusable elements',helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/focus-order.html",selector:'button[tabindex="0"], a[href][tabindex="0"], input[tabindex="0"], select[tabindex="0"], textarea[tabindex="0"], summary[tabindex="0"]',evaluate(e){return{status:"fail",message:`<${e.tagName.toLowerCase()}> is focusable by default \u2014 tabindex="0" adds nothing.`,fix:"Remove the tabindex attribute."}}};var dl=new Set(["script","style","noscript","template"]);function fs(e){let t="";for(let o of e.childNodes){if(o.nodeType===Node.TEXT_NODE){t+=o.textContent;continue}if(o.nodeType!==Node.ELEMENT_NODE)continue;let a=o.tagName.toLowerCase();if(dl.has(a)||a==="img"||a==="area"||a==="svg"||o.getAttribute("aria-hidden")==="true"||o.hasAttribute("hidden"))continue;let n=getComputedStyle(o);n.display==="none"||n.visibility==="hidden"||(t+=fs(o))}return t}var ps=e=>(e??"").replace(/\s+/g," ").trim().toLowerCase(),ms={id:"redundant-image-alt",name:"Redundant image alt",impact:"minor",tags:["best-practice"],help:"Image alt should not repeat adjacent link or button text",helpUrl:"https://www.w3.org/WAI/tutorials/images/functional/",selector:"a[href] img[alt], button img[alt], a[href] img[title]:not([alt]), button img[title]:not([alt])",evaluate(e){let t=e.getAttribute("alt"),o=t===null,a=ps(o?e.getAttribute("title"):t);if(!a)return{status:"pass"};let n=e.closest("a[href], button"),s=ps(fs(n));if(!s)return{status:"pass"};if(a!==s)return{status:"pass"};let i=n.tagName==="A"?"link":"button";return{status:"fail",message:o?`The image title repeats the ${i} text \u2014 the title names the image, so screen readers announce "${e.getAttribute("title")}" twice.`:`The image alt repeats the ${i} text \u2014 screen readers announce "${e.getAttribute("alt")}" twice.`,fix:o?'Add alt="" to the image (and drop the title if it is not needed as a tooltip); the visible text already names the control.':'Use alt="" on the image; the visible text already names the control.'}}};var hl=e=>e.hasAttribute("aria-label")||e.hasAttribute("aria-labelledby")||e.hasAttribute("title");function pl(e){for(let t=e.parentElement;t;t=t.parentElement){let o=t.getAttribute("role")?.trim().split(/\s+/)[0]?.toLowerCase(),a=o??ae(t);if(!(!o&&(a==="form"||a==="region")&&!hl(t))&&a&&Ue.has(a))return{element:t,role:a}}return null}var gs={id:"landmark-top-level",name:"Top-level landmarks",impact:"moderate",tags:["best-practice"],help:"banner, main, contentinfo and complementary landmarks must be top level",helpUrl:"https://www.w3.org/WAI/ARIA/apg/practices/landmark-regions/",selector:'header, footer, main, aside, [role="banner"], [role="contentinfo"], [role="main"], [role="complementary"]',evaluate(e){let t=e.tagName.toLowerCase();if((t==="header"||t==="footer")&&!e.hasAttribute("role")&&e.closest("article, aside, main, nav, section"))return{status:"pass"};if(t==="aside"&&!e.hasAttribute("role")&&ae(e)!=="complementary")return{status:"pass"};let o=pl(e);return o?{status:"fail",message:`This ${e.getAttribute("role")??{header:"banner",footer:"contentinfo",main:"main",aside:"complementary"}[t]} landmark is nested inside a ${o.role} landmark (<${o.element.tagName.toLowerCase()}>) \u2014 page-level regions lose their meaning when nested.`,fix:"Move it to be a direct child of <body>, or remove the landmark role."}:{status:"pass"}}};var bs={id:"accesskeys",name:"Duplicate access keys",impact:"serious",tags:["best-practice"],help:"The same accesskey must not be assigned twice",helpUrl:"https://www.w3.org/WAI/WCAG22/Understanding/character-key-shortcuts.html",selector:"[accesskey]",visibleOnly:!1,evaluateAll(e){let t={};e.forEach((a,n)=>{let s=a.getAttribute("accesskey").trim().toLowerCase();(t[s]??=[]).push(n)});let o=e.map(()=>({status:"pass"}));for(let[a,n]of Object.entries(t))if(!(n.length<2))for(let s of n)o[s]={status:"fail",message:`accesskey="${a}" is used ${n.length} times \u2014 the browser can only honour one, so the others silently do nothing.`,fix:"Give each accesskey a unique value, or remove them (they conflict with AT shortcuts anyway)."};return o}};function fl(e){return e.querySelector('button, input[type="submit"], input[type="image"]')}var ws={id:"button-type",name:"Button types in forms",impact:"minor",tags:["best-practice"],help:"Buttons inside forms should declare their type",helpUrl:"https://html.spec.whatwg.org/multipage/form-elements.html#attr-button-type",selector:'form button:not([type]), form button[type=""]',evaluate(e){let t=e.form??e.closest("form"),o=t.querySelectorAll("button");return o.length===1&&o[0]===e&&fl(t)===e?{status:"pass"}:{status:"fail",message:"A <button> without a type inside a form is a submit button by default (the HTML missing value default is the Submit Button state), so activating it submits the form. Declare the type so the intent is explicit.",fix:'Add type="button" (or type="submit" if submission is intended).'}}};var ml='dialog, [role="dialog"], [role="alertdialog"], [popover]',ys={id:"no-autofocus",name:"Autofocus on load",impact:"minor",tags:["best-practice"],help:"autofocus disorients assistive-technology users",helpUrl:"https://html.spec.whatwg.org/multipage/interaction.html#the-autofocus-attribute",selector:"[autofocus]",visibleOnly:!1,evaluate(e){if(e.closest(ml))return{status:"pass"};let t=e.tagName.toLowerCase();return{status:"incomplete",message:`autofocus moves focus to this <${t}> as soon as the page loads, so screen-reader and magnifier users skip everything before it. Review: the HTML spec allows this only when the control is the page's main purpose (a search box on a search page, say); otherwise it disorients.`,fix:`Remove autofocus from the <${t}> unless this control is the page's whole purpose; let users reach it in document order.`}}};var gl=/new (window|tab)|opens? in/i;function bl(e){return e.closest("[lang]")?.getAttribute("lang")?.trim()||e.ownerDocument.documentElement.getAttribute("lang")?.trim()||""}function wl(e){let t=e.getAttribute("aria-describedby");if(!t)return"";let o=e.getRootNode();return t.split(/\s+/).filter(Boolean).map(a=>o.getElementById?.(a)?.textContent??"").join(" ")}var xs={id:"new-window-link",name:"New-window warnings",impact:"minor",tags:["best-practice"],help:"Links opening a new window should say so",helpUrl:"https://www.w3.org/WAI/WCAG22/Techniques/general/G201",selector:'a[target="_blank"], a[target="blank"]',evaluate(e,{accessibleName:t}){let o=`${t(e)} ${e.getAttribute("title")??""} ${wl(e)}`;if(gl.test(o))return{status:"pass"};let a=bl(e);return a&&!/^en(?:[-_]|$)/i.test(a)?{status:"incomplete",message:`This link opens a new window or tab. Does its name, title or description say so in the page's language ("${a}")? The automated wording check reads English only.`,fix:'Say so in the link text or a visually hidden span (for example the local-language equivalent of "opens in new window"), or drop target="_blank".'}:{status:"fail",message:"This link opens a new window/tab without saying so \u2014 the back button stops working and screen-reader users get no warning about the context change.",fix:'Append visually-hidden text like <span class="sr-only">(opens in new window)</span>, or drop target="_blank".'}}};var vs={id:"fieldset-legend",name:"Grouped field labels",impact:"moderate",tags:["best-practice"],help:"Radio and checkbox groups should be grouped with a label",helpUrl:"https://www.w3.org/WAI/tutorials/forms/grouping/",selector:'input[type="radio"][name], input[type="checkbox"][name]',evaluateAll(e){let t=new Map;e.forEach((a,n)=>{let s=a.form??a.getRootNode();t.has(s)||t.set(s,new Map);let i=t.get(s),r=`${a.type}::${a.name}`;i.has(r)||i.set(r,[]),i.get(r).push(n)});let o=e.map(()=>({status:"pass"}));for(let a of[...t.values()].flatMap(n=>[...n.values()])){if(a.length<2)continue;let n=e[a[0]],s=n.closest('fieldset, [role="group"], [role="radiogroup"]'),i=s?.querySelector(":scope > legend");s&&a.every(l=>s.contains(e[l]))&&(i&&dt(i)||ue(s)||s.getAttribute("aria-label")?.trim())||(o[a[0]]={status:"fail",message:`This group of ${a.length} ${n.type} inputs (name="${n.name}") has no group label \u2014 screen-reader users hear each option without knowing what question it answers.`,fix:'Wrap the group in <fieldset> with a <legend>, or role="radiogroup"/"group" with an aria-label.'})}return o}};function As(e){let t=e.tags.find(a=>/^wcag\d{3,4}$/.test(a));if(!t)return[9,9,99];let o=t.slice(4);return[+o[0],+o[1],+o.slice(2)]}var ks=[So,To,Ro,No,Wo,Lo,Oo,Do,Fo,Po,Bo,qo,zo,fa,ma,ba,ya,va,ka,Sa,Ta,Wa,La,Oa,Ua,Da,Fa,Pa,qa,za,_a,Ha,ja,Ya,Ka,Xa,Za,Ja,Qa,en,nn,sn,ln,cn,dn,hn,mn,gn,bn,yn,xn,vn,An,kn,Cn,Sn,Tn,Rn,Nn,$n,In,En,Mn,Wn,On,Un,Dn,Fn,Pn,Bn,Gn,qn,zn,_n,Hn,Yn,Kn,Xn,pn,fn,Zn,Jn,Qn,jn,es,ts,as,is,rs,cs,ds,hs,ms,gs,bs,ws,ys,xs,vs].sort((e,t)=>{let o=As(e),a=As(t);return o[0]-a[0]||o[1]-a[1]||o[2]-a[2]||e.id.localeCompare(t.id)});var S=(e,t,o,a,n="2.0")=>({num:e,name:t,level:o,automation:a,since:n,principle:{1:"Perceivable",2:"Operable",3:"Understandable",4:"Robust"}[e[0]],url:`https://www.w3.org/WAI/WCAG22/Understanding/${t.toLowerCase().replace(/[(),]/g,"").replace(/\s+/g,"-")}.html`}),Cs=[S("1.1.1","Non-text Content","A","partial"),S("1.2.1","Audio-only and Video-only (Prerecorded)","A","partial"),S("1.2.2","Captions (Prerecorded)","A","partial"),S("1.2.3","Audio Description or Media Alternative (Prerecorded)","A","partial"),S("1.2.4","Captions (Live)","AA","manual"),S("1.2.5","Audio Description (Prerecorded)","AA","partial"),S("1.2.6","Sign Language (Prerecorded)","AAA","manual"),S("1.2.7","Extended Audio Description (Prerecorded)","AAA","manual"),S("1.2.8","Media Alternative (Prerecorded)","AAA","manual"),S("1.2.9","Audio-only (Live)","AAA","manual"),S("1.3.1","Info and Relationships","A","partial"),S("1.3.2","Meaningful Sequence","A","partial"),S("1.3.3","Sensory Characteristics","A","manual"),S("1.3.4","Orientation","AA","partial","2.1"),S("1.3.5","Identify Input Purpose","AA","partial","2.1"),S("1.3.6","Identify Purpose","AAA","partial","2.1"),S("1.4.1","Use of Color","A","partial"),S("1.4.2","Audio Control","A","partial"),S("1.4.3","Contrast (Minimum)","AA","partial"),S("1.4.4","Resize Text","AA","partial"),S("1.4.5","Images of Text","AA","manual"),S("1.4.6","Contrast (Enhanced)","AAA","partial"),S("1.4.7","Low or No Background Audio","AAA","manual"),S("1.4.8","Visual Presentation","AAA","partial"),S("1.4.9","Images of Text (No Exception)","AAA","manual"),S("1.4.10","Reflow","AA","partial","2.1"),S("1.4.11","Non-text Contrast","AA","partial","2.1"),S("1.4.12","Text Spacing","AA","partial","2.1"),S("1.4.13","Content on Hover or Focus","AA","manual","2.1"),S("2.1.1","Keyboard","A","partial"),S("2.1.2","No Keyboard Trap","A","manual"),S("2.1.3","Keyboard (No Exception)","AAA","partial"),S("2.1.4","Character Key Shortcuts","A","manual","2.1"),S("2.2.1","Timing Adjustable","A","partial"),S("2.2.2","Pause, Stop, Hide","A","partial"),S("2.2.3","No Timing","AAA","manual"),S("2.2.4","Interruptions","AAA","partial"),S("2.2.5","Re-authenticating","AAA","manual"),S("2.2.6","Timeouts","AAA","manual","2.1"),S("2.3.1","Three Flashes or Below Threshold","A","manual"),S("2.3.2","Three Flashes","AAA","manual"),S("2.3.3","Animation from Interactions","AAA","partial","2.1"),S("2.4.1","Bypass Blocks","A","partial"),S("2.4.2","Page Titled","A","partial"),S("2.4.3","Focus Order","A","partial"),S("2.4.4","Link Purpose (In Context)","A","partial"),S("2.4.5","Multiple Ways","AA","manual"),S("2.4.6","Headings and Labels","AA","partial"),S("2.4.7","Focus Visible","AA","partial"),S("2.4.8","Location","AAA","manual"),S("2.4.9","Link Purpose (Link Only)","AAA","partial"),S("2.4.10","Section Headings","AAA","partial"),S("2.4.11","Focus Not Obscured (Minimum)","AA","partial","2.2"),S("2.4.12","Focus Not Obscured (Enhanced)","AAA","partial","2.2"),S("2.4.13","Focus Appearance","AAA","manual","2.2"),S("2.5.1","Pointer Gestures","A","partial","2.1"),S("2.5.2","Pointer Cancellation","A","manual","2.1"),S("2.5.3","Label in Name","A","manual","2.1"),S("2.5.4","Motion Actuation","A","manual","2.1"),S("2.5.5","Target Size (Enhanced)","AAA","partial","2.1"),S("2.5.6","Concurrent Input Mechanisms","AAA","manual","2.1"),S("2.5.7","Dragging Movements","AA","partial","2.2"),S("2.5.8","Target Size (Minimum)","AA","partial","2.2"),S("3.1.1","Language of Page","A","partial"),S("3.1.2","Language of Parts","AA","partial"),S("3.1.3","Unusual Words","AAA","manual"),S("3.1.4","Abbreviations","AAA","manual"),S("3.1.5","Reading Level","AAA","manual"),S("3.1.6","Pronunciation","AAA","manual"),S("3.2.1","On Focus","A","partial"),S("3.2.2","On Input","A","partial"),S("3.2.3","Consistent Navigation","AA","manual"),S("3.2.4","Consistent Identification","AA","manual"),S("3.2.5","Change on Request","AAA","partial"),S("3.2.6","Consistent Help","A","manual","2.2"),S("3.3.1","Error Identification","A","partial"),S("3.3.2","Labels or Instructions","A","partial"),S("3.3.3","Error Suggestion","AA","manual"),S("3.3.4","Error Prevention (Legal, Financial, Data)","AA","partial"),S("3.3.5","Help","AAA","manual"),S("3.3.6","Error Prevention (All)","AAA","manual"),S("3.3.7","Redundant Entry","A","partial","2.2"),S("3.3.8","Accessible Authentication (Minimum)","AA","partial","2.2"),S("3.3.9","Accessible Authentication (Enhanced)","AAA","partial","2.2"),S("4.1.2","Name, Role, Value","A","partial"),S("4.1.3","Status Messages","AA","manual","2.1")];var Rs=Rt.engine.name,Ns=Rt.engine.version,yl={isVisible:It,isRendered:ct,cssPath:Mt,htmlSnippet:Wt,ownText:Lt,accessibleName:dt};function xl(e,t){return t?.length?e.tags.some(o=>t.includes(o)):!0}function vl(e){if(!e?.length)return{version:"2.2",level:"AAA"};let t=e.filter(n=>/^wcag(2|21|22)(a|aa|aaa)$/.test(n));if(!t.length)return null;let o=t.some(n=>n.startsWith("wcag22"))?"2.2":t.some(n=>n.startsWith("wcag21"))?"2.1":"2.0",a=t.some(n=>/aaa$/.test(n))?"AAA":t.some(n=>/aa$/.test(n))?"AA":"A";return{version:o,level:a}}var Ss={"2.0":0,"2.1":1,"2.2":2},Ts={A:0,AA:1,AAA:2};function Al(e){let t=vl(e);return t?Cs.filter(o=>o.automation!=="auto").filter(o=>Ss[o.since]<=Ss[t.version]).filter(o=>Ts[o.level]<=Ts[t.level]).map(({num:o,name:a,level:n,principle:s,url:i,automation:r})=>({num:o,name:a,level:n,principle:s,url:i,automation:r})):[]}function kl(e,t){let o=e;for(;o;){if(o.closest?.(t))return!0;o=o.getRootNode()?.host??null}return!1}function Cl(e,t){let o={target:[Mt(e)],html:Wt(e),failureSummary:[t.message,t.fix&&`Fix: ${t.fix}`].filter(Boolean).join(`
`)};return t.data&&(o.data=t.data),o}async function Sl(e=document,t={},o){let a=performance.now(),n={testEngine:{name:Rs,version:Ns},timestamp:new Date().toISOString(),url:e.location?.href??e.ownerDocument?.location?.href??"",violations:[],passes:[],incomplete:[],inapplicable:[],manualReview:Al(t.tags),ruleTimings:[]},s=ks.filter(x=>!x.disabled&&xl(x,t.tags));Ko(),Co();let i=xe(e.querySelectorAll?e:document),r=null,l=(x,I)=>[...x.nodeType===1&&x.matches(I)?[x]:[],...x.querySelectorAll(I)],d=x=>x==="*"?(r??=i.flatMap(I=>l(I,"*")),r):i.flatMap(I=>l(I,x)),u=0,c={critical:0,serious:0,moderate:0,minor:0,review:0},h={critical:0,serious:0,moderate:0,minor:0,review:0},f=performance.now(),m=typeof MessageChannel=="function"?new MessageChannel:null,y=()=>new Promise(x=>{if(!m){setTimeout(x,0);return}m.port1.onmessage=x,m.port2.postMessage(0)}),g=async x=>{performance.now()-f<16||(x?.(),await y(),f=performance.now())},w=()=>{if(t.signal?.aborted)throw new DOMException("Audit stopped","AbortError")},b={...yl,yieldToMain:async()=>{w(),await g(),w()}};try{for(let x of s){if(t.signal?.aborted)throw new DOMException("Audit stopped","AbortError");await g(),o?.({done:u,total:s.length,rule:x.id,running:!0});let I=performance.now(),O=d(x.selector);t.exclude&&(O=O.filter(N=>!kl(N,t.exclude))),x.visibleOnly!==!1&&(O=O.filter(x.visibility==="visual"?ct:It));let F;if(x.evaluateAll)F=await x.evaluateAll(O,b);else{F=new Array(O.length);for(let N=0;N<O.length;N++){if((N&31)===0&&N>0){if(t.signal?.aborted)throw new DOMException("Audit stopped","AbortError");await g(()=>o?.({done:u+N/O.length,total:s.length,rule:x.id,running:!0}))}F[N]=await x.evaluate(O[N],b)}}let E={fail:[],incomplete:[]},q=0,B=0;for(let N=0;N<O.length;N++){(N&127)===0&&await b.yieldToMain();let V=O[N],_=F[N].status;_==="pass"?q+=1:_==="skipped"?B+=1:E[_]?.push(Cl(V,F[N]))}let k={id:x.id,...B?{skippedCount:B}:{},name:x.name??x.id,impact:x.impact,tags:x.tags,help:x.help,description:x.help,helpUrl:x.helpUrl};O.length||n.inapplicable.push({...k,nodes:[]}),E.fail.length&&n.violations.push({...k,nodes:E.fail}),E.incomplete.length&&n.incomplete.push({...k,nodes:E.incomplete}),q&&n.passes.push({...k,nodes:[],nodeCount:q}),c[x.impact]=(c[x.impact]??0)+E.fail.length,c.review+=E.incomplete.length,E.fail.length&&(h[x.impact]=(h[x.impact]??0)+1),E.incomplete.length&&(h.review+=1);let U=Math.round((performance.now()-I)*10)/10;n.ruleTimings.push({rule:x.id,ms:U,elements:O.length,...B?{skippedCount:B}:{}}),B&&(n.skippedChecks=(n.skippedChecks??0)+B),o?.({done:++u,total:s.length,rule:x.id,ms:U,counts:{...c},typeCounts:{...h},...E.fail.length||E.incomplete.length?{findings:{...E.fail.length?{violation:{...k,nodes:E.fail}}:{},...E.incomplete.length?{incomplete:{...k,nodes:E.incomplete}}:{}}}:{}})}return n.durationMs=Math.round(performance.now()-a),n}finally{Et(),m?.port1.close(),m?.port2.close()}}return Ls(Tl);})();