@yuktishaalaa/yuktai 5.2.0 → 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- "use strict";var YuktAI=(()=>{var T=Object.defineProperty;var le=Object.getOwnPropertyDescriptor;var ce=Object.getOwnPropertyNames;var ue=Object.prototype.hasOwnProperty;var de=(e,t)=>{for(var a in t)T(e,a,{get:t[a],enumerable:!0})},fe=(e,t,a,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of ce(t))!ue.call(e,i)&&i!==a&&T(e,i,{get:()=>t[i],enumerable:!(r=le(t,i))||r.enumerable});return e};var pe=e=>fe(T({},"__esModule",{value:!0}),e);var Be={};de(Be,{wcagPlugin:()=>qe});function O(){let e=window;return e.Rewriter||e.ai?.rewriter||null}async function S(){try{let e=O();if(!e)return!1;if(typeof e.availability=="function"){let t=await e.availability();return t==="readily"||t==="available"||t==="downloadable"}return typeof e.capabilities=="function"?(await e.capabilities())?.available!=="no":typeof e.create=="function"}catch{return!1}}async function me(e){if(!e||e.trim().length<20)return{success:!1,original:e,rewritten:e,error:"Text too short"};try{let t=O();if(!t)throw new Error("Rewriter API not available");let a=await t.create({tone:"more-casual",format:"plain-text",length:"as-is",outputLanguage:"en"}),r=await a.rewrite(e,{context:"Rewrite this text in simple plain English. Use short sentences. Avoid jargon. Make it easy to understand for everyone."});return a.destroy(),{success:!0,original:e,rewritten:r.trim()}}catch(t){return{success:!1,original:e,rewritten:e,error:t instanceof Error?t.message:"Rewrite failed"}}}async function q(){if(!await S())return{fixed:0,error:"Chrome Built-in AI Rewriter not available. Enable via chrome://flags."};let t=document.querySelectorAll("p, h1, h2, h3, h4, h5, h6, li, blockquote, td, th, label, figcaption"),a=0;for(let r of t){let i=r.innerText?.trim();if(!i||i.length<20||r.closest("[data-yuktai-panel]"))continue;let o=await me(i);o.success&&o.rewritten!==i&&(r.dataset.yuktaiOriginal=i,r.innerText=o.rewritten,a++)}return{fixed:a}}function B(){let e=document.querySelectorAll("[data-yuktai-original]");for(let t of e){let a=t.dataset.yuktaiOriginal;a&&(t.innerText=a,delete t.dataset.yuktaiOriginal)}}var D="yuktai-summary-box";function N(){let e=window;return e.Summarizer||e.ai?.summarizer||null}async function L(){try{let e=N();if(!e)return!1;if(typeof e.availability=="function"){let t=await e.availability();return t==="readily"||t==="available"||t==="downloadable"}return typeof e.capabilities=="function"?(await e.capabilities())?.available!=="no":typeof e.create=="function"}catch{return!1}}function be(){let e=document.querySelectorAll("p, h1, h2, h3, h4, h5, h6, li, blockquote, article, section"),t=[];for(let a of e){if(a.closest("[data-yuktai-panel]"))continue;let r=window.getComputedStyle(a);if(r.display==="none"||r.visibility==="hidden")continue;let i=a.innerText?.trim();i&&i.length>10&&t.push(i)}return t.join(" ").slice(0,5e3)}async function F(){if(!await L())return{success:!1,summary:"",error:"Chrome Built-in AI Summarizer not available. Enable via chrome://flags."};let t=be();if(!t||t.length<100)return{success:!1,summary:"",error:"Not enough text on this page to summarise."};try{let a=N();if(!a)throw new Error("Summarizer API not available");let r=await a.create({type:"tl;dr",format:"plain-text",length:"short",outputLanguage:"en"}),i=await r.summarize(t,{context:"Summarise this page in 2-3 simple sentences for a screen reader user who wants to know if this page is relevant to them."});return r.destroy(),ye(i.trim()),{success:!0,summary:i.trim()}}catch(a){return{success:!1,summary:"",error:a instanceof Error?a.message:"Summary failed"}}}function ye(e){h();let t=document.createElement("div");t.id=D,t.setAttribute("data-yuktai-panel","true"),t.setAttribute("role","region"),t.setAttribute("aria-label","Page summary by yuktai"),t.style.cssText=`
1
+ "use strict";var YuktAI=(()=>{var L=Object.defineProperty;var fe=Object.getOwnPropertyDescriptor;var pe=Object.getOwnPropertyNames;var me=Object.prototype.hasOwnProperty;var be=(e,t)=>{for(var a in t)L(e,a,{get:t[a],enumerable:!0})},ye=(e,t,a,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of pe(t))!me.call(e,i)&&i!==a&&L(e,i,{get:()=>t[i],enumerable:!(r=fe(t,i))||r.enumerable});return e};var ge=e=>ye(L({},"__esModule",{value:!0}),e);var Ve={};be(Ve,{wcagPlugin:()=>Fe});function N(){let e=window;return e.Rewriter||e.ai?.rewriter||null}async function M(){try{let e=N();if(!e)return!1;if(typeof e.availability=="function"){let t=await e.availability();return t==="readily"||t==="available"||t==="downloadable"}return typeof e.capabilities=="function"?(await e.capabilities())?.available!=="no":typeof e.create=="function"}catch{return!1}}async function he(e){if(!e||e.trim().length<20)return{success:!1,original:e,rewritten:e,error:"Text too short"};try{let t=N();if(!t)throw new Error("Rewriter API not available");let a=await t.create({tone:"more-casual",format:"plain-text",length:"as-is",outputLanguage:"en"}),r=await a.rewrite(e,{context:"Rewrite this text in simple plain English. Use short sentences. Avoid jargon. Make it easy to understand for everyone."});return a.destroy(),{success:!0,original:e,rewritten:r.trim()}}catch(t){return{success:!1,original:e,rewritten:e,error:t instanceof Error?t.message:"Rewrite failed"}}}async function D(){if(!await M())return{fixed:0,error:"Chrome Built-in AI Rewriter not available. Enable via chrome://flags."};let t=document.querySelectorAll("p, h1, h2, h3, h4, h5, h6, li, blockquote, td, th, label, figcaption"),a=0;for(let r of t){let i=r.innerText?.trim();if(!i||i.length<20||r.closest("[data-yuktai-panel]"))continue;let s=await he(i);s.success&&s.rewritten!==i&&(r.dataset.yuktaiOriginal=i,r.innerText=s.rewritten,a++)}return{fixed:a}}function F(){let e=document.querySelectorAll("[data-yuktai-original]");for(let t of e){let a=t.dataset.yuktaiOriginal;a&&(t.innerText=a,delete t.dataset.yuktaiOriginal)}}var V="yuktai-summary-box";function _(){let e=window;return e.Summarizer||e.ai?.summarizer||null}async function C(){try{let e=_();if(!e)return!1;if(typeof e.availability=="function"){let t=await e.availability();return t==="readily"||t==="available"||t==="downloadable"}return typeof e.capabilities=="function"?(await e.capabilities())?.available!=="no":typeof e.create=="function"}catch{return!1}}function xe(){let e=document.querySelectorAll("p, h1, h2, h3, h4, h5, h6, li, blockquote, article, section"),t=[];for(let a of e){if(a.closest("[data-yuktai-panel]"))continue;let r=window.getComputedStyle(a);if(r.display==="none"||r.visibility==="hidden")continue;let i=a.innerText?.trim();i&&i.length>10&&t.push(i)}return t.join(" ").slice(0,5e3)}async function G(){if(!await C())return{success:!1,summary:"",error:"Chrome Built-in AI Summarizer not available. Enable via chrome://flags."};let t=xe();if(!t||t.length<100)return{success:!1,summary:"",error:"Not enough text on this page to summarise."};try{let a=_();if(!a)throw new Error("Summarizer API not available");let r=await a.create({type:"tl;dr",format:"plain-text",length:"short",outputLanguage:"en"}),i=await r.summarize(t,{context:"Summarise this page in 2-3 simple sentences for a screen reader user who wants to know if this page is relevant to them."});return r.destroy(),we(i.trim()),{success:!0,summary:i.trim()}}catch(a){return{success:!1,summary:"",error:a instanceof Error?a.message:"Summary failed"}}}function we(e){w();let t=document.createElement("div");t.id=V,t.setAttribute("data-yuktai-panel","true"),t.setAttribute("role","region"),t.setAttribute("aria-label","Page summary by yuktai"),t.style.cssText=`
2
2
  position: fixed;
3
3
  top: 0;
4
4
  left: 0;
@@ -19,7 +19,7 @@
19
19
  background: none; border: none; color: #ffffff;
20
20
  font-size: 20px; cursor: pointer; padding: 0 4px;
21
21
  line-height: 1; flex-shrink: 0;
22
- `,r.addEventListener("click",h),t.appendChild(a),t.appendChild(r),document.body.prepend(t)}function h(){let e=document.getElementById(D);e&&e.remove()}var V=[{code:"en",label:"English"},{code:"hi",label:"Hindi"},{code:"es",label:"Spanish"},{code:"fr",label:"French"},{code:"de",label:"German"},{code:"it",label:"Italian"},{code:"pt",label:"Portuguese"},{code:"nl",label:"Dutch"},{code:"pl",label:"Polish"},{code:"ru",label:"Russian"},{code:"ja",label:"Japanese"},{code:"ko",label:"Korean"},{code:"zh",label:"Chinese"},{code:"ar",label:"Arabic"},{code:"tr",label:"Turkish"},{code:"vi",label:"Vietnamese"},{code:"bn",label:"Bengali"},{code:"id",label:"Indonesian"}],x="en";function ge(){let e=window;return e.Translator||e.translation||null}async function he(e){try{let t=window;if(!ge())return!1;if(t.Translator&&typeof t.Translator.availability=="function")try{let r=await t.Translator.availability({sourceLanguage:"en",targetLanguage:e});return r==="readily"||r==="available"||r==="downloadable"||r==="after-download"}catch{}return t.Translator&&typeof t.Translator.canTranslate=="function"?await t.Translator.canTranslate({sourceLanguage:"en",targetLanguage:e})!=="no":t.translation&&typeof t.translation.canTranslate=="function"?await t.translation.canTranslate({sourceLanguage:"en",targetLanguage:e})!=="no":!1}catch{return!1}}async function xe(e){let t=window,a={sourceLanguage:"en",targetLanguage:e};if(t.Translator&&typeof t.Translator.create=="function")return await t.Translator.create(a);if(t.translation&&typeof t.translation.createTranslator=="function")return await t.translation.createTranslator(a);throw new Error("Translation API not available")}async function _(e){if(e===x)return{success:!0,language:e,fixed:0};if(e==="en")return M(),x="en",{success:!0,language:"en",fixed:0};if(!await he(e))return{success:!1,language:e,fixed:0,error:`Translation to ${e} not available. Enable via chrome://flags.`};try{let a=await xe(e),r=document.querySelectorAll("p, h1, h2, h3, h4, h5, h6, li, blockquote, td, th, label, figcaption, span, a"),i=0;for(let o of r){if(o.closest("[data-yuktai-panel]")||o.children.length>0)continue;let n=o.innerText?.trim();if(!n||n.length<2)continue;o.dataset.yuktaiTranslationOriginal||(o.dataset.yuktaiTranslationOriginal=n);let s=await a.translate(n);s&&s!==n&&(o.innerText=s,i++)}return typeof a.destroy=="function"&&a.destroy(),x=e,{success:!0,language:e,fixed:i}}catch(a){return{success:!1,language:e,fixed:0,error:a instanceof Error?a.message:"Translation failed"}}}function M(){let e=document.querySelectorAll("[data-yuktai-translation-original]");for(let t of e){let a=t.dataset.yuktaiTranslationOriginal;a&&(t.innerText=a,delete t.dataset.yuktaiTranslationOriginal)}x="en"}var we=[{phrases:["go to main","skip to main","main content"],action:"focus-main",label:"Jump to main content"},{phrases:["go to navigation","go to nav","open menu"],action:"focus-nav",label:"Jump to navigation"},{phrases:["go to search","search","find"],action:"focus-search",label:"Jump to search"},{phrases:["scroll down","page down","next"],action:"scroll-down",label:"Scroll down"},{phrases:["scroll up","page up","back up"],action:"scroll-up",label:"Scroll up"},{phrases:["go back","previous page"],action:"go-back",label:"Go back"},{phrases:["click","press","select"],action:"click-focused",label:"Click focused element"},{phrases:["next item","tab forward","tab"],action:"tab-forward",label:"Move to next element"},{phrases:["previous item","tab back","shift tab"],action:"tab-back",label:"Move to previous element"},{phrases:["stop listening","stop voice","quiet"],action:"stop-voice",label:"Stop voice control"}],f=null,w=!1,m=null;function C(){return!!(window.SpeechRecognition||window.webkitSpeechRecognition)}function ve(e){let t=e.toLowerCase().trim();for(let a of we)for(let r of a.phrases)if(t.includes(r))return{action:a.action,label:a.label};return null}function ke(e){switch(e){case"focus-main":{let t=document.querySelector("main, [role='main'], #main");t&&(t.focus(),t.scrollIntoView({behavior:"smooth"}));break}case"focus-nav":{let t=document.querySelector("nav, [role='navigation']");t&&(t.focus(),t.scrollIntoView({behavior:"smooth"}));break}case"focus-search":{let t=document.querySelector("input[type='search'], input[role='searchbox'], [aria-label*='search' i]");t&&(t.focus(),t.scrollIntoView({behavior:"smooth"}));break}case"scroll-down":{window.scrollBy({top:400,behavior:"smooth"});break}case"scroll-up":{window.scrollBy({top:-400,behavior:"smooth"});break}case"go-back":{window.history.back();break}case"click-focused":{let t=document.activeElement;t&&t!==document.body&&t.click();break}case"tab-forward":{let t=G(),a=t.indexOf(document.activeElement),r=t[a+1]||t[0];r&&r.focus();break}case"tab-back":{let t=G(),a=t.indexOf(document.activeElement),r=t[a-1]||t[t.length-1];r&&r.focus();break}case"stop-voice":{P();break}}}function G(){return Array.from(document.querySelectorAll('a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])')).filter(e=>!e.closest("[data-yuktai-panel]"))}function W(e){if(!C())return!1;if(w)return!0;e&&(m=e);let t=window.SpeechRecognition||window.webkitSpeechRecognition;return f=new t,f.continuous=!0,f.interimResults=!1,f.lang="en-US",f.onresult=a=>{let r=a.results[a.results.length-1][0].transcript,i=ve(r);if(i){ke(i.action);let o={success:!0,command:r,action:i.label};if(m&&m(o),i.action==="stop-voice")return}},f.onend=()=>{w&&f?.start()},f.onerror=a=>{a.error!=="no-speech"&&m&&m({success:!1,command:"",action:"",error:`Voice error: ${a.error}`})},f.start(),w=!0,Ae(),!0}function P(){w=!1,f&&(f.stop(),f=null),m=null,K()}var j="yuktai-voice-indicator";function Ae(){K();let e=document.createElement("div");e.id=j,e.setAttribute("data-yuktai-panel","true"),e.setAttribute("aria-live","polite"),e.setAttribute("aria-label","yuktai voice control is listening"),e.style.cssText=`
22
+ `,r.addEventListener("click",w),t.appendChild(a),t.appendChild(r),document.body.prepend(t)}function w(){let e=document.getElementById(V);e&&e.remove()}var W=[{code:"en",label:"English"},{code:"hi",label:"Hindi"},{code:"es",label:"Spanish"},{code:"fr",label:"French"},{code:"de",label:"German"},{code:"it",label:"Italian"},{code:"pt",label:"Portuguese"},{code:"nl",label:"Dutch"},{code:"pl",label:"Polish"},{code:"ru",label:"Russian"},{code:"ja",label:"Japanese"},{code:"ko",label:"Korean"},{code:"zh",label:"Chinese"},{code:"ar",label:"Arabic"},{code:"tr",label:"Turkish"},{code:"vi",label:"Vietnamese"},{code:"bn",label:"Bengali"},{code:"id",label:"Indonesian"}],v="en";function ve(){let e=window;return e.Translator||e.translation||null}async function ke(e){try{let t=window;if(!ve())return!1;if(t.Translator&&typeof t.Translator.availability=="function")try{let r=await t.Translator.availability({sourceLanguage:"en",targetLanguage:e});return r==="readily"||r==="available"||r==="downloadable"||r==="after-download"}catch{}return t.Translator&&typeof t.Translator.canTranslate=="function"?await t.Translator.canTranslate({sourceLanguage:"en",targetLanguage:e})!=="no":t.translation&&typeof t.translation.canTranslate=="function"?await t.translation.canTranslate({sourceLanguage:"en",targetLanguage:e})!=="no":!1}catch{return!1}}async function Ae(e){let t=window,a={sourceLanguage:"en",targetLanguage:e};if(t.Translator&&typeof t.Translator.create=="function")return await t.Translator.create(a);if(t.translation&&typeof t.translation.createTranslator=="function")return await t.translation.createTranslator(a);throw new Error("Translation API not available")}async function j(e){if(e===v)return{success:!0,language:e,fixed:0};if(e==="en")return P(),v="en",{success:!0,language:"en",fixed:0};if(!await ke(e))return{success:!1,language:e,fixed:0,error:`Translation to ${e} not available. Enable via chrome://flags.`};try{let a=await Ae(e),r=document.querySelectorAll("p, h1, h2, h3, h4, h5, h6, li, blockquote, td, th, label, figcaption, span, a"),i=0;for(let s of r){if(s.closest("[data-yuktai-panel]")||s.children.length>0)continue;let n=s.innerText?.trim();if(!n||n.length<2)continue;s.dataset.yuktaiTranslationOriginal||(s.dataset.yuktaiTranslationOriginal=n);let o=await a.translate(n);o&&o!==n&&(s.innerText=o,i++)}return typeof a.destroy=="function"&&a.destroy(),v=e,{success:!0,language:e,fixed:i}}catch(a){return{success:!1,language:e,fixed:0,error:a instanceof Error?a.message:"Translation failed"}}}function P(){let e=document.querySelectorAll("[data-yuktai-translation-original]");for(let t of e){let a=t.dataset.yuktaiTranslationOriginal;a&&(t.innerText=a,delete t.dataset.yuktaiTranslationOriginal)}v="en"}var Ee=[{phrases:["go to main","skip to main","main content"],action:"focus-main",label:"Jump to main content"},{phrases:["go to navigation","go to nav","open menu"],action:"focus-nav",label:"Jump to navigation"},{phrases:["go to search","search","find"],action:"focus-search",label:"Jump to search"},{phrases:["scroll down","page down","next"],action:"scroll-down",label:"Scroll down"},{phrases:["scroll up","page up","back up"],action:"scroll-up",label:"Scroll up"},{phrases:["go back","previous page"],action:"go-back",label:"Go back"},{phrases:["click","press","select"],action:"click-focused",label:"Click focused element"},{phrases:["next item","tab forward","tab"],action:"tab-forward",label:"Move to next element"},{phrases:["previous item","tab back","shift tab"],action:"tab-back",label:"Move to previous element"},{phrases:["stop listening","stop voice","quiet"],action:"stop-voice",label:"Stop voice control"}],f=null,k=!1,m=null;function H(){return!!(window.SpeechRecognition||window.webkitSpeechRecognition)}function Te(e){let t=e.toLowerCase().trim();for(let a of Ee)for(let r of a.phrases)if(t.includes(r))return{action:a.action,label:a.label};return null}function Se(e){switch(e){case"focus-main":{let t=document.querySelector("main, [role='main'], #main");t&&(t.focus(),t.scrollIntoView({behavior:"smooth"}));break}case"focus-nav":{let t=document.querySelector("nav, [role='navigation']");t&&(t.focus(),t.scrollIntoView({behavior:"smooth"}));break}case"focus-search":{let t=document.querySelector("input[type='search'], input[role='searchbox'], [aria-label*='search' i]");t&&(t.focus(),t.scrollIntoView({behavior:"smooth"}));break}case"scroll-down":{window.scrollBy({top:400,behavior:"smooth"});break}case"scroll-up":{window.scrollBy({top:-400,behavior:"smooth"});break}case"go-back":{window.history.back();break}case"click-focused":{let t=document.activeElement;t&&t!==document.body&&t.click();break}case"tab-forward":{let t=K(),a=t.indexOf(document.activeElement),r=t[a+1]||t[0];r&&r.focus();break}case"tab-back":{let t=K(),a=t.indexOf(document.activeElement),r=t[a-1]||t[t.length-1];r&&r.focus();break}case"stop-voice":{$();break}}}function K(){return Array.from(document.querySelectorAll('a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])')).filter(e=>!e.closest("[data-yuktai-panel]"))}function U(e){if(!H())return!1;if(k)return!0;e&&(m=e);let t=window.SpeechRecognition||window.webkitSpeechRecognition;return f=new t,f.continuous=!0,f.interimResults=!1,f.lang="en-US",f.onresult=a=>{let r=a.results[a.results.length-1][0].transcript,i=Te(r);if(i){Se(i.action);let s={success:!0,command:r,action:i.label};if(m&&m(s),i.action==="stop-voice")return}},f.onend=()=>{k&&f?.start()},f.onerror=a=>{a.error!=="no-speech"&&m&&m({success:!1,command:"",action:"",error:`Voice error: ${a.error}`})},f.start(),k=!0,Le(),!0}function $(){k=!1,f&&(f.stop(),f=null),m=null,J()}var Y="yuktai-voice-indicator";function Le(){J();let e=document.createElement("div");e.id=Y,e.setAttribute("data-yuktai-panel","true"),e.setAttribute("aria-live","polite"),e.setAttribute("aria-label","yuktai voice control is listening"),e.style.cssText=`
23
23
  position: fixed;
24
24
  bottom: 80px;
25
25
  left: 50%;
@@ -49,7 +49,7 @@
49
49
  0%, 100% { opacity: 1; transform: scale(1); }
50
50
  50% { opacity: 0.4; transform: scale(0.7); }
51
51
  }
52
- `,document.head.appendChild(r)}let a=document.createElement("span");a.textContent="Listening for commands...",e.appendChild(t),e.appendChild(a),document.body.appendChild(e)}function K(){let e=document.getElementById(j);e&&e.remove()}var Ee=["button:not([aria-label]):not([aria-labelledby])","a:not([aria-label]):not([aria-labelledby])","input:not([aria-label]):not([aria-labelledby]):not([id])","select:not([aria-label]):not([aria-labelledby])","textarea:not([aria-label]):not([aria-labelledby])","[role='button']:not([aria-label])","[role='link']:not([aria-label])","[role='checkbox']:not([aria-label])","[role='tab']:not([aria-label])"].join(", ");function U(){let e=window;return e.Writer||e.ai?.writer||null}async function $(){try{let e=U();if(!e)return!1;if(typeof e.availability=="function"){let t=await e.availability();return t==="readily"||t==="available"||t==="downloadable"}return typeof e.capabilities=="function"?(await e.capabilities())?.available!=="no":typeof e.create=="function"}catch{return!1}}function Te(e){let t=[],a=e.innerText?.trim();a&&t.push(`element text: "${a}"`);let r=e.placeholder?.trim();r&&t.push(`placeholder: "${r}"`);let i=e.getAttribute("name")?.trim();i&&t.push(`name: "${i}"`);let o=e.getAttribute("type")?.trim();o&&t.push(`type: "${o}"`);let n=e.id;if(n){let c=document.querySelector(`label[for="${n}"]`);c&&t.push(`label: "${c.innerText?.trim()}"`)}let s=e.parentElement?.innerText?.trim().slice(0,60);s&&t.push(`parent context: "${s}"`),t.push(`tag: ${e.tagName.toLowerCase()}`);let d=e.getAttribute("role");return d&&t.push(`role: ${d}`),t.join(". ")}async function Se(e,t){let a=`
52
+ `,document.head.appendChild(r)}let a=document.createElement("span");a.textContent="Listening for commands...",e.appendChild(t),e.appendChild(a),document.body.appendChild(e)}function J(){let e=document.getElementById(Y);e&&e.remove()}var Me=["button:not([aria-label]):not([aria-labelledby])","a:not([aria-label]):not([aria-labelledby])","input:not([aria-label]):not([aria-labelledby]):not([id])","select:not([aria-label]):not([aria-labelledby])","textarea:not([aria-label]):not([aria-labelledby])","[role='button']:not([aria-label])","[role='link']:not([aria-label])","[role='checkbox']:not([aria-label])","[role='tab']:not([aria-label])"].join(", ");function X(){let e=window;return e.Writer||e.ai?.writer||null}async function R(){try{let e=X();if(!e)return!1;if(typeof e.availability=="function"){let t=await e.availability();return t==="readily"||t==="available"||t==="downloadable"}return typeof e.capabilities=="function"?(await e.capabilities())?.available!=="no":typeof e.create=="function"}catch{return!1}}function Ce(e){let t=[],a=e.innerText?.trim();a&&t.push(`element text: "${a}"`);let r=e.placeholder?.trim();r&&t.push(`placeholder: "${r}"`);let i=e.getAttribute("name")?.trim();i&&t.push(`name: "${i}"`);let s=e.getAttribute("type")?.trim();s&&t.push(`type: "${s}"`);let n=e.id;if(n){let d=document.querySelector(`label[for="${n}"]`);d&&t.push(`label: "${d.innerText?.trim()}"`)}let o=e.parentElement?.innerText?.trim().slice(0,60);o&&t.push(`parent context: "${o}"`),t.push(`tag: ${e.tagName.toLowerCase()}`);let p=e.getAttribute("role");return p&&t.push(`role: ${p}`),t.join(". ")}async function Pe(e,t){let a=`
53
53
  Generate a short, clear aria-label for an HTML element.
54
54
  The label must be 2-6 words maximum.
55
55
  The label must describe what the element does or what it is.
@@ -60,7 +60,7 @@
60
60
  ${t}
61
61
 
62
62
  Output only the label. Nothing else.
63
- `.trim();return(await e.write(a)).trim().replace(/^["']|["']$/g,"").replace(/\.$/,"").trim()}async function Y(){if(!await $())return{success:!1,fixed:0,elements:[],error:"Chrome Built-in AI Writer not available. Enable via chrome://flags."};let t=document.querySelectorAll(Ee);if(t.length===0)return{success:!0,fixed:0,elements:[]};try{let a=U();if(!a)throw new Error("Writer API not available");let r=await a.create({tone:"neutral",format:"plain-text",length:"short",outputLanguage:"en"}),i=0,o=[];for(let n of t){if(n.closest("[data-yuktai-panel]"))continue;let s=window.getComputedStyle(n);if(s.display==="none"||s.visibility==="hidden")continue;let d=Te(n),c=await Se(r,d);c&&c.length>0&&(n.dataset.yuktaiLabelOriginal=n.getAttribute("aria-label")||"",n.setAttribute("aria-label",c),i++,o.push({tag:n.tagName.toLowerCase(),label:c}))}return r.destroy(),{success:!0,fixed:i,elements:o}}catch(a){return{success:!1,fixed:0,elements:[],error:a instanceof Error?a.message:"Label generation failed"}}}function J(){let e=document.querySelectorAll("[data-yuktai-label-original]");for(let t of e){let a=t.dataset.yuktaiLabelOriginal;a?t.setAttribute("aria-label",a):t.removeAttribute("aria-label"),delete t.dataset.yuktaiLabelOriginal}}var A=null,X=null;var Q=null,H=null,u=null,b=null,v=null,R=null,y=null,k={deuteranopia:"yuktai-cb-d",protanopia:"yuktai-cb-p",tritanopia:"yuktai-cb-t"};var Z=new Set(["input","select","textarea"]);var z={nav:"navigation",header:"banner",footer:"contentinfo",main:"main",aside:"complementary"};function I(e,t="polite"){if(typeof window>"u"||!y?.speechEnabled||!window.speechSynthesis)return;window.speechSynthesis.cancel();let a=new SpeechSynthesisUtterance(e);a.rate=1,a.pitch=1,a.volume=1;let r=window.speechSynthesis.getVoices();r.length>0&&(a.voice=r[0]),window.speechSynthesis.speak(a)}function oe(e,t="info"){if(typeof document>"u")return;let r={success:{bg:"#0f9d58",border:"#0a7a44",icon:"\u2713"},error:{bg:"#d93025",border:"#b52a1c",icon:"\u2715"},warning:{bg:"#f29900",border:"#c67c00",icon:"\u26A0"},info:{bg:"#1a73e8",border:"#1557b0",icon:"\u2139"}}[t];u||(u=document.createElement("div"),u.setAttribute("role","alert"),u.setAttribute("aria-live","assertive"),u.setAttribute("aria-atomic","true"),u.style.cssText=`
63
+ `.trim();return(await e.write(a)).trim().replace(/^["']|["']$/g,"").replace(/\.$/,"").trim()}async function Q(){if(!await R())return{success:!1,fixed:0,elements:[],error:"Chrome Built-in AI Writer not available. Enable via chrome://flags."};let t=document.querySelectorAll(Me);if(t.length===0)return{success:!0,fixed:0,elements:[]};try{let a=X();if(!a)throw new Error("Writer API not available");let r=await a.create({tone:"neutral",format:"plain-text",length:"short",outputLanguage:"en"}),i=0,s=[];for(let n of t){if(n.closest("[data-yuktai-panel]"))continue;let o=window.getComputedStyle(n);if(o.display==="none"||o.visibility==="hidden")continue;let p=Ce(n),d=await Pe(r,p);d&&d.length>0&&(n.dataset.yuktaiLabelOriginal=n.getAttribute("aria-label")||"",n.setAttribute("aria-label",d),i++,s.push({tag:n.tagName.toLowerCase(),label:d}))}return r.destroy(),{success:!0,fixed:i,elements:s}}catch(a){return{success:!1,fixed:0,elements:[],error:a instanceof Error?a.message:"Label generation failed"}}}function Z(){let e=document.querySelectorAll("[data-yuktai-label-original]");for(let t of e){let a=t.dataset.yuktaiLabelOriginal;a?t.setAttribute("aria-label",a):t.removeAttribute("aria-label"),delete t.dataset.yuktaiLabelOriginal}}var T=null,ee=null;var te=null,z=null,u=null,b=null,A=null,I=null,y=null,E={deuteranopia:"yuktai-cb-d",protanopia:"yuktai-cb-p",tritanopia:"yuktai-cb-t"};var ae=new Set(["input","select","textarea"]);var O={nav:"navigation",header:"banner",footer:"contentinfo",main:"main",aside:"complementary"};function q(e,t="polite"){if(typeof window>"u"||!y?.speechEnabled||!window.speechSynthesis)return;window.speechSynthesis.cancel();let a=new SpeechSynthesisUtterance(e);a.rate=1,a.pitch=1,a.volume=1;let r=window.speechSynthesis.getVoices();r.length>0&&(a.voice=r[0]),window.speechSynthesis.speak(a)}function ue(e,t="info"){if(typeof document>"u")return;let r={success:{bg:"#0a7a44",border:"#075e34",icon:"\u2713"},error:{bg:"#b52a1c",border:"#8f2116",icon:"\u2715"},warning:{bg:"#a35f00",border:"#7a4700",icon:"\u26A0"},info:{bg:"#1557b0",border:"#0f4287",icon:"\u2139"}}[t];u||(u=document.createElement("div"),u.setAttribute("role","alert"),u.setAttribute("aria-live","assertive"),u.setAttribute("aria-atomic","true"),u.style.cssText=`
64
64
  position: fixed;
65
65
  top: 80px;
66
66
  right: 16px;
@@ -86,7 +86,7 @@
86
86
  onclick="this.parentElement.style.transform='translateX(120%)';this.parentElement.style.opacity='0'"
87
87
  style="background:none;border:none;color:#fff;cursor:pointer;font-size:18px;padding:0;line-height:1"
88
88
  aria-label="Close notification">\xD7</button>
89
- `,window.innerWidth<=480&&(u.style.right="8px",u.style.left="8px",u.style.maxWidth="none",u.style.width="auto"),requestAnimationFrame(()=>{u&&(u.style.transform="translateX(0)",u.style.opacity="1")}),setTimeout(()=>{u&&(u.style.transform="translateX(120%)",u.style.opacity="0")},5e3)}function l(e,t="info",a=!0){A&&(A.textContent=e),oe(e,t),a&&I(e,t==="error"?"assertive":"polite")}function Le(){if(typeof document>"u"||Q)return;let e=[{label:"Skip to main content",selector:"main,[role='main'],#main,#main-content"},{label:"Skip to navigation",selector:"nav,[role='navigation'],#nav,#navigation"},{label:"Skip to search",selector:"[role='search'],#search,input[type='search']"}],t=document.createElement("div");t.setAttribute("data-yuktai-skip-bar","true"),t.setAttribute("role","navigation"),t.setAttribute("aria-label","Skip links"),t.style.cssText=`
89
+ `,window.innerWidth<=480&&(u.style.right="8px",u.style.left="8px",u.style.maxWidth="none",u.style.width="auto"),requestAnimationFrame(()=>{u&&(u.style.transform="translateX(0)",u.style.opacity="1")}),setTimeout(()=>{u&&(u.style.transform="translateX(120%)",u.style.opacity="0")},5e3)}function l(e,t="info",a=!0){T&&(T.textContent=e),ue(e,t),a&&q(e,t==="error"?"assertive":"polite")}function He(){if(typeof document>"u"||te)return;let e=[{label:"Skip to main content",selector:"main,[role='main'],#main,#main-content"},{label:"Skip to navigation",selector:"nav,[role='navigation'],#nav,#navigation"},{label:"Skip to search",selector:"[role='search'],#search,input[type='search']"}],t=document.createElement("div");t.setAttribute("data-yuktai-skip-bar","true"),t.setAttribute("role","navigation"),t.setAttribute("aria-label","Skip links"),t.style.cssText=`
90
90
  position: fixed;
91
91
  top: 0;
92
92
  left: 0;
@@ -100,7 +100,7 @@
100
100
  transform: translateY(-100%);
101
101
  transition: transform 0.2s ease;
102
102
  font-family: system-ui, sans-serif;
103
- `;let a=!1;if(e.forEach(({label:i,selector:o})=>{let n=document.querySelector(o);if(!n)return;a=!0,n.getAttribute("tabindex")||n.setAttribute("tabindex","-1");let s=document.createElement("a");s.href="#",s.textContent=i,s.style.cssText=`
103
+ `;let a=!1;if(e.forEach(({label:i,selector:s})=>{let n=document.querySelector(s);if(!n)return;a=!0,n.getAttribute("tabindex")||n.setAttribute("tabindex","-1");let o=document.createElement("a");o.href="#",o.textContent=i,o.style.cssText=`
104
104
  color: #fff;
105
105
  background: #1a73e8;
106
106
  padding: 8px 14px;
@@ -111,7 +111,7 @@
111
111
  white-space: nowrap;
112
112
  border: 2px solid transparent;
113
113
  transition: background 0.15s, border-color 0.15s;
114
- `,s.addEventListener("focus",()=>{t.style.transform="translateY(0)"}),s.addEventListener("blur",()=>{setTimeout(()=>{t.matches(":focus-within")||(t.style.transform="translateY(-100%)")},2e3)}),s.addEventListener("click",d=>{d.preventDefault(),n.focus(),n.scrollIntoView({behavior:"smooth",block:"start"}),l(`Jumped to ${i.replace("Skip to ","")}`,"info"),t.style.transform="translateY(-100%)"}),t.appendChild(s)}),!a)return;window.innerWidth<768&&(t.style.transform="translateY(0)",t.style.position="sticky"),window.addEventListener("resize",()=>{window.innerWidth<768&&(t.style.transform="translateY(0)")}),document.body.insertBefore(t,document.body.firstChild),Q=t}function Me(){if(typeof document>"u"||document.querySelector("[data-yuktai-focus-style]"))return;let e=document.createElement("style");e.setAttribute("data-yuktai-focus-style","true"),e.textContent=`
114
+ `,o.addEventListener("focus",()=>{t.style.transform="translateY(0)"}),o.addEventListener("blur",()=>{setTimeout(()=>{t.matches(":focus-within")||(t.style.transform="translateY(-100%)")},2e3)}),o.addEventListener("click",p=>{p.preventDefault(),n.focus(),n.scrollIntoView({behavior:"smooth",block:"start"}),l(`Jumped to ${i.replace("Skip to ","")}`,"info"),t.style.transform="translateY(-100%)"}),t.appendChild(o)}),!a)return;window.innerWidth<768&&(t.style.transform="translateY(0)",t.style.position="sticky"),window.addEventListener("resize",()=>{window.innerWidth<768&&(t.style.transform="translateY(0)")}),document.body.insertBefore(t,document.body.firstChild),te=t}function $e(){if(typeof document>"u"||document.querySelector("[data-yuktai-focus-style]"))return;let e=document.createElement("style");e.setAttribute("data-yuktai-focus-style","true"),e.textContent=`
115
115
 
116
116
  /* \u2500\u2500 Focus indicator \u2014 WCAG 2.4.11 minimum 2px solid \u2500\u2500 */
117
117
  [data-yuktai-a11y] *:focus-visible {
@@ -257,7 +257,7 @@
257
257
  width: auto !important;
258
258
  }
259
259
  }
