@manototh/do11y 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/do11y.js CHANGED
@@ -1,6 +1,6 @@
1
1
  (function() {
2
2
  //#region src/do11y.ts
3
- const VERSION = "0.0.3";
3
+ const VERSION = "0.0.4";
4
4
  const _alreadyLoaded = !!window.__do11yInitialized;
5
5
  window.__do11yInitialized = true;
6
6
  const config = {
@@ -47,7 +47,7 @@
47
47
  const FRAMEWORK_PRESETS = {
48
48
  mintlify: {
49
49
  searchSelector: "#search-bar-entry, #search-bar-entry-mobile, [class*=\"search\"]",
50
- copyButtonSelector: "[class*=\"copy\"], button[aria-label*=\"copy\" i]",
50
+ copyButtonSelector: "button[class*=\"copy\"], button[aria-label*=\"copy\" i]",
51
51
  codeBlockSelector: "pre, [class*=\"code\"]",
52
52
  navigationSelector: "nav, [role=\"navigation\"], #navbar, #sidebar, [class*=\"nav\"], [class*=\"sidebar\"]",
53
53
  footerSelector: "footer, [role=\"contentinfo\"], [class*=\"footer\"]",
@@ -78,17 +78,6 @@
78
78
  tocSelector: ".nextra-toc, [class*=\"toc\"]",
79
79
  feedbackSelector: "[class*=\"feedback\"], [class*=\"helpful\"]"
80
80
  },
81
- gitbook: {
82
- searchSelector: "[data-testid*=\"search\"], button[aria-label*=\"search\" i]",
83
- copyButtonSelector: "[class*=\"copy\"], button[aria-label*=\"copy\" i]",
84
- codeBlockSelector: "pre, code, [class*=\"code\"]",
85
- navigationSelector: "nav, [role=\"navigation\"], [class*=\"nav\"], [class*=\"sidebar\"]",
86
- footerSelector: "footer, [role=\"contentinfo\"], [class*=\"footer\"]",
87
- contentSelector: "main, article, [role=\"main\"], [class*=\"content\"]",
88
- tabContainerSelector: "[role=\"tablist\"], [class*=\"tab\"]",
89
- tocSelector: "[class*=\"table-of-contents\"], [class*=\"toc\"], [class*=\"page-outline\"]",
90
- feedbackSelector: "[class*=\"feedback\"], [class*=\"helpful\"], [class*=\"rating\"]"
91
- },
92
81
  "mkdocs-material": {
93
82
  searchSelector: ".md-search__input",
94
83
  copyButtonSelector: ".md-clipboard, .md-code__button[title=\"Copy to clipboard\"]",
@@ -110,6 +99,17 @@
110
99
  tabContainerSelector: ".vp-code-group .tabs, [role=\"tablist\"]",
111
100
  tocSelector: ".VPDocAsideOutline, .VPLocalNavOutlineDropdown, a.outline-link",
112
101
  feedbackSelector: "[class*=\"feedback\"], [class*=\"helpful\"]"
102
+ },
103
+ starlight: {
104
+ searchSelector: "site-search button[data-open-modal], sl-doc-search .DocSearch-Button, button[aria-label*=\"search\" i]",
105
+ copyButtonSelector: ".expressive-code .copy button, .copy button[data-code]",
106
+ codeBlockSelector: ".expressive-code pre, pre",
107
+ navigationSelector: "nav, [role=\"navigation\"], [class*=\"sidebar\"]",
108
+ footerSelector: "footer, [role=\"contentinfo\"], [class*=\"footer\"]",
109
+ contentSelector: "main, .sl-markdown-content, [role=\"main\"]",
110
+ tabContainerSelector: "starlight-tabs [role=\"tablist\"], [role=\"tablist\"]",
111
+ tocSelector: ".right-sidebar-panel, starlight-toc, mobile-starlight-toc",
112
+ feedbackSelector: "[class*=\"feedback\"], [class*=\"helpful\"]"
113
113
  }
114
114
  };
115
115
  const SELECTOR_KEYS = [
@@ -213,6 +213,11 @@
213
213
  if (fromClass) return fromClass;
214
214
  const langText = el.querySelector(":scope > span.lang")?.textContent?.trim();
215
215
  if (langText) return langText;
216
+ const deepLang = el.querySelector("[data-language], [data-lang], [data-code-lang], [class*=\"language-\"], [language]");
217
+ if (deepLang) {
218
+ const dl = deepLang.getAttribute("language") ?? deepLang.getAttribute("data-language") ?? deepLang.getAttribute("data-lang") ?? deepLang.getAttribute("data-code-lang") ?? languageFromClassName(getElementClassName(deepLang));
219
+ if (dl) return dl;
220
+ }
216
221
  }
217
222
  return "unknown";
218
223
  }
@@ -225,10 +230,10 @@
225
230
  return null;
226
231
  }
227
232
  function resolveTocContainer(link) {
228
- const selector = validateSelector(config.tocSelector) ?? ".table-of-contents, .VPDocAsideOutline, .VPLocalNavOutlineDropdown, [class*=\"toc\"], [class*=\"TableOfContents\"], [class*=\"page-outline\"]";
233
+ const selector = validateSelector(config.tocSelector) ?? ".table-of-contents, .VPDocAsideOutline, .VPLocalNavOutlineDropdown, [class*=\"toc\"], [class*=\"TableOfContents\"], [class*=\"page-outline\"], .right-sidebar-panel, starlight-toc";
229
234
  let container = link.closest(selector);
230
235
  if (!container) return null;
231
- if (container === link || container.tagName === "A") container = link.closest(".VPDocAsideOutline, .VPLocalNavOutlineDropdown, nav, aside") ?? container.parentElement;
236
+ if (container === link || container.tagName === "A") container = link.closest(".VPDocAsideOutline, .VPLocalNavOutlineDropdown, nav, aside, .right-sidebar-panel, starlight-toc") ?? container.parentElement;
232
237
  return container;
233
238
  }
234
239
  function sanitizeText(text, maxLength) {
@@ -728,7 +733,7 @@
728
733
  /**
729
734
  * Track scroll depth.
730
735
  *
731
- * Some frameworks (GitBook/HonKit, MkDocs Material) use container-based
736
+ * Some frameworks (MkDocs Material) use container-based
732
737
  * scrolling where the window itself never scrolls. We detect the scrollable
733
738
  * container by walking up from the content element and listen on it in
734
739
  * addition to the window.
@@ -850,7 +855,7 @@
850
855
  function setupSearchTracking() {
851
856
  document.addEventListener("click", (e) => {
852
857
  if (e.target.closest(config.searchSelector)) queueEvent("search_opened", {});
853
- });
858
+ }, true);
854
859
  document.addEventListener("keydown", (e) => {
855
860
  if ((e.metaKey || e.ctrlKey) && e.key === "k") queueEvent("search_opened", { trigger: "keyboard" });
856
861
  });
@@ -867,9 +872,9 @@
867
872
  document.addEventListener("click", (e) => {
868
873
  const copyButton = e.target.closest(config.copyButtonSelector);
869
874
  if (copyButton) {
870
- const codeBlock = copyButton.closest("[class*=\"language-\"]") ?? copyButton.closest(config.codeBlockSelector) ?? copyButton.closest("div, section")?.querySelector("pre") ?? copyButton.parentElement?.querySelector("pre") ?? null;
875
+ const codeBlock = copyButton.closest("[class*=\"language-\"], [language]") ?? copyButton.closest(config.codeBlockSelector) ?? copyButton.closest(".expressive-code")?.querySelector("pre") ?? copyButton.closest("div, section")?.querySelector("pre") ?? copyButton.parentElement?.querySelector("pre") ?? null;
871
876
  queueEvent("code_copied", {
872
- language: extractCodeLanguage((codeBlock ? codeBlock.tagName === "PRE" ? codeBlock.querySelector("code") : codeBlock.querySelector("code[class*=\"language-\"]") ?? codeBlock.querySelector("code") : null) ?? codeBlock ?? copyButton),
877
+ language: extractCodeLanguage((codeBlock ? codeBlock.tagName === "PRE" ? codeBlock.querySelector("code") : codeBlock.querySelector("code[class*=\"language-\"], code[language]") ?? codeBlock.querySelector("code") : null) ?? codeBlock ?? copyButton),
873
878
  codeSection: sanitizeText(getNearestHeading(codeBlock ?? copyButton), 100),
874
879
  codeBlockIndex: getCodeBlockIndex(codeBlock)
875
880
  });
package/dist/do11y.min.js CHANGED
@@ -1 +1 @@
1
- (function(){let e=`0.0.3`,t=!!window.__do11yInitialized;window.__do11yInitialized=!0;let n={destination:`supabase`,supabaseUrl:``,supabaseKey:``,supabaseTable:`do11y_events`,httpEndpoint:``,httpHeaders:{},debug:!1,flushInterval:5e3,maxBatchSize:10,trackOutboundLinks:!0,trackInternalLinks:!0,trackScrollDepth:!0,scrollThresholds:[25,50,75,90],allowedDomains:null,respectDNT:!0,maxRetries:2,retryDelay:1e3,rateLimitMs:100,framework:`mintlify`,trackSectionVisibility:!0,sectionVisibleThreshold:3,trackTabSwitches:!0,trackTocClicks:!0,trackExpandCollapse:!0,trackFeedback:!0,tabContainerSelector:null,tocSelector:null,feedbackSelector:null,searchSelector:null,copyButtonSelector:null,codeBlockSelector:null,navigationSelector:null,footerSelector:null,contentSelector:null},r={mintlify:{searchSelector:`#search-bar-entry, #search-bar-entry-mobile, [class*="search"]`,copyButtonSelector:`[class*="copy"], button[aria-label*="copy" i]`,codeBlockSelector:`pre, [class*="code"]`,navigationSelector:`nav, [role="navigation"], #navbar, #sidebar, [class*="nav"], [class*="sidebar"]`,footerSelector:`footer, [role="contentinfo"], [class*="footer"]`,contentSelector:`main, article, [role="main"], [class*="content"]`,tabContainerSelector:`[role="tablist"], [class*="tab"]`,tocSelector:`#table-of-contents, [data-testid="table-of-contents"], [class*="table-of-contents"], [class*="toc"]`,feedbackSelector:`[class*="feedback"], [class*="helpful"]`},docusaurus:{searchSelector:`.DocSearch, .DocSearch-Button`,copyButtonSelector:`button.clean-btn[aria-label*="copy" i], button[class*="copyButton"]`,codeBlockSelector:`pre, [class*="code"]`,navigationSelector:`nav, [role="navigation"], .navbar, .sidebar, [class*="nav"], [class*="sidebar"]`,footerSelector:`footer, [role="contentinfo"], [class*="footer"]`,contentSelector:`main, article, [role="main"], [class*="content"]`,tabContainerSelector:`.tabs[role="tablist"], [class*="tabs"]`,tocSelector:`.table-of-contents, [class*="toc"]`,feedbackSelector:`[class*="feedback"], [class*="helpful"]`},nextra:{searchSelector:`.nextra-search input, input[placeholder*="search" i], button[aria-label*="search" i]`,copyButtonSelector:`button[class*="copy"], button[aria-label*="copy" i], button[title*="copy" i]`,codeBlockSelector:`pre, [class*="code"]`,navigationSelector:`nav, [role="navigation"], [class*="nav"], [class*="sidebar"]`,footerSelector:`footer, [role="contentinfo"], [class*="footer"]`,contentSelector:`main, article, [role="main"], [class*="content"]`,tabContainerSelector:`[role="tablist"], [class*="tab"]`,tocSelector:`.nextra-toc, [class*="toc"]`,feedbackSelector:`[class*="feedback"], [class*="helpful"]`},gitbook:{searchSelector:`[data-testid*="search"], button[aria-label*="search" i]`,copyButtonSelector:`[class*="copy"], button[aria-label*="copy" i]`,codeBlockSelector:`pre, code, [class*="code"]`,navigationSelector:`nav, [role="navigation"], [class*="nav"], [class*="sidebar"]`,footerSelector:`footer, [role="contentinfo"], [class*="footer"]`,contentSelector:`main, article, [role="main"], [class*="content"]`,tabContainerSelector:`[role="tablist"], [class*="tab"]`,tocSelector:`[class*="table-of-contents"], [class*="toc"], [class*="page-outline"]`,feedbackSelector:`[class*="feedback"], [class*="helpful"], [class*="rating"]`},"mkdocs-material":{searchSelector:`.md-search__input`,copyButtonSelector:`.md-clipboard, .md-code__button[title="Copy to clipboard"]`,codeBlockSelector:`pre, code, [class*="code"]`,navigationSelector:`nav, [role="navigation"], .md-nav, .md-sidebar`,footerSelector:`footer, [role="contentinfo"], .md-footer`,contentSelector:`main, article, [role="main"], .md-content`,tabContainerSelector:`.tabbed-labels, .md-typeset .tabbed-set`,tocSelector:`.md-sidebar--secondary .md-nav, [class*="toc"]`,feedbackSelector:`[class*="feedback"], [class*="helpful"]`},vitepress:{searchSelector:`.VPNavBarSearch button, .VPNavBarSearchButton, #local-search`,copyButtonSelector:`button.copy, .vp-code-copy, button.copy[title*="Copy"]`,codeBlockSelector:`div[class*="language-"], pre, [class*="code"]`,navigationSelector:`nav, [role="navigation"], .VPNav, .VPSidebar, [class*="nav"], [class*="sidebar"]`,footerSelector:`footer, [role="contentinfo"], .VPFooter, [class*="footer"]`,contentSelector:`main, article, [role="main"], .VPContent, [class*="content"]`,tabContainerSelector:`.vp-code-group .tabs, [role="tablist"]`,tocSelector:`.VPDocAsideOutline, .VPLocalNavOutlineDropdown, a.outline-link`,feedbackSelector:`[class*="feedback"], [class*="helpful"]`}},i=[`searchSelector`,`copyButtonSelector`,`codeBlockSelector`,`navigationSelector`,`footerSelector`,`contentSelector`,`tabContainerSelector`,`tocSelector`,`feedbackSelector`];function a(){let e=r[n.framework];e?i.forEach(t=>{n[t]||(n[t]=e[t])}):n.framework!==`custom`&&n.debug&&console.warn(`[Do11y] Unknown framework "${n.framework}". Falling back to generic selectors. Supported: `+Object.keys(r).join(`, `)+`, custom`);let t=r.mintlify;t&&i.forEach(e=>{n[e]||(n[e]=t[e])})}function o(){if(n.respectDNT&&(navigator.doNotTrack===`1`||navigator.doNotTrack===`yes`||window.doNotTrack===`1`))return n.debug&&console.log(`[Do11y] Disabled: Do Not Track is enabled`),!0;if(n.allowedDomains&&n.allowedDomains.length>0){let e=window.location.hostname;if(!n.allowedDomains.some(t=>e===t||e.endsWith(`.`+t)))return n.debug&&console.log(`[Do11y] Disabled: Domain not allowed:`,e),!0}return!1}function s(e){if(!e||typeof e!=`string`)return null;try{return document.querySelector(e),e}catch{return n.debug&&console.warn(`[Do11y] Invalid CSS selector rejected:`,e),null}}let c=[`/pixel/`];function l(e){let t=e??window.location.pathname;return c.some(e=>t.startsWith(e))}function u(e){if(typeof e.className==`string`)return e.className;let t=e.className;return t&&typeof t.baseVal==`string`?t.baseVal:``}function d(e){let t=e.match(/(?:^|\s)language-([\w-]+)(?:\s|$)/);return t?t[1]:null}function f(e){if(!e)return`unknown`;let t=e;for(let e=0;t&&e<12;e++,t=t.parentElement){for(let e of[`language`,`data-language`,`data-lang`,`data-code-lang`]){let n=t.getAttribute(e);if(n)return n}let e=d(u(t));if(e)return e;let n=t.querySelector(`:scope > span.lang`)?.textContent?.trim();if(n)return n}return`unknown`}function ee(e){if(e.startsWith(`#`))return e;let t=e.indexOf(`#`);if(t===-1)return null;let n=e.slice(0,t);return!n||n===window.location.pathname||n===`${window.location.pathname}${window.location.search}`?e.slice(t):null}function te(e){let t=s(n.tocSelector)??`.table-of-contents, .VPDocAsideOutline, .VPLocalNavOutlineDropdown, [class*="toc"], [class*="TableOfContents"], [class*="page-outline"]`,r=e.closest(t);return r?((r===e||r.tagName===`A`)&&(r=e.closest(`.VPDocAsideOutline, .VPLocalNavOutlineDropdown, nav, aside`)??r.parentElement),r):null}function p(e,t){if(!e||typeof e!=`string`)return null;let n=t??100,r=e;return r=r.replace(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,`[email]`),r=r.replace(/\b\d{3}[-.]?\d{3}[-.]?\d{4}\b/g,`[phone]`),r=r.replace(/\b\d{3}-\d{2}-\d{4}\b/g,`[redacted]`),r=r.replace(/\b(?:\d[ -]?){13,19}\b/g,`[card]`),r=r.replace(/eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g,`[token]`),r=r.replace(/\bxa[a-z]{2}-[A-Za-z0-9_-]{20,}/g,`[token]`),r=r.replace(/\b[0-9a-fA-F]{32,}\b/g,`[redacted]`),r.trim().substring(0,n)}function m(){if(window.crypto&&typeof window.crypto.randomUUID==`function`)return window.crypto.randomUUID();if(window.crypto&&typeof window.crypto.getRandomValues==`function`){let e=new Uint8Array(16);window.crypto.getRandomValues(e),e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t=Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``);return t.slice(0,8)+`-`+t.slice(8,12)+`-`+t.slice(12,16)+`-`+t.slice(16,20)+`-`+t.slice(20)}return`no-crypto-00-0000-0000-000000000000`}function ne(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.id==`string`&&t.id.length>0&&typeof t.startTime==`string`&&Array.isArray(t.pageSequence)&&typeof t.pageCount==`number`}function h(){let e=null;try{let t=sessionStorage.getItem(`do11y_session`);if(t){let n=JSON.parse(t);ne(n)&&(e=n)}}catch{}return e||(e={id:m(),startTime:new Date().toISOString(),pageSequence:[],pageCount:0,referrerCategory:null,aiPlatform:null},g(e)),e}function g(e){try{sessionStorage.setItem(`do11y_session`,JSON.stringify(e))}catch{}}function re(e){let t=h();return t.pageCount++,t.pageSequence.push({path:e,timestamp:new Date().toISOString(),index:t.pageCount}),t.pageSequence.length>50&&(t.pageSequence=t.pageSequence.slice(-50)),g(t),t}function ie(){return{viewportCategory:ae(),browserFamily:_(),deviceType:v(),language:(navigator.language||``).split(`-`)[0]||`unknown`,timezoneOffset:new Date().getTimezoneOffset()/60}}function ae(){let e=window.innerWidth;return e<640?`mobile`:e<1024?`tablet`:e<1440?`desktop`:`large-desktop`}function _(){let e=navigator.userAgent;return e.includes(`Firefox`)?`Firefox`:e.includes(`Edg`)?`Edge`:e.includes(`Chrome`)?`Chrome`:e.includes(`Safari`)?`Safari`:`Other`}function v(){let e=navigator.userAgent;return/Mobile|Android|iPhone|iPad/.test(e)?/iPad|Tablet/.test(e)?`tablet`:`mobile`:`desktop`}let y=[{match:`chatgpt`,platform:`ChatGPT`},{match:`chat.com`,platform:`ChatGPT`},{match:`openai`,platform:`ChatGPT`},{match:`perplexity`,platform:`Perplexity`},{match:`claude.ai`,platform:`Claude`},{match:`anthropic`,platform:`Claude`},{match:`gemini`,platform:`Gemini`},{match:`copilot`,platform:`Copilot`},{match:`deepseek`,platform:`DeepSeek`},{match:`meta.ai`,platform:`Meta AI`},{match:`grok`,platform:`Grok`},{match:`x.ai`,platform:`Grok`},{match:`mistral`,platform:`Mistral`},{match:`you.com`,platform:`You.com`},{match:`phind`,platform:`Phind`}];function b(e){if(!e||e===`direct`)return{referrerCategory:`direct`,aiPlatform:null};if(e===`internal`)return{referrerCategory:`internal`,aiPlatform:null};if(e===`unknown`)return{referrerCategory:`unknown`,aiPlatform:null};let t=e.toLowerCase();for(let e of y)if(t.indexOf(e.match)!==-1)return{referrerCategory:`ai`,aiPlatform:e.platform};return/google\.|bing\.|baidu\.|yandex\.|duckduckgo\.|yahoo\./.test(t)?{referrerCategory:`search-engine`,aiPlatform:null}:/github\.|gitlab\.|bitbucket\./.test(t)?{referrerCategory:`code-host`,aiPlatform:null}:/stackoverflow\.|stackexchange\.|reddit\.|news\.ycombinator\./.test(t)?{referrerCategory:`community`,aiPlatform:null}:/twitter\.|x\.com|linkedin\.|facebook\.|threads\.net/.test(t)?{referrerCategory:`social`,aiPlatform:null}:{referrerCategory:`other`,aiPlatform:null}}function x(){try{if(!document.referrer)return`direct`;let e=new URL(document.referrer);return e.hostname===window.location.hostname?`internal`:e.hostname}catch{return`unknown`}}function S(){return{path:window.location.pathname,hash:window.location.hash||null,search:window.location.search?`has_params`:null,title:p(document.title,150)}}let C=[],w=null,T={},E=!1;function D(t,r){if(E)return;let i=Date.now();if(n.rateLimitMs>0&&T[t]&&i-T[t]<n.rateLimitMs){n.debug&&console.log(`[Do11y] Rate limited:`,t);return}T[t]=i;let a=h(),o={_time:new Date().toISOString(),eventType:t,do11y_version:e,sessionId:a.id,sessionPageCount:a.pageCount,...S(),...ie(),...r};n.debug&&console.log(`[Do11y] Event queued:`,o),C.push(o),C.length>100&&(C=C.slice(-100),n.debug&&console.warn(`[Do11y] Event queue capped at 100 events`)),C.length>=n.maxBatchSize?A():oe()}function oe(){w||=setTimeout(A,n.flushInterval)}function se(e){try{let t=new URL(e);return!(t.protocol!==`https:`||!t.hostname.endsWith(`.supabase.co`))}catch{return!1}}function ce(e){try{let t=new URL(e);if(t.protocol!==`https:`)return!1;let n=t.hostname;return!(n===`localhost`||n===`127.0.0.1`||n===`::1`||/^(10\.|172\.(1[6-9]|2\d|3[01])\.|192\.168\.)/.test(n))}catch{return!1}}function O(){return n.destination===`supabase`?n.supabaseUrl?se(n.supabaseUrl)?!n.supabaseKey||typeof n.supabaseKey!=`string`||n.supabaseKey.length<10?(n.debug&&console.warn(`[Do11y] Invalid or missing Supabase publishable key`),!1):/^[a-zA-Z0-9_-]+$/.test(n.supabaseTable)?!0:(n.debug&&console.warn(`[Do11y] Invalid table name`),!1):(n.debug&&console.warn(`[Do11y] Invalid Supabase URL. Must be https://<project>.supabase.co`),!1):(n.debug&&console.warn(`[Do11y] No Supabase URL configured`),!1):n.destination===`http`?n.httpEndpoint?ce(n.httpEndpoint)?!0:(n.debug&&console.warn(`[Do11y] Invalid HTTP endpoint. Must be HTTPS and not a private address.`),!1):(n.debug&&console.warn(`[Do11y] No HTTP endpoint configured`),!1):(n.debug&&console.warn(`[Do11y] Unknown destination:`,n.destination),!1)}function k(e){return n.destination===`supabase`?{url:n.supabaseUrl.replace(/\/$/,``)+`/rest/v1/`+n.supabaseTable,headers:{apikey:n.supabaseKey,Authorization:`Bearer `+n.supabaseKey,"Content-Type":`application/json`,Prefer:`return=minimal`},body:JSON.stringify(e.map(e=>({payload:e})))}:{url:n.httpEndpoint,headers:{"Content-Type":`application/json`,...n.httpHeaders},body:JSON.stringify(e)}}function A(e){if(w&&=(clearTimeout(w),null),C.length===0||!O())return;let t=typeof e==`number`?e:n.maxRetries,r=C.slice();C=[],le(k(r),r,t)}function le(e,t,r){fetch(e.url,{method:`POST`,headers:e.headers,body:e.body,keepalive:!0}).then(e=>{if(e.ok){n.debug&&console.log(`[Do11y] Flushed`,t.length,`events`);return}if(r>0&&(e.status>=500||e.status===429)){n.debug&&console.log(`[Do11y] Retrying after error:`,e.status),C=t.concat(C),setTimeout(()=>{A(r-1)},n.retryDelay*(n.maxRetries-r+1));return}n.debug&&e.text().then(t=>{console.error(`[Do11y] Ingest failed:`,e.status,t)}).catch(()=>{})}).catch(e=>{r>0?(n.debug&&console.log(`[Do11y] Network error, retrying:`,e.message),C=t.concat(C),setTimeout(()=>{A(r-1)},n.retryDelay*(n.maxRetries-r+1))):n.debug&&console.error(`[Do11y] Failed to send events:`,e)})}function j(){if(C.length===0||!O())return;let e=C;C=[];let t=k(e);try{fetch(t.url,{method:`POST`,headers:t.headers,body:t.body,keepalive:!0})}catch{}n.debug&&console.log(`[Do11y] Sync flushed`,e.length,`events`)}function M(){let e=re(window.location.pathname),t=x(),n=b(t);e.pageCount===1&&(e.referrerCategory=n.referrerCategory,e.aiPlatform=n.aiPlatform,g(e)),D(`page_view`,{referrerDomain:t,referrerCategory:n.referrerCategory,aiPlatform:n.aiPlatform,isFirstPage:e.pageCount===1,previousPath:e.pageSequence.length>1?e.pageSequence[e.pageSequence.length-2].path:null})}function N(){document.addEventListener(`click`,e=>{let t=e.target.closest(`a`);if(!t)return;let r=t.getAttribute(`href`);if(!r)return;let i=`other`,a=null;try{if(r.startsWith(`#`))i=`anchor`;else if(r.startsWith(`/`)||r.startsWith(`./`)||r.startsWith(`../`))i=`internal`;else if(r.startsWith(`http`)){let e=new URL(r);e.hostname===window.location.hostname?i=`internal`:(i=`external`,a=e.hostname)}else r.startsWith(`mailto:`)&&(i=`email`)}catch{}i===`internal`&&!n.trackInternalLinks||i===`external`&&!n.trackOutboundLinks||(D(`link_click`,{linkType:i,targetUrl:r,targetDomain:a,linkText:p(t.textContent,100),linkContext:P(t),linkSection:p(F(t),100),linkIndex:I(t,r)}),A())},!0)}function P(e){return e.closest(n.navigationSelector)?`navigation`:e.closest(n.footerSelector)?`footer`:e.closest(n.contentSelector)?`content`:`other`}function F(e){let t=e;for(;t&&t!==document.body;){let e=t.previousElementSibling;for(;e;){if(/^H[1-6]$/.test(e.tagName))return e.textContent?.trim().substring(0,100)??null;let t=e.querySelectorAll(`h1, h2, h3, h4, h5, h6`);if(t.length>0)return t[t.length-1].textContent?.trim().substring(0,100)??null;e=e.previousElementSibling}t=t.parentElement}return null}function I(e,t){if(typeof CSS>`u`||typeof CSS.escape!=`function`)return 1;try{let n=document.querySelectorAll(`a[href="`+CSS.escape(t)+`"]`);for(let t=0;t<n.length;t++)if(n[t]===e)return t+1}catch{}return 1}let L=new Set,R=null;function z(e){let t=e;for(;t&&t!==document.body&&t!==document.documentElement;){let e=window.getComputedStyle(t).overflowY;if((e===`auto`||e===`scroll`)&&t.scrollHeight>t.clientHeight)return t;t=t.parentElement}return null}function B(){if(!n.trackScrollDepth)return;if(n.contentSelector){let e=document.querySelector(n.contentSelector);e&&(R=z(e))}let e=!1;function t(){e||=(window.requestAnimationFrame(()=>{V(),e=!1}),!0)}if(window.addEventListener(`scroll`,t),R&&(R.addEventListener(`scroll`,t),n.debug)){let e=R;console.log(`[do11y] Using container-based scroll tracking:`,e.className||e.tagName)}V()}function V(){if(l())return;let e,t,r;R&&R.scrollHeight>R.clientHeight?(e=R.scrollTop,t=R.scrollHeight,r=R.clientHeight):(e=window.scrollY||document.documentElement.scrollTop,t=document.documentElement.scrollHeight,r=window.innerHeight);let i=t-r;if(i<=0){n.scrollThresholds.forEach(e=>{L.has(e)||(L.add(e),D(`scroll_depth`,{threshold:e,scrollPercent:100}))});return}let a=Math.round(e/i*100);n.scrollThresholds.forEach(e=>{a>=e&&!L.has(e)&&(L.add(e),D(`scroll_depth`,{threshold:e,scrollPercent:a}))})}let H=Date.now(),U=Date.now(),W=0,G=!0;function K(){if(l())return;G&&(W+=Date.now()-U);let e=Date.now()-H,t=e>0?W/e:0,n=0;L.forEach(e=>{e>n&&(n=e)}),X();let r=h();D(`page_exit`,{totalTimeSeconds:Math.round(e/1e3),activeTimeSeconds:Math.round(W/1e3),engagementRatio:Math.round(t*100)/100,maxScrollDepth:n,referrerCategory:r.referrerCategory,aiPlatform:r.aiPlatform})}function ue(){document.addEventListener(`visibilitychange`,()=>{document.hidden?G&&=(W+=Date.now()-U,!1):(U=Date.now(),G=!0)}),window.addEventListener(`beforeunload`,()=>{K(),ve()})}function de(){document.addEventListener(`click`,e=>{e.target.closest(n.searchSelector)&&D(`search_opened`,{})}),document.addEventListener(`keydown`,e=>{(e.metaKey||e.ctrlKey)&&e.key===`k`&&D(`search_opened`,{trigger:`keyboard`})})}function fe(e){if(!e)return 1;try{let t=document.querySelectorAll(n.codeBlockSelector);for(let n=0;n<t.length;n++)if(t[n]===e)return n+1}catch{}return 1}function pe(){document.addEventListener(`click`,e=>{let t=e.target.closest(n.copyButtonSelector);if(t){let e=t.closest(`[class*="language-"]`)??t.closest(n.codeBlockSelector)??t.closest(`div, section`)?.querySelector(`pre`)??t.parentElement?.querySelector(`pre`)??null;D(`code_copied`,{language:f((e?e.tagName===`PRE`?e.querySelector(`code`):e.querySelector(`code[class*="language-"]`)??e.querySelector(`code`):null)??e??t),codeSection:p(F(e??t),100),codeBlockIndex:fe(e)})}},!0)}let q=null,J={};function me(){if(!n.trackSectionVisibility||typeof IntersectionObserver>`u`)return;let e=n.sectionVisibleThreshold*1e3;q=new IntersectionObserver(t=>{t.forEach(t=>{let n=t.target.getAttribute(`data-do11y-section-id`);if(n)if(t.isIntersecting)J[n]||(J[n]={start:Date.now(),reported:!1});else{if(J[n]&&!J[n].reported){let r=Date.now()-J[n].start;r>=e&&(D(`section_visible`,{heading:p(t.target.textContent?.trim()??``,100),headingLevel:parseInt(t.target.tagName.charAt(1),10),visibleSeconds:Math.round(r/1e3)}),J[n].reported=!0)}delete J[n]}})},{threshold:.5}),Y()}function Y(){q&&document.querySelectorAll(`h2, h3`).forEach((e,t)=>{e.setAttribute(`data-do11y-section-id`,`section-`+t),q.observe(e)})}function X(){if(!q)return;let e=Date.now(),t=n.sectionVisibleThreshold*1e3;Object.keys(J).forEach(n=>{let r=J[n];if(r&&!r.reported){let i=e-r.start;if(i>=t){let e=typeof CSS<`u`&&typeof CSS.escape==`function`?CSS.escape(n):n.replace(/["\\]/g,`\\$&`),t=document.querySelector(`[data-do11y-section-id="`+e+`"]`);t&&D(`section_visible`,{heading:p(t.textContent?.trim()??``,100),headingLevel:parseInt(t.tagName.charAt(1),10),visibleSeconds:Math.round(i/1e3)})}}}),J={}}function he(){n.trackTabSwitches&&document.addEventListener(`click`,e=>{let t=`[role="tab"], .tabs button, .tabs a, .tabbed-labels label`,r=s(n.tabContainerSelector);r&&(t+=`, `+r+` button, `+r+` a, `+r+` label`);let i=e.target.closest(t);if(!i||i.getAttribute(`aria-selected`)===`true`||i.classList.contains(`active`)||i.classList.contains(`is-active`))return;let a=p(i.textContent,50);a&&D(`tab_switch`,{tabLabel:a,tabGroup:p(F(i),100),isDefault:!1})})}function Z(){n.trackTocClicks&&document.addEventListener(`click`,e=>{let t=e.target.closest(`a`);if(!t)return;let n=te(t);if(!n)return;let r=t.getAttribute(`href`),i=r?ee(r):null;if(!i)return;let a=p(t.textContent,100),o=null;try{let e=i.slice(1),t=document.getElementById(e);t&&/^H[1-6]$/.test(t.tagName)&&(o=parseInt(t.tagName.charAt(1),10))}catch{}let s=n.querySelectorAll(`a[href*="#"]`),c=1;for(let e=0;e<s.length;e++)if(s[e]===t){c=e+1;break}D(`toc_click`,{heading:a,headingLevel:o,tocPosition:c})},!0)}function ge(){n.trackFeedback&&document.addEventListener(`click`,e=>{let t=e.target.closest(`button, [role="button"], a`);if(!t||!t.closest(s(n.feedbackSelector)??`[class*="feedback"], [class*="helpful"], [class*="rating"], [class*="was-this"], [data-feedback]`))return;let r=(t.textContent??``).trim().toLowerCase(),i=(t.getAttribute(`aria-label`)??``).toLowerCase(),a=(t.getAttribute(`title`)??``).toLowerCase(),o=t.getAttribute(`data-value`)??t.getAttribute(`data-md-value`)??t.getAttribute(`data-feedback`),c=o&&/^[\w\s.,!?-]{1,50}$/.test(o)?o:null,l=null;c?l=c:/\byes\b|👍|thumbs.?up|helpful/i.test(r+` `+i+` `+a)?l=`yes`:/\bno\b|👎|thumbs.?down|not.?helpful/i.test(r+` `+i+` `+a)&&(l=`no`),l&&D(`feedback`,{rating:l})})}function _e(){n.trackExpandCollapse&&(document.addEventListener(`toggle`,e=>{let t=e.target;if(t.tagName!==`DETAILS`)return;let n=t.querySelector(`summary`);D(`expand_collapse`,{summary:p(n?n.textContent:``,100),action:t.open?`expand`:`collapse`,section:p(F(t),100)})},!0),document.addEventListener(`click`,e=>{let t=e.target.closest(`[aria-expanded], [class*="accordion"] button, [class*="collapsible"] button`);if(!t||t.closest(`details`)||t.closest(`nav, [role="navigation"], header`))return;let n=t.getAttribute(`aria-expanded`)===`true`;D(`expand_collapse`,{summary:p(t.textContent,100),action:n?`collapse`:`expand`,section:p(F(t),100)})}))}let Q=null;function $(){if(window.Do11yConfig&&typeof window.Do11yConfig==`object`)for(let e in window.Do11yConfig)Object.prototype.hasOwnProperty.call(window.Do11yConfig,e)&&Object.prototype.hasOwnProperty.call(n,e)&&(n[e]=window.Do11yConfig[e]);let e=document.querySelector(`meta[name="do11y-destination"]`);if(e){let t=e.getAttribute(`content`);(t===`supabase`||t===`http`)&&(n.destination=t)}let t=document.querySelector(`meta[name="do11y-url"]`);t&&(n.supabaseUrl=t.getAttribute(`content`)??n.supabaseUrl);let r=document.querySelector(`meta[name="do11y-key"]`);r&&(n.supabaseKey=r.getAttribute(`content`)??n.supabaseKey);let i=document.querySelector(`meta[name="do11y-table"]`);i&&(n.supabaseTable=i.getAttribute(`content`)??n.supabaseTable);let s=document.querySelector(`meta[name="do11y-http-endpoint"]`);s&&(n.httpEndpoint=s.getAttribute(`content`)??n.httpEndpoint);let c=document.querySelector(`meta[name="do11y-debug"]`);c&&c.getAttribute(`content`)===`true`&&(n.debug=!0);let l=document.querySelector(`meta[name="do11y-domains"]`);if(l){let e=l.getAttribute(`content`);e&&(n.allowedDomains=e.split(`,`).map(e=>e.trim()))}let u=document.querySelector(`meta[name="do11y-framework"]`);if(u&&(n.framework=u.getAttribute(`content`)??n.framework),a(),n.debug&&console.log(`[Do11y] Initializing with config:`,{destination:n.destination,hasCredentials:n.destination===`supabase`?!!n.supabaseKey:!!n.httpEndpoint,framework:n.framework,allowedDomains:n.allowedDomains,respectDNT:n.respectDNT}),o()){E=!0,n.debug&&console.log(`[Do11y] Tracking disabled`);return}(n.destination===`supabase`?n.supabaseKey:n.httpEndpoint)||n.debug&&(console.warn(`[Do11y] No destination configured. Events will not be sent.`),console.warn(`[Do11y] Add <meta name="do11y-url"> and <meta name="do11y-key"> to enable.`)),M(),N(),B(),ue(),de(),pe(),me(),he(),Z(),ge(),_e();let d=window.location.pathname;Q=new MutationObserver(()=>{window.location.pathname!==d&&(d=window.location.pathname,K(),L=new Set,H=Date.now(),U=Date.now(),W=0,G=!0,M(),Y(),V())}),Q.observe(document.body,{childList:!0,subtree:!0}),window.addEventListener(`popstate`,()=>{window.location.pathname!==d&&(d=window.location.pathname,K(),L=new Set,H=Date.now(),U=Date.now(),W=0,G=!0,M(),Y(),V())}),Object.freeze(n),n.debug&&console.log(`[Do11y] Initialized successfully`)}function ve(){Q&&=(Q.disconnect(),null),q&&=(X(),q.disconnect(),null),w&&=(clearTimeout(w),null),j()}t||(document.readyState===`loading`?document.addEventListener(`DOMContentLoaded`,$):$()),window.Do11y=window.Do11y??{getConfig:()=>({destination:n.destination,hasCredentials:n.destination===`supabase`?!!n.supabaseKey:!!n.httpEndpoint,isDisabled:E,allowedDomains:n.allowedDomains,respectDNT:n.respectDNT}),flush:A,isEnabled:()=>!E&&(n.destination===`supabase`?!!n.supabaseKey:!!n.httpEndpoint),getQueueSize:()=>C.length,version:e}})();
1
+ (function(){let e=`0.0.4`,t=!!window.__do11yInitialized;window.__do11yInitialized=!0;let n={destination:`supabase`,supabaseUrl:``,supabaseKey:``,supabaseTable:`do11y_events`,httpEndpoint:``,httpHeaders:{},debug:!1,flushInterval:5e3,maxBatchSize:10,trackOutboundLinks:!0,trackInternalLinks:!0,trackScrollDepth:!0,scrollThresholds:[25,50,75,90],allowedDomains:null,respectDNT:!0,maxRetries:2,retryDelay:1e3,rateLimitMs:100,framework:`mintlify`,trackSectionVisibility:!0,sectionVisibleThreshold:3,trackTabSwitches:!0,trackTocClicks:!0,trackExpandCollapse:!0,trackFeedback:!0,tabContainerSelector:null,tocSelector:null,feedbackSelector:null,searchSelector:null,copyButtonSelector:null,codeBlockSelector:null,navigationSelector:null,footerSelector:null,contentSelector:null},r={mintlify:{searchSelector:`#search-bar-entry, #search-bar-entry-mobile, [class*="search"]`,copyButtonSelector:`button[class*="copy"], button[aria-label*="copy" i]`,codeBlockSelector:`pre, [class*="code"]`,navigationSelector:`nav, [role="navigation"], #navbar, #sidebar, [class*="nav"], [class*="sidebar"]`,footerSelector:`footer, [role="contentinfo"], [class*="footer"]`,contentSelector:`main, article, [role="main"], [class*="content"]`,tabContainerSelector:`[role="tablist"], [class*="tab"]`,tocSelector:`#table-of-contents, [data-testid="table-of-contents"], [class*="table-of-contents"], [class*="toc"]`,feedbackSelector:`[class*="feedback"], [class*="helpful"]`},docusaurus:{searchSelector:`.DocSearch, .DocSearch-Button`,copyButtonSelector:`button.clean-btn[aria-label*="copy" i], button[class*="copyButton"]`,codeBlockSelector:`pre, [class*="code"]`,navigationSelector:`nav, [role="navigation"], .navbar, .sidebar, [class*="nav"], [class*="sidebar"]`,footerSelector:`footer, [role="contentinfo"], [class*="footer"]`,contentSelector:`main, article, [role="main"], [class*="content"]`,tabContainerSelector:`.tabs[role="tablist"], [class*="tabs"]`,tocSelector:`.table-of-contents, [class*="toc"]`,feedbackSelector:`[class*="feedback"], [class*="helpful"]`},nextra:{searchSelector:`.nextra-search input, input[placeholder*="search" i], button[aria-label*="search" i]`,copyButtonSelector:`button[class*="copy"], button[aria-label*="copy" i], button[title*="copy" i]`,codeBlockSelector:`pre, [class*="code"]`,navigationSelector:`nav, [role="navigation"], [class*="nav"], [class*="sidebar"]`,footerSelector:`footer, [role="contentinfo"], [class*="footer"]`,contentSelector:`main, article, [role="main"], [class*="content"]`,tabContainerSelector:`[role="tablist"], [class*="tab"]`,tocSelector:`.nextra-toc, [class*="toc"]`,feedbackSelector:`[class*="feedback"], [class*="helpful"]`},"mkdocs-material":{searchSelector:`.md-search__input`,copyButtonSelector:`.md-clipboard, .md-code__button[title="Copy to clipboard"]`,codeBlockSelector:`pre, code, [class*="code"]`,navigationSelector:`nav, [role="navigation"], .md-nav, .md-sidebar`,footerSelector:`footer, [role="contentinfo"], .md-footer`,contentSelector:`main, article, [role="main"], .md-content`,tabContainerSelector:`.tabbed-labels, .md-typeset .tabbed-set`,tocSelector:`.md-sidebar--secondary .md-nav, [class*="toc"]`,feedbackSelector:`[class*="feedback"], [class*="helpful"]`},vitepress:{searchSelector:`.VPNavBarSearch button, .VPNavBarSearchButton, #local-search`,copyButtonSelector:`button.copy, .vp-code-copy, button.copy[title*="Copy"]`,codeBlockSelector:`div[class*="language-"], pre, [class*="code"]`,navigationSelector:`nav, [role="navigation"], .VPNav, .VPSidebar, [class*="nav"], [class*="sidebar"]`,footerSelector:`footer, [role="contentinfo"], .VPFooter, [class*="footer"]`,contentSelector:`main, article, [role="main"], .VPContent, [class*="content"]`,tabContainerSelector:`.vp-code-group .tabs, [role="tablist"]`,tocSelector:`.VPDocAsideOutline, .VPLocalNavOutlineDropdown, a.outline-link`,feedbackSelector:`[class*="feedback"], [class*="helpful"]`},starlight:{searchSelector:`site-search button[data-open-modal], sl-doc-search .DocSearch-Button, button[aria-label*="search" i]`,copyButtonSelector:`.expressive-code .copy button, .copy button[data-code]`,codeBlockSelector:`.expressive-code pre, pre`,navigationSelector:`nav, [role="navigation"], [class*="sidebar"]`,footerSelector:`footer, [role="contentinfo"], [class*="footer"]`,contentSelector:`main, .sl-markdown-content, [role="main"]`,tabContainerSelector:`starlight-tabs [role="tablist"], [role="tablist"]`,tocSelector:`.right-sidebar-panel, starlight-toc, mobile-starlight-toc`,feedbackSelector:`[class*="feedback"], [class*="helpful"]`}},i=[`searchSelector`,`copyButtonSelector`,`codeBlockSelector`,`navigationSelector`,`footerSelector`,`contentSelector`,`tabContainerSelector`,`tocSelector`,`feedbackSelector`];function a(){let e=r[n.framework];e?i.forEach(t=>{n[t]||(n[t]=e[t])}):n.framework!==`custom`&&n.debug&&console.warn(`[Do11y] Unknown framework "${n.framework}". Falling back to generic selectors. Supported: `+Object.keys(r).join(`, `)+`, custom`);let t=r.mintlify;t&&i.forEach(e=>{n[e]||(n[e]=t[e])})}function o(){if(n.respectDNT&&(navigator.doNotTrack===`1`||navigator.doNotTrack===`yes`||window.doNotTrack===`1`))return n.debug&&console.log(`[Do11y] Disabled: Do Not Track is enabled`),!0;if(n.allowedDomains&&n.allowedDomains.length>0){let e=window.location.hostname;if(!n.allowedDomains.some(t=>e===t||e.endsWith(`.`+t)))return n.debug&&console.log(`[Do11y] Disabled: Domain not allowed:`,e),!0}return!1}function s(e){if(!e||typeof e!=`string`)return null;try{return document.querySelector(e),e}catch{return n.debug&&console.warn(`[Do11y] Invalid CSS selector rejected:`,e),null}}let c=[`/pixel/`];function l(e){let t=e??window.location.pathname;return c.some(e=>t.startsWith(e))}function u(e){if(typeof e.className==`string`)return e.className;let t=e.className;return t&&typeof t.baseVal==`string`?t.baseVal:``}function d(e){let t=e.match(/(?:^|\s)language-([\w-]+)(?:\s|$)/);return t?t[1]:null}function f(e){if(!e)return`unknown`;let t=e;for(let e=0;t&&e<12;e++,t=t.parentElement){for(let e of[`language`,`data-language`,`data-lang`,`data-code-lang`]){let n=t.getAttribute(e);if(n)return n}let e=d(u(t));if(e)return e;let n=t.querySelector(`:scope > span.lang`)?.textContent?.trim();if(n)return n;let r=t.querySelector(`[data-language], [data-lang], [data-code-lang], [class*="language-"], [language]`);if(r){let e=r.getAttribute(`language`)??r.getAttribute(`data-language`)??r.getAttribute(`data-lang`)??r.getAttribute(`data-code-lang`)??d(u(r));if(e)return e}}return`unknown`}function ee(e){if(e.startsWith(`#`))return e;let t=e.indexOf(`#`);if(t===-1)return null;let n=e.slice(0,t);return!n||n===window.location.pathname||n===`${window.location.pathname}${window.location.search}`?e.slice(t):null}function te(e){let t=s(n.tocSelector)??`.table-of-contents, .VPDocAsideOutline, .VPLocalNavOutlineDropdown, [class*="toc"], [class*="TableOfContents"], [class*="page-outline"], .right-sidebar-panel, starlight-toc`,r=e.closest(t);return r?((r===e||r.tagName===`A`)&&(r=e.closest(`.VPDocAsideOutline, .VPLocalNavOutlineDropdown, nav, aside, .right-sidebar-panel, starlight-toc`)??r.parentElement),r):null}function p(e,t){if(!e||typeof e!=`string`)return null;let n=t??100,r=e;return r=r.replace(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/g,`[email]`),r=r.replace(/\b\d{3}[-.]?\d{3}[-.]?\d{4}\b/g,`[phone]`),r=r.replace(/\b\d{3}-\d{2}-\d{4}\b/g,`[redacted]`),r=r.replace(/\b(?:\d[ -]?){13,19}\b/g,`[card]`),r=r.replace(/eyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/g,`[token]`),r=r.replace(/\bxa[a-z]{2}-[A-Za-z0-9_-]{20,}/g,`[token]`),r=r.replace(/\b[0-9a-fA-F]{32,}\b/g,`[redacted]`),r.trim().substring(0,n)}function m(){if(window.crypto&&typeof window.crypto.randomUUID==`function`)return window.crypto.randomUUID();if(window.crypto&&typeof window.crypto.getRandomValues==`function`){let e=new Uint8Array(16);window.crypto.getRandomValues(e),e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t=Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``);return t.slice(0,8)+`-`+t.slice(8,12)+`-`+t.slice(12,16)+`-`+t.slice(16,20)+`-`+t.slice(20)}return`no-crypto-00-0000-0000-000000000000`}function ne(e){if(!e||typeof e!=`object`)return!1;let t=e;return typeof t.id==`string`&&t.id.length>0&&typeof t.startTime==`string`&&Array.isArray(t.pageSequence)&&typeof t.pageCount==`number`}function h(){let e=null;try{let t=sessionStorage.getItem(`do11y_session`);if(t){let n=JSON.parse(t);ne(n)&&(e=n)}}catch{}return e||(e={id:m(),startTime:new Date().toISOString(),pageSequence:[],pageCount:0,referrerCategory:null,aiPlatform:null},g(e)),e}function g(e){try{sessionStorage.setItem(`do11y_session`,JSON.stringify(e))}catch{}}function re(e){let t=h();return t.pageCount++,t.pageSequence.push({path:e,timestamp:new Date().toISOString(),index:t.pageCount}),t.pageSequence.length>50&&(t.pageSequence=t.pageSequence.slice(-50)),g(t),t}function ie(){return{viewportCategory:ae(),browserFamily:_(),deviceType:v(),language:(navigator.language||``).split(`-`)[0]||`unknown`,timezoneOffset:new Date().getTimezoneOffset()/60}}function ae(){let e=window.innerWidth;return e<640?`mobile`:e<1024?`tablet`:e<1440?`desktop`:`large-desktop`}function _(){let e=navigator.userAgent;return e.includes(`Firefox`)?`Firefox`:e.includes(`Edg`)?`Edge`:e.includes(`Chrome`)?`Chrome`:e.includes(`Safari`)?`Safari`:`Other`}function v(){let e=navigator.userAgent;return/Mobile|Android|iPhone|iPad/.test(e)?/iPad|Tablet/.test(e)?`tablet`:`mobile`:`desktop`}let y=[{match:`chatgpt`,platform:`ChatGPT`},{match:`chat.com`,platform:`ChatGPT`},{match:`openai`,platform:`ChatGPT`},{match:`perplexity`,platform:`Perplexity`},{match:`claude.ai`,platform:`Claude`},{match:`anthropic`,platform:`Claude`},{match:`gemini`,platform:`Gemini`},{match:`copilot`,platform:`Copilot`},{match:`deepseek`,platform:`DeepSeek`},{match:`meta.ai`,platform:`Meta AI`},{match:`grok`,platform:`Grok`},{match:`x.ai`,platform:`Grok`},{match:`mistral`,platform:`Mistral`},{match:`you.com`,platform:`You.com`},{match:`phind`,platform:`Phind`}];function b(e){if(!e||e===`direct`)return{referrerCategory:`direct`,aiPlatform:null};if(e===`internal`)return{referrerCategory:`internal`,aiPlatform:null};if(e===`unknown`)return{referrerCategory:`unknown`,aiPlatform:null};let t=e.toLowerCase();for(let e of y)if(t.indexOf(e.match)!==-1)return{referrerCategory:`ai`,aiPlatform:e.platform};return/google\.|bing\.|baidu\.|yandex\.|duckduckgo\.|yahoo\./.test(t)?{referrerCategory:`search-engine`,aiPlatform:null}:/github\.|gitlab\.|bitbucket\./.test(t)?{referrerCategory:`code-host`,aiPlatform:null}:/stackoverflow\.|stackexchange\.|reddit\.|news\.ycombinator\./.test(t)?{referrerCategory:`community`,aiPlatform:null}:/twitter\.|x\.com|linkedin\.|facebook\.|threads\.net/.test(t)?{referrerCategory:`social`,aiPlatform:null}:{referrerCategory:`other`,aiPlatform:null}}function x(){try{if(!document.referrer)return`direct`;let e=new URL(document.referrer);return e.hostname===window.location.hostname?`internal`:e.hostname}catch{return`unknown`}}function S(){return{path:window.location.pathname,hash:window.location.hash||null,search:window.location.search?`has_params`:null,title:p(document.title,150)}}let C=[],w=null,T={},E=!1;function D(t,r){if(E)return;let i=Date.now();if(n.rateLimitMs>0&&T[t]&&i-T[t]<n.rateLimitMs){n.debug&&console.log(`[Do11y] Rate limited:`,t);return}T[t]=i;let a=h(),o={_time:new Date().toISOString(),eventType:t,do11y_version:e,sessionId:a.id,sessionPageCount:a.pageCount,...S(),...ie(),...r};n.debug&&console.log(`[Do11y] Event queued:`,o),C.push(o),C.length>100&&(C=C.slice(-100),n.debug&&console.warn(`[Do11y] Event queue capped at 100 events`)),C.length>=n.maxBatchSize?A():oe()}function oe(){w||=setTimeout(A,n.flushInterval)}function se(e){try{let t=new URL(e);return!(t.protocol!==`https:`||!t.hostname.endsWith(`.supabase.co`))}catch{return!1}}function ce(e){try{let t=new URL(e);if(t.protocol!==`https:`)return!1;let n=t.hostname;return!(n===`localhost`||n===`127.0.0.1`||n===`::1`||/^(10\.|172\.(1[6-9]|2\d|3[01])\.|192\.168\.)/.test(n))}catch{return!1}}function O(){return n.destination===`supabase`?n.supabaseUrl?se(n.supabaseUrl)?!n.supabaseKey||typeof n.supabaseKey!=`string`||n.supabaseKey.length<10?(n.debug&&console.warn(`[Do11y] Invalid or missing Supabase publishable key`),!1):/^[a-zA-Z0-9_-]+$/.test(n.supabaseTable)?!0:(n.debug&&console.warn(`[Do11y] Invalid table name`),!1):(n.debug&&console.warn(`[Do11y] Invalid Supabase URL. Must be https://<project>.supabase.co`),!1):(n.debug&&console.warn(`[Do11y] No Supabase URL configured`),!1):n.destination===`http`?n.httpEndpoint?ce(n.httpEndpoint)?!0:(n.debug&&console.warn(`[Do11y] Invalid HTTP endpoint. Must be HTTPS and not a private address.`),!1):(n.debug&&console.warn(`[Do11y] No HTTP endpoint configured`),!1):(n.debug&&console.warn(`[Do11y] Unknown destination:`,n.destination),!1)}function k(e){return n.destination===`supabase`?{url:n.supabaseUrl.replace(/\/$/,``)+`/rest/v1/`+n.supabaseTable,headers:{apikey:n.supabaseKey,Authorization:`Bearer `+n.supabaseKey,"Content-Type":`application/json`,Prefer:`return=minimal`},body:JSON.stringify(e.map(e=>({payload:e})))}:{url:n.httpEndpoint,headers:{"Content-Type":`application/json`,...n.httpHeaders},body:JSON.stringify(e)}}function A(e){if(w&&=(clearTimeout(w),null),C.length===0||!O())return;let t=typeof e==`number`?e:n.maxRetries,r=C.slice();C=[],le(k(r),r,t)}function le(e,t,r){fetch(e.url,{method:`POST`,headers:e.headers,body:e.body,keepalive:!0}).then(e=>{if(e.ok){n.debug&&console.log(`[Do11y] Flushed`,t.length,`events`);return}if(r>0&&(e.status>=500||e.status===429)){n.debug&&console.log(`[Do11y] Retrying after error:`,e.status),C=t.concat(C),setTimeout(()=>{A(r-1)},n.retryDelay*(n.maxRetries-r+1));return}n.debug&&e.text().then(t=>{console.error(`[Do11y] Ingest failed:`,e.status,t)}).catch(()=>{})}).catch(e=>{r>0?(n.debug&&console.log(`[Do11y] Network error, retrying:`,e.message),C=t.concat(C),setTimeout(()=>{A(r-1)},n.retryDelay*(n.maxRetries-r+1))):n.debug&&console.error(`[Do11y] Failed to send events:`,e)})}function j(){if(C.length===0||!O())return;let e=C;C=[];let t=k(e);try{fetch(t.url,{method:`POST`,headers:t.headers,body:t.body,keepalive:!0})}catch{}n.debug&&console.log(`[Do11y] Sync flushed`,e.length,`events`)}function M(){let e=re(window.location.pathname),t=x(),n=b(t);e.pageCount===1&&(e.referrerCategory=n.referrerCategory,e.aiPlatform=n.aiPlatform,g(e)),D(`page_view`,{referrerDomain:t,referrerCategory:n.referrerCategory,aiPlatform:n.aiPlatform,isFirstPage:e.pageCount===1,previousPath:e.pageSequence.length>1?e.pageSequence[e.pageSequence.length-2].path:null})}function N(){document.addEventListener(`click`,e=>{let t=e.target.closest(`a`);if(!t)return;let r=t.getAttribute(`href`);if(!r)return;let i=`other`,a=null;try{if(r.startsWith(`#`))i=`anchor`;else if(r.startsWith(`/`)||r.startsWith(`./`)||r.startsWith(`../`))i=`internal`;else if(r.startsWith(`http`)){let e=new URL(r);e.hostname===window.location.hostname?i=`internal`:(i=`external`,a=e.hostname)}else r.startsWith(`mailto:`)&&(i=`email`)}catch{}i===`internal`&&!n.trackInternalLinks||i===`external`&&!n.trackOutboundLinks||(D(`link_click`,{linkType:i,targetUrl:r,targetDomain:a,linkText:p(t.textContent,100),linkContext:P(t),linkSection:p(F(t),100),linkIndex:I(t,r)}),A())},!0)}function P(e){return e.closest(n.navigationSelector)?`navigation`:e.closest(n.footerSelector)?`footer`:e.closest(n.contentSelector)?`content`:`other`}function F(e){let t=e;for(;t&&t!==document.body;){let e=t.previousElementSibling;for(;e;){if(/^H[1-6]$/.test(e.tagName))return e.textContent?.trim().substring(0,100)??null;let t=e.querySelectorAll(`h1, h2, h3, h4, h5, h6`);if(t.length>0)return t[t.length-1].textContent?.trim().substring(0,100)??null;e=e.previousElementSibling}t=t.parentElement}return null}function I(e,t){if(typeof CSS>`u`||typeof CSS.escape!=`function`)return 1;try{let n=document.querySelectorAll(`a[href="`+CSS.escape(t)+`"]`);for(let t=0;t<n.length;t++)if(n[t]===e)return t+1}catch{}return 1}let L=new Set,R=null;function z(e){let t=e;for(;t&&t!==document.body&&t!==document.documentElement;){let e=window.getComputedStyle(t).overflowY;if((e===`auto`||e===`scroll`)&&t.scrollHeight>t.clientHeight)return t;t=t.parentElement}return null}function B(){if(!n.trackScrollDepth)return;if(n.contentSelector){let e=document.querySelector(n.contentSelector);e&&(R=z(e))}let e=!1;function t(){e||=(window.requestAnimationFrame(()=>{V(),e=!1}),!0)}if(window.addEventListener(`scroll`,t),R&&(R.addEventListener(`scroll`,t),n.debug)){let e=R;console.log(`[do11y] Using container-based scroll tracking:`,e.className||e.tagName)}V()}function V(){if(l())return;let e,t,r;R&&R.scrollHeight>R.clientHeight?(e=R.scrollTop,t=R.scrollHeight,r=R.clientHeight):(e=window.scrollY||document.documentElement.scrollTop,t=document.documentElement.scrollHeight,r=window.innerHeight);let i=t-r;if(i<=0){n.scrollThresholds.forEach(e=>{L.has(e)||(L.add(e),D(`scroll_depth`,{threshold:e,scrollPercent:100}))});return}let a=Math.round(e/i*100);n.scrollThresholds.forEach(e=>{a>=e&&!L.has(e)&&(L.add(e),D(`scroll_depth`,{threshold:e,scrollPercent:a}))})}let H=Date.now(),U=Date.now(),W=0,G=!0;function K(){if(l())return;G&&(W+=Date.now()-U);let e=Date.now()-H,t=e>0?W/e:0,n=0;L.forEach(e=>{e>n&&(n=e)}),X();let r=h();D(`page_exit`,{totalTimeSeconds:Math.round(e/1e3),activeTimeSeconds:Math.round(W/1e3),engagementRatio:Math.round(t*100)/100,maxScrollDepth:n,referrerCategory:r.referrerCategory,aiPlatform:r.aiPlatform})}function ue(){document.addEventListener(`visibilitychange`,()=>{document.hidden?G&&=(W+=Date.now()-U,!1):(U=Date.now(),G=!0)}),window.addEventListener(`beforeunload`,()=>{K(),ve()})}function de(){document.addEventListener(`click`,e=>{e.target.closest(n.searchSelector)&&D(`search_opened`,{})},!0),document.addEventListener(`keydown`,e=>{(e.metaKey||e.ctrlKey)&&e.key===`k`&&D(`search_opened`,{trigger:`keyboard`})})}function fe(e){if(!e)return 1;try{let t=document.querySelectorAll(n.codeBlockSelector);for(let n=0;n<t.length;n++)if(t[n]===e)return n+1}catch{}return 1}function pe(){document.addEventListener(`click`,e=>{let t=e.target.closest(n.copyButtonSelector);if(t){let e=t.closest(`[class*="language-"], [language]`)??t.closest(n.codeBlockSelector)??t.closest(`.expressive-code`)?.querySelector(`pre`)??t.closest(`div, section`)?.querySelector(`pre`)??t.parentElement?.querySelector(`pre`)??null;D(`code_copied`,{language:f((e?e.tagName===`PRE`?e.querySelector(`code`):e.querySelector(`code[class*="language-"], code[language]`)??e.querySelector(`code`):null)??e??t),codeSection:p(F(e??t),100),codeBlockIndex:fe(e)})}},!0)}let q=null,J={};function me(){if(!n.trackSectionVisibility||typeof IntersectionObserver>`u`)return;let e=n.sectionVisibleThreshold*1e3;q=new IntersectionObserver(t=>{t.forEach(t=>{let n=t.target.getAttribute(`data-do11y-section-id`);if(n)if(t.isIntersecting)J[n]||(J[n]={start:Date.now(),reported:!1});else{if(J[n]&&!J[n].reported){let r=Date.now()-J[n].start;r>=e&&(D(`section_visible`,{heading:p(t.target.textContent?.trim()??``,100),headingLevel:parseInt(t.target.tagName.charAt(1),10),visibleSeconds:Math.round(r/1e3)}),J[n].reported=!0)}delete J[n]}})},{threshold:.5}),Y()}function Y(){q&&document.querySelectorAll(`h2, h3`).forEach((e,t)=>{e.setAttribute(`data-do11y-section-id`,`section-`+t),q.observe(e)})}function X(){if(!q)return;let e=Date.now(),t=n.sectionVisibleThreshold*1e3;Object.keys(J).forEach(n=>{let r=J[n];if(r&&!r.reported){let i=e-r.start;if(i>=t){let e=typeof CSS<`u`&&typeof CSS.escape==`function`?CSS.escape(n):n.replace(/["\\]/g,`\\$&`),t=document.querySelector(`[data-do11y-section-id="`+e+`"]`);t&&D(`section_visible`,{heading:p(t.textContent?.trim()??``,100),headingLevel:parseInt(t.tagName.charAt(1),10),visibleSeconds:Math.round(i/1e3)})}}}),J={}}function he(){n.trackTabSwitches&&document.addEventListener(`click`,e=>{let t=`[role="tab"], .tabs button, .tabs a, .tabbed-labels label`,r=s(n.tabContainerSelector);r&&(t+=`, `+r+` button, `+r+` a, `+r+` label`);let i=e.target.closest(t);if(!i||i.getAttribute(`aria-selected`)===`true`||i.classList.contains(`active`)||i.classList.contains(`is-active`))return;let a=p(i.textContent,50);a&&D(`tab_switch`,{tabLabel:a,tabGroup:p(F(i),100),isDefault:!1})})}function Z(){n.trackTocClicks&&document.addEventListener(`click`,e=>{let t=e.target.closest(`a`);if(!t)return;let n=te(t);if(!n)return;let r=t.getAttribute(`href`),i=r?ee(r):null;if(!i)return;let a=p(t.textContent,100),o=null;try{let e=i.slice(1),t=document.getElementById(e);t&&/^H[1-6]$/.test(t.tagName)&&(o=parseInt(t.tagName.charAt(1),10))}catch{}let s=n.querySelectorAll(`a[href*="#"]`),c=1;for(let e=0;e<s.length;e++)if(s[e]===t){c=e+1;break}D(`toc_click`,{heading:a,headingLevel:o,tocPosition:c})},!0)}function ge(){n.trackFeedback&&document.addEventListener(`click`,e=>{let t=e.target.closest(`button, [role="button"], a`);if(!t||!t.closest(s(n.feedbackSelector)??`[class*="feedback"], [class*="helpful"], [class*="rating"], [class*="was-this"], [data-feedback]`))return;let r=(t.textContent??``).trim().toLowerCase(),i=(t.getAttribute(`aria-label`)??``).toLowerCase(),a=(t.getAttribute(`title`)??``).toLowerCase(),o=t.getAttribute(`data-value`)??t.getAttribute(`data-md-value`)??t.getAttribute(`data-feedback`),c=o&&/^[\w\s.,!?-]{1,50}$/.test(o)?o:null,l=null;c?l=c:/\byes\b|👍|thumbs.?up|helpful/i.test(r+` `+i+` `+a)?l=`yes`:/\bno\b|👎|thumbs.?down|not.?helpful/i.test(r+` `+i+` `+a)&&(l=`no`),l&&D(`feedback`,{rating:l})})}function _e(){n.trackExpandCollapse&&(document.addEventListener(`toggle`,e=>{let t=e.target;if(t.tagName!==`DETAILS`)return;let n=t.querySelector(`summary`);D(`expand_collapse`,{summary:p(n?n.textContent:``,100),action:t.open?`expand`:`collapse`,section:p(F(t),100)})},!0),document.addEventListener(`click`,e=>{let t=e.target.closest(`[aria-expanded], [class*="accordion"] button, [class*="collapsible"] button`);if(!t||t.closest(`details`)||t.closest(`nav, [role="navigation"], header`))return;let n=t.getAttribute(`aria-expanded`)===`true`;D(`expand_collapse`,{summary:p(t.textContent,100),action:n?`collapse`:`expand`,section:p(F(t),100)})}))}let Q=null;function $(){if(window.Do11yConfig&&typeof window.Do11yConfig==`object`)for(let e in window.Do11yConfig)Object.prototype.hasOwnProperty.call(window.Do11yConfig,e)&&Object.prototype.hasOwnProperty.call(n,e)&&(n[e]=window.Do11yConfig[e]);let e=document.querySelector(`meta[name="do11y-destination"]`);if(e){let t=e.getAttribute(`content`);(t===`supabase`||t===`http`)&&(n.destination=t)}let t=document.querySelector(`meta[name="do11y-url"]`);t&&(n.supabaseUrl=t.getAttribute(`content`)??n.supabaseUrl);let r=document.querySelector(`meta[name="do11y-key"]`);r&&(n.supabaseKey=r.getAttribute(`content`)??n.supabaseKey);let i=document.querySelector(`meta[name="do11y-table"]`);i&&(n.supabaseTable=i.getAttribute(`content`)??n.supabaseTable);let s=document.querySelector(`meta[name="do11y-http-endpoint"]`);s&&(n.httpEndpoint=s.getAttribute(`content`)??n.httpEndpoint);let c=document.querySelector(`meta[name="do11y-debug"]`);c&&c.getAttribute(`content`)===`true`&&(n.debug=!0);let l=document.querySelector(`meta[name="do11y-domains"]`);if(l){let e=l.getAttribute(`content`);e&&(n.allowedDomains=e.split(`,`).map(e=>e.trim()))}let u=document.querySelector(`meta[name="do11y-framework"]`);if(u&&(n.framework=u.getAttribute(`content`)??n.framework),a(),n.debug&&console.log(`[Do11y] Initializing with config:`,{destination:n.destination,hasCredentials:n.destination===`supabase`?!!n.supabaseKey:!!n.httpEndpoint,framework:n.framework,allowedDomains:n.allowedDomains,respectDNT:n.respectDNT}),o()){E=!0,n.debug&&console.log(`[Do11y] Tracking disabled`);return}(n.destination===`supabase`?n.supabaseKey:n.httpEndpoint)||n.debug&&(console.warn(`[Do11y] No destination configured. Events will not be sent.`),console.warn(`[Do11y] Add <meta name="do11y-url"> and <meta name="do11y-key"> to enable.`)),M(),N(),B(),ue(),de(),pe(),me(),he(),Z(),ge(),_e();let d=window.location.pathname;Q=new MutationObserver(()=>{window.location.pathname!==d&&(d=window.location.pathname,K(),L=new Set,H=Date.now(),U=Date.now(),W=0,G=!0,M(),Y(),V())}),Q.observe(document.body,{childList:!0,subtree:!0}),window.addEventListener(`popstate`,()=>{window.location.pathname!==d&&(d=window.location.pathname,K(),L=new Set,H=Date.now(),U=Date.now(),W=0,G=!0,M(),Y(),V())}),Object.freeze(n),n.debug&&console.log(`[Do11y] Initialized successfully`)}function ve(){Q&&=(Q.disconnect(),null),q&&=(X(),q.disconnect(),null),w&&=(clearTimeout(w),null),j()}t||(document.readyState===`loading`?document.addEventListener(`DOMContentLoaded`,$):$()),window.Do11y=window.Do11y??{getConfig:()=>({destination:n.destination,hasCredentials:n.destination===`supabase`?!!n.supabaseKey:!!n.httpEndpoint,isDisabled:E,allowedDomains:n.allowedDomains,respectDNT:n.respectDNT}),flush:A,isEnabled:()=>!E&&(n.destination===`supabase`?!!n.supabaseKey:!!n.httpEndpoint),getQueueSize:()=>C.length,version:e}})();
@@ -25,7 +25,7 @@ window.Do11yConfig = {
25
25
  supabaseTable: 'do11y_events',
26
26
 
27
27
  // Documentation framework. Supported values:
28
- // 'mintlify', 'docusaurus', 'nextra', 'gitbook', 'mkdocs-material',
28
+ // 'mintlify', 'docusaurus', 'nextra', 'starlight', 'mkdocs-material',
29
29
  // 'vitepress', 'custom'
30
30
  framework: 'mintlify',
31
31
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@manototh/do11y",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "Documentation observability",
5
5
  "type": "module",
6
6
  "main": "./dist/do11y.min.js",