260
- `,document.head.appendChild(e),document.documentElement.setAttribute("data-yuktai-a11y","true")}function Ce(){typeof document>"u"||document.querySelector("[data-yuktai-kb-init]")||(document.documentElement.setAttribute("data-yuktai-kb-init","true"),document.addEventListener("keydown",e=>{let t=document.activeElement;if(!t)return;let a=t.getAttribute("role")||"";if(e.key==="Escape"){let r=t.closest("[role='dialog'],[role='alertdialog']");if(r){r.style.display="none",l("Dialog closed","info");return}let i=t.closest("[role='menu'],[role='menubar']");i&&(i.style.display="none",l("Menu closed","info"))}if(a==="menuitem"||t.closest("[role='menu'],[role='menubar']")){let r=t.closest("[role='menu'],[role='menubar']");if(!r)return;let i=Array.from(r.querySelectorAll("[role='menuitem']:not([disabled])")),o=i.indexOf(t);e.key==="ArrowDown"||e.key==="ArrowRight"?(e.preventDefault(),i[(o+1)%i.length]?.focus()):e.key==="ArrowUp"||e.key==="ArrowLeft"?(e.preventDefault(),i[(o-1+i.length)%i.length]?.focus()):e.key==="Home"?(e.preventDefault(),i[0]?.focus()):e.key==="End"&&(e.preventDefault(),i[i.length-1]?.focus())}if(a==="tab"||t.closest("[role='tablist']")){let r=t.closest("[role='tablist']");if(!r)return;let i=Array.from(r.querySelectorAll("[role='tab']:not([disabled])")),o=i.indexOf(t);if(e.key==="ArrowRight"||e.key==="ArrowDown"){e.preventDefault();let n=i[(o+1)%i.length];n?.focus(),n?.click()}else if(e.key==="ArrowLeft"||e.key==="ArrowUp"){e.preventDefault();let n=i[(o-1+i.length)%i.length];n?.focus(),n?.click()}}if(a==="option"||t.closest("[role='listbox']")){let r=t.closest("[role='listbox']");if(!r)return;let i=Array.from(r.querySelectorAll("[role='option']:not([aria-disabled='true'])")),o=i.indexOf(t);e.key==="ArrowDown"?(e.preventDefault(),i[(o+1)%i.length]?.focus()):e.key==="ArrowUp"?(e.preventDefault(),i[(o-1+i.length)%i.length]?.focus()):(e.key==="Enter"||e.key===" ")&&(e.preventDefault(),t.setAttribute("aria-selected","true"),i.forEach(n=>{n!==t&&n.setAttribute("aria-selected","false")}),l(`Selected: ${t.textContent?.trim()}`,"success"))}e.altKey&&e.key==="a"&&(e.preventDefault(),Pe()),e.key==="Tab"&&y?.speechEnabled&&setTimeout(()=>{let r=document.activeElement;if(!r)return;let i=r.getAttribute("aria-label")||r.getAttribute("title")||r.textContent?.trim()||r.tagName.toLowerCase(),o=r.getAttribute("role")||r.tagName.toLowerCase();I(`${i}, ${o}`)},100)}))}function E(e){let t=e.querySelectorAll('button:not([disabled]),a[href],input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"]),[role="button"]');if(t.length===0)return;let a=t[0],r=t[t.length-1];a.focus(),e.addEventListener("keydown",i=>{i.key==="Tab"&&(i.shiftKey?document.activeElement===a&&(i.preventDefault(),r.focus()):document.activeElement===r&&(i.preventDefault(),a.focus()))})}function Pe(){if(typeof document>"u")return;if(b){b.remove(),b=null;return}let e=document.createElement("div");e.setAttribute("role","dialog"),e.setAttribute("aria-label","Keyboard shortcuts"),e.setAttribute("aria-modal","true"),e.setAttribute("data-yuktai-cheatsheet","true"),e.style.cssText=`
260
+ `,document.head.appendChild(e),document.documentElement.setAttribute("data-yuktai-a11y","true")}function Re(){typeof document>"u"||document.querySelector("[data-yuktai-kb-init]")||(document.documentElement.setAttribute("data-yuktai-kb-init","true"),document.addEventListener("keydown",e=>{let t=document.activeElement;if(!t)return;let a=t.getAttribute("role")||"";if(e.key==="Escape"){let r=t.closest("[role='dialog'],[role='alertdialog']");if(r){r.style.display="none",l("Dialog closed","info");return}let i=t.closest("[role='menu'],[role='menubar']");i&&(i.style.display="none",l("Menu closed","info"))}if(a==="menuitem"||t.closest("[role='menu'],[role='menubar']")){let r=t.closest("[role='menu'],[role='menubar']");if(!r)return;let i=Array.from(r.querySelectorAll("[role='menuitem']:not([disabled])")),s=i.indexOf(t);e.key==="ArrowDown"||e.key==="ArrowRight"?(e.preventDefault(),i[(s+1)%i.length]?.focus()):e.key==="ArrowUp"||e.key==="ArrowLeft"?(e.preventDefault(),i[(s-1+i.length)%i.length]?.focus()):e.key==="Home"?(e.preventDefault(),i[0]?.focus()):e.key==="End"&&(e.preventDefault(),i[i.length-1]?.focus())}if(a==="tab"||t.closest("[role='tablist']")){let r=t.closest("[role='tablist']");if(!r)return;let i=Array.from(r.querySelectorAll("[role='tab']:not([disabled])")),s=i.indexOf(t);if(e.key==="ArrowRight"||e.key==="ArrowDown"){e.preventDefault();let n=i[(s+1)%i.length];n?.focus(),n?.click()}else if(e.key==="ArrowLeft"||e.key==="ArrowUp"){e.preventDefault();let n=i[(s-1+i.length)%i.length];n?.focus(),n?.click()}}if(a==="option"||t.closest("[role='listbox']")){let r=t.closest("[role='listbox']");if(!r)return;let i=Array.from(r.querySelectorAll("[role='option']:not([aria-disabled='true'])")),s=i.indexOf(t);e.key==="ArrowDown"?(e.preventDefault(),i[(s+1)%i.length]?.focus()):e.key==="ArrowUp"?(e.preventDefault(),i[(s-1+i.length)%i.length]?.focus()):(e.key==="Enter"||e.key===" ")&&(e.preventDefault(),t.setAttribute("aria-selected","true"),i.forEach(n=>{n!==t&&n.setAttribute("aria-selected","false")}),l(`Selected: ${t.textContent?.trim()}`,"success"))}e.altKey&&e.key==="a"&&(e.preventDefault(),ze()),e.key==="Tab"&&y?.speechEnabled&&setTimeout(()=>{let r=document.activeElement;if(!r)return;let i=r.getAttribute("aria-label")||r.getAttribute("title")||r.textContent?.trim()||r.tagName.toLowerCase(),s=r.getAttribute("role")||r.tagName.toLowerCase();q(`${i}, ${s}`)},100)}))}function S(e){let t=e.querySelectorAll('button:not([disabled]),a[href],input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"]),[role="button"]');if(t.length===0)return;let a=t[0],r=t[t.length-1];a.focus(),e.addEventListener("keydown",i=>{i.key==="Tab"&&(i.shiftKey?document.activeElement===a&&(i.preventDefault(),r.focus()):document.activeElement===r&&(i.preventDefault(),a.focus()))})}function ze(){if(typeof document>"u")return;if(b){b.remove(),b=null;return}let e=document.createElement("div");e.setAttribute("role","dialog"),e.setAttribute("aria-label","Keyboard shortcuts"),e.setAttribute("aria-modal","true"),e.setAttribute("data-yuktai-cheatsheet","true"),e.style.cssText=`
261
261
  position: fixed;
262
262
  top: 50%;
263
263
  left: 50%;
@@ -287,7 +287,7 @@
287
287
  <span style="font-size:12px;color:#ccc;text-align:right;flex:1;margin-left:12px">${i}</span>
288
288
  </div>
289
289
  `).join("")}
290
- `,e.querySelector("[data-yuktai-close]")?.addEventListener("click",()=>{e.remove(),b=null}),e.addEventListener("keydown",r=>{r.key==="Escape"&&(e.remove(),b=null)}),document.body.appendChild(e),b=e,E(e),l("Keyboard shortcuts opened. Press Escape to close.","info")}function $e(e){if(typeof document>"u"||!y?.showAuditBadge||typeof window<"u"&&!window.location.hostname.includes("localhost")&&!window.location.hostname.includes("127.0.0.1"))return;H&&H.remove();let t=e.score,a=t>=90?"#0f9d58":t>=70?"#f29900":"#d93025",r=t>=90?"\u267F":t>=70?"\u26A0":"\u2715",i=document.createElement("button");i.setAttribute("aria-label",`Accessibility score: ${t} out of 100`),i.setAttribute("data-yuktai-badge","true"),i.style.cssText=`
290
+ `,e.querySelector("[data-yuktai-close]")?.addEventListener("click",()=>{e.remove(),b=null}),e.addEventListener("keydown",r=>{r.key==="Escape"&&(e.remove(),b=null)}),document.body.appendChild(e),b=e,S(e),l("Keyboard shortcuts opened. Press Escape to close.","info")}function Ie(e){if(typeof document>"u"||!y?.showAuditBadge||typeof window<"u"&&!window.location.hostname.includes("localhost")&&!window.location.hostname.includes("127.0.0.1"))return;z&&z.remove();let t=e.score,a=t>=90?"#0f9d58":t>=70?"#f29900":"#d93025",r=t>=90?"\u267F":t>=70?"\u26A0":"\u2715",i=document.createElement("button");i.setAttribute("aria-label",`Accessibility score: ${t} out of 100`),i.setAttribute("data-yuktai-badge","true"),i.style.cssText=`
291
291
  position: fixed;
292
292
  bottom: 16px;
293
293
  left: 16px;
@@ -306,7 +306,7 @@
306
306
  align-items: center;
307
307
  gap: 6px;
308
308
  transition: transform 0.15s;
309
- `,i.innerHTML=`${r} ${t}/100 <span style="font-weight:400;opacity:0.85">${e.details.length} issues</span>`,i.addEventListener("click",()=>He(e)),document.body.appendChild(i),H=i}function He(e){let t=document.querySelector("[data-yuktai-audit-details]");if(t){t.remove();return}let a=document.createElement("div");a.setAttribute("data-yuktai-audit-details","true"),a.setAttribute("role","dialog"),a.setAttribute("aria-label","Accessibility audit details"),a.style.cssText=`
309
+ `,i.innerHTML=`${r} ${t}/100 <span style="font-weight:400;opacity:0.85">${e.details.length} issues</span>`,i.addEventListener("click",()=>Oe(e)),document.body.appendChild(i),z=i}function Oe(e){let t=document.querySelector("[data-yuktai-audit-details]");if(t){t.remove();return}let a=document.createElement("div");a.setAttribute("data-yuktai-audit-details","true"),a.setAttribute("role","dialog"),a.setAttribute("aria-label","Accessibility audit details"),a.style.cssText=`
310
310
  position: fixed;
311
311
  bottom: 56px;
312
312
  left: 16px;
@@ -338,7 +338,7 @@
338
338
  </div>
339
339
  `).join("")}
340
340
  ${e.details.length>20?`<div style="color:#888;padding:8px 0;text-align:center">+${e.details.length-20} more issues</div>`:""}
341
- `,a.addEventListener("keydown",i=>{i.key==="Escape"&&a.remove()}),document.body.appendChild(a),E(a)}function se(e){typeof document>"u"||(R&&clearTimeout(R),R=setTimeout(()=>{if(v)return;let t=document.createElement("div");t.setAttribute("role","alertdialog"),t.setAttribute("aria-label","Session timeout warning"),t.setAttribute("aria-modal","true"),t.setAttribute("data-yuktai-timeout","true"),t.style.cssText=`
341
+ `,a.addEventListener("keydown",i=>{i.key==="Escape"&&a.remove()}),document.body.appendChild(a),S(a)}function de(e){typeof document>"u"||(I&&clearTimeout(I),I=setTimeout(()=>{if(A)return;let t=document.createElement("div");t.setAttribute("role","alertdialog"),t.setAttribute("aria-label","Session timeout warning"),t.setAttribute("aria-modal","true"),t.setAttribute("data-yuktai-timeout","true"),t.style.cssText=`
342
342
  position: fixed;
343
343
  top: 50%;
344
344
  left: 50%;
@@ -367,19 +367,19 @@
367
367
  No, sign out
368
368
  </button>
369
369
  </div>
370
- `;let a=t.querySelector("[data-yuktai-extend]"),r=t.querySelector("[data-yuktai-dismiss]");a?.addEventListener("click",()=>{t.remove(),v=null,l("Session extended. You have more time.","success"),y?.timeoutWarning&&se(y.timeoutWarning)}),r?.addEventListener("click",()=>{t.remove(),v=null}),document.body.appendChild(t),v=t,E(t),l("Warning: Your session will expire soon. Do you need more time?","warning")},e*1e3))}function Re(e){if(typeof document>"u")return;let t=document.documentElement;if(t.toggleAttribute("data-yuktai-high-contrast",!!e.highContrast),t.toggleAttribute("data-yuktai-dark",!!e.darkMode),t.toggleAttribute("data-yuktai-reduce-motion",!!e.reduceMotion),t.toggleAttribute("data-yuktai-large-targets",!!e.largeTargets),t.toggleAttribute("data-yuktai-keyboard",!!e.keyboardHints),t.toggleAttribute("data-yuktai-dyslexia",!!e.dyslexiaFont),e.localFont?document.body.style.fontFamily=`"${e.localFont}", system-ui, sans-serif`:e.dyslexiaFont||(document.body.style.fontFamily=""),e.fontSizeMultiplier&&e.fontSizeMultiplier!==1?document.documentElement.style.fontSize=`${e.fontSizeMultiplier*100}%`:document.documentElement.style.fontSize="",e.colorBlindMode&&e.colorBlindMode!=="none"){let a=e.colorBlindMode==="achromatopsia"?"grayscale(100%)":`url(#${k[e.colorBlindMode]})`;document.body.style.filter=a}else document.body.style.filter=""}function ze(e){try{let t=localStorage.getItem("yuktai-a11y-prefs");t&&Object.assign(e,JSON.parse(t))}catch{}}async function ee(e){if(e){if(!await S()){l("Plain English requires Chrome 127+","warning");return}l("Rewriting page in plain English...","info",!1);let a=await q();l(a.error?`Plain English failed: ${a.error}`:`${a.fixed} sections rewritten in plain English`,a.error?"error":"success",!1)}else B(),l("Original text restored","info",!1)}async function te(e){if(e){if(!await L()){l("Page summariser requires Chrome 127+","warning");return}l("Generating page summary...","info",!1);let a=await F();l(a.error?`Summary failed: ${a.error}`:"Page summary added at top",a.error?"error":"success",!1)}else h(),l("Page summary removed","info",!1)}async function ae(e){if(e==="en"){M(),l("Page restored to English","info",!1);return}l(`Translating page to ${e}...`,"info",!1);let t=await _(e);l(t.error?`Translation failed: ${t.error}`:`Page translated to ${e}`,t.error?"error":"success",!1)}async function ne(e){if(e){if(!C()){l("Voice control not supported in this browser","warning");return}W(t=>{t.success&&l(`Voice: ${t.action}`,"info",!1)}),l("Voice control started. Say a command.","success",!1)}else P(),l("Voice control stopped","info",!1)}async function ie(e){if(e){if(!await $()){l("Smart labels requires Chrome 127+","warning");return}l("Generating smart labels...","info",!1);let a=await Y();l(a.error?`Smart labels failed: ${a.error}`:`${a.fixed} elements labelled`,a.error?"error":"success",!1)}else J(),l("Smart labels removed","info",!1)}function Ie(){if(typeof document>"u"||A)return;let e=document.createElement("div");e.setAttribute("aria-live","polite"),e.setAttribute("aria-atomic","true"),e.setAttribute("aria-relevant","text"),e.style.cssText="position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);",document.body.appendChild(e),A=e}function Oe(){if(typeof document>"u"||X)return;let e=document.createElementNS("http://www.w3.org/2000/svg","svg");e.setAttribute("aria-hidden","true"),e.style.cssText="position:absolute;width:0;height:0;overflow:hidden;",e.innerHTML=`
370
+ `;let a=t.querySelector("[data-yuktai-extend]"),r=t.querySelector("[data-yuktai-dismiss]");a?.addEventListener("click",()=>{t.remove(),A=null,l("Session extended. You have more time.","success"),y?.timeoutWarning&&de(y.timeoutWarning)}),r?.addEventListener("click",()=>{t.remove(),A=null}),document.body.appendChild(t),A=t,S(t),l("Warning: Your session will expire soon. Do you need more time?","warning")},e*1e3))}function qe(e){if(typeof document>"u")return;let t=document.documentElement;if(t.toggleAttribute("data-yuktai-high-contrast",!!e.highContrast),t.toggleAttribute("data-yuktai-dark",!!e.darkMode),t.toggleAttribute("data-yuktai-reduce-motion",!!e.reduceMotion),t.toggleAttribute("data-yuktai-large-targets",!!e.largeTargets),t.toggleAttribute("data-yuktai-keyboard",!!e.keyboardHints),t.toggleAttribute("data-yuktai-dyslexia",!!e.dyslexiaFont),e.localFont?document.body.style.fontFamily=`"${e.localFont}", system-ui, sans-serif`:e.dyslexiaFont||(document.body.style.fontFamily=""),e.fontSizeMultiplier&&e.fontSizeMultiplier!==1?document.documentElement.style.fontSize=`${e.fontSizeMultiplier*100}%`:document.documentElement.style.fontSize="",e.colorBlindMode&&e.colorBlindMode!=="none"){let a=e.colorBlindMode==="achromatopsia"?"grayscale(100%)":`url(#${E[e.colorBlindMode]})`;document.body.style.filter=a}else document.body.style.filter=""}function Be(e){try{let t=localStorage.getItem("yuktai-a11y-prefs");t&&Object.assign(e,JSON.parse(t))}catch{}}async function ne(e){if(e){if(!await M()){l("Plain English requires Chrome 127+","warning");return}l("Rewriting page in plain English...","info",!1);let a=await D();l(a.error?`Plain English failed: ${a.error}`:`${a.fixed} sections rewritten in plain English`,a.error?"error":"success",!1)}else F(),l("Original text restored","info",!1)}async function ie(e){if(e){if(!await C()){l("Page summariser requires Chrome 127+","warning");return}l("Generating page summary...","info",!1);let a=await G();l(a.error?`Summary failed: ${a.error}`:"Page summary added at top",a.error?"error":"success",!1)}else w(),l("Page summary removed","info",!1)}async function re(e){if(e==="en"){P(),l("Page restored to English","info",!1);return}l(`Translating page to ${e}...`,"info",!1);let t=await j(e);l(t.error?`Translation failed: ${t.error}`:`Page translated to ${e}`,t.error?"error":"success",!1)}async function oe(e){if(e){if(!H()){l("Voice control not supported in this browser","warning");return}U(t=>{t.success&&l(`Voice: ${t.action}`,"info",!1)}),l("Voice control started. Say a command.","success",!1)}else $(),l("Voice control stopped","info",!1)}async function se(e){if(e){if(!await R()){l("Smart labels requires Chrome 127+","warning");return}l("Generating smart labels...","info",!1);let a=await Q();l(a.error?`Smart labels failed: ${a.error}`:`${a.fixed} elements labelled`,a.error?"error":"success",!1)}else Z(),l("Smart labels removed","info",!1)}function Ne(){if(typeof document>"u"||T)return;let e=document.createElement("div");e.setAttribute("aria-live","polite"),e.setAttribute("aria-atomic","true"),e.setAttribute("aria-relevant","text"),e.style.cssText="position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden;clip:rect(0,0,0,0);",document.body.appendChild(e),T=e}function De(){if(typeof document>"u"||ee)return;let e=document.createElementNS("http://www.w3.org/2000/svg","svg");e.setAttribute("aria-hidden","true"),e.style.cssText="position:absolute;width:0;height:0;overflow:hidden;",e.innerHTML=`
371
371
  <defs>
372
- <filter id="${k.deuteranopia}">
372
+ <filter id="${E.deuteranopia}">
373
373
  <feColorMatrix type="matrix"
374
374
  values="0.625 0.375 0 0 0 0.7 0.3 0 0 0 0 0.3 0.7 0 0 0 0 0 1 0"/>
375
375
  </filter>
376
- <filter id="${k.protanopia}">
376
+ <filter id="${E.protanopia}">
377
377
  <feColorMatrix type="matrix"
378
378
  values="0.567 0.433 0 0 0 0.558 0.442 0 0 0 0 0.242 0.758 0 0 0 0 0 1 0"/>
379
379
  </filter>
380
- <filter id="${k.tritanopia}">
380
+ <filter id="${E.tritanopia}">
381
381
  <feColorMatrix type="matrix"
382
382
  values="0.95 0.05 0 0 0 0 0.433 0.567 0 0 0 0.475 0.525 0 0 0 0 0 1 0"/>
383
383
  </filter>
384
384
  </defs>
385
- `,document.body.appendChild(e),X=e}function re(e){let t={critical:20,serious:10,moderate:5,minor:2},a=e.details.reduce((r,i)=>r+(t[i.severity]||0),0);return Math.max(0,Math.min(100,100-a))}var qe={name:"yuktai-a11y",version:"4.0.0",observer:null,async execute(e){if(!e.enabled)return this.stopObserver(),"yuktai: disabled.";y=e,ze(e),Ie(),Oe(),Me(),Ce(),e.showSkipLinks!==!1&&Le(),e.showPreferencePanel,Re(e);let t=this.applyFixes(e);t.score=re(t),e.showAuditBadge&&$e(t),e.timeoutWarning&&se(e.timeoutWarning),e.autoFix&&this.startObserver(e),e.plainEnglish&&await ee(!0),e.summarisePage&&await te(!0),e.translateLanguage&&e.translateLanguage!=="en"&&await ae(e.translateLanguage),e.voiceControl&&await ne(!0),e.smartLabels&&await ie(!0);let a=`${t.fixed} fixes applied. Score: ${t.score}/100.`;return l(a,t.score>=90?"success":"info",!1),`yuktai v4.0.0: ${a} Scanned ${t.scanned} elements in ${t.renderTime}ms.`},applyFixes(e){let t={fixed:0,scanned:0,renderTime:0,score:100,details:[]};if(typeof document>"u")return t;let a=performance.now(),r=document.querySelectorAll("*");t.scanned=r.length;let i=(o,n,s,d)=>{t.details.push({tag:o,fix:n,severity:s,element:d.outerHTML.slice(0,100)}),t.fixed++};return r.forEach(o=>{let n=o,s=n.tagName.toLowerCase();if(s==="html"&&!n.getAttribute("lang")&&(n.setAttribute("lang","en"),i(s,'lang="en" added',"critical",n)),s==="meta"){let c=n.getAttribute("name"),p=n.getAttribute("content")||"";c==="viewport"&&p.includes("user-scalable=no")&&(n.setAttribute("content",p.replace("user-scalable=no","user-scalable=yes")),i(s,"user-scalable=yes restored","serious",n)),c==="viewport"&&/maximum-scale=1(?:[^0-9]|$)/.test(p)&&(n.setAttribute("content",p.replace(/maximum-scale=1(?=[^0-9]|$)/,"maximum-scale=5")),i(s,"maximum-scale=5 restored","serious",n))}if(s==="main"&&!n.getAttribute("tabindex")&&(n.setAttribute("tabindex","-1"),n.getAttribute("id")||n.setAttribute("id","main-content")),s==="img"&&(n.hasAttribute("alt")||(n.setAttribute("alt",""),n.setAttribute("aria-hidden","true"),i(s,'alt="" aria-hidden="true"',"serious",n))),s==="svg"&&(!n.getAttribute("aria-hidden")&&!n.getAttribute("aria-label")&&!o.querySelector("title")&&(n.setAttribute("aria-hidden","true"),i(s,'aria-hidden="true" (decorative svg)',"minor",n)),n.getAttribute("focusable")||n.setAttribute("focusable","false")),s==="iframe"&&!n.getAttribute("title")&&!n.getAttribute("aria-label")&&(n.setAttribute("title","embedded content"),n.setAttribute("aria-label","embedded content"),i(s,"title + aria-label added","serious",n)),s==="button"){if(!n.innerText?.trim()&&!n.getAttribute("aria-label")){let c=n.getAttribute("title")||"button";n.setAttribute("aria-label",c),i(s,`aria-label="${c}" (empty button)`,"critical",n)}n.hasAttribute("disabled")&&!n.getAttribute("aria-disabled")&&(n.setAttribute("aria-disabled","true"),t.fixed++)}if(s==="a"){let c=n;!n.innerText?.trim()&&!n.getAttribute("aria-label")&&(n.setAttribute("aria-label",n.getAttribute("title")||"link"),i(s,"aria-label added (empty link)","critical",n)),c.target==="_blank"&&!c.rel?.includes("noopener")&&(c.rel="noopener noreferrer",t.fixed++)}if(Z.has(s)){let c=n;if(!n.getAttribute("aria-label")&&!n.getAttribute("aria-labelledby")){let p=n.getAttribute("placeholder")||n.getAttribute("name")||s;n.setAttribute("aria-label",p),i(s,`aria-label="${p}"`,"serious",n)}if(n.hasAttribute("required")&&!n.getAttribute("aria-required")&&(n.setAttribute("aria-required","true"),t.fixed++),s==="input"&&!c.autocomplete){let p=c.name||"";c.type==="email"||p.includes("email")?c.autocomplete="email":c.type==="tel"||p.includes("tel")?c.autocomplete="tel":c.type==="password"&&(c.autocomplete="current-password"),t.fixed++}}s==="th"&&!n.getAttribute("scope")&&(n.setAttribute("scope",n.closest("thead")?"col":"row"),i(s,"scope added to <th>","moderate",n)),z[s]&&!n.getAttribute("role")&&(n.setAttribute("role",z[s]),i(s,`role="${z[s]}"`,"minor",n));let d=n.getAttribute("role")||"";d==="tab"&&!n.getAttribute("aria-selected")&&(n.setAttribute("aria-selected","false"),t.fixed++),["alert","status","log"].includes(d)&&!n.getAttribute("aria-live")&&(n.setAttribute("aria-live",d==="alert"?"assertive":"polite"),i(s,`aria-live added on role=${d}`,"moderate",n)),d==="combobox"&&!n.getAttribute("aria-expanded")&&(n.setAttribute("aria-expanded","false"),i(s,'aria-expanded="false" on combobox',"serious",n)),(d==="checkbox"||d==="radio")&&!n.getAttribute("aria-checked")&&(n.setAttribute("aria-checked","false"),i(s,`aria-checked="false" on role=${d}`,"serious",n))}),t.renderTime=parseFloat((performance.now()-a).toFixed(2)),t},scan(){let e={fixed:0,scanned:0,renderTime:0,score:100,details:[]};if(typeof document>"u")return e;let t=performance.now(),a=document.querySelectorAll("*");e.scanned=a.length;let r=(i,o,n,s)=>e.details.push({tag:i,fix:o,severity:n,element:s.outerHTML.slice(0,100)});return a.forEach(i=>{let o=i,n=o.tagName.toLowerCase();(n==="a"||n==="button")&&!o.innerText?.trim()&&!o.getAttribute("aria-label")&&r(n,"needs aria-label (empty)","critical",o),n==="img"&&!o.hasAttribute("alt")&&r(n,"needs alt text","serious",o),Z.has(n)&&!o.getAttribute("aria-label")&&!o.getAttribute("aria-labelledby")&&r(n,"needs aria-label","serious",o),n==="iframe"&&!o.getAttribute("title")&&!o.getAttribute("aria-label")&&r(n,"iframe needs title","serious",o)}),e.fixed=e.details.length,e.score=re(e),e.renderTime=parseFloat((performance.now()-t).toFixed(2)),e},startObserver(e){this.observer||typeof document>"u"||(this.observer=new MutationObserver(()=>this.applyFixes(e)),this.observer.observe(document.body,{childList:!0,subtree:!0,attributes:!1}))},stopObserver(){this.observer?.disconnect(),this.observer=null},announce:l,speak:I,showVisualAlert:oe,trapFocus:E,handlePlainEnglish:ee,handleSummarisePage:te,handleTranslate:ae,handleVoiceControl:ne,handleSmartLabels:ie,SUPPORTED_LANGUAGES:V};return pe(Be);})();
385
+ `,document.body.appendChild(e),ee=e}function le(e){return e.getAttribute("aria-label")?.trim()||e.getAttribute("aria-labelledby")||e.getAttribute("title")?.trim()||e.textContent?.trim()?!0:!!e.querySelector("img[alt]:not([alt='']), svg[aria-label], svg title, [aria-label]")}function ce(e){let t={critical:20,serious:10,moderate:5,minor:2},a=e.details.reduce((r,i)=>r+(t[i.severity]||0),0);return Math.max(0,Math.min(100,100-a))}var Fe={name:"yuktai-a11y",version:"4.0.0",observer:null,async execute(e){if(!e.enabled)return this.stopObserver(),"yuktai: disabled.";y=e,Be(e),Ne(),De(),$e(),Re(),e.showSkipLinks!==!1&&He(),e.showPreferencePanel,qe(e);let t=this.applyFixes(e);t.score=ce(t),e.showAuditBadge&&Ie(t),e.timeoutWarning&&de(e.timeoutWarning),e.autoFix&&this.startObserver(e),e.plainEnglish&&await ne(!0),e.summarisePage&&await ie(!0),e.translateLanguage&&e.translateLanguage!=="en"&&await re(e.translateLanguage),e.voiceControl&&await oe(!0),e.smartLabels&&await se(!0);let a=`${t.fixed} fixes applied. Score: ${t.score}/100.`;return l(a,t.score>=90?"success":"info",!1),`yuktai v4.0.0: ${a} Scanned ${t.scanned} elements in ${t.renderTime}ms.`},applyFixes(e){let t={fixed:0,scanned:0,renderTime:0,score:100,details:[]};if(typeof document>"u")return t;let a=performance.now(),r=document.querySelectorAll("*");t.scanned=r.length;let i=(s,n,o,p)=>{t.details.push({tag:s,fix:n,severity:o,element:p.outerHTML.slice(0,100)}),t.fixed++};return r.forEach(s=>{let n=s,o=n.tagName.toLowerCase();if(o==="html"&&!n.getAttribute("lang")&&(n.setAttribute("lang","en"),i(o,'lang="en" added',"critical",n)),o==="meta"){let c=n.getAttribute("name"),g=n.getAttribute("content")||"";c==="viewport"&&g.includes("user-scalable=no")&&(n.setAttribute("content",g.replace("user-scalable=no","user-scalable=yes")),i(o,"user-scalable=yes restored","serious",n)),c==="viewport"&&/maximum-scale=1(?:[^0-9]|$)/.test(g)&&(n.setAttribute("content",g.replace(/maximum-scale=1(?=[^0-9]|$)/,"maximum-scale=5")),i(o,"maximum-scale=5 restored","serious",n))}if(o==="main"&&!n.getAttribute("tabindex")&&(n.setAttribute("tabindex","-1"),n.getAttribute("id")||n.setAttribute("id","main-content")),o==="img"&&(n.hasAttribute("alt")||(n.setAttribute("alt",""),n.setAttribute("aria-hidden","true"),i(o,'alt="" aria-hidden="true"',"serious",n))),o==="svg"&&(!n.getAttribute("aria-hidden")&&!n.getAttribute("aria-label")&&!s.querySelector("title")&&(n.setAttribute("aria-hidden","true"),i(o,'aria-hidden="true" (decorative svg)',"minor",n)),n.getAttribute("focusable")||n.setAttribute("focusable","false")),o==="iframe"&&!n.getAttribute("title")&&!n.getAttribute("aria-label")&&(n.setAttribute("title","embedded content"),n.setAttribute("aria-label","embedded content"),i(o,"title + aria-label added","serious",n)),o==="button"){if(!le(n)){let c=n.getAttribute("title")||"button";n.setAttribute("aria-label",c),i(o,`aria-label="${c}" (empty button)`,"critical",n)}n.hasAttribute("disabled")&&!n.getAttribute("aria-disabled")&&(n.setAttribute("aria-disabled","true"),t.fixed++)}if(o==="a"){let c=n;le(n)||(n.setAttribute("aria-label",n.getAttribute("title")||"link"),i(o,"aria-label added (empty link)","critical",n)),c.target==="_blank"&&!c.rel?.includes("noopener")&&(c.rel="noopener noreferrer",t.fixed++)}if(ae.has(o)){let c=n;if(!(!!(c.labels&&c.labels.length)||!!n.getAttribute("title")||c.type==="hidden"||c.type==="submit"||c.type==="button"||c.type==="reset")&&!n.getAttribute("aria-label")&&!n.getAttribute("aria-labelledby")){let h=n.getAttribute("placeholder")||n.getAttribute("name")||o;n.setAttribute("aria-label",h),i(o,`aria-label="${h}"`,"serious",n)}if(n.hasAttribute("required")&&!n.getAttribute("aria-required")&&(n.setAttribute("aria-required","true"),t.fixed++),o==="input"&&!c.autocomplete){let h=c.name||"",B=c.type==="email"||h.includes("email")?"email":c.type==="tel"||h.includes("tel")?"tel":c.type==="password"?"current-password":"";B&&(c.autocomplete=B,t.fixed++)}}o==="th"&&!n.getAttribute("scope")&&(n.setAttribute("scope",n.closest("thead")?"col":"row"),i(o,"scope added to <th>","moderate",n));let p=(o==="header"||o==="footer")&&!!n.parentElement?.closest("article,aside,main,nav,section,[role='dialog'],[role='region']");O[o]&&!n.getAttribute("role")&&!p&&(n.setAttribute("role",O[o]),i(o,`role="${O[o]}"`,"minor",n));let d=n.getAttribute("role")||"";d==="tab"&&!n.getAttribute("aria-selected")&&(n.setAttribute("aria-selected","false"),t.fixed++),["alert","status","log"].includes(d)&&!n.getAttribute("aria-live")&&(n.setAttribute("aria-live",d==="alert"?"assertive":"polite"),i(o,`aria-live added on role=${d}`,"moderate",n)),d==="combobox"&&!n.getAttribute("aria-expanded")&&(n.setAttribute("aria-expanded","false"),i(o,'aria-expanded="false" on combobox',"serious",n)),(d==="checkbox"||d==="radio")&&!n.getAttribute("aria-checked")&&(n.setAttribute("aria-checked","false"),i(o,`aria-checked="false" on role=${d}`,"serious",n))}),t.renderTime=parseFloat((performance.now()-a).toFixed(2)),t},scan(){let e={fixed:0,scanned:0,renderTime:0,score:100,details:[]};if(typeof document>"u")return e;let t=performance.now(),a=document.querySelectorAll("*");e.scanned=a.length;let r=(i,s,n,o)=>e.details.push({tag:i,fix:s,severity:n,element:o.outerHTML.slice(0,100)});return a.forEach(i=>{let s=i,n=s.tagName.toLowerCase();(n==="a"||n==="button")&&!s.innerText?.trim()&&!s.getAttribute("aria-label")&&r(n,"needs aria-label (empty)","critical",s),n==="img"&&!s.hasAttribute("alt")&&r(n,"needs alt text","serious",s),ae.has(n)&&!s.getAttribute("aria-label")&&!s.getAttribute("aria-labelledby")&&r(n,"needs aria-label","serious",s),n==="iframe"&&!s.getAttribute("title")&&!s.getAttribute("aria-label")&&r(n,"iframe needs title","serious",s)}),e.fixed=e.details.length,e.score=ce(e),e.renderTime=parseFloat((performance.now()-t).toFixed(2)),e},startObserver(e){this.observer||typeof document>"u"||(this.observer=new MutationObserver(()=>this.applyFixes(e)),this.observer.observe(document.body,{childList:!0,subtree:!0,attributes:!1}))},stopObserver(){this.observer?.disconnect(),this.observer=null},announce:l,speak:q,showVisualAlert:ue,trapFocus:S,handlePlainEnglish:ne,handleSummarisePage:ie,handleTranslate:re,handleVoiceControl:oe,handleSmartLabels:se,SUPPORTED_LANGUAGES:W};return ge(Ve);})();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@yuktishaalaa/yuktai",
3
- "version": "5.2.0",
4
- "description": "Next.js accessibility, AI and data toolkit: WCAG 2.2 auto-fix, agentic data grid, accessibility copilot, QA reports and in-browser RAG. Zero API keys.",
3
+ "version": "5.3.0",
4
+ "description": "Accessibility, AI and data toolkit for Next.js, React and plain HTML: WCAG 2.2 auto-fix, agentic data grid, accessibility copilot, QA reports and in-browser RAG. Zero API keys.",
5
5
  "author": "Sandeep Miriyala — Yuktishaalaa AI Lab",
6
6
  "license": "ISC",
7
7
  "homepage": "https://aksharatantra.miriyala.in",
@@ -9,6 +9,9 @@
9
9
  "type": "git",
10
10
  "url": "git+https://github.com/sandeepmiriyala03/yuktai.git"
11
11
  },
12
+ "bugs": {
13
+ "url": "https://github.com/sandeepmiriyala03/yuktai/issues"
14
+ },
12
15
  "keywords": [
13
16
  "accessibility",
14
17
  "wcag",
@@ -16,6 +19,9 @@
16
19
  "aria",
17
20
  "react",
18
21
  "nextjs",
22
+ "vanilla-js",
23
+ "html",
24
+ "no-framework",
19
25
  "browser-ai",
20
26
  "on-device-ai",
21
27
  "transformers",
@@ -24,29 +30,41 @@
24
30
  "agentic-ai",
25
31
  "data-grid",
26
32
  "webmcp",
27
- "telugu"
33
+ "telugu",
34
+ "indian-languages"
28
35
  ],
29
36
  "main": "./dist/index.js",
30
37
  "module": "./dist/index.mjs",
31
38
  "types": "./dist/index.d.ts",
39
+ "unpkg": "vanilla/index.min.js",
40
+ "jsdelivr": "vanilla/index.min.js",
32
41
  "exports": {
33
42
  ".": {
34
43
  "types": "./dist/index.d.ts",
35
44
  "import": "./dist/index.mjs",
36
45
  "require": "./dist/index.js"
37
- }
46
+ },
47
+ "./vanilla": "./vanilla/index.min.js",
48
+ "./vanilla/index.js": "./vanilla/index.js",
49
+ "./vanilla/index.min.js": "./vanilla/index.min.js",
50
+ "./package.json": "./package.json"
38
51
  },
39
52
  "files": [
40
53
  "dist",
54
+ "vanilla/index.js",
55
+ "vanilla/index.min.js",
56
+ "vanilla/README.md",
41
57
  "README.md",
42
58
  "LICENSE"
43
59
  ],
44
60
  "scripts": {
45
61
  "dev": "tsup --watch",
46
62
  "build": "tsup",
63
+ "build:vanilla": "node vanilla/build.mjs",
64
+ "build:all": "npm run build && npm run build:vanilla",
47
65
  "lint": "eslint src --ext .ts,.tsx",
48
66
  "test": "vitest run",
49
- "prepublishOnly": "npm run build"
67
+ "prepublishOnly": "npm run build:all"
50
68
  },
51
69
  "dependencies": {
52
70
  "jszip": "^3.10.1"
@@ -65,8 +83,11 @@
65
83
  "@types/jszip": "^3.4.0",
66
84
  "@types/react": "^18.3.3",
67
85
  "@types/react-dom": "^18.3.0",
86
+ "axe-core": "^4.14.0",
87
+ "esbuild": "^0.24.0",
68
88
  "eslint": "^8.57.0",
69
89
  "happy-dom": "^15.11.7",
90
+ "playwright-core": "^1.64.1",
70
91
  "react": "^19.3.1",
71
92
  "react-dom": "^19.3.1",
72
93
  "tsup": "^8.5.1",
@@ -81,4 +102,4 @@
81
102
  "Chrome >= 113",
82
103
  "Edge >= 113"
83
104
  ]
84
- }
105
+ }
@@ -0,0 +1,162 @@
1
+ # yuktai — Vanilla JS
2
+
3
+ The whole yuktai 5.2 toolkit for plain HTML pages: one script file, no React, no build step, no API keys.
4
+
5
+ - **Data grid you can talk to**: search, sort, pagination, selection, CSV export, five WCAG themes, table/card views, Telugu UI, and keyboard navigation with ARIA grid roles.
6
+ - **Agents**: smart grid queries, BI answers, multi-step tasks, an anomaly finder, a grid assistant with custom rules and voice, and WebMCP.
7
+ - **Page tools**: Accessibility Copilot, QA report (15 WCAG checks), form review, design review, page Q&A and voice commands.
8
+ - **Accessibility engine**: WCAG auto-fixes, high contrast, dark mode, reduced motion, large targets, colour-blind filters, a dyslexia font, text size 80–130%, skip links and speak-on-focus.
9
+
10
+ The logic is bundled from this repo's `src/` (the same code as the npm package), so a question gets the same answer in React and in plain HTML. Only the React components and hooks are rewritten, in `vanilla/src/`.
11
+
12
+ ## Use it
13
+
14
+ ```html
15
+ <script>
16
+ window.YUKTAI_CONFIG = { position: "right", showPageTools: true } // optional
17
+ </script>
18
+ <script src="./index.js"></script> <!-- or index.min.js -->
19
+
20
+ <div id="staff"></div>
21
+ <script>
22
+ const grid = yuktai.renderGrid("#staff", {
23
+ data: rows,
24
+ rowKey: "id",
25
+ columns: [
26
+ { key: "name", label: "Name" },
27
+ { key: "salary", label: "Salary", type: "number" },
28
+ { key: "joined", label: "Joined", type: "date" },
29
+ { key: "status", label: "Status", type: "badge" },
30
+ ],
31
+ agentic: true, // question bar: "salary over 1 lakh", "average salary by department"
32
+ ai: true, // assistant: custom rules → phrases → tools, with voice input
33
+ })
34
+ </script>
35
+ ```
36
+
37
+ Open `index.html` in this folder to see every feature with working examples, including a Telugu grid.
38
+
39
+ ## `YUKTAI_CONFIG` (floating buttons)
40
+
41
+ | Option | Default | Purpose |
42
+ | --- | --- | --- |
43
+ | `position` | `"left"` | Side for the floating buttons: `"left"` or `"right"` |
44
+ | `primaryColor` | `#0f766e` | Accent colour (keep 4.5:1 against white) |
45
+ | `title` | `"Accessibility"` | Settings dialog title |
46
+ | `showPageTools` | `false` | Adds the 🛠 button that opens the six page tools |
47
+ | `defaultTab`, `voiceLang` | `"qa"`, `"en-IN"` | Settings for the page tools |
48
+ | `generate(q, ctx)`, `summarize(text)` | — | Optional hooks for your own model (Ask tab) |
49
+ | `config` | — | Engine overrides, for example `{ autoFix: false }` |
50
+ | `applyOnLoad` | `true` | Run the engine once on page load (restores saved settings) |
51
+ | `autoInit` | `true` | Set `false` to call `yuktai.init()` yourself |
52
+
53
+ `yuktai.open()`, `yuktai.close()`, `yuktai.openTools("forms")`, `yuktai.apply({ highContrast: true })`, `yuktai.reset()` and `yuktai.getSettings()` control the widget from code. Settings are saved in `localStorage` (`yuktai-a11y-prefs`), the same key the npm package uses.
54
+
55
+ ## `renderGrid(container, options)`
56
+
57
+ The v5.1 vanilla signature `renderGrid(container, rows, columns, options)` still works.
58
+
59
+ | Option | Purpose |
60
+ | --- | --- |
61
+ | `data`, `columns`, `rowKey` (`"id"`) | Rows, columns, row ID field |
62
+ | column: `key`, `label`, `type` (`text`/`number`/`date`/`boolean`/`badge`), `align`, `sortable`, `render(value, row, index)` returns text or a DOM node, `hiddenOnMobile`, `width` | |
63
+ | `label` | Accessible name of the grid |
64
+ | `locale` | `"en-IN"` (default), `"te-IN"` for Telugu UI and messages, or any Indian locale code |
65
+ | `theme` | `default`, `high-contrast`, `dark`, `color-blind`, `dyslexia` |
66
+ | `view`, `mobileBreakpoint` | `table`, `card` or `auto` (cards below 640px) |
67
+ | `pagination` | `{ pageSize, showSizeChanger, sizeOptions }`, or `false` |
68
+ | `search`, `selectable`, `exportable` | `false` turns each one off |
69
+ | `selectedKeys`, `highlightIds`, `autoScrollToHighlight` | Initial state |
70
+ | `loading`, `empty` | Loading state; empty message (text or a node) |
71
+ | `agentic` | `true` or `{ title, placeholder, examples, hint }`: the question bar |
72
+ | `ai`, `inputLanguage`, `assistantExamples` | Built-in assistant with voice input |
73
+ | `customRules` | `[{ name, phrases, description, execute({ input, data, columns, executeTool }) }]`, in any language |
74
+ | `parseIntent(text, ctx)` | Replace the built-in phrase parser |
75
+ | `webmcp`, `toolName`, `toolDescriptions`, `onWebMCPStatusChange` | Expose the 11 grid tools to browser AI agents |
76
+ | `referenceDate` | "Now" for "this month" questions |
77
+ | `onRowClick(row)`, `onOpenRow(id)` | Enables the `open` tool and "open Ravi" |
78
+ | `onSelectionChange(keys)`, `onSortChange(sort)`, `onFiltersChange(filters)`, `onAgentResult(r)` | Events |
79
+ | `wrap`, `maxHeight`, `showTitle`, `className` | Layout |
80
+
81
+ **Keyboard:** Tab into the table, then use the arrow keys to move between cells.
82
+
83
+ - Home / End go to the first or last cell in a row; Ctrl+Home / Ctrl+End go to the first or last cell in the table.
84
+ - Page Up / Page Down change the page.
85
+ - Space selects a row; Enter sorts (on a column header) or opens the row.
86
+ - Only one cell is in the Tab order.
87
+
88
+ ### Grid API
89
+
90
+ ```js
91
+ await grid.ask("salary over 1 lakh in Hyderabad") // answer text (useAgenticGrid)
92
+ await grid.askDetailed("average salary by department") // { answer, kind, table, steps, gridData, … }
93
+ await grid.assistantAsk("sort by salary desc") // assistant pipeline result
94
+ await grid.executeTool("filter", { key: "salary", operator: "greaterThan", value: 100000 })
95
+ grid.search("Pune"); grid.setFilters([...]); grid.clearFilters(); grid.sortBy("name", "desc"); grid.clearSort()
96
+ grid.highlight(["1001"]); grid.clearHighlight(); grid.select(["1001"]); grid.getSelectedRows()
97
+ grid.goToPage(3); grid.nextPage(); grid.prevPage(); grid.setPageSize(50); grid.getPage()
98
+ grid.setTheme("dark"); grid.setView("card"); grid.setLoading(true)
99
+ grid.getRows(); grid.getPageRows(); grid.getData(); grid.refresh(newRows); grid.setData(rows, columns)
100
+ grid.biSummary(); grid.anomalies(); grid.exportCSV(); grid.reset(); grid.destroy()
101
+ grid.tools; grid.agent; grid.agentic; grid.webmcpStatus
102
+ ```
103
+
104
+ Tool results are always `{ success, message, data?, error?: { code } }` and never throw. The error codes are `NOT_FOUND`, `NOT_SUPPORTED`, `INVALID_INPUT`, `INTERNAL` and `NOT_UNDERSTOOD`.
105
+
106
+ ## Without a grid
107
+
108
+ ```js
109
+ const agentic = yuktai.createAgenticGrid({ data: rows, columns, rowKey: "id" }) // useAgenticGrid
110
+ yuktai.mountAgenticGridBar("#bar", agentic, { examples: ["salary under 50k"] }) // AgenticGridBar
111
+ agentic.subscribe((s) => drawMyTable(s.gridData, s.highlightIds))
112
+
113
+ const tools = yuktai.createGridTools({ data: rows, columns, rowKey: "id", onFiltersChange, onSortChange }, { name: "my_grid" })
114
+ const agent = yuktai.createGridAgent({ tools, columns, customRules, locale: "te" }) // useYuktaiGridAgent
115
+ await agent.ask("ఎన్ని")
116
+ yuktai.registerWebMCP(tools, { onStatusChange: console.log }) // YuktaiGridWebMCP
117
+ ```
118
+
119
+ ## Page tools
120
+
121
+ ```js
122
+ yuktai.mountAgenticPanel("#tools", { defaultTab: "qa", voiceLang: "te-IN" }) // AgenticPanel, six tabs
123
+ ```
124
+
125
+ The panel is marked `data-yuktai-panel`, so the agents never audit their own UI.
126
+
127
+ ## Core functions (same as npm)
128
+
129
+ - **Grid queries:** `parseAmount`, `parseGridQuery`, `executeGridQuery`, `runGridQuery`, `answerGridQuestion`, `detectAnomalies`, `summarizeRows`
130
+ - **BI:** `askInsight`, `groupBy`, `comparePeriods`, `trend`, `aggregate`
131
+ - **Tasks:** `planTasks`, `runTasks`
132
+ - **QA:** `runQaAudit`, `auditToMarkdown`, `auditToJSON`, `AUDIT_RULES`
133
+ - **Copilot:** `createA11yCopilot`
134
+ - **Page understanding:** `askAboutPage`, `analyzePage`, `detectPageIntent`
135
+ - **Page and data RAG:** `createContextIndex`, `tokenize`
136
+ - **Forms and design:** `reviewForms`, `reviewForm`, `readFormFields`, `reviewDesign`
137
+ - **Voice:** `parseVoiceA11yCommand`, `createVoiceA11yController`, `moveGridRowFocus`
138
+ - **Grid tools:** `createGridTools`, `getRowId`, `applyGridFilters`, `toGridToolColumns`, and each tool function
139
+ - **Other:** `contrastRatio`, `parseColor`, `relativeLuminance`, `accessibleName`, `wcagPlugin`
140
+ - **Icons:** `icon(name, size, label?)` and `iconNames`
141
+
142
+ ## Build and test
143
+
144
+ ```bash
145
+ npm i -D esbuild # once
146
+ node vanilla/build.mjs # → vanilla/index.js and vanilla/index.min.js
147
+
148
+ # End-to-end checks in real Chromium (37 checks plus axe-core)
149
+ npm i -D playwright-core axe-core
150
+ CHROME=/path/to/chrome node vanilla/test/e2e.mjs
151
+ ```
152
+
153
+ Edit `vanilla/src/*` or `src/*`, then rebuild. Do not edit `vanilla/index.js` by hand.
154
+
155
+ ## Honest limits
156
+
157
+ - Questions are understood with rules, not a language model, so unusual phrasing may need rewording. Telugu and Hindi data questions need custom rules.
158
+ - QA, form and design checks are heuristics. Test with a keyboard and a screen reader before release.
159
+ - Voice depends on the browser's speech recognition. Typed commands always work.
160
+ - WebMCP needs `document.modelContext`. The real status is always reported.
161
+ - Filtering and paging run in the browser and suit a few thousand rows. For 100K+ rows, page on the server and call `grid.refresh(pageRows)`.
162
+ - The floating buttons are added under `<html>` (not `<body>`), so the colour-blind filter on `<body>` cannot move them